@grabjs/superapp-sdk 2.0.0-beta.14 → 2.0.0-beta.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/README.md +170 -55
  2. package/{dist → api-reference/json}/api.json +17192 -7721
  3. package/api-reference/markdown/README.md +194 -0
  4. package/api-reference/markdown/classes/BaseModule.md +123 -0
  5. package/api-reference/markdown/classes/CameraModule.md +177 -0
  6. package/api-reference/markdown/classes/CheckoutModule.md +181 -0
  7. package/api-reference/markdown/classes/ContainerModule.md +751 -0
  8. package/api-reference/markdown/classes/DeviceCapabilityModule.md +161 -0
  9. package/api-reference/markdown/classes/FileModule.md +178 -0
  10. package/api-reference/markdown/classes/IdentityModule.md +299 -0
  11. package/api-reference/markdown/classes/LocaleModule.md +161 -0
  12. package/api-reference/markdown/classes/LocationModule.md +239 -0
  13. package/api-reference/markdown/classes/MediaModule.md +219 -0
  14. package/api-reference/markdown/classes/PlatformModule.md +162 -0
  15. package/api-reference/markdown/classes/ProfileModule.md +224 -0
  16. package/api-reference/markdown/classes/ScopeModule.md +219 -0
  17. package/api-reference/markdown/classes/StorageModule.md +608 -0
  18. package/api-reference/markdown/classes/SystemWebViewKitModule.md +177 -0
  19. package/api-reference/markdown/classes/UserAttributesModule.md +164 -0
  20. package/api-reference/markdown/functions/isClientError.md +37 -0
  21. package/api-reference/markdown/functions/isErrorResponse.md +40 -0
  22. package/api-reference/markdown/functions/isRedirection.md +37 -0
  23. package/api-reference/markdown/functions/isServerError.md +37 -0
  24. package/api-reference/markdown/functions/isSuccess.md +39 -0
  25. package/api-reference/markdown/globals.md +176 -0
  26. package/api-reference/markdown/interfaces/GrabAppInfo.md +23 -0
  27. package/api-reference/markdown/interfaces/InvokeOptions.md +63 -0
  28. package/api-reference/markdown/interfaces/Version.md +23 -0
  29. package/api-reference/markdown/interfaces/WrappedModule.md +51 -0
  30. package/api-reference/markdown/type-aliases/AuthorizeRequest.md +79 -0
  31. package/api-reference/markdown/type-aliases/AuthorizeResponse.md +58 -0
  32. package/api-reference/markdown/type-aliases/AuthorizeResult.md +33 -0
  33. package/api-reference/markdown/type-aliases/BackResponse.md +37 -0
  34. package/api-reference/markdown/type-aliases/BackResult.md +8 -0
  35. package/api-reference/markdown/type-aliases/BridgeClientError.md +9 -0
  36. package/api-reference/markdown/type-aliases/BridgeError.md +8 -0
  37. package/api-reference/markdown/type-aliases/BridgeRedirection.md +8 -0
  38. package/api-reference/markdown/type-aliases/BridgeResponse.md +40 -0
  39. package/api-reference/markdown/type-aliases/BridgeServerError.md +8 -0
  40. package/api-reference/markdown/type-aliases/BridgeStatusCode.md +7 -0
  41. package/api-reference/markdown/type-aliases/BridgeStream.md +29 -0
  42. package/api-reference/markdown/type-aliases/BridgeStreamHandlers.md +25 -0
  43. package/api-reference/markdown/type-aliases/BridgeSuccessResponse.md +14 -0
  44. package/api-reference/markdown/type-aliases/ClearAuthorizationArtifactsResponse.md +18 -0
  45. package/api-reference/markdown/type-aliases/ClearAuthorizationArtifactsResult.md +8 -0
  46. package/api-reference/markdown/type-aliases/CloseResponse.md +37 -0
  47. package/api-reference/markdown/type-aliases/CloseResult.md +8 -0
  48. package/api-reference/markdown/type-aliases/DRMContentConfig.md +34 -0
  49. package/api-reference/markdown/type-aliases/DRMPlaybackEvent.md +43 -0
  50. package/api-reference/markdown/type-aliases/DownloadFileRequest.md +32 -0
  51. package/api-reference/markdown/type-aliases/DownloadFileResponse.md +48 -0
  52. package/api-reference/markdown/type-aliases/DownloadFileResult.md +11 -0
  53. package/api-reference/markdown/type-aliases/ErrorResponse.md +32 -0
  54. package/api-reference/markdown/type-aliases/FetchEmailResponse.md +58 -0
  55. package/api-reference/markdown/type-aliases/FetchEmailResult.md +21 -0
  56. package/api-reference/markdown/type-aliases/GetAuthorizationArtifactsResponse.md +42 -0
  57. package/api-reference/markdown/type-aliases/GetAuthorizationArtifactsResult.md +57 -0
  58. package/api-reference/markdown/type-aliases/GetBooleanRequest.md +21 -0
  59. package/api-reference/markdown/type-aliases/GetBooleanResponse.md +57 -0
  60. package/api-reference/markdown/type-aliases/GetBooleanResult.md +27 -0
  61. package/api-reference/markdown/type-aliases/GetCoordinateResponse.md +49 -0
  62. package/api-reference/markdown/type-aliases/GetCoordinateResult.md +29 -0
  63. package/api-reference/markdown/type-aliases/GetCountryCodeResponse.md +57 -0
  64. package/api-reference/markdown/type-aliases/GetCountryCodeResult.md +25 -0
  65. package/api-reference/markdown/type-aliases/GetDoubleRequest.md +21 -0
  66. package/api-reference/markdown/type-aliases/GetDoubleResponse.md +57 -0
  67. package/api-reference/markdown/type-aliases/GetDoubleResult.md +27 -0
  68. package/api-reference/markdown/type-aliases/GetIntRequest.md +21 -0
  69. package/api-reference/markdown/type-aliases/GetIntResponse.md +57 -0
  70. package/api-reference/markdown/type-aliases/GetIntResult.md +27 -0
  71. package/api-reference/markdown/type-aliases/GetLanguageLocaleIdentifierResponse.md +48 -0
  72. package/api-reference/markdown/type-aliases/GetLanguageLocaleIdentifierResult.md +31 -0
  73. package/api-reference/markdown/type-aliases/GetSelectedTravelDestinationResponse.md +48 -0
  74. package/api-reference/markdown/type-aliases/GetSelectedTravelDestinationResult.md +17 -0
  75. package/api-reference/markdown/type-aliases/GetSessionParamsResponse.md +40 -0
  76. package/api-reference/markdown/type-aliases/GetSessionParamsResult.md +27 -0
  77. package/api-reference/markdown/type-aliases/GetStringRequest.md +21 -0
  78. package/api-reference/markdown/type-aliases/GetStringResponse.md +57 -0
  79. package/api-reference/markdown/type-aliases/GetStringResult.md +27 -0
  80. package/api-reference/markdown/type-aliases/HasAccessToResponse.md +66 -0
  81. package/api-reference/markdown/type-aliases/HasAccessToResult.md +27 -0
  82. package/api-reference/markdown/type-aliases/HideBackButtonResponse.md +37 -0
  83. package/api-reference/markdown/type-aliases/HideBackButtonResult.md +8 -0
  84. package/api-reference/markdown/type-aliases/HideLoaderResponse.md +37 -0
  85. package/api-reference/markdown/type-aliases/HideLoaderResult.md +8 -0
  86. package/api-reference/markdown/type-aliases/HideRefreshButtonResponse.md +37 -0
  87. package/api-reference/markdown/type-aliases/HideRefreshButtonResult.md +8 -0
  88. package/api-reference/markdown/type-aliases/IsConnectedResponse.md +31 -0
  89. package/api-reference/markdown/type-aliases/IsConnectedResult.md +27 -0
  90. package/api-reference/markdown/type-aliases/IsEsimSupportedResponse.md +48 -0
  91. package/api-reference/markdown/type-aliases/IsEsimSupportedResult.md +17 -0
  92. package/api-reference/markdown/type-aliases/ObserveDRMPlaybackResponse.md +15 -0
  93. package/api-reference/markdown/type-aliases/ObserveLocationChangeResponse.md +15 -0
  94. package/api-reference/markdown/type-aliases/OnContentLoadedResponse.md +37 -0
  95. package/api-reference/markdown/type-aliases/OnContentLoadedResult.md +8 -0
  96. package/api-reference/markdown/type-aliases/OnCtaTapRequest.md +13 -0
  97. package/api-reference/markdown/type-aliases/OnCtaTapResponse.md +37 -0
  98. package/api-reference/markdown/type-aliases/OnCtaTapResult.md +8 -0
  99. package/api-reference/markdown/type-aliases/OpenExternalLinkRequest.md +13 -0
  100. package/api-reference/markdown/type-aliases/OpenExternalLinkResponse.md +46 -0
  101. package/api-reference/markdown/type-aliases/OpenExternalLinkResult.md +8 -0
  102. package/api-reference/markdown/type-aliases/Platform.md +7 -0
  103. package/api-reference/markdown/type-aliases/PlayDRMContentResponse.md +43 -0
  104. package/api-reference/markdown/type-aliases/PlayDRMContentResult.md +8 -0
  105. package/api-reference/markdown/type-aliases/RedirectToSystemWebViewRequest.md +23 -0
  106. package/api-reference/markdown/type-aliases/RedirectToSystemWebViewResponse.md +55 -0
  107. package/api-reference/markdown/type-aliases/RedirectToSystemWebViewResult.md +8 -0
  108. package/api-reference/markdown/type-aliases/ReloadScopesResponse.md +46 -0
  109. package/api-reference/markdown/type-aliases/ReloadScopesResult.md +8 -0
  110. package/api-reference/markdown/type-aliases/RemoveAllResponse.md +37 -0
  111. package/api-reference/markdown/type-aliases/RemoveAllResult.md +8 -0
  112. package/api-reference/markdown/type-aliases/RemoveResponse.md +46 -0
  113. package/api-reference/markdown/type-aliases/RemoveResult.md +8 -0
  114. package/api-reference/markdown/type-aliases/ResponseStatusCode200.md +34 -0
  115. package/api-reference/markdown/type-aliases/ResponseStatusCode204.md +20 -0
  116. package/api-reference/markdown/type-aliases/ResponseStatusCode302.md +20 -0
  117. package/api-reference/markdown/type-aliases/ResponseStatusCode400.md +7 -0
  118. package/api-reference/markdown/type-aliases/ResponseStatusCode401.md +7 -0
  119. package/api-reference/markdown/type-aliases/ResponseStatusCode403.md +7 -0
  120. package/api-reference/markdown/type-aliases/ResponseStatusCode404.md +7 -0
  121. package/api-reference/markdown/type-aliases/ResponseStatusCode424.md +7 -0
  122. package/api-reference/markdown/type-aliases/ResponseStatusCode426.md +12 -0
  123. package/api-reference/markdown/type-aliases/ResponseStatusCode500.md +7 -0
  124. package/api-reference/markdown/type-aliases/ResponseStatusCode501.md +12 -0
  125. package/api-reference/markdown/type-aliases/ScanQRCodeRequest.md +27 -0
  126. package/api-reference/markdown/type-aliases/ScanQRCodeResponse.md +64 -0
  127. package/api-reference/markdown/type-aliases/ScanQRCodeResult.md +21 -0
  128. package/api-reference/markdown/type-aliases/SendAnalyticsEventRequest.md +56 -0
  129. package/api-reference/markdown/type-aliases/SendAnalyticsEventResponse.md +46 -0
  130. package/api-reference/markdown/type-aliases/SendAnalyticsEventResult.md +8 -0
  131. package/api-reference/markdown/type-aliases/SetBackgroundColorRequest.md +13 -0
  132. package/api-reference/markdown/type-aliases/SetBackgroundColorResponse.md +46 -0
  133. package/api-reference/markdown/type-aliases/SetBackgroundColorResult.md +8 -0
  134. package/api-reference/markdown/type-aliases/SetBooleanResponse.md +46 -0
  135. package/api-reference/markdown/type-aliases/SetBooleanResult.md +8 -0
  136. package/api-reference/markdown/type-aliases/SetDoubleResponse.md +46 -0
  137. package/api-reference/markdown/type-aliases/SetDoubleResult.md +8 -0
  138. package/api-reference/markdown/type-aliases/SetIntResponse.md +46 -0
  139. package/api-reference/markdown/type-aliases/SetIntResult.md +8 -0
  140. package/api-reference/markdown/type-aliases/SetStringResponse.md +46 -0
  141. package/api-reference/markdown/type-aliases/SetStringResult.md +8 -0
  142. package/api-reference/markdown/type-aliases/SetTitleRequest.md +13 -0
  143. package/api-reference/markdown/type-aliases/SetTitleResponse.md +46 -0
  144. package/api-reference/markdown/type-aliases/SetTitleResult.md +8 -0
  145. package/api-reference/markdown/type-aliases/ShowBackButtonResponse.md +37 -0
  146. package/api-reference/markdown/type-aliases/ShowBackButtonResult.md +8 -0
  147. package/api-reference/markdown/type-aliases/ShowLoaderResponse.md +37 -0
  148. package/api-reference/markdown/type-aliases/ShowLoaderResult.md +8 -0
  149. package/api-reference/markdown/type-aliases/ShowRefreshButtonResponse.md +37 -0
  150. package/api-reference/markdown/type-aliases/ShowRefreshButtonResult.md +8 -0
  151. package/api-reference/markdown/type-aliases/StatusCodeMap.md +80 -0
  152. package/api-reference/markdown/type-aliases/Subscription.md +12 -0
  153. package/api-reference/markdown/type-aliases/TriggerCheckoutRequest.md +26 -0
  154. package/api-reference/markdown/type-aliases/TriggerCheckoutResponse.md +76 -0
  155. package/api-reference/markdown/type-aliases/TriggerCheckoutResult.md +75 -0
  156. package/api-reference/markdown/type-aliases/VerifyEmailRequest.md +32 -0
  157. package/api-reference/markdown/type-aliases/VerifyEmailResponse.md +55 -0
  158. package/api-reference/markdown/type-aliases/VerifyEmailResult.md +8 -0
  159. package/api-reference/markdown/variables/ContainerAnalyticsEventData.md +21 -0
  160. package/api-reference/markdown/variables/ContainerAnalyticsEventName.md +13 -0
  161. package/api-reference/markdown/variables/ContainerAnalyticsEventState.md +25 -0
  162. package/dist/index.d.ts +1825 -1298
  163. package/dist/index.esm.js +1 -1
  164. package/dist/index.js +1 -1
  165. package/package.json +22 -10
package/dist/index.esm.js CHANGED
@@ -4,4 +4,4 @@
4
4
  * This source code is licensed under the MIT license found in the LICENSE file in the root
5
5
  * directory of this source tree.
6
6
  */
7
- var e,t={exports:{}},r=(e||(e=1,function(e){function t(e){var t=!1;return{isUnsubscribed:function(){return t},unsubscribe:function(){t||(e(),t=!0)}}}function r(e){return{subscribe:e,then:function(t,r){return new Promise(function(n,o){try{var i=null,a=!1;i=e({next:function(e){n(null==t?void 0:t(e)),i&&i.unsubscribe(),a=!0}}),a&&i&&i.unsubscribe()}catch(e){null==r?o(e):n(r(e))}})}}}function n(n,o){return o.funcNameToWrap,function(n,o){var i=o.callbackNameFunc,a=o.funcToWrap;return r(function(r){var o,s=i();return n[s]=function(t){if(function(e){for(var t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];if(!e)return!1;var n=function(e){return Object.keys(e).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(e)))}(e);return t.every(function(e){return 0<=n.indexOf(e)})}(t.result,"event"))t.result.event===e.StreamEvent.STREAM_TERMINATED&&o.unsubscribe();else{var n=t.result,i=t.error,a=t.status_code;r&&r.next&&r.next({result:null===n?void 0:n,error:null===i?void 0:i,status_code:null===a?void 0:a})}},a(s),o=t(function(){n[s]=void 0,r&&r.complete&&r.complete()})})}(n,function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(e);o<n.length;o++)t.indexOf(n[o])<0&&(r[n[o]]=e[n[o]])}return r}(o,["funcNameToWrap"]))}(e.StreamEvent||(e.StreamEvent={})).STREAM_TERMINATED="STREAM_TERMINATED",e.createDataStream=r,e.createSubscription=t,e.getModuleEnvironment=function(e,t){return e[t]?"android":e.webkit&&e.webkit.messageHandlers&&e.webkit.messageHandlers[t]?"ios":void 0},e.wrapModule=function(e,t){var r;e[(r=t,"Wrapped"+r)]=function(e,t,r){return{invoke:function(o,i){return n(e,{funcNameToWrap:o,callbackNameFunc:function(){return function(e,t){var r=t.moduleName,n=t.funcName,o=0;return function(){for(var t,i,a="";(a=(t={moduleName:r,funcName:n,requestID:o}).moduleName+"_"+t.funcName+"Callback"+(null!==(i=t.requestID)?"_"+i:""))in e;)o+=1;return o+=1,a}()}(e,{moduleName:t,funcName:o})},funcToWrap:function(e){return r({callback:e,method:o,module:t,parameters:null!=i?i:{}})}})}}}(e,t,function(r){if(e[t]&&e[t][r.method]instanceof Function)e[t][r.method](JSON.stringify(r));else{if(!(e.webkit&&e.webkit.messageHandlers&&e.webkit.messageHandlers[t]))throw new Error("Unexpected method '"+r.method+"' for module '"+t+"'");e.webkit.messageHandlers[t].postMessage(r)}})},Object.defineProperty(e,"__esModule",{value:!0})}(t.exports)),t.exports);function n(e){return e instanceof Error?e.message:String(e)}function o(e,t){return e instanceof Error&&e.message===t}function i(){if("undefined"==typeof window||!window.navigator)return null;const e=window.navigator.userAgent;return e?function(e){if(!e||"string"!=typeof e)return null;const t=e.match(/(Grab|GrabBeta|GrabBetaDebug|GrabTaxi|GrabEarlyAccess)\/v?([0-9]+)\.([0-9]+)\.([0-9]+) \(.*(Android|iOS).*\)/i);return t?{appName:t[1],version:{major:Number(t[2]),minor:Number(t[3]),patch:Number(t[4])},platform:t[5]}:null}(e):null}function a(){if("undefined"==typeof window||!window.navigator)return!1;const e=window.navigator.userAgent;return!!e&&/grab[a-z]*\//i.test(e)}class s{get wrappedModule(){return window[`Wrapped${this.name}`]}constructor(e){if(this.name=e,!this.wrappedModule)try{r.wrapModule(window,this.name)}catch(e){throw new Error(`Failed to initialize ${this.name}: ${n(e)}`,{cause:e})}}invoke(e,t){return a()?this.wrappedModule.invoke(e,t):Promise.resolve({status_code:501,result:void 0,error:"Not implemented: This method requires the Grab app environment"})}}class u extends s{constructor(){super("CameraModule")}scanQRCode(e){return this.invoke("scanQRCode",e)}}class c extends s{constructor(){super("CheckoutModule")}triggerCheckout(e){return this.invoke("triggerCheckout",e)}}const l={HOMEPAGE:"HOMEPAGE",CHECKOUT_PAGE:"CHECKOUT_PAGE",BOOKING_COMPLETION:"BOOKING_COMPLETION",CUSTOM:"CUSTOM"},d={DEFAULT:"DEFAULT"},h={TRANSACTION_AMOUNT:"transaction_amount",TRANSACTION_CURRENCY:"transaction_currency",PAGE:"page"};class m extends s{constructor(){super("ContainerModule")}setBackgroundColor(e){return this.invoke("setBackgroundColor",{backgroundColor:e})}setTitle(e){return this.invoke("setTitle",{title:e})}hideBackButton(){return this.invoke("hideBackButton")}showBackButton(){return this.invoke("showBackButton")}hideRefreshButton(){return this.invoke("hideRefreshButton")}showRefreshButton(){return this.invoke("showRefreshButton")}close(){return this.invoke("close")}onContentLoaded(){return this.invoke("onContentLoaded")}showLoader(){return this.invoke("showLoader")}hideLoader(){return this.invoke("hideLoader")}openExternalLink(e){return this.invoke("openExternalLink",{url:e})}onCtaTap(e){return this.invoke("onCtaTap",{action:e})}sendAnalyticsEvent(e){const t=this.validateAnalyticsEvent(e);return t?Promise.resolve({status_code:400,result:void 0,error:t}):this.invoke("sendAnalyticsEvent",{state:e.state,name:e.name,data:e.data?JSON.stringify(e.data):null})}isConnected(){const e=a();return Promise.resolve(e?{status_code:200,result:{connected:!0},error:null}:{status_code:404,error:"Not connected to Grab app",result:null})}getSessionParams(){return this.invoke("getSessionParams")}validateAnalyticsEvent(e){return null==e.name?"name is required":"string"!=typeof e.name?"name must be a string":null==e.state?"state is required":"string"!=typeof e.state?"state must be a string":null!=e.data&&"object"!=typeof e.data?"data must be undefined or an object":null}}function v(e){const t=new Uint32Array(e);crypto.getRandomValues(t);let r="";for(let n=0;n<e;n+=1)r+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(t[n]%62);return r}async function g(e){const t=(new TextEncoder).encode(e);return function(e){const t=new Uint8Array(e);let r="";for(let e=0;e<t.byteLength;e+=1)r+=String.fromCharCode(t[e]);return btoa(r).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}(await crypto.subtle.digest("SHA-256",t))}function f(e,t){return e.major!==t.major?e.major>t.major:e.minor!==t.minor?e.minor>t.minor:e.patch>=t.patch}const p="grabid",w={staging:"https://partner-api.stg-myteksi.com/grabid/v1/oauth2/.well-known/openid-configuration",production:"https://partner-api.grab.com/grabid/v1/oauth2/.well-known/openid-configuration"};class b extends s{constructor(){super("IdentityModule")}async fetchAuthorizationEndpoint(e){const t=w[e];if(!t)throw new Error(`Invalid environment: ${e}. Must be 'staging' or 'production'`);try{const e=await fetch(t);if(!e.ok)throw console.error(`Failed to fetch OpenID configuration from ${t}: ${e.status} ${e.statusText}`),new Error("Failed to fetch authorization configuration");const r=await e.json();if(!r.authorization_endpoint)throw console.error("authorization_endpoint not found in OpenID configuration response"),new Error("Invalid authorization configuration");return r.authorization_endpoint}catch(e){if(console.error("Error fetching authorization endpoint:",e),o(e,"Failed to fetch authorization configuration")||o(e,"Invalid authorization configuration"))throw e;throw new Error("Something wrong happened when fetching authorization configuration",{cause:e})}}async generatePKCEArtifacts(){const e=v(16),t=v(7),r=(n=v(64),btoa(n).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_"));var n;return{nonce:e,state:t,codeVerifier:r,codeChallenge:await g(r),codeChallengeMethod:"S256"}}storePKCEArtifacts(e){this.setStorageItem("nonce",e.nonce),this.setStorageItem("state",e.state),this.setStorageItem("code_verifier",e.codeVerifier),this.setStorageItem("redirect_uri",e.redirectUri)}async getAuthorizationArtifacts(){const e=this.getStorageItem("state"),t=this.getStorageItem("code_verifier"),r=this.getStorageItem("nonce"),n=this.getStorageItem("redirect_uri"),o=[e,t,r,n].filter(e=>null!==e).length;return 4===o?Promise.resolve({status_code:200,result:{state:e,codeVerifier:t,nonce:r,redirectUri:n},error:null}):0===o?Promise.resolve({status_code:204,result:null,error:null}):Promise.resolve({status_code:400,result:null,error:"Inconsistent authorization artifacts in storage"})}async clearAuthorizationArtifacts(){return window.localStorage.removeItem(`${p}:nonce`),window.localStorage.removeItem(`${p}:state`),window.localStorage.removeItem(`${p}:code_verifier`),window.localStorage.removeItem(`${p}:redirect_uri`),window.localStorage.removeItem(`${p}:login_return_uri`),Promise.resolve({status_code:204,result:null,error:null})}setStorageItem(e,t){window.localStorage.setItem(`${p}:${e}`,t)}getStorageItem(e){return window.localStorage.getItem(`${p}:${e}`)}static normalizeUrl(e){const t=new URL(e);return`${t.origin}${t.pathname}`}static buildAuthorizeUrl(e,t){return`${e}?${Object.entries(t).filter(e=>void 0!==e[1]&&null!==e[1]).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`).join("&")}`}static shouldUseWebConsent(e){const t=i();return!t||"staging"!==e.environment&&!f(t.version,{major:5,minor:396,patch:0})}async performWebAuthorization(e){let t;this.setStorageItem("login_return_uri",window.location.href),this.setStorageItem("redirect_uri",e.redirectUri);try{t=await this.fetchAuthorizationEndpoint(e.environment)}catch(e){return Promise.resolve({status_code:400,error:n(e),result:void 0})}const r={client_id:e.clientId,scope:e.scope,response_type:"code",redirect_uri:e.redirectUri,nonce:e.nonce,state:e.state,code_challenge_method:e.codeChallengeMethod,code_challenge:e.codeChallenge},o=b.buildAuthorizeUrl(t,r);return window.location.assign(o),Promise.resolve({status_code:302,result:null})}async performNativeAuthorization(e){return this.wrappedModule.invoke("authorize",{clientId:e.clientId,redirectUri:e.actualRedirectUri,scope:e.scope,nonce:e.nonce,state:e.state,codeChallenge:e.codeChallenge,codeChallengeMethod:e.codeChallengeMethod,responseMode:e.responseMode})}async authorize(e){const t=b.validateAuthorizeRequest(e);if(t)return Promise.resolve({status_code:400,result:void 0,error:t});const r=await this.generatePKCEArtifacts(),n=e.responseMode||"redirect",o="in_place"===n?b.normalizeUrl(window.location.href):e.redirectUri;this.storePKCEArtifacts({...r,redirectUri:o});const i={clientId:e.clientId,redirectUri:e.redirectUri,scope:e.scope,nonce:r.nonce,state:r.state,codeChallenge:r.codeChallenge,codeChallengeMethod:r.codeChallengeMethod};if(b.shouldUseWebConsent(e))return this.performWebAuthorization({...i,environment:e.environment});try{const t=await this.performNativeAuthorization({...i,actualRedirectUri:o,responseMode:n});return 400===t.status_code||401===t.status_code||403===t.status_code?(console.error(`Native authorization returned ${t.status_code}, falling back to web flow:`,t.error),this.performWebAuthorization({...i,environment:e.environment})):t}catch(t){return console.error("Native authorization failed, falling back to web flow:",t),this.performWebAuthorization({...i,environment:e.environment})}}static validateRequiredString(e,t){return e&&"string"==typeof e&&""!==e.trim()?null:`${t} is required and must be a non-empty string`}static validateAuthorizeRequest(e){if(null==e)return"request is required";const t=b.validateRequiredString(e.scope,"scope");if(t)return t;const r=b.validateRequiredString(e.clientId,"clientId");if(r)return r;const n=b.validateRequiredString(e.redirectUri,"redirectUri");if(n)return n;try{if(!new URL(e.redirectUri))return"redirectUri must be a valid URL"}catch{return"redirectUri must be a valid URL"}return b.validateRequiredString(e.environment,"environment")||("staging"!==e.environment&&"production"!==e.environment?"environment must be either 'staging' or 'production'":null)}}class k extends s{constructor(){super("LocaleModule")}getLanguageLocaleIdentifier(){return this.invoke("getLanguageLocaleIdentifier")}}class y extends s{constructor(){super("LocationModule")}getCoordinate(){return this.invoke("getCoordinate")}observeLocationChange(){return this.wrappedModule.invoke("observeLocationChange")}getCountryCode(){return this.invoke("getCountryCode")}}class C extends s{constructor(){super("MediaModule")}playDRMContent(e){return this.invoke("playDRMContent",{data:e})}observePlayDRMContent(e){return this.wrappedModule.invoke("observePlayDRMContent",{data:e})}}class S extends s{constructor(){super("PlatformModule")}back(){return this.invoke("back")}}class _ extends s{constructor(){super("ProfileModule")}static isSupported(){const e=i();return!!e&&f(e.version,{major:5,minor:399,patch:0})}fetchEmail(){return _.isSupported()?this.invoke("fetchEmail"):Promise.resolve({status_code:403,result:void 0,error:"This feature requires Grab app version 5.399 or above."})}verifyEmail(e){return _.isSupported()?this.invoke("verifyEmail",e):Promise.resolve({status_code:403,result:void 0,error:"This feature requires Grab app version 5.399 or above."})}}class A extends s{constructor(){super("ScopeModule")}hasAccessTo(e,t){return this.invoke("hasAccessTo",{module:e,method:t})}reloadScopes(){return this.invoke("reloadScopes")}}class E extends s{constructor(){super("StorageModule")}setBoolean(e,t){return this.invoke("setBoolean",{key:e,value:t})}getBoolean(e){return this.invoke("getBoolean",{key:e})}setInt(e,t){return this.invoke("setInt",{key:e,value:t})}getInt(e){return this.invoke("getInt",{key:e})}setString(e,t){return this.invoke("setString",{key:e,value:t})}getString(e){return this.invoke("getString",{key:e})}setDouble(e,t){return this.invoke("setDouble",{key:e,value:t})}getDouble(e){return this.invoke("getDouble",{key:e})}remove(e){return this.invoke("remove",{key:e})}removeAll(){return this.invoke("removeAll")}}class I extends s{constructor(){super("SystemWebViewKitModule")}redirectToSystemWebView(e){return this.invoke("redirectToSystemWebView",e)}}export{s as BaseModule,u as CameraModule,c as CheckoutModule,h as ContainerAnalyticsEventData,d as ContainerAnalyticsEventName,l as ContainerAnalyticsEventState,m as ContainerModule,b as IdentityModule,k as LocaleModule,y as LocationModule,C as MediaModule,S as PlatformModule,_ as ProfileModule,A as ScopeModule,E as StorageModule,I as SystemWebViewKitModule};
7
+ var e,t={exports:{}},r=(e||(e=1,function(e){function t(e){var t=!1;return{isUnsubscribed:function(){return t},unsubscribe:function(){t||(e(),t=!0)}}}function r(e){return{subscribe:e,then:function(t,r){return new Promise(function(n,o){try{var a=null,i=!1;a=e({next:function(e){n(null==t?void 0:t(e)),a&&a.unsubscribe(),i=!0}}),i&&a&&a.unsubscribe()}catch(e){null==r?o(e):n(r(e))}})}}}function n(n,o){return o.funcNameToWrap,function(n,o){var a=o.callbackNameFunc,i=o.funcToWrap;return r(function(r){var o,s=a();return n[s]=function(t){if(function(e){for(var t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];if(!e)return!1;var n=function(e){return Object.keys(e).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(e)))}(e);return t.every(function(e){return 0<=n.indexOf(e)})}(t.result,"event"))t.result.event===e.StreamEvent.STREAM_TERMINATED&&o.unsubscribe();else{var n=t.result,a=t.error,i=t.status_code;r&&r.next&&r.next({result:null===n?void 0:n,error:null===a?void 0:a,status_code:null===i?void 0:i})}},i(s),o=t(function(){n[s]=void 0,r&&r.complete&&r.complete()})})}(n,function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(e);o<n.length;o++)t.indexOf(n[o])<0&&(r[n[o]]=e[n[o]])}return r}(o,["funcNameToWrap"]))}(e.StreamEvent||(e.StreamEvent={})).STREAM_TERMINATED="STREAM_TERMINATED",e.createDataStream=r,e.createSubscription=t,e.getModuleEnvironment=function(e,t){return e[t]?"android":e.webkit&&e.webkit.messageHandlers&&e.webkit.messageHandlers[t]?"ios":void 0},e.wrapModule=function(e,t){var r;e[(r=t,"Wrapped"+r)]=function(e,t,r){return{invoke:function(o,a){return n(e,{funcNameToWrap:o,callbackNameFunc:function(){return function(e,t){var r=t.moduleName,n=t.funcName,o=0;return function(){for(var t,a,i="";(i=(t={moduleName:r,funcName:n,requestID:o}).moduleName+"_"+t.funcName+"Callback"+(null!==(a=t.requestID)?"_"+a:""))in e;)o+=1;return o+=1,i}()}(e,{moduleName:t,funcName:o})},funcToWrap:function(e){return r({callback:e,method:o,module:t,parameters:null!=a?a:{}})}})}}}(e,t,function(r){if(e[t]&&e[t][r.method]instanceof Function)e[t][r.method](JSON.stringify(r));else{if(!(e.webkit&&e.webkit.messageHandlers&&e.webkit.messageHandlers[t]))throw new Error("Unexpected method '"+r.method+"' for module '"+t+"'");e.webkit.messageHandlers[t].postMessage(r)}})},Object.defineProperty(e,"__esModule",{value:!0})}(t.exports)),t.exports);function n(e){return"object"==typeof e&&null!==e&&"message"in e&&"string"==typeof e.message}function o(){if("undefined"==typeof window||!window.navigator)return null;const e=window.navigator.userAgent;return e?function(e){if(!e||"string"!=typeof e)return null;const t=e.match(/(Grab|GrabBeta|GrabBetaDebug|GrabTaxi|GrabEarlyAccess)\/v?([0-9]+)\.([0-9]+)\.([0-9]+) \(.*(Android|iOS).*\)/i);return t?{appName:t[1],version:{major:Number(t[2]),minor:Number(t[3]),patch:Number(t[4])},platform:t[5]}:null}(e):null}class a{get wrappedModule(){return window[`Wrapped${this.name}`]}constructor(e){if(this.name=e,!this.wrappedModule)try{r.wrapModule(window,this.name)}catch(e){throw new Error(`Failed to initialize ${this.name}${n(e)&&`: ${e.message}`}`,{cause:e})}}async invoke(e){const{method:t,params:r,isSupported:n,transformResponse:a}=e;try{const e=o();if(!e)return{status_code:501,error:"Not implemented: This method requires the Grab app environment"};if(n&&!n(e))return{status_code:426,error:"Upgrade Required: This method requires a newer version of the Grab app"};const i=await this.wrappedModule.invoke(t,r);return a?a(i):i}catch{return{status_code:500,error:"Failed to invoke method"}}}createErrorStream(e){return{subscribe:t=>(t?.next?.(e),t?.complete?.(),{isUnsubscribed:()=>!0,unsubscribe:()=>{}}),then:t=>Promise.resolve(e).then(t)}}invokeStream(e){const{method:t,params:r,isSupported:n,transformResponse:a}=e;try{const e=o();if(!e)return this.createErrorStream({status_code:501,error:"Not implemented: This method requires the Grab app environment"});if(n&&!n(e))return this.createErrorStream({status_code:426,error:"Upgrade Required: This method requires a newer version of the Grab app"});const i=this.wrappedModule.invoke(t,r);return a?{subscribe:e=>i.subscribe({next:t=>e?.next?.(a(t)),complete:e?.complete}),then:e=>i.then(t=>e?e(a(t)):a(t))}:i}catch{return this.createErrorStream({status_code:500,error:"Failed to invoke method"})}}}function i(e){return 200===e.status_code||204===e.status_code}function s(e){return 302===e.status_code}function c(e){return 400===e.status_code||401===e.status_code||403===e.status_code||404===e.status_code||424===e.status_code||426===e.status_code}function u(e){return 500===e.status_code||501===e.status_code}function d(e){return c(e)||u(e)}class l extends a{constructor(){super("CameraModule")}async scanQRCode(e){return await this.invoke({method:"scanQRCode",params:e})}}class h extends a{constructor(){super("CheckoutModule")}async triggerCheckout(e){return await this.invoke({method:"triggerCheckout",params:e})}}const m={HOMEPAGE:"HOMEPAGE",CHECKOUT_PAGE:"CHECKOUT_PAGE",BOOKING_COMPLETION:"BOOKING_COMPLETION",CUSTOM:"CUSTOM"},p={DEFAULT:"DEFAULT"},g={TRANSACTION_AMOUNT:"transaction_amount",TRANSACTION_CURRENCY:"transaction_currency",PAGE:"page"};class f extends a{constructor(){super("ContainerModule")}async setBackgroundColor(e){return await this.invoke({method:"setBackgroundColor",params:{backgroundColor:e}})}async setTitle(e){return await this.invoke({method:"setTitle",params:{title:e}})}async hideBackButton(){return await this.invoke({method:"hideBackButton"})}async showBackButton(){return await this.invoke({method:"showBackButton"})}async hideRefreshButton(){return await this.invoke({method:"hideRefreshButton"})}async showRefreshButton(){return await this.invoke({method:"showRefreshButton"})}async close(){return await this.invoke({method:"close"})}async onContentLoaded(){return await this.invoke({method:"onContentLoaded"})}async showLoader(){return await this.invoke({method:"showLoader"})}async hideLoader(){return await this.invoke({method:"hideLoader"})}async openExternalLink(e){return await this.invoke({method:"openExternalLink",params:{url:e}})}async onCtaTap(e){return await this.invoke({method:"onCtaTap",params:{action:e}})}async sendAnalyticsEvent(e){const t=this.validateAnalyticsEvent(e);return t?{status_code:400,error:t}:await this.invoke({method:"sendAnalyticsEvent",params:{state:e.state,name:e.name,data:e.data?JSON.stringify(e.data):null}})}async isConnected(){return null!==o()?{status_code:200,result:{connected:!0}}:{status_code:404,error:"Not connected to Grab app"}}async getSessionParams(){return await this.invoke({method:"getSessionParams"})}validateAnalyticsEvent(e){return null==e.name?"name is required":"string"!=typeof e.name?"name must be a string":null==e.state?"state is required":"string"!=typeof e.state?"state must be a string":null!=e.data&&"object"!=typeof e.data?"data must be undefined or an object":null}}class v extends a{constructor(){super("DeviceCapabilityModule")}async isEsimSupported(){return await this.invoke({method:"isEsimSupported"})}}class w extends a{constructor(){super("FileModule")}async downloadFile(e){return await this.invoke({method:"downloadFile",params:e})}}function y(e){const t=new Uint32Array(e);crypto.getRandomValues(t);let r="";for(let n=0;n<e;n+=1)r+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(t[n]%62);return r}async function b(e){const t=(new TextEncoder).encode(e);return function(e){const t=new Uint8Array(e);let r="";for(let e=0;e<t.byteLength;e+=1)r+=String.fromCharCode(t[e]);return btoa(r).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}(await crypto.subtle.digest("SHA-256",t))}function k(e,t){return e.major!==t.major?e.major>t.major:e.minor!==t.minor?e.minor>t.minor:e.patch>=t.patch}const S="grabid",_={staging:"https://partner-api.stg-myteksi.com/grabid/v1/oauth2/.well-known/openid-configuration",production:"https://partner-api.grab.com/grabid/v1/oauth2/.well-known/openid-configuration"};class C extends Error{constructor(e,t){super(e),this.cause=t,this.name="AuthorizationConfigurationError"}}class M extends a{constructor(){super("IdentityModule")}async fetchAuthorizationEndpoint(e){const t=_[e];if(!t)throw new Error(`Invalid environment: ${e}. Must be 'staging' or 'production'`);try{const e=await fetch(t);if(!e.ok)throw console.error(`Failed to fetch OpenID configuration from ${t}: ${e.status} ${e.statusText}`),new C("Failed to fetch authorization configuration");const r=await e.json();if(!r.authorization_endpoint)throw console.error("authorization_endpoint not found in OpenID configuration response"),new C("Invalid authorization configuration");return r.authorization_endpoint}catch(e){if(console.error("Error fetching authorization endpoint:",e),e instanceof C)throw e;throw new Error("Something wrong happened when fetching authorization configuration",{cause:e})}}async generatePKCEArtifacts(){const e=y(16),t=y(7),r=(n=y(64),btoa(n).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_"));var n;return{nonce:e,state:t,codeVerifier:r,codeChallenge:await b(r),codeChallengeMethod:"S256"}}storePKCEArtifacts(e){this.setStorageItem("nonce",e.nonce),this.setStorageItem("state",e.state),this.setStorageItem("code_verifier",e.codeVerifier),this.setStorageItem("redirect_uri",e.redirectUri)}async getAuthorizationArtifacts(){const e=this.getStorageItem("state"),t=this.getStorageItem("code_verifier"),r=this.getStorageItem("nonce"),n=this.getStorageItem("redirect_uri"),o=[e,t,r,n].filter(e=>null!==e).length;return 4===o?{status_code:200,result:{state:e,codeVerifier:t,nonce:r,redirectUri:n}}:0===o?{status_code:204}:{status_code:400,error:"Inconsistent authorization artifacts in storage"}}async clearAuthorizationArtifacts(){return window.localStorage.removeItem(`${S}:nonce`),window.localStorage.removeItem(`${S}:state`),window.localStorage.removeItem(`${S}:code_verifier`),window.localStorage.removeItem(`${S}:redirect_uri`),window.localStorage.removeItem(`${S}:login_return_uri`),{status_code:204}}setStorageItem(e,t){window.localStorage.setItem(`${S}:${e}`,t)}getStorageItem(e){return window.localStorage.getItem(`${S}:${e}`)}static normalizeUrl(e){const t=new URL(e);return`${t.origin}${t.pathname}`}static buildAuthorizeUrl(e,t){return`${e}?${Object.entries(t).filter(e=>void 0!==e[1]&&null!==e[1]).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`).join("&")}`}static shouldUseWebConsent(e){const t=o();return!t||"staging"!==e.environment&&!k(t.version,{major:5,minor:396,patch:0})}async performWebAuthorization(e){let t;this.setStorageItem("login_return_uri",window.location.href),this.setStorageItem("redirect_uri",e.redirectUri);try{t=await this.fetchAuthorizationEndpoint(e.environment)}catch(e){return{status_code:400,error:n(e)?e.message:"Could not fetch authorization endpoint"}}const r={client_id:e.clientId,scope:e.scope,response_type:"code",redirect_uri:e.redirectUri,nonce:e.nonce,state:e.state,code_challenge_method:e.codeChallengeMethod,code_challenge:e.codeChallenge},o=M.buildAuthorizeUrl(t,r);return window.location.assign(o),{status_code:302}}async performNativeAuthorization(e){return await this.invoke({method:"authorize",params:{clientId:e.clientId,redirectUri:e.actualRedirectUri,scope:e.scope,nonce:e.nonce,state:e.state,codeChallenge:e.codeChallenge,codeChallengeMethod:e.codeChallengeMethod,responseMode:e.responseMode}})}async authorize(e){const t=M.validateAuthorizeRequest(e);if(t)return{status_code:400,error:t};const r=await this.generatePKCEArtifacts(),n=e.responseMode||"redirect",o="in_place"===n?M.normalizeUrl(window.location.href):e.redirectUri;this.storePKCEArtifacts({...r,redirectUri:o});const a={clientId:e.clientId,redirectUri:e.redirectUri,scope:e.scope,nonce:r.nonce,state:r.state,codeChallenge:r.codeChallenge,codeChallengeMethod:r.codeChallengeMethod};if(M.shouldUseWebConsent(e))return this.performWebAuthorization({...a,environment:e.environment});try{const t=await this.performNativeAuthorization({...a,actualRedirectUri:o,responseMode:n});return 400===t.status_code||401===t.status_code||403===t.status_code||500===t.status_code||501===t.status_code?(console.error(`Native authorization returned ${t.status_code}, falling back to web flow:`,t.error),this.performWebAuthorization({...a,environment:e.environment})):t}catch(t){return console.error("Native authorization failed, falling back to web flow:",t),this.performWebAuthorization({...a,environment:e.environment})}}static validateRequiredString(e,t){return e&&"string"==typeof e&&""!==e.trim()?null:`${t} is required and must be a non-empty string`}static validateAuthorizeRequest(e){if(null==e)return"request is required";const t=M.validateRequiredString(e.scope,"scope");if(t)return t;const r=M.validateRequiredString(e.clientId,"clientId");if(r)return r;const n=M.validateRequiredString(e.redirectUri,"redirectUri");if(n)return n;try{if(!new URL(e.redirectUri))return"redirectUri must be a valid URL"}catch{return"redirectUri must be a valid URL"}return M.validateRequiredString(e.environment,"environment")||("staging"!==e.environment&&"production"!==e.environment?"environment must be either 'staging' or 'production'":null)}}class E extends a{constructor(){super("LocaleModule")}async getLanguageLocaleIdentifier(){return await this.invoke({method:"getLanguageLocaleIdentifier"})}}class I extends a{constructor(){super("LocationModule")}async getCoordinate(){return await this.invoke({method:"getCoordinate"})}observeLocationChange(){return this.invokeStream({method:"observeLocationChange"})}async getCountryCode(){return await this.invoke({method:"getCountryCode"})}}class A extends a{constructor(){super("MediaModule")}async playDRMContent(e){return await this.invoke({method:"playDRMContent",params:{data:e}})}observePlayDRMContent(e){return this.invokeStream({method:"observePlayDRMContent",params:{data:e}})}}class U extends a{constructor(){super("PlatformModule")}async back(){return await this.invoke({method:"back"})}}class N extends a{constructor(){super("ProfileModule")}async fetchEmail(){return await this.invoke({method:"fetchEmail",isSupported:e=>k(e.version,N.MINIMUM_VERSION)})}async verifyEmail(e){return await this.invoke({method:"verifyEmail",params:e,isSupported:e=>k(e.version,N.MINIMUM_VERSION)})}}N.MINIMUM_VERSION={major:5,minor:399,patch:0};class T extends a{constructor(){super("ScopeModule")}async hasAccessTo(e,t){return await this.invoke({method:"hasAccessTo",params:{module:e,method:t}})}async reloadScopes(){return await this.invoke({method:"reloadScopes"})}}class R extends a{constructor(){super("StorageModule")}async setBoolean(e,t){return await this.invoke({method:"setBoolean",params:{key:e,value:t}})}async getBoolean(e){return await this.invoke({method:"getBoolean",params:{key:e}})}async setInt(e,t){return await this.invoke({method:"setInt",params:{key:e,value:t}})}async getInt(e){return await this.invoke({method:"getInt",params:{key:e}})}async setString(e,t){return await this.invoke({method:"setString",params:{key:e,value:t}})}async getString(e){return await this.invoke({method:"getString",params:{key:e}})}async setDouble(e,t){return await this.invoke({method:"setDouble",params:{key:e,value:t}})}async getDouble(e){return await this.invoke({method:"getDouble",params:{key:e}})}async remove(e){return await this.invoke({method:"remove",params:{key:e}})}async removeAll(){return await this.invoke({method:"removeAll"})}}class O extends a{constructor(){super("SystemWebViewKitModule")}async redirectToSystemWebView(e){return await this.invoke({method:"redirectToSystemWebView",params:e})}}class x extends a{constructor(){super("UserAttributesModule")}async getSelectedTravelDestination(){return await this.invoke({method:"getSelectedTravelDestination"})}}export{a as BaseModule,l as CameraModule,h as CheckoutModule,g as ContainerAnalyticsEventData,p as ContainerAnalyticsEventName,m as ContainerAnalyticsEventState,f as ContainerModule,v as DeviceCapabilityModule,w as FileModule,M as IdentityModule,E as LocaleModule,I as LocationModule,A as MediaModule,U as PlatformModule,N as ProfileModule,T as ScopeModule,R as StorageModule,O as SystemWebViewKitModule,x as UserAttributesModule,c as isClientError,d as isErrorResponse,s as isRedirection,u as isServerError,i as isSuccess};
package/dist/index.js CHANGED
@@ -4,4 +4,4 @@
4
4
  * This source code is licensed under the MIT license found in the LICENSE file in the root
5
5
  * directory of this source tree.
6
6
  */
7
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SuperAppSDK={})}(this,function(e){"use strict";var t,r={exports:{}},n=(t||(t=1,function(e){function t(e){var t=!1;return{isUnsubscribed:function(){return t},unsubscribe:function(){t||(e(),t=!0)}}}function r(e){return{subscribe:e,then:function(t,r){return new Promise(function(n,o){try{var i=null,a=!1;i=e({next:function(e){n(null==t?void 0:t(e)),i&&i.unsubscribe(),a=!0}}),a&&i&&i.unsubscribe()}catch(e){null==r?o(e):n(r(e))}})}}}function n(n,o){return o.funcNameToWrap,function(n,o){var i=o.callbackNameFunc,a=o.funcToWrap;return r(function(r){var o,s=i();return n[s]=function(t){if(function(e){for(var t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];if(!e)return!1;var n=function(e){return Object.keys(e).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(e)))}(e);return t.every(function(e){return 0<=n.indexOf(e)})}(t.result,"event"))t.result.event===e.StreamEvent.STREAM_TERMINATED&&o.unsubscribe();else{var n=t.result,i=t.error,a=t.status_code;r&&r.next&&r.next({result:null===n?void 0:n,error:null===i?void 0:i,status_code:null===a?void 0:a})}},a(s),o=t(function(){n[s]=void 0,r&&r.complete&&r.complete()})})}(n,function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(e);o<n.length;o++)t.indexOf(n[o])<0&&(r[n[o]]=e[n[o]])}return r}(o,["funcNameToWrap"]))}(e.StreamEvent||(e.StreamEvent={})).STREAM_TERMINATED="STREAM_TERMINATED",e.createDataStream=r,e.createSubscription=t,e.getModuleEnvironment=function(e,t){return e[t]?"android":e.webkit&&e.webkit.messageHandlers&&e.webkit.messageHandlers[t]?"ios":void 0},e.wrapModule=function(e,t){var r;e[(r=t,"Wrapped"+r)]=function(e,t,r){return{invoke:function(o,i){return n(e,{funcNameToWrap:o,callbackNameFunc:function(){return function(e,t){var r=t.moduleName,n=t.funcName,o=0;return function(){for(var t,i,a="";(a=(t={moduleName:r,funcName:n,requestID:o}).moduleName+"_"+t.funcName+"Callback"+(null!==(i=t.requestID)?"_"+i:""))in e;)o+=1;return o+=1,a}()}(e,{moduleName:t,funcName:o})},funcToWrap:function(e){return r({callback:e,method:o,module:t,parameters:null!=i?i:{}})}})}}}(e,t,function(r){if(e[t]&&e[t][r.method]instanceof Function)e[t][r.method](JSON.stringify(r));else{if(!(e.webkit&&e.webkit.messageHandlers&&e.webkit.messageHandlers[t]))throw new Error("Unexpected method '"+r.method+"' for module '"+t+"'");e.webkit.messageHandlers[t].postMessage(r)}})},Object.defineProperty(e,"__esModule",{value:!0})}(r.exports)),r.exports);function o(e){return e instanceof Error?e.message:String(e)}function i(e,t){return e instanceof Error&&e.message===t}function a(){if("undefined"==typeof window||!window.navigator)return null;const e=window.navigator.userAgent;return e?function(e){if(!e||"string"!=typeof e)return null;const t=e.match(/(Grab|GrabBeta|GrabBetaDebug|GrabTaxi|GrabEarlyAccess)\/v?([0-9]+)\.([0-9]+)\.([0-9]+) \(.*(Android|iOS).*\)/i);return t?{appName:t[1],version:{major:Number(t[2]),minor:Number(t[3]),patch:Number(t[4])},platform:t[5]}:null}(e):null}function s(){if("undefined"==typeof window||!window.navigator)return!1;const e=window.navigator.userAgent;return!!e&&/grab[a-z]*\//i.test(e)}class u{get wrappedModule(){return window[`Wrapped${this.name}`]}constructor(e){if(this.name=e,!this.wrappedModule)try{n.wrapModule(window,this.name)}catch(e){throw new Error(`Failed to initialize ${this.name}: ${o(e)}`,{cause:e})}}invoke(e,t){return s()?this.wrappedModule.invoke(e,t):Promise.resolve({status_code:501,result:void 0,error:"Not implemented: This method requires the Grab app environment"})}}function c(e){const t=new Uint32Array(e);crypto.getRandomValues(t);let r="";for(let n=0;n<e;n+=1)r+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(t[n]%62);return r}async function l(e){const t=(new TextEncoder).encode(e);return function(e){const t=new Uint8Array(e);let r="";for(let e=0;e<t.byteLength;e+=1)r+=String.fromCharCode(t[e]);return btoa(r).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}(await crypto.subtle.digest("SHA-256",t))}function d(e,t){return e.major!==t.major?e.major>t.major:e.minor!==t.minor?e.minor>t.minor:e.patch>=t.patch}const h="grabid",m={staging:"https://partner-api.stg-myteksi.com/grabid/v1/oauth2/.well-known/openid-configuration",production:"https://partner-api.grab.com/grabid/v1/oauth2/.well-known/openid-configuration"};class f extends u{constructor(){super("IdentityModule")}async fetchAuthorizationEndpoint(e){const t=m[e];if(!t)throw new Error(`Invalid environment: ${e}. Must be 'staging' or 'production'`);try{const e=await fetch(t);if(!e.ok)throw console.error(`Failed to fetch OpenID configuration from ${t}: ${e.status} ${e.statusText}`),new Error("Failed to fetch authorization configuration");const r=await e.json();if(!r.authorization_endpoint)throw console.error("authorization_endpoint not found in OpenID configuration response"),new Error("Invalid authorization configuration");return r.authorization_endpoint}catch(e){if(console.error("Error fetching authorization endpoint:",e),i(e,"Failed to fetch authorization configuration")||i(e,"Invalid authorization configuration"))throw e;throw new Error("Something wrong happened when fetching authorization configuration",{cause:e})}}async generatePKCEArtifacts(){const e=c(16),t=c(7),r=(n=c(64),btoa(n).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_"));var n;return{nonce:e,state:t,codeVerifier:r,codeChallenge:await l(r),codeChallengeMethod:"S256"}}storePKCEArtifacts(e){this.setStorageItem("nonce",e.nonce),this.setStorageItem("state",e.state),this.setStorageItem("code_verifier",e.codeVerifier),this.setStorageItem("redirect_uri",e.redirectUri)}async getAuthorizationArtifacts(){const e=this.getStorageItem("state"),t=this.getStorageItem("code_verifier"),r=this.getStorageItem("nonce"),n=this.getStorageItem("redirect_uri"),o=[e,t,r,n].filter(e=>null!==e).length;return 4===o?Promise.resolve({status_code:200,result:{state:e,codeVerifier:t,nonce:r,redirectUri:n},error:null}):0===o?Promise.resolve({status_code:204,result:null,error:null}):Promise.resolve({status_code:400,result:null,error:"Inconsistent authorization artifacts in storage"})}async clearAuthorizationArtifacts(){return window.localStorage.removeItem(`${h}:nonce`),window.localStorage.removeItem(`${h}:state`),window.localStorage.removeItem(`${h}:code_verifier`),window.localStorage.removeItem(`${h}:redirect_uri`),window.localStorage.removeItem(`${h}:login_return_uri`),Promise.resolve({status_code:204,result:null,error:null})}setStorageItem(e,t){window.localStorage.setItem(`${h}:${e}`,t)}getStorageItem(e){return window.localStorage.getItem(`${h}:${e}`)}static normalizeUrl(e){const t=new URL(e);return`${t.origin}${t.pathname}`}static buildAuthorizeUrl(e,t){return`${e}?${Object.entries(t).filter(e=>void 0!==e[1]&&null!==e[1]).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`).join("&")}`}static shouldUseWebConsent(e){const t=a();return!t||"staging"!==e.environment&&!d(t.version,{major:5,minor:396,patch:0})}async performWebAuthorization(e){let t;this.setStorageItem("login_return_uri",window.location.href),this.setStorageItem("redirect_uri",e.redirectUri);try{t=await this.fetchAuthorizationEndpoint(e.environment)}catch(e){return Promise.resolve({status_code:400,error:o(e),result:void 0})}const r={client_id:e.clientId,scope:e.scope,response_type:"code",redirect_uri:e.redirectUri,nonce:e.nonce,state:e.state,code_challenge_method:e.codeChallengeMethod,code_challenge:e.codeChallenge},n=f.buildAuthorizeUrl(t,r);return window.location.assign(n),Promise.resolve({status_code:302,result:null})}async performNativeAuthorization(e){return this.wrappedModule.invoke("authorize",{clientId:e.clientId,redirectUri:e.actualRedirectUri,scope:e.scope,nonce:e.nonce,state:e.state,codeChallenge:e.codeChallenge,codeChallengeMethod:e.codeChallengeMethod,responseMode:e.responseMode})}async authorize(e){const t=f.validateAuthorizeRequest(e);if(t)return Promise.resolve({status_code:400,result:void 0,error:t});const r=await this.generatePKCEArtifacts(),n=e.responseMode||"redirect",o="in_place"===n?f.normalizeUrl(window.location.href):e.redirectUri;this.storePKCEArtifacts({...r,redirectUri:o});const i={clientId:e.clientId,redirectUri:e.redirectUri,scope:e.scope,nonce:r.nonce,state:r.state,codeChallenge:r.codeChallenge,codeChallengeMethod:r.codeChallengeMethod};if(f.shouldUseWebConsent(e))return this.performWebAuthorization({...i,environment:e.environment});try{const t=await this.performNativeAuthorization({...i,actualRedirectUri:o,responseMode:n});return 400===t.status_code||401===t.status_code||403===t.status_code?(console.error(`Native authorization returned ${t.status_code}, falling back to web flow:`,t.error),this.performWebAuthorization({...i,environment:e.environment})):t}catch(t){return console.error("Native authorization failed, falling back to web flow:",t),this.performWebAuthorization({...i,environment:e.environment})}}static validateRequiredString(e,t){return e&&"string"==typeof e&&""!==e.trim()?null:`${t} is required and must be a non-empty string`}static validateAuthorizeRequest(e){if(null==e)return"request is required";const t=f.validateRequiredString(e.scope,"scope");if(t)return t;const r=f.validateRequiredString(e.clientId,"clientId");if(r)return r;const n=f.validateRequiredString(e.redirectUri,"redirectUri");if(n)return n;try{if(!new URL(e.redirectUri))return"redirectUri must be a valid URL"}catch{return"redirectUri must be a valid URL"}return f.validateRequiredString(e.environment,"environment")||("staging"!==e.environment&&"production"!==e.environment?"environment must be either 'staging' or 'production'":null)}}class v extends u{constructor(){super("ProfileModule")}static isSupported(){const e=a();return!!e&&d(e.version,{major:5,minor:399,patch:0})}fetchEmail(){return v.isSupported()?this.invoke("fetchEmail"):Promise.resolve({status_code:403,result:void 0,error:"This feature requires Grab app version 5.399 or above."})}verifyEmail(e){return v.isSupported()?this.invoke("verifyEmail",e):Promise.resolve({status_code:403,result:void 0,error:"This feature requires Grab app version 5.399 or above."})}}e.BaseModule=u,e.CameraModule=class extends u{constructor(){super("CameraModule")}scanQRCode(e){return this.invoke("scanQRCode",e)}},e.CheckoutModule=class extends u{constructor(){super("CheckoutModule")}triggerCheckout(e){return this.invoke("triggerCheckout",e)}},e.ContainerAnalyticsEventData={TRANSACTION_AMOUNT:"transaction_amount",TRANSACTION_CURRENCY:"transaction_currency",PAGE:"page"},e.ContainerAnalyticsEventName={DEFAULT:"DEFAULT"},e.ContainerAnalyticsEventState={HOMEPAGE:"HOMEPAGE",CHECKOUT_PAGE:"CHECKOUT_PAGE",BOOKING_COMPLETION:"BOOKING_COMPLETION",CUSTOM:"CUSTOM"},e.ContainerModule=class extends u{constructor(){super("ContainerModule")}setBackgroundColor(e){return this.invoke("setBackgroundColor",{backgroundColor:e})}setTitle(e){return this.invoke("setTitle",{title:e})}hideBackButton(){return this.invoke("hideBackButton")}showBackButton(){return this.invoke("showBackButton")}hideRefreshButton(){return this.invoke("hideRefreshButton")}showRefreshButton(){return this.invoke("showRefreshButton")}close(){return this.invoke("close")}onContentLoaded(){return this.invoke("onContentLoaded")}showLoader(){return this.invoke("showLoader")}hideLoader(){return this.invoke("hideLoader")}openExternalLink(e){return this.invoke("openExternalLink",{url:e})}onCtaTap(e){return this.invoke("onCtaTap",{action:e})}sendAnalyticsEvent(e){const t=this.validateAnalyticsEvent(e);return t?Promise.resolve({status_code:400,result:void 0,error:t}):this.invoke("sendAnalyticsEvent",{state:e.state,name:e.name,data:e.data?JSON.stringify(e.data):null})}isConnected(){const e=s();return Promise.resolve(e?{status_code:200,result:{connected:!0},error:null}:{status_code:404,error:"Not connected to Grab app",result:null})}getSessionParams(){return this.invoke("getSessionParams")}validateAnalyticsEvent(e){return null==e.name?"name is required":"string"!=typeof e.name?"name must be a string":null==e.state?"state is required":"string"!=typeof e.state?"state must be a string":null!=e.data&&"object"!=typeof e.data?"data must be undefined or an object":null}},e.IdentityModule=f,e.LocaleModule=class extends u{constructor(){super("LocaleModule")}getLanguageLocaleIdentifier(){return this.invoke("getLanguageLocaleIdentifier")}},e.LocationModule=class extends u{constructor(){super("LocationModule")}getCoordinate(){return this.invoke("getCoordinate")}observeLocationChange(){return this.wrappedModule.invoke("observeLocationChange")}getCountryCode(){return this.invoke("getCountryCode")}},e.MediaModule=class extends u{constructor(){super("MediaModule")}playDRMContent(e){return this.invoke("playDRMContent",{data:e})}observePlayDRMContent(e){return this.wrappedModule.invoke("observePlayDRMContent",{data:e})}},e.PlatformModule=class extends u{constructor(){super("PlatformModule")}back(){return this.invoke("back")}},e.ProfileModule=v,e.ScopeModule=class extends u{constructor(){super("ScopeModule")}hasAccessTo(e,t){return this.invoke("hasAccessTo",{module:e,method:t})}reloadScopes(){return this.invoke("reloadScopes")}},e.StorageModule=class extends u{constructor(){super("StorageModule")}setBoolean(e,t){return this.invoke("setBoolean",{key:e,value:t})}getBoolean(e){return this.invoke("getBoolean",{key:e})}setInt(e,t){return this.invoke("setInt",{key:e,value:t})}getInt(e){return this.invoke("getInt",{key:e})}setString(e,t){return this.invoke("setString",{key:e,value:t})}getString(e){return this.invoke("getString",{key:e})}setDouble(e,t){return this.invoke("setDouble",{key:e,value:t})}getDouble(e){return this.invoke("getDouble",{key:e})}remove(e){return this.invoke("remove",{key:e})}removeAll(){return this.invoke("removeAll")}},e.SystemWebViewKitModule=class extends u{constructor(){super("SystemWebViewKitModule")}redirectToSystemWebView(e){return this.invoke("redirectToSystemWebView",e)}}});
7
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SuperAppSDK={})}(this,function(e){"use strict";var t,r={exports:{}},n=(t||(t=1,function(e){function t(e){var t=!1;return{isUnsubscribed:function(){return t},unsubscribe:function(){t||(e(),t=!0)}}}function r(e){return{subscribe:e,then:function(t,r){return new Promise(function(n,o){try{var a=null,i=!1;a=e({next:function(e){n(null==t?void 0:t(e)),a&&a.unsubscribe(),i=!0}}),i&&a&&a.unsubscribe()}catch(e){null==r?o(e):n(r(e))}})}}}function n(n,o){return o.funcNameToWrap,function(n,o){var a=o.callbackNameFunc,i=o.funcToWrap;return r(function(r){var o,s=a();return n[s]=function(t){if(function(e){for(var t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];if(!e)return!1;var n=function(e){return Object.keys(e).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(e)))}(e);return t.every(function(e){return 0<=n.indexOf(e)})}(t.result,"event"))t.result.event===e.StreamEvent.STREAM_TERMINATED&&o.unsubscribe();else{var n=t.result,a=t.error,i=t.status_code;r&&r.next&&r.next({result:null===n?void 0:n,error:null===a?void 0:a,status_code:null===i?void 0:i})}},i(s),o=t(function(){n[s]=void 0,r&&r.complete&&r.complete()})})}(n,function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(e);o<n.length;o++)t.indexOf(n[o])<0&&(r[n[o]]=e[n[o]])}return r}(o,["funcNameToWrap"]))}(e.StreamEvent||(e.StreamEvent={})).STREAM_TERMINATED="STREAM_TERMINATED",e.createDataStream=r,e.createSubscription=t,e.getModuleEnvironment=function(e,t){return e[t]?"android":e.webkit&&e.webkit.messageHandlers&&e.webkit.messageHandlers[t]?"ios":void 0},e.wrapModule=function(e,t){var r;e[(r=t,"Wrapped"+r)]=function(e,t,r){return{invoke:function(o,a){return n(e,{funcNameToWrap:o,callbackNameFunc:function(){return function(e,t){var r=t.moduleName,n=t.funcName,o=0;return function(){for(var t,a,i="";(i=(t={moduleName:r,funcName:n,requestID:o}).moduleName+"_"+t.funcName+"Callback"+(null!==(a=t.requestID)?"_"+a:""))in e;)o+=1;return o+=1,i}()}(e,{moduleName:t,funcName:o})},funcToWrap:function(e){return r({callback:e,method:o,module:t,parameters:null!=a?a:{}})}})}}}(e,t,function(r){if(e[t]&&e[t][r.method]instanceof Function)e[t][r.method](JSON.stringify(r));else{if(!(e.webkit&&e.webkit.messageHandlers&&e.webkit.messageHandlers[t]))throw new Error("Unexpected method '"+r.method+"' for module '"+t+"'");e.webkit.messageHandlers[t].postMessage(r)}})},Object.defineProperty(e,"__esModule",{value:!0})}(r.exports)),r.exports);function o(e){return"object"==typeof e&&null!==e&&"message"in e&&"string"==typeof e.message}function a(){if("undefined"==typeof window||!window.navigator)return null;const e=window.navigator.userAgent;return e?function(e){if(!e||"string"!=typeof e)return null;const t=e.match(/(Grab|GrabBeta|GrabBetaDebug|GrabTaxi|GrabEarlyAccess)\/v?([0-9]+)\.([0-9]+)\.([0-9]+) \(.*(Android|iOS).*\)/i);return t?{appName:t[1],version:{major:Number(t[2]),minor:Number(t[3]),patch:Number(t[4])},platform:t[5]}:null}(e):null}class i{get wrappedModule(){return window[`Wrapped${this.name}`]}constructor(e){if(this.name=e,!this.wrappedModule)try{n.wrapModule(window,this.name)}catch(e){throw new Error(`Failed to initialize ${this.name}${o(e)&&`: ${e.message}`}`,{cause:e})}}async invoke(e){const{method:t,params:r,isSupported:n,transformResponse:o}=e;try{const e=a();if(!e)return{status_code:501,error:"Not implemented: This method requires the Grab app environment"};if(n&&!n(e))return{status_code:426,error:"Upgrade Required: This method requires a newer version of the Grab app"};const i=await this.wrappedModule.invoke(t,r);return o?o(i):i}catch{return{status_code:500,error:"Failed to invoke method"}}}createErrorStream(e){return{subscribe:t=>(t?.next?.(e),t?.complete?.(),{isUnsubscribed:()=>!0,unsubscribe:()=>{}}),then:t=>Promise.resolve(e).then(t)}}invokeStream(e){const{method:t,params:r,isSupported:n,transformResponse:o}=e;try{const e=a();if(!e)return this.createErrorStream({status_code:501,error:"Not implemented: This method requires the Grab app environment"});if(n&&!n(e))return this.createErrorStream({status_code:426,error:"Upgrade Required: This method requires a newer version of the Grab app"});const i=this.wrappedModule.invoke(t,r);return o?{subscribe:e=>i.subscribe({next:t=>e?.next?.(o(t)),complete:e?.complete}),then:e=>i.then(t=>e?e(o(t)):o(t))}:i}catch{return this.createErrorStream({status_code:500,error:"Failed to invoke method"})}}}function s(e){return 400===e.status_code||401===e.status_code||403===e.status_code||404===e.status_code||424===e.status_code||426===e.status_code}function c(e){return 500===e.status_code||501===e.status_code}function u(e){const t=new Uint32Array(e);crypto.getRandomValues(t);let r="";for(let n=0;n<e;n+=1)r+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(t[n]%62);return r}async function d(e){const t=(new TextEncoder).encode(e);return function(e){const t=new Uint8Array(e);let r="";for(let e=0;e<t.byteLength;e+=1)r+=String.fromCharCode(t[e]);return btoa(r).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}(await crypto.subtle.digest("SHA-256",t))}function l(e,t){return e.major!==t.major?e.major>t.major:e.minor!==t.minor?e.minor>t.minor:e.patch>=t.patch}const h="grabid",m={staging:"https://partner-api.stg-myteksi.com/grabid/v1/oauth2/.well-known/openid-configuration",production:"https://partner-api.grab.com/grabid/v1/oauth2/.well-known/openid-configuration"};class p extends Error{constructor(e,t){super(e),this.cause=t,this.name="AuthorizationConfigurationError"}}class f extends i{constructor(){super("IdentityModule")}async fetchAuthorizationEndpoint(e){const t=m[e];if(!t)throw new Error(`Invalid environment: ${e}. Must be 'staging' or 'production'`);try{const e=await fetch(t);if(!e.ok)throw console.error(`Failed to fetch OpenID configuration from ${t}: ${e.status} ${e.statusText}`),new p("Failed to fetch authorization configuration");const r=await e.json();if(!r.authorization_endpoint)throw console.error("authorization_endpoint not found in OpenID configuration response"),new p("Invalid authorization configuration");return r.authorization_endpoint}catch(e){if(console.error("Error fetching authorization endpoint:",e),e instanceof p)throw e;throw new Error("Something wrong happened when fetching authorization configuration",{cause:e})}}async generatePKCEArtifacts(){const e=u(16),t=u(7),r=(n=u(64),btoa(n).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_"));var n;return{nonce:e,state:t,codeVerifier:r,codeChallenge:await d(r),codeChallengeMethod:"S256"}}storePKCEArtifacts(e){this.setStorageItem("nonce",e.nonce),this.setStorageItem("state",e.state),this.setStorageItem("code_verifier",e.codeVerifier),this.setStorageItem("redirect_uri",e.redirectUri)}async getAuthorizationArtifacts(){const e=this.getStorageItem("state"),t=this.getStorageItem("code_verifier"),r=this.getStorageItem("nonce"),n=this.getStorageItem("redirect_uri"),o=[e,t,r,n].filter(e=>null!==e).length;return 4===o?{status_code:200,result:{state:e,codeVerifier:t,nonce:r,redirectUri:n}}:0===o?{status_code:204}:{status_code:400,error:"Inconsistent authorization artifacts in storage"}}async clearAuthorizationArtifacts(){return window.localStorage.removeItem(`${h}:nonce`),window.localStorage.removeItem(`${h}:state`),window.localStorage.removeItem(`${h}:code_verifier`),window.localStorage.removeItem(`${h}:redirect_uri`),window.localStorage.removeItem(`${h}:login_return_uri`),{status_code:204}}setStorageItem(e,t){window.localStorage.setItem(`${h}:${e}`,t)}getStorageItem(e){return window.localStorage.getItem(`${h}:${e}`)}static normalizeUrl(e){const t=new URL(e);return`${t.origin}${t.pathname}`}static buildAuthorizeUrl(e,t){return`${e}?${Object.entries(t).filter(e=>void 0!==e[1]&&null!==e[1]).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`).join("&")}`}static shouldUseWebConsent(e){const t=a();return!t||"staging"!==e.environment&&!l(t.version,{major:5,minor:396,patch:0})}async performWebAuthorization(e){let t;this.setStorageItem("login_return_uri",window.location.href),this.setStorageItem("redirect_uri",e.redirectUri);try{t=await this.fetchAuthorizationEndpoint(e.environment)}catch(e){return{status_code:400,error:o(e)?e.message:"Could not fetch authorization endpoint"}}const r={client_id:e.clientId,scope:e.scope,response_type:"code",redirect_uri:e.redirectUri,nonce:e.nonce,state:e.state,code_challenge_method:e.codeChallengeMethod,code_challenge:e.codeChallenge},n=f.buildAuthorizeUrl(t,r);return window.location.assign(n),{status_code:302}}async performNativeAuthorization(e){return await this.invoke({method:"authorize",params:{clientId:e.clientId,redirectUri:e.actualRedirectUri,scope:e.scope,nonce:e.nonce,state:e.state,codeChallenge:e.codeChallenge,codeChallengeMethod:e.codeChallengeMethod,responseMode:e.responseMode}})}async authorize(e){const t=f.validateAuthorizeRequest(e);if(t)return{status_code:400,error:t};const r=await this.generatePKCEArtifacts(),n=e.responseMode||"redirect",o="in_place"===n?f.normalizeUrl(window.location.href):e.redirectUri;this.storePKCEArtifacts({...r,redirectUri:o});const a={clientId:e.clientId,redirectUri:e.redirectUri,scope:e.scope,nonce:r.nonce,state:r.state,codeChallenge:r.codeChallenge,codeChallengeMethod:r.codeChallengeMethod};if(f.shouldUseWebConsent(e))return this.performWebAuthorization({...a,environment:e.environment});try{const t=await this.performNativeAuthorization({...a,actualRedirectUri:o,responseMode:n});return 400===t.status_code||401===t.status_code||403===t.status_code||500===t.status_code||501===t.status_code?(console.error(`Native authorization returned ${t.status_code}, falling back to web flow:`,t.error),this.performWebAuthorization({...a,environment:e.environment})):t}catch(t){return console.error("Native authorization failed, falling back to web flow:",t),this.performWebAuthorization({...a,environment:e.environment})}}static validateRequiredString(e,t){return e&&"string"==typeof e&&""!==e.trim()?null:`${t} is required and must be a non-empty string`}static validateAuthorizeRequest(e){if(null==e)return"request is required";const t=f.validateRequiredString(e.scope,"scope");if(t)return t;const r=f.validateRequiredString(e.clientId,"clientId");if(r)return r;const n=f.validateRequiredString(e.redirectUri,"redirectUri");if(n)return n;try{if(!new URL(e.redirectUri))return"redirectUri must be a valid URL"}catch{return"redirectUri must be a valid URL"}return f.validateRequiredString(e.environment,"environment")||("staging"!==e.environment&&"production"!==e.environment?"environment must be either 'staging' or 'production'":null)}}class g extends i{constructor(){super("ProfileModule")}async fetchEmail(){return await this.invoke({method:"fetchEmail",isSupported:e=>l(e.version,g.MINIMUM_VERSION)})}async verifyEmail(e){return await this.invoke({method:"verifyEmail",params:e,isSupported:e=>l(e.version,g.MINIMUM_VERSION)})}}g.MINIMUM_VERSION={major:5,minor:399,patch:0},e.BaseModule=i,e.CameraModule=class extends i{constructor(){super("CameraModule")}async scanQRCode(e){return await this.invoke({method:"scanQRCode",params:e})}},e.CheckoutModule=class extends i{constructor(){super("CheckoutModule")}async triggerCheckout(e){return await this.invoke({method:"triggerCheckout",params:e})}},e.ContainerAnalyticsEventData={TRANSACTION_AMOUNT:"transaction_amount",TRANSACTION_CURRENCY:"transaction_currency",PAGE:"page"},e.ContainerAnalyticsEventName={DEFAULT:"DEFAULT"},e.ContainerAnalyticsEventState={HOMEPAGE:"HOMEPAGE",CHECKOUT_PAGE:"CHECKOUT_PAGE",BOOKING_COMPLETION:"BOOKING_COMPLETION",CUSTOM:"CUSTOM"},e.ContainerModule=class extends i{constructor(){super("ContainerModule")}async setBackgroundColor(e){return await this.invoke({method:"setBackgroundColor",params:{backgroundColor:e}})}async setTitle(e){return await this.invoke({method:"setTitle",params:{title:e}})}async hideBackButton(){return await this.invoke({method:"hideBackButton"})}async showBackButton(){return await this.invoke({method:"showBackButton"})}async hideRefreshButton(){return await this.invoke({method:"hideRefreshButton"})}async showRefreshButton(){return await this.invoke({method:"showRefreshButton"})}async close(){return await this.invoke({method:"close"})}async onContentLoaded(){return await this.invoke({method:"onContentLoaded"})}async showLoader(){return await this.invoke({method:"showLoader"})}async hideLoader(){return await this.invoke({method:"hideLoader"})}async openExternalLink(e){return await this.invoke({method:"openExternalLink",params:{url:e}})}async onCtaTap(e){return await this.invoke({method:"onCtaTap",params:{action:e}})}async sendAnalyticsEvent(e){const t=this.validateAnalyticsEvent(e);return t?{status_code:400,error:t}:await this.invoke({method:"sendAnalyticsEvent",params:{state:e.state,name:e.name,data:e.data?JSON.stringify(e.data):null}})}async isConnected(){return null!==a()?{status_code:200,result:{connected:!0}}:{status_code:404,error:"Not connected to Grab app"}}async getSessionParams(){return await this.invoke({method:"getSessionParams"})}validateAnalyticsEvent(e){return null==e.name?"name is required":"string"!=typeof e.name?"name must be a string":null==e.state?"state is required":"string"!=typeof e.state?"state must be a string":null!=e.data&&"object"!=typeof e.data?"data must be undefined or an object":null}},e.DeviceCapabilityModule=class extends i{constructor(){super("DeviceCapabilityModule")}async isEsimSupported(){return await this.invoke({method:"isEsimSupported"})}},e.FileModule=class extends i{constructor(){super("FileModule")}async downloadFile(e){return await this.invoke({method:"downloadFile",params:e})}},e.IdentityModule=f,e.LocaleModule=class extends i{constructor(){super("LocaleModule")}async getLanguageLocaleIdentifier(){return await this.invoke({method:"getLanguageLocaleIdentifier"})}},e.LocationModule=class extends i{constructor(){super("LocationModule")}async getCoordinate(){return await this.invoke({method:"getCoordinate"})}observeLocationChange(){return this.invokeStream({method:"observeLocationChange"})}async getCountryCode(){return await this.invoke({method:"getCountryCode"})}},e.MediaModule=class extends i{constructor(){super("MediaModule")}async playDRMContent(e){return await this.invoke({method:"playDRMContent",params:{data:e}})}observePlayDRMContent(e){return this.invokeStream({method:"observePlayDRMContent",params:{data:e}})}},e.PlatformModule=class extends i{constructor(){super("PlatformModule")}async back(){return await this.invoke({method:"back"})}},e.ProfileModule=g,e.ScopeModule=class extends i{constructor(){super("ScopeModule")}async hasAccessTo(e,t){return await this.invoke({method:"hasAccessTo",params:{module:e,method:t}})}async reloadScopes(){return await this.invoke({method:"reloadScopes"})}},e.StorageModule=class extends i{constructor(){super("StorageModule")}async setBoolean(e,t){return await this.invoke({method:"setBoolean",params:{key:e,value:t}})}async getBoolean(e){return await this.invoke({method:"getBoolean",params:{key:e}})}async setInt(e,t){return await this.invoke({method:"setInt",params:{key:e,value:t}})}async getInt(e){return await this.invoke({method:"getInt",params:{key:e}})}async setString(e,t){return await this.invoke({method:"setString",params:{key:e,value:t}})}async getString(e){return await this.invoke({method:"getString",params:{key:e}})}async setDouble(e,t){return await this.invoke({method:"setDouble",params:{key:e,value:t}})}async getDouble(e){return await this.invoke({method:"getDouble",params:{key:e}})}async remove(e){return await this.invoke({method:"remove",params:{key:e}})}async removeAll(){return await this.invoke({method:"removeAll"})}},e.SystemWebViewKitModule=class extends i{constructor(){super("SystemWebViewKitModule")}async redirectToSystemWebView(e){return await this.invoke({method:"redirectToSystemWebView",params:e})}},e.UserAttributesModule=class extends i{constructor(){super("UserAttributesModule")}async getSelectedTravelDestination(){return await this.invoke({method:"getSelectedTravelDestination"})}},e.isClientError=s,e.isErrorResponse=function(e){return s(e)||c(e)},e.isRedirection=function(e){return 302===e.status_code},e.isServerError=c,e.isSuccess=function(e){return 200===e.status_code||204===e.status_code}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grabjs/superapp-sdk",
3
- "version": "2.0.0-beta.14",
3
+ "version": "2.0.0-beta.23",
4
4
  "description": "SDK for Grab SuperApp WebView.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -24,7 +24,8 @@
24
24
  "build": "npm run build:dist && npm run build:docs",
25
25
  "build:dist": "node scripts/build.mjs",
26
26
  "build:docs": "typedoc",
27
- "check": "npm run check:format && npm run check:lint",
27
+ "build:watch": "rollup -cw",
28
+ "check": "npm run check:format && npm run check:lint && npm run test:check",
28
29
  "check:format": "prettier --check .",
29
30
  "check:lint": "eslint .",
30
31
  "clean": "rimraf dist build",
@@ -33,19 +34,23 @@
33
34
  "fix:lint": "eslint . --fix",
34
35
  "prepare": "husky",
35
36
  "prepublishOnly": "npm run build",
36
- "watch": "rollup -cw"
37
+ "test": "vitest run",
38
+ "test:check": "vitest run",
39
+ "test:watch": "vitest"
37
40
  },
38
41
  "repository": {
39
42
  "type": "git",
40
43
  "url": "git+https://github.com/grab/superapp-sdk.git"
41
44
  },
42
45
  "maintainers": [
43
- "Viet Hai Pham <viethai.pham@grabtaxi.com>",
44
- "Oleksandr Prokofiev <oleksandr.prokofiev@grabtaxi.com>",
45
- "Xijun Li <xijun.li@grabtaxi.com>"
46
+ "Maxime Debersaques <maxime.debersaques@grabtaxi.com>",
47
+ "Stefanus Anggara <stefanus.anggara@grabtaxi.com>",
48
+ "Mengshen Aw <mengshen.aw@grabtaxi.com>",
49
+ "Oleksandr Prokofiev <oleksandr.prokofiev@grabtaxi.com>"
46
50
  ],
47
51
  "files": [
48
- "dist"
52
+ "dist",
53
+ "api-reference"
49
54
  ],
50
55
  "keywords": [
51
56
  "superapp",
@@ -63,19 +68,21 @@
63
68
  "@eslint/js": "^10.0.1",
64
69
  "@eslint/json": "^1.0.1",
65
70
  "@eslint/markdown": "^7.5.1",
66
- "@grabjs/mobile-kit-bridge-sdk": "^2.2.2",
67
71
  "@microsoft/api-extractor": "^7.57.6",
68
72
  "@rollup/plugin-commonjs": "^29.0.0",
69
73
  "@rollup/plugin-node-resolve": "^16.0.3",
70
74
  "@rollup/plugin-terser": "^0.4.4",
71
75
  "@rollup/plugin-typescript": "^12.3.0",
72
- "@types/node": "@types/node@^24",
76
+ "@types/node": "^24",
77
+ "@vitest/coverage-v8": "^4.0.18",
78
+ "@vitest/eslint-plugin": "^1.1.36",
73
79
  "eslint": "^10.0.2",
74
80
  "eslint-plugin-jsdoc": "^62.7.1",
75
81
  "eslint-plugin-license-header": "^0.9.0",
76
82
  "eslint-plugin-simple-import-sort": "^12.1.1",
77
83
  "globals": "^17.4.0",
78
84
  "husky": "^9.1.7",
85
+ "jsdom": "^26.0.0",
79
86
  "lint-staged": "^16.3.1",
80
87
  "prettier": "3.8.1",
81
88
  "rimraf": "^6.1.3",
@@ -83,8 +90,13 @@
83
90
  "tslib": "^2.8.1",
84
91
  "typedoc": "^0.28.17",
85
92
  "typedoc-plugin-markdown": "^4.10.0",
93
+ "typedoc-plugin-no-inherit": "^1.6.1",
86
94
  "typescript": "^5.9.3",
87
- "typescript-eslint": "^8.56.1"
95
+ "typescript-eslint": "^8.56.1",
96
+ "vitest": "^4.0.18"
97
+ },
98
+ "peerDependencies": {
99
+ "@grabjs/mobile-kit-bridge-sdk": "^2.2.2"
88
100
  },
89
101
  "lint-staged": {
90
102
  "**/*": "prettier --write --ignore-unknown",