@tma.js/sdk 1.3.0 → 1.4.0
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.
- package/dist/dts/launch-params/index.d.ts +1 -0
- package/dist/dts/launch-params/retrieveFromUrl.d.ts +6 -0
- package/dist/dts/launch-params/types.d.ts +12 -8
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.iife.js +1 -1
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +243 -238
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/globals.ts +39 -0
- package/src/back-button/__tests__/BackButton.ts +129 -0
- package/src/bridge/__tests__/request.ts +236 -0
- package/src/bridge/env/__tests__/hasExternalNotify.ts +15 -0
- package/src/bridge/env/__tests__/hasWebviewProxy.ts +15 -0
- package/src/bridge/env/__tests__/isIframe.ts +30 -0
- package/src/bridge/events/__tests__/createEmitter.ts +143 -0
- package/src/bridge/events/__tests__/off.ts +34 -0
- package/src/bridge/events/__tests__/on.ts +49 -0
- package/src/bridge/events/__tests__/onTelegramEvent.ts +51 -0
- package/src/bridge/events/__tests__/once.ts +64 -0
- package/src/bridge/events/__tests__/singletonEmitter.ts +22 -0
- package/src/bridge/events/__tests__/subscribe.ts +49 -0
- package/src/bridge/events/__tests__/unsubscribe.ts +34 -0
- package/src/bridge/events/parsers/__tests__/clipboardTextReceived.ts +21 -0
- package/src/bridge/events/parsers/__tests__/invoiceClosed.ts +12 -0
- package/src/bridge/events/parsers/__tests__/popupClosed.ts +10 -0
- package/src/bridge/events/parsers/__tests__/qrTextReceived.ts +9 -0
- package/src/bridge/events/parsers/__tests__/theme-changed.ts +42 -0
- package/src/bridge/events/parsers/__tests__/viewportChanged.ts +49 -0
- package/src/bridge/methods/__tests__/createPostEvent.ts +37 -0
- package/src/bridge/methods/__tests__/postEvent.ts +137 -0
- package/src/classnames/__tests__/classNames.ts +20 -0
- package/src/classnames/__tests__/mergeClassNames.ts +21 -0
- package/src/closing-behavior/__tests__/ClosingBehavior.ts +86 -0
- package/src/colors/__tests__/isColorDark.ts +12 -0
- package/src/colors/__tests__/isRGB.ts +13 -0
- package/src/colors/__tests__/isRGBShort.ts +13 -0
- package/src/colors/__tests__/toRGB.ts +23 -0
- package/src/event-emitter/__tests__/EventEmitter.ts +145 -0
- package/src/haptic-feedback/__tests__/HapticFeedback.ts +68 -0
- package/src/init/creators/__tests__/createViewport.ts +96 -0
- package/src/init-data/__tests__/InitData.ts +98 -0
- package/src/init-data/__tests__/chatParser.ts +102 -0
- package/src/init-data/__tests__/initDataParser.ts +136 -0
- package/src/init-data/__tests__/parseInitData.ts +136 -0
- package/src/init-data/__tests__/userParser.ts +96 -0
- package/src/launch-params/__tests__/retrieveFromUrl.ts +19 -0
- package/src/launch-params/index.ts +1 -0
- package/src/launch-params/launchParamsParser.ts +4 -0
- package/src/launch-params/retrieveFromLocation.ts +2 -2
- package/src/launch-params/retrieveFromPerformance.ts +2 -7
- package/src/launch-params/retrieveFromUrl.ts +19 -0
- package/src/launch-params/types.ts +13 -8
- package/src/logger/__tests__/Logger.ts +107 -0
- package/src/main-button/__tests__/MainButton.ts +346 -0
- package/src/mini-app/__tests__/MiniApp.ts +140 -0
- package/src/misc/__tests__/isRecord.ts +21 -0
- package/src/navigation/HashNavigator/__tests__/HashNavigator.ts +144 -0
- package/src/navigation/HashNavigator/__tests__/drop.ts +42 -0
- package/src/navigation/HashNavigator/__tests__/go.ts +9 -0
- package/src/parsing/__tests__/ArrayValueParser.ts +18 -0
- package/src/parsing/__tests__/toRecord.ts +10 -0
- package/src/parsing/parsers/__tests__/array.ts +39 -0
- package/src/parsing/parsers/__tests__/boolean.ts +31 -0
- package/src/parsing/parsers/__tests__/date.ts +25 -0
- package/src/parsing/parsers/__tests__/json.ts +80 -0
- package/src/parsing/parsers/__tests__/number.ts +23 -0
- package/src/parsing/parsers/__tests__/rgb.ts +22 -0
- package/src/parsing/parsers/__tests__/searchParams.ts +105 -0
- package/src/parsing/parsers/__tests__/string.ts +25 -0
- package/src/popup/__tests__/Popup.ts +130 -0
- package/src/popup/__tests__/preparePopupParams.ts +85 -0
- package/src/supports/__tests__/supports.ts +123 -0
- package/src/theme-params/__tests__/keys.ts +19 -0
- package/src/theme-params/__tests__/parseThemeParams.ts +29 -0
- package/src/theme-params/__tests__/serializeThemeParams.ts +29 -0
- package/src/theme-params/__tests__/themeParamsParser.ts +29 -0
- package/src/timeout/__tests__/isTimeoutError.ts +9 -0
- package/src/timeout/__tests__/withTimeout.ts +28 -0
- package/src/version/__tests__/compareVersions.ts +19 -0
- package/src/viewport/__tests__/isStableViewportPlatform.ts +15 -0
- package/src/viewport/__tests__/utils.ts +12 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
MiniAppsMethodName,
|
|
5
|
+
MiniAppsMethodVersionedParams,
|
|
6
|
+
MiniAppsMethodWithVersionedParams,
|
|
7
|
+
} from '../../bridge';
|
|
8
|
+
import type { Version } from '../../version';
|
|
9
|
+
import { supports } from '../supports';
|
|
10
|
+
|
|
11
|
+
type HaveCheckSupportMethodTuple = {
|
|
12
|
+
[M in MiniAppsMethodWithVersionedParams]: [M, MiniAppsMethodVersionedParams<M>]
|
|
13
|
+
}[MiniAppsMethodWithVersionedParams];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Increases specified version by amount of updates.
|
|
17
|
+
* @param version - initial version.
|
|
18
|
+
* @param amount - count of bumps.
|
|
19
|
+
*/
|
|
20
|
+
function increaseVersion(version: Version, amount: number): string {
|
|
21
|
+
const match = version.match(/(.+\.)(\d+)$/);
|
|
22
|
+
if (!match) {
|
|
23
|
+
throw new Error(`Invalid version: ${version}`);
|
|
24
|
+
}
|
|
25
|
+
return `${match[1]}${parseInt(match[2], 10) + amount}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const tests: [
|
|
29
|
+
version: Version | 'any',
|
|
30
|
+
methods: (MiniAppsMethodName | HaveCheckSupportMethodTuple)[],
|
|
31
|
+
][] = [
|
|
32
|
+
['any', [
|
|
33
|
+
'iframe_ready',
|
|
34
|
+
'iframe_will_reload',
|
|
35
|
+
'web_app_close',
|
|
36
|
+
'web_app_data_send',
|
|
37
|
+
'web_app_expand',
|
|
38
|
+
'web_app_open_link',
|
|
39
|
+
'web_app_ready',
|
|
40
|
+
'web_app_request_theme',
|
|
41
|
+
'web_app_request_viewport',
|
|
42
|
+
'web_app_setup_main_button',
|
|
43
|
+
'web_app_setup_closing_behavior',
|
|
44
|
+
]],
|
|
45
|
+
['6.1', [
|
|
46
|
+
'web_app_open_tg_link',
|
|
47
|
+
'web_app_open_invoice',
|
|
48
|
+
'web_app_setup_back_button',
|
|
49
|
+
'web_app_set_background_color',
|
|
50
|
+
'web_app_set_header_color',
|
|
51
|
+
'web_app_trigger_haptic_feedback',
|
|
52
|
+
]],
|
|
53
|
+
['6.2', [
|
|
54
|
+
'web_app_open_popup',
|
|
55
|
+
]],
|
|
56
|
+
['6.4', [
|
|
57
|
+
'web_app_read_text_from_clipboard',
|
|
58
|
+
'web_app_close_scan_qr_popup',
|
|
59
|
+
'web_app_close_scan_qr_popup',
|
|
60
|
+
['web_app_open_link', 'try_instant_view'],
|
|
61
|
+
]],
|
|
62
|
+
['6.7', [
|
|
63
|
+
'web_app_switch_inline_query',
|
|
64
|
+
]],
|
|
65
|
+
['6.9', [
|
|
66
|
+
'web_app_invoke_custom_method',
|
|
67
|
+
'web_app_request_write_access',
|
|
68
|
+
'web_app_request_phone',
|
|
69
|
+
['web_app_set_header_color', 'color'],
|
|
70
|
+
]],
|
|
71
|
+
['6.10', [
|
|
72
|
+
'web_app_setup_settings_button',
|
|
73
|
+
]],
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
tests.forEach(([version, methods]) => {
|
|
77
|
+
if (version === 'any') {
|
|
78
|
+
methods.forEach((methodOrTuple) => {
|
|
79
|
+
if (Array.isArray(methodOrTuple)) {
|
|
80
|
+
const [method, param] = methodOrTuple;
|
|
81
|
+
it(`should return true in case, passed method is "${method}", parameter is "${param}" and version is 1`, () => {
|
|
82
|
+
expect(supports(method, param, '1')).toBe(true);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const method = methodOrTuple;
|
|
89
|
+
it(`should return true in case, passed method is "${method}" and version is 1`, () => {
|
|
90
|
+
expect(supports(method, '1')).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
methods.forEach((methodOrTuple) => {
|
|
97
|
+
if (Array.isArray(methodOrTuple)) {
|
|
98
|
+
const [method, param] = methodOrTuple;
|
|
99
|
+
|
|
100
|
+
it(`should return true in case, passed method is "${method}", parameter is "${param}" and version is ${version} or higher`, () => {
|
|
101
|
+
expect(supports(method, param, version)).toBe(true);
|
|
102
|
+
expect(supports(method, param, increaseVersion(version, 1))).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it(`should return false in case, passed method is "${method}", parameter is "${param}" and version is lower than ${version}`, () => {
|
|
106
|
+
expect(supports(method, param, increaseVersion(version, -1))).toBe(false);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const method = methodOrTuple;
|
|
113
|
+
|
|
114
|
+
it(`should return true in case, passed method is "${method}" and version is ${version} or higher`, () => {
|
|
115
|
+
expect(supports(method, version)).toBe(true);
|
|
116
|
+
expect(supports(method, increaseVersion(version, 1))).toBe(true);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it(`should return false in case, passed method is "${method}" and version is lower than ${version}`, () => {
|
|
120
|
+
expect(supports(method, increaseVersion(version, -1))).toBe(false);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { keyToExternal, keyToLocal } from '../keys';
|
|
4
|
+
|
|
5
|
+
describe('keyToLocal', () => {
|
|
6
|
+
it('should replace "^bg" and "_bg" with "background" and "_background". Then replace _[a-z] with [A-Z]', () => {
|
|
7
|
+
expect(keyToLocal('bg_color')).toBe('backgroundColor');
|
|
8
|
+
expect(keyToLocal('secondary_bg_color')).toBe('secondaryBackgroundColor');
|
|
9
|
+
expect(keyToLocal('text_color')).toBe('textColor');
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe('keyToExternal', () => {
|
|
14
|
+
it('should replace [A-Z] with _[a-z]. Then replace "background" and "_background" with "^bg" and "_bg"', () => {
|
|
15
|
+
expect(keyToExternal('backgroundColor')).toBe('bg_color');
|
|
16
|
+
expect(keyToExternal('secondaryBackgroundColor')).toBe('secondary_bg_color');
|
|
17
|
+
expect(keyToExternal('textColor')).toBe('text_color');
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { parseThemeParams } from '../parseThemeParams';
|
|
4
|
+
|
|
5
|
+
[
|
|
6
|
+
['accent_text_color', 'accentTextColor'],
|
|
7
|
+
['bg_color', 'backgroundColor'],
|
|
8
|
+
['button_color', 'buttonColor'],
|
|
9
|
+
['button_text_color', 'buttonTextColor'],
|
|
10
|
+
['destructive_text_color', 'destructiveTextColor'],
|
|
11
|
+
['header_bg_color', 'headerBackgroundColor'],
|
|
12
|
+
['hint_color', 'hintColor'],
|
|
13
|
+
['link_color', 'linkColor'],
|
|
14
|
+
['secondary_bg_color', 'secondaryBackgroundColor'],
|
|
15
|
+
['section_header_text_color', 'sectionHeaderTextColor'],
|
|
16
|
+
['section_bg_color', 'sectionBackgroundColor'],
|
|
17
|
+
['subtitle_text_color', 'subtitleTextColor'],
|
|
18
|
+
['text_color', 'textColor'],
|
|
19
|
+
].forEach(([from, to]) => {
|
|
20
|
+
describe(to, () => {
|
|
21
|
+
it(`should throw if "${from}" property contains not a string in format "#RRGGBB"`, () => {
|
|
22
|
+
expect(() => parseThemeParams({ [from]: 999 })).toThrow();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it(`should map to "${to}" property parsing it as string in "#RRGGBB" format`, () => {
|
|
26
|
+
expect(parseThemeParams({ [from]: '#aabbcc' })).toStrictEqual({ [to]: '#aabbcc' });
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { serializeThemeParams } from '../serializeThemeParams';
|
|
4
|
+
|
|
5
|
+
[
|
|
6
|
+
['accent_text_color', 'accentTextColor'],
|
|
7
|
+
['bg_color', 'backgroundColor'],
|
|
8
|
+
['button_color', 'buttonColor'],
|
|
9
|
+
['button_text_color', 'buttonTextColor'],
|
|
10
|
+
['destructive_text_color', 'destructiveTextColor'],
|
|
11
|
+
['header_bg_color', 'headerBackgroundColor'],
|
|
12
|
+
['hint_color', 'hintColor'],
|
|
13
|
+
['link_color', 'linkColor'],
|
|
14
|
+
['secondary_bg_color', 'secondaryBackgroundColor'],
|
|
15
|
+
['section_header_text_color', 'sectionHeaderTextColor'],
|
|
16
|
+
['section_bg_color', 'sectionBackgroundColor'],
|
|
17
|
+
['subtitle_text_color', 'subtitleTextColor'],
|
|
18
|
+
['text_color', 'textColor'],
|
|
19
|
+
].forEach(([to, from]) => {
|
|
20
|
+
describe(from, () => {
|
|
21
|
+
it(`should omit the "${to}" property in case this property is missing`, () => {
|
|
22
|
+
expect(serializeThemeParams({})).not.toMatch(`"${to}"`);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it(`should map this property to "${to}" property`, () => {
|
|
26
|
+
expect(serializeThemeParams({ [from]: '#aabbcc' })).toBe(`{"${to}":"#aabbcc"}`);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { themeParamsParser } from '../themeParamsParser';
|
|
4
|
+
|
|
5
|
+
[
|
|
6
|
+
['accent_text_color', 'accentTextColor'],
|
|
7
|
+
['bg_color', 'backgroundColor'],
|
|
8
|
+
['button_color', 'buttonColor'],
|
|
9
|
+
['button_text_color', 'buttonTextColor'],
|
|
10
|
+
['destructive_text_color', 'destructiveTextColor'],
|
|
11
|
+
['header_bg_color', 'headerBackgroundColor'],
|
|
12
|
+
['hint_color', 'hintColor'],
|
|
13
|
+
['link_color', 'linkColor'],
|
|
14
|
+
['secondary_bg_color', 'secondaryBackgroundColor'],
|
|
15
|
+
['section_header_text_color', 'sectionHeaderTextColor'],
|
|
16
|
+
['section_bg_color', 'sectionBackgroundColor'],
|
|
17
|
+
['subtitle_text_color', 'subtitleTextColor'],
|
|
18
|
+
['text_color', 'textColor'],
|
|
19
|
+
].forEach(([from, to]) => {
|
|
20
|
+
describe(to, () => {
|
|
21
|
+
it(`should throw if "${from}" property contains not a string in format "#RRGGBB"`, () => {
|
|
22
|
+
expect(() => themeParamsParser().parse({ [from]: 999 })).toThrow();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it(`should map to "${to}" property parsing it as string in "#RRGGBB" format`, () => {
|
|
26
|
+
expect(themeParamsParser().parse({ [from]: '#aabbcc' })).toStrictEqual({ [to]: '#aabbcc' });
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { isTimeoutError } from '../isTimeoutError';
|
|
4
|
+
import { TimeoutError } from '../TimeoutError';
|
|
5
|
+
|
|
6
|
+
it('should return true if passed value is instance of TimeoutError', () => {
|
|
7
|
+
expect(isTimeoutError(null)).toBe(false);
|
|
8
|
+
expect(isTimeoutError(new TimeoutError(1000))).toBe(true);
|
|
9
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { afterAll, beforeAll, expect, it, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { TimeoutError, withTimeout } from '../index';
|
|
4
|
+
|
|
5
|
+
beforeAll(() => {
|
|
6
|
+
vi.useFakeTimers();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
afterAll(() => {
|
|
10
|
+
vi.useRealTimers();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should throw an error in case timeout reached', () => {
|
|
14
|
+
const promise = withTimeout(() => new Promise((res) => {
|
|
15
|
+
setTimeout(res, 500);
|
|
16
|
+
}), 100);
|
|
17
|
+
|
|
18
|
+
Promise.resolve().then(() => vi.advanceTimersByTime(500));
|
|
19
|
+
expect(promise).rejects.toStrictEqual(new TimeoutError(100));
|
|
20
|
+
}, 1000);
|
|
21
|
+
|
|
22
|
+
it('should return resolved value by wrapped function', () => {
|
|
23
|
+
const promise = withTimeout(() => new Promise((res) => {
|
|
24
|
+
res('I am fine');
|
|
25
|
+
}), 100);
|
|
26
|
+
|
|
27
|
+
expect(promise).resolves.toBe('I am fine');
|
|
28
|
+
}, 1000);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { compareVersions } from '../compareVersions';
|
|
4
|
+
|
|
5
|
+
it('should return 1 in case "a" is greater than "b"', () => {
|
|
6
|
+
expect(compareVersions('6.1', '6.0')).toBe(1);
|
|
7
|
+
expect(compareVersions('6.1', '6')).toBe(1);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('should return 0 in case "a" is equal to "b"', () => {
|
|
11
|
+
expect(compareVersions('6', '6')).toBe(0);
|
|
12
|
+
expect(compareVersions('6', '6.0')).toBe(0);
|
|
13
|
+
expect(compareVersions('6.0', '6')).toBe(0);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should return -1 in case "a" is lower than "b"', () => {
|
|
17
|
+
expect(compareVersions('5', '6.0')).toBe(-1);
|
|
18
|
+
expect(compareVersions('6.0', '6.1')).toBe(-1);
|
|
19
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { isStableViewportPlatform } from '../isStableViewportPlatform';
|
|
4
|
+
|
|
5
|
+
['macos', 'tdesktop', 'unigram', 'web', 'weba'].forEach((platform) => {
|
|
6
|
+
it(`should return true if passed platform is "${platform}"`, () => {
|
|
7
|
+
expect(isStableViewportPlatform(platform)).toBe(true);
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
['unknown', 'android', 'android_x'].forEach((platform) => {
|
|
12
|
+
it(`should return false if passed platform is "${platform}"`, () => {
|
|
13
|
+
expect(isStableViewportPlatform(platform)).toBe(false);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { truncate } from '../utils';
|
|
4
|
+
|
|
5
|
+
it('should return zero if value is less than 0', () => {
|
|
6
|
+
expect(truncate(-1)).toBe(0);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('should return value if it is equals to or higher than 0', () => {
|
|
10
|
+
expect(truncate(0)).toBe(0);
|
|
11
|
+
expect(truncate(20)).toBe(20);
|
|
12
|
+
});
|