@tma.js/bridge 1.3.4 → 1.3.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.
@@ -185,6 +185,14 @@ export interface MethodsParams {
185
185
  color?: string;
186
186
  text_color?: string;
187
187
  }>;
188
+ /**
189
+ * Updates current information about Settings Button.
190
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_setup_settings_button
191
+ * @since 6.10
192
+ */
193
+ web_app_setup_settings_button: CreateParams<{
194
+ is_visible: boolean;
195
+ }>;
188
196
  /**
189
197
  * Generates haptic feedback event.
190
198
  * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_trigger_haptic_feedback
package/dist/index.js CHANGED
@@ -137,24 +137,24 @@ function Z() {
137
137
  }
138
138
  }), e;
139
139
  }
140
- function d() {
140
+ function p() {
141
141
  const e = window;
142
142
  return e[b] === void 0 && (e[b] = Z()), e[b];
143
143
  }
144
144
  function W(e, t) {
145
- d().off(e, t);
145
+ p().off(e, t);
146
146
  }
147
- function V(e, t) {
148
- return d().on(e, t), () => W(e, t);
147
+ function D(e, t) {
148
+ return p().on(e, t), () => W(e, t);
149
149
  }
150
150
  function _e(e, t) {
151
- return d().once(e, t), () => W(e, t);
151
+ return p().once(e, t), () => W(e, t);
152
152
  }
153
- function D(e) {
154
- d().unsubscribe(e);
153
+ function V(e) {
154
+ p().unsubscribe(e);
155
155
  }
156
156
  function ue(e) {
157
- return d().subscribe(e), () => D(e);
157
+ return p().subscribe(e), () => V(e);
158
158
  }
159
159
  function O(e) {
160
160
  return "external" in e && l(e.external) && "notify" in e.external && typeof e.external.notify == "function";
@@ -192,12 +192,12 @@ function re(e, t, r) {
192
192
  "Unable to determine current environment and possible way to send event."
193
193
  );
194
194
  }
195
- function de(e, t, r, n) {
195
+ function pe(e, t, r, n) {
196
196
  let o, c, f, w;
197
197
  typeof t == "string" || Array.isArray(t) ? (f = Array.isArray(t) ? t : [t], o = r) : (c = t, f = Array.isArray(r) ? r : [r], o = n), l(c) && typeof c.req_id == "string" && (w = c.req_id);
198
198
  const { postEvent: A = re, timeout: h } = o || {}, m = o && "capture" in o ? o.capture : null, y = new Promise((R, C) => {
199
- const N = f.map((u) => V(u, (p) => {
200
- typeof w == "string" && (!l(p) || p.req_id !== w) || typeof m == "function" && !m(p) || (E(), R(p));
199
+ const N = f.map((u) => D(u, (d) => {
200
+ typeof w == "string" && (!l(d) || d.req_id !== w) || typeof m == "function" && !m(d) || (E(), R(d));
201
201
  })), E = () => N.forEach((u) => u());
202
202
  try {
203
203
  A(e, c);
@@ -210,7 +210,7 @@ function de(e, t, r, n) {
210
210
  function _(e, t) {
211
211
  return J(e, t) <= 0;
212
212
  }
213
- function pe(e, t) {
213
+ function de(e, t) {
214
214
  return e === "web_app_open_link" && "try_instant_view" in t ? ["try_instant_view"] : e === "web_app_set_header_color" && "color" in t ? ["color"] : [];
215
215
  }
216
216
  function le(e, t, r) {
@@ -238,24 +238,26 @@ function le(e, t, r) {
238
238
  case "web_app_request_write_access":
239
239
  case "web_app_request_phone":
240
240
  return _("6.9", t);
241
+ case "web_app_setup_settings_button":
242
+ return _("6.10", t);
241
243
  default:
242
244
  return !0;
243
245
  }
244
246
  }
245
247
  export {
246
- pe as detectSupportParams,
248
+ de as detectSupportParams,
247
249
  O as hasExternalNotify,
248
250
  ee as hasWebviewProxy,
249
251
  te as isIframe,
250
252
  W as off,
251
- V as on,
253
+ D as on,
252
254
  _e as once,
253
255
  re as postEvent,
254
- de as request,
256
+ pe as request,
255
257
  ce as setDebug,
256
258
  ae as setTargetOrigin,
257
259
  ue as subscribe,
258
260
  le as supports,
259
- D as unsubscribe
261
+ V as unsubscribe
260
262
  };
261
263
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/globals.ts","../src/events/parsing.ts","../src/events/onTelegramEvent.ts","../src/events/emitter.ts","../src/events/off.ts","../src/events/on.ts","../src/events/once.ts","../src/events/unsubscribe.ts","../src/events/subscribe.ts","../src/env.ts","../src/methods/postEvent.ts","../src/request.ts","../src/supports.ts"],"sourcesContent":["import { log as utilLog } from '@tma.js/logger';\n\nlet currentDebug = false;\nlet currentTargetOrigin = 'https://web.telegram.org';\n\n/**\n * Sets new debug mode. Enabling debug mode leads to printing\n * additional messages in console, related to the processes\n * inside the package.\n * @param value - should debug mode be enabled.\n */\nexport function setDebug(value: boolean): void {\n currentDebug = value;\n}\n\n/**\n * Sets new global targetOrigin, used by `postEvent` method.\n * Default value is \"https://web.telegram.org\". You don't need to\n * use this method until you know what you are doing.\n *\n * This method could be used for test purposes.\n * @param value - new target origin.\n */\nexport function setTargetOrigin(value: string): void {\n currentTargetOrigin = value;\n}\n\n/**\n * Returns current global target origin.\n */\nexport function targetOrigin(): string {\n return currentTargetOrigin;\n}\n\n/**\n * Logs message in case, debug mode is enabled.\n * @param level - log level\n * @param args - values to print.\n */\nexport const log: typeof utilLog = (level, ...args) => {\n if (currentDebug) {\n utilLog(level, '[Bridge]', ...args);\n }\n};\n","import {\n number,\n string,\n boolean,\n json,\n rgb,\n} from '@tma.js/parsing';\n\nimport type {\n ClipboardTextReceivedPayload, CustomMethodInvokedPayload,\n InvoiceClosedPayload, PhoneRequestedPayload,\n PopupClosedPayload, QrTextReceivedPayload,\n ThemeChangedPayload,\n ViewportChangedPayload, WriteAccessRequestedPayload,\n} from './payloads.js';\n\nfunction isNullOrUndefined(value: unknown): boolean {\n return value === null || value === undefined;\n}\n\n/**\n * Parses incoming value as ThemeChangedPayload.\n */\nexport const themeChangedPayload = json<ThemeChangedPayload>({\n theme_params: json<ThemeChangedPayload['theme_params']>({\n bg_color: rgb().optional(),\n text_color: rgb().optional(),\n hint_color: rgb().optional(),\n link_color: rgb().optional(),\n button_color: rgb().optional(),\n button_text_color: rgb().optional(),\n secondary_bg_color: rgb().optional(),\n }),\n});\n\n/**\n * Parses incoming value as ViewportChangedPayload.\n * @param value - value to parse.\n */\nexport const viewportChangedPayload = json<ViewportChangedPayload>({\n height: number(),\n width: number().optional(isNullOrUndefined).default(() => window.innerWidth),\n is_state_stable: boolean(),\n is_expanded: boolean(),\n});\n\n/**\n * Parses incoming value as PopupClosedPayload.\n */\nexport const popupClosedPayload = json<PopupClosedPayload>({\n button_id: string().optional(isNullOrUndefined),\n});\n\n/**\n * Parses incoming value as QrTextReceivedPayload.\n */\nexport const qrTextReceivedPayload = json<QrTextReceivedPayload>({\n data: string().optional(),\n});\n\n/**\n * Parses incoming value as InvoiceClosedPayload.\n */\nexport const invoiceClosedPayload = json<InvoiceClosedPayload>({\n slug: string(),\n status: string(),\n});\n\n/**\n * Parses incoming value as clipboard text received payload.\n */\nexport const clipboardTextReceivedPayload = json<ClipboardTextReceivedPayload>({\n req_id: string(),\n data: (value) => (value === null ? value : string().optional().parse(value)),\n});\n\n/**\n * Parses incoming value as WriteAccessRequestedPayload.\n */\nexport const writeAccessRequestedPayload = json<WriteAccessRequestedPayload>({ status: string() });\n\n/**\n * Parses incoming value as PhoneRequestedPayload.\n */\nexport const phoneRequestedPayload = json<PhoneRequestedPayload>({ status: string() });\n\n/**\n * Parses incoming value as CustomMethodInvokedPayload.\n */\nexport const customMethodInvokedPayload = json<CustomMethodInvokedPayload>({\n req_id: string(),\n result: (value) => value,\n error: string().optional(),\n});\n","import { json, string } from '@tma.js/parsing';\n\n/**\n * Extracts event data from native application event.\n */\nconst eventDataJson = json<{ eventType: string; eventData?: unknown }>({\n eventType: string(),\n eventData: (value) => value,\n});\n\n/**\n * Emits event sent from Telegram native application like it was sent in\n * default web environment between 2 iframes. It dispatches new MessageEvent\n * and expects it to be handled via `window.addEventListener('message', ...)`\n * as developer would do it to handle messages sent from parent iframe.\n * @param eventType - event name.\n * @param eventData - event payload.\n */\nfunction emitEvent(eventType: string, eventData: unknown): void {\n window.dispatchEvent(new MessageEvent('message', {\n data: JSON.stringify({ eventType, eventData }),\n }));\n}\n\n/**\n * Defines special handlers by known paths, which are recognized by\n * Telegram as ports to receive events. This function also sets special\n * function in global window object to prevent duplicate declaration.\n */\nfunction defineEventHandlers(): void {\n const wnd: any = window;\n\n // Prevent from duplicate event handlers definition.\n if ('TelegramGameProxy_receiveEvent' in wnd) {\n return;\n }\n\n // Iterate over each path, where \"receiveEvent\" function should be\n // defined. This function is called by external environment in case,\n // it wants to emit some event.\n [\n ['TelegramGameProxy_receiveEvent'], // Windows Phone.\n ['TelegramGameProxy', 'receiveEvent'], // Desktop.\n ['Telegram', 'WebView', 'receiveEvent'], // Android and iOS.\n ].forEach((path) => {\n // Path starts from \"window\" object.\n let pointer = wnd;\n\n path.forEach((item, idx, arr) => {\n // We are on the last iteration, where function property name is passed.\n if (idx === arr.length - 1) {\n pointer[item] = emitEvent;\n return;\n }\n\n if (!(item in pointer)) {\n pointer[item] = {};\n }\n pointer = pointer[item];\n });\n });\n}\n\n/**\n * Adds listener to window \"message\" event assuming, that this event could\n * be sent by Telegram native application. Calls passed callback with event\n * type and data.\n * @param cb - callback to call.\n */\nexport function onTelegramEvent(cb: (eventType: string, eventData: unknown) => void): void {\n // Define event handlers to make sure, message handler will work correctly.\n defineEventHandlers();\n\n // We expect Telegram to send us new event through \"message\" event.\n window.addEventListener('message', (event) => {\n try {\n const { eventType, eventData } = eventDataJson.parse(event.data);\n cb(eventType, eventData);\n } catch {\n // We ignore incorrect messages as they could be generated by any other code.\n }\n });\n}\n","import { EventEmitter as UtilEventEmitter } from '@tma.js/event-emitter';\nimport { string } from '@tma.js/parsing';\n\nimport { log } from '../globals.js';\nimport {\n clipboardTextReceivedPayload,\n customMethodInvokedPayload,\n invoiceClosedPayload,\n phoneRequestedPayload,\n popupClosedPayload,\n qrTextReceivedPayload,\n themeChangedPayload,\n viewportChangedPayload,\n writeAccessRequestedPayload,\n} from './parsing.js';\nimport { onTelegramEvent } from './onTelegramEvent.js';\n\nimport type { EventEmitter, EventName } from './events.js';\n\nconst CACHED_EMITTER = '__telegram-cached-emitter__';\n\n/**\n * Returns event emitter which could be safely used, to process events from\n * Telegram native application.\n */\nexport function createEmitter(): EventEmitter {\n const emitter: EventEmitter = new UtilEventEmitter();\n const emit: EventEmitter['emit'] = (event: any, ...data: any[]) => {\n log('log', 'Emitting processed event:', event, ...data);\n emitter.emit(event, ...data);\n };\n\n // Desktop version of Telegram is sometimes not sending the viewport_changed\n // event. For example, when main button is shown. That's why we should\n // add our own listener to make sure, viewport information is always fresh.\n // Issue: https://github.com/Telegram-Web-Apps/tma.js/issues/10\n window.addEventListener('resize', () => {\n emit('viewport_changed', {\n width: window.innerWidth,\n height: window.innerHeight,\n is_state_stable: true,\n is_expanded: true,\n });\n });\n\n // In case, any Telegram event was received, we should prepare data before\n // passing it to emitter.\n onTelegramEvent((eventType: EventName | string, eventData): void => {\n log('log', 'Received raw event:', eventType, eventData);\n\n try {\n switch (eventType) {\n case 'viewport_changed':\n return emit(eventType, viewportChangedPayload.parse(eventData));\n\n case 'theme_changed':\n return emit(eventType, themeChangedPayload.parse(eventData));\n\n case 'popup_closed':\n // FIXME: Payloads are different on different platforms.\n // Issue: https://github.com/Telegram-Web-Apps/tma.js/issues/2\n if (\n // Sent on desktop.\n eventData === undefined\n // Sent on iOS.\n || eventData === null\n ) {\n return emit(eventType, {});\n }\n return emit(eventType, popupClosedPayload.parse(eventData));\n\n case 'set_custom_style':\n return emit(eventType, string().parse(eventData));\n\n case 'qr_text_received':\n return emit(eventType, qrTextReceivedPayload.parse(eventData));\n\n case 'clipboard_text_received':\n return emit(eventType, clipboardTextReceivedPayload.parse(eventData));\n\n case 'invoice_closed':\n return emit(eventType, invoiceClosedPayload.parse(eventData));\n\n case 'phone_requested':\n return emit('phone_requested', phoneRequestedPayload.parse(eventData));\n\n case 'custom_method_invoked':\n return emit('custom_method_invoked', customMethodInvokedPayload.parse(eventData));\n\n case 'write_access_requested':\n return emit('write_access_requested', writeAccessRequestedPayload.parse(eventData));\n\n // Events which have no parameters.\n case 'main_button_pressed':\n case 'back_button_pressed':\n case 'settings_button_pressed':\n case 'scan_qr_popup_closed':\n return emit(eventType);\n\n // All other event listeners will receive unknown type of data.\n default:\n return emit(eventType as any, eventData);\n }\n } catch (cause) {\n log('error', 'Error processing event:', cause);\n }\n });\n\n return emitter;\n}\n\n/**\n * Returns singleton instance of bridge EventEmitter. Also, defines\n * Telegram event handlers.\n */\nexport function singletonEmitter(): EventEmitter {\n const wnd: any = window;\n const cachedEmitter = wnd[CACHED_EMITTER];\n\n if (cachedEmitter === undefined) {\n wnd[CACHED_EMITTER] = createEmitter();\n }\n\n return wnd[CACHED_EMITTER];\n}\n","import { singletonEmitter } from './emitter.js';\n\nimport type { EventName, EventListener } from './events.js';\n\n/**\n * Removes listener from specified event.\n * @param event - event to listen.\n * @param listener - event listener.\n */\nexport function off<E extends EventName>(event: E, listener: EventListener<E>): void {\n singletonEmitter().off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { off } from './off.js';\n\nimport type { EventName, EventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Adds new listener to the specified event. Returns handler\n * which allows to stop listening to event.\n * @param event - event name.\n * @param listener - event listener.\n */\nexport function on<E extends EventName>(event: E, listener: EventListener<E>): StopListening {\n singletonEmitter().on(event, listener);\n return () => off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { off } from './off.js';\n\nimport type { EventName, EventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Works the same as \"on\" method, but after catching the event, will remove event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\nexport function once<E extends EventName>(event: E, listener: EventListener<E>): StopListening {\n singletonEmitter().once(event, listener);\n return () => off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\n\nimport type { GlobalEventListener } from './events.js';\n\n/**\n * Removes global event listener.\n * @param listener - event listener.\n */\nexport function unsubscribe(listener: GlobalEventListener): void {\n singletonEmitter().unsubscribe(listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { unsubscribe } from './unsubscribe.js';\n\nimport type { GlobalEventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Subscribes to all events sent from the native Telegram application.\n * Returns function used to remove added event listener.\n * @param listener - event listener.\n */\nexport function subscribe(listener: GlobalEventListener): StopListening {\n singletonEmitter().subscribe(listener);\n return () => unsubscribe(listener);\n}\n","import { isRecord } from '@tma.js/utils';\n\ntype AnyFunc = (...args: unknown[]) => unknown;\n\ntype WithExternalNotify<T> = T & {\n external: { notify: AnyFunc }\n};\n\ntype WithWebviewProxy<T> = T & {\n TelegramWebviewProxy: {\n postEvent: AnyFunc;\n }\n};\n\n/**\n * Returns true in case, passed value contains path `external.notify` property and `notify` is a\n * function.\n * @param value - value to check.\n */\nexport function hasExternalNotify<T extends {}>(value: T): value is WithExternalNotify<T> {\n return 'external' in value\n && isRecord(value.external)\n && 'notify' in value.external\n && typeof value.external.notify === 'function';\n}\n\n/**\n * Returns true in case, passed value contains path `TelegramWebviewProxy.postEvent` property and\n * `postEvent` is a function.\n * @param value - value to check.\n */\nexport function hasWebviewProxy<T extends {}>(value: T): value is WithWebviewProxy<T> {\n return 'TelegramWebviewProxy' in value\n && isRecord(value.TelegramWebviewProxy)\n && 'postEvent' in value.TelegramWebviewProxy\n && typeof value.TelegramWebviewProxy.postEvent === 'function';\n}\n\n/**\n * Returns true in case, current environment is iframe.\n * @see https://stackoverflow.com/a/326076\n */\nexport function isIframe(): boolean {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n}\n","import {\n isIframe,\n hasExternalNotify,\n hasWebviewProxy,\n} from '../env.js';\nimport { targetOrigin as globalTargetOrigin } from '../globals.js';\n\nimport type {\n EmptyMethodName,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './params.js';\n\ninterface PostEventOptions {\n /**\n * Origin used while posting message. This option is only used in case,\n * current environment is browser (Web version of Telegram) and could\n * be used for test purposes.\n * @default 'https://web.telegram.org'\n */\n targetOrigin?: string;\n}\n\nexport type PostEvent = typeof postEvent;\n\n/**\n * Sends event to native application which launched Web App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param params - event parameters.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current\n * environment and possible way to send event.\n */\nexport function postEvent<E extends NonEmptyMethodName>(\n eventType: E,\n params: MethodParams<E>,\n options?: PostEventOptions,\n): void;\n\n/**\n * Sends event to native application which launched Web App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current\n * environment and possible way to send event.\n */\nexport function postEvent(eventType: EmptyMethodName, options?: PostEventOptions): void;\n\nexport function postEvent(\n eventType: MethodName,\n paramsOrOptions?: MethodParams<MethodName> | PostEventOptions,\n options?: PostEventOptions,\n): void {\n let postOptions: PostEventOptions = {};\n let eventData: any;\n\n if (paramsOrOptions === undefined && options === undefined) {\n // Parameters and options were not passed.\n postOptions = {};\n } else if (paramsOrOptions !== undefined && options !== undefined) {\n // Both parameters and options passed.\n postOptions = options;\n eventData = paramsOrOptions;\n } else if (paramsOrOptions !== undefined) {\n // Only parameters were passed.\n if ('targetOrigin' in paramsOrOptions) {\n postOptions = paramsOrOptions;\n } else {\n eventData = paramsOrOptions;\n }\n }\n const { targetOrigin = globalTargetOrigin() } = postOptions;\n\n // Telegram Web.\n if (isIframe()) {\n window.parent.postMessage(JSON.stringify({\n eventType,\n eventData,\n }), targetOrigin);\n return;\n }\n\n // Telegram for Windows Phone or Android.\n if (hasExternalNotify(window)) {\n window.external.notify(JSON.stringify({ eventType, eventData }));\n return;\n }\n\n // Telegram for iOS and macOS.\n if (hasWebviewProxy(window)) {\n window.TelegramWebviewProxy.postEvent(eventType, JSON.stringify(eventData));\n return;\n }\n\n // Otherwise current environment is unknown, and we are not able to send\n // event.\n throw new Error(\n 'Unable to determine current environment and possible way to send event.',\n );\n}\n","import { withTimeout, isRecord } from '@tma.js/utils';\n\nimport type { And, If, IsNever } from '@tma.js/util-types';\n\nimport { postEvent as defaultPostEvent, type PostEvent } from './methods/postEvent.js';\nimport { on, type EventName, type EventParams, type EventHasParams } from './events/index.js';\n\nimport type {\n EmptyMethodName, MethodHasParams,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './methods/params.js';\n\n/**\n * Names of methods, which require passing \"req_id\" parameter.\n */\ntype MethodNameWithRequestId = {\n [Method in MethodName]: If<\n And<MethodHasParams<Method>, MethodParams<Method> extends { req_id: string } ? true : false>,\n Method,\n never\n >;\n}[MethodName];\n\n/**\n * Names of events, which contain \"req_id\" parameter.\n */\ntype EventNameWithRequestId = {\n [Event in EventName]: If<\n And<EventHasParams<Event>, EventParams<Event> extends { req_id: string } ? true : false>,\n Event,\n never\n >;\n}[EventName];\n\nexport interface RequestOptions {\n /**\n * Bridge postEvent method.\n * @default Global postEvent method.\n */\n postEvent?: PostEvent;\n\n /**\n * Execution timeout.\n */\n timeout?: number;\n}\n\nexport interface RequestOptionsAdvanced<EventPayload> extends RequestOptions {\n /**\n * Should return true in case, this event should be captured. If not specified,\n * request is not skipping captured events.\n */\n capture?: If<IsNever<EventPayload>, () => boolean, (payload: EventPayload) => boolean>;\n}\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, event with specified in method request identifier\n * was captured.\n * @param method - method to execute.\n * @param params - method parameters.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<\n Method extends MethodNameWithRequestId,\n Event extends EventNameWithRequestId,\n>(\n method: Method,\n params: MethodParams<Method>,\n event: Event | Event[],\n options?: RequestOptions,\n): Promise<EventParams<Event>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<Method extends EmptyMethodName, Event extends EventName>(\n method: Method,\n event: Event | Event[],\n options?: RequestOptionsAdvanced<EventParams<Event>>,\n): Promise<EventParams<Event>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute\n * @param params - method parameters.\n * @param event - event or events to listen\n * @param options - additional execution options.\n */\nexport function request<Method extends NonEmptyMethodName, Event extends EventName>(\n method: Method,\n params: MethodParams<Method>,\n event: Event | Event[],\n options?: RequestOptionsAdvanced<EventParams<Event>>,\n): Promise<EventParams<Event>>;\n\nexport function request(\n method: MethodName,\n eventOrParams: EventName | EventName[] | EventParams<any>,\n eventOrOptions?: EventName | EventName[] | RequestOptions | RequestOptionsAdvanced<any>,\n options?: RequestOptions | RequestOptionsAdvanced<any>,\n): Promise<any> {\n let executionOptions: RequestOptions | RequestOptionsAdvanced<any> | undefined;\n let methodParams: EventParams<any> | undefined;\n let events: EventName[];\n let requestId: string | undefined;\n\n if (typeof eventOrParams === 'string' || Array.isArray(eventOrParams)) {\n // Override: [method, event, options?]\n events = Array.isArray(eventOrParams) ? eventOrParams : [eventOrParams] as EventName[];\n executionOptions = eventOrOptions as (RequestOptionsAdvanced<any> | undefined);\n } else {\n // Override: [method, params, event, options?]\n methodParams = eventOrParams as EventParams<any>;\n events = Array.isArray(eventOrOptions) ? eventOrOptions : [eventOrOptions] as EventName[];\n executionOptions = options;\n }\n\n // In case, method parameters were passed, and they contained request identifier, we should store\n // it and wait for the event with this identifier to occur.\n if (isRecord(methodParams) && typeof methodParams.req_id === 'string') {\n requestId = methodParams.req_id;\n }\n\n const { postEvent = defaultPostEvent, timeout } = executionOptions || {};\n const capture = executionOptions && 'capture' in executionOptions\n ? executionOptions.capture\n : null;\n\n const promise = new Promise((res, rej) => {\n // Iterate over each event and create event listener.\n const stoppers = events.map((ev) => on(ev, (data?) => {\n // If request identifier was specified, we are waiting for event with the same value\n // to occur.\n if (typeof requestId === 'string' && (!isRecord(data) || data.req_id !== requestId)) {\n return;\n }\n\n if (typeof capture === 'function' && !capture(data)) {\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n stopListening();\n res(data);\n }));\n\n // Function which removes all event listeners.\n const stopListening = () => stoppers.forEach((stop) => stop());\n\n try {\n // We are wrapping this call in try catch, because it can throw errors in case,\n // compatibility check was enabled. We want an error to be captured by promise, not by\n // another one external try catch.\n postEvent(method as any, methodParams);\n } catch (e) {\n stopListening();\n rej(e);\n }\n });\n\n return typeof timeout === 'number' ? withTimeout(promise, timeout) : promise;\n}\n","import { compareVersions, type Version } from '@tma.js/utils';\n\nimport type {\n HasCheckSupportMethodParam,\n HasCheckSupportMethodName,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './methods/index.js';\n\nfunction lessOrEqual(a: Version, b: Version): boolean {\n return compareVersions(a, b) <= 0;\n}\n\n/**\n * By specified method and parameters extracts properties which could be used by\n * supports function as TWA method parameter.\n * @param method - TWA method.\n * @param params - method parameters.\n */\nexport function detectSupportParams<M extends NonEmptyMethodName>(\n method: M,\n params: MethodParams<M>,\n): HasCheckSupportMethodParam<HasCheckSupportMethodName>[] {\n if (method === 'web_app_open_link') {\n if ('try_instant_view' in params) {\n return ['try_instant_view'];\n }\n }\n\n if (method === 'web_app_set_header_color') {\n if ('color' in params) {\n return ['color'];\n }\n }\n\n return [];\n}\n\n/**\n * Returns true in case, passed parameter in specified method is supported.\n * @param method - method name\n * @param param - method parameter\n * @param inVersion - platform version.\n */\nexport function supports<M extends HasCheckSupportMethodName>(\n method: M,\n param: HasCheckSupportMethodParam<M>,\n inVersion: Version,\n): boolean;\n/**\n * Returns true in case, specified method is supported in passed version.\n * @param method - method name.\n * @param inVersion - platform version.\n */\nexport function supports(method: MethodName, inVersion: Version): boolean;\nexport function supports(\n method: MethodName,\n paramOrVersion: Version | string,\n inVersion?: string,\n): boolean {\n // Method name, parameter, target version.\n if (typeof inVersion === 'string') {\n if (method === 'web_app_open_link') {\n if (paramOrVersion === 'try_instant_view') {\n return lessOrEqual('6.4', inVersion);\n }\n }\n\n if (method === 'web_app_set_header_color') {\n if (paramOrVersion === 'color') {\n return lessOrEqual('6.9', inVersion);\n }\n }\n }\n\n // Method name, target version.\n switch (method) {\n case 'web_app_open_tg_link':\n case 'web_app_open_invoice':\n case 'web_app_setup_back_button':\n case 'web_app_set_background_color':\n case 'web_app_set_header_color':\n case 'web_app_trigger_haptic_feedback':\n return lessOrEqual('6.1', paramOrVersion);\n case 'web_app_open_popup':\n return lessOrEqual('6.2', paramOrVersion);\n case 'web_app_close_scan_qr_popup':\n case 'web_app_open_scan_qr_popup':\n case 'web_app_read_text_from_clipboard':\n return lessOrEqual('6.4', paramOrVersion);\n case 'web_app_invoke_custom_method':\n case 'web_app_request_write_access':\n case 'web_app_request_phone':\n return lessOrEqual('6.9', paramOrVersion);\n default:\n return true;\n }\n}\n"],"names":["currentDebug","currentTargetOrigin","setDebug","value","setTargetOrigin","targetOrigin","log","level","args","utilLog","isNullOrUndefined","themeChangedPayload","json","rgb","viewportChangedPayload","number","boolean","popupClosedPayload","string","qrTextReceivedPayload","invoiceClosedPayload","clipboardTextReceivedPayload","writeAccessRequestedPayload","phoneRequestedPayload","customMethodInvokedPayload","eventDataJson","emitEvent","eventType","eventData","defineEventHandlers","wnd","path","pointer","item","idx","arr","onTelegramEvent","cb","event","CACHED_EMITTER","createEmitter","emitter","UtilEventEmitter","emit","data","cause","singletonEmitter","off","listener","on","once","unsubscribe","subscribe","hasExternalNotify","isRecord","hasWebviewProxy","isIframe","postEvent","paramsOrOptions","options","postOptions","globalTargetOrigin","request","method","eventOrParams","eventOrOptions","executionOptions","methodParams","events","requestId","defaultPostEvent","timeout","capture","promise","res","rej","stoppers","ev","stopListening","stop","e","withTimeout","lessOrEqual","a","b","compareVersions","detectSupportParams","params","supports","paramOrVersion","inVersion"],"mappings":";;;;AAEA,IAAIA,IAAe,IACfC,IAAsB;AAQnB,SAASC,GAASC,GAAsB;AAC9B,EAAAH,IAAAG;AACjB;AAUO,SAASC,GAAgBD,GAAqB;AAC7B,EAAAF,IAAAE;AACxB;AAKO,SAASE,IAAuB;AAC9B,SAAAJ;AACT;AAOa,MAAAK,IAAsB,CAACC,MAAUC,MAAS;AACrD,EAAIR,KACMS,EAAAF,GAAO,YAAY,GAAGC,CAAI;AAEtC;AC3BA,SAASE,EAAkBP,GAAyB;AAC3C,SAAAA,KAAU;AACnB;AAKO,MAAMQ,IAAsBC,EAA0B;AAAA,EAC3D,cAAcA,EAA0C;AAAA,IACtD,UAAUC,EAAI,EAAE,SAAS;AAAA,IACzB,YAAYA,EAAI,EAAE,SAAS;AAAA,IAC3B,YAAYA,EAAI,EAAE,SAAS;AAAA,IAC3B,YAAYA,EAAI,EAAE,SAAS;AAAA,IAC3B,cAAcA,EAAI,EAAE,SAAS;AAAA,IAC7B,mBAAmBA,EAAI,EAAE,SAAS;AAAA,IAClC,oBAAoBA,EAAI,EAAE,SAAS;AAAA,EAAA,CACpC;AACH,CAAC,GAMYC,IAAyBF,EAA6B;AAAA,EACjE,QAAQG,EAAO;AAAA,EACf,OAAOA,EAAS,EAAA,SAASL,CAAiB,EAAE,QAAQ,MAAM,OAAO,UAAU;AAAA,EAC3E,iBAAiBM,EAAQ;AAAA,EACzB,aAAaA,EAAQ;AACvB,CAAC,GAKYC,IAAqBL,EAAyB;AAAA,EACzD,WAAWM,EAAA,EAAS,SAASR,CAAiB;AAChD,CAAC,GAKYS,IAAwBP,EAA4B;AAAA,EAC/D,MAAMM,EAAO,EAAE,SAAS;AAC1B,CAAC,GAKYE,IAAuBR,EAA2B;AAAA,EAC7D,MAAMM,EAAO;AAAA,EACb,QAAQA,EAAO;AACjB,CAAC,GAKYG,IAA+BT,EAAmC;AAAA,EAC7E,QAAQM,EAAO;AAAA,EACf,MAAM,CAACf,MAAWA,MAAU,OAAOA,IAAQe,EAAA,EAAS,SAAA,EAAW,MAAMf,CAAK;AAC5E,CAAC,GAKYmB,IAA8BV,EAAkC,EAAE,QAAQM,EAAA,EAAU,CAAA,GAKpFK,IAAwBX,EAA4B,EAAE,QAAQM,EAAA,EAAU,CAAA,GAKxEM,IAA6BZ,EAAiC;AAAA,EACzE,QAAQM,EAAO;AAAA,EACf,QAAQ,CAACf,MAAUA;AAAA,EACnB,OAAOe,EAAO,EAAE,SAAS;AAC3B,CAAC,GCxFKO,IAAgBb,EAAiD;AAAA,EACrE,WAAWM,EAAO;AAAA,EAClB,WAAW,CAACf,MAAUA;AACxB,CAAC;AAUD,SAASuB,EAAUC,GAAmBC,GAA0B;AACvD,SAAA,cAAc,IAAI,aAAa,WAAW;AAAA,IAC/C,MAAM,KAAK,UAAU,EAAE,WAAAD,GAAW,WAAAC,GAAW;AAAA,EAC9C,CAAA,CAAC;AACJ;AAOA,SAASC,IAA4B;AACnC,QAAMC,IAAW;AAGjB,EAAI,oCAAoCA,KAOxC;AAAA,IACE,CAAC,gCAAgC;AAAA;AAAA,IACjC,CAAC,qBAAqB,cAAc;AAAA;AAAA,IACpC,CAAC,YAAY,WAAW,cAAc;AAAA;AAAA,EAAA,EACtC,QAAQ,CAACC,MAAS;AAElB,QAAIC,IAAUF;AAEd,IAAAC,EAAK,QAAQ,CAACE,GAAMC,GAAKC,MAAQ;AAE3B,UAAAD,MAAQC,EAAI,SAAS,GAAG;AAC1B,QAAAH,EAAQC,CAAI,IAAIP;AAChB;AAAA,MACF;AAEI,MAAEO,KAAQD,MACJA,EAAAC,CAAI,IAAI,KAElBD,IAAUA,EAAQC,CAAI;AAAA,IAAA,CACvB;AAAA,EAAA,CACF;AACH;AAQO,SAASG,EAAgBC,GAA2D;AAErE,EAAAR,KAGb,OAAA,iBAAiB,WAAW,CAACS,MAAU;AACxC,QAAA;AACF,YAAM,EAAE,WAAAX,GAAW,WAAAC,MAAcH,EAAc,MAAMa,EAAM,IAAI;AAC/D,MAAAD,EAAGV,GAAWC,CAAS;AAAA,IAAA,QACjB;AAAA,IAER;AAAA,EAAA,CACD;AACH;AC/DA,MAAMW,IAAiB;AAMhB,SAASC,IAA8B;AACtC,QAAAC,IAAwB,IAAIC,KAC5BC,IAA6B,CAACL,MAAeM,MAAgB;AACjE,IAAAtC,EAAI,OAAO,6BAA6BgC,GAAO,GAAGM,CAAI,GAC9CH,EAAA,KAAKH,GAAO,GAAGM,CAAI;AAAA,EAAA;AAOtB,gBAAA,iBAAiB,UAAU,MAAM;AACtC,IAAAD,EAAK,oBAAoB;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO;AAAA,MACf,iBAAiB;AAAA,MACjB,aAAa;AAAA,IAAA,CACd;AAAA,EAAA,CACF,GAIeP,EAAA,CAACT,GAA+BC,MAAoB;AAC9D,IAAAtB,EAAA,OAAO,uBAAuBqB,GAAWC,CAAS;AAElD,QAAA;AACF,cAAQD,GAAW;AAAA,QACjB,KAAK;AACH,iBAAOgB,EAAKhB,GAAWb,EAAuB,MAAMc,CAAS,CAAC;AAAA,QAEhE,KAAK;AACH,iBAAOe,EAAKhB,GAAWhB,EAAoB,MAAMiB,CAAS,CAAC;AAAA,QAE7D,KAAK;AAGH;AAAA;AAAA,YAIKA,KAAc,OAEVe,EAAKhB,GAAW,CAAA,CAAE,IAEpBgB,EAAKhB,GAAWV,EAAmB,MAAMW,CAAS,CAAC;AAAA;AAAA,QAE5D,KAAK;AACH,iBAAOe,EAAKhB,GAAWT,EAAS,EAAA,MAAMU,CAAS,CAAC;AAAA,QAElD,KAAK;AACH,iBAAOe,EAAKhB,GAAWR,EAAsB,MAAMS,CAAS,CAAC;AAAA,QAE/D,KAAK;AACH,iBAAOe,EAAKhB,GAAWN,EAA6B,MAAMO,CAAS,CAAC;AAAA,QAEtE,KAAK;AACH,iBAAOe,EAAKhB,GAAWP,EAAqB,MAAMQ,CAAS,CAAC;AAAA,QAE9D,KAAK;AACH,iBAAOe,EAAK,mBAAmBpB,EAAsB,MAAMK,CAAS,CAAC;AAAA,QAEvE,KAAK;AACH,iBAAOe,EAAK,yBAAyBnB,EAA2B,MAAMI,CAAS,CAAC;AAAA,QAElF,KAAK;AACH,iBAAOe,EAAK,0BAA0BrB,EAA4B,MAAMM,CAAS,CAAC;AAAA,QAGpF,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH,iBAAOe,EAAKhB,CAAS;AAAA,QAGvB;AACS,iBAAAgB,EAAKhB,GAAkBC,CAAS;AAAA,MAC3C;AAAA,aACOiB,GAAO;AACV,MAAAvC,EAAA,SAAS,2BAA2BuC,CAAK;AAAA,IAC/C;AAAA,EAAA,CACD,GAEMJ;AACT;AAMO,SAASK,IAAiC;AAC/C,QAAMhB,IAAW;AAGjB,SAFsBA,EAAIS,CAAc,MAElB,WAChBT,EAAAS,CAAc,IAAIC,MAGjBV,EAAIS,CAAc;AAC3B;ACnHgB,SAAAQ,EAAyBT,GAAUU,GAAkC;AAClE,EAAAF,IAAE,IAAIR,GAAOU,CAAQ;AACxC;ACEgB,SAAAC,EAAwBX,GAAUU,GAA2C;AAC1E,SAAAF,IAAE,GAAGR,GAAOU,CAAQ,GAC9B,MAAMD,EAAIT,GAAOU,CAAQ;AAClC;ACJgB,SAAAE,GAA0BZ,GAAUU,GAA2C;AAC5E,SAAAF,IAAE,KAAKR,GAAOU,CAAQ,GAChC,MAAMD,EAAIT,GAAOU,CAAQ;AAClC;ACPO,SAASG,EAAYH,GAAqC;AAC9C,EAAAF,EAAA,EAAE,YAAYE,CAAQ;AACzC;ACEO,SAASI,GAAUJ,GAA8C;AACrD,SAAAF,EAAA,EAAE,UAAUE,CAAQ,GAC9B,MAAMG,EAAYH,CAAQ;AACnC;ACIO,SAASK,EAAgClD,GAA0C;AACxF,SAAO,cAAcA,KAChBmD,EAASnD,EAAM,QAAQ,KACvB,YAAYA,EAAM,YAClB,OAAOA,EAAM,SAAS,UAAW;AACxC;AAOO,SAASoD,GAA8BpD,GAAwC;AACpF,SAAO,0BAA0BA,KAC5BmD,EAASnD,EAAM,oBAAoB,KACnC,eAAeA,EAAM,wBACrB,OAAOA,EAAM,qBAAqB,aAAc;AACvD;AAMO,SAASqD,KAAoB;AAC9B,MAAA;AACK,WAAA,OAAO,SAAS,OAAO;AAAA,UACpB;AACH,WAAA;AAAA,EACT;AACF;ACGgB,SAAAC,GACd9B,GACA+B,GACAC,GACM;AACN,MAAIC,IAAgC,CAAA,GAChChC;AAEA,EAAA8B,MAAoB,UAAaC,MAAY,SAE/CC,IAAc,CAAA,IACLF,MAAoB,UAAaC,MAAY,UAExCC,IAAAD,GACF/B,IAAA8B,KACHA,MAAoB,WAEzB,kBAAkBA,IACNE,IAAAF,IAEF9B,IAAA8B;AAGhB,QAAM,gBAAErD,IAAewD,EAAmB,EAAA,IAAMD;AAGhD,MAAIJ,MAAY;AACP,WAAA,OAAO,YAAY,KAAK,UAAU;AAAA,MACvC,WAAA7B;AAAA,MACA,WAAAC;AAAA,IAAA,CACD,GAAGvB,CAAY;AAChB;AAAA,EACF;AAGI,MAAAgD,EAAkB,MAAM,GAAG;AACtB,WAAA,SAAS,OAAO,KAAK,UAAU,EAAE,WAAA1B,GAAW,WAAAC,EAAW,CAAA,CAAC;AAC/D;AAAA,EACF;AAGI,MAAA2B,GAAgB,MAAM,GAAG;AAC3B,WAAO,qBAAqB,UAAU5B,GAAW,KAAK,UAAUC,CAAS,CAAC;AAC1E;AAAA,EACF;AAIA,QAAM,IAAI;AAAA,IACR;AAAA,EAAA;AAEJ;ACEO,SAASkC,GACdC,GACAC,GACAC,GACAN,GACc;AACV,MAAAO,GACAC,GACAC,GACAC;AAEJ,EAAI,OAAOL,KAAkB,YAAY,MAAM,QAAQA,CAAa,KAElEI,IAAS,MAAM,QAAQJ,CAAa,IAAIA,IAAgB,CAACA,CAAa,GACnDE,IAAAD,MAGJE,IAAAH,GACfI,IAAS,MAAM,QAAQH,CAAc,IAAIA,IAAiB,CAACA,CAAc,GACtDC,IAAAP,IAKjBL,EAASa,CAAY,KAAK,OAAOA,EAAa,UAAW,aAC3DE,IAAYF,EAAa;AAG3B,QAAM,EAAA,WAAEV,IAAYa,IAAkB,SAAAC,EAAQ,IAAIL,KAAoB,CAAA,GAChEM,IAAUN,KAAoB,aAAaA,IAC7CA,EAAiB,UACjB,MAEEO,IAAU,IAAI,QAAQ,CAACC,GAAKC,MAAQ;AAElC,UAAAC,IAAWR,EAAO,IAAI,CAACS,MAAO5B,EAAG4B,GAAI,CAACjC,MAAU;AAGhD,MAAA,OAAOyB,KAAc,aAAa,CAACf,EAASV,CAAI,KAAKA,EAAK,WAAWyB,MAIrE,OAAOG,KAAY,cAAc,CAACA,EAAQ5B,CAAI,MAKpCkC,KACdJ,EAAI9B,CAAI;AAAA,IACT,CAAA,CAAC,GAGIkC,IAAgB,MAAMF,EAAS,QAAQ,CAACG,MAASA,GAAM;AAEzD,QAAA;AAIFtB,MAAAA,EAAUM,GAAeI,CAAY;AAAA,aAC9Ba,GAAG;AACI,MAAAF,KACdH,EAAIK,CAAC;AAAA,IACP;AAAA,EAAA,CACD;AAED,SAAO,OAAOT,KAAY,WAAWU,EAAYR,GAASF,CAAO,IAAIE;AACvE;AChKA,SAASS,EAAYC,GAAYC,GAAqB;AAC7C,SAAAC,EAAgBF,GAAGC,CAAC,KAAK;AAClC;AAQgB,SAAAE,GACdvB,GACAwB,GACyD;AACzD,SAAIxB,MAAW,uBACT,sBAAsBwB,IACjB,CAAC,kBAAkB,IAI1BxB,MAAW,8BACT,WAAWwB,IACN,CAAC,OAAO,IAIZ;AACT;AAmBgB,SAAAC,GACdzB,GACA0B,GACAC,GACS;AAEL,MAAA,OAAOA,KAAc,UAAU;AACjC,QAAI3B,MAAW,uBACT0B,MAAmB;AACd,aAAAP,EAAY,OAAOQ,CAAS;AAIvC,QAAI3B,MAAW,8BACT0B,MAAmB;AACd,aAAAP,EAAY,OAAOQ,CAAS;AAAA,EAGzC;AAGA,UAAQ3B,GAAQ;AAAA,IACd,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACI,aAAAmB,EAAY,OAAOO,CAAc;AAAA,IAC1C,KAAK;AACI,aAAAP,EAAY,OAAOO,CAAc;AAAA,IAC1C,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACI,aAAAP,EAAY,OAAOO,CAAc;AAAA,IAC1C,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACI,aAAAP,EAAY,OAAOO,CAAc;AAAA,IAC1C;AACS,aAAA;AAAA,EACX;AACF;"}
1
+ {"version":3,"file":"index.js","sources":["../src/globals.ts","../src/events/parsing.ts","../src/events/onTelegramEvent.ts","../src/events/emitter.ts","../src/events/off.ts","../src/events/on.ts","../src/events/once.ts","../src/events/unsubscribe.ts","../src/events/subscribe.ts","../src/env.ts","../src/methods/postEvent.ts","../src/request.ts","../src/supports.ts"],"sourcesContent":["import { log as utilLog } from '@tma.js/logger';\n\nlet currentDebug = false;\nlet currentTargetOrigin = 'https://web.telegram.org';\n\n/**\n * Sets new debug mode. Enabling debug mode leads to printing\n * additional messages in console, related to the processes\n * inside the package.\n * @param value - should debug mode be enabled.\n */\nexport function setDebug(value: boolean): void {\n currentDebug = value;\n}\n\n/**\n * Sets new global targetOrigin, used by `postEvent` method.\n * Default value is \"https://web.telegram.org\". You don't need to\n * use this method until you know what you are doing.\n *\n * This method could be used for test purposes.\n * @param value - new target origin.\n */\nexport function setTargetOrigin(value: string): void {\n currentTargetOrigin = value;\n}\n\n/**\n * Returns current global target origin.\n */\nexport function targetOrigin(): string {\n return currentTargetOrigin;\n}\n\n/**\n * Logs message in case, debug mode is enabled.\n * @param level - log level\n * @param args - values to print.\n */\nexport const log: typeof utilLog = (level, ...args) => {\n if (currentDebug) {\n utilLog(level, '[Bridge]', ...args);\n }\n};\n","import {\n number,\n string,\n boolean,\n json,\n rgb,\n} from '@tma.js/parsing';\n\nimport type {\n ClipboardTextReceivedPayload, CustomMethodInvokedPayload,\n InvoiceClosedPayload, PhoneRequestedPayload,\n PopupClosedPayload, QrTextReceivedPayload,\n ThemeChangedPayload,\n ViewportChangedPayload, WriteAccessRequestedPayload,\n} from './payloads.js';\n\nfunction isNullOrUndefined(value: unknown): boolean {\n return value === null || value === undefined;\n}\n\n/**\n * Parses incoming value as ThemeChangedPayload.\n */\nexport const themeChangedPayload = json<ThemeChangedPayload>({\n theme_params: json<ThemeChangedPayload['theme_params']>({\n bg_color: rgb().optional(),\n text_color: rgb().optional(),\n hint_color: rgb().optional(),\n link_color: rgb().optional(),\n button_color: rgb().optional(),\n button_text_color: rgb().optional(),\n secondary_bg_color: rgb().optional(),\n }),\n});\n\n/**\n * Parses incoming value as ViewportChangedPayload.\n * @param value - value to parse.\n */\nexport const viewportChangedPayload = json<ViewportChangedPayload>({\n height: number(),\n width: number().optional(isNullOrUndefined).default(() => window.innerWidth),\n is_state_stable: boolean(),\n is_expanded: boolean(),\n});\n\n/**\n * Parses incoming value as PopupClosedPayload.\n */\nexport const popupClosedPayload = json<PopupClosedPayload>({\n button_id: string().optional(isNullOrUndefined),\n});\n\n/**\n * Parses incoming value as QrTextReceivedPayload.\n */\nexport const qrTextReceivedPayload = json<QrTextReceivedPayload>({\n data: string().optional(),\n});\n\n/**\n * Parses incoming value as InvoiceClosedPayload.\n */\nexport const invoiceClosedPayload = json<InvoiceClosedPayload>({\n slug: string(),\n status: string(),\n});\n\n/**\n * Parses incoming value as clipboard text received payload.\n */\nexport const clipboardTextReceivedPayload = json<ClipboardTextReceivedPayload>({\n req_id: string(),\n data: (value) => (value === null ? value : string().optional().parse(value)),\n});\n\n/**\n * Parses incoming value as WriteAccessRequestedPayload.\n */\nexport const writeAccessRequestedPayload = json<WriteAccessRequestedPayload>({ status: string() });\n\n/**\n * Parses incoming value as PhoneRequestedPayload.\n */\nexport const phoneRequestedPayload = json<PhoneRequestedPayload>({ status: string() });\n\n/**\n * Parses incoming value as CustomMethodInvokedPayload.\n */\nexport const customMethodInvokedPayload = json<CustomMethodInvokedPayload>({\n req_id: string(),\n result: (value) => value,\n error: string().optional(),\n});\n","import { json, string } from '@tma.js/parsing';\n\n/**\n * Extracts event data from native application event.\n */\nconst eventDataJson = json<{ eventType: string; eventData?: unknown }>({\n eventType: string(),\n eventData: (value) => value,\n});\n\n/**\n * Emits event sent from Telegram native application like it was sent in\n * default web environment between 2 iframes. It dispatches new MessageEvent\n * and expects it to be handled via `window.addEventListener('message', ...)`\n * as developer would do it to handle messages sent from parent iframe.\n * @param eventType - event name.\n * @param eventData - event payload.\n */\nfunction emitEvent(eventType: string, eventData: unknown): void {\n window.dispatchEvent(new MessageEvent('message', {\n data: JSON.stringify({ eventType, eventData }),\n }));\n}\n\n/**\n * Defines special handlers by known paths, which are recognized by\n * Telegram as ports to receive events. This function also sets special\n * function in global window object to prevent duplicate declaration.\n */\nfunction defineEventHandlers(): void {\n const wnd: any = window;\n\n // Prevent from duplicate event handlers definition.\n if ('TelegramGameProxy_receiveEvent' in wnd) {\n return;\n }\n\n // Iterate over each path, where \"receiveEvent\" function should be\n // defined. This function is called by external environment in case,\n // it wants to emit some event.\n [\n ['TelegramGameProxy_receiveEvent'], // Windows Phone.\n ['TelegramGameProxy', 'receiveEvent'], // Desktop.\n ['Telegram', 'WebView', 'receiveEvent'], // Android and iOS.\n ].forEach((path) => {\n // Path starts from \"window\" object.\n let pointer = wnd;\n\n path.forEach((item, idx, arr) => {\n // We are on the last iteration, where function property name is passed.\n if (idx === arr.length - 1) {\n pointer[item] = emitEvent;\n return;\n }\n\n if (!(item in pointer)) {\n pointer[item] = {};\n }\n pointer = pointer[item];\n });\n });\n}\n\n/**\n * Adds listener to window \"message\" event assuming, that this event could\n * be sent by Telegram native application. Calls passed callback with event\n * type and data.\n * @param cb - callback to call.\n */\nexport function onTelegramEvent(cb: (eventType: string, eventData: unknown) => void): void {\n // Define event handlers to make sure, message handler will work correctly.\n defineEventHandlers();\n\n // We expect Telegram to send us new event through \"message\" event.\n window.addEventListener('message', (event) => {\n try {\n const { eventType, eventData } = eventDataJson.parse(event.data);\n cb(eventType, eventData);\n } catch {\n // We ignore incorrect messages as they could be generated by any other code.\n }\n });\n}\n","import { EventEmitter as UtilEventEmitter } from '@tma.js/event-emitter';\nimport { string } from '@tma.js/parsing';\n\nimport { log } from '../globals.js';\nimport {\n clipboardTextReceivedPayload,\n customMethodInvokedPayload,\n invoiceClosedPayload,\n phoneRequestedPayload,\n popupClosedPayload,\n qrTextReceivedPayload,\n themeChangedPayload,\n viewportChangedPayload,\n writeAccessRequestedPayload,\n} from './parsing.js';\nimport { onTelegramEvent } from './onTelegramEvent.js';\n\nimport type { EventEmitter, EventName } from './events.js';\n\nconst CACHED_EMITTER = '__telegram-cached-emitter__';\n\n/**\n * Returns event emitter which could be safely used, to process events from\n * Telegram native application.\n */\nexport function createEmitter(): EventEmitter {\n const emitter: EventEmitter = new UtilEventEmitter();\n const emit: EventEmitter['emit'] = (event: any, ...data: any[]) => {\n log('log', 'Emitting processed event:', event, ...data);\n emitter.emit(event, ...data);\n };\n\n // Desktop version of Telegram is sometimes not sending the viewport_changed\n // event. For example, when main button is shown. That's why we should\n // add our own listener to make sure, viewport information is always fresh.\n // Issue: https://github.com/Telegram-Web-Apps/tma.js/issues/10\n window.addEventListener('resize', () => {\n emit('viewport_changed', {\n width: window.innerWidth,\n height: window.innerHeight,\n is_state_stable: true,\n is_expanded: true,\n });\n });\n\n // In case, any Telegram event was received, we should prepare data before\n // passing it to emitter.\n onTelegramEvent((eventType: EventName | string, eventData): void => {\n log('log', 'Received raw event:', eventType, eventData);\n\n try {\n switch (eventType) {\n case 'viewport_changed':\n return emit(eventType, viewportChangedPayload.parse(eventData));\n\n case 'theme_changed':\n return emit(eventType, themeChangedPayload.parse(eventData));\n\n case 'popup_closed':\n // FIXME: Payloads are different on different platforms.\n // Issue: https://github.com/Telegram-Web-Apps/tma.js/issues/2\n if (\n // Sent on desktop.\n eventData === undefined\n // Sent on iOS.\n || eventData === null\n ) {\n return emit(eventType, {});\n }\n return emit(eventType, popupClosedPayload.parse(eventData));\n\n case 'set_custom_style':\n return emit(eventType, string().parse(eventData));\n\n case 'qr_text_received':\n return emit(eventType, qrTextReceivedPayload.parse(eventData));\n\n case 'clipboard_text_received':\n return emit(eventType, clipboardTextReceivedPayload.parse(eventData));\n\n case 'invoice_closed':\n return emit(eventType, invoiceClosedPayload.parse(eventData));\n\n case 'phone_requested':\n return emit('phone_requested', phoneRequestedPayload.parse(eventData));\n\n case 'custom_method_invoked':\n return emit('custom_method_invoked', customMethodInvokedPayload.parse(eventData));\n\n case 'write_access_requested':\n return emit('write_access_requested', writeAccessRequestedPayload.parse(eventData));\n\n // Events which have no parameters.\n case 'main_button_pressed':\n case 'back_button_pressed':\n case 'settings_button_pressed':\n case 'scan_qr_popup_closed':\n return emit(eventType);\n\n // All other event listeners will receive unknown type of data.\n default:\n return emit(eventType as any, eventData);\n }\n } catch (cause) {\n log('error', 'Error processing event:', cause);\n }\n });\n\n return emitter;\n}\n\n/**\n * Returns singleton instance of bridge EventEmitter. Also, defines\n * Telegram event handlers.\n */\nexport function singletonEmitter(): EventEmitter {\n const wnd: any = window;\n const cachedEmitter = wnd[CACHED_EMITTER];\n\n if (cachedEmitter === undefined) {\n wnd[CACHED_EMITTER] = createEmitter();\n }\n\n return wnd[CACHED_EMITTER];\n}\n","import { singletonEmitter } from './emitter.js';\n\nimport type { EventName, EventListener } from './events.js';\n\n/**\n * Removes listener from specified event.\n * @param event - event to listen.\n * @param listener - event listener.\n */\nexport function off<E extends EventName>(event: E, listener: EventListener<E>): void {\n singletonEmitter().off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { off } from './off.js';\n\nimport type { EventName, EventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Adds new listener to the specified event. Returns handler\n * which allows to stop listening to event.\n * @param event - event name.\n * @param listener - event listener.\n */\nexport function on<E extends EventName>(event: E, listener: EventListener<E>): StopListening {\n singletonEmitter().on(event, listener);\n return () => off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { off } from './off.js';\n\nimport type { EventName, EventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Works the same as \"on\" method, but after catching the event, will remove event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\nexport function once<E extends EventName>(event: E, listener: EventListener<E>): StopListening {\n singletonEmitter().once(event, listener);\n return () => off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\n\nimport type { GlobalEventListener } from './events.js';\n\n/**\n * Removes global event listener.\n * @param listener - event listener.\n */\nexport function unsubscribe(listener: GlobalEventListener): void {\n singletonEmitter().unsubscribe(listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { unsubscribe } from './unsubscribe.js';\n\nimport type { GlobalEventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Subscribes to all events sent from the native Telegram application.\n * Returns function used to remove added event listener.\n * @param listener - event listener.\n */\nexport function subscribe(listener: GlobalEventListener): StopListening {\n singletonEmitter().subscribe(listener);\n return () => unsubscribe(listener);\n}\n","import { isRecord } from '@tma.js/utils';\n\ntype AnyFunc = (...args: unknown[]) => unknown;\n\ntype WithExternalNotify<T> = T & {\n external: { notify: AnyFunc }\n};\n\ntype WithWebviewProxy<T> = T & {\n TelegramWebviewProxy: {\n postEvent: AnyFunc;\n }\n};\n\n/**\n * Returns true in case, passed value contains path `external.notify` property and `notify` is a\n * function.\n * @param value - value to check.\n */\nexport function hasExternalNotify<T extends {}>(value: T): value is WithExternalNotify<T> {\n return 'external' in value\n && isRecord(value.external)\n && 'notify' in value.external\n && typeof value.external.notify === 'function';\n}\n\n/**\n * Returns true in case, passed value contains path `TelegramWebviewProxy.postEvent` property and\n * `postEvent` is a function.\n * @param value - value to check.\n */\nexport function hasWebviewProxy<T extends {}>(value: T): value is WithWebviewProxy<T> {\n return 'TelegramWebviewProxy' in value\n && isRecord(value.TelegramWebviewProxy)\n && 'postEvent' in value.TelegramWebviewProxy\n && typeof value.TelegramWebviewProxy.postEvent === 'function';\n}\n\n/**\n * Returns true in case, current environment is iframe.\n * @see https://stackoverflow.com/a/326076\n */\nexport function isIframe(): boolean {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n}\n","import {\n isIframe,\n hasExternalNotify,\n hasWebviewProxy,\n} from '../env.js';\nimport { targetOrigin as globalTargetOrigin } from '../globals.js';\n\nimport type {\n EmptyMethodName,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './params.js';\n\ninterface PostEventOptions {\n /**\n * Origin used while posting message. This option is only used in case,\n * current environment is browser (Web version of Telegram) and could\n * be used for test purposes.\n * @default 'https://web.telegram.org'\n */\n targetOrigin?: string;\n}\n\nexport type PostEvent = typeof postEvent;\n\n/**\n * Sends event to native application which launched Web App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param params - event parameters.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current\n * environment and possible way to send event.\n */\nexport function postEvent<E extends NonEmptyMethodName>(\n eventType: E,\n params: MethodParams<E>,\n options?: PostEventOptions,\n): void;\n\n/**\n * Sends event to native application which launched Web App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current\n * environment and possible way to send event.\n */\nexport function postEvent(eventType: EmptyMethodName, options?: PostEventOptions): void;\n\nexport function postEvent(\n eventType: MethodName,\n paramsOrOptions?: MethodParams<MethodName> | PostEventOptions,\n options?: PostEventOptions,\n): void {\n let postOptions: PostEventOptions = {};\n let eventData: any;\n\n if (paramsOrOptions === undefined && options === undefined) {\n // Parameters and options were not passed.\n postOptions = {};\n } else if (paramsOrOptions !== undefined && options !== undefined) {\n // Both parameters and options passed.\n postOptions = options;\n eventData = paramsOrOptions;\n } else if (paramsOrOptions !== undefined) {\n // Only parameters were passed.\n if ('targetOrigin' in paramsOrOptions) {\n postOptions = paramsOrOptions;\n } else {\n eventData = paramsOrOptions;\n }\n }\n const { targetOrigin = globalTargetOrigin() } = postOptions;\n\n // Telegram Web.\n if (isIframe()) {\n window.parent.postMessage(JSON.stringify({\n eventType,\n eventData,\n }), targetOrigin);\n return;\n }\n\n // Telegram for Windows Phone or Android.\n if (hasExternalNotify(window)) {\n window.external.notify(JSON.stringify({ eventType, eventData }));\n return;\n }\n\n // Telegram for iOS and macOS.\n if (hasWebviewProxy(window)) {\n window.TelegramWebviewProxy.postEvent(eventType, JSON.stringify(eventData));\n return;\n }\n\n // Otherwise current environment is unknown, and we are not able to send\n // event.\n throw new Error(\n 'Unable to determine current environment and possible way to send event.',\n );\n}\n","import { withTimeout, isRecord } from '@tma.js/utils';\n\nimport type { And, If, IsNever } from '@tma.js/util-types';\n\nimport { postEvent as defaultPostEvent, type PostEvent } from './methods/postEvent.js';\nimport { on, type EventName, type EventParams, type EventHasParams } from './events/index.js';\n\nimport type {\n EmptyMethodName, MethodHasParams,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './methods/params.js';\n\n/**\n * Names of methods, which require passing \"req_id\" parameter.\n */\ntype MethodNameWithRequestId = {\n [Method in MethodName]: If<\n And<MethodHasParams<Method>, MethodParams<Method> extends { req_id: string } ? true : false>,\n Method,\n never\n >;\n}[MethodName];\n\n/**\n * Names of events, which contain \"req_id\" parameter.\n */\ntype EventNameWithRequestId = {\n [Event in EventName]: If<\n And<EventHasParams<Event>, EventParams<Event> extends { req_id: string } ? true : false>,\n Event,\n never\n >;\n}[EventName];\n\nexport interface RequestOptions {\n /**\n * Bridge postEvent method.\n * @default Global postEvent method.\n */\n postEvent?: PostEvent;\n\n /**\n * Execution timeout.\n */\n timeout?: number;\n}\n\nexport interface RequestOptionsAdvanced<EventPayload> extends RequestOptions {\n /**\n * Should return true in case, this event should be captured. If not specified,\n * request is not skipping captured events.\n */\n capture?: If<IsNever<EventPayload>, () => boolean, (payload: EventPayload) => boolean>;\n}\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, event with specified in method request identifier\n * was captured.\n * @param method - method to execute.\n * @param params - method parameters.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<\n Method extends MethodNameWithRequestId,\n Event extends EventNameWithRequestId,\n>(\n method: Method,\n params: MethodParams<Method>,\n event: Event | Event[],\n options?: RequestOptions,\n): Promise<EventParams<Event>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<Method extends EmptyMethodName, Event extends EventName>(\n method: Method,\n event: Event | Event[],\n options?: RequestOptionsAdvanced<EventParams<Event>>,\n): Promise<EventParams<Event>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute\n * @param params - method parameters.\n * @param event - event or events to listen\n * @param options - additional execution options.\n */\nexport function request<Method extends NonEmptyMethodName, Event extends EventName>(\n method: Method,\n params: MethodParams<Method>,\n event: Event | Event[],\n options?: RequestOptionsAdvanced<EventParams<Event>>,\n): Promise<EventParams<Event>>;\n\nexport function request(\n method: MethodName,\n eventOrParams: EventName | EventName[] | EventParams<any>,\n eventOrOptions?: EventName | EventName[] | RequestOptions | RequestOptionsAdvanced<any>,\n options?: RequestOptions | RequestOptionsAdvanced<any>,\n): Promise<any> {\n let executionOptions: RequestOptions | RequestOptionsAdvanced<any> | undefined;\n let methodParams: EventParams<any> | undefined;\n let events: EventName[];\n let requestId: string | undefined;\n\n if (typeof eventOrParams === 'string' || Array.isArray(eventOrParams)) {\n // Override: [method, event, options?]\n events = Array.isArray(eventOrParams) ? eventOrParams : [eventOrParams] as EventName[];\n executionOptions = eventOrOptions as (RequestOptionsAdvanced<any> | undefined);\n } else {\n // Override: [method, params, event, options?]\n methodParams = eventOrParams as EventParams<any>;\n events = Array.isArray(eventOrOptions) ? eventOrOptions : [eventOrOptions] as EventName[];\n executionOptions = options;\n }\n\n // In case, method parameters were passed, and they contained request identifier, we should store\n // it and wait for the event with this identifier to occur.\n if (isRecord(methodParams) && typeof methodParams.req_id === 'string') {\n requestId = methodParams.req_id;\n }\n\n const { postEvent = defaultPostEvent, timeout } = executionOptions || {};\n const capture = executionOptions && 'capture' in executionOptions\n ? executionOptions.capture\n : null;\n\n const promise = new Promise((res, rej) => {\n // Iterate over each event and create event listener.\n const stoppers = events.map((ev) => on(ev, (data?) => {\n // If request identifier was specified, we are waiting for event with the same value\n // to occur.\n if (typeof requestId === 'string' && (!isRecord(data) || data.req_id !== requestId)) {\n return;\n }\n\n if (typeof capture === 'function' && !capture(data)) {\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n stopListening();\n res(data);\n }));\n\n // Function which removes all event listeners.\n const stopListening = () => stoppers.forEach((stop) => stop());\n\n try {\n // We are wrapping this call in try catch, because it can throw errors in case,\n // compatibility check was enabled. We want an error to be captured by promise, not by\n // another one external try catch.\n postEvent(method as any, methodParams);\n } catch (e) {\n stopListening();\n rej(e);\n }\n });\n\n return typeof timeout === 'number' ? withTimeout(promise, timeout) : promise;\n}\n","import { compareVersions, type Version } from '@tma.js/utils';\n\nimport type {\n HasCheckSupportMethodParam,\n HasCheckSupportMethodName,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './methods/index.js';\n\nfunction lessOrEqual(a: Version, b: Version): boolean {\n return compareVersions(a, b) <= 0;\n}\n\n/**\n * By specified method and parameters extracts properties which could be used by\n * supports function as TWA method parameter.\n * @param method - TWA method.\n * @param params - method parameters.\n */\nexport function detectSupportParams<M extends NonEmptyMethodName>(\n method: M,\n params: MethodParams<M>,\n): HasCheckSupportMethodParam<HasCheckSupportMethodName>[] {\n if (method === 'web_app_open_link') {\n if ('try_instant_view' in params) {\n return ['try_instant_view'];\n }\n }\n\n if (method === 'web_app_set_header_color') {\n if ('color' in params) {\n return ['color'];\n }\n }\n\n return [];\n}\n\n/**\n * Returns true in case, passed parameter in specified method is supported.\n * @param method - method name\n * @param param - method parameter\n * @param inVersion - platform version.\n */\nexport function supports<M extends HasCheckSupportMethodName>(\n method: M,\n param: HasCheckSupportMethodParam<M>,\n inVersion: Version,\n): boolean;\n/**\n * Returns true in case, specified method is supported in passed version.\n * @param method - method name.\n * @param inVersion - platform version.\n */\nexport function supports(method: MethodName, inVersion: Version): boolean;\nexport function supports(\n method: MethodName,\n paramOrVersion: Version | string,\n inVersion?: string,\n): boolean {\n // Method name, parameter, target version.\n if (typeof inVersion === 'string') {\n if (method === 'web_app_open_link') {\n if (paramOrVersion === 'try_instant_view') {\n return lessOrEqual('6.4', inVersion);\n }\n }\n\n if (method === 'web_app_set_header_color') {\n if (paramOrVersion === 'color') {\n return lessOrEqual('6.9', inVersion);\n }\n }\n }\n\n // Method name, target version.\n switch (method) {\n case 'web_app_open_tg_link':\n case 'web_app_open_invoice':\n case 'web_app_setup_back_button':\n case 'web_app_set_background_color':\n case 'web_app_set_header_color':\n case 'web_app_trigger_haptic_feedback':\n return lessOrEqual('6.1', paramOrVersion);\n case 'web_app_open_popup':\n return lessOrEqual('6.2', paramOrVersion);\n case 'web_app_close_scan_qr_popup':\n case 'web_app_open_scan_qr_popup':\n case 'web_app_read_text_from_clipboard':\n return lessOrEqual('6.4', paramOrVersion);\n case 'web_app_invoke_custom_method':\n case 'web_app_request_write_access':\n case 'web_app_request_phone':\n return lessOrEqual('6.9', paramOrVersion);\n case 'web_app_setup_settings_button':\n return lessOrEqual('6.10', paramOrVersion);\n default:\n return true;\n }\n}\n"],"names":["currentDebug","currentTargetOrigin","setDebug","value","setTargetOrigin","targetOrigin","log","level","args","utilLog","isNullOrUndefined","themeChangedPayload","json","rgb","viewportChangedPayload","number","boolean","popupClosedPayload","string","qrTextReceivedPayload","invoiceClosedPayload","clipboardTextReceivedPayload","writeAccessRequestedPayload","phoneRequestedPayload","customMethodInvokedPayload","eventDataJson","emitEvent","eventType","eventData","defineEventHandlers","wnd","path","pointer","item","idx","arr","onTelegramEvent","cb","event","CACHED_EMITTER","createEmitter","emitter","UtilEventEmitter","emit","data","cause","singletonEmitter","off","listener","on","once","unsubscribe","subscribe","hasExternalNotify","isRecord","hasWebviewProxy","isIframe","postEvent","paramsOrOptions","options","postOptions","globalTargetOrigin","request","method","eventOrParams","eventOrOptions","executionOptions","methodParams","events","requestId","defaultPostEvent","timeout","capture","promise","res","rej","stoppers","ev","stopListening","stop","e","withTimeout","lessOrEqual","a","b","compareVersions","detectSupportParams","params","supports","paramOrVersion","inVersion"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- (function(i,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("@tma.js/utils"),require("@tma.js/logger"),require("@tma.js/event-emitter"),require("@tma.js/parsing")):typeof define=="function"&&define.amd?define(["exports","@tma.js/utils","@tma.js/logger","@tma.js/event-emitter","@tma.js/parsing"],c):(i=typeof globalThis<"u"?globalThis:i||self,c((i["@tma"]=i["@tma"]||{},i["@tma"]["js/bridge"]={}),i["@tma"]["js/utils"],i["@tma"]["js/logger"],i["@tma"]["js/event-emitter"],i["@tma"]["js/parsing"]))})(this,function(i,c,A,S,r){"use strict";let m=!1,h="https://web.telegram.org";function N(e){m=e}function C(e){h=e}function I(){return h}const l=(e,...t)=>{m&&A.log(e,"[Bridge]",...t)};function y(e){return e==null}const J=r.json({theme_params:r.json({bg_color:r.rgb().optional(),text_color:r.rgb().optional(),hint_color:r.rgb().optional(),link_color:r.rgb().optional(),button_color:r.rgb().optional(),button_text_color:r.rgb().optional(),secondary_bg_color:r.rgb().optional()})}),M=r.json({height:r.number(),width:r.number().optional(y).default(()=>window.innerWidth),is_state_stable:r.boolean(),is_expanded:r.boolean()}),G=r.json({button_id:r.string().optional(y)}),H=r.json({data:r.string().optional()}),L=r.json({slug:r.string(),status:r.string()}),U=r.json({req_id:r.string(),data:e=>e===null?e:r.string().optional().parse(e)}),$=r.json({status:r.string()}),z=r.json({status:r.string()}),B=r.json({req_id:r.string(),result:e=>e,error:r.string().optional()}),F=r.json({eventType:r.string(),eventData:e=>e});function K(e,t){window.dispatchEvent(new MessageEvent("message",{data:JSON.stringify({eventType:e,eventData:t})}))}function Q(){const e=window;"TelegramGameProxy_receiveEvent"in e||[["TelegramGameProxy_receiveEvent"],["TelegramGameProxy","receiveEvent"],["Telegram","WebView","receiveEvent"]].forEach(t=>{let n=e;t.forEach((o,s,u)=>{if(s===u.length-1){n[o]=K;return}o in n||(n[o]={}),n=n[o]})})}function X(e){Q(),window.addEventListener("message",t=>{try{const{eventType:n,eventData:o}=F.parse(t.data);e(n,o)}catch{}})}const w="__telegram-cached-emitter__";function Y(){const e=new S.EventEmitter,t=(n,...o)=>{l("log","Emitting processed event:",n,...o),e.emit(n,...o)};return window.addEventListener("resize",()=>{t("viewport_changed",{width:window.innerWidth,height:window.innerHeight,is_state_stable:!0,is_expanded:!0})}),X((n,o)=>{l("log","Received raw event:",n,o);try{switch(n){case"viewport_changed":return t(n,M.parse(o));case"theme_changed":return t(n,J.parse(o));case"popup_closed":return o==null?t(n,{}):t(n,G.parse(o));case"set_custom_style":return t(n,r.string().parse(o));case"qr_text_received":return t(n,H.parse(o));case"clipboard_text_received":return t(n,U.parse(o));case"invoice_closed":return t(n,L.parse(o));case"phone_requested":return t("phone_requested",z.parse(o));case"custom_method_invoked":return t("custom_method_invoked",B.parse(o));case"write_access_requested":return t("write_access_requested",$.parse(o));case"main_button_pressed":case"back_button_pressed":case"settings_button_pressed":case"scan_qr_popup_closed":return t(n);default:return t(n,o)}}catch(s){l("error","Error processing event:",s)}}),e}function a(){const e=window;return e[w]===void 0&&(e[w]=Y()),e[w]}function p(e,t){a().off(e,t)}function E(e,t){return a().on(e,t),()=>p(e,t)}function Z(e,t){return a().once(e,t),()=>p(e,t)}function j(e){a().unsubscribe(e)}function D(e){return a().subscribe(e),()=>j(e)}function q(e){return"external"in e&&c.isRecord(e.external)&&"notify"in e.external&&typeof e.external.notify=="function"}function v(e){return"TelegramWebviewProxy"in e&&c.isRecord(e.TelegramWebviewProxy)&&"postEvent"in e.TelegramWebviewProxy&&typeof e.TelegramWebviewProxy.postEvent=="function"}function P(){try{return window.self!==window.top}catch{return!0}}function x(e,t,n){let o={},s;t===void 0&&n===void 0?o={}:t!==void 0&&n!==void 0?(o=n,s=t):t!==void 0&&("targetOrigin"in t?o=t:s=t);const{targetOrigin:u=I()}=o;if(P()){window.parent.postMessage(JSON.stringify({eventType:e,eventData:s}),u);return}if(q(window)){window.external.notify(JSON.stringify({eventType:e,eventData:s}));return}if(v(window)){window.TelegramWebviewProxy.postEvent(e,JSON.stringify(s));return}throw new Error("Unable to determine current environment and possible way to send event.")}function V(e,t,n,o){let s,u,b,g;typeof t=="string"||Array.isArray(t)?(b=Array.isArray(t)?t:[t],s=n):(u=t,b=Array.isArray(n)?n:[n],s=o),c.isRecord(u)&&typeof u.req_id=="string"&&(g=u.req_id);const{postEvent:te=x,timeout:k}=s||{},R=s&&"capture"in s?s.capture:null,T=new Promise((ne,re)=>{const oe=b.map(d=>E(d,f=>{typeof g=="string"&&(!c.isRecord(f)||f.req_id!==g)||typeof R=="function"&&!R(f)||(W(),ne(f))})),W=()=>oe.forEach(d=>d());try{te(e,u)}catch(d){W(),re(d)}});return typeof k=="number"?c.withTimeout(T,k):T}function _(e,t){return c.compareVersions(e,t)<=0}function O(e,t){return e==="web_app_open_link"&&"try_instant_view"in t?["try_instant_view"]:e==="web_app_set_header_color"&&"color"in t?["color"]:[]}function ee(e,t,n){if(typeof n=="string"){if(e==="web_app_open_link"&&t==="try_instant_view")return _("6.4",n);if(e==="web_app_set_header_color"&&t==="color")return _("6.9",n)}switch(e){case"web_app_open_tg_link":case"web_app_open_invoice":case"web_app_setup_back_button":case"web_app_set_background_color":case"web_app_set_header_color":case"web_app_trigger_haptic_feedback":return _("6.1",t);case"web_app_open_popup":return _("6.2",t);case"web_app_close_scan_qr_popup":case"web_app_open_scan_qr_popup":case"web_app_read_text_from_clipboard":return _("6.4",t);case"web_app_invoke_custom_method":case"web_app_request_write_access":case"web_app_request_phone":return _("6.9",t);default:return!0}}i.detectSupportParams=O,i.hasExternalNotify=q,i.hasWebviewProxy=v,i.isIframe=P,i.off=p,i.on=E,i.once=Z,i.postEvent=x,i.request=V,i.setDebug=N,i.setTargetOrigin=C,i.subscribe=D,i.supports=ee,i.unsubscribe=j,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});
1
+ (function(i,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("@tma.js/utils"),require("@tma.js/logger"),require("@tma.js/event-emitter"),require("@tma.js/parsing")):typeof define=="function"&&define.amd?define(["exports","@tma.js/utils","@tma.js/logger","@tma.js/event-emitter","@tma.js/parsing"],c):(i=typeof globalThis<"u"?globalThis:i||self,c((i["@tma"]=i["@tma"]||{},i["@tma"]["js/bridge"]={}),i["@tma"]["js/utils"],i["@tma"]["js/logger"],i["@tma"]["js/event-emitter"],i["@tma"]["js/parsing"]))})(this,function(i,c,A,S,o){"use strict";let m=!1,h="https://web.telegram.org";function N(e){m=e}function C(e){h=e}function I(){return h}const l=(e,...t)=>{m&&A.log(e,"[Bridge]",...t)};function y(e){return e==null}const J=o.json({theme_params:o.json({bg_color:o.rgb().optional(),text_color:o.rgb().optional(),hint_color:o.rgb().optional(),link_color:o.rgb().optional(),button_color:o.rgb().optional(),button_text_color:o.rgb().optional(),secondary_bg_color:o.rgb().optional()})}),M=o.json({height:o.number(),width:o.number().optional(y).default(()=>window.innerWidth),is_state_stable:o.boolean(),is_expanded:o.boolean()}),G=o.json({button_id:o.string().optional(y)}),H=o.json({data:o.string().optional()}),L=o.json({slug:o.string(),status:o.string()}),U=o.json({req_id:o.string(),data:e=>e===null?e:o.string().optional().parse(e)}),$=o.json({status:o.string()}),z=o.json({status:o.string()}),B=o.json({req_id:o.string(),result:e=>e,error:o.string().optional()}),F=o.json({eventType:o.string(),eventData:e=>e});function K(e,t){window.dispatchEvent(new MessageEvent("message",{data:JSON.stringify({eventType:e,eventData:t})}))}function Q(){const e=window;"TelegramGameProxy_receiveEvent"in e||[["TelegramGameProxy_receiveEvent"],["TelegramGameProxy","receiveEvent"],["Telegram","WebView","receiveEvent"]].forEach(t=>{let n=e;t.forEach((r,s,u)=>{if(s===u.length-1){n[r]=K;return}r in n||(n[r]={}),n=n[r]})})}function X(e){Q(),window.addEventListener("message",t=>{try{const{eventType:n,eventData:r}=F.parse(t.data);e(n,r)}catch{}})}const w="__telegram-cached-emitter__";function Y(){const e=new S.EventEmitter,t=(n,...r)=>{l("log","Emitting processed event:",n,...r),e.emit(n,...r)};return window.addEventListener("resize",()=>{t("viewport_changed",{width:window.innerWidth,height:window.innerHeight,is_state_stable:!0,is_expanded:!0})}),X((n,r)=>{l("log","Received raw event:",n,r);try{switch(n){case"viewport_changed":return t(n,M.parse(r));case"theme_changed":return t(n,J.parse(r));case"popup_closed":return r==null?t(n,{}):t(n,G.parse(r));case"set_custom_style":return t(n,o.string().parse(r));case"qr_text_received":return t(n,H.parse(r));case"clipboard_text_received":return t(n,U.parse(r));case"invoice_closed":return t(n,L.parse(r));case"phone_requested":return t("phone_requested",z.parse(r));case"custom_method_invoked":return t("custom_method_invoked",B.parse(r));case"write_access_requested":return t("write_access_requested",$.parse(r));case"main_button_pressed":case"back_button_pressed":case"settings_button_pressed":case"scan_qr_popup_closed":return t(n);default:return t(n,r)}}catch(s){l("error","Error processing event:",s)}}),e}function a(){const e=window;return e[w]===void 0&&(e[w]=Y()),e[w]}function p(e,t){a().off(e,t)}function E(e,t){return a().on(e,t),()=>p(e,t)}function Z(e,t){return a().once(e,t),()=>p(e,t)}function j(e){a().unsubscribe(e)}function D(e){return a().subscribe(e),()=>j(e)}function q(e){return"external"in e&&c.isRecord(e.external)&&"notify"in e.external&&typeof e.external.notify=="function"}function v(e){return"TelegramWebviewProxy"in e&&c.isRecord(e.TelegramWebviewProxy)&&"postEvent"in e.TelegramWebviewProxy&&typeof e.TelegramWebviewProxy.postEvent=="function"}function P(){try{return window.self!==window.top}catch{return!0}}function x(e,t,n){let r={},s;t===void 0&&n===void 0?r={}:t!==void 0&&n!==void 0?(r=n,s=t):t!==void 0&&("targetOrigin"in t?r=t:s=t);const{targetOrigin:u=I()}=r;if(P()){window.parent.postMessage(JSON.stringify({eventType:e,eventData:s}),u);return}if(q(window)){window.external.notify(JSON.stringify({eventType:e,eventData:s}));return}if(v(window)){window.TelegramWebviewProxy.postEvent(e,JSON.stringify(s));return}throw new Error("Unable to determine current environment and possible way to send event.")}function V(e,t,n,r){let s,u,b,g;typeof t=="string"||Array.isArray(t)?(b=Array.isArray(t)?t:[t],s=n):(u=t,b=Array.isArray(n)?n:[n],s=r),c.isRecord(u)&&typeof u.req_id=="string"&&(g=u.req_id);const{postEvent:te=x,timeout:k}=s||{},R=s&&"capture"in s?s.capture:null,T=new Promise((ne,oe)=>{const re=b.map(d=>E(d,f=>{typeof g=="string"&&(!c.isRecord(f)||f.req_id!==g)||typeof R=="function"&&!R(f)||(W(),ne(f))})),W=()=>re.forEach(d=>d());try{te(e,u)}catch(d){W(),oe(d)}});return typeof k=="number"?c.withTimeout(T,k):T}function _(e,t){return c.compareVersions(e,t)<=0}function O(e,t){return e==="web_app_open_link"&&"try_instant_view"in t?["try_instant_view"]:e==="web_app_set_header_color"&&"color"in t?["color"]:[]}function ee(e,t,n){if(typeof n=="string"){if(e==="web_app_open_link"&&t==="try_instant_view")return _("6.4",n);if(e==="web_app_set_header_color"&&t==="color")return _("6.9",n)}switch(e){case"web_app_open_tg_link":case"web_app_open_invoice":case"web_app_setup_back_button":case"web_app_set_background_color":case"web_app_set_header_color":case"web_app_trigger_haptic_feedback":return _("6.1",t);case"web_app_open_popup":return _("6.2",t);case"web_app_close_scan_qr_popup":case"web_app_open_scan_qr_popup":case"web_app_read_text_from_clipboard":return _("6.4",t);case"web_app_invoke_custom_method":case"web_app_request_write_access":case"web_app_request_phone":return _("6.9",t);case"web_app_setup_settings_button":return _("6.10",t);default:return!0}}i.detectSupportParams=O,i.hasExternalNotify=q,i.hasWebviewProxy=v,i.isIframe=P,i.off=p,i.on=E,i.once=Z,i.postEvent=x,i.request=V,i.setDebug=N,i.setTargetOrigin=C,i.subscribe=D,i.supports=ee,i.unsubscribe=j,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});
2
2
  //# sourceMappingURL=index.umd.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.cjs","sources":["../src/globals.ts","../src/events/parsing.ts","../src/events/onTelegramEvent.ts","../src/events/emitter.ts","../src/events/off.ts","../src/events/on.ts","../src/events/once.ts","../src/events/unsubscribe.ts","../src/events/subscribe.ts","../src/env.ts","../src/methods/postEvent.ts","../src/request.ts","../src/supports.ts"],"sourcesContent":["import { log as utilLog } from '@tma.js/logger';\n\nlet currentDebug = false;\nlet currentTargetOrigin = 'https://web.telegram.org';\n\n/**\n * Sets new debug mode. Enabling debug mode leads to printing\n * additional messages in console, related to the processes\n * inside the package.\n * @param value - should debug mode be enabled.\n */\nexport function setDebug(value: boolean): void {\n currentDebug = value;\n}\n\n/**\n * Sets new global targetOrigin, used by `postEvent` method.\n * Default value is \"https://web.telegram.org\". You don't need to\n * use this method until you know what you are doing.\n *\n * This method could be used for test purposes.\n * @param value - new target origin.\n */\nexport function setTargetOrigin(value: string): void {\n currentTargetOrigin = value;\n}\n\n/**\n * Returns current global target origin.\n */\nexport function targetOrigin(): string {\n return currentTargetOrigin;\n}\n\n/**\n * Logs message in case, debug mode is enabled.\n * @param level - log level\n * @param args - values to print.\n */\nexport const log: typeof utilLog = (level, ...args) => {\n if (currentDebug) {\n utilLog(level, '[Bridge]', ...args);\n }\n};\n","import {\n number,\n string,\n boolean,\n json,\n rgb,\n} from '@tma.js/parsing';\n\nimport type {\n ClipboardTextReceivedPayload, CustomMethodInvokedPayload,\n InvoiceClosedPayload, PhoneRequestedPayload,\n PopupClosedPayload, QrTextReceivedPayload,\n ThemeChangedPayload,\n ViewportChangedPayload, WriteAccessRequestedPayload,\n} from './payloads.js';\n\nfunction isNullOrUndefined(value: unknown): boolean {\n return value === null || value === undefined;\n}\n\n/**\n * Parses incoming value as ThemeChangedPayload.\n */\nexport const themeChangedPayload = json<ThemeChangedPayload>({\n theme_params: json<ThemeChangedPayload['theme_params']>({\n bg_color: rgb().optional(),\n text_color: rgb().optional(),\n hint_color: rgb().optional(),\n link_color: rgb().optional(),\n button_color: rgb().optional(),\n button_text_color: rgb().optional(),\n secondary_bg_color: rgb().optional(),\n }),\n});\n\n/**\n * Parses incoming value as ViewportChangedPayload.\n * @param value - value to parse.\n */\nexport const viewportChangedPayload = json<ViewportChangedPayload>({\n height: number(),\n width: number().optional(isNullOrUndefined).default(() => window.innerWidth),\n is_state_stable: boolean(),\n is_expanded: boolean(),\n});\n\n/**\n * Parses incoming value as PopupClosedPayload.\n */\nexport const popupClosedPayload = json<PopupClosedPayload>({\n button_id: string().optional(isNullOrUndefined),\n});\n\n/**\n * Parses incoming value as QrTextReceivedPayload.\n */\nexport const qrTextReceivedPayload = json<QrTextReceivedPayload>({\n data: string().optional(),\n});\n\n/**\n * Parses incoming value as InvoiceClosedPayload.\n */\nexport const invoiceClosedPayload = json<InvoiceClosedPayload>({\n slug: string(),\n status: string(),\n});\n\n/**\n * Parses incoming value as clipboard text received payload.\n */\nexport const clipboardTextReceivedPayload = json<ClipboardTextReceivedPayload>({\n req_id: string(),\n data: (value) => (value === null ? value : string().optional().parse(value)),\n});\n\n/**\n * Parses incoming value as WriteAccessRequestedPayload.\n */\nexport const writeAccessRequestedPayload = json<WriteAccessRequestedPayload>({ status: string() });\n\n/**\n * Parses incoming value as PhoneRequestedPayload.\n */\nexport const phoneRequestedPayload = json<PhoneRequestedPayload>({ status: string() });\n\n/**\n * Parses incoming value as CustomMethodInvokedPayload.\n */\nexport const customMethodInvokedPayload = json<CustomMethodInvokedPayload>({\n req_id: string(),\n result: (value) => value,\n error: string().optional(),\n});\n","import { json, string } from '@tma.js/parsing';\n\n/**\n * Extracts event data from native application event.\n */\nconst eventDataJson = json<{ eventType: string; eventData?: unknown }>({\n eventType: string(),\n eventData: (value) => value,\n});\n\n/**\n * Emits event sent from Telegram native application like it was sent in\n * default web environment between 2 iframes. It dispatches new MessageEvent\n * and expects it to be handled via `window.addEventListener('message', ...)`\n * as developer would do it to handle messages sent from parent iframe.\n * @param eventType - event name.\n * @param eventData - event payload.\n */\nfunction emitEvent(eventType: string, eventData: unknown): void {\n window.dispatchEvent(new MessageEvent('message', {\n data: JSON.stringify({ eventType, eventData }),\n }));\n}\n\n/**\n * Defines special handlers by known paths, which are recognized by\n * Telegram as ports to receive events. This function also sets special\n * function in global window object to prevent duplicate declaration.\n */\nfunction defineEventHandlers(): void {\n const wnd: any = window;\n\n // Prevent from duplicate event handlers definition.\n if ('TelegramGameProxy_receiveEvent' in wnd) {\n return;\n }\n\n // Iterate over each path, where \"receiveEvent\" function should be\n // defined. This function is called by external environment in case,\n // it wants to emit some event.\n [\n ['TelegramGameProxy_receiveEvent'], // Windows Phone.\n ['TelegramGameProxy', 'receiveEvent'], // Desktop.\n ['Telegram', 'WebView', 'receiveEvent'], // Android and iOS.\n ].forEach((path) => {\n // Path starts from \"window\" object.\n let pointer = wnd;\n\n path.forEach((item, idx, arr) => {\n // We are on the last iteration, where function property name is passed.\n if (idx === arr.length - 1) {\n pointer[item] = emitEvent;\n return;\n }\n\n if (!(item in pointer)) {\n pointer[item] = {};\n }\n pointer = pointer[item];\n });\n });\n}\n\n/**\n * Adds listener to window \"message\" event assuming, that this event could\n * be sent by Telegram native application. Calls passed callback with event\n * type and data.\n * @param cb - callback to call.\n */\nexport function onTelegramEvent(cb: (eventType: string, eventData: unknown) => void): void {\n // Define event handlers to make sure, message handler will work correctly.\n defineEventHandlers();\n\n // We expect Telegram to send us new event through \"message\" event.\n window.addEventListener('message', (event) => {\n try {\n const { eventType, eventData } = eventDataJson.parse(event.data);\n cb(eventType, eventData);\n } catch {\n // We ignore incorrect messages as they could be generated by any other code.\n }\n });\n}\n","import { EventEmitter as UtilEventEmitter } from '@tma.js/event-emitter';\nimport { string } from '@tma.js/parsing';\n\nimport { log } from '../globals.js';\nimport {\n clipboardTextReceivedPayload,\n customMethodInvokedPayload,\n invoiceClosedPayload,\n phoneRequestedPayload,\n popupClosedPayload,\n qrTextReceivedPayload,\n themeChangedPayload,\n viewportChangedPayload,\n writeAccessRequestedPayload,\n} from './parsing.js';\nimport { onTelegramEvent } from './onTelegramEvent.js';\n\nimport type { EventEmitter, EventName } from './events.js';\n\nconst CACHED_EMITTER = '__telegram-cached-emitter__';\n\n/**\n * Returns event emitter which could be safely used, to process events from\n * Telegram native application.\n */\nexport function createEmitter(): EventEmitter {\n const emitter: EventEmitter = new UtilEventEmitter();\n const emit: EventEmitter['emit'] = (event: any, ...data: any[]) => {\n log('log', 'Emitting processed event:', event, ...data);\n emitter.emit(event, ...data);\n };\n\n // Desktop version of Telegram is sometimes not sending the viewport_changed\n // event. For example, when main button is shown. That's why we should\n // add our own listener to make sure, viewport information is always fresh.\n // Issue: https://github.com/Telegram-Web-Apps/tma.js/issues/10\n window.addEventListener('resize', () => {\n emit('viewport_changed', {\n width: window.innerWidth,\n height: window.innerHeight,\n is_state_stable: true,\n is_expanded: true,\n });\n });\n\n // In case, any Telegram event was received, we should prepare data before\n // passing it to emitter.\n onTelegramEvent((eventType: EventName | string, eventData): void => {\n log('log', 'Received raw event:', eventType, eventData);\n\n try {\n switch (eventType) {\n case 'viewport_changed':\n return emit(eventType, viewportChangedPayload.parse(eventData));\n\n case 'theme_changed':\n return emit(eventType, themeChangedPayload.parse(eventData));\n\n case 'popup_closed':\n // FIXME: Payloads are different on different platforms.\n // Issue: https://github.com/Telegram-Web-Apps/tma.js/issues/2\n if (\n // Sent on desktop.\n eventData === undefined\n // Sent on iOS.\n || eventData === null\n ) {\n return emit(eventType, {});\n }\n return emit(eventType, popupClosedPayload.parse(eventData));\n\n case 'set_custom_style':\n return emit(eventType, string().parse(eventData));\n\n case 'qr_text_received':\n return emit(eventType, qrTextReceivedPayload.parse(eventData));\n\n case 'clipboard_text_received':\n return emit(eventType, clipboardTextReceivedPayload.parse(eventData));\n\n case 'invoice_closed':\n return emit(eventType, invoiceClosedPayload.parse(eventData));\n\n case 'phone_requested':\n return emit('phone_requested', phoneRequestedPayload.parse(eventData));\n\n case 'custom_method_invoked':\n return emit('custom_method_invoked', customMethodInvokedPayload.parse(eventData));\n\n case 'write_access_requested':\n return emit('write_access_requested', writeAccessRequestedPayload.parse(eventData));\n\n // Events which have no parameters.\n case 'main_button_pressed':\n case 'back_button_pressed':\n case 'settings_button_pressed':\n case 'scan_qr_popup_closed':\n return emit(eventType);\n\n // All other event listeners will receive unknown type of data.\n default:\n return emit(eventType as any, eventData);\n }\n } catch (cause) {\n log('error', 'Error processing event:', cause);\n }\n });\n\n return emitter;\n}\n\n/**\n * Returns singleton instance of bridge EventEmitter. Also, defines\n * Telegram event handlers.\n */\nexport function singletonEmitter(): EventEmitter {\n const wnd: any = window;\n const cachedEmitter = wnd[CACHED_EMITTER];\n\n if (cachedEmitter === undefined) {\n wnd[CACHED_EMITTER] = createEmitter();\n }\n\n return wnd[CACHED_EMITTER];\n}\n","import { singletonEmitter } from './emitter.js';\n\nimport type { EventName, EventListener } from './events.js';\n\n/**\n * Removes listener from specified event.\n * @param event - event to listen.\n * @param listener - event listener.\n */\nexport function off<E extends EventName>(event: E, listener: EventListener<E>): void {\n singletonEmitter().off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { off } from './off.js';\n\nimport type { EventName, EventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Adds new listener to the specified event. Returns handler\n * which allows to stop listening to event.\n * @param event - event name.\n * @param listener - event listener.\n */\nexport function on<E extends EventName>(event: E, listener: EventListener<E>): StopListening {\n singletonEmitter().on(event, listener);\n return () => off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { off } from './off.js';\n\nimport type { EventName, EventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Works the same as \"on\" method, but after catching the event, will remove event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\nexport function once<E extends EventName>(event: E, listener: EventListener<E>): StopListening {\n singletonEmitter().once(event, listener);\n return () => off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\n\nimport type { GlobalEventListener } from './events.js';\n\n/**\n * Removes global event listener.\n * @param listener - event listener.\n */\nexport function unsubscribe(listener: GlobalEventListener): void {\n singletonEmitter().unsubscribe(listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { unsubscribe } from './unsubscribe.js';\n\nimport type { GlobalEventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Subscribes to all events sent from the native Telegram application.\n * Returns function used to remove added event listener.\n * @param listener - event listener.\n */\nexport function subscribe(listener: GlobalEventListener): StopListening {\n singletonEmitter().subscribe(listener);\n return () => unsubscribe(listener);\n}\n","import { isRecord } from '@tma.js/utils';\n\ntype AnyFunc = (...args: unknown[]) => unknown;\n\ntype WithExternalNotify<T> = T & {\n external: { notify: AnyFunc }\n};\n\ntype WithWebviewProxy<T> = T & {\n TelegramWebviewProxy: {\n postEvent: AnyFunc;\n }\n};\n\n/**\n * Returns true in case, passed value contains path `external.notify` property and `notify` is a\n * function.\n * @param value - value to check.\n */\nexport function hasExternalNotify<T extends {}>(value: T): value is WithExternalNotify<T> {\n return 'external' in value\n && isRecord(value.external)\n && 'notify' in value.external\n && typeof value.external.notify === 'function';\n}\n\n/**\n * Returns true in case, passed value contains path `TelegramWebviewProxy.postEvent` property and\n * `postEvent` is a function.\n * @param value - value to check.\n */\nexport function hasWebviewProxy<T extends {}>(value: T): value is WithWebviewProxy<T> {\n return 'TelegramWebviewProxy' in value\n && isRecord(value.TelegramWebviewProxy)\n && 'postEvent' in value.TelegramWebviewProxy\n && typeof value.TelegramWebviewProxy.postEvent === 'function';\n}\n\n/**\n * Returns true in case, current environment is iframe.\n * @see https://stackoverflow.com/a/326076\n */\nexport function isIframe(): boolean {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n}\n","import {\n isIframe,\n hasExternalNotify,\n hasWebviewProxy,\n} from '../env.js';\nimport { targetOrigin as globalTargetOrigin } from '../globals.js';\n\nimport type {\n EmptyMethodName,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './params.js';\n\ninterface PostEventOptions {\n /**\n * Origin used while posting message. This option is only used in case,\n * current environment is browser (Web version of Telegram) and could\n * be used for test purposes.\n * @default 'https://web.telegram.org'\n */\n targetOrigin?: string;\n}\n\nexport type PostEvent = typeof postEvent;\n\n/**\n * Sends event to native application which launched Web App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param params - event parameters.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current\n * environment and possible way to send event.\n */\nexport function postEvent<E extends NonEmptyMethodName>(\n eventType: E,\n params: MethodParams<E>,\n options?: PostEventOptions,\n): void;\n\n/**\n * Sends event to native application which launched Web App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current\n * environment and possible way to send event.\n */\nexport function postEvent(eventType: EmptyMethodName, options?: PostEventOptions): void;\n\nexport function postEvent(\n eventType: MethodName,\n paramsOrOptions?: MethodParams<MethodName> | PostEventOptions,\n options?: PostEventOptions,\n): void {\n let postOptions: PostEventOptions = {};\n let eventData: any;\n\n if (paramsOrOptions === undefined && options === undefined) {\n // Parameters and options were not passed.\n postOptions = {};\n } else if (paramsOrOptions !== undefined && options !== undefined) {\n // Both parameters and options passed.\n postOptions = options;\n eventData = paramsOrOptions;\n } else if (paramsOrOptions !== undefined) {\n // Only parameters were passed.\n if ('targetOrigin' in paramsOrOptions) {\n postOptions = paramsOrOptions;\n } else {\n eventData = paramsOrOptions;\n }\n }\n const { targetOrigin = globalTargetOrigin() } = postOptions;\n\n // Telegram Web.\n if (isIframe()) {\n window.parent.postMessage(JSON.stringify({\n eventType,\n eventData,\n }), targetOrigin);\n return;\n }\n\n // Telegram for Windows Phone or Android.\n if (hasExternalNotify(window)) {\n window.external.notify(JSON.stringify({ eventType, eventData }));\n return;\n }\n\n // Telegram for iOS and macOS.\n if (hasWebviewProxy(window)) {\n window.TelegramWebviewProxy.postEvent(eventType, JSON.stringify(eventData));\n return;\n }\n\n // Otherwise current environment is unknown, and we are not able to send\n // event.\n throw new Error(\n 'Unable to determine current environment and possible way to send event.',\n );\n}\n","import { withTimeout, isRecord } from '@tma.js/utils';\n\nimport type { And, If, IsNever } from '@tma.js/util-types';\n\nimport { postEvent as defaultPostEvent, type PostEvent } from './methods/postEvent.js';\nimport { on, type EventName, type EventParams, type EventHasParams } from './events/index.js';\n\nimport type {\n EmptyMethodName, MethodHasParams,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './methods/params.js';\n\n/**\n * Names of methods, which require passing \"req_id\" parameter.\n */\ntype MethodNameWithRequestId = {\n [Method in MethodName]: If<\n And<MethodHasParams<Method>, MethodParams<Method> extends { req_id: string } ? true : false>,\n Method,\n never\n >;\n}[MethodName];\n\n/**\n * Names of events, which contain \"req_id\" parameter.\n */\ntype EventNameWithRequestId = {\n [Event in EventName]: If<\n And<EventHasParams<Event>, EventParams<Event> extends { req_id: string } ? true : false>,\n Event,\n never\n >;\n}[EventName];\n\nexport interface RequestOptions {\n /**\n * Bridge postEvent method.\n * @default Global postEvent method.\n */\n postEvent?: PostEvent;\n\n /**\n * Execution timeout.\n */\n timeout?: number;\n}\n\nexport interface RequestOptionsAdvanced<EventPayload> extends RequestOptions {\n /**\n * Should return true in case, this event should be captured. If not specified,\n * request is not skipping captured events.\n */\n capture?: If<IsNever<EventPayload>, () => boolean, (payload: EventPayload) => boolean>;\n}\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, event with specified in method request identifier\n * was captured.\n * @param method - method to execute.\n * @param params - method parameters.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<\n Method extends MethodNameWithRequestId,\n Event extends EventNameWithRequestId,\n>(\n method: Method,\n params: MethodParams<Method>,\n event: Event | Event[],\n options?: RequestOptions,\n): Promise<EventParams<Event>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<Method extends EmptyMethodName, Event extends EventName>(\n method: Method,\n event: Event | Event[],\n options?: RequestOptionsAdvanced<EventParams<Event>>,\n): Promise<EventParams<Event>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute\n * @param params - method parameters.\n * @param event - event or events to listen\n * @param options - additional execution options.\n */\nexport function request<Method extends NonEmptyMethodName, Event extends EventName>(\n method: Method,\n params: MethodParams<Method>,\n event: Event | Event[],\n options?: RequestOptionsAdvanced<EventParams<Event>>,\n): Promise<EventParams<Event>>;\n\nexport function request(\n method: MethodName,\n eventOrParams: EventName | EventName[] | EventParams<any>,\n eventOrOptions?: EventName | EventName[] | RequestOptions | RequestOptionsAdvanced<any>,\n options?: RequestOptions | RequestOptionsAdvanced<any>,\n): Promise<any> {\n let executionOptions: RequestOptions | RequestOptionsAdvanced<any> | undefined;\n let methodParams: EventParams<any> | undefined;\n let events: EventName[];\n let requestId: string | undefined;\n\n if (typeof eventOrParams === 'string' || Array.isArray(eventOrParams)) {\n // Override: [method, event, options?]\n events = Array.isArray(eventOrParams) ? eventOrParams : [eventOrParams] as EventName[];\n executionOptions = eventOrOptions as (RequestOptionsAdvanced<any> | undefined);\n } else {\n // Override: [method, params, event, options?]\n methodParams = eventOrParams as EventParams<any>;\n events = Array.isArray(eventOrOptions) ? eventOrOptions : [eventOrOptions] as EventName[];\n executionOptions = options;\n }\n\n // In case, method parameters were passed, and they contained request identifier, we should store\n // it and wait for the event with this identifier to occur.\n if (isRecord(methodParams) && typeof methodParams.req_id === 'string') {\n requestId = methodParams.req_id;\n }\n\n const { postEvent = defaultPostEvent, timeout } = executionOptions || {};\n const capture = executionOptions && 'capture' in executionOptions\n ? executionOptions.capture\n : null;\n\n const promise = new Promise((res, rej) => {\n // Iterate over each event and create event listener.\n const stoppers = events.map((ev) => on(ev, (data?) => {\n // If request identifier was specified, we are waiting for event with the same value\n // to occur.\n if (typeof requestId === 'string' && (!isRecord(data) || data.req_id !== requestId)) {\n return;\n }\n\n if (typeof capture === 'function' && !capture(data)) {\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n stopListening();\n res(data);\n }));\n\n // Function which removes all event listeners.\n const stopListening = () => stoppers.forEach((stop) => stop());\n\n try {\n // We are wrapping this call in try catch, because it can throw errors in case,\n // compatibility check was enabled. We want an error to be captured by promise, not by\n // another one external try catch.\n postEvent(method as any, methodParams);\n } catch (e) {\n stopListening();\n rej(e);\n }\n });\n\n return typeof timeout === 'number' ? withTimeout(promise, timeout) : promise;\n}\n","import { compareVersions, type Version } from '@tma.js/utils';\n\nimport type {\n HasCheckSupportMethodParam,\n HasCheckSupportMethodName,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './methods/index.js';\n\nfunction lessOrEqual(a: Version, b: Version): boolean {\n return compareVersions(a, b) <= 0;\n}\n\n/**\n * By specified method and parameters extracts properties which could be used by\n * supports function as TWA method parameter.\n * @param method - TWA method.\n * @param params - method parameters.\n */\nexport function detectSupportParams<M extends NonEmptyMethodName>(\n method: M,\n params: MethodParams<M>,\n): HasCheckSupportMethodParam<HasCheckSupportMethodName>[] {\n if (method === 'web_app_open_link') {\n if ('try_instant_view' in params) {\n return ['try_instant_view'];\n }\n }\n\n if (method === 'web_app_set_header_color') {\n if ('color' in params) {\n return ['color'];\n }\n }\n\n return [];\n}\n\n/**\n * Returns true in case, passed parameter in specified method is supported.\n * @param method - method name\n * @param param - method parameter\n * @param inVersion - platform version.\n */\nexport function supports<M extends HasCheckSupportMethodName>(\n method: M,\n param: HasCheckSupportMethodParam<M>,\n inVersion: Version,\n): boolean;\n/**\n * Returns true in case, specified method is supported in passed version.\n * @param method - method name.\n * @param inVersion - platform version.\n */\nexport function supports(method: MethodName, inVersion: Version): boolean;\nexport function supports(\n method: MethodName,\n paramOrVersion: Version | string,\n inVersion?: string,\n): boolean {\n // Method name, parameter, target version.\n if (typeof inVersion === 'string') {\n if (method === 'web_app_open_link') {\n if (paramOrVersion === 'try_instant_view') {\n return lessOrEqual('6.4', inVersion);\n }\n }\n\n if (method === 'web_app_set_header_color') {\n if (paramOrVersion === 'color') {\n return lessOrEqual('6.9', inVersion);\n }\n }\n }\n\n // Method name, target version.\n switch (method) {\n case 'web_app_open_tg_link':\n case 'web_app_open_invoice':\n case 'web_app_setup_back_button':\n case 'web_app_set_background_color':\n case 'web_app_set_header_color':\n case 'web_app_trigger_haptic_feedback':\n return lessOrEqual('6.1', paramOrVersion);\n case 'web_app_open_popup':\n return lessOrEqual('6.2', paramOrVersion);\n case 'web_app_close_scan_qr_popup':\n case 'web_app_open_scan_qr_popup':\n case 'web_app_read_text_from_clipboard':\n return lessOrEqual('6.4', paramOrVersion);\n case 'web_app_invoke_custom_method':\n case 'web_app_request_write_access':\n case 'web_app_request_phone':\n return lessOrEqual('6.9', paramOrVersion);\n default:\n return true;\n }\n}\n"],"names":["currentDebug","currentTargetOrigin","setDebug","value","setTargetOrigin","targetOrigin","log","level","args","utilLog","isNullOrUndefined","themeChangedPayload","json","rgb","viewportChangedPayload","number","boolean","popupClosedPayload","string","qrTextReceivedPayload","invoiceClosedPayload","clipboardTextReceivedPayload","writeAccessRequestedPayload","phoneRequestedPayload","customMethodInvokedPayload","eventDataJson","emitEvent","eventType","eventData","defineEventHandlers","wnd","path","pointer","item","idx","arr","onTelegramEvent","cb","event","CACHED_EMITTER","createEmitter","emitter","UtilEventEmitter","emit","data","cause","singletonEmitter","off","listener","on","once","unsubscribe","subscribe","hasExternalNotify","isRecord","hasWebviewProxy","isIframe","postEvent","paramsOrOptions","options","postOptions","globalTargetOrigin","request","method","eventOrParams","eventOrOptions","executionOptions","methodParams","events","requestId","defaultPostEvent","timeout","capture","promise","res","rej","stoppers","ev","stopListening","stop","e","withTimeout","lessOrEqual","a","b","compareVersions","detectSupportParams","params","supports","paramOrVersion","inVersion"],"mappings":"2iBAEA,IAAIA,EAAe,GACfC,EAAsB,2BAQnB,SAASC,EAASC,EAAsB,CAC9BH,EAAAG,CACjB,CAUO,SAASC,EAAgBD,EAAqB,CAC7BF,EAAAE,CACxB,CAKO,SAASE,GAAuB,CAC9B,OAAAJ,CACT,CAOa,MAAAK,EAAsB,CAACC,KAAUC,IAAS,CACjDR,GACMS,EAAAA,IAAAF,EAAO,WAAY,GAAGC,CAAI,CAEtC,EC3BA,SAASE,EAAkBP,EAAyB,CAC3C,OAAAA,GAAU,IACnB,CAKO,MAAMQ,EAAsBC,EAAAA,KAA0B,CAC3D,aAAcA,EAAAA,KAA0C,CACtD,SAAUC,EAAAA,IAAI,EAAE,SAAS,EACzB,WAAYA,EAAAA,IAAI,EAAE,SAAS,EAC3B,WAAYA,EAAAA,IAAI,EAAE,SAAS,EAC3B,WAAYA,EAAAA,IAAI,EAAE,SAAS,EAC3B,aAAcA,EAAAA,IAAI,EAAE,SAAS,EAC7B,kBAAmBA,EAAAA,IAAI,EAAE,SAAS,EAClC,mBAAoBA,EAAAA,IAAI,EAAE,SAAS,CAAA,CACpC,CACH,CAAC,EAMYC,EAAyBF,EAAAA,KAA6B,CACjE,OAAQG,EAAAA,OAAO,EACf,MAAOA,EAAAA,OAAS,EAAA,SAASL,CAAiB,EAAE,QAAQ,IAAM,OAAO,UAAU,EAC3E,gBAAiBM,EAAAA,QAAQ,EACzB,YAAaA,EAAAA,QAAQ,CACvB,CAAC,EAKYC,EAAqBL,EAAAA,KAAyB,CACzD,UAAWM,EAAA,OAAA,EAAS,SAASR,CAAiB,CAChD,CAAC,EAKYS,EAAwBP,EAAAA,KAA4B,CAC/D,KAAMM,EAAAA,OAAO,EAAE,SAAS,CAC1B,CAAC,EAKYE,EAAuBR,EAAAA,KAA2B,CAC7D,KAAMM,EAAAA,OAAO,EACb,OAAQA,EAAAA,OAAO,CACjB,CAAC,EAKYG,EAA+BT,EAAAA,KAAmC,CAC7E,OAAQM,EAAAA,OAAO,EACf,KAAOf,GAAWA,IAAU,KAAOA,EAAQe,EAAA,OAAA,EAAS,SAAA,EAAW,MAAMf,CAAK,CAC5E,CAAC,EAKYmB,EAA8BV,EAAAA,KAAkC,CAAE,OAAQM,EAAA,OAAA,CAAU,CAAA,EAKpFK,EAAwBX,EAAAA,KAA4B,CAAE,OAAQM,EAAA,OAAA,CAAU,CAAA,EAKxEM,EAA6BZ,EAAAA,KAAiC,CACzE,OAAQM,EAAAA,OAAO,EACf,OAASf,GAAUA,EACnB,MAAOe,EAAAA,OAAO,EAAE,SAAS,CAC3B,CAAC,ECxFKO,EAAgBb,EAAAA,KAAiD,CACrE,UAAWM,EAAAA,OAAO,EAClB,UAAYf,GAAUA,CACxB,CAAC,EAUD,SAASuB,EAAUC,EAAmBC,EAA0B,CACvD,OAAA,cAAc,IAAI,aAAa,UAAW,CAC/C,KAAM,KAAK,UAAU,CAAE,UAAAD,EAAW,UAAAC,EAAW,CAC9C,CAAA,CAAC,CACJ,CAOA,SAASC,GAA4B,CACnC,MAAMC,EAAW,OAGb,mCAAoCA,GAOxC,CACE,CAAC,gCAAgC,EACjC,CAAC,oBAAqB,cAAc,EACpC,CAAC,WAAY,UAAW,cAAc,CAAA,EACtC,QAASC,GAAS,CAElB,IAAIC,EAAUF,EAEdC,EAAK,QAAQ,CAACE,EAAMC,EAAKC,IAAQ,CAE3B,GAAAD,IAAQC,EAAI,OAAS,EAAG,CAC1BH,EAAQC,CAAI,EAAIP,EAChB,MACF,CAEMO,KAAQD,IACJA,EAAAC,CAAI,EAAI,IAElBD,EAAUA,EAAQC,CAAI,CAAA,CACvB,CAAA,CACF,CACH,CAQO,SAASG,EAAgBC,EAA2D,CAErER,IAGb,OAAA,iBAAiB,UAAYS,GAAU,CACxC,GAAA,CACF,KAAM,CAAE,UAAAX,EAAW,UAAAC,GAAcH,EAAc,MAAMa,EAAM,IAAI,EAC/DD,EAAGV,EAAWC,CAAS,CAAA,MACjB,CAER,CAAA,CACD,CACH,CC/DA,MAAMW,EAAiB,8BAMhB,SAASC,GAA8B,CACtC,MAAAC,EAAwB,IAAIC,EAAAA,aAC5BC,EAA6B,CAACL,KAAeM,IAAgB,CACjEtC,EAAI,MAAO,4BAA6BgC,EAAO,GAAGM,CAAI,EAC9CH,EAAA,KAAKH,EAAO,GAAGM,CAAI,CAAA,EAOtB,cAAA,iBAAiB,SAAU,IAAM,CACtCD,EAAK,mBAAoB,CACvB,MAAO,OAAO,WACd,OAAQ,OAAO,YACf,gBAAiB,GACjB,YAAa,EAAA,CACd,CAAA,CACF,EAIeP,EAAA,CAACT,EAA+BC,IAAoB,CAC9DtB,EAAA,MAAO,sBAAuBqB,EAAWC,CAAS,EAElD,GAAA,CACF,OAAQD,EAAW,CACjB,IAAK,mBACH,OAAOgB,EAAKhB,EAAWb,EAAuB,MAAMc,CAAS,CAAC,EAEhE,IAAK,gBACH,OAAOe,EAAKhB,EAAWhB,EAAoB,MAAMiB,CAAS,CAAC,EAE7D,IAAK,eAGH,OAIKA,GAAc,KAEVe,EAAKhB,EAAW,CAAA,CAAE,EAEpBgB,EAAKhB,EAAWV,EAAmB,MAAMW,CAAS,CAAC,EAE5D,IAAK,mBACH,OAAOe,EAAKhB,EAAWT,EAAAA,OAAS,EAAA,MAAMU,CAAS,CAAC,EAElD,IAAK,mBACH,OAAOe,EAAKhB,EAAWR,EAAsB,MAAMS,CAAS,CAAC,EAE/D,IAAK,0BACH,OAAOe,EAAKhB,EAAWN,EAA6B,MAAMO,CAAS,CAAC,EAEtE,IAAK,iBACH,OAAOe,EAAKhB,EAAWP,EAAqB,MAAMQ,CAAS,CAAC,EAE9D,IAAK,kBACH,OAAOe,EAAK,kBAAmBpB,EAAsB,MAAMK,CAAS,CAAC,EAEvE,IAAK,wBACH,OAAOe,EAAK,wBAAyBnB,EAA2B,MAAMI,CAAS,CAAC,EAElF,IAAK,yBACH,OAAOe,EAAK,yBAA0BrB,EAA4B,MAAMM,CAAS,CAAC,EAGpF,IAAK,sBACL,IAAK,sBACL,IAAK,0BACL,IAAK,uBACH,OAAOe,EAAKhB,CAAS,EAGvB,QACS,OAAAgB,EAAKhB,EAAkBC,CAAS,CAC3C,QACOiB,EAAO,CACVvC,EAAA,QAAS,0BAA2BuC,CAAK,CAC/C,CAAA,CACD,EAEMJ,CACT,CAMO,SAASK,GAAiC,CAC/C,MAAMhB,EAAW,OAGjB,OAFsBA,EAAIS,CAAc,IAElB,SAChBT,EAAAS,CAAc,EAAIC,KAGjBV,EAAIS,CAAc,CAC3B,CCnHgB,SAAAQ,EAAyBT,EAAUU,EAAkC,CAClEF,IAAE,IAAIR,EAAOU,CAAQ,CACxC,CCEgB,SAAAC,EAAwBX,EAAUU,EAA2C,CAC1E,OAAAF,IAAE,GAAGR,EAAOU,CAAQ,EAC9B,IAAMD,EAAIT,EAAOU,CAAQ,CAClC,CCJgB,SAAAE,EAA0BZ,EAAUU,EAA2C,CAC5E,OAAAF,IAAE,KAAKR,EAAOU,CAAQ,EAChC,IAAMD,EAAIT,EAAOU,CAAQ,CAClC,CCPO,SAASG,EAAYH,EAAqC,CAC9CF,EAAA,EAAE,YAAYE,CAAQ,CACzC,CCEO,SAASI,EAAUJ,EAA8C,CACrD,OAAAF,EAAA,EAAE,UAAUE,CAAQ,EAC9B,IAAMG,EAAYH,CAAQ,CACnC,CCIO,SAASK,EAAgClD,EAA0C,CACxF,MAAO,aAAcA,GAChBmD,EAAS,SAAAnD,EAAM,QAAQ,GACvB,WAAYA,EAAM,UAClB,OAAOA,EAAM,SAAS,QAAW,UACxC,CAOO,SAASoD,EAA8BpD,EAAwC,CACpF,MAAO,yBAA0BA,GAC5BmD,EAAS,SAAAnD,EAAM,oBAAoB,GACnC,cAAeA,EAAM,sBACrB,OAAOA,EAAM,qBAAqB,WAAc,UACvD,CAMO,SAASqD,GAAoB,CAC9B,GAAA,CACK,OAAA,OAAO,OAAS,OAAO,SACpB,CACH,MAAA,EACT,CACF,CCGgB,SAAAC,EACd9B,EACA+B,EACAC,EACM,CACN,IAAIC,EAAgC,CAAA,EAChChC,EAEA8B,IAAoB,QAAaC,IAAY,OAE/CC,EAAc,CAAA,EACLF,IAAoB,QAAaC,IAAY,QAExCC,EAAAD,EACF/B,EAAA8B,GACHA,IAAoB,SAEzB,iBAAkBA,EACNE,EAAAF,EAEF9B,EAAA8B,GAGhB,KAAM,cAAErD,EAAewD,EAAmB,CAAA,EAAMD,EAGhD,GAAIJ,IAAY,CACP,OAAA,OAAO,YAAY,KAAK,UAAU,CACvC,UAAA7B,EACA,UAAAC,CAAA,CACD,EAAGvB,CAAY,EAChB,MACF,CAGI,GAAAgD,EAAkB,MAAM,EAAG,CACtB,OAAA,SAAS,OAAO,KAAK,UAAU,CAAE,UAAA1B,EAAW,UAAAC,CAAW,CAAA,CAAC,EAC/D,MACF,CAGI,GAAA2B,EAAgB,MAAM,EAAG,CAC3B,OAAO,qBAAqB,UAAU5B,EAAW,KAAK,UAAUC,CAAS,CAAC,EAC1E,MACF,CAIA,MAAM,IAAI,MACR,yEAAA,CAEJ,CCEO,SAASkC,EACdC,EACAC,EACAC,EACAN,EACc,CACV,IAAAO,EACAC,EACAC,EACAC,EAEA,OAAOL,GAAkB,UAAY,MAAM,QAAQA,CAAa,GAElEI,EAAS,MAAM,QAAQJ,CAAa,EAAIA,EAAgB,CAACA,CAAa,EACnDE,EAAAD,IAGJE,EAAAH,EACfI,EAAS,MAAM,QAAQH,CAAc,EAAIA,EAAiB,CAACA,CAAc,EACtDC,EAAAP,GAKjBL,EAAAA,SAASa,CAAY,GAAK,OAAOA,EAAa,QAAW,WAC3DE,EAAYF,EAAa,QAG3B,KAAM,CAAA,UAAEV,GAAYa,EAAkB,QAAAC,CAAQ,EAAIL,GAAoB,CAAA,EAChEM,EAAUN,GAAoB,YAAaA,EAC7CA,EAAiB,QACjB,KAEEO,EAAU,IAAI,QAAQ,CAACC,GAAKC,KAAQ,CAElC,MAAAC,GAAWR,EAAO,IAAKS,GAAO5B,EAAG4B,EAAKjC,GAAU,CAGhD,OAAOyB,GAAc,WAAa,CAACf,WAASV,CAAI,GAAKA,EAAK,SAAWyB,IAIrE,OAAOG,GAAY,YAAc,CAACA,EAAQ5B,CAAI,IAKpCkC,IACdJ,GAAI9B,CAAI,EACT,CAAA,CAAC,EAGIkC,EAAgB,IAAMF,GAAS,QAASG,GAASA,GAAM,EAEzD,GAAA,CAIFtB,GAAUM,EAAeI,CAAY,QAC9Ba,EAAG,CACIF,IACdH,GAAIK,CAAC,CACP,CAAA,CACD,EAED,OAAO,OAAOT,GAAY,SAAWU,EAAAA,YAAYR,EAASF,CAAO,EAAIE,CACvE,CChKA,SAASS,EAAYC,EAAYC,EAAqB,CAC7C,OAAAC,kBAAgBF,EAAGC,CAAC,GAAK,CAClC,CAQgB,SAAAE,EACdvB,EACAwB,EACyD,CACzD,OAAIxB,IAAW,qBACT,qBAAsBwB,EACjB,CAAC,kBAAkB,EAI1BxB,IAAW,4BACT,UAAWwB,EACN,CAAC,OAAO,EAIZ,EACT,CAmBgB,SAAAC,GACdzB,EACA0B,EACAC,EACS,CAEL,GAAA,OAAOA,GAAc,SAAU,CACjC,GAAI3B,IAAW,qBACT0B,IAAmB,mBACd,OAAAP,EAAY,MAAOQ,CAAS,EAIvC,GAAI3B,IAAW,4BACT0B,IAAmB,QACd,OAAAP,EAAY,MAAOQ,CAAS,CAGzC,CAGA,OAAQ3B,EAAQ,CACd,IAAK,uBACL,IAAK,uBACL,IAAK,4BACL,IAAK,+BACL,IAAK,2BACL,IAAK,kCACI,OAAAmB,EAAY,MAAOO,CAAc,EAC1C,IAAK,qBACI,OAAAP,EAAY,MAAOO,CAAc,EAC1C,IAAK,8BACL,IAAK,6BACL,IAAK,mCACI,OAAAP,EAAY,MAAOO,CAAc,EAC1C,IAAK,+BACL,IAAK,+BACL,IAAK,wBACI,OAAAP,EAAY,MAAOO,CAAc,EAC1C,QACS,MAAA,EACX,CACF"}
1
+ {"version":3,"file":"index.umd.cjs","sources":["../src/globals.ts","../src/events/parsing.ts","../src/events/onTelegramEvent.ts","../src/events/emitter.ts","../src/events/off.ts","../src/events/on.ts","../src/events/once.ts","../src/events/unsubscribe.ts","../src/events/subscribe.ts","../src/env.ts","../src/methods/postEvent.ts","../src/request.ts","../src/supports.ts"],"sourcesContent":["import { log as utilLog } from '@tma.js/logger';\n\nlet currentDebug = false;\nlet currentTargetOrigin = 'https://web.telegram.org';\n\n/**\n * Sets new debug mode. Enabling debug mode leads to printing\n * additional messages in console, related to the processes\n * inside the package.\n * @param value - should debug mode be enabled.\n */\nexport function setDebug(value: boolean): void {\n currentDebug = value;\n}\n\n/**\n * Sets new global targetOrigin, used by `postEvent` method.\n * Default value is \"https://web.telegram.org\". You don't need to\n * use this method until you know what you are doing.\n *\n * This method could be used for test purposes.\n * @param value - new target origin.\n */\nexport function setTargetOrigin(value: string): void {\n currentTargetOrigin = value;\n}\n\n/**\n * Returns current global target origin.\n */\nexport function targetOrigin(): string {\n return currentTargetOrigin;\n}\n\n/**\n * Logs message in case, debug mode is enabled.\n * @param level - log level\n * @param args - values to print.\n */\nexport const log: typeof utilLog = (level, ...args) => {\n if (currentDebug) {\n utilLog(level, '[Bridge]', ...args);\n }\n};\n","import {\n number,\n string,\n boolean,\n json,\n rgb,\n} from '@tma.js/parsing';\n\nimport type {\n ClipboardTextReceivedPayload, CustomMethodInvokedPayload,\n InvoiceClosedPayload, PhoneRequestedPayload,\n PopupClosedPayload, QrTextReceivedPayload,\n ThemeChangedPayload,\n ViewportChangedPayload, WriteAccessRequestedPayload,\n} from './payloads.js';\n\nfunction isNullOrUndefined(value: unknown): boolean {\n return value === null || value === undefined;\n}\n\n/**\n * Parses incoming value as ThemeChangedPayload.\n */\nexport const themeChangedPayload = json<ThemeChangedPayload>({\n theme_params: json<ThemeChangedPayload['theme_params']>({\n bg_color: rgb().optional(),\n text_color: rgb().optional(),\n hint_color: rgb().optional(),\n link_color: rgb().optional(),\n button_color: rgb().optional(),\n button_text_color: rgb().optional(),\n secondary_bg_color: rgb().optional(),\n }),\n});\n\n/**\n * Parses incoming value as ViewportChangedPayload.\n * @param value - value to parse.\n */\nexport const viewportChangedPayload = json<ViewportChangedPayload>({\n height: number(),\n width: number().optional(isNullOrUndefined).default(() => window.innerWidth),\n is_state_stable: boolean(),\n is_expanded: boolean(),\n});\n\n/**\n * Parses incoming value as PopupClosedPayload.\n */\nexport const popupClosedPayload = json<PopupClosedPayload>({\n button_id: string().optional(isNullOrUndefined),\n});\n\n/**\n * Parses incoming value as QrTextReceivedPayload.\n */\nexport const qrTextReceivedPayload = json<QrTextReceivedPayload>({\n data: string().optional(),\n});\n\n/**\n * Parses incoming value as InvoiceClosedPayload.\n */\nexport const invoiceClosedPayload = json<InvoiceClosedPayload>({\n slug: string(),\n status: string(),\n});\n\n/**\n * Parses incoming value as clipboard text received payload.\n */\nexport const clipboardTextReceivedPayload = json<ClipboardTextReceivedPayload>({\n req_id: string(),\n data: (value) => (value === null ? value : string().optional().parse(value)),\n});\n\n/**\n * Parses incoming value as WriteAccessRequestedPayload.\n */\nexport const writeAccessRequestedPayload = json<WriteAccessRequestedPayload>({ status: string() });\n\n/**\n * Parses incoming value as PhoneRequestedPayload.\n */\nexport const phoneRequestedPayload = json<PhoneRequestedPayload>({ status: string() });\n\n/**\n * Parses incoming value as CustomMethodInvokedPayload.\n */\nexport const customMethodInvokedPayload = json<CustomMethodInvokedPayload>({\n req_id: string(),\n result: (value) => value,\n error: string().optional(),\n});\n","import { json, string } from '@tma.js/parsing';\n\n/**\n * Extracts event data from native application event.\n */\nconst eventDataJson = json<{ eventType: string; eventData?: unknown }>({\n eventType: string(),\n eventData: (value) => value,\n});\n\n/**\n * Emits event sent from Telegram native application like it was sent in\n * default web environment between 2 iframes. It dispatches new MessageEvent\n * and expects it to be handled via `window.addEventListener('message', ...)`\n * as developer would do it to handle messages sent from parent iframe.\n * @param eventType - event name.\n * @param eventData - event payload.\n */\nfunction emitEvent(eventType: string, eventData: unknown): void {\n window.dispatchEvent(new MessageEvent('message', {\n data: JSON.stringify({ eventType, eventData }),\n }));\n}\n\n/**\n * Defines special handlers by known paths, which are recognized by\n * Telegram as ports to receive events. This function also sets special\n * function in global window object to prevent duplicate declaration.\n */\nfunction defineEventHandlers(): void {\n const wnd: any = window;\n\n // Prevent from duplicate event handlers definition.\n if ('TelegramGameProxy_receiveEvent' in wnd) {\n return;\n }\n\n // Iterate over each path, where \"receiveEvent\" function should be\n // defined. This function is called by external environment in case,\n // it wants to emit some event.\n [\n ['TelegramGameProxy_receiveEvent'], // Windows Phone.\n ['TelegramGameProxy', 'receiveEvent'], // Desktop.\n ['Telegram', 'WebView', 'receiveEvent'], // Android and iOS.\n ].forEach((path) => {\n // Path starts from \"window\" object.\n let pointer = wnd;\n\n path.forEach((item, idx, arr) => {\n // We are on the last iteration, where function property name is passed.\n if (idx === arr.length - 1) {\n pointer[item] = emitEvent;\n return;\n }\n\n if (!(item in pointer)) {\n pointer[item] = {};\n }\n pointer = pointer[item];\n });\n });\n}\n\n/**\n * Adds listener to window \"message\" event assuming, that this event could\n * be sent by Telegram native application. Calls passed callback with event\n * type and data.\n * @param cb - callback to call.\n */\nexport function onTelegramEvent(cb: (eventType: string, eventData: unknown) => void): void {\n // Define event handlers to make sure, message handler will work correctly.\n defineEventHandlers();\n\n // We expect Telegram to send us new event through \"message\" event.\n window.addEventListener('message', (event) => {\n try {\n const { eventType, eventData } = eventDataJson.parse(event.data);\n cb(eventType, eventData);\n } catch {\n // We ignore incorrect messages as they could be generated by any other code.\n }\n });\n}\n","import { EventEmitter as UtilEventEmitter } from '@tma.js/event-emitter';\nimport { string } from '@tma.js/parsing';\n\nimport { log } from '../globals.js';\nimport {\n clipboardTextReceivedPayload,\n customMethodInvokedPayload,\n invoiceClosedPayload,\n phoneRequestedPayload,\n popupClosedPayload,\n qrTextReceivedPayload,\n themeChangedPayload,\n viewportChangedPayload,\n writeAccessRequestedPayload,\n} from './parsing.js';\nimport { onTelegramEvent } from './onTelegramEvent.js';\n\nimport type { EventEmitter, EventName } from './events.js';\n\nconst CACHED_EMITTER = '__telegram-cached-emitter__';\n\n/**\n * Returns event emitter which could be safely used, to process events from\n * Telegram native application.\n */\nexport function createEmitter(): EventEmitter {\n const emitter: EventEmitter = new UtilEventEmitter();\n const emit: EventEmitter['emit'] = (event: any, ...data: any[]) => {\n log('log', 'Emitting processed event:', event, ...data);\n emitter.emit(event, ...data);\n };\n\n // Desktop version of Telegram is sometimes not sending the viewport_changed\n // event. For example, when main button is shown. That's why we should\n // add our own listener to make sure, viewport information is always fresh.\n // Issue: https://github.com/Telegram-Web-Apps/tma.js/issues/10\n window.addEventListener('resize', () => {\n emit('viewport_changed', {\n width: window.innerWidth,\n height: window.innerHeight,\n is_state_stable: true,\n is_expanded: true,\n });\n });\n\n // In case, any Telegram event was received, we should prepare data before\n // passing it to emitter.\n onTelegramEvent((eventType: EventName | string, eventData): void => {\n log('log', 'Received raw event:', eventType, eventData);\n\n try {\n switch (eventType) {\n case 'viewport_changed':\n return emit(eventType, viewportChangedPayload.parse(eventData));\n\n case 'theme_changed':\n return emit(eventType, themeChangedPayload.parse(eventData));\n\n case 'popup_closed':\n // FIXME: Payloads are different on different platforms.\n // Issue: https://github.com/Telegram-Web-Apps/tma.js/issues/2\n if (\n // Sent on desktop.\n eventData === undefined\n // Sent on iOS.\n || eventData === null\n ) {\n return emit(eventType, {});\n }\n return emit(eventType, popupClosedPayload.parse(eventData));\n\n case 'set_custom_style':\n return emit(eventType, string().parse(eventData));\n\n case 'qr_text_received':\n return emit(eventType, qrTextReceivedPayload.parse(eventData));\n\n case 'clipboard_text_received':\n return emit(eventType, clipboardTextReceivedPayload.parse(eventData));\n\n case 'invoice_closed':\n return emit(eventType, invoiceClosedPayload.parse(eventData));\n\n case 'phone_requested':\n return emit('phone_requested', phoneRequestedPayload.parse(eventData));\n\n case 'custom_method_invoked':\n return emit('custom_method_invoked', customMethodInvokedPayload.parse(eventData));\n\n case 'write_access_requested':\n return emit('write_access_requested', writeAccessRequestedPayload.parse(eventData));\n\n // Events which have no parameters.\n case 'main_button_pressed':\n case 'back_button_pressed':\n case 'settings_button_pressed':\n case 'scan_qr_popup_closed':\n return emit(eventType);\n\n // All other event listeners will receive unknown type of data.\n default:\n return emit(eventType as any, eventData);\n }\n } catch (cause) {\n log('error', 'Error processing event:', cause);\n }\n });\n\n return emitter;\n}\n\n/**\n * Returns singleton instance of bridge EventEmitter. Also, defines\n * Telegram event handlers.\n */\nexport function singletonEmitter(): EventEmitter {\n const wnd: any = window;\n const cachedEmitter = wnd[CACHED_EMITTER];\n\n if (cachedEmitter === undefined) {\n wnd[CACHED_EMITTER] = createEmitter();\n }\n\n return wnd[CACHED_EMITTER];\n}\n","import { singletonEmitter } from './emitter.js';\n\nimport type { EventName, EventListener } from './events.js';\n\n/**\n * Removes listener from specified event.\n * @param event - event to listen.\n * @param listener - event listener.\n */\nexport function off<E extends EventName>(event: E, listener: EventListener<E>): void {\n singletonEmitter().off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { off } from './off.js';\n\nimport type { EventName, EventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Adds new listener to the specified event. Returns handler\n * which allows to stop listening to event.\n * @param event - event name.\n * @param listener - event listener.\n */\nexport function on<E extends EventName>(event: E, listener: EventListener<E>): StopListening {\n singletonEmitter().on(event, listener);\n return () => off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { off } from './off.js';\n\nimport type { EventName, EventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Works the same as \"on\" method, but after catching the event, will remove event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\nexport function once<E extends EventName>(event: E, listener: EventListener<E>): StopListening {\n singletonEmitter().once(event, listener);\n return () => off(event, listener);\n}\n","import { singletonEmitter } from './emitter.js';\n\nimport type { GlobalEventListener } from './events.js';\n\n/**\n * Removes global event listener.\n * @param listener - event listener.\n */\nexport function unsubscribe(listener: GlobalEventListener): void {\n singletonEmitter().unsubscribe(listener);\n}\n","import { singletonEmitter } from './emitter.js';\nimport { unsubscribe } from './unsubscribe.js';\n\nimport type { GlobalEventListener } from './events.js';\n\ntype StopListening = () => void;\n\n/**\n * Subscribes to all events sent from the native Telegram application.\n * Returns function used to remove added event listener.\n * @param listener - event listener.\n */\nexport function subscribe(listener: GlobalEventListener): StopListening {\n singletonEmitter().subscribe(listener);\n return () => unsubscribe(listener);\n}\n","import { isRecord } from '@tma.js/utils';\n\ntype AnyFunc = (...args: unknown[]) => unknown;\n\ntype WithExternalNotify<T> = T & {\n external: { notify: AnyFunc }\n};\n\ntype WithWebviewProxy<T> = T & {\n TelegramWebviewProxy: {\n postEvent: AnyFunc;\n }\n};\n\n/**\n * Returns true in case, passed value contains path `external.notify` property and `notify` is a\n * function.\n * @param value - value to check.\n */\nexport function hasExternalNotify<T extends {}>(value: T): value is WithExternalNotify<T> {\n return 'external' in value\n && isRecord(value.external)\n && 'notify' in value.external\n && typeof value.external.notify === 'function';\n}\n\n/**\n * Returns true in case, passed value contains path `TelegramWebviewProxy.postEvent` property and\n * `postEvent` is a function.\n * @param value - value to check.\n */\nexport function hasWebviewProxy<T extends {}>(value: T): value is WithWebviewProxy<T> {\n return 'TelegramWebviewProxy' in value\n && isRecord(value.TelegramWebviewProxy)\n && 'postEvent' in value.TelegramWebviewProxy\n && typeof value.TelegramWebviewProxy.postEvent === 'function';\n}\n\n/**\n * Returns true in case, current environment is iframe.\n * @see https://stackoverflow.com/a/326076\n */\nexport function isIframe(): boolean {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n}\n","import {\n isIframe,\n hasExternalNotify,\n hasWebviewProxy,\n} from '../env.js';\nimport { targetOrigin as globalTargetOrigin } from '../globals.js';\n\nimport type {\n EmptyMethodName,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './params.js';\n\ninterface PostEventOptions {\n /**\n * Origin used while posting message. This option is only used in case,\n * current environment is browser (Web version of Telegram) and could\n * be used for test purposes.\n * @default 'https://web.telegram.org'\n */\n targetOrigin?: string;\n}\n\nexport type PostEvent = typeof postEvent;\n\n/**\n * Sends event to native application which launched Web App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param params - event parameters.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current\n * environment and possible way to send event.\n */\nexport function postEvent<E extends NonEmptyMethodName>(\n eventType: E,\n params: MethodParams<E>,\n options?: PostEventOptions,\n): void;\n\n/**\n * Sends event to native application which launched Web App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current\n * environment and possible way to send event.\n */\nexport function postEvent(eventType: EmptyMethodName, options?: PostEventOptions): void;\n\nexport function postEvent(\n eventType: MethodName,\n paramsOrOptions?: MethodParams<MethodName> | PostEventOptions,\n options?: PostEventOptions,\n): void {\n let postOptions: PostEventOptions = {};\n let eventData: any;\n\n if (paramsOrOptions === undefined && options === undefined) {\n // Parameters and options were not passed.\n postOptions = {};\n } else if (paramsOrOptions !== undefined && options !== undefined) {\n // Both parameters and options passed.\n postOptions = options;\n eventData = paramsOrOptions;\n } else if (paramsOrOptions !== undefined) {\n // Only parameters were passed.\n if ('targetOrigin' in paramsOrOptions) {\n postOptions = paramsOrOptions;\n } else {\n eventData = paramsOrOptions;\n }\n }\n const { targetOrigin = globalTargetOrigin() } = postOptions;\n\n // Telegram Web.\n if (isIframe()) {\n window.parent.postMessage(JSON.stringify({\n eventType,\n eventData,\n }), targetOrigin);\n return;\n }\n\n // Telegram for Windows Phone or Android.\n if (hasExternalNotify(window)) {\n window.external.notify(JSON.stringify({ eventType, eventData }));\n return;\n }\n\n // Telegram for iOS and macOS.\n if (hasWebviewProxy(window)) {\n window.TelegramWebviewProxy.postEvent(eventType, JSON.stringify(eventData));\n return;\n }\n\n // Otherwise current environment is unknown, and we are not able to send\n // event.\n throw new Error(\n 'Unable to determine current environment and possible way to send event.',\n );\n}\n","import { withTimeout, isRecord } from '@tma.js/utils';\n\nimport type { And, If, IsNever } from '@tma.js/util-types';\n\nimport { postEvent as defaultPostEvent, type PostEvent } from './methods/postEvent.js';\nimport { on, type EventName, type EventParams, type EventHasParams } from './events/index.js';\n\nimport type {\n EmptyMethodName, MethodHasParams,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './methods/params.js';\n\n/**\n * Names of methods, which require passing \"req_id\" parameter.\n */\ntype MethodNameWithRequestId = {\n [Method in MethodName]: If<\n And<MethodHasParams<Method>, MethodParams<Method> extends { req_id: string } ? true : false>,\n Method,\n never\n >;\n}[MethodName];\n\n/**\n * Names of events, which contain \"req_id\" parameter.\n */\ntype EventNameWithRequestId = {\n [Event in EventName]: If<\n And<EventHasParams<Event>, EventParams<Event> extends { req_id: string } ? true : false>,\n Event,\n never\n >;\n}[EventName];\n\nexport interface RequestOptions {\n /**\n * Bridge postEvent method.\n * @default Global postEvent method.\n */\n postEvent?: PostEvent;\n\n /**\n * Execution timeout.\n */\n timeout?: number;\n}\n\nexport interface RequestOptionsAdvanced<EventPayload> extends RequestOptions {\n /**\n * Should return true in case, this event should be captured. If not specified,\n * request is not skipping captured events.\n */\n capture?: If<IsNever<EventPayload>, () => boolean, (payload: EventPayload) => boolean>;\n}\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, event with specified in method request identifier\n * was captured.\n * @param method - method to execute.\n * @param params - method parameters.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<\n Method extends MethodNameWithRequestId,\n Event extends EventNameWithRequestId,\n>(\n method: Method,\n params: MethodParams<Method>,\n event: Event | Event[],\n options?: RequestOptions,\n): Promise<EventParams<Event>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<Method extends EmptyMethodName, Event extends EventName>(\n method: Method,\n event: Event | Event[],\n options?: RequestOptionsAdvanced<EventParams<Event>>,\n): Promise<EventParams<Event>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute\n * @param params - method parameters.\n * @param event - event or events to listen\n * @param options - additional execution options.\n */\nexport function request<Method extends NonEmptyMethodName, Event extends EventName>(\n method: Method,\n params: MethodParams<Method>,\n event: Event | Event[],\n options?: RequestOptionsAdvanced<EventParams<Event>>,\n): Promise<EventParams<Event>>;\n\nexport function request(\n method: MethodName,\n eventOrParams: EventName | EventName[] | EventParams<any>,\n eventOrOptions?: EventName | EventName[] | RequestOptions | RequestOptionsAdvanced<any>,\n options?: RequestOptions | RequestOptionsAdvanced<any>,\n): Promise<any> {\n let executionOptions: RequestOptions | RequestOptionsAdvanced<any> | undefined;\n let methodParams: EventParams<any> | undefined;\n let events: EventName[];\n let requestId: string | undefined;\n\n if (typeof eventOrParams === 'string' || Array.isArray(eventOrParams)) {\n // Override: [method, event, options?]\n events = Array.isArray(eventOrParams) ? eventOrParams : [eventOrParams] as EventName[];\n executionOptions = eventOrOptions as (RequestOptionsAdvanced<any> | undefined);\n } else {\n // Override: [method, params, event, options?]\n methodParams = eventOrParams as EventParams<any>;\n events = Array.isArray(eventOrOptions) ? eventOrOptions : [eventOrOptions] as EventName[];\n executionOptions = options;\n }\n\n // In case, method parameters were passed, and they contained request identifier, we should store\n // it and wait for the event with this identifier to occur.\n if (isRecord(methodParams) && typeof methodParams.req_id === 'string') {\n requestId = methodParams.req_id;\n }\n\n const { postEvent = defaultPostEvent, timeout } = executionOptions || {};\n const capture = executionOptions && 'capture' in executionOptions\n ? executionOptions.capture\n : null;\n\n const promise = new Promise((res, rej) => {\n // Iterate over each event and create event listener.\n const stoppers = events.map((ev) => on(ev, (data?) => {\n // If request identifier was specified, we are waiting for event with the same value\n // to occur.\n if (typeof requestId === 'string' && (!isRecord(data) || data.req_id !== requestId)) {\n return;\n }\n\n if (typeof capture === 'function' && !capture(data)) {\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n stopListening();\n res(data);\n }));\n\n // Function which removes all event listeners.\n const stopListening = () => stoppers.forEach((stop) => stop());\n\n try {\n // We are wrapping this call in try catch, because it can throw errors in case,\n // compatibility check was enabled. We want an error to be captured by promise, not by\n // another one external try catch.\n postEvent(method as any, methodParams);\n } catch (e) {\n stopListening();\n rej(e);\n }\n });\n\n return typeof timeout === 'number' ? withTimeout(promise, timeout) : promise;\n}\n","import { compareVersions, type Version } from '@tma.js/utils';\n\nimport type {\n HasCheckSupportMethodParam,\n HasCheckSupportMethodName,\n MethodName,\n MethodParams,\n NonEmptyMethodName,\n} from './methods/index.js';\n\nfunction lessOrEqual(a: Version, b: Version): boolean {\n return compareVersions(a, b) <= 0;\n}\n\n/**\n * By specified method and parameters extracts properties which could be used by\n * supports function as TWA method parameter.\n * @param method - TWA method.\n * @param params - method parameters.\n */\nexport function detectSupportParams<M extends NonEmptyMethodName>(\n method: M,\n params: MethodParams<M>,\n): HasCheckSupportMethodParam<HasCheckSupportMethodName>[] {\n if (method === 'web_app_open_link') {\n if ('try_instant_view' in params) {\n return ['try_instant_view'];\n }\n }\n\n if (method === 'web_app_set_header_color') {\n if ('color' in params) {\n return ['color'];\n }\n }\n\n return [];\n}\n\n/**\n * Returns true in case, passed parameter in specified method is supported.\n * @param method - method name\n * @param param - method parameter\n * @param inVersion - platform version.\n */\nexport function supports<M extends HasCheckSupportMethodName>(\n method: M,\n param: HasCheckSupportMethodParam<M>,\n inVersion: Version,\n): boolean;\n/**\n * Returns true in case, specified method is supported in passed version.\n * @param method - method name.\n * @param inVersion - platform version.\n */\nexport function supports(method: MethodName, inVersion: Version): boolean;\nexport function supports(\n method: MethodName,\n paramOrVersion: Version | string,\n inVersion?: string,\n): boolean {\n // Method name, parameter, target version.\n if (typeof inVersion === 'string') {\n if (method === 'web_app_open_link') {\n if (paramOrVersion === 'try_instant_view') {\n return lessOrEqual('6.4', inVersion);\n }\n }\n\n if (method === 'web_app_set_header_color') {\n if (paramOrVersion === 'color') {\n return lessOrEqual('6.9', inVersion);\n }\n }\n }\n\n // Method name, target version.\n switch (method) {\n case 'web_app_open_tg_link':\n case 'web_app_open_invoice':\n case 'web_app_setup_back_button':\n case 'web_app_set_background_color':\n case 'web_app_set_header_color':\n case 'web_app_trigger_haptic_feedback':\n return lessOrEqual('6.1', paramOrVersion);\n case 'web_app_open_popup':\n return lessOrEqual('6.2', paramOrVersion);\n case 'web_app_close_scan_qr_popup':\n case 'web_app_open_scan_qr_popup':\n case 'web_app_read_text_from_clipboard':\n return lessOrEqual('6.4', paramOrVersion);\n case 'web_app_invoke_custom_method':\n case 'web_app_request_write_access':\n case 'web_app_request_phone':\n return lessOrEqual('6.9', paramOrVersion);\n case 'web_app_setup_settings_button':\n return lessOrEqual('6.10', paramOrVersion);\n default:\n return true;\n }\n}\n"],"names":["currentDebug","currentTargetOrigin","setDebug","value","setTargetOrigin","targetOrigin","log","level","args","utilLog","isNullOrUndefined","themeChangedPayload","json","rgb","viewportChangedPayload","number","boolean","popupClosedPayload","string","qrTextReceivedPayload","invoiceClosedPayload","clipboardTextReceivedPayload","writeAccessRequestedPayload","phoneRequestedPayload","customMethodInvokedPayload","eventDataJson","emitEvent","eventType","eventData","defineEventHandlers","wnd","path","pointer","item","idx","arr","onTelegramEvent","cb","event","CACHED_EMITTER","createEmitter","emitter","UtilEventEmitter","emit","data","cause","singletonEmitter","off","listener","on","once","unsubscribe","subscribe","hasExternalNotify","isRecord","hasWebviewProxy","isIframe","postEvent","paramsOrOptions","options","postOptions","globalTargetOrigin","request","method","eventOrParams","eventOrOptions","executionOptions","methodParams","events","requestId","defaultPostEvent","timeout","capture","promise","res","rej","stoppers","ev","stopListening","stop","e","withTimeout","lessOrEqual","a","b","compareVersions","detectSupportParams","params","supports","paramOrVersion","inVersion"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tma.js/bridge",
3
- "version": "1.3.4",
3
+ "version": "1.3.5",
4
4
  "description": "Communication layer between Telegram and frontend applications.",
5
5
  "author": "Vladislav Kibenko <wolfram.deus@gmail.com>",
6
6
  "homepage": "https://github.com/Telegram-Mini-Apps/tma.js#readme",
@@ -55,7 +55,7 @@
55
55
  "access": "public"
56
56
  },
57
57
  "scripts": {
58
- "test": "jest",
58
+ "test": "vitest",
59
59
  "lint": "eslint -c .eslintrc.cjs src/**/* __tests__/**/*",
60
60
  "build": "vite build"
61
61
  }
@@ -197,6 +197,15 @@ export interface MethodsParams {
197
197
  text_color?: string;
198
198
  }>;
199
199
 
200
+ /**
201
+ * Updates current information about Settings Button.
202
+ * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_setup_settings_button
203
+ * @since 6.10
204
+ */
205
+ web_app_setup_settings_button: CreateParams<{
206
+ is_visible: boolean;
207
+ }>;
208
+
200
209
  /**
201
210
  * Generates haptic feedback event.
202
211
  * @see https://docs.telegram-mini-apps.com/docs/apps-communication/methods#web_app_trigger_haptic_feedback
package/src/supports.ts CHANGED
@@ -93,6 +93,8 @@ export function supports(
93
93
  case 'web_app_request_write_access':
94
94
  case 'web_app_request_phone':
95
95
  return lessOrEqual('6.9', paramOrVersion);
96
+ case 'web_app_setup_settings_button':
97
+ return lessOrEqual('6.10', paramOrVersion);
96
98
  default:
97
99
  return true;
98
100
  }