@grabjs/superapp-sdk 1.8.10 → 2.0.0-beta.7

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.
@@ -1,524 +0,0 @@
1
- # ContainerModule
2
-
3
- ## Description
4
-
5
- Provides APIs to interact with the webview container.
6
-
7
- ## Methods
8
-
9
- ### 1. Set background color
10
-
11
- **Method name**: `setBackgroundColor`
12
-
13
- **Arguments**
14
-
15
- | Name | Type | Required | Description |
16
- | --------------- | ------ | -------- | ----------------------- |
17
- | backgroundColor | String | Yes | Hexadecimal color value |
18
-
19
- **Return type**
20
-
21
- `None`
22
-
23
- **Code example**
24
-
25
- ```javascript
26
- import { ContainerModule } from "@grabjs/superapp-sdk";
27
-
28
- // Ideally, initialize this only one and reuse across app.
29
- const containerModule = new ContainerModule();
30
-
31
- containerModule.setBackgroundColor("#ffffff").then(({ result, error }) => {
32
- if (error) {
33
- // Some error happened.
34
- }
35
- });
36
- ```
37
-
38
- ### 2. Set title
39
-
40
- **Method name**: `setTitle`
41
-
42
- **Arguments**
43
-
44
- | Name | Type | Required | Description |
45
- | ----- | ------ | -------- | ----------------- |
46
- | title | String | Yes | Title of the page |
47
-
48
- **Return type**
49
-
50
- `None`
51
-
52
- **Code example**
53
-
54
- ```javascript
55
- import { ContainerModule } from "@grabjs/superapp-sdk";
56
-
57
- // Ideally, initialize this only one and reuse across app.
58
- const containerModule = new ContainerModule();
59
-
60
- containerModule.setTitle("Home").then(({ result, error }) => {
61
- if (error) {
62
- // Some error happened.
63
- }
64
- });
65
- ```
66
-
67
- ### 3. Hide back button
68
-
69
- **Method name**: `hideBackButton`
70
-
71
- **Arguments**
72
-
73
- `None`
74
-
75
- **Return type**
76
-
77
- `None`
78
-
79
- **Code example**
80
-
81
- ```javascript
82
- import { ContainerModule } from "@grabjs/superapp-sdk";
83
-
84
- // Ideally, initialize this only one and reuse across app.
85
- const containerModule = new ContainerModule();
86
-
87
- containerModule.hideBackButton().then(({ result, error }) => {
88
- if (error) {
89
- // Some error happened.
90
- }
91
- });
92
- ```
93
-
94
- ### 4. Show back button
95
-
96
- **Method name**: `showBackButton`
97
-
98
- **Arguments**
99
-
100
- `None`
101
-
102
- **Return type**
103
-
104
- `None`
105
-
106
- **Code example**
107
-
108
- ```javascript
109
- import { ContainerModule } from "@grabjs/superapp-sdk";
110
-
111
- // Ideally, initialize this only one and reuse across app.
112
- const containerModule = new ContainerModule();
113
-
114
- containerModule.showBackButton().then(({ result, error }) => {
115
- if (error) {
116
- // Some error happened.
117
- }
118
- });
119
- ```
120
-
121
- ### 5. Hide refresh button
122
-
123
- **Method name**: `hideRefreshButton`
124
-
125
- **Arguments**
126
-
127
- `None`
128
-
129
- **Return type**
130
-
131
- `None`
132
-
133
- **Code example**
134
-
135
- ```javascript
136
- import { ContainerModule } from "@grabjs/superapp-sdk";
137
-
138
- // Ideally, initialize this only one and reuse across app.
139
- const containerModule = new ContainerModule();
140
-
141
- containerModule.hideRefreshButton().then(({ result, error }) => {
142
- if (result) {
143
- // There is a valid result.
144
- } else if (error) {
145
- // Some error happened.
146
- }
147
- });
148
- ```
149
-
150
- ### 6. Show refresh button
151
-
152
- **Method name**: `showRefreshButton`
153
-
154
- **Arguments**
155
-
156
- `None`
157
-
158
- **Return type**
159
-
160
- `None`
161
-
162
- **Code example**
163
-
164
- ```javascript
165
- import { ContainerModule } from "@grabjs/superapp-sdk";
166
-
167
- // Ideally, initialize this only one and reuse across app.
168
- const containerModule = new ContainerModule();
169
-
170
- containerModule.showRefreshButton().then(({ result, error }) => {
171
- if (result) {
172
- // There is a valid result.
173
- } else if (error) {
174
- // Some error happened.
175
- }
176
- });
177
- ```
178
-
179
- ### 7. Close
180
-
181
- **Method name**: `close`
182
-
183
- **Arguments**
184
-
185
- `None`
186
-
187
- **Return type**
188
-
189
- `None`
190
-
191
- **Code example**
192
-
193
- ```javascript
194
- import { ContainerModule } from "@grabjs/superapp-sdk";
195
-
196
- // Ideally, initialize this only one and reuse across app.
197
- const containerModule = new ContainerModule();
198
-
199
- containerModule.close().then(({ result, error }) => {
200
- if (result) {
201
- // There is a valid result.
202
- } else if (error) {
203
- // Some error happened.
204
- }
205
- });
206
- ```
207
-
208
- ### 8. On content loaded
209
-
210
- **Method name**: `onContentLoaded`
211
- Call this method to notify the client that page content loaded
212
-
213
- **Arguments**
214
-
215
- `None`
216
-
217
- **Return type**
218
-
219
- `None`
220
-
221
- **Code example**
222
-
223
- ```javascript
224
- import { ContainerModule } from "@grabjs/superapp-sdk";
225
-
226
- // Ideally, initialize this only one and reuse across app.
227
- const containerModule = new ContainerModule();
228
-
229
- containerModule.onContentLoaded().then(({ result, error }) => {
230
- if (result) {
231
- // There is a valid result.
232
- } else if (error) {
233
- // Some error happened.
234
- }
235
- });
236
- ```
237
-
238
- ### 9. Show loader
239
-
240
- **Method name**: `showLoader`
241
- Call this method to notify the client to show loader
242
-
243
- **Arguments**
244
-
245
- `None`
246
-
247
- **Return type**
248
-
249
- `None`
250
-
251
- **Code example**
252
-
253
- ```javascript
254
- import { ContainerModule } from "@grabjs/superapp-sdk";
255
-
256
- // Ideally, initialize this only one and reuse across app.
257
- const containerModule = new ContainerModule();
258
-
259
- containerModule.showLoader().then(({ result, error }) => {
260
- if (error) {
261
- // Some error happened.
262
- }
263
- });
264
- ```
265
-
266
- ### 10. Hide loader
267
-
268
- **Method name**: `hideLoader`
269
- Call this method to notify the client to hide loader
270
-
271
- **Arguments**
272
-
273
- `None`
274
-
275
- **Return type**
276
-
277
- `None`
278
-
279
- **Code example**
280
-
281
- ```javascript
282
- import { ContainerModule } from "@grabjs/superapp-sdk";
283
-
284
- // Ideally, initialize this only one and reuse across app.
285
- const containerModule = new ContainerModule();
286
-
287
- containerModule.hideLoader().then(({ result, error }) => {
288
- if (error) {
289
- // Some error happened.
290
- }
291
- });
292
- ```
293
-
294
- ### 11. Open link in external browser
295
-
296
- **Method name**: `openExternalLink`
297
- Call this method to tell client to open the link in external browser
298
-
299
- **Arguments**
300
-
301
- | Name | Type | Required | Description |
302
- | ---- | ------ | -------- | ----------- |
303
- | url | String | Yes | URL to open |
304
-
305
- **Return type**
306
-
307
- `None`
308
-
309
- **Code example**
310
-
311
- ```javascript
312
- import { ContainerModule } from "@grabjs/superapp-sdk";
313
-
314
- // Ideally, initialize this only one and reuse across app.
315
- const containerModule = new ContainerModule();
316
-
317
- containerModule
318
- .openExternalLink("https://grab.com")
319
- .then(({ result, error }) => {
320
- if (result) {
321
- // There is a valid result.
322
- } else if (error) {
323
- // Some error happened.
324
- }
325
- });
326
- ```
327
-
328
- ### 12. On CTA Tap
329
-
330
- **Method name**: `onCtaTap`
331
- Call this method to notify the client that the user has continued the flow
332
-
333
- **Arguments**
334
-
335
- | Name | Type | Required | Description |
336
- |--------| ------ | -------- |-------------|
337
- | action | String | Yes | tap action |
338
-
339
- **Return type**
340
-
341
- `None`
342
-
343
- **Code example**
344
-
345
- ```javascript
346
- import { ContainerModule } from "@grabjs/superapp-sdk";
347
-
348
- // Ideally, initialize this only one and reuse across app.
349
- const containerModule = new ContainerModule();
350
-
351
- containerModule
352
- .onCtaTap("AV_LANDING_PAGE_CONTINUE")
353
- .then(({ result, error }) => {
354
- if (result) {
355
- // There is a valid result.
356
- } else if (error) {
357
- // Some error happened.
358
- }
359
- });
360
- ```
361
-
362
- ### 13. Check connection status
363
-
364
- **Method name**: `isConnected`
365
- Call this method to check if the web app is connected to the Grab app via JSBridge.
366
-
367
- **Arguments**
368
-
369
- `None`
370
-
371
- **Return type**
372
-
373
- `None`
374
-
375
- **Code example**
376
-
377
- ```javascript
378
- import { ContainerModule } from "@grabjs/superapp-sdk";
379
-
380
- const containerModule = new ContainerModule();
381
-
382
- containerModule.isConnected().then(({ status_code, error }) => {
383
- if (status_code === 200) {
384
- // Connected to Grab app
385
- } else if (error) {
386
- // Not connected to Grab app
387
- }
388
- });
389
- ```
390
-
391
- ### 14. Send analytics event
392
-
393
- **Method name**: `sendAnalyticsEvent`
394
-
395
- **Arguments**
396
-
397
- | Name | Type | Required | Description |
398
- | ------------ | ------ | -------- | ---------------------------------------------- |
399
- | eventDetails | Object | Yes | Event details containing state, name, and data |
400
-
401
- **EventDetails Object Properties**
402
-
403
- | Property | Type | Required | Description |
404
- | -------- | ------ | -------- | -------------------------------------------------------------------------- |
405
- | state | String | Yes | State of the event (cf. Predefined ContainerAnalyticsEventState) |
406
- | name | String | Yes | Name of the event (cf. Predefined ContainerAnalyticsEventName) |
407
- | data | Object | No | Additional data for the event (cf. Predefined ContainerAnalyticsEventData) |
408
-
409
- **Predefined ContainerAnalyticsEventState**
410
-
411
- - 'HOMEPAGE'
412
- - 'CHECKOUT_PAGE'
413
- - 'BOOKING_COMPLETION'
414
- - 'CUSTOM'
415
-
416
- **Predefined ContainerAnalyticsEventName**
417
-
418
- - 'DEFAULT'
419
-
420
- **Predefined ContainerAnalyticsEventData**
421
-
422
- - 'TRANSACTION_AMOUNT': 'transaction_amount'
423
- - 'TRANSACTION_CURRENCY': 'transaction_currency'
424
- - 'PAGE': 'page'
425
-
426
- **Return type**
427
-
428
- `None`
429
-
430
- **Code example**
431
-
432
- ```javascript
433
- import {
434
- ContainerModule,
435
- ContainerAnalyticsEventState,
436
- ContainerAnalyticsEventName,
437
- ContainerAnalyticsEventData,
438
- } from "@grabjs/superapp-sdk";
439
-
440
- const containerModule = new ContainerModule();
441
-
442
- // Example: Send a DEFAULT event for HOMEPAGE state
443
- containerModule
444
- .sendAnalyticsEvent({
445
- state: ContainerAnalyticsEventState.HOMEPAGE,
446
- name: ContainerAnalyticsEventName.DEFAULT,
447
- })
448
- .then(({ result, error }) => {
449
- if (error) {
450
- // Handle validation or other errors
451
- }
452
- });
453
-
454
- // Example: Send a BOOK event for CHECKOUT_PAGE state
455
- containerModule
456
- .sendAnalyticsEvent({
457
- state: ContainerAnalyticsEventState.CHECKOUT_PAGE,
458
- name: "BOOK",
459
- data: {
460
- [ContainerAnalyticsEventData.TRANSACTION_AMOUNT]: 100,
461
- [ContainerAnalyticsEventData.TRANSACTION_CURRENCY]: "SGD",
462
- },
463
- })
464
- .then(({ result, error }) => {
465
- if (error) {
466
- // Handle validation or other errors
467
- }
468
- });
469
-
470
- // Example: Send a CLICK_RIDE event for CUSTOM state
471
- containerModule
472
- .sendAnalyticsEvent({
473
- state: ContainerAnalyticsEventState.CUSTOM,
474
- name: "CLICK_RIDE",
475
- data: {
476
- [ContainerAnalyticsEventData.PAGE]: "LIST_RIDES",
477
- departure_time: "2025-06-01 08:00:00",
478
- arrival_time: "2025-06-01 10:30:00",
479
- departure_address: "6 Bayfront Ave, Singapore 018974",
480
- arrival_address:
481
- "Petronas Twin Tower, Kuala Lumpur City Centre, 50088 Kuala Lumpur, Malaysia",
482
- },
483
- })
484
- .then(({ result, error }) => {
485
- if (error) {
486
- // Handle validation or other errors
487
- }
488
- });
489
- ```
490
-
491
- ### 15. Get session parameters
492
-
493
- **Method name**: `getSessionParams`
494
-
495
- **Arguments**
496
-
497
- `None`
498
-
499
- **Return type**
500
-
501
- | Name | Type | Description |
502
- | ------------- | ------ | ----------------------------------------------------------- |
503
- | sessionParams | String | Parameters attached to the current session |
504
-
505
- **Code example**
506
-
507
- ```javascript
508
- import { ContainerModule } from "@grabjs/superapp-sdk";
509
-
510
- // Ideally, initialize this only once and reuse across app.
511
- const containerModule = new ContainerModule();
512
-
513
- containerModule.getSessionParams().then(({ result, error }) => {
514
- if (result) {
515
- // Session params can be in any format (primitive, base64 encoded string, etc)
516
- // e.g. stringified JSON object '{"param1": 123, "param2": "grab-test"}'
517
- const sessionParams = JSON.parse(result);
518
- console.log("Session parameters:", sessionParams);
519
- } else if (error) {
520
- // Some error happened.
521
- console.error("Error getting session params:", error);
522
- }
523
- });
524
- ```
@@ -1,192 +0,0 @@
1
- # IdentityModule
2
-
3
- ## Description
4
-
5
- The IdentityModule provides functionality related to user identity.
6
-
7
- ## Methods
8
-
9
- ### 1. Authorize
10
-
11
- **Method name**: `authorize`
12
-
13
- **Arguments**
14
-
15
- | Name | Type | Required | Description |
16
- | --- | --- | --- | --- |
17
- | request | Object | Yes | Authorization request parameters |
18
-
19
- **Request Object Properties**
20
-
21
- | Property | Type | Required | Description |
22
- | --- | --- | --- | --- |
23
- | clientId | String | Yes | Client ID for authorization |
24
- | scope | String | Yes | Scope of the authorization |
25
- | redirectUri | String | Yes | Redirect URI for authorization callback |
26
- | environment | String | Yes | Environment ('staging' or 'production'). Used to fetch the authorization endpoint from the OpenID configuration for the web flow |
27
- | responseMode | String | No | Response mode ('redirect' or 'in_place'). Defaults to 'redirect' if not specified |
28
-
29
- **Important Note on `redirectUri` and `responseMode`:**
30
-
31
- The actual `redirectUri` used during authorization may differ from the one you provide, depending on the flow:
32
-
33
- - **`responseMode: 'in_place'` when native flow is available**: Uses the current page URL (normalized) as the `redirectUri`, overriding your provided value
34
- - **`responseMode: 'in_place'` falling back to web flow if native flow is not available**: Uses your provided `redirectUri`
35
- - **`responseMode: 'redirect'`**: Always uses your provided `redirectUri`
36
-
37
- To ensure successful token exchange (which requires matching `redirectUri` values), **always retrieve the actual `redirectUri` from `getAuthorizationArtifacts()`** after authorization completes.
38
-
39
- **Consent Selection Rules (Native vs Web):**
40
-
41
- - If the user agent does not match the Grab app pattern, the SDK uses **web consent**.
42
- - If `environment` is `staging`, the SDK **skips version gating** and attempts native consent.
43
- - Otherwise, if the app version in the user agent is below **5.396.0** (iOS or Android), the SDK uses **web consent**.
44
- - For supported versions, the SDK attempts **native consent** first and falls back to web on specific native errors.
45
-
46
- **Return type**
47
-
48
- | Name | Type | Description |
49
- | --- | --- | --- |
50
- | result | Object | Result of the authorization |
51
- | error | String | Error message if authorization fails |
52
- | status_code | Number | HTTP status code (e.g. 200 for success, 499 for user cancellation) |
53
-
54
- **Result Object Properties**
55
-
56
- | Property | Type | Description |
57
- | --- | --- | --- |
58
- | state | String | The state parameter returned from the server |
59
- | code | String | The authorization code returned from the server |
60
-
61
- **Code example**
62
-
63
- ```javascript
64
- import { IdentityModule } from "@grabjs/superapp-sdk";
65
-
66
- // Ideally, initialize this only one and reuse across app.
67
- const identityModule = new IdentityModule();
68
-
69
- const request = {
70
- clientId: "your-client-id",
71
- scope: "profile openid",
72
- redirectUri: "https://your-redirect-uri.com",
73
- environment: "production", // or "staging"
74
- responseMode: "redirect"
75
- };
76
-
77
- const { result, error, status_code } = await identityModule.authorize(request);
78
- if (status_code === 200 && result) {
79
- // Authorization successful (in_place mode with native flow)
80
- console.log("Auth Code:", result.code);
81
- console.log("State:", result.state);
82
- } else if (status_code === 302) {
83
- // Authorization redirect initiated (web flow or redirect response mode)
84
- // The page will redirect to the authorization server
85
- } else if (status_code === 204) {
86
- // User cancelled the authorization
87
- console.log("User cancelled");
88
- } else if (error) {
89
- // Authorization failed
90
- console.error("Auth error:", error);
91
- }
92
- ```
93
-
94
- ### 2. Get Authorization Artifacts
95
-
96
- **Method name**: `getAuthorizationArtifacts`
97
-
98
- **Description**
99
-
100
- Retrieves the authorization artifacts that were stored in localStorage during the authorization flow. These include PKCE (Proof Key for Code Exchange) values and the actual `redirectUri` that was used. These values are needed to complete the OAuth token exchange after the authorization redirect.
101
-
102
- **Important:** The `redirectUri` returned by this method is the **actual** redirect URI that was sent to the authorization server. This may differ from the `redirectUri` you provided to `authorize()` if you used `responseMode: 'in_place'` with native flow. You **must** use this returned `redirectUri` for token exchange to ensure OAuth compliance.
103
-
104
- **Arguments**
105
-
106
- None
107
-
108
- **Return type**
109
-
110
- | Name | Type | Description |
111
- | --- | --- | --- |
112
- | result | Object \| null | Object containing the authorization artifacts (200), or null if not stored (204) or inconsistent (400) |
113
- | error | String \| null | Error message if artifacts are inconsistent (400), otherwise null |
114
- | status_code | Number | HTTP status code: 200 (success), 204 (no artifacts), or 400 (inconsistent state) |
115
-
116
- **Result Object Properties**
117
-
118
- When `status_code` is 200, the `result` object contains:
119
-
120
- | Property | Type | Description |
121
- | --- | --- | --- |
122
- | state | String | The state parameter used for CSRF protection |
123
- | codeVerifier | String | The PKCE code verifier used for token exchange |
124
- | nonce | String | The nonce used for ID token verification |
125
- | redirectUri | String | The actual redirect URI that was used during authorization |
126
-
127
- **Status Codes**
128
-
129
- - **200**: All four artifacts are present and returned in `result`
130
- - **204**: No artifacts are stored (authorization has not been called yet)
131
- - **400**: Inconsistent state detected (only some artifacts present, possible data corruption)
132
-
133
- **Code example**
134
-
135
- ```javascript
136
- import { IdentityModule } from "@grabjs/superapp-sdk";
137
-
138
- // Ideally, initialize this only once and reuse across app.
139
- const identityModule = new IdentityModule();
140
-
141
- // After authorization redirect, retrieve the stored artifacts
142
- const { result, status_code, error } = await identityModule.getAuthorizationArtifacts();
143
-
144
- if (status_code === 200 && result) {
145
- // All artifacts present - proceed with token exchange
146
- const { state, codeVerifier, nonce, redirectUri } = result;
147
- console.log("State:", state);
148
- console.log("Code Verifier:", codeVerifier);
149
- console.log("Nonce:", nonce);
150
- console.log("Redirect URI:", redirectUri);
151
- } else if (status_code === 204) {
152
- // No artifacts yet - user hasn't authorized
153
- console.log("No authorization artifacts found. Authorization has not been initiated.");
154
- } else if (status_code === 400) {
155
- // Inconsistent state - possible data corruption
156
- console.error("Authorization artifacts error:", error);
157
- }
158
- ```
159
-
160
- ### 3. Clear Authorization Artifacts
161
-
162
- **Method name**: `clearAuthorizationArtifacts`
163
-
164
- **Description**
165
-
166
- Clears all stored authorization artifacts from localStorage. This should be called after a successful token exchange or when you need to reset the authorization state (e.g., on error or logout).
167
-
168
- **Arguments**
169
-
170
- None
171
-
172
- **Return type**
173
-
174
- | Name | Type | Description |
175
- | --- | --- | --- |
176
- | result | null | Always null (no data to return) |
177
- | error | null | Always null (no error) |
178
- | status_code | Number | Always 204 (No Content - successful operation) |
179
-
180
- **Code example**
181
-
182
- ```javascript
183
- import { IdentityModule } from "@grabjs/superapp-sdk";
184
-
185
- const identityModule = new IdentityModule();
186
-
187
- // After successful token exchange or on error
188
- const { status_code } = await identityModule.clearAuthorizationArtifacts();
189
- if (status_code === 204) {
190
- console.log("Authorization artifacts cleared");
191
- }
192
- ```