@bzbs/react-api-client 1.4.14 → 2.0.0
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 +542 -264
- package/dist/index.d.mts +35 -10
- package/dist/index.d.ts +35 -10
- package/dist/index.js +145 -297
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +145 -297
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
# @bzbs/react-api-client
|
|
2
2
|
|
|
3
|
-
A TypeScript API client
|
|
3
|
+
A TypeScript library providing a type-safe API client for Buzzebees loyalty and reward services. Supports authentication, campaigns, user profiles, shopping carts, notifications, stamps, consent management, and more.
|
|
4
4
|
|
|
5
|
-
**Version:** 1.4.
|
|
5
|
+
**Version:** 1.4.15 | **License:** ISC | **Author:** Buzzebees Co., Ltd.
|
|
6
|
+
**Repository:** [Azure DevOps](https://dev.azure.com/buzzebees/Buzzebees/_git/React_API_Client)
|
|
7
|
+
|
|
8
|
+
---
|
|
6
9
|
|
|
7
10
|
## Table of Contents
|
|
8
11
|
|
|
9
12
|
- [Installation](#installation)
|
|
10
13
|
- [Quick Start](#quick-start)
|
|
14
|
+
- [API Version](#api-version)
|
|
11
15
|
- [Configuration](#configuration)
|
|
12
16
|
- [Architecture](#architecture)
|
|
17
|
+
- [BzbsService Properties](#bzbsservice-properties)
|
|
18
|
+
- [Response Handling](#response-handling)
|
|
19
|
+
- [Complete API Endpoint Table](#complete-api-endpoint-table)
|
|
13
20
|
- [API Reference](#api-reference)
|
|
14
21
|
- [AuthenticateApi](#authenticateapi)
|
|
15
22
|
- [CampaignApi](#campaignapi)
|
|
@@ -31,10 +38,11 @@ A TypeScript API client library for integrating with Buzzebees services. Provide
|
|
|
31
38
|
- [RequestHelpApi (Forum)](#requesthelpapi-forum)
|
|
32
39
|
- [SettingApi](#settingapi)
|
|
33
40
|
- [Blob](#blob)
|
|
34
|
-
- [
|
|
35
|
-
- [
|
|
36
|
-
- [
|
|
37
|
-
- [Development](#development)
|
|
41
|
+
- [Models Reference](#models-reference)
|
|
42
|
+
- [BaseService Utilities](#baseservice-utilities)
|
|
43
|
+
- [Testing Guide](#testing-guide)
|
|
44
|
+
- [Development Commands](#development-commands)
|
|
45
|
+
- [Adding a New API](#adding-a-new-api)
|
|
38
46
|
- [Build Output](#build-output)
|
|
39
47
|
|
|
40
48
|
---
|
|
@@ -45,6 +53,14 @@ A TypeScript API client library for integrating with Buzzebees services. Provide
|
|
|
45
53
|
npm install @bzbs/react-api-client
|
|
46
54
|
```
|
|
47
55
|
|
|
56
|
+
Peer dependency: `axios`
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm install axios
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
48
64
|
## Quick Start
|
|
49
65
|
|
|
50
66
|
```typescript
|
|
@@ -81,6 +97,20 @@ if (result.type === 'success') {
|
|
|
81
97
|
}
|
|
82
98
|
```
|
|
83
99
|
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## API Version
|
|
103
|
+
|
|
104
|
+
This library targets **Buzzebees API v2**. Key differences from v1:
|
|
105
|
+
|
|
106
|
+
- All POST request bodies use **JSON** (`application/json`) — no more `application/x-www-form-urlencoded`
|
|
107
|
+
- Profile image upload uses `multipart/form-data` via the dedicated `updateProfileImage()` method
|
|
108
|
+
- Flat endpoint paths replace REST-style path parameters (e.g. `campaign/detail?campaignId=123` replaces `campaign/123`)
|
|
109
|
+
- `profile/me/` prefix removed — the auth token identifies the user (e.g. `profile/info` replaces `profile/me`)
|
|
110
|
+
- Address lookups moved from `main/` to `address/` prefix
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
84
114
|
## Configuration
|
|
85
115
|
|
|
86
116
|
### Constructor
|
|
@@ -122,8 +152,6 @@ axiosClient.interceptors.request.use((config) => {
|
|
|
122
152
|
|
|
123
153
|
### Dynamic URL Updates
|
|
124
154
|
|
|
125
|
-
You can update base URLs at runtime:
|
|
126
|
-
|
|
127
155
|
```typescript
|
|
128
156
|
bzbsService.setBaseUrl('https://new-api.buzzebees.com/api/');
|
|
129
157
|
bzbsService.setBlobUrl('https://new-blob.buzzebees.com/');
|
|
@@ -134,36 +162,43 @@ bzbsService.setLineUrl('https://api.line.me/');
|
|
|
134
162
|
|
|
135
163
|
## Architecture
|
|
136
164
|
|
|
137
|
-
The library follows a layered service architecture:
|
|
138
|
-
|
|
139
165
|
```
|
|
166
|
+
Consumer Code
|
|
167
|
+
│
|
|
168
|
+
▼
|
|
140
169
|
BzbsService (entry point)
|
|
141
170
|
├── AuthenticateApi → auth/
|
|
142
171
|
├── BadgeApi → profile/me/badges
|
|
143
172
|
├── CampaignApi → campaign/
|
|
144
173
|
├── CartApi → cart/
|
|
145
|
-
├── CategoryApi →
|
|
174
|
+
├── CategoryApi → category/
|
|
146
175
|
├── ConsentApi → consent/
|
|
147
176
|
├── CouponApi → coupon/
|
|
148
|
-
├── DashboardApi → dashboard/
|
|
177
|
+
├── DashboardApi → dashboard/config
|
|
149
178
|
├── HistoryApi → redeem/
|
|
150
179
|
├── LineApi → LINE OAuth (optional)
|
|
151
|
-
├── NotificationApi →
|
|
180
|
+
├── NotificationApi → notification/
|
|
152
181
|
├── PlaceApi → place/
|
|
153
182
|
├── PointLogApi → log/points
|
|
154
|
-
├── ProfileApi → profile/
|
|
183
|
+
├── ProfileApi → profile/
|
|
155
184
|
├── RegistrationApi → auth/register
|
|
156
|
-
├── AddressApi → profile/
|
|
185
|
+
├── AddressApi → profile/address, address/
|
|
157
186
|
├── StampApi → stamp/
|
|
158
187
|
├── RequestHelpApi → buzz/, profile/me/help
|
|
159
|
-
├── SettingApi → setting/
|
|
188
|
+
├── SettingApi → setting/add
|
|
160
189
|
└── Blob → blob storage
|
|
190
|
+
│
|
|
191
|
+
▼
|
|
192
|
+
BaseService ← Abstract HTTP layer
|
|
193
|
+
│
|
|
194
|
+
▼
|
|
195
|
+
AxiosInstance ← Consumer-injected, fully configurable
|
|
161
196
|
```
|
|
162
197
|
|
|
163
198
|
All API classes extend `BaseService`, which provides:
|
|
164
199
|
- HTTP methods: `get`, `post`, `put`, `delete`, `patch`
|
|
165
|
-
- Automatic response normalization
|
|
166
|
-
- Error handling with typed
|
|
200
|
+
- Automatic response normalization (handles both `{ Success, Data }` and `{ success, data }` formats)
|
|
201
|
+
- Error handling with typed `ServiceResponse<T>`
|
|
167
202
|
- URL construction utilities
|
|
168
203
|
- FormData creation utility
|
|
169
204
|
|
|
@@ -200,11 +235,92 @@ src/
|
|
|
200
235
|
|
|
201
236
|
---
|
|
202
237
|
|
|
203
|
-
##
|
|
238
|
+
## BzbsService Properties
|
|
239
|
+
|
|
240
|
+
| Property | Type | Description |
|
|
241
|
+
|---|---|---|
|
|
242
|
+
| `authApi` | `AuthenticateApi` | Authentication, login, OTP, session management |
|
|
243
|
+
| `badgeApi` | `BadgeApi` | User badges and missions |
|
|
244
|
+
| `campaignApi` | `CampaignApi` | Campaigns, redemption, favorites |
|
|
245
|
+
| `cartApi` | `CartApi` | Shopping cart |
|
|
246
|
+
| `categoryApi` | `CategoryApi` | Campaign categories |
|
|
247
|
+
| `consentApi` | `ConsentApi` | PDPA / privacy consent |
|
|
248
|
+
| `couponApi` | `CouponApi` | Coupon code processing |
|
|
249
|
+
| `dashboardApi` | `DashboardApi` | Dashboard content |
|
|
250
|
+
| `historyApi` | `HistoryApi` | Redemption history, voucher usage |
|
|
251
|
+
| `lineApi` | `LineApi \| undefined` | LINE OAuth (only if `baseLineUrl` provided) |
|
|
252
|
+
| `notificationApi` | `NotificationApi` | Push notifications |
|
|
253
|
+
| `placeApi` | `PlaceApi` | Locations / stores |
|
|
254
|
+
| `pointLogApi` | `PointLogApi` | Point transaction logs |
|
|
255
|
+
| `profileApi` | `ProfileApi` | User profile, points, account |
|
|
256
|
+
| `registerApi` | `RegistrationApi` | User registration |
|
|
257
|
+
| `addressApi` | `AddressApi` | Addresses, provinces, districts |
|
|
258
|
+
| `stampApi` | `StampApi` | Stamp cards |
|
|
259
|
+
| `forumApi` | `RequestHelpApi` | Help/support forum (Buzz) |
|
|
260
|
+
| `settingApi` | `SettingApi` | Web landing / cart settings |
|
|
261
|
+
| `blob` | `Blob` | Blob storage, maintenance, consent versions |
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Response Handling
|
|
266
|
+
|
|
267
|
+
All API methods return `Promise<ServiceResponse<T>>`, a discriminated union:
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
type ServiceResponse<T> = SuccessResponse<T> | ErrorResponse;
|
|
204
271
|
|
|
205
|
-
|
|
272
|
+
type SuccessResponse<T> = {
|
|
273
|
+
type: 'success';
|
|
274
|
+
model: T; // The typed response data
|
|
275
|
+
response: AxiosResponse;
|
|
276
|
+
};
|
|
206
277
|
|
|
207
|
-
|
|
278
|
+
type ErrorResponse = ClientError | ServerError;
|
|
279
|
+
|
|
280
|
+
type ServerError = {
|
|
281
|
+
type: 'server-error';
|
|
282
|
+
error: BzbsErrorResponse; // { requestId, error: { id, message, code, type } }
|
|
283
|
+
statusCode: number;
|
|
284
|
+
response: AxiosResponse;
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
type ClientError = {
|
|
288
|
+
type: 'client-error';
|
|
289
|
+
message: string;
|
|
290
|
+
details?: any;
|
|
291
|
+
};
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Usage Pattern
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
const result = await bzbsService.campaignApi.campaigns({ config: 'main' });
|
|
298
|
+
|
|
299
|
+
switch (result.type) {
|
|
300
|
+
case 'success':
|
|
301
|
+
console.log(result.model); // Campaign[]
|
|
302
|
+
break;
|
|
303
|
+
|
|
304
|
+
case 'server-error':
|
|
305
|
+
console.error(result.error.error?.message);
|
|
306
|
+
console.error('Status:', result.statusCode);
|
|
307
|
+
break;
|
|
308
|
+
|
|
309
|
+
case 'client-error':
|
|
310
|
+
console.error(result.message);
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Response Normalization
|
|
316
|
+
|
|
317
|
+
The library automatically handles both uppercase and lowercase API response formats:
|
|
318
|
+
- `{ Success: true, Data: ... }` and `{ success: true, data: ... }` are both supported
|
|
319
|
+
- HTTP 204 responses return an empty object as the model
|
|
320
|
+
|
|
321
|
+
### Custom Request Headers
|
|
322
|
+
|
|
323
|
+
Pass `RequestOptions` as the last argument to any API method:
|
|
208
324
|
|
|
209
325
|
```typescript
|
|
210
326
|
type RequestOptions = {
|
|
@@ -213,13 +329,123 @@ type RequestOptions = {
|
|
|
213
329
|
data?: any;
|
|
214
330
|
baseUrl?: string;
|
|
215
331
|
};
|
|
332
|
+
|
|
333
|
+
const response = await bzbsService.profileApi.profile(undefined, {
|
|
334
|
+
headers: { 'Accept-Language': 'th' },
|
|
335
|
+
});
|
|
216
336
|
```
|
|
217
337
|
|
|
218
338
|
---
|
|
219
339
|
|
|
340
|
+
## Complete API Endpoint Table
|
|
341
|
+
|
|
342
|
+
> All endpoints are relative to `baseUrl` (constructor param), except `LineApi` (uses `baseLineUrl`) and `Blob` (uses `baseBlobUrl`).
|
|
343
|
+
>
|
|
344
|
+
> **Feature Tags:** `#auth` `#campaign` `#cart` `#category` `#consent` `#coupon` `#dashboard` `#history` `#line` `#notification` `#place` `#points` `#profile` `#registration` `#address` `#stamp` `#forum` `#setting` `#blob`
|
|
345
|
+
|
|
346
|
+
| Service | Method | HTTP | Endpoint | Key Parameters | Return Model | Tags |
|
|
347
|
+
|---|---|---|---|---|---|---|
|
|
348
|
+
| `authApi` | `deviceLogin` | POST | `auth/device_login` | appId, uuid, deviceLocale, os, platform, deviceToken, macAddress; opt: otp, refcode, contact_number | `LoginResponse` | `#auth` |
|
|
349
|
+
| `authApi` | `facebookLogin` | POST | `auth/login` | accessToken, appId, uuid, deviceLocale, os, platform, deviceToken, macAddress | `LoginResponse` | `#auth` |
|
|
350
|
+
| `authApi` | `googleLogin` | POST | `auth/google_login` | idToken, appId, uuid, deviceLocale, os, platform, deviceToken, macAddress | `LoginResponse` | `#auth` |
|
|
351
|
+
| `authApi` | `lineLogin` | POST | `auth/line_login` | idToken, lineAccessToken, authorizationCode, appId, uuid, os, platform, deviceToken, macAddress | `LoginResponse` | `#auth #line` |
|
|
352
|
+
| `authApi` | `appleLogin` | POST | `auth/apple_login` | idToken, refreshToken, appId, uuid, os, platform, deviceToken, macAddress | `LoginResponse` | `#auth` |
|
|
353
|
+
| `authApi` | `appleToken` | POST | `auth/apple_token` | authorizationCode, idToken, appId, os, platform, macAddress, clientVersion | `AppleToken` | `#auth` |
|
|
354
|
+
| `authApi` | `usernamePasswordLogin` | POST | `auth/bzbs_login` | username, password, appId, uuid, deviceLocale, os, platform, deviceToken, macAddress | `LoginResponse` | `#auth` |
|
|
355
|
+
| `authApi` | `connectLine` | POST | `auth/line_login` | idToken, lineAccessToken, authorizationCode, appId, uuid, os, platform, deviceToken, macAddress | `LoginResponse` | `#auth #line` |
|
|
356
|
+
| `authApi` | `connectFacebook` | POST | `auth/login` | accessToken, appId, uuid, os, platform, deviceToken, macAddress | `LoginResponse` | `#auth` |
|
|
357
|
+
| `authApi` | `connectGoogle` | POST | `auth/google_login` | idToken, appId, uuid, os, platform, deviceToken, macAddress | `LoginResponse` | `#auth` |
|
|
358
|
+
| `authApi` | `connectApple` | POST | `auth/apple_login` | idToken, refreshToken, appId, uuid, os, platform, deviceToken, macAddress | `LoginResponse` | `#auth` |
|
|
359
|
+
| `authApi` | `logout` | POST | `auth/logout` | uuid | `unknown` | `#auth` |
|
|
360
|
+
| `authApi` | `forgetPassword` | GET | `profile/forget_password` | contact (as `id` param), type (`email`\|`contact_number`\|`email_otp`) | `ForgetPasswordResponse` | `#auth #profile` |
|
|
361
|
+
| `authApi` | `resetPassword` | POST | `profile/forget_password` | contact (as `id`), refCode, newPassword; opt: otp | `StatusResponse` | `#auth #profile` |
|
|
362
|
+
| `authApi` | `otp` | GET | `auth/otp` | uuid, appId, contactNumber; opt: channel | `OtpResponse` | `#auth` |
|
|
363
|
+
| `authApi` | `otpV2` | POST | `auth/otp` | appId, contactNumber; opt: channel | `OtpResponse` | `#auth` |
|
|
364
|
+
| `authApi` | `otpEmail` | GET | `auth/otp_email` | uuid, appId, email; opt: channel | `OtpResponse` | `#auth` |
|
|
365
|
+
| `authApi` | `confirmOtp` | POST | `auth/bzbs_authen` | otp, refCode, contactNumber | `ConfirmOtpResponse` | `#auth` |
|
|
366
|
+
| `authApi` | `validateOtp` | POST | `auth/validate_otp` | appId, otp, refCode, type; opt: contactNumber, email, use, channel | `ValidateOtpResponse` | `#auth` |
|
|
367
|
+
| `authApi` | `resume` | POST | `auth/device_resume` | uuid, deviceAppId, os, platform, macAddress, deviceNotificationEnabled, clientVersion, deviceToken | `ResumeResponse` | `#auth` |
|
|
368
|
+
| `authApi` | `updateDevice` | POST | `auth/update_device` | uuid, deviceAppId, os, platform, macAddress, deviceNotificationEnabled, clientVersion, deviceToken | `ResumeResponse` | `#auth` |
|
|
369
|
+
| `authApi` | `version` | GET | `auth/version` | clientVersion | `Version` | `#auth` |
|
|
370
|
+
| `authApi` | `versionRaw` | GET | `auth/version` | clientVersion | `any` | `#auth` |
|
|
371
|
+
| `badgeApi` | `badges` | GET | `profile/me/badges` | opt: badgeId | `Badge[]` | `#profile` |
|
|
372
|
+
| `campaignApi` | `campaigns` | GET | `campaign/list` | config; opt: cat, byConfig, skip, top, locale, keyword, startDate, sponsorId, maxPoints, minPoints, sortBy, center, hashTags, locationAgencyId | `Campaign[]` | `#campaign` |
|
|
373
|
+
| `campaignApi` | `favoriteCampaigns` | GET | `profile/favourite_campaign` | opt: skip, top, locale | `Campaign[]` | `#campaign #profile` |
|
|
374
|
+
| `campaignApi` | `campaignDetails` | GET | `campaign/detail` | id (as `campaignId`); opt: deviceLocale | `CampaignDetail` | `#campaign` |
|
|
375
|
+
| `campaignApi` | `addToFavorite` | POST | `campaign/favourite` | id (as body `id`, `favourite: true`) | `FavoriteResponse` | `#campaign` |
|
|
376
|
+
| `campaignApi` | `removeFromFavorite` | DELETE | `campaign/favourite` | id (as query param) | `FavoriteResponse` | `#campaign` |
|
|
377
|
+
| `campaignApi` | `redeem` | POST | `campaign/redeem` | id (as `campaignid`); opt: addressKey, contactNumber, pointUnit, spPoints | `RedeemResponse` | `#campaign #points` |
|
|
378
|
+
| `campaignApi` | `bulkRedeem` | POST | `campaign/{id}/bulkredeem` | id, quantity; opt: addressKey, contactNumber, pointUnit, spPoints | `RedeemResponse` | `#campaign #points` |
|
|
379
|
+
| `cartApi` | `addCart` | POST | `cart/{id}/add` | id; opt: mode, qty, sideCampaignJson | `CartCountResponse` | `#cart #campaign` |
|
|
380
|
+
| `cartApi` | `cartCount` | GET | `cart/count` | opt: options | `CartCountResponse` | `#cart` |
|
|
381
|
+
| `cartApi` | `cartAccess` | POST | `setting/add` | errorUrl, successUrl, returnUrl, appId, appName | `CartAccessResponse` | `#cart #setting` |
|
|
382
|
+
| `categoryApi` | `categories` | GET | `category/menu` | config; opt: byConfig | `Category[]` | `#category #campaign` |
|
|
383
|
+
| `consentApi` | `consent` | GET | `consent/status` | opt: options | `Consent` | `#consent` |
|
|
384
|
+
| `consentApi` | `updateConsent` | POST | `consent/consent` | opt: termsAndConditions, dataPrivacy, marketingOption, consentAge, email, sms, notification, line, analyticsBuzzebeesCookies, analyticsFirebaseCookies, analyticsGoogleCookies, analyticsMetaCookies, analyticsOtherCookies, functionalCookies, marketingCookies, necessaryCookies | `Consent` | `#consent` |
|
|
385
|
+
| `consentApi` | `unconsent` | POST | `consent/unconsent` | opt: options | `unknown` | `#consent` |
|
|
386
|
+
| `couponApi` | `processCodes` | POST | `coupon/process` | codes (string or string[], sent as JSON array) | `CouponResponse` | `#coupon #campaign` |
|
|
387
|
+
| `dashboardApi` | `mainDashboard` | GET | `dashboard/config` | appName (as `config`), locale | `Dashboard[]` | `#dashboard` |
|
|
388
|
+
| `dashboardApi` | `subDashboard` | GET | `dashboard/config` | dashboardName (as `config`), locale | `Dashboard[]` | `#dashboard` |
|
|
389
|
+
| `historyApi` | `redeemHistories` | GET | `redeem/list` | byConfig, config, skip, top; opt: locale, startDate, endDate | `Purchase[]` | `#history #campaign` |
|
|
390
|
+
| `historyApi` | `use` | POST | `redeem/use` | redeemKey (as `redeemkey` in body) | `UseCampaignResponse` | `#history #campaign` |
|
|
391
|
+
| `lineApi` | `lineAuth` | POST | `oauth2/v2.1/token` _(baseLineUrl)_ | grantType, code, clientId, clientSecret, redirectUrl | `LineAuthResponse` | `#line #auth` |
|
|
392
|
+
| `notificationApi` | `notifications` | GET | `notification/list` | mode (`new`\|`all`), sortBy (`createdate_desc`\|`createdate_asc`); opt: top, skip | `Notification[]` | `#notification` |
|
|
393
|
+
| `notificationApi` | `read` | POST | `notification/read` | ids (comma-separated, sent as JSON body) | `unknown` | `#notification` |
|
|
394
|
+
| `placeApi` | `placeList` | GET | `place` | agencyId, center, distance, top; opt: provinceCode, category, mode, requiredCampaign, keyword, isFavourite | `Place[]` | `#place` |
|
|
395
|
+
| `placeApi` | `place` | GET | `place/{id}` | id, agencyId; opt: requiredCampaign, isFavourite | `Place` | `#place` |
|
|
396
|
+
| `placeApi` | `addToFavourite` | POST | `place/{id}/favourite` | id | `unknown` | `#place` |
|
|
397
|
+
| `placeApi` | `removeFromFavourite` | POST | `place/{id}/unfavourite` | id | `unknown` | `#place` |
|
|
398
|
+
| `pointLogApi` | `getPointLog` | GET | `log/points` | month; opt: type, lastRowKey, top | `PointLog[]` | `#points #profile` |
|
|
399
|
+
| `profileApi` | `profile` | GET | `profile/info` | opt: options | `ProfileResponse` | `#profile` |
|
|
400
|
+
| `profileApi` | `updateProfile` | POST | `profile/info` | opt: firstName, lastName, contactNumber, email, notification, locale, title, gender, birthDate, address, subdistrictCode, districtCode, provinceCode, countryCode, zipCode, idCard, passport, maritalStatus, displayName, latitude, longitude, income, interests, region, occupation, remark, ... (JSON body) | `ProfileResponse` | `#profile` |
|
|
401
|
+
| `profileApi` | `updateProfileImage` | POST | `profile/picture` | image (File or `{uri, name, type}`, sent as `multipart/form-data` with key `data`) | `ProfileResponse` | `#profile` |
|
|
402
|
+
| `profileApi` | `changePassword` | POST | `profile/change_password` | current, change | `StatusResponse` | `#profile #auth` |
|
|
403
|
+
| `profileApi` | `updateShipping` | POST | `profile/shipping` | opt: shippingFirstName, shippingLastName, shippingProvinceCode, shippingDistrictCode, shippingSubDistrictCode, shippingZipCode, shippingAddress, shippingContactNumber, ... | `unknown` | `#profile #address` |
|
|
404
|
+
| `profileApi` | `changeContactNumber` | POST | `auth/change_authen` | contactNumber, otp, refCode; opt: idCard | `ConfirmOtpResponse` | `#profile #auth` |
|
|
405
|
+
| `profileApi` | `changeContactNumberV2` | POST | `profile/contact_number` | contactNumber, otp, refCode | `any` | `#profile #auth` |
|
|
406
|
+
| `profileApi` | `changeContactNumberV3` | POST | `profile/contact_number` | userId (as `userid` in body), contactNumber, otp, refCode | `any` | `#profile #auth` |
|
|
407
|
+
| `profileApi` | `points` | GET | `profile/updated_points` | opt: options | `UpdatedPoints` | `#profile #points` |
|
|
408
|
+
| `profileApi` | `expiringPoints` | GET | `profile/allexpiring_points` | opt: options | `ExpiringPoints` | `#profile #points` |
|
|
409
|
+
| `profileApi` | `deactivate` | POST | `profile/deactivate` | opt: options | `unknown` | `#profile` |
|
|
410
|
+
| `registerApi` | `validateRegister` | POST | `auth/validate_register` | appId, username, email, contactNumber | `OtpResponse` | `#registration #auth` |
|
|
411
|
+
| `registerApi` | `register` | POST | `auth/register` | appId, uuid, macAddress, os, platform, clientVersion, deviceNotificationEnable, username, password, confirmPassword, firstName, lastName, contactNumber, otp, refCode, options; opt: address, gender, birthdate, email, refUserCode, termAndConditionVersion, dataPrivacyVersion, marketingOptionsVersion, consentAge, emailMarketing, smsMarketing, notificationMarketing, lineMarketing, phoneMarketing | `RegistrationResponse` | `#registration #auth` |
|
|
412
|
+
| `addressApi` | `zipCodes` | GET | `address/postcode` | opt: zipCode | `ZipCode[]` | `#address` |
|
|
413
|
+
| `addressApi` | `provinces` | GET | `address/province` | opt: options | `Province[]` | `#address` |
|
|
414
|
+
| `addressApi` | `districts` | GET | `address/district` | opt: provinceCode | `District[]` | `#address` |
|
|
415
|
+
| `addressApi` | `subDistricts` | GET | `address/subdistrict` | opt: provinceCode, districtCode | `SubDistrict[]` | `#address` |
|
|
416
|
+
| `addressApi` | `userAddresses` | GET | `profile/addresses` | opt: options | `Address[]` | `#address #profile` |
|
|
417
|
+
| `addressApi` | `updateAddress` | POST | `profile/address` | opt: name, addressName, firstName, lastName, address, zipcode, provinceCode, provinceName, districtCode, districtName, subDistrictCode, subDistrictName, contactNumber, countryCode, countryName, latitude, longitude, landmark, isDefault, rowKey | `Address` | `#address #profile` |
|
|
418
|
+
| `addressApi` | `deleteAddress` | DELETE | `profile/address` | opt: rowKey | `unknown` | `#address #profile` |
|
|
419
|
+
| `addressApi` | `userTaxAddresses` | GET | `profile/taxes` | opt: options | `Address[]` | `#address #profile` |
|
|
420
|
+
| `addressApi` | `updateTaxAddress` | POST | `profile/tax` | opt: rowKey, taxId, isDefault, personType, title, name, firstName, lastName, email, contactNumber, brnachId, branchName, companyName, address, addressName, floor, building, moo, road, room, soi, village, districtCode, provinceName, subDistrictCode, zipcode | `Address` | `#address #profile` |
|
|
421
|
+
| `addressApi` | `deleteTaxAddress` | DELETE | `profile/tax` | opt: rowKey | `unknown` | `#address #profile` |
|
|
422
|
+
| `stampApi` | `createStamp` | POST | `stamp/create` | opt: imei, issuer, os, platform | `CreateStampResponse` | `#stamp` |
|
|
423
|
+
| `stampApi` | `stamps` | GET | `stamp` | options | `Stamp[]` | `#stamp` |
|
|
424
|
+
| `stampApi` | `stampProfile` | GET | `stamp/{id}/profile` | id, cardId | `StampProfileResponse` | `#stamp` |
|
|
425
|
+
| `forumApi` | `helpCode` | POST | `profile/me/help` | os, platform, clientVersion | `RequestHelpCode` | `#forum #profile` |
|
|
426
|
+
| `forumApi` | `requestHelpList` | GET | `buzz/{requestId}/list` | requestId | `ChatMessage[]` | `#forum` |
|
|
427
|
+
| `forumApi` | `requestDetail` | GET | `buzz/{buzzKey}` | buzzKey | `ChatMessage` | `#forum` |
|
|
428
|
+
| `forumApi` | `postRequestHelp` | POST | `buzz/{requestId}/buzz` | requestId, message; opt: image (File) | `ChatMessage` | `#forum` |
|
|
429
|
+
| `forumApi` | `comments` | GET | `buzz/{buzzKey}/comments` | buzzKey; opt: lastRowKey | `ChatMessage[]` | `#forum` |
|
|
430
|
+
| `forumApi` | `postComment` | POST | `buzz/{buzzKey}/comments` | buzzKey, message; opt: image (File) | `ChatMessage` | `#forum` |
|
|
431
|
+
| `forumApi` | `like` | POST | `buzz/{buzzKey}/like` | buzzKey | `LikeForumResponse` | `#forum` |
|
|
432
|
+
| `forumApi` | `unlike` | DELETE | `buzz/{buzzKey}/like` | buzzKey | `LikeForumResponse` | `#forum` |
|
|
433
|
+
| `settingApi` | `accessKey` | POST | `setting/add` | data (JSON: app_id, campaign_id, locale, return_url, version; opt: redeem_key) | `AccessTokenResponse` | `#setting #campaign` |
|
|
434
|
+
| `blob` | `consentVersion` | GET | `pdpaconsent/{appId}/version` _(baseBlobUrl)_ | appId | `ConsentVersion` | `#blob #consent` |
|
|
435
|
+
| `blob` | `maintenance` | GET | `config/maintenance/{appId}.json` _(baseBlobUrl)_ | appId | `Maintenance` | `#blob` |
|
|
436
|
+
| `blob` | `blob` | GET | `{path}` _(baseBlobUrl)_ | path | `unknown` | `#blob` |
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
## API Reference
|
|
441
|
+
|
|
442
|
+
Every method accepts an optional `requestOptions` as the last argument for custom headers or query params.
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
220
446
|
### AuthenticateApi
|
|
221
447
|
|
|
222
|
-
|
|
448
|
+
`bzbsService.authApi` — Authentication, login providers, OTP, session management.
|
|
223
449
|
|
|
224
450
|
| Method | Description | Returns |
|
|
225
451
|
|---|---|---|
|
|
@@ -230,26 +456,27 @@ Accessed via `bzbsService.authApi`.
|
|
|
230
456
|
| `appleLogin(params)` | Login with Apple ID token + refresh token | `LoginResponse` |
|
|
231
457
|
| `appleToken(params)` | Request Apple refresh token | `AppleToken` |
|
|
232
458
|
| `usernamePasswordLogin(params)` | Login with username/password | `LoginResponse` |
|
|
233
|
-
| `connectLine(params)` | Connect/
|
|
234
|
-
| `connectFacebook(params)` | Connect/
|
|
235
|
-
| `connectGoogle(params)` | Connect/
|
|
236
|
-
| `connectApple(params)` | Connect/
|
|
459
|
+
| `connectLine(params)` | Connect/link LINE to existing account | `LoginResponse` |
|
|
460
|
+
| `connectFacebook(params)` | Connect/link Facebook to existing account | `LoginResponse` |
|
|
461
|
+
| `connectGoogle(params)` | Connect/link Google to existing account | `LoginResponse` |
|
|
462
|
+
| `connectApple(params)` | Connect/link Apple to existing account | `LoginResponse` |
|
|
237
463
|
| `logout(params)` | Logout user | `unknown` |
|
|
238
464
|
| `forgetPassword(params)` | Send forget password request | `ForgetPasswordResponse` |
|
|
239
|
-
| `resetPassword(params)` | Reset user password | `StatusResponse` |
|
|
240
|
-
| `otp(params)` | Request OTP
|
|
241
|
-
| `otpV2(params)` | Request OTP
|
|
465
|
+
| `resetPassword(params)` | Reset user password with OTP | `StatusResponse` |
|
|
466
|
+
| `otp(params)` | Request OTP (GET) | `OtpResponse` |
|
|
467
|
+
| `otpV2(params)` | Request OTP (POST) | `OtpResponse` |
|
|
242
468
|
| `otpEmail(params)` | Request OTP via email | `OtpResponse` |
|
|
243
|
-
| `confirmOtp(params)` | Confirm OTP | `ConfirmOtpResponse` |
|
|
244
|
-
| `validateOtp(params)` | Validate OTP | `ValidateOtpResponse` |
|
|
245
|
-
| `resume(params)` |
|
|
246
|
-
| `updateDevice(params)` | Update device
|
|
469
|
+
| `confirmOtp(params)` | Confirm OTP for authentication | `ConfirmOtpResponse` |
|
|
470
|
+
| `validateOtp(params)` | Validate OTP (generic) | `ValidateOtpResponse` |
|
|
471
|
+
| `resume(params)` | Resume/refresh session | `ResumeResponse` |
|
|
472
|
+
| `updateDevice(params)` | Update device push token | `ResumeResponse` |
|
|
247
473
|
| `version(clientVersion)` | Get app version info | `Version` |
|
|
248
474
|
| `versionRaw(clientVersion)` | Get raw version info | `any` |
|
|
249
475
|
|
|
250
|
-
####
|
|
476
|
+
#### Examples
|
|
251
477
|
|
|
252
478
|
```typescript
|
|
479
|
+
// Device login
|
|
253
480
|
const result = await bzbsService.authApi.deviceLogin({
|
|
254
481
|
appId: 'your-app-id',
|
|
255
482
|
uuid: 'device-uuid',
|
|
@@ -262,25 +489,14 @@ const result = await bzbsService.authApi.deviceLogin({
|
|
|
262
489
|
macAddress: 'device-mac-address',
|
|
263
490
|
});
|
|
264
491
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
// Store token for subsequent requests
|
|
268
|
-
}
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
#### OTP Flow Example
|
|
272
|
-
|
|
273
|
-
```typescript
|
|
274
|
-
// 1. Request OTP
|
|
275
|
-
const otpResult = await bzbsService.authApi.otp({
|
|
276
|
-
uuid: 'device-uuid',
|
|
492
|
+
// OTP flow
|
|
493
|
+
const otpResult = await bzbsService.authApi.otpV2({
|
|
277
494
|
appId: 'your-app-id',
|
|
278
495
|
contactNumber: '0812345678',
|
|
279
496
|
});
|
|
280
497
|
|
|
281
|
-
// 2. Validate OTP
|
|
282
498
|
if (otpResult.type === 'success') {
|
|
283
|
-
const
|
|
499
|
+
const validated = await bzbsService.authApi.validateOtp({
|
|
284
500
|
appId: 'your-app-id',
|
|
285
501
|
otp: '123456',
|
|
286
502
|
refCode: otpResult.model.refcode,
|
|
@@ -294,7 +510,7 @@ if (otpResult.type === 'success') {
|
|
|
294
510
|
|
|
295
511
|
### CampaignApi
|
|
296
512
|
|
|
297
|
-
|
|
513
|
+
`bzbsService.campaignApi` — Campaign listing, details, redemption, and favorites.
|
|
298
514
|
|
|
299
515
|
| Method | Description | Returns |
|
|
300
516
|
|---|---|---|
|
|
@@ -317,14 +533,12 @@ Accessed via `bzbsService.campaignApi`.
|
|
|
317
533
|
| `top` | `number` | No | Number of items to retrieve |
|
|
318
534
|
| `keyword` | `string` | No | Search keyword |
|
|
319
535
|
| `sortBy` | `string` | No | Sort order |
|
|
320
|
-
| `center` | `string` | No | Geo coordinates for location-based search |
|
|
536
|
+
| `center` | `string` | No | Geo coordinates (`lat,lng`) for location-based search |
|
|
321
537
|
| `hashTags` | `string` | No | Filter by hashtags |
|
|
322
538
|
| `sponsorId` | `string` | No | Sponsor filter |
|
|
323
539
|
| `minPoints` | `string` | No | Minimum points filter |
|
|
324
540
|
| `maxPoints` | `string` | No | Maximum points filter |
|
|
325
541
|
|
|
326
|
-
#### Example
|
|
327
|
-
|
|
328
542
|
```typescript
|
|
329
543
|
// List campaigns
|
|
330
544
|
const campaigns = await bzbsService.campaignApi.campaigns({
|
|
@@ -333,7 +547,6 @@ const campaigns = await bzbsService.campaignApi.campaigns({
|
|
|
333
547
|
skip: 0,
|
|
334
548
|
top: 20,
|
|
335
549
|
keyword: 'coffee',
|
|
336
|
-
sortBy: 'popular',
|
|
337
550
|
});
|
|
338
551
|
|
|
339
552
|
// Redeem a campaign
|
|
@@ -347,12 +560,13 @@ const redeem = await bzbsService.campaignApi.redeem({
|
|
|
347
560
|
|
|
348
561
|
### ProfileApi
|
|
349
562
|
|
|
350
|
-
|
|
563
|
+
`bzbsService.profileApi` — User profile management, points, password, contact number.
|
|
351
564
|
|
|
352
565
|
| Method | Description | Returns |
|
|
353
566
|
|---|---|---|
|
|
354
567
|
| `profile()` | Get current user profile | `ProfileResponse` |
|
|
355
|
-
| `updateProfile(params)` | Update user profile (
|
|
568
|
+
| `updateProfile(params)` | Update user profile fields (JSON body) | `ProfileResponse` |
|
|
569
|
+
| `updateProfileImage(params)` | Upload profile picture (multipart/form-data) | `ProfileResponse` |
|
|
356
570
|
| `changePassword(params)` | Change user password | `StatusResponse` |
|
|
357
571
|
| `updateShipping(params)` | Update shipping information | `unknown` |
|
|
358
572
|
| `changeContactNumber(params)` | Change contact number (v1) | `ConfirmOtpResponse` |
|
|
@@ -360,12 +574,10 @@ Accessed via `bzbsService.profileApi`.
|
|
|
360
574
|
| `changeContactNumberV3(params)` | Change contact number by user ID (v3) | `any` |
|
|
361
575
|
| `points()` | Get user's current points | `UpdatedPoints` |
|
|
362
576
|
| `expiringPoints()` | Get user's expiring points | `ExpiringPoints` |
|
|
363
|
-
| `deactivate()` | Deactivate user
|
|
364
|
-
|
|
365
|
-
#### Profile Update Example
|
|
577
|
+
| `deactivate()` | Deactivate user account | `unknown` |
|
|
366
578
|
|
|
367
579
|
```typescript
|
|
368
|
-
// Update profile
|
|
580
|
+
// Update profile fields (JSON)
|
|
369
581
|
const result = await bzbsService.profileApi.updateProfile({
|
|
370
582
|
firstName: 'John',
|
|
371
583
|
lastName: 'Doe',
|
|
@@ -373,7 +585,11 @@ const result = await bzbsService.profileApi.updateProfile({
|
|
|
373
585
|
contactNumber: '0812345678',
|
|
374
586
|
gender: 'male',
|
|
375
587
|
birthDate: 946684800, // Unix timestamp in seconds
|
|
376
|
-
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
// Upload profile picture (multipart/form-data, field key: "data")
|
|
591
|
+
await bzbsService.profileApi.updateProfileImage({
|
|
592
|
+
image: imageFile, // File | { uri: string; name: string; type: string }
|
|
377
593
|
});
|
|
378
594
|
```
|
|
379
595
|
|
|
@@ -381,7 +597,7 @@ const result = await bzbsService.profileApi.updateProfile({
|
|
|
381
597
|
|
|
382
598
|
### CartApi
|
|
383
599
|
|
|
384
|
-
|
|
600
|
+
`bzbsService.cartApi` — Shopping cart management.
|
|
385
601
|
|
|
386
602
|
| Method | Description | Returns |
|
|
387
603
|
|---|---|---|
|
|
@@ -398,7 +614,7 @@ const count = await bzbsService.cartApi.cartCount();
|
|
|
398
614
|
|
|
399
615
|
### CategoryApi
|
|
400
616
|
|
|
401
|
-
|
|
617
|
+
`bzbsService.categoryApi` — Campaign categories.
|
|
402
618
|
|
|
403
619
|
| Method | Description | Returns |
|
|
404
620
|
|---|---|---|
|
|
@@ -415,11 +631,11 @@ const categories = await bzbsService.categoryApi.categories({
|
|
|
415
631
|
|
|
416
632
|
### CouponApi
|
|
417
633
|
|
|
418
|
-
|
|
634
|
+
`bzbsService.couponApi` — Coupon code processing.
|
|
419
635
|
|
|
420
636
|
| Method | Description | Returns |
|
|
421
637
|
|---|---|---|
|
|
422
|
-
| `processCodes(params)` | Process coupon codes | `CouponResponse` |
|
|
638
|
+
| `processCodes(params)` | Process one or more coupon codes | `CouponResponse` |
|
|
423
639
|
|
|
424
640
|
```typescript
|
|
425
641
|
const result = await bzbsService.couponApi.processCodes({
|
|
@@ -431,7 +647,7 @@ const result = await bzbsService.couponApi.processCodes({
|
|
|
431
647
|
|
|
432
648
|
### NotificationApi
|
|
433
649
|
|
|
434
|
-
|
|
650
|
+
`bzbsService.notificationApi` — Push notification management.
|
|
435
651
|
|
|
436
652
|
| Method | Description | Returns |
|
|
437
653
|
|---|---|---|
|
|
@@ -440,23 +656,20 @@ Accessed via `bzbsService.notificationApi`.
|
|
|
440
656
|
|
|
441
657
|
```typescript
|
|
442
658
|
const notifs = await bzbsService.notificationApi.notifications({
|
|
443
|
-
mode: 'new',
|
|
659
|
+
mode: 'new', // 'new' | 'all'
|
|
444
660
|
sortBy: 'createdate_desc',
|
|
445
661
|
top: 20,
|
|
446
662
|
skip: 0,
|
|
447
663
|
});
|
|
448
664
|
|
|
449
|
-
|
|
450
|
-
await bzbsService.notificationApi.read({
|
|
451
|
-
ids: 'rowKey1,rowKey2',
|
|
452
|
-
});
|
|
665
|
+
await bzbsService.notificationApi.read({ ids: 'rowKey1,rowKey2' });
|
|
453
666
|
```
|
|
454
667
|
|
|
455
668
|
---
|
|
456
669
|
|
|
457
670
|
### HistoryApi
|
|
458
671
|
|
|
459
|
-
|
|
672
|
+
`bzbsService.historyApi` — Redemption history and voucher usage.
|
|
460
673
|
|
|
461
674
|
| Method | Description | Returns |
|
|
462
675
|
|---|---|---|
|
|
@@ -471,7 +684,6 @@ const history = await bzbsService.historyApi.redeemHistories({
|
|
|
471
684
|
top: 20,
|
|
472
685
|
});
|
|
473
686
|
|
|
474
|
-
// Use a coupon
|
|
475
687
|
await bzbsService.historyApi.use({ redeemKey: 'ABC123_1' });
|
|
476
688
|
```
|
|
477
689
|
|
|
@@ -479,17 +691,17 @@ await bzbsService.historyApi.use({ redeemKey: 'ABC123_1' });
|
|
|
479
691
|
|
|
480
692
|
### RegistrationApi
|
|
481
693
|
|
|
482
|
-
|
|
694
|
+
`bzbsService.registerApi` — New user registration with OTP verification.
|
|
483
695
|
|
|
484
696
|
| Method | Description | Returns |
|
|
485
697
|
|---|---|---|
|
|
486
|
-
| `validateRegister(params)` | Validate registration
|
|
698
|
+
| `validateRegister(params)` | Validate registration and trigger OTP | `OtpResponse` |
|
|
487
699
|
| `register(params)` | Register a new user | `RegistrationResponse` |
|
|
488
700
|
|
|
489
701
|
**Validation Error Codes:**
|
|
490
|
-
- `2078`
|
|
491
|
-
- `2089`
|
|
492
|
-
- `401`
|
|
702
|
+
- `2078` — Duplicate contact number
|
|
703
|
+
- `2089` — Duplicate email
|
|
704
|
+
- `401` — Duplicate username
|
|
493
705
|
|
|
494
706
|
```typescript
|
|
495
707
|
// Step 1: Validate
|
|
@@ -525,7 +737,7 @@ const registration = await bzbsService.registerApi.register({
|
|
|
525
737
|
|
|
526
738
|
### AddressApi
|
|
527
739
|
|
|
528
|
-
|
|
740
|
+
`bzbsService.addressApi` — User addresses and Thailand geographical data.
|
|
529
741
|
|
|
530
742
|
| Method | Description | Returns |
|
|
531
743
|
|---|---|---|
|
|
@@ -534,22 +746,19 @@ Accessed via `bzbsService.addressApi`.
|
|
|
534
746
|
| `districts(params)` | Get districts by province | `District[]` |
|
|
535
747
|
| `subDistricts(params)` | Get sub-districts by province/district | `SubDistrict[]` |
|
|
536
748
|
| `userAddresses()` | Get user's saved addresses | `Address[]` |
|
|
537
|
-
| `updateAddress(params)` | Create or update
|
|
749
|
+
| `updateAddress(params)` | Create or update a delivery address | `Address` |
|
|
538
750
|
| `deleteAddress(params)` | Delete an address | `unknown` |
|
|
539
751
|
| `userTaxAddresses()` | Get user's tax addresses | `Address[]` |
|
|
540
752
|
| `updateTaxAddress(params)` | Create or update a tax address | `Address` |
|
|
541
753
|
| `deleteTaxAddress(params)` | Delete a tax address | `unknown` |
|
|
542
754
|
|
|
543
755
|
```typescript
|
|
544
|
-
// Get provinces
|
|
545
756
|
const provinces = await bzbsService.addressApi.provinces();
|
|
546
757
|
|
|
547
|
-
// Get districts for a province
|
|
548
758
|
const districts = await bzbsService.addressApi.districts({
|
|
549
759
|
provinceCode: '10',
|
|
550
760
|
});
|
|
551
761
|
|
|
552
|
-
// Save an address
|
|
553
762
|
await bzbsService.addressApi.updateAddress({
|
|
554
763
|
firstName: 'John',
|
|
555
764
|
lastName: 'Doe',
|
|
@@ -568,15 +777,14 @@ await bzbsService.addressApi.updateAddress({
|
|
|
568
777
|
|
|
569
778
|
### BadgeApi
|
|
570
779
|
|
|
571
|
-
|
|
780
|
+
`bzbsService.badgeApi` — User badges and mission progress.
|
|
572
781
|
|
|
573
782
|
| Method | Description | Returns |
|
|
574
783
|
|---|---|---|
|
|
575
|
-
| `badges(params)` | Get user badges | `Badge[]` |
|
|
784
|
+
| `badges(params)` | Get user badges (opt: filter by badgeId) | `Badge[]` |
|
|
576
785
|
|
|
577
786
|
```typescript
|
|
578
787
|
const badges = await bzbsService.badgeApi.badges({});
|
|
579
|
-
// Or filter by badge ID
|
|
580
788
|
const badge = await bzbsService.badgeApi.badges({ badgeId: '123' });
|
|
581
789
|
```
|
|
582
790
|
|
|
@@ -584,7 +792,9 @@ const badge = await bzbsService.badgeApi.badges({ badgeId: '123' });
|
|
|
584
792
|
|
|
585
793
|
### ConsentApi
|
|
586
794
|
|
|
587
|
-
|
|
795
|
+
`bzbsService.consentApi` — PDPA and marketing consent management.
|
|
796
|
+
|
|
797
|
+
> **v2 change:** `consent()` now calls `consent/status`; `updateConsent()` now calls `consent/consent`.
|
|
588
798
|
|
|
589
799
|
| Method | Description | Returns |
|
|
590
800
|
|---|---|---|
|
|
@@ -592,16 +802,18 @@ Accessed via `bzbsService.consentApi`.
|
|
|
592
802
|
| `updateConsent(params)` | Update consent preferences | `Consent` |
|
|
593
803
|
| `unconsent()` | Withdraw all consent | `unknown` |
|
|
594
804
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
805
|
+
**`consentAge`** accepts one of:
|
|
806
|
+
- `'0'` — user has not consented to age verification
|
|
807
|
+
- `'1'` — user has consented (age confirmed)
|
|
808
|
+
- The user's actual age as a string (e.g. `'25'`)
|
|
598
809
|
|
|
599
|
-
|
|
810
|
+
```typescript
|
|
600
811
|
await bzbsService.consentApi.updateConsent({
|
|
601
812
|
termsAndConditions: '1.0',
|
|
602
813
|
dataPrivacy: '1.0',
|
|
603
814
|
marketingOption: '1.0',
|
|
604
|
-
|
|
815
|
+
consentAge: '25', // '0' | '1' | actual age string
|
|
816
|
+
email: '1', // '0' or '1'
|
|
605
817
|
sms: '1',
|
|
606
818
|
notification: '1',
|
|
607
819
|
line: '0',
|
|
@@ -612,7 +824,9 @@ await bzbsService.consentApi.updateConsent({
|
|
|
612
824
|
|
|
613
825
|
### DashboardApi
|
|
614
826
|
|
|
615
|
-
|
|
827
|
+
`bzbsService.dashboardApi` — Dashboard content configuration.
|
|
828
|
+
|
|
829
|
+
> **v2 change:** Both `mainDashboard` and `subDashboard` now call `dashboard/config`. The `appName`/`dashboardName` param is sent as `config`.
|
|
616
830
|
|
|
617
831
|
| Method | Description | Returns |
|
|
618
832
|
|---|---|---|
|
|
@@ -621,12 +835,12 @@ Accessed via `bzbsService.dashboardApi`.
|
|
|
621
835
|
|
|
622
836
|
```typescript
|
|
623
837
|
const dashboard = await bzbsService.dashboardApi.mainDashboard({
|
|
624
|
-
appName: 'buzzebeesdemo',
|
|
625
|
-
locale: 1054,
|
|
838
|
+
appName: 'buzzebeesdemo', // sent as `config` query param
|
|
839
|
+
locale: 1054,
|
|
626
840
|
});
|
|
627
841
|
|
|
628
|
-
const
|
|
629
|
-
dashboardName: 'featured',
|
|
842
|
+
const sub = await bzbsService.dashboardApi.subDashboard({
|
|
843
|
+
dashboardName: 'featured', // sent as `config` query param
|
|
630
844
|
locale: 1054,
|
|
631
845
|
});
|
|
632
846
|
```
|
|
@@ -635,7 +849,7 @@ const subDashboard = await bzbsService.dashboardApi.subDashboard({
|
|
|
635
849
|
|
|
636
850
|
### LineApi
|
|
637
851
|
|
|
638
|
-
|
|
852
|
+
`bzbsService.lineApi` — LINE OAuth token exchange. Only initialized when `baseLineUrl` is provided. Uses `baseLineUrl` as the base URL.
|
|
639
853
|
|
|
640
854
|
| Method | Description | Returns |
|
|
641
855
|
|---|---|---|
|
|
@@ -657,7 +871,7 @@ if (bzbsService.lineApi) {
|
|
|
657
871
|
|
|
658
872
|
### PlaceApi
|
|
659
873
|
|
|
660
|
-
|
|
874
|
+
`bzbsService.placeApi` — Location/store management with geo-search.
|
|
661
875
|
|
|
662
876
|
| Method | Description | Returns |
|
|
663
877
|
|---|---|---|
|
|
@@ -680,16 +894,16 @@ const places = await bzbsService.placeApi.placeList({
|
|
|
680
894
|
|
|
681
895
|
### PointLogApi
|
|
682
896
|
|
|
683
|
-
|
|
897
|
+
`bzbsService.pointLogApi` — Point transaction history.
|
|
684
898
|
|
|
685
899
|
| Method | Description | Returns |
|
|
686
900
|
|---|---|---|
|
|
687
|
-
| `getPointLog(params)` | Get point transaction log | `PointLog[]` |
|
|
901
|
+
| `getPointLog(params)` | Get point transaction log by month | `PointLog[]` |
|
|
688
902
|
|
|
689
903
|
```typescript
|
|
690
904
|
const logs = await bzbsService.pointLogApi.getPointLog({
|
|
691
905
|
month: '2025-01',
|
|
692
|
-
type: 'earn',
|
|
906
|
+
type: 'earn',
|
|
693
907
|
top: 50,
|
|
694
908
|
});
|
|
695
909
|
```
|
|
@@ -698,7 +912,7 @@ const logs = await bzbsService.pointLogApi.getPointLog({
|
|
|
698
912
|
|
|
699
913
|
### StampApi
|
|
700
914
|
|
|
701
|
-
|
|
915
|
+
`bzbsService.stampApi` — Stamp card system.
|
|
702
916
|
|
|
703
917
|
| Method | Description | Returns |
|
|
704
918
|
|---|---|---|
|
|
@@ -719,28 +933,26 @@ const profile = await bzbsService.stampApi.stampProfile({
|
|
|
719
933
|
|
|
720
934
|
### RequestHelpApi (Forum)
|
|
721
935
|
|
|
722
|
-
|
|
936
|
+
`bzbsService.forumApi` — Help/support forum (Buzz chat system).
|
|
723
937
|
|
|
724
938
|
| Method | Description | Returns |
|
|
725
939
|
|---|---|---|
|
|
726
940
|
| `helpCode(params)` | Get help request code | `RequestHelpCode` |
|
|
727
|
-
| `requestHelpList(params)` | List help request
|
|
728
|
-
| `requestDetail(params)` | Get
|
|
729
|
-
| `postRequestHelp(params)` | Post a help
|
|
941
|
+
| `requestHelpList(params)` | List messages in a help request | `ChatMessage[]` |
|
|
942
|
+
| `requestDetail(params)` | Get a specific message | `ChatMessage` |
|
|
943
|
+
| `postRequestHelp(params)` | Post a help message (supports image) | `ChatMessage` |
|
|
730
944
|
| `comments(params)` | Get comments on a post | `ChatMessage[]` |
|
|
731
945
|
| `postComment(params)` | Post a comment (supports image) | `ChatMessage` |
|
|
732
946
|
| `like(params)` | Like a post | `LikeForumResponse` |
|
|
733
947
|
| `unlike(params)` | Unlike a post | `LikeForumResponse` |
|
|
734
948
|
|
|
735
949
|
```typescript
|
|
736
|
-
// Create a help request
|
|
737
950
|
const helpCode = await bzbsService.forumApi.helpCode({
|
|
738
951
|
os: 'ios 17.0',
|
|
739
952
|
platform: 'iPhone',
|
|
740
953
|
clientVersion: 'ios_myapp1.0.0',
|
|
741
954
|
});
|
|
742
955
|
|
|
743
|
-
// Post a message
|
|
744
956
|
await bzbsService.forumApi.postRequestHelp({
|
|
745
957
|
requestId: 'req-123',
|
|
746
958
|
message: 'I need help with my order',
|
|
@@ -752,7 +964,9 @@ await bzbsService.forumApi.postRequestHelp({
|
|
|
752
964
|
|
|
753
965
|
### SettingApi
|
|
754
966
|
|
|
755
|
-
|
|
967
|
+
`bzbsService.settingApi` — Web landing page access tokens.
|
|
968
|
+
|
|
969
|
+
> **v2 change:** Endpoint changed from `setting` to `setting/add`.
|
|
756
970
|
|
|
757
971
|
| Method | Description | Returns |
|
|
758
972
|
|---|---|---|
|
|
@@ -774,12 +988,12 @@ const accessKey = await bzbsService.settingApi.accessKey({
|
|
|
774
988
|
|
|
775
989
|
### Blob
|
|
776
990
|
|
|
777
|
-
|
|
991
|
+
`bzbsService.blob` — Blob storage retrieval. Uses `baseBlobUrl` as base URL.
|
|
778
992
|
|
|
779
993
|
| Method | Description | Returns |
|
|
780
994
|
|---|---|---|
|
|
781
|
-
| `consentVersion(appId)` | Get PDPA consent version | `ConsentVersion` |
|
|
782
|
-
| `maintenance(appId)` | Get maintenance configuration | `Maintenance` |
|
|
995
|
+
| `consentVersion(appId)` | Get PDPA consent document version | `ConsentVersion` |
|
|
996
|
+
| `maintenance(appId)` | Get app maintenance configuration | `Maintenance` |
|
|
783
997
|
| `blob(path)` | Fetch any blob storage path | `unknown` |
|
|
784
998
|
|
|
785
999
|
```typescript
|
|
@@ -789,183 +1003,245 @@ const maintenance = await bzbsService.blob.maintenance('your-app-id');
|
|
|
789
1003
|
|
|
790
1004
|
---
|
|
791
1005
|
|
|
792
|
-
##
|
|
1006
|
+
## Models Reference
|
|
793
1007
|
|
|
794
|
-
All
|
|
1008
|
+
All TypeScript interfaces are exported from `@bzbs/react-api-client`:
|
|
795
1009
|
|
|
796
1010
|
```typescript
|
|
797
|
-
|
|
1011
|
+
import {
|
|
1012
|
+
Campaign,
|
|
1013
|
+
CampaignDetail,
|
|
1014
|
+
ProfileResponse,
|
|
1015
|
+
LoginResponse,
|
|
1016
|
+
Purchase,
|
|
1017
|
+
// ... etc
|
|
1018
|
+
} from '@bzbs/react-api-client';
|
|
798
1019
|
```
|
|
799
1020
|
|
|
800
|
-
###
|
|
1021
|
+
### Authentication Models
|
|
801
1022
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
1023
|
+
| Model | Key Fields |
|
|
1024
|
+
|---|---|
|
|
1025
|
+
| `LoginResponse` | Token, UserId, UserCode, Username, Points, Consent fields, ProfileImage, Locale |
|
|
1026
|
+
| `ResumeResponse` | Same structure as LoginResponse |
|
|
1027
|
+
| `AppleToken` | refresh_token, id_token |
|
|
1028
|
+
| `LineAuthResponse` | access_token, token_type, refresh_token, expires_in, scope, id_token |
|
|
1029
|
+
| `OtpResponse` | refcode, channel, expiredate, expireinseconds |
|
|
1030
|
+
| `ConfirmOtpResponse` | status, token |
|
|
1031
|
+
| `ValidateOtpResponse` | validatecode |
|
|
1032
|
+
| `ForgetPasswordResponse` | status, refcode, expiredate, expireinseconds |
|
|
1033
|
+
| `RegistrationResponse` | Registration result with Buzzebees user account |
|
|
1034
|
+
| `Version` | allow_use, has_new_version, welcome_page_times |
|
|
1035
|
+
|
|
1036
|
+
### Campaign Models
|
|
1037
|
+
|
|
1038
|
+
| Model | Key Fields |
|
|
1039
|
+
|---|---|
|
|
1040
|
+
| `Campaign` | ID, Name, Points, StartDate, EndDate, CategoryId, ImageUrl, Quantity, IsLike |
|
|
1041
|
+
| `CampaignDetail` | All Campaign fields + images (Picture[]), SubCampaigns, conditions, terms |
|
|
1042
|
+
| `Picture` | ID, Type, Sequence, ImageUrl |
|
|
1043
|
+
| `SubCampaign` | ID, Name, styles (SubCampaignStyle[]), quantity, points |
|
|
1044
|
+
| `RedeemResponse` | RedeemKey, PrivilegeMessageEN, PrivilegeMessageTH, UpdatedPoints, ExpiryDate |
|
|
1045
|
+
| `UseCampaignResponse` | PrivilegeMessageEN, PrivilegeMessageTH, redeemKey, points |
|
|
1046
|
+
| `FavoriteResponse` | totalLike, isLike |
|
|
1047
|
+
| `CouponResponse` | success/error results per code |
|
|
1048
|
+
| `Purchase` | RedeemKey, CampaignName, ExpiryDate, Status, Points, barcode, images |
|
|
1049
|
+
|
|
1050
|
+
### Cart Models
|
|
1051
|
+
|
|
1052
|
+
| Model | Key Fields |
|
|
1053
|
+
|---|---|
|
|
1054
|
+
| `CartCountResponse` | cart_count |
|
|
1055
|
+
| `CartAccessResponse` | success, access key |
|
|
809
1056
|
|
|
810
|
-
###
|
|
1057
|
+
### Profile & Points Models
|
|
811
1058
|
|
|
812
|
-
|
|
813
|
-
|
|
1059
|
+
| Model | Key Fields |
|
|
1060
|
+
|---|---|
|
|
1061
|
+
| `ProfileResponse` | UserId, Name, FirstName, LastName, Email, Contact_Number, address fields, TermAndCondition, DataPrivacy, MarketingOption, ConsentAge (0=not consented, 1=consented, or actual age), EmailMarketing, SMSMarketing, NotificationMarketing, LineMarketing, Token, Jwt, updated_points, Info1–Info10 (60+ fields) |
|
|
1062
|
+
| `UpdatedPoints` | points, time |
|
|
1063
|
+
| `ExpiringPoints` | expiringPoints, expiryDate |
|
|
1064
|
+
| `Badge` | badgeId, name, description, imageUrl, missions (Mission[]) |
|
|
1065
|
+
| `Mission` | missionId, name, current, target, isCompleted |
|
|
1066
|
+
| `PointLog` | UserId, Info, Detail, Points, Type, Timestamp |
|
|
814
1067
|
|
|
815
|
-
|
|
816
|
-
type: 'server-error';
|
|
817
|
-
error: BzbsErrorResponse; // { requestId, error: { id, message, code, type } }
|
|
818
|
-
statusCode: number;
|
|
819
|
-
response: AxiosResponse;
|
|
820
|
-
};
|
|
1068
|
+
### Address & Location Models
|
|
821
1069
|
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
1070
|
+
| Model | Key Fields |
|
|
1071
|
+
|---|---|
|
|
1072
|
+
| `Address` | rowKey, name, firstName, lastName, address, zipcode, province/district/subdistrict codes and names, contactNumber, isDefault, taxId |
|
|
1073
|
+
| `Province` | province_code, province_name_th, province_name_en |
|
|
1074
|
+
| `District` | district_code, district_name_th, district_name_en, province_code |
|
|
1075
|
+
| `SubDistrict` | subdistrict_code, subdistrict_name_th, zip_code |
|
|
1076
|
+
| `ZipCode` | Hierarchical address with zone info |
|
|
1077
|
+
| `Place` | id, name, latitude, longitude, address, workingHours, services, isFavorite |
|
|
828
1078
|
|
|
829
|
-
###
|
|
1079
|
+
### Consent & Settings Models
|
|
830
1080
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
1081
|
+
| Model | Key Fields |
|
|
1082
|
+
|---|---|
|
|
1083
|
+
| `Consent` | TermAndCondition, DataPrivacy, MarketingOption, SMSMarketing, NotificationMarketing, LineMarketing, cookie consent flags |
|
|
1084
|
+
| `ConsentVersion` | version values per consent type |
|
|
1085
|
+
| `Version` | allow_use, has_new_version, welcome_page_times |
|
|
1086
|
+
| `Maintenance` | isUnderMaintenance, message, startDate, endDate |
|
|
835
1087
|
|
|
836
|
-
|
|
837
|
-
case 'success':
|
|
838
|
-
// result.model is Campaign[]
|
|
839
|
-
console.log(result.model);
|
|
840
|
-
break;
|
|
1088
|
+
### Stamp & Dashboard Models
|
|
841
1089
|
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
1090
|
+
| Model | Key Fields |
|
|
1091
|
+
|---|---|
|
|
1092
|
+
| `Stamp` | stampId, cardId, count, maxCount, rewards, expiry |
|
|
1093
|
+
| `StampProfileResponse` | stamp card profile with history |
|
|
1094
|
+
| `CreateStampResponse` | result of stamp creation |
|
|
1095
|
+
| `Dashboard` | id, name, menuItems, images, startDate, endDate |
|
|
1096
|
+
| `Category` | id, name (TH/EN), subcategories, imageUrl |
|
|
847
1097
|
|
|
848
|
-
|
|
849
|
-
// Network error or client-side issue
|
|
850
|
-
console.error(result.message);
|
|
851
|
-
break;
|
|
852
|
-
}
|
|
853
|
-
```
|
|
1098
|
+
### Notification & Forum Models
|
|
854
1099
|
|
|
855
|
-
|
|
1100
|
+
| Model | Key Fields |
|
|
1101
|
+
|---|---|
|
|
1102
|
+
| `Notification` | notiId, title, message, objectType, imageUrl, expireDate, isRead |
|
|
1103
|
+
| `ChatMessage` | buzzKey, message, images, sender info, likes, comments count, createdDate (65+ fields) |
|
|
1104
|
+
| `LikeForumResponse` | likeCount, isLiked |
|
|
1105
|
+
| `RequestHelpCode` | helpCode |
|
|
856
1106
|
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
1107
|
+
### Error & Response Models
|
|
1108
|
+
|
|
1109
|
+
| Model | Key Fields |
|
|
1110
|
+
|---|---|
|
|
1111
|
+
| `BzbsErrorResponse` | requestId, error: { id, message, code, type } |
|
|
1112
|
+
| `StatusResponse` | status |
|
|
1113
|
+
| `AccessTokenResponse` | token key |
|
|
1114
|
+
|
|
1115
|
+
**Common Error Codes:**
|
|
1116
|
+
|
|
1117
|
+
| Code | Description |
|
|
1118
|
+
|---|---|
|
|
1119
|
+
| `401` | Unauthorized / Duplicate username |
|
|
1120
|
+
| `2078` | Duplicate contact number |
|
|
1121
|
+
| `2089` | Duplicate email |
|
|
861
1122
|
|
|
862
1123
|
---
|
|
863
1124
|
|
|
864
|
-
##
|
|
1125
|
+
## BaseService Utilities
|
|
865
1126
|
|
|
866
|
-
###
|
|
1127
|
+
### createFormData
|
|
1128
|
+
|
|
1129
|
+
Static method for building `multipart/form-data` payloads. Skips `undefined`, `null`, and empty string values — preserves `0` and `false`.
|
|
867
1130
|
|
|
868
1131
|
```typescript
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
code?: number;
|
|
875
|
-
type?: string;
|
|
876
|
-
};
|
|
877
|
-
}
|
|
1132
|
+
const formData = BaseService.createFormData(
|
|
1133
|
+
{ name: 'John', age: 0, active: false },
|
|
1134
|
+
'profileImage', // optional file field key
|
|
1135
|
+
imageFile // optional File object
|
|
1136
|
+
);
|
|
878
1137
|
```
|
|
879
1138
|
|
|
880
|
-
###
|
|
1139
|
+
### setBaseUrl / setLineUrl / setBlobUrl
|
|
881
1140
|
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
1141
|
+
Update base URLs at runtime (propagates to all sub-services):
|
|
1142
|
+
|
|
1143
|
+
```typescript
|
|
1144
|
+
bzbsService.setBaseUrl('https://new-api.buzzebees.com/api/');
|
|
1145
|
+
bzbsService.setLineUrl('https://api.line.me/');
|
|
1146
|
+
bzbsService.setBlobUrl('https://new-blob.buzzebees.com/');
|
|
1147
|
+
```
|
|
887
1148
|
|
|
888
1149
|
---
|
|
889
1150
|
|
|
890
|
-
##
|
|
1151
|
+
## Testing Guide
|
|
1152
|
+
|
|
1153
|
+
Tests are in the `tests/` directory, mirroring `src/` structure.
|
|
891
1154
|
|
|
892
|
-
|
|
1155
|
+
### Test Utilities (`tests/helpers/test-utils.ts`)
|
|
893
1156
|
|
|
894
1157
|
```typescript
|
|
895
1158
|
import {
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
} from '
|
|
1159
|
+
createMockClient,
|
|
1160
|
+
createSuccessResponse,
|
|
1161
|
+
createRawSuccessResponse,
|
|
1162
|
+
createServerErrorResponse,
|
|
1163
|
+
createAxiosError,
|
|
1164
|
+
createDeviceParams,
|
|
1165
|
+
} from '../helpers/test-utils';
|
|
1166
|
+
|
|
1167
|
+
// Create mocked Axios instance
|
|
1168
|
+
const { client, mockRequest } = createMockClient();
|
|
1169
|
+
|
|
1170
|
+
// Mock a wrapped success response: { Success: true, Data: {...} }
|
|
1171
|
+
mockRequest.mockResolvedValue(createSuccessResponse({ id: '123' }));
|
|
1172
|
+
|
|
1173
|
+
// Mock a raw success (no wrapper)
|
|
1174
|
+
mockRequest.mockResolvedValue(createRawSuccessResponse({ id: '123' }));
|
|
1175
|
+
|
|
1176
|
+
// Mock a server error response
|
|
1177
|
+
mockRequest.mockResolvedValue(createServerErrorResponse());
|
|
1178
|
+
|
|
1179
|
+
// Mock a network error (client error)
|
|
1180
|
+
mockRequest.mockRejectedValue(createAxiosError());
|
|
1181
|
+
|
|
1182
|
+
// Standard device parameters (appId, uuid, os, platform, clientVersion, macAddress, deviceToken, ...)
|
|
1183
|
+
const deviceParams = createDeviceParams();
|
|
903
1184
|
```
|
|
904
1185
|
|
|
905
|
-
###
|
|
1186
|
+
### Test Pattern
|
|
906
1187
|
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
| `Campaign` | Campaign list item (ID, name, points, dates, images) |
|
|
911
|
-
| `CampaignDetail` | Full campaign details with pictures, subcampaigns, conditions |
|
|
912
|
-
| `ProfileResponse` | User profile with personal info, address, shipping, marketing preferences |
|
|
913
|
-
| `Purchase` | Redeem history item with usage status, voucher info, delivery status |
|
|
914
|
-
| `Address` | User address with full Thailand address structure, tax fields |
|
|
915
|
-
| `Notification` | Push notification with object type, category, read status |
|
|
916
|
-
| `Place` | Store/place with location, services, working hours |
|
|
917
|
-
| `Dashboard` | Dashboard configuration item with images and metadata |
|
|
918
|
-
| `Consent` | User consent status for terms, privacy, marketing channels, cookies |
|
|
919
|
-
| `ConsentVersion` | PDPA consent version from blob storage |
|
|
920
|
-
| `Maintenance` | App maintenance configuration |
|
|
921
|
-
| `Badge` | User badge information |
|
|
922
|
-
| `Category` | Campaign category |
|
|
923
|
-
| `PointLog` | Point transaction record |
|
|
924
|
-
| `Stamp` | Stamp card information |
|
|
925
|
-
| `StampProfileResponse` | Stamp card profile details |
|
|
926
|
-
| `OtpResponse` | OTP request response with reference code |
|
|
927
|
-
| `ConfirmOtpResponse` | OTP confirmation result |
|
|
928
|
-
| `ValidateOtpResponse` | OTP validation result |
|
|
929
|
-
| `RedeemResponse` | Campaign redemption result |
|
|
930
|
-
| `FavoriteResponse` | Favorite toggle response |
|
|
931
|
-
| `UseCampaignResponse` | Coupon usage result |
|
|
932
|
-
| `CartCountResponse` | Cart item count |
|
|
933
|
-
| `CartAccessResponse` | Cart web landing access token |
|
|
934
|
-
| `AccessTokenResponse` | Web landing access token |
|
|
935
|
-
| `LineAuthResponse` | LINE OAuth token response |
|
|
936
|
-
| `AppleToken` | Apple refresh token response |
|
|
937
|
-
| `ResumeResponse` | Session resume/token refresh response |
|
|
938
|
-
| `Version` | App version info |
|
|
939
|
-
| `RegistrationResponse` | Registration result |
|
|
940
|
-
| `ForgetPasswordResponse` | Password reset request result |
|
|
941
|
-
| `StatusResponse` | Generic status response |
|
|
942
|
-
| `RequestHelpCode` | Help request code |
|
|
943
|
-
| `ChatMessage` | Forum/help chat message |
|
|
944
|
-
| `LikeForumResponse` | Forum like/unlike result |
|
|
945
|
-
| `Province` | Thailand province |
|
|
946
|
-
| `District` | Thailand district |
|
|
947
|
-
| `SubDistrict` | Thailand sub-district |
|
|
948
|
-
| `ZipCode` | Zip code information |
|
|
949
|
-
| `UpdatedPoints` | User points with timestamp |
|
|
950
|
-
| `ExpiringPoints` | User expiring points info |
|
|
951
|
-
| `PointUnit` | Point service unit configuration |
|
|
1188
|
+
```typescript
|
|
1189
|
+
import { AuthenticateApi } from '../../src/api/auth/auth-api';
|
|
1190
|
+
import { createMockClient, createSuccessResponse, createDeviceParams } from '../helpers/test-utils';
|
|
952
1191
|
|
|
953
|
-
|
|
1192
|
+
describe('AuthenticateApi', () => {
|
|
1193
|
+
let api: AuthenticateApi;
|
|
1194
|
+
let mockRequest: jest.Mock;
|
|
1195
|
+
|
|
1196
|
+
beforeEach(() => {
|
|
1197
|
+
const { client, mockRequest: mock } = createMockClient();
|
|
1198
|
+
mockRequest = mock;
|
|
1199
|
+
api = new AuthenticateApi(client, 'https://api.buzzebees.com/');
|
|
1200
|
+
});
|
|
1201
|
+
|
|
1202
|
+
it('deviceLogin returns success', async () => {
|
|
1203
|
+
const data = { Token: 'abc', UserId: '1' };
|
|
1204
|
+
mockRequest.mockResolvedValue(createSuccessResponse(data));
|
|
1205
|
+
|
|
1206
|
+
const result = await api.deviceLogin(createDeviceParams());
|
|
1207
|
+
|
|
1208
|
+
expect(result.type).toBe('success');
|
|
1209
|
+
if (result.type === 'success') {
|
|
1210
|
+
expect(result.model.Token).toBe('abc');
|
|
1211
|
+
}
|
|
1212
|
+
expect(mockRequest).toHaveBeenCalledWith(
|
|
1213
|
+
expect.objectContaining({ url: 'auth/device_login', method: 'post' })
|
|
1214
|
+
);
|
|
1215
|
+
});
|
|
1216
|
+
|
|
1217
|
+
it('deviceLogin handles server error', async () => {
|
|
1218
|
+
mockRequest.mockResolvedValue(createServerErrorResponse());
|
|
1219
|
+
|
|
1220
|
+
const result = await api.deviceLogin(createDeviceParams());
|
|
1221
|
+
|
|
1222
|
+
expect(result.type).toBe('server-error');
|
|
1223
|
+
});
|
|
1224
|
+
});
|
|
1225
|
+
```
|
|
954
1226
|
|
|
955
|
-
|
|
1227
|
+
### Run Tests
|
|
956
1228
|
|
|
957
|
-
|
|
1229
|
+
```bash
|
|
1230
|
+
npm test # Watch mode with coverage
|
|
1231
|
+
npx jest --coverage # Single run with coverage
|
|
1232
|
+
npx jest tests/api/auth # Run specific folder
|
|
1233
|
+
npx jest --testNamePattern otp # Run tests matching pattern
|
|
1234
|
+
```
|
|
958
1235
|
|
|
959
|
-
|
|
960
|
-
- npm
|
|
1236
|
+
---
|
|
961
1237
|
|
|
962
|
-
|
|
1238
|
+
## Development Commands
|
|
963
1239
|
|
|
964
1240
|
```bash
|
|
965
1241
|
# Install dependencies
|
|
966
1242
|
npm install
|
|
967
1243
|
|
|
968
|
-
# Build
|
|
1244
|
+
# Build (CJS + ESM + type declarations → dist/)
|
|
969
1245
|
npm run build
|
|
970
1246
|
|
|
971
1247
|
# Run tests in watch mode with coverage
|
|
@@ -979,20 +1255,18 @@ npm run lint:fix
|
|
|
979
1255
|
|
|
980
1256
|
# Format code with Prettier
|
|
981
1257
|
npm run format
|
|
982
|
-
```
|
|
983
1258
|
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
npm run
|
|
988
|
-
npm run minor # Build, bump minor version, publish
|
|
989
|
-
npm run major # Build, bump major version, publish
|
|
1259
|
+
# Publish (build + version bump + npm publish)
|
|
1260
|
+
npm run patch # 1.4.14 → 1.4.15
|
|
1261
|
+
npm run minor # 1.4.14 → 1.5.0
|
|
1262
|
+
npm run major # 1.4.14 → 2.0.0
|
|
990
1263
|
```
|
|
991
1264
|
|
|
992
|
-
|
|
1265
|
+
---
|
|
1266
|
+
|
|
1267
|
+
## Adding a New API
|
|
993
1268
|
|
|
994
|
-
1. Create
|
|
995
|
-
2. Create an API class that extends `BaseService`:
|
|
1269
|
+
1. Create `src/api/my-feature/my-feature-api.ts`:
|
|
996
1270
|
|
|
997
1271
|
```typescript
|
|
998
1272
|
import { AxiosInstance } from 'axios';
|
|
@@ -1005,31 +1279,35 @@ export class MyFeatureApi extends BaseService {
|
|
|
1005
1279
|
}
|
|
1006
1280
|
|
|
1007
1281
|
public async getItems(
|
|
1008
|
-
params: { id: string
|
|
1282
|
+
params: { id: string },
|
|
1009
1283
|
requestOptions?: RequestOptions
|
|
1010
1284
|
): Promise<ServiceResponse<MyModel[]>> {
|
|
1011
|
-
return await this.get<MyModel[]>(
|
|
1012
|
-
`my-feature/${params.id}`,
|
|
1013
|
-
{ ...params.options },
|
|
1014
|
-
requestOptions
|
|
1015
|
-
);
|
|
1285
|
+
return await this.get<MyModel[]>(`my-feature/${params.id}`, {}, requestOptions);
|
|
1016
1286
|
}
|
|
1017
1287
|
}
|
|
1018
1288
|
```
|
|
1019
1289
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1290
|
+
2. Create model interface in `src/models/my-model.ts` and export from `src/models/index.ts`
|
|
1291
|
+
3. Export from `src/api/index.ts`
|
|
1292
|
+
4. Add to `BzbsService` constructor and `setBaseUrl()` method in `src/api/bzbs-service.ts`
|
|
1023
1293
|
|
|
1024
1294
|
---
|
|
1025
1295
|
|
|
1026
1296
|
## Build Output
|
|
1027
1297
|
|
|
1028
|
-
The build process (tsup) generates:
|
|
1029
|
-
|
|
1030
1298
|
| File | Format | Description |
|
|
1031
1299
|
|---|---|---|
|
|
1032
1300
|
| `dist/index.js` | CommonJS | For `require()` usage |
|
|
1033
1301
|
| `dist/index.mjs` | ES Module | For `import` usage |
|
|
1034
1302
|
| `dist/index.d.ts` | TypeScript | Type declarations |
|
|
1035
1303
|
| `dist/*.map` | Source Maps | For debugging |
|
|
1304
|
+
|
|
1305
|
+
### Package Exports
|
|
1306
|
+
|
|
1307
|
+
```json
|
|
1308
|
+
{
|
|
1309
|
+
"main": "./dist/index.js",
|
|
1310
|
+
"module": "./dist/index.mjs",
|
|
1311
|
+
"types": "./dist/index.d.ts"
|
|
1312
|
+
}
|
|
1313
|
+
```
|