@telegram-apps/bridge
Version:
TypeScript package to provide communication layer between Mini App and Telegram application.
5 lines (4 loc) • 13.4 kB
JavaScript
;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("valibot"),b=require("better-promises"),w=require("@telegram-apps/toolkit"),l=require("@telegram-apps/transformers"),oe=require("mitt"),M=require("@telegram-apps/signals"),h=require("error-kid");function S(e){return btoa(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g,(r,t)=>String.fromCharCode(parseInt(`0x${t}`)))).replace(/\+/g,"-").replace(/\//g,"_")}function N(e){return decodeURIComponent(atob(e).replace(/-/g,"+").replace(/_/g,"/").split("").map(r=>"%"+("00"+r.charCodeAt(0).toString(16)).slice(-2)).join(""))}function T(e){return n.is(n.looseObject({TelegramWebviewProxy:n.looseObject({postEvent:n.function()})}),e)}function C(){try{return window.self!==window.top}catch{return!0}}function ae(e,r){const t=new Map,o=oe(),s=(a,i,c)=>{c||(c=!1);const p=t.get(a)||new Map;t.set(a,p);const _=p.get(i)||[];p.set(i,_);const f=_.findIndex(m=>m[1]===c);if(f>=0&&(o.off(a,_[f][0]),_.splice(f,1),!_.length&&(p.delete(i),!p.size))){const m=t.size;t.delete(a),m&&!t.size&&r()}};return[function(i,c,p){!t.size&&e();const _=()=>{s(i,c,p)},f=(...U)=>{p&&_(),i==="*"?c(U):c(...U)};o.on(i,f);const m=t.get(i)||new Map;t.set(i,m);const x=m.get(c)||[];return m.set(c,x),x.push([f,p||!1]),_},s,o.emit,function(){const i=t.size;o.all.clear(),t.clear(),i&&r()}]}function v(e,r){window.dispatchEvent(new MessageEvent("message",{data:JSON.stringify({eventType:e,eventData:r}),source:window.parent}))}let y=!1;const I=e=>{g().log("Event received:",e)};function G(e){e!==y&&(y=e,y?j("*",I):Q("*",I))}const g=M.signal(w.createLogger("Bridge",{bgColor:"#9147ff",textColor:"white",shouldLog(){return y}}));function J(e,r,t,o){Object.defineProperty(e,r,{enumerable:!0,configurable:!0,get:t,set:o})}function O(e,r){const t=e[r];J(e,r,()=>t,o=>{Object.entries(o).forEach(([s,a])=>{t[s]=a})})}function W(e,r,t){Object.defineProperty(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t})}function P(e,r,t){const o=e[r],s=[t];typeof o=="function"&&s.push(o);const a=(...c)=>{s.forEach(p=>{p(...c)})},i=Object.assign((...c)=>{a(...c)},{unwrap(){const{length:c}=s;if(c===1){delete e[r];return}if(c===2){W(e,r,s[1]);return}s.unshift(1),W(e,r,a)}});J(e,r,()=>i,c=>{s.push(c)})}const ne={clipboard_text_received:n.looseObject({req_id:n.string(),data:n.nullish(n.string())}),custom_method_invoked:n.looseObject({req_id:n.string(),result:n.optional(n.unknown()),error:n.optional(n.string())}),popup_closed:n.nullish(n.looseObject({button_id:n.nullish(n.string(),()=>{})}),{}),viewport_changed:n.looseObject({height:n.number(),width:n.nullish(n.number(),()=>window.innerWidth),is_state_stable:n.boolean(),is_expanded:n.boolean()}),theme_changed:n.looseObject({theme_params:l.themeParams()})};function R(e){if(e.source!==window.parent)return;let r;try{r=n.parse(n.pipe(n.string(),l.jsonParse(),l.MiniAppsMessageSchema),e.data)}catch{return}const{eventType:t,eventData:o}=r,s=ne[t];let a;try{a=s?n.parse(s,o):o}catch(i){return g().forceError([`An error occurred processing the "${t}" event from the Telegram application.`,"Please, file an issue here:","https://github.com/Telegram-Mini-Apps/telegram-apps/issues/new/choose"].join(`
`),r,i)}se(t,a)}const[j,Q,se,B]=ae(()=>{const e=window;!e.TelegramGameProxy&&(e.TelegramGameProxy={}),P(e.TelegramGameProxy,"receiveEvent",v),O(e,"TelegramGameProxy"),!e.Telegram&&(e.Telegram={}),!e.Telegram.WebView&&(e.Telegram.WebView={}),P(e.Telegram.WebView,"receiveEvent",v),O(e.Telegram,"WebView"),P(e,"TelegramGameProxy_receiveEvent",v),window.addEventListener("message",R)},()=>{[["TelegramGameProxy_receiveEvent"],["TelegramGameProxy","receiveEvent"],["Telegram","WebView","receiveEvent"]].forEach(e=>{const r=window;let t=[void 0,r];for(const a of e)if(t=[t[1],t[1][a]],!t[1])return;const[o,s]=t;"unwrap"in s&&(s.unwrap(),o&&o!==r&&!Object.keys(o).length&&delete r[e[0]])}),window.removeEventListener("message",R)}),[K,ie]=h.errorClass("MethodUnsupportedError",(e,r)=>[`Method "${e}" is unsupported in Mini Apps version ${r}`]),[F,ce]=h.errorClass("MethodParameterUnsupportedError",(e,r,t)=>[`Parameter "${r}" of "${e}" method is unsupported in Mini Apps version ${t}`]),[H,pe]=h.errorClassWithData("LaunchParamsRetrieveError",e=>({errors:e}),e=>[["Unable to retrieve launch parameters from any known source. Perhaps, you have opened your app outside Telegram?","📖 Refer to docs for more information:","https://docs.telegram-mini-apps.com/packages/telegram-apps-bridge/environment","","Collected errors:",...e.map(([r,t])=>`Source: ${r} / ${t instanceof Error?t.message:String(t)}`)].join(`
`)]),[Y,ue]=h.errorClass("InvalidLaunchParamsError",(e,r)=>[`Invalid value for launch params: ${e}`,{cause:r}]),[X,_e]=h.errorClass("UnknownEnvError"),[Z,le]=h.errorClass("InvokeCustomMethodError",e=>[`Server returned error: ${e}`]),d=M.signal((...e)=>{try{window.parent.postMessage(...e)}catch(r){r instanceof SyntaxError?g().forceError("Unable to call window.parent.postMessage due to incorrectly configured target origin. Use the setTargetOrigin method to allow this origin to receive events",r):g().forceError(r)}}),V=(...e)=>d()(...e),E=M.signal("https://web.telegram.org");function fe(e){E.set(e),g().log("New target origin set",e)}function q(e,r){g().log("Posting event:",r?{eventType:e,eventData:r}:{eventType:e});const t=window,o=JSON.stringify({eventType:e,eventData:r});if(C())return V(o,E());if(T(t)){t.TelegramWebviewProxy.postEvent(e,JSON.stringify(r));return}if(n.is(n.looseObject({external:n.looseObject({notify:n.function()})}),t)){t.external.notify(o);return}throw new X}function A(e,r,t){t||(t={});const{capture:o}=t,[s,a]=w.createCbCollector();return new b.AbortablePromise(i=>{(Array.isArray(r)?r:[r]).forEach(c=>{s(j(c,p=>{(!o||(Array.isArray(r)?o({event:c,payload:p}):o(p)))&&i(p)}))}),(t.postEvent||q)(e,t.params)},t).finally(a)}const $="launchParams";function z(e){return e.replace(/^[^?#]*[?#]/,"").replace(/[?#]/g,"&")}function L(){const e=[];for(const[r,t]of[[()=>z(window.location.href),"window.location.href"],[()=>{const o=performance.getEntriesByType("navigation")[0];return o&&z(o.name)},"performance navigation entries"],[()=>w.getStorageValue($),"local storage"]]){const o=r();if(!o){e.push([t,new Error("Source is empty")]);continue}if(l.isLaunchParamsQuery(o))return w.setStorageValue($,o),o;try{l.parseLaunchParamsQuery(o)}catch(s){e.push([t,s])}}throw new H(e)}function ee(e){const r=l.parseLaunchParamsQuery(L());return e?w.deepSnakeToCamelObjKeys(r):r}function ge(e,r){if(!e)try{return ee(),!0}catch{return!1}return b.AbortablePromise.fn(async t=>{if(T(window))return!0;try{return await A("web_app_request_theme","theme_changed",t),!0}catch{return!1}},r||{timeout:100})}function be({launchParams:e,onEvent:r,resetPostMessage:t}={}){if(e){const a=typeof e=="string"||e instanceof URLSearchParams?e.toString():l.serializeLaunchParamsQuery({...e,tgWebAppData:void 0})+(e.tgWebAppData?`&tgWebAppData=${encodeURIComponent(e.tgWebAppData.toString())}`:"");if(!l.isLaunchParamsQuery(a))try{l.parseLaunchParamsQuery(a)}catch(i){throw new Y(a,i)}w.setStorageValue("launchParams",a)}if(C()){if(!r)return;const a=n.pipe(n.string(),l.jsonParse(),l.MiniAppsMessageSchema);t&&d.reset();const i=d();d.set((...c)=>{const[p]=c,_=()=>{i(...c)};if(n.is(a,p)){const f=n.parse(a,p);r([f.eventType,f.eventData],_)}else _()});return}const o=window.TelegramWebviewProxy||{},s=o.postEvent||(()=>{});window.TelegramWebviewProxy={...o,postEvent(a,i){const c=()=>{s(a,i)};r?r([a,i?JSON.parse(i):void 0],c):c()}},g().log("Environment was mocked by the mockTelegramEnv function")}function me(){return new URLSearchParams(L()).get("tgWebAppData")||void 0}function re(e){return({req_id:r})=>r===e}function D(e){return e.split(".").map(Number)}function te(e,r){const t=D(e),o=D(r),s=Math.max(t.length,o.length);for(let a=0;a<s;a+=1){const i=t[a]||0,c=o[a]||0;if(i!==c)return i>c?1:-1}return 0}function u(e,r){return te(e,r)<=0}function k(e,r,t){if(typeof t=="string"){if(e==="web_app_open_link"){if(r==="try_instant_view")return u("6.4",t);if(r==="try_browser")return u("7.6",t)}if(e==="web_app_set_header_color"&&r==="color")return u("6.9",t);if(e==="web_app_close"&&r==="return_back")return u("7.6",t);if(e==="web_app_setup_main_button"&&r==="has_shine_effect")return u("7.10",t)}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 u("6.1",r);case"web_app_open_popup":return u("6.2",r);case"web_app_close_scan_qr_popup":case"web_app_open_scan_qr_popup":case"web_app_read_text_from_clipboard":return u("6.4",r);case"web_app_switch_inline_query":return u("6.7",r);case"web_app_invoke_custom_method":case"web_app_request_write_access":case"web_app_request_phone":return u("6.9",r);case"web_app_setup_settings_button":return u("6.10",r);case"web_app_biometry_get_info":case"web_app_biometry_open_settings":case"web_app_biometry_request_access":case"web_app_biometry_request_auth":case"web_app_biometry_update_token":return u("7.2",r);case"web_app_setup_swipe_behavior":return u("7.7",r);case"web_app_share_to_story":return u("7.8",r);case"web_app_setup_secondary_button":case"web_app_set_bottom_bar_color":return u("7.10",r);case"web_app_request_safe_area":case"web_app_request_content_safe_area":case"web_app_request_fullscreen":case"web_app_exit_fullscreen":case"web_app_set_emoji_status":case"web_app_add_to_home_screen":case"web_app_check_home_screen":case"web_app_request_emoji_status_access":case"web_app_check_location":case"web_app_open_location_settings":case"web_app_request_file_download":case"web_app_request_location":case"web_app_send_prepared_message":case"web_app_start_accelerometer":case"web_app_start_device_orientation":case"web_app_start_gyroscope":case"web_app_stop_accelerometer":case"web_app_stop_device_orientation":case"web_app_stop_gyroscope":case"web_app_toggle_orientation_lock":return u("8.0",r);case"web_app_device_storage_clear":case"web_app_device_storage_get_key":case"web_app_device_storage_save_key":case"web_app_secure_storage_clear":case"web_app_secure_storage_get_key":case"web_app_secure_storage_restore_key":case"web_app_secure_storage_save_key":return u("9.0",r);case"web_app_hide_keyboard":return u("9.1",r);default:return["iframe_ready","iframe_will_reload","web_app_close","web_app_data_send","web_app_expand","web_app_open_link","web_app_ready","web_app_request_theme","web_app_request_viewport","web_app_setup_main_button","web_app_setup_closing_behavior"].includes(e)}}function we(e,r){r||(r="strict");const t=typeof r=="function"?r:o=>{const{method:s,version:a}=o,i="param"in o?new F(s,o.param,a):new K(s,a);if(r==="strict")throw i;return g().forceWarn(i.message)};return(o,s)=>k(o,e)?o==="web_app_set_header_color"&&n.is(n.looseObject({color:n.any()}),s)&&!k(o,"color",e)?t({version:e,method:o,param:"color"}):q(o,s):t({version:e,method:o})}function de(e){const r=S(typeof e=="string"?e:JSON.stringify(e));if(r.length>512)throw new Error("Value is too long for start parameter");return r}function he(e,r){const t=N(e);return r==="json"?JSON.parse(t):r?r(t):t}function ve(e){return S(e).length<=512}function ye(e,r,t,o){return A("web_app_invoke_custom_method","custom_method_invoked",{...o||{},params:{method:e,params:r,req_id:t},capture:re(t)}).then(({result:s,error:a})=>{if(a)throw new Z(a);return s})}function Ee(){Object.hasOwn||(Object.hasOwn=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)})}function Pe(){B(),G(!1),[d,E].forEach(e=>{e.unsubAll(),e.reset()})}Object.defineProperty(exports,"AbortablePromise",{enumerable:!0,get:()=>b.AbortablePromise});Object.defineProperty(exports,"CancelledError",{enumerable:!0,get:()=>b.CancelledError});Object.defineProperty(exports,"ManualPromise",{enumerable:!0,get:()=>b.ManualPromise});Object.defineProperty(exports,"TimeoutError",{enumerable:!0,get:()=>b.TimeoutError});Object.defineProperty(exports,"isCancelledError",{enumerable:!0,get:()=>b.isCancelledError});Object.defineProperty(exports,"isTimeoutError",{enumerable:!0,get:()=>b.isTimeoutError});Object.defineProperty(exports,"createLogger",{enumerable:!0,get:()=>w.createLogger});exports.InvalidLaunchParamsError=Y;exports.InvokeCustomMethodError=Z;exports.LaunchParamsRetrieveError=H;exports.MethodParameterUnsupportedError=F;exports.MethodUnsupportedError=K;exports.UnknownEnvError=X;exports.applyPolyfills=Ee;exports.captureSameReq=re;exports.compareVersions=te;exports.createPostEvent=we;exports.createStartParam=de;exports.decodeBase64Url=N;exports.decodeStartParam=he;exports.emitEvent=v;exports.encodeBase64Url=S;exports.hasWebviewProxy=T;exports.invokeCustomMethod=ye;exports.isIframe=C;exports.isInvalidLaunchParamsError=ue;exports.isInvokeCustomMethodError=le;exports.isLaunchParamsRetrieveError=pe;exports.isMethodMethodParameterUnsupportedError=ce;exports.isMethodUnsupportedError=ie;exports.isSafeToCreateStartParam=ve;exports.isTMA=ge;exports.isUnknownEnvError=_e;exports.logger=g;exports.mockTelegramEnv=be;exports.off=Q;exports.offAll=B;exports.on=j;exports.postEvent=q;exports.postMessage=V;exports.postMessageImplementation=d;exports.request=A;exports.resetPackageState=Pe;exports.retrieveLaunchParams=ee;exports.retrieveRawInitData=me;exports.retrieveRawLaunchParams=L;exports.setDebug=G;exports.setTargetOrigin=fe;exports.supports=k;exports.targetOrigin=E;
//# sourceMappingURL=index.cjs.map