@tma.js/bridge 1.3.2

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 (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +28 -0
  3. package/dist/lib/browser.js +2 -0
  4. package/dist/lib/browser.js.map +1 -0
  5. package/dist/lib/index.cjs +2 -0
  6. package/dist/lib/index.cjs.map +1 -0
  7. package/dist/lib/index.mjs +2 -0
  8. package/dist/lib/index.mjs.map +1 -0
  9. package/dist/types/env.d.ts +29 -0
  10. package/dist/types/events/emitter.d.ts +11 -0
  11. package/dist/types/events/events.d.ts +113 -0
  12. package/dist/types/events/index.d.ts +7 -0
  13. package/dist/types/events/off.d.ts +7 -0
  14. package/dist/types/events/on.d.ts +10 -0
  15. package/dist/types/events/onTelegramEvent.d.ts +7 -0
  16. package/dist/types/events/once.d.ts +9 -0
  17. package/dist/types/events/parsing.d.ts +38 -0
  18. package/dist/types/events/payloads.d.ts +47 -0
  19. package/dist/types/events/subscribe.d.ts +9 -0
  20. package/dist/types/events/unsubscribe.d.ts +6 -0
  21. package/dist/types/globals.d.ts +27 -0
  22. package/dist/types/index.d.ts +6 -0
  23. package/dist/types/methods/haptic.d.ts +40 -0
  24. package/dist/types/methods/index.d.ts +5 -0
  25. package/dist/types/methods/invoke-custom-method.d.ts +24 -0
  26. package/dist/types/methods/params.d.ts +227 -0
  27. package/dist/types/methods/popup.d.ts +50 -0
  28. package/dist/types/methods/postEvent.d.ts +31 -0
  29. package/dist/types/request.d.ts +66 -0
  30. package/dist/types/shared.d.ts +5 -0
  31. package/dist/types/supports.d.ts +22 -0
  32. package/package.json +67 -0
  33. package/src/env.ts +49 -0
  34. package/src/events/emitter.ts +125 -0
  35. package/src/events/events.ts +152 -0
  36. package/src/events/index.ts +7 -0
  37. package/src/events/off.ts +12 -0
  38. package/src/events/on.ts +17 -0
  39. package/src/events/onTelegramEvent.ts +83 -0
  40. package/src/events/once.ts +16 -0
  41. package/src/events/parsing.ts +94 -0
  42. package/src/events/payloads.ts +65 -0
  43. package/src/events/subscribe.ts +16 -0
  44. package/src/events/unsubscribe.ts +11 -0
  45. package/src/globals.ts +44 -0
  46. package/src/index.ts +6 -0
  47. package/src/methods/haptic.ts +52 -0
  48. package/src/methods/index.ts +5 -0
  49. package/src/methods/invoke-custom-method.ts +25 -0
  50. package/src/methods/params.ts +245 -0
  51. package/src/methods/popup.ts +55 -0
  52. package/src/methods/postEvent.ts +103 -0
  53. package/src/request.ts +171 -0
  54. package/src/shared.ts +5 -0
  55. package/src/supports.ts +99 -0
@@ -0,0 +1,16 @@
1
+ import { singletonEmitter } from './emitter.js';
2
+ import { unsubscribe } from './unsubscribe.js';
3
+
4
+ import type { GlobalEventListener } from './events.js';
5
+
6
+ type StopListening = () => void;
7
+
8
+ /**
9
+ * Subscribes to all events sent from the native Telegram application.
10
+ * Returns function used to remove added event listener.
11
+ * @param listener - event listener.
12
+ */
13
+ export function subscribe(listener: GlobalEventListener): StopListening {
14
+ singletonEmitter().subscribe(listener);
15
+ return () => unsubscribe(listener);
16
+ }
@@ -0,0 +1,11 @@
1
+ import { singletonEmitter } from './emitter.js';
2
+
3
+ import type { GlobalEventListener } from './events.js';
4
+
5
+ /**
6
+ * Removes global event listener.
7
+ * @param listener - event listener.
8
+ */
9
+ export function unsubscribe(listener: GlobalEventListener): void {
10
+ singletonEmitter().unsubscribe(listener);
11
+ }
package/src/globals.ts ADDED
@@ -0,0 +1,44 @@
1
+ import { log as utilLog } from '@tma.js/logger';
2
+
3
+ let currentDebug = false;
4
+ let currentTargetOrigin = 'https://web.telegram.org';
5
+
6
+ /**
7
+ * Sets new debug mode. Enabling debug mode leads to printing
8
+ * additional messages in console, related to the processes
9
+ * inside the package.
10
+ * @param value - should debug mode be enabled.
11
+ */
12
+ export function setDebug(value: boolean): void {
13
+ currentDebug = value;
14
+ }
15
+
16
+ /**
17
+ * Sets new global targetOrigin, used by `postEvent` method.
18
+ * Default value is "https://web.telegram.org". You don't need to
19
+ * use this method until you know what you are doing.
20
+ *
21
+ * This method could be used for test purposes.
22
+ * @param value - new target origin.
23
+ */
24
+ export function setTargetOrigin(value: string): void {
25
+ currentTargetOrigin = value;
26
+ }
27
+
28
+ /**
29
+ * Returns current global target origin.
30
+ */
31
+ export function targetOrigin(): string {
32
+ return currentTargetOrigin;
33
+ }
34
+
35
+ /**
36
+ * Logs message in case, debug mode is enabled.
37
+ * @param level - log level
38
+ * @param args - values to print.
39
+ */
40
+ export const log: typeof utilLog = (level, ...args) => {
41
+ if (currentDebug) {
42
+ utilLog(level, '[Bridge]', ...args);
43
+ }
44
+ };
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './events/index.js';
2
+ export * from './methods/index.js';
3
+ export * from './env.js';
4
+ export { setDebug, setTargetOrigin } from './globals.js';
5
+ export * from './request.js';
6
+ export * from './supports.js';
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Generic type which creates new types of haptic feedback.
3
+ */
4
+ type CreateHapticFeedbackParams<T extends string, P> = { type: T } & P;
5
+
6
+ /**
7
+ * Style of impact occurred haptic event.
8
+ * - `light`, indicates a collision between small or lightweight UI objects,
9
+ * - `medium`, indicates a collision between medium-sized or medium-weight UI objects,
10
+ * - `heavy`, indicates a collision between large or heavyweight UI objects,
11
+ * - `rigid`, indicates a collision between hard or inflexible UI objects,
12
+ * - `soft`, indicates a collision between soft or flexible UI objects.
13
+ */
14
+ export type ImpactHapticFeedbackStyle =
15
+ | 'light'
16
+ | 'medium'
17
+ | 'heavy'
18
+ | 'rigid'
19
+ | 'soft';
20
+
21
+ /**
22
+ * Type of notification occurred type event.
23
+ * - `error`, indicates that a task or action has failed,
24
+ * - `success`, indicates that a task or action has completed successfully,
25
+ * - `warning`, indicates that a task or action produced a warning.
26
+ */
27
+ export type NotificationHapticFeedbackType = 'error' | 'success' | 'warning';
28
+
29
+ /**
30
+ * `impactOccurred` haptic feedback.
31
+ */
32
+ export type ImpactHapticFeedbackParams = CreateHapticFeedbackParams<'impact', {
33
+ impact_style: ImpactHapticFeedbackStyle;
34
+ }>;
35
+
36
+ /**
37
+ * `notificationOccurred` haptic feedback.
38
+ */
39
+ export type NotificationHapticFeedbackParams = CreateHapticFeedbackParams<'notification', {
40
+ notification_type: NotificationHapticFeedbackType;
41
+ }>;
42
+
43
+ /**
44
+ * `selectionChanged` haptic feedback.
45
+ */
46
+ // eslint-disable-next-line @typescript-eslint/ban-types
47
+ export type SelectionHapticFeedbackParams = CreateHapticFeedbackParams<'selection_change', {}>;
48
+
49
+ export type AnyHapticFeedbackParams =
50
+ | ImpactHapticFeedbackParams
51
+ | NotificationHapticFeedbackParams
52
+ | SelectionHapticFeedbackParams;
@@ -0,0 +1,5 @@
1
+ export type * from './haptic.js';
2
+ export type * from './invoke-custom-method.js';
3
+ export type * from './params.js';
4
+ export type * from './popup.js';
5
+ export * from './postEvent.js';
@@ -0,0 +1,25 @@
1
+ import type { RequestId } from '../shared.js';
2
+
3
+ interface CreateInvokeCustomMethodParams<M extends string, Params extends object> {
4
+ /**
5
+ * Unique request identifier.
6
+ */
7
+ req_id: RequestId;
8
+
9
+ /**
10
+ * Method name.
11
+ */
12
+ method: M;
13
+
14
+ /**
15
+ * Method specific parameters.
16
+ */
17
+ params: Params;
18
+ }
19
+
20
+ export type AnyInvokeCustomMethodParams =
21
+ | CreateInvokeCustomMethodParams<'deleteStorageValues', { keys: string | string[] }>
22
+ | CreateInvokeCustomMethodParams<'getStorageValues', { keys: string | string[] }>
23
+ | CreateInvokeCustomMethodParams<'getStorageKeys', {}>
24
+ | CreateInvokeCustomMethodParams<'saveStorageValue', { key: string, value: string }>
25
+ | CreateInvokeCustomMethodParams<string, any>;
@@ -0,0 +1,245 @@
1
+ import type { RGB } from '@tma.js/colors';
2
+ import type { IsNever, Not, UnionKeys } from '@tma.js/util-types';
3
+
4
+ import type { PopupParams } from './popup.js';
5
+ import type { AnyHapticFeedbackParams } from './haptic.js';
6
+ import type { RequestId } from '../shared.js';
7
+ import type { AnyInvokeCustomMethodParams } from './invoke-custom-method.js';
8
+
9
+ /**
10
+ * Color key which could be used tot update header color.
11
+ */
12
+ export type HeaderColorKey = 'bg_color' | 'secondary_bg_color';
13
+
14
+ type CreateParams<P = never, SupportCheckKey extends UnionKeys<P> = never> = {
15
+ params: P;
16
+ supportCheckKey: SupportCheckKey;
17
+ };
18
+
19
+ /**
20
+ * Describes list of events and their parameters that could be posted by
21
+ * Bridge.
22
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods
23
+ */
24
+ export interface MethodsParams {
25
+ /**
26
+ * Notifies parent iframe about current frame is ready.
27
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#iframe_ready
28
+ * @since 6.0
29
+ */
30
+ iframe_ready: CreateParams;
31
+
32
+ /**
33
+ * Closes WebApp.
34
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_close
35
+ * @since 6.0
36
+ */
37
+ web_app_close: CreateParams;
38
+
39
+ /**
40
+ * Closes QR scanner.
41
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_close_scan_qr_popup
42
+ * @since 6.4
43
+ */
44
+ web_app_close_scan_qr_popup: CreateParams;
45
+
46
+ /**
47
+ * Sends data to bot.
48
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_data_send
49
+ * @since 6.0
50
+ */
51
+ web_app_data_send: CreateParams<{ data: string }>;
52
+
53
+ /**
54
+ * Expands Web App.
55
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_expand
56
+ * @since 6.0
57
+ */
58
+ web_app_expand: CreateParams;
59
+
60
+ /**
61
+ * Invokes custom method.
62
+ * @since 6.9
63
+ */
64
+ web_app_invoke_custom_method: CreateParams<AnyInvokeCustomMethodParams>;
65
+
66
+ /**
67
+ * Opens new invoice.
68
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_open_invoice
69
+ * @since 6.1
70
+ */
71
+ web_app_open_invoice: CreateParams<{ slug: string }>;
72
+
73
+ /**
74
+ * Opens link in default browser. Doesn't close application.
75
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_open_link
76
+ * @since 6.0
77
+ */
78
+ web_app_open_link: CreateParams<{
79
+ url: string,
80
+
81
+ // TODO: Add to docs.
82
+ /**
83
+ * Link will be opened in Instant View mode if possible.
84
+ * @see https://instantview.telegram.org/
85
+ * @since 6.4
86
+ */
87
+ try_instant_view?: boolean;
88
+ }, 'try_instant_view'>;
89
+
90
+ /**
91
+ * Opens new popup.
92
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_open_popup
93
+ * @since 6.2
94
+ */
95
+ web_app_open_popup: CreateParams<PopupParams>;
96
+
97
+ /**
98
+ * Opens QR scanner.
99
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_open_scan_qr_popup
100
+ * @since 6.4
101
+ */
102
+ web_app_open_scan_qr_popup: CreateParams<{ text?: string }>;
103
+
104
+ /**
105
+ * Opens link which has format like "https://t.me/*".
106
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_open_tg_link
107
+ * @since 6.1
108
+ */
109
+ web_app_open_tg_link: CreateParams<{ path_full: string }>;
110
+
111
+ /**
112
+ * Reads text from clipboard.
113
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_read_text_from_clipboard
114
+ * @since 6.4
115
+ */
116
+ web_app_read_text_from_clipboard: CreateParams<{ req_id: RequestId }>;
117
+
118
+ /**
119
+ * Notifies Telegram about current application is ready to be shown.
120
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_ready
121
+ * @since 6.0
122
+ */
123
+ web_app_ready: CreateParams;
124
+
125
+ /**
126
+ * Requests access to current user's phone.
127
+ * @since 6.9
128
+ */
129
+ web_app_request_phone: CreateParams;
130
+
131
+ /**
132
+ * Requests current theme from Telegram.
133
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_request_theme
134
+ * @since 6.0
135
+ */
136
+ web_app_request_theme: CreateParams;
137
+
138
+ /**
139
+ * Requests current viewport information from Telegram.
140
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_request_viewport
141
+ * @since 6.0
142
+ */
143
+ web_app_request_viewport: CreateParams;
144
+
145
+ /**
146
+ * Requests write message access to current user.
147
+ * @since 6.9
148
+ */
149
+ web_app_request_write_access: CreateParams;
150
+
151
+ /**
152
+ * Updates current background color.
153
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_set_background_color
154
+ * @since 6.1
155
+ */
156
+ web_app_set_background_color: CreateParams<{ color: string }>;
157
+
158
+ /**
159
+ * Updates current header color.
160
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_set_header_color
161
+ * @since 6.1
162
+ */
163
+ web_app_set_header_color: CreateParams<
164
+ | { color_key: HeaderColorKey }
165
+ | {
166
+ /**
167
+ * @since 6.9
168
+ */
169
+ color: RGB
170
+ }, 'color'>;
171
+
172
+ /**
173
+ * Updates current information about back button.
174
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_setup_back_button
175
+ * @since 6.1
176
+ */
177
+ web_app_setup_back_button: CreateParams<{ is_visible: boolean }>;
178
+
179
+ /**
180
+ * Changes current closing confirmation requirement status.
181
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_setup_closing_behavior
182
+ * @since 6.0
183
+ */
184
+ web_app_setup_closing_behavior: CreateParams<{ need_confirmation: boolean }>;
185
+
186
+ /**
187
+ * Updates current information about main button.
188
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_setup_main_button
189
+ * @since 6.0
190
+ */
191
+ web_app_setup_main_button: CreateParams<{
192
+ is_visible?: boolean;
193
+ is_active?: boolean;
194
+ is_progress_visible?: boolean;
195
+ text?: string;
196
+ color?: string;
197
+ text_color?: string;
198
+ }>;
199
+
200
+ /**
201
+ * Generates haptic feedback event.
202
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_trigger_haptic_feedback
203
+ * @since 6.1
204
+ */
205
+ web_app_trigger_haptic_feedback: CreateParams<AnyHapticFeedbackParams>;
206
+ }
207
+
208
+ /**
209
+ * Any post-available event name.
210
+ */
211
+ export type MethodName = keyof MethodsParams;
212
+
213
+ /**
214
+ * Returns parameters for specified post-available event.
215
+ */
216
+ export type MethodParams<E extends MethodName> = MethodsParams[E]['params'];
217
+
218
+ /**
219
+ * Returns true in case, method has parameters.
220
+ */
221
+ export type MethodHasParams<M extends MethodName> = Not<IsNever<MethodParams<M>>>;
222
+
223
+ /**
224
+ * Any post-available event name which does not require arguments.
225
+ */
226
+ export type EmptyMethodName = {
227
+ [E in MethodName]: IsNever<MethodParams<E>> extends true ? E : never;
228
+ }[MethodName];
229
+
230
+ /**
231
+ * Any post-available event name which require arguments.
232
+ */
233
+ export type NonEmptyMethodName = Exclude<MethodName, EmptyMethodName>;
234
+
235
+ /**
236
+ * Method names which could be used in supportsParam method.
237
+ */
238
+ export type HasCheckSupportMethodName = {
239
+ [E in MethodName]: IsNever<MethodsParams[E]['supportCheckKey']> extends true ? never : E;
240
+ }[MethodName];
241
+
242
+ /**
243
+ * Method parameter which can be checked via support method.
244
+ */
245
+ export type HasCheckSupportMethodParam<M extends HasCheckSupportMethodName> = MethodsParams[M]['supportCheckKey'];
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Describes the native popup.
3
+ * @see https://core.telegram.org/bots/webapps#popupparams
4
+ */
5
+ export interface PopupParams {
6
+ /**
7
+ * The text to be displayed in the popup title, 0-64 characters.
8
+ */
9
+ title: string;
10
+
11
+ /**
12
+ * The message to be displayed in the body of the popup, 1-256 characters.
13
+ */
14
+ message: string;
15
+
16
+ /**
17
+ * List of buttons to be displayed in the popup, 1-3 buttons.
18
+ */
19
+ buttons: PopupButton[];
20
+ }
21
+
22
+ /**
23
+ * Describes the native popup button.
24
+ * @see https://core.telegram.org/bots/webapps#popupbutton
25
+ */
26
+ export type PopupButton = {
27
+ /**
28
+ * Identifier of the button, 0-64 characters.
29
+ */
30
+ id: string;
31
+ } & (
32
+ {
33
+ /**
34
+ * Type of the button:
35
+ * - `default`, a button with the default style;
36
+ * - `destructive`, a button with a style that indicates a destructive
37
+ * action (e.g. "Remove", "Delete", etc.).
38
+ *
39
+ * @default "default"
40
+ */
41
+ type?: 'default' | 'destructive';
42
+
43
+ /**
44
+ * The text to be displayed on the button, 0-64 characters.
45
+ */
46
+ text: string;
47
+ } | {
48
+ /**
49
+ * Type of the button:
50
+ * - `ok`, a button with the localized text "OK";
51
+ * - `close`, a button with the localized text "Close";
52
+ * - `cancel`, a button with the localized text "Cancel".
53
+ */
54
+ type: 'ok' | 'close' | 'cancel';
55
+ });
@@ -0,0 +1,103 @@
1
+ import {
2
+ isIframe,
3
+ hasExternalNotify,
4
+ hasWebviewProxy,
5
+ } from '../env.js';
6
+ import { targetOrigin as globalTargetOrigin } from '../globals.js';
7
+
8
+ import type {
9
+ EmptyMethodName,
10
+ MethodName,
11
+ MethodParams,
12
+ NonEmptyMethodName,
13
+ } from './params.js';
14
+
15
+ interface PostEventOptions {
16
+ /**
17
+ * Origin used while posting message. This option is only used in case,
18
+ * current environment is browser (Web version of Telegram) and could
19
+ * be used for test purposes.
20
+ * @default 'https://web.telegram.org'
21
+ */
22
+ targetOrigin?: string;
23
+ }
24
+
25
+ export type PostEvent = typeof postEvent;
26
+
27
+ /**
28
+ * Sends event to native application which launched Web App. This function
29
+ * accepts only events, which require arguments.
30
+ * @param eventType - event name.
31
+ * @param params - event parameters.
32
+ * @param options - posting options.
33
+ * @throws {Error} Bridge could not determine current
34
+ * environment and possible way to send event.
35
+ */
36
+ export function postEvent<E extends NonEmptyMethodName>(
37
+ eventType: E,
38
+ params: MethodParams<E>,
39
+ options?: PostEventOptions,
40
+ ): void;
41
+
42
+ /**
43
+ * Sends event to native application which launched Web App. This function
44
+ * accepts only events, which require arguments.
45
+ * @param eventType - event name.
46
+ * @param options - posting options.
47
+ * @throws {Error} Bridge could not determine current
48
+ * environment and possible way to send event.
49
+ */
50
+ export function postEvent(eventType: EmptyMethodName, options?: PostEventOptions): void;
51
+
52
+ export function postEvent(
53
+ eventType: MethodName,
54
+ paramsOrOptions?: MethodParams<MethodName> | PostEventOptions,
55
+ options?: PostEventOptions,
56
+ ): void {
57
+ let postOptions: PostEventOptions = {};
58
+ let eventData: any;
59
+
60
+ if (paramsOrOptions === undefined && options === undefined) {
61
+ // Parameters and options were not passed.
62
+ postOptions = {};
63
+ } else if (paramsOrOptions !== undefined && options !== undefined) {
64
+ // Both parameters and options passed.
65
+ postOptions = options;
66
+ eventData = paramsOrOptions;
67
+ } else if (paramsOrOptions !== undefined) {
68
+ // Only parameters were passed.
69
+ if ('targetOrigin' in paramsOrOptions) {
70
+ postOptions = paramsOrOptions;
71
+ } else {
72
+ eventData = paramsOrOptions;
73
+ }
74
+ }
75
+ const { targetOrigin = globalTargetOrigin() } = postOptions;
76
+
77
+ // Telegram Web.
78
+ if (isIframe()) {
79
+ window.parent.postMessage(JSON.stringify({
80
+ eventType,
81
+ eventData,
82
+ }), targetOrigin);
83
+ return;
84
+ }
85
+
86
+ // Telegram for Windows Phone or Android.
87
+ if (hasExternalNotify(window)) {
88
+ window.external.notify(JSON.stringify({ eventType, eventData }));
89
+ return;
90
+ }
91
+
92
+ // Telegram for iOS and macOS.
93
+ if (hasWebviewProxy(window)) {
94
+ window.TelegramWebviewProxy.postEvent(eventType, JSON.stringify(eventData));
95
+ return;
96
+ }
97
+
98
+ // Otherwise current environment is unknown, and we are not able to send
99
+ // event.
100
+ throw new Error(
101
+ 'Unable to determine current environment and possible way to send event.',
102
+ );
103
+ }