UNPKG

@telegram-apps/bridge

Version:

TypeScript package to provide communication layer between Mini App and Telegram application.

5 lines (4 loc) 12 kB
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("valibot"),g=require("better-promises"),b=require("@telegram-apps/toolkit"),l=require("@telegram-apps/transformers"),V=require("mitt"),M=require("@telegram-apps/signals"),d=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 $(e){return decodeURIComponent(atob(e).replace(/-/g,"+").replace(/_/g,"/").split("").map(r=>"%"+("00"+r.charCodeAt(0).toString(16)).slice(-2)).join(""))}function k(e){return a.is(a.looseObject({TelegramWebviewProxy:a.looseObject({postEvent:a.function()})}),e)}function C(){try{return window.self!==window.top}catch{return!0}}function ee(e,r){const t=V(),o=new Map,i=(n,s,c)=>{c||(c=!1);const p=o.get(n)||new Map;o.set(n,p);const _=p.get(s)||[];p.set(s,_);const f=_.findIndex(h=>h[1]===c);f>=0&&(t.off(n,_[f][0]),_.splice(f,1),!_.length&&p.delete(s),p.size||(o.delete(n),!o.size&&r()))};return[function(s,c,p){!o.size&&e();function _(){i(s,c,p)}function f(...x){p&&_(),s==="*"?c(x):c(...x)}t.on(s,f);const h=o.get(s)||new Map;o.set(s,h);const T=h.get(c)||[];return h.set(c,T),T.push([f,p||!1]),_},i,t.emit,function(){const s=t.all.size;t.all.clear(),o.clear(),s&&r()}]}function y(e,r){window.dispatchEvent(new MessageEvent("message",{data:JSON.stringify({eventType:e,eventData:r}),source:window.parent}))}let v=!1;const U=e=>{m().log("Event received:",e)};function D(e){e!==v&&(v=e,v?j("*",U):N("*",U))}const m=M.signal(b.createLogger("Bridge",{bgColor:"#9147ff",textColor:"white",shouldLog(){return v}})),re={clipboard_text_received:a.looseObject({req_id:a.string(),data:a.nullish(a.string())}),custom_method_invoked:a.looseObject({req_id:a.string(),result:a.optional(a.unknown()),error:a.optional(a.string())}),popup_closed:a.nullish(a.looseObject({button_id:a.nullish(a.string(),()=>{})}),{}),viewport_changed:a.looseObject({height:a.number(),width:a.nullish(a.number(),()=>window.innerWidth),is_state_stable:a.boolean(),is_expanded:a.boolean()}),theme_changed:a.looseObject({theme_params:l.themeParams()})};function I(e){if(e.source!==window.parent)return;let r;try{r=a.parse(a.pipe(a.string(),l.jsonParse(),l.MiniAppsMessageSchema),e.data)}catch{return}const{eventType:t,eventData:o}=r,i=re[t];let n;try{n=i?a.parse(i,o):o}catch(s){return m().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,s)}te(t,n)}const[j,N,te,Q]=ee(()=>{const e=window,r={receiveEvent:y};e.TelegramGameProxy_receiveEvent=y,e.TelegramGameProxy=r,e.Telegram={WebView:r},window.addEventListener("message",I)},()=>{["TelegramGameProxy_receiveEvent","TelegramGameProxy","Telegram"].forEach(e=>{delete window[e]}),window.removeEventListener("message",I)}),[z,oe]=d.errorClass("MethodUnsupportedError",(e,r)=>[`Method "${e}" is unsupported in Mini Apps version ${r}`]),[B,ae]=d.errorClass("MethodParameterUnsupportedError",(e,r,t)=>[`Parameter "${r}" of "${e}" method is unsupported in Mini Apps version ${t}`]),[G,ne]=d.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(` `)]),[J,se]=d.errorClass("InvalidLaunchParamsError",(e,r)=>[`Invalid value for launch params: ${e}`,{cause:r}]),[K,ie]=d.errorClass("UnknownEnvError"),[F,ce]=d.errorClass("InvokeCustomMethodError",e=>[`Server returned error: ${e}`]),w=M.signal((...e)=>{try{window.parent.postMessage(...e)}catch(r){r instanceof SyntaxError?m().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):m().forceError(r)}}),Y=(...e)=>w()(...e),E=M.signal("https://web.telegram.org");function pe(e){E.set(e),m().log("New target origin set",e)}function q(e,r){m().log("Posting event:",r?{eventType:e,eventData:r}:{eventType:e});const t=window,o=JSON.stringify({eventType:e,eventData:r});if(C())return Y(o,E());if(k(t)){t.TelegramWebviewProxy.postEvent(e,JSON.stringify(r));return}if(a.is(a.looseObject({external:a.looseObject({notify:a.function()})}),t)){t.external.notify(o);return}throw new K}function L(e,r,t){t||(t={});const{capture:o}=t,[i,n]=b.createCbCollector();return new g.AbortablePromise(s=>{(Array.isArray(r)?r:[r]).forEach(c=>{i(j(c,p=>{(!o||(Array.isArray(r)?o({event:c,payload:p}):o(p)))&&s(p)}))}),(t.postEvent||q)(e,t.params)},t).finally(n)}const R="launchParams";function O(e){return e.replace(/^[^?#]*[?#]/,"").replace(/[?#]/g,"&")}function A(){const e=[];for(const[r,t]of[[()=>O(window.location.href),"window.location.href"],[()=>{const o=performance.getEntriesByType("navigation")[0];return o&&O(o.name)},"performance navigation entries"],[()=>b.getStorageValue(R),"local storage"]]){const o=r();if(!o){e.push([t,new Error("Source is empty")]);continue}if(l.isLaunchParamsQuery(o))return b.setStorageValue(R,o),o;try{l.parseLaunchParamsQuery(o)}catch(i){e.push([t,i])}}throw new G(e)}function H(e){const r=l.parseLaunchParamsQuery(A());return e?b.deepSnakeToCamelObjKeys(r):r}function ue(e,r){if(!e)try{return H(),!0}catch{return!1}return g.AbortablePromise.fn(async t=>{if(k(window))return!0;try{return await L("web_app_request_theme","theme_changed",t),!0}catch{return!1}},r||{timeout:100})}function _e({launchParams:e,onEvent:r,resetPostMessage:t}={}){if(e){const n=typeof e=="string"||e instanceof URLSearchParams?e.toString():l.serializeLaunchParamsQuery({...e,tgWebAppData:void 0})+(e.tgWebAppData?`&tgWebAppData=${encodeURIComponent(e.tgWebAppData.toString())}`:"");if(!l.isLaunchParamsQuery(n))try{l.parseLaunchParamsQuery(n)}catch(s){throw new J(n,s)}b.setStorageValue("launchParams",n)}if(C()){if(!r)return;const n=a.pipe(a.string(),l.jsonParse(),l.MiniAppsMessageSchema);t&&w.reset();const s=w();w.set((...c)=>{const[p]=c,_=()=>{s(...c)};if(a.is(n,p)){const f=a.parse(n,p);r([f.eventType,f.eventData],_)}else _()});return}const o=window.TelegramWebviewProxy||{},i=o.postEvent||(()=>{});window.TelegramWebviewProxy={...o,postEvent(n,s){const c=()=>{i(n,s)};r?r([n,s?JSON.parse(s):void 0],c):c()}},m().log("Environment was mocked by the mockTelegramEnv function")}function le(){return new URLSearchParams(A()).get("tgWebAppData")||void 0}function X(e){return({req_id:r})=>r===e}function W(e){return e.split(".").map(Number)}function Z(e,r){const t=W(e),o=W(r),i=Math.max(t.length,o.length);for(let n=0;n<i;n+=1){const s=t[n]||0,c=o[n]||0;if(s!==c)return s>c?1:-1}return 0}function u(e,r){return Z(e,r)<=0}function P(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);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 fe(e,r){r||(r="strict");const t=typeof r=="function"?r:o=>{const{method:i,version:n}=o,s="param"in o?new B(i,o.param,n):new z(i,n);if(r==="strict")throw s;return m().forceWarn(s.message)};return(o,i)=>P(o,e)?o==="web_app_set_header_color"&&a.is(a.looseObject({color:a.any()}),i)&&!P(o,"color",e)?t({version:e,method:o,param:"color"}):q(o,i):t({version:e,method:o})}function me(e){const r=S(e);if(r.length>512)throw new Error("Value is too long for start parameter");return r}const ge=$;function be(e){return S(e).length<=512}function we(e,r,t,o){return L("web_app_invoke_custom_method","custom_method_invoked",{...o||{},params:{method:e,params:r,req_id:t},capture:X(t)}).then(({result:i,error:n})=>{if(n)throw new F(n);return i})}function de(){Object.hasOwn||(Object.hasOwn=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)})}function he(){Q(),D(!1),[w,E].forEach(e=>{e.unsubAll(),e.reset()})}Object.defineProperty(exports,"AbortablePromise",{enumerable:!0,get:()=>g.AbortablePromise});Object.defineProperty(exports,"CancelledError",{enumerable:!0,get:()=>g.CancelledError});Object.defineProperty(exports,"ManualPromise",{enumerable:!0,get:()=>g.ManualPromise});Object.defineProperty(exports,"TimeoutError",{enumerable:!0,get:()=>g.TimeoutError});Object.defineProperty(exports,"isCancelledError",{enumerable:!0,get:()=>g.isCancelledError});Object.defineProperty(exports,"isTimeoutError",{enumerable:!0,get:()=>g.isTimeoutError});Object.defineProperty(exports,"createLogger",{enumerable:!0,get:()=>b.createLogger});exports.InvalidLaunchParamsError=J;exports.InvokeCustomMethodError=F;exports.LaunchParamsRetrieveError=G;exports.MethodParameterUnsupportedError=B;exports.MethodUnsupportedError=z;exports.UnknownEnvError=K;exports.applyPolyfills=de;exports.captureSameReq=X;exports.compareVersions=Z;exports.createPostEvent=fe;exports.createStartParam=me;exports.decodeBase64Url=$;exports.decodeStartParam=ge;exports.emitEvent=y;exports.encodeBase64Url=S;exports.hasWebviewProxy=k;exports.invokeCustomMethod=we;exports.isIframe=C;exports.isInvalidLaunchParamsError=se;exports.isInvokeCustomMethodError=ce;exports.isLaunchParamsRetrieveError=ne;exports.isMethodMethodParameterUnsupportedError=ae;exports.isMethodUnsupportedError=oe;exports.isSafeToCreateStartParam=be;exports.isTMA=ue;exports.isUnknownEnvError=ie;exports.logger=m;exports.mockTelegramEnv=_e;exports.off=N;exports.offAll=Q;exports.on=j;exports.postEvent=q;exports.postMessage=Y;exports.postMessageImplementation=w;exports.request=L;exports.resetPackageState=he;exports.retrieveLaunchParams=H;exports.retrieveRawInitData=le;exports.retrieveRawLaunchParams=A;exports.setDebug=D;exports.setTargetOrigin=pe;exports.supports=P;exports.targetOrigin=E; //# sourceMappingURL=index.cjs.map