@grabjs/superapp-sdk 1.7.13 → 1.7.16
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.
- package/README.md +1 -0
- package/dist/index.js +1 -1
- package/docs/CameraModule.md +96 -0
- package/docs/ContainerModule.md +89 -48
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@ response object must have a structure defined in this document.
|
|
|
7
7
|
|
|
8
8
|
## Currently available modules
|
|
9
9
|
|
|
10
|
+
- [Camera Module](https://github.com/grab/superapp-sdk/blob/master/docs/CameraModule.md)
|
|
10
11
|
- [Checkout Module](https://github.com/grab/superapp-sdk/blob/master/docs/CheckoutModule.md).
|
|
11
12
|
- [Container Module](https://github.com/grab/superapp-sdk/blob/master/docs/ContainerModule.md).
|
|
12
13
|
- [Location Module](https://github.com/grab/superapp-sdk/blob/master/docs/LocationModule.md).
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e=e||self).SuperAppSDK={})}(this,function(e){"use strict";function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function t(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}function o(e,n){for(var t=0;t<n.length;t++){var o=n[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}function r(e,n,t){return n&&o(e.prototype,n),t&&o(e,t),e}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var u,i
|
|
1
|
+
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e=e||self).SuperAppSDK={})}(this,function(e){"use strict";function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function t(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}function o(e,n){for(var t=0;t<n.length;t++){var o=n[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}function r(e,n,t){return n&&o(e.prototype,n),t&&o(e,t),e}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var u,a,i=(function(e,n){function i(e){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];if(!e)return!1;var o=function(e){return Object.keys(e).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(e)))}(e);return n.every(function(e){return 0<=o.indexOf(e)})}function l(r,e){var u=e.callbackNameFunc,a=e.funcToWrap;return function(e){return{subscribe:e,then:function(o,r){return new Promise(function(){try{var n=null,t=!1;n=e({next:function(e){o&&o(e),n&&n.unsubscribe(),t=!0}}),t&&n&&n.unsubscribe()}catch(e){r&&r(e)}})}}}(function(t){var n,o=u();return r[o]=function(e){if(i(e,"status_code"))if(i(e.result,"event"))switch(e.result.event){case d.StreamEvent.STREAM_TERMINATED:n.unsubscribe()}else t&&t.next&&t.next(e)},a(o),n=function(e){var n=!1;return{isUnsubscribed:function(){return n},unsubscribe:function(){n||(delete r[o],t&&t.complete&&t.complete(),n=!0)}}}()})}var d;((d=n).StreamEvent||(d.StreamEvent={})).STREAM_TERMINATED="STREAM_TERMINATED",d.wrapModule=function(u,a){u[function(e){return"Wrapped"+e}(a)]=function(e,o,n){var r={};return{invoke:function(n,t){return function(e,n){return n.funcNameToWrap,l(e,function(e,n){var t={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&n.indexOf(o)<0&&(t[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var r=0;for(o=Object.getOwnPropertySymbols(e);r<o.length;r++)n.indexOf(o[r])<0&&(t[o[r]]=e[o[r]])}return t}(n,["funcNameToWrap"]))}(e,{funcNameToWrap:n,callbackNameFunc:function(){var e=r[n]||0;return r[n]=e+1,function(e){var n=e.moduleName,t=e.funcName,o=e.requestID;return n+"_"+t+"Callback"+(null!==o?"_"+o:"")}({moduleName:o,requestID:e,funcName:n})},funcToWrap:function(e){return function(e){if(u[a])u[a][e.method](JSON.stringify(e));else{if(!(u.webkit&&u.webkit.messageHandlers&&u.webkit.messageHandlers[a]))throw new Error("Unexpected method '"+e.method+"' for module '"+a+"'");u.webkit.messageHandlers[a].postMessage(e)}}({callback:e,method:n,module:o,parameters:null!=t?t:{}})}})}}}(u,a)},Object.defineProperty(d,"__esModule",{value:!0})}(u={exports:{}},u.exports),u.exports),l=(a=i)&&a.__esModule&&Object.prototype.hasOwnProperty.call(a,"default")?a.default:a,d=function(){function e(){t(this,e),l.wrapModule(window,"CameraModule")}return r(e,[{key:"scanQRCode",value:function(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};return window.WrappedCameraModule.invoke("scanQRCode",e)}}]),e}(),c=function(){function e(){t(this,e),l.wrapModule(window,"CheckoutModule")}return r(e,[{key:"triggerCheckout",value:function(e){return window.WrappedCheckoutModule.invoke("triggerCheckout",e)}}]),e}(),f=function(){function e(){t(this,e),l.wrapModule(window,"ContainerModule")}return r(e,[{key:"setBackgroundColor",value:function(e){return window.WrappedContainerModule.invoke("setBackgroundColor",{backgroundColor:e})}},{key:"setTitle",value:function(e){return window.WrappedContainerModule.invoke("setTitle",{title:e})}},{key:"hideBackButton",value:function(){return window.WrappedContainerModule.invoke("hideBackButton")}},{key:"showBackButton",value:function(){return window.WrappedContainerModule.invoke("showBackButton")}},{key:"hideRefreshButton",value:function(){return window.WrappedContainerModule.invoke("hideRefreshButton")}},{key:"showRefreshButton",value:function(){return window.WrappedContainerModule.invoke("showRefreshButton")}},{key:"close",value:function(){return window.WrappedContainerModule.invoke("close")}},{key:"onContentLoaded",value:function(){return window.WrappedContainerModule.invoke("onContentLoaded")}},{key:"openExternalLink",value:function(e){return window.WrappedContainerModule.invoke("openExternalLink",{url:e})}},{key:"sendAnalyticsEvent",value:function(e){var n=this._validateAnalyticsEvent(e);return n?{then:function(e){return e({status_code:400,error:n})}}:window.WrappedContainerModule.invoke("sendAnalyticsEvent",{state:e.state,name:e.name,data:e.data?JSON.stringify(e.data):null})}},{key:"isConnected",value:function(){var e=window.navigator&&window.navigator.userAgent;if(!e)return{then:function(e){return e({status_code:404,error:"User agent not available"})}};var n=e.toLowerCase().startsWith("grab");return{then:function(e){return e({status_code:n?200:404,error:n?null:"Not connected to Grab app"})}}}},{key:"_validateAnalyticsEvent",value:function(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"!==n(e.data)?"data must be undefined or an object":null}}]),e}(),s=function(){function e(){t(this,e),l.wrapModule(window,"LocaleModule")}return r(e,[{key:"getLanguageLocaleIdentifier",value:function(){return window.WrappedLocaleModule.invoke("getLanguageLocaleIdentifier")}}]),e}(),p=function(){function e(){t(this,e),l.wrapModule(window,"LocationModule")}return r(e,[{key:"getCoordinate",value:function(){return window.WrappedLocationModule.invoke("getCoordinate")}},{key:"observeLocationChange",value:function(){return window.WrappedLocationModule.invoke("observeLocationChange")}}]),e}(),w=function(){function e(){t(this,e),l.wrapModule(window,"MediaModule")}return r(e,[{key:"playDRMContent",value:function(e){return window.WrappedMediaModule.invoke("playDRMContent",{data:e})}}]),e}(),v=function(){function e(){t(this,e),l.wrapModule(window,"PlatformModule")}return r(e,[{key:"back",value:function(){return window.WrappedPlatformModule.invoke("back")}}]),e}(),y=function(){function e(){t(this,e),l.wrapModule(window,"ScopeModule")}return r(e,[{key:"hasAccessTo",value:function(e,n){return window.WrappedScopeModule.invoke("hasAccessTo",{module:e,method:n})}},{key:"reloadScopes",value:function(){return window.WrappedScopeModule.invoke("reloadScopes")}}]),e}(),k=function(){function e(){t(this,e),l.wrapModule(window,"StorageModule")}return r(e,[{key:"setBoolean",value:function(e,n){return window.WrappedStorageModule.invoke("setBoolean",{key:e,value:n})}},{key:"getBoolean",value:function(e){return window.WrappedStorageModule.invoke("getBoolean",{key:e})}},{key:"setInt",value:function(e,n){return window.WrappedStorageModule.invoke("setInt",{key:e,value:n})}},{key:"getInt",value:function(e){return window.WrappedStorageModule.invoke("getInt",{key:e})}},{key:"setString",value:function(e,n){return window.WrappedStorageModule.invoke("setString",{key:e,value:n})}},{key:"getString",value:function(e){return window.WrappedStorageModule.invoke("getString",{key:e})}},{key:"setDouble",value:function(e,n){return window.WrappedStorageModule.invoke("setDouble",{key:e,value:n})}},{key:"getDouble",value:function(e){return window.WrappedStorageModule.invoke("getDouble",{key:e})}},{key:"remove",value:function(e){return window.WrappedStorageModule.invoke("remove",{key:e})}},{key:"removeAll",value:function(){return window.WrappedStorageModule.invoke("removeAll")}}]),e}(),M=function(){function e(){t(this,e),l.wrapModule(window,"SystemWebViewKitModule")}return r(e,[{key:"redirectToSystemWebView",value:function(e){return window.WrappedSystemWebViewKitModule.invoke("redirectToSystemWebView",e)}}]),e}();e.CameraModule=d,e.CameraResultCode={SUCCESS:"SUCCESS",CANCELLED:"CANCELLED"},e.CheckoutModule=c,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=f,e.LocaleModule=s,e.LocationModule=p,e.MediaModule=w,e.PlatformModule=v,e.ScopeModule=y,e.StorageModule=k,e.SystemWebViewKitModule=M,Object.defineProperty(e,"__esModule",{value:!0})});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# CameraModule
|
|
2
|
+
|
|
3
|
+
The CameraModule provides functionality to open the device camera for QR code scanning and retrieve the scan results.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
import { CameraModule, CameraResultCode } from '@grab/superapp-sdk';
|
|
9
|
+
|
|
10
|
+
const cameraModule = new CameraModule();
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Methods
|
|
14
|
+
|
|
15
|
+
### `scanQRCode(config)`
|
|
16
|
+
|
|
17
|
+
Opens the camera to scan QR codes with optional configuration.
|
|
18
|
+
|
|
19
|
+
**Parameters:**
|
|
20
|
+
- `config` (Object, optional): Configuration object for QR code scanning
|
|
21
|
+
- `title` (string, optional): Title to display in camera view
|
|
22
|
+
|
|
23
|
+
**Returns:** `Object` (QR code result object)
|
|
24
|
+
|
|
25
|
+
**Example:**
|
|
26
|
+
```javascript
|
|
27
|
+
// With custom title
|
|
28
|
+
cameraModule.scanQRCode({ title: 'Scan Payment QR' })
|
|
29
|
+
.then(({ result, error }) => {
|
|
30
|
+
if (result) {
|
|
31
|
+
if (result.code === CameraResultCode.SUCCESS) {
|
|
32
|
+
console.log('QR Code scanned:', result.data);
|
|
33
|
+
} else if (result.code === CameraResultCode.CANCELLED) {
|
|
34
|
+
console.log('User cancelled camera');
|
|
35
|
+
}
|
|
36
|
+
} else if (error) {
|
|
37
|
+
// Some error happened.
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// With default settings
|
|
42
|
+
cameraModule.scanQRCode()
|
|
43
|
+
.then(({ result, error }) => {
|
|
44
|
+
if (result) {
|
|
45
|
+
// Handle successful result
|
|
46
|
+
} else if (error) {
|
|
47
|
+
// Some error happened.
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Constants
|
|
53
|
+
|
|
54
|
+
### `CameraResultCode`
|
|
55
|
+
|
|
56
|
+
Enum for different camera result codes:
|
|
57
|
+
|
|
58
|
+
- `SUCCESS`: Successfully scanned a QR code
|
|
59
|
+
- `CANCELLED`: User cancelled the camera operation
|
|
60
|
+
|
|
61
|
+
## Response Format
|
|
62
|
+
|
|
63
|
+
The camera method returns an object containing:
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
{
|
|
67
|
+
result: {
|
|
68
|
+
code: CameraResultCode.SUCCESS, // Result code
|
|
69
|
+
data: "scanned_qr_code_string", // The QR code content (for SUCCESS code)
|
|
70
|
+
},
|
|
71
|
+
error: null // Error message if an error occurred
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Error Handling
|
|
76
|
+
|
|
77
|
+
The camera method returns a result/error object:
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
cameraModule.scanQRCode()
|
|
81
|
+
.then(({ result, error }) => {
|
|
82
|
+
if (result) {
|
|
83
|
+
if (result.code === CameraResultCode.SUCCESS) {
|
|
84
|
+
console.log('QR Code scanned:', result.data);
|
|
85
|
+
} else if (result.code === CameraResultCode.CANCELLED) {
|
|
86
|
+
console.log('User cancelled camera');
|
|
87
|
+
}
|
|
88
|
+
} else if (error) {
|
|
89
|
+
// Some error happened.
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Notes
|
|
95
|
+
|
|
96
|
+
Camera permissions and lifecycle (opening/closing) are handled automatically by the native iOS app, so no additional management is required from the JavaScript side.
|
package/docs/ContainerModule.md
CHANGED
|
@@ -258,29 +258,60 @@ import { ContainerModule } from "@grabjs/superapp-sdk";
|
|
|
258
258
|
// Ideally, initialize this only one and reuse across app.
|
|
259
259
|
const containerModule = new ContainerModule();
|
|
260
260
|
|
|
261
|
-
containerModule
|
|
262
|
-
|
|
263
|
-
|
|
261
|
+
containerModule
|
|
262
|
+
.openExternalLink("https://grab.com")
|
|
263
|
+
.then(({ result, error }) => {
|
|
264
|
+
if (result) {
|
|
265
|
+
// There is a valid result.
|
|
266
|
+
} else if (error) {
|
|
267
|
+
// Some error happened.
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### 10. Check connection status
|
|
273
|
+
|
|
274
|
+
**Method name**: `isConnected`
|
|
275
|
+
Call this method to check if the web app is connected to the Grab app via JSBridge.
|
|
276
|
+
|
|
277
|
+
**Arguments**
|
|
278
|
+
|
|
279
|
+
`None`
|
|
280
|
+
|
|
281
|
+
**Return type**
|
|
282
|
+
|
|
283
|
+
`None`
|
|
284
|
+
|
|
285
|
+
**Code example**
|
|
286
|
+
|
|
287
|
+
```javascript
|
|
288
|
+
import { ContainerModule } from "@grabjs/superapp-sdk";
|
|
289
|
+
|
|
290
|
+
const containerModule = new ContainerModule();
|
|
291
|
+
|
|
292
|
+
containerModule.isConnected().then(({ status_code, error }) => {
|
|
293
|
+
if (status_code === 200) {
|
|
294
|
+
// Connected to Grab app
|
|
264
295
|
} else if (error) {
|
|
265
|
-
//
|
|
296
|
+
// Not connected to Grab app
|
|
266
297
|
}
|
|
267
298
|
});
|
|
268
299
|
```
|
|
269
300
|
|
|
270
|
-
###
|
|
301
|
+
### 11. Send analytics event
|
|
271
302
|
|
|
272
303
|
**Method name**: `sendAnalyticsEvent`
|
|
273
304
|
|
|
274
305
|
**Arguments**
|
|
275
306
|
|
|
276
|
-
| Name | Type | Required | Description
|
|
277
|
-
| ------------ | ------ | -------- |
|
|
278
|
-
| eventDetails | Object | Yes | Event details containing state, name, and data
|
|
307
|
+
| Name | Type | Required | Description |
|
|
308
|
+
| ------------ | ------ | -------- | ---------------------------------------------- |
|
|
309
|
+
| eventDetails | Object | Yes | Event details containing state, name, and data |
|
|
279
310
|
|
|
280
311
|
**EventDetails Object Properties**
|
|
281
312
|
|
|
282
|
-
| Property | Type | Required | Description
|
|
283
|
-
| -------- | ------ | -------- |
|
|
313
|
+
| Property | Type | Required | Description |
|
|
314
|
+
| -------- | ------ | -------- | -------------------------------------------------------------------------- |
|
|
284
315
|
| state | String | Yes | State of the event (cf. Predefined ContainerAnalyticsEventState) |
|
|
285
316
|
| name | String | Yes | Name of the event (cf. Predefined ContainerAnalyticsEventName) |
|
|
286
317
|
| data | Object | No | Additional data for the event (cf. Predefined ContainerAnalyticsEventData) |
|
|
@@ -309,50 +340,60 @@ containerModule.openExternalLink("https://grab.com").then(({ result, error }) =>
|
|
|
309
340
|
**Code example**
|
|
310
341
|
|
|
311
342
|
```javascript
|
|
312
|
-
import {
|
|
343
|
+
import {
|
|
344
|
+
ContainerModule,
|
|
345
|
+
ContainerAnalyticsEventState,
|
|
346
|
+
ContainerAnalyticsEventName,
|
|
347
|
+
ContainerAnalyticsEventData,
|
|
348
|
+
} from "@grabjs/superapp-sdk";
|
|
313
349
|
|
|
314
350
|
const containerModule = new ContainerModule();
|
|
315
351
|
|
|
316
352
|
// Example: Send a DEFAULT event for HOMEPAGE state
|
|
317
|
-
containerModule
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
353
|
+
containerModule
|
|
354
|
+
.sendAnalyticsEvent({
|
|
355
|
+
state: ContainerAnalyticsEventState.HOMEPAGE,
|
|
356
|
+
name: ContainerAnalyticsEventName.DEFAULT,
|
|
357
|
+
})
|
|
358
|
+
.then(({ result, error }) => {
|
|
359
|
+
if (error) {
|
|
360
|
+
// Handle validation or other errors
|
|
361
|
+
}
|
|
362
|
+
});
|
|
325
363
|
|
|
326
364
|
// Example: Send a BOOK event for CHECKOUT_PAGE state
|
|
327
|
-
containerModule
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
365
|
+
containerModule
|
|
366
|
+
.sendAnalyticsEvent({
|
|
367
|
+
state: ContainerAnalyticsEventState.CHECKOUT_PAGE,
|
|
368
|
+
name: "BOOK",
|
|
369
|
+
data: {
|
|
370
|
+
[ContainerAnalyticsEventData.TRANSACTION_AMOUNT]: 100,
|
|
371
|
+
[ContainerAnalyticsEventData.TRANSACTION_CURRENCY]: "SGD",
|
|
372
|
+
},
|
|
373
|
+
})
|
|
374
|
+
.then(({ result, error }) => {
|
|
375
|
+
if (error) {
|
|
376
|
+
// Handle validation or other errors
|
|
377
|
+
}
|
|
378
|
+
});
|
|
339
379
|
|
|
340
380
|
// Example: Send a CLICK_RIDE event for CUSTOM state
|
|
341
|
-
containerModule
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
381
|
+
containerModule
|
|
382
|
+
.sendAnalyticsEvent({
|
|
383
|
+
state: ContainerAnalyticsEventState.CUSTOM,
|
|
384
|
+
name: "CLICK_RIDE",
|
|
385
|
+
data: {
|
|
386
|
+
[ContainerAnalyticsEventData.PAGE]: "LIST_RIDES",
|
|
387
|
+
departure_time: "2025-06-01 08:00:00",
|
|
388
|
+
arrival_time: "2025-06-01 10:30:00",
|
|
389
|
+
departure_address: "6 Bayfront Ave, Singapore 018974",
|
|
390
|
+
arrival_address:
|
|
391
|
+
"Petronas Twin Tower, Kuala Lumpur City Centre, 50088 Kuala Lumpur, Malaysia",
|
|
392
|
+
},
|
|
393
|
+
})
|
|
394
|
+
.then(({ result, error }) => {
|
|
395
|
+
if (error) {
|
|
396
|
+
// Handle validation or other errors
|
|
397
|
+
}
|
|
398
|
+
});
|
|
357
399
|
```
|
|
358
|
-
|