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