pathao-merchant-sdk 2.0.1 → 2.1.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/CHANGELOG.md CHANGED
@@ -13,6 +13,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
13
13
 
14
14
  ## [Unreleased]
15
15
 
16
+ ## [2.0.2] - 2025-12-08
17
+
18
+ ### Added
19
+ - **Factory methods**: `PathaoApiService.fromEnv()` and `PathaoApiService.fromConfig()` for convenient initialization patterns
20
+ - **Debug logging**: Optional `debug` flag in constructor options to log all HTTP requests and responses
21
+ - **Configurable circuit breaker**: `circuitBreaker` option to customize failure threshold and timeout
22
+ - **Comprehensive error handling examples** in README with `PathaoApiError` usage patterns
23
+ - **Advanced options documentation** for factory methods and configuration
24
+
25
+ ### Changed
26
+ - **Breaking**: Deferred configuration validation to first API call instead of constructor throw. SDK now initializes successfully even without credentials, and throws `PathaoApiError` when attempting an API call with missing config.
27
+ - Removed config duplication in constructor (axios create config now uses resolved config values).
28
+ - Constructor now accepts optional `options` parameter: `new PathaoApiService(config, { debug?, circuitBreaker? })`
29
+ - Constructor no longer throws upfront, allowing graceful error handling at first API usage.
30
+
31
+ ### Fixed
32
+ - `ResolvedPathaoConfig` internal type ensures `timeout` is always a number.
33
+ - Tests updated to reflect deferred validation behavior.
34
+ - Circuit breaker now properly resets on successful requests and maintains configurable thresholds.
35
+
36
+ ### Verified
37
+ - `npm test` passes with 22/22 tests.
38
+ - Build succeeds (CJS/ESM/DTS).
39
+
16
40
  ## [2.0.1] - 2025-12-05
17
41
 
18
42
  ### Changed
package/README.md CHANGED
@@ -21,6 +21,7 @@ An **unofficial** TypeScript SDK for integrating with the Pathao Merchant API. T
21
21
  - [API Reference](#api-reference)
22
22
  - [Examples](#examples)
23
23
  - [Error Handling](#error-handling)
24
+ - [Webhooks](#webhooks)
24
25
  - [Authentication](#authentication)
25
26
  - [Official Documentation](#official-documentation)
26
27
  - [Contributing](#contributing)
@@ -37,6 +38,8 @@ An **unofficial** TypeScript SDK for integrating with the Pathao Merchant API. T
37
38
  - 🏪 **Store Management** - Create and manage pickup/service points
38
39
  - 💰 **Price Calculation** - Get accurate delivery charges before creating orders
39
40
  - 🌍 **Location Services** - Access cities, zones, and areas data
41
+ - 🔔 **Webhook Support** - Verify and handle inbound Pathao webhook events
42
+ - ♻️ **Retry & Circuit Breaker** - Automatic retry with backoff, circuit breaker for resilience
40
43
  - ⚡ **Built with Axios** - Reliable HTTP client with request/response interceptors
41
44
  - 🛡️ **Error Handling** - Comprehensive error handling with detailed error messages
42
45
  - 📚 **Well Documented** - Extensive documentation and examples
@@ -164,6 +167,56 @@ const pathao = new PathaoApiService({
164
167
  });
165
168
  ```
166
169
 
170
+ #### Factory Methods
171
+
172
+ The SDK provides convenient factory methods for common initialization patterns:
173
+
174
+ ```typescript
175
+ // Create from environment variables
176
+ const pathao = PathaoApiService.fromEnv();
177
+
178
+ // Create from environment with additional options
179
+ const pathao = PathaoApiService.fromEnv({
180
+ debug: true, // Enable debug logging
181
+ circuitBreaker: {
182
+ threshold: 10, // Number of failures before opening circuit (default: 5)
183
+ timeout: 120000 // Timeout before attempting to close circuit (default: 60000ms)
184
+ }
185
+ });
186
+
187
+ // Create from explicit config
188
+ const pathao = PathaoApiService.fromConfig({
189
+ baseURL: 'https://api-hermes.pathao.com',
190
+ clientId: 'client-id',
191
+ clientSecret: 'client-secret',
192
+ username: 'username',
193
+ password: 'password',
194
+ timeout: 5000
195
+ }, {
196
+ debug: true,
197
+ circuitBreaker: { threshold: 8 }
198
+ });
199
+ ```
200
+
201
+ #### Advanced Options
202
+
203
+ ```typescript
204
+ const pathao = new PathaoApiService(config, {
205
+ debug: false, // Enable detailed debug logging (default: false)
206
+ circuitBreaker: {
207
+ threshold: 5, // Failures before opening circuit (default: 5)
208
+ timeout: 60000 // Wait time before retry (default: 60000ms = 1 min)
209
+ }
210
+ });
211
+ ```
212
+
213
+ When `debug` is enabled, the SDK logs all HTTP requests and responses:
214
+
215
+ ```
216
+ [Pathao SDK] GET /aladdin/api/v1/stores { headers: {...}, data: {...} }
217
+ [Pathao SDK] Response 200 { url: '...', data: {...} }
218
+ ```
219
+
167
220
  ### Order Management
168
221
 
169
222
  #### Create Order
@@ -297,21 +350,225 @@ enum ItemType {
297
350
 
298
351
  ## Error Handling
299
352
 
300
- The SDK provides comprehensive error handling with detailed error messages:
353
+ The SDK provides comprehensive error handling through the `PathaoApiError` class, which extends Error with additional properties for detailed error information:
301
354
 
302
355
  ```typescript
356
+ import { PathaoApiService, PathaoApiError } from 'pathao-merchant-sdk';
357
+
358
+ const pathao = new PathaoApiService({
359
+ clientId: process.env.PATHAO_CLIENT_ID,
360
+ clientSecret: process.env.PATHAO_CLIENT_SECRET,
361
+ username: process.env.PATHAO_USERNAME,
362
+ password: process.env.PATHAO_PASSWORD
363
+ });
364
+
303
365
  try {
304
366
  const order = await pathao.createOrder(orderData);
367
+ console.log('Order created:', order.data.consignment_id);
368
+ } catch (error) {
369
+ // Check if it's a PathaoApiError (structured error from Pathao API)
370
+ if (error instanceof PathaoApiError) {
371
+ console.error('Pathao API Error:', {
372
+ status: error.status, // HTTP status code
373
+ code: error.code, // Pathao error code
374
+ type: error.type, // Error type (e.g., 'ValidationException')
375
+ message: error.message, // Error message
376
+ errors: error.errors, // Field-level errors
377
+ validation: error.validation // Validation errors
378
+ });
379
+ } else {
380
+ console.error('Unexpected error:', error.message);
381
+ }
382
+ }
383
+ ```
384
+
385
+ ### Error Properties
386
+
387
+ - **status**: HTTP status code (e.g., 400, 401, 422)
388
+ - **code**: Pathao API error code for programmatic handling
389
+ - **type**: Error type string (e.g., 'ValidationException', 'AuthenticationException')
390
+ - **errors**: Object with field-level error messages
391
+ - **validation**: Object with validation error messages
392
+ - **message**: Human-readable error message
393
+
394
+ ### Configuration Validation
395
+
396
+ Configuration validation is deferred until the first API call to allow gradual setup:
397
+
398
+ ```typescript
399
+ // This won't throw immediately
400
+ const pathao = new PathaoApiService({});
401
+
402
+ // This will throw PathaoApiError if credentials are missing
403
+ try {
404
+ await pathao.getStores();
305
405
  } catch (error) {
306
- console.error('Order creation failed:', error.message);
307
-
308
- // Check if it's a Pathao API error
309
- if (error.response?.data) {
310
- console.error('API Error:', error.response.data);
406
+ if (error instanceof PathaoApiError) {
407
+ console.error('Configuration error:', error.validation);
311
408
  }
312
409
  }
313
410
  ```
314
411
 
412
+ ## Webhooks
413
+
414
+ The `pathao-merchant-sdk/webhooks` sub-module handles inbound Pathao webhook events. It has **zero extra runtime dependencies** — only Node.js built-ins (`crypto`, `events`).
415
+
416
+ > **Note:** Pathao has no official webhook documentation. This implementation is based on reverse-engineering the [`pathao-courier`](https://www.npmjs.com/package/pathao-courier) package. The signature scheme is plain shared-secret equality (no HMAC) via constant-time comparison.
417
+
418
+ ### Installation
419
+
420
+ The webhooks module is a separate entry point. Import it explicitly:
421
+
422
+ ```typescript
423
+ import {
424
+ PathaoWebhookHandler,
425
+ constructEvent,
426
+ verifySignature,
427
+ PathaoWebhookEvent,
428
+ } from 'pathao-merchant-sdk/webhooks';
429
+ ```
430
+
431
+ ```javascript
432
+ // CommonJS
433
+ const { PathaoWebhookHandler } = require('pathao-merchant-sdk/webhooks');
434
+ ```
435
+
436
+ ### Quick verification
437
+
438
+ ```typescript
439
+ import { verifySignature } from 'pathao-merchant-sdk/webhooks';
440
+
441
+ const isValid = verifySignature(
442
+ req.headers['x-pathao-signature'],
443
+ process.env.PATHAO_WEBHOOK_SECRET!,
444
+ );
445
+ ```
446
+
447
+ ### Verify + parse in one call
448
+
449
+ ```typescript
450
+ import { constructEvent, PathaoWebhookError } from 'pathao-merchant-sdk/webhooks';
451
+
452
+ app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
453
+ try {
454
+ const payload = constructEvent(
455
+ req.body, // raw Buffer — do NOT pre-parse
456
+ req.headers,
457
+ process.env.PATHAO_WEBHOOK_SECRET!,
458
+ );
459
+ console.log('Event:', payload.event, payload.data);
460
+ res.sendStatus(200);
461
+ } catch (err) {
462
+ if (err instanceof PathaoWebhookError) {
463
+ res.status(400).send(err.message);
464
+ } else {
465
+ res.sendStatus(500);
466
+ }
467
+ }
468
+ });
469
+ ```
470
+
471
+ ### Express middleware
472
+
473
+ ```typescript
474
+ import { PathaoWebhookHandler, PathaoWebhookEvent } from 'pathao-merchant-sdk/webhooks';
475
+
476
+ const handler = new PathaoWebhookHandler(process.env.PATHAO_WEBHOOK_SECRET!);
477
+
478
+ // Listen for specific events (fully typed payload)
479
+ handler.on(PathaoWebhookEvent.ORDER_DELIVERED, (payload) => {
480
+ console.log('Delivered:', payload.consignment_id);
481
+ });
482
+
483
+ handler.on(PathaoWebhookEvent.ORDER_CANCELLED, (payload) => {
484
+ console.log('Cancelled:', payload.consignment_id, payload.reason);
485
+ });
486
+
487
+ // Catch all events
488
+ handler.on('webhook', (payload) => {
489
+ console.log('Any event:', payload.event, payload.data);
490
+ });
491
+
492
+ // Handle errors (invalid signature, bad JSON, etc.)
493
+ handler.on('error', (err) => {
494
+ console.error('Webhook error:', err.message);
495
+ });
496
+
497
+ // Mount — must use express.raw() BEFORE this middleware
498
+ app.post(
499
+ '/webhook/pathao',
500
+ express.raw({ type: 'application/json' }),
501
+ handler.expressMiddleware(),
502
+ );
503
+
504
+ // Access the parsed payload downstream
505
+ app.post('/webhook/pathao', express.raw({ type: 'application/json' }), handler.expressMiddleware(), (req, res) => {
506
+ console.log(req.pathaoWebhook); // typed PathaoWebhookPayload
507
+ res.sendStatus(200);
508
+ });
509
+ ```
510
+
511
+ ### Generic (non-Express) middleware
512
+
513
+ ```typescript
514
+ const handler = new PathaoWebhookHandler(process.env.PATHAO_WEBHOOK_SECRET!);
515
+ const middleware = handler.middleware();
516
+
517
+ // Returns { payload, error } — never rejects
518
+ const { payload, error } = await middleware(rawBody, headers);
519
+ if (error) {
520
+ console.error('Bad webhook:', error.message);
521
+ } else {
522
+ console.log('Event:', payload!.event);
523
+ }
524
+ ```
525
+
526
+ ### Supported event types
527
+
528
+ | Event constant | Event string |
529
+ |---|---|
530
+ | `ORDER_CREATED` | `order.created` |
531
+ | `ORDER_ACCEPTED` | `order.accepted` |
532
+ | `ORDER_PICKUP_REQUESTED` | `order.pickup_requested` |
533
+ | `ORDER_PICKED` | `order.picked` |
534
+ | `ORDER_IN_TRANSIT` | `order.in_transit` |
535
+ | `ORDER_DELIVERED` | `order.delivered` |
536
+ | `ORDER_CANCELLED` | `order.cancelled` |
537
+ | `ORDER_HOLD` | `order.hold` |
538
+ | `ORDER_RETURN_REQUESTED` | `order.return_requested` |
539
+ | `ORDER_RETURN_PICKUP_REQUESTED` | `order.return_pickup_requested` |
540
+ | `ORDER_RETURN_PICKED` | `order.return_picked` |
541
+ | `ORDER_RETURN_IN_TRANSIT` | `order.return_in_transit` |
542
+ | `ORDER_PARTIAL_DELIVERED` | `order.partial_delivered` |
543
+ | `ORDER_DELIVERY_FAILED` | `order.delivery_failed` |
544
+ | `ORDER_ON_HOLD` | `order.on_hold` |
545
+ | `ORDER_PAID` | `order.paid` |
546
+ | `ORDER_PAID_RETURN` | `order.paid_return` |
547
+ | `ORDER_RETURNED` | `order.returned` |
548
+ | `ORDER_EXCHANGED` | `order.exchanged` |
549
+ | `STORE_CREATED` | `store.created` |
550
+ | `STORE_UPDATED` | `store.updated` |
551
+
552
+ ### TypeScript types
553
+
554
+ All event payloads are fully typed. Access them via `WebhookEventPayloadMap`:
555
+
556
+ ```typescript
557
+ import type {
558
+ WebhookEventPayloadMap,
559
+ PathaoWebhookEvent,
560
+ OrderDeliveredPayload,
561
+ } from 'pathao-merchant-sdk/webhooks';
562
+
563
+ // Explicit payload type
564
+ const handler = (payload: OrderDeliveredPayload) => {
565
+ console.log(payload.consignment_id, payload.amount_to_collect);
566
+ };
567
+
568
+ // Via mapped type
569
+ type DeliveredPayload = WebhookEventPayloadMap[PathaoWebhookEvent.ORDER_DELIVERED];
570
+ ```
571
+
315
572
  ## Authentication
316
573
 
317
574
  The SDK automatically handles OAuth2 authentication and token refresh. You only need to provide your credentials once during initialization:
@@ -417,6 +674,28 @@ This is an **unofficial** SDK and is not affiliated with or endorsed by Pathao.
417
674
 
418
675
  ## Changelog
419
676
 
677
+ ### 2.1.0
678
+ - Added webhook support via `pathao-merchant-sdk/webhooks` sub-path
679
+ - `PathaoWebhookHandler` — EventEmitter with typed `on()` overloads for all 21 event types
680
+ - `constructEvent()` and `verifySignature()` standalone helpers
681
+ - Express middleware and generic async middleware
682
+ - Constant-time signature comparison via `crypto.timingSafeEqual`
683
+ - Fixed case-insensitive header lookup for `X-PATHAO-Signature`
684
+
685
+ ### 2.0.x
686
+ - Added retry logic: 429 reads `Retry-After`, 5xx exponential backoff (max 2 retries)
687
+ - Added circuit breaker: throws `PathaoApiError` (code 503) when open
688
+ - Added `sandbox()` and `production()` named constructors
689
+ - Deferred config validation to first API call
690
+ - HTTPS-only enforcement in `validateConfiguration()`
691
+ - Auth token redacted as `Bearer [REDACTED]` in debug logs
692
+ - Added `User-Agent: pathao-merchant-sdk node/<version>` header
693
+ - `getStores()` accepts optional `page` parameter
694
+ - `validateContactNumber` requires `startsWith('01')`
695
+ - `is_active` and `cod_enabled` typed as `0 | 1`
696
+ - Fixed shell injection in `scripts/release.js` (replaced `execSync` with `spawnSync`)
697
+ - CI/CD: replaced deprecated actions, added version-existence check before publish
698
+
420
699
  ### 1.0.0
421
700
  - Initial release
422
701
  - Complete Pathao API integration
package/dist/index.d.mts CHANGED
@@ -65,7 +65,7 @@ interface PathaoStore {
65
65
  store_id: number;
66
66
  store_name: string;
67
67
  store_address: string;
68
- is_active: number;
68
+ is_active: 0 | 1;
69
69
  city_id: number;
70
70
  zone_id: number;
71
71
  hub_id: number;
@@ -107,7 +107,7 @@ interface PathaoPriceResponse {
107
107
  discount: number;
108
108
  promo_discount: number;
109
109
  plan_id: number;
110
- cod_enabled: number;
110
+ cod_enabled: 0 | 1;
111
111
  cod_percentage: number;
112
112
  additional_charge: number;
113
113
  final_price: number;
@@ -176,14 +176,27 @@ interface PathaoError {
176
176
  errors?: Record<string, string[]>;
177
177
  validation?: Record<string, string[]>;
178
178
  }
179
+ /**
180
+ * Delivery type codes defined by the Pathao API.
181
+ * Values correspond to Pathao's internal delivery_type IDs.
182
+ * @see https://developers.pathao.com - Order Creation endpoint
183
+ */
179
184
  declare enum DeliveryType {
185
+ /** Standard delivery (API value: 48) */
180
186
  NORMAL = 48,
187
+ /** Same-day on-demand delivery (API value: 12) */
181
188
  ON_DEMAND = 12
182
189
  }
183
190
  declare enum ItemType {
184
191
  DOCUMENT = 1,
185
192
  PARCEL = 2
186
193
  }
194
+ interface PathaoBulkOrderResponse {
195
+ message: string;
196
+ type: string;
197
+ code: number;
198
+ data: boolean;
199
+ }
187
200
 
188
201
  /**
189
202
  * Pathao Merchant API Service (Unofficial SDK)
@@ -221,6 +234,10 @@ declare class PathaoApiError extends Error {
221
234
  responseData?: unknown;
222
235
  });
223
236
  }
237
+ interface CircuitBreakerConfig {
238
+ threshold?: number;
239
+ timeout?: number;
240
+ }
224
241
  declare class PathaoApiService {
225
242
  private pathaoClient;
226
243
  private accessToken;
@@ -229,31 +246,31 @@ declare class PathaoApiService {
229
246
  private config;
230
247
  private isAuthenticating;
231
248
  private authPromise;
232
- private requestQueue;
249
+ private hasValidated;
250
+ private debug;
233
251
  private circuitBreaker;
234
- constructor(config: PathaoConfig);
252
+ constructor(config: PathaoConfig, options?: {
253
+ debug?: boolean;
254
+ circuitBreaker?: CircuitBreakerConfig;
255
+ });
256
+ private validateConfiguration;
235
257
  private ensureAuthenticated;
236
258
  private performAuthentication;
237
- private processRequestQueue;
238
259
  private authenticate;
239
260
  private refreshAccessToken;
240
261
  private getErrorMessage;
241
262
  private toPathaoApiError;
242
263
  private handleCircuitBreaker;
264
+ private delay;
243
265
  createOrder(orderData: PathaoOrderRequest): Promise<PathaoOrderResponse>;
244
266
  createStore(storeData: PathaoStoreRequest): Promise<PathaoStoreCreateResponse>;
245
- getStores(): Promise<PathaoStoreListResponse>;
267
+ getStores(page?: number): Promise<PathaoStoreListResponse>;
246
268
  calculatePrice(priceData: PathaoPriceRequest): Promise<PathaoPriceResponse>;
247
269
  getCities(): Promise<PathaoCityResponse>;
248
270
  getZones(cityId: number): Promise<PathaoZoneResponse>;
249
271
  getAreas(zoneId: number): Promise<PathaoAreaResponse>;
250
272
  getOrderStatus(consignmentId: string): Promise<PathaoOrderStatusResponse>;
251
- createBulkOrder(orders: PathaoOrderRequest[]): Promise<{
252
- message: string;
253
- type: string;
254
- code: number;
255
- data: boolean;
256
- }>;
273
+ createBulkOrder(orders: PathaoOrderRequest[]): Promise<PathaoBulkOrderResponse>;
257
274
  static validatePhoneNumber(phone: string): boolean;
258
275
  static formatPhoneNumber(phone: string): string;
259
276
  static validateAddress(address: string): boolean;
@@ -264,6 +281,22 @@ declare class PathaoApiService {
264
281
  static validateContactNumber(phone: string): boolean;
265
282
  static validateStoreAddress(address: string): boolean;
266
283
  clearAuth(): void;
284
+ static fromEnv(options?: {
285
+ debug?: boolean;
286
+ circuitBreaker?: CircuitBreakerConfig;
287
+ }): PathaoApiService;
288
+ static fromConfig(config: PathaoConfig, options?: {
289
+ debug?: boolean;
290
+ circuitBreaker?: CircuitBreakerConfig;
291
+ }): PathaoApiService;
292
+ static sandbox(credentials: Omit<PathaoConfig, 'baseURL'>, options?: {
293
+ debug?: boolean;
294
+ circuitBreaker?: CircuitBreakerConfig;
295
+ }): PathaoApiService;
296
+ static production(credentials: Omit<PathaoConfig, 'baseURL'>, options?: {
297
+ debug?: boolean;
298
+ circuitBreaker?: CircuitBreakerConfig;
299
+ }): PathaoApiService;
267
300
  }
268
301
 
269
- export { DeliveryType, ItemType, PathaoApiError, PathaoApiService, type PathaoAreaResponse, type PathaoAuthResponse, type PathaoCityResponse, type PathaoConfig, type PathaoError, type PathaoOrderRequest, type PathaoOrderResponse, type PathaoOrderStatusResponse, type PathaoPriceRequest, type PathaoPriceResponse, type PathaoStore, type PathaoStoreCreateResponse, type PathaoStoreListResponse, type PathaoStoreRequest, type PathaoZoneResponse };
302
+ export { type CircuitBreakerConfig, DeliveryType, ItemType, PathaoApiError, PathaoApiService, type PathaoAreaResponse, type PathaoAuthResponse, type PathaoBulkOrderResponse, type PathaoCityResponse, type PathaoConfig, type PathaoError, type PathaoOrderRequest, type PathaoOrderResponse, type PathaoOrderStatusResponse, type PathaoPriceRequest, type PathaoPriceResponse, type PathaoStore, type PathaoStoreCreateResponse, type PathaoStoreListResponse, type PathaoStoreRequest, type PathaoZoneResponse };
package/dist/index.d.ts CHANGED
@@ -65,7 +65,7 @@ interface PathaoStore {
65
65
  store_id: number;
66
66
  store_name: string;
67
67
  store_address: string;
68
- is_active: number;
68
+ is_active: 0 | 1;
69
69
  city_id: number;
70
70
  zone_id: number;
71
71
  hub_id: number;
@@ -107,7 +107,7 @@ interface PathaoPriceResponse {
107
107
  discount: number;
108
108
  promo_discount: number;
109
109
  plan_id: number;
110
- cod_enabled: number;
110
+ cod_enabled: 0 | 1;
111
111
  cod_percentage: number;
112
112
  additional_charge: number;
113
113
  final_price: number;
@@ -176,14 +176,27 @@ interface PathaoError {
176
176
  errors?: Record<string, string[]>;
177
177
  validation?: Record<string, string[]>;
178
178
  }
179
+ /**
180
+ * Delivery type codes defined by the Pathao API.
181
+ * Values correspond to Pathao's internal delivery_type IDs.
182
+ * @see https://developers.pathao.com - Order Creation endpoint
183
+ */
179
184
  declare enum DeliveryType {
185
+ /** Standard delivery (API value: 48) */
180
186
  NORMAL = 48,
187
+ /** Same-day on-demand delivery (API value: 12) */
181
188
  ON_DEMAND = 12
182
189
  }
183
190
  declare enum ItemType {
184
191
  DOCUMENT = 1,
185
192
  PARCEL = 2
186
193
  }
194
+ interface PathaoBulkOrderResponse {
195
+ message: string;
196
+ type: string;
197
+ code: number;
198
+ data: boolean;
199
+ }
187
200
 
188
201
  /**
189
202
  * Pathao Merchant API Service (Unofficial SDK)
@@ -221,6 +234,10 @@ declare class PathaoApiError extends Error {
221
234
  responseData?: unknown;
222
235
  });
223
236
  }
237
+ interface CircuitBreakerConfig {
238
+ threshold?: number;
239
+ timeout?: number;
240
+ }
224
241
  declare class PathaoApiService {
225
242
  private pathaoClient;
226
243
  private accessToken;
@@ -229,31 +246,31 @@ declare class PathaoApiService {
229
246
  private config;
230
247
  private isAuthenticating;
231
248
  private authPromise;
232
- private requestQueue;
249
+ private hasValidated;
250
+ private debug;
233
251
  private circuitBreaker;
234
- constructor(config: PathaoConfig);
252
+ constructor(config: PathaoConfig, options?: {
253
+ debug?: boolean;
254
+ circuitBreaker?: CircuitBreakerConfig;
255
+ });
256
+ private validateConfiguration;
235
257
  private ensureAuthenticated;
236
258
  private performAuthentication;
237
- private processRequestQueue;
238
259
  private authenticate;
239
260
  private refreshAccessToken;
240
261
  private getErrorMessage;
241
262
  private toPathaoApiError;
242
263
  private handleCircuitBreaker;
264
+ private delay;
243
265
  createOrder(orderData: PathaoOrderRequest): Promise<PathaoOrderResponse>;
244
266
  createStore(storeData: PathaoStoreRequest): Promise<PathaoStoreCreateResponse>;
245
- getStores(): Promise<PathaoStoreListResponse>;
267
+ getStores(page?: number): Promise<PathaoStoreListResponse>;
246
268
  calculatePrice(priceData: PathaoPriceRequest): Promise<PathaoPriceResponse>;
247
269
  getCities(): Promise<PathaoCityResponse>;
248
270
  getZones(cityId: number): Promise<PathaoZoneResponse>;
249
271
  getAreas(zoneId: number): Promise<PathaoAreaResponse>;
250
272
  getOrderStatus(consignmentId: string): Promise<PathaoOrderStatusResponse>;
251
- createBulkOrder(orders: PathaoOrderRequest[]): Promise<{
252
- message: string;
253
- type: string;
254
- code: number;
255
- data: boolean;
256
- }>;
273
+ createBulkOrder(orders: PathaoOrderRequest[]): Promise<PathaoBulkOrderResponse>;
257
274
  static validatePhoneNumber(phone: string): boolean;
258
275
  static formatPhoneNumber(phone: string): string;
259
276
  static validateAddress(address: string): boolean;
@@ -264,6 +281,22 @@ declare class PathaoApiService {
264
281
  static validateContactNumber(phone: string): boolean;
265
282
  static validateStoreAddress(address: string): boolean;
266
283
  clearAuth(): void;
284
+ static fromEnv(options?: {
285
+ debug?: boolean;
286
+ circuitBreaker?: CircuitBreakerConfig;
287
+ }): PathaoApiService;
288
+ static fromConfig(config: PathaoConfig, options?: {
289
+ debug?: boolean;
290
+ circuitBreaker?: CircuitBreakerConfig;
291
+ }): PathaoApiService;
292
+ static sandbox(credentials: Omit<PathaoConfig, 'baseURL'>, options?: {
293
+ debug?: boolean;
294
+ circuitBreaker?: CircuitBreakerConfig;
295
+ }): PathaoApiService;
296
+ static production(credentials: Omit<PathaoConfig, 'baseURL'>, options?: {
297
+ debug?: boolean;
298
+ circuitBreaker?: CircuitBreakerConfig;
299
+ }): PathaoApiService;
267
300
  }
268
301
 
269
- export { DeliveryType, ItemType, PathaoApiError, PathaoApiService, type PathaoAreaResponse, type PathaoAuthResponse, type PathaoCityResponse, type PathaoConfig, type PathaoError, type PathaoOrderRequest, type PathaoOrderResponse, type PathaoOrderStatusResponse, type PathaoPriceRequest, type PathaoPriceResponse, type PathaoStore, type PathaoStoreCreateResponse, type PathaoStoreListResponse, type PathaoStoreRequest, type PathaoZoneResponse };
302
+ export { type CircuitBreakerConfig, DeliveryType, ItemType, PathaoApiError, PathaoApiService, type PathaoAreaResponse, type PathaoAuthResponse, type PathaoBulkOrderResponse, type PathaoCityResponse, type PathaoConfig, type PathaoError, type PathaoOrderRequest, type PathaoOrderResponse, type PathaoOrderStatusResponse, type PathaoPriceRequest, type PathaoPriceResponse, type PathaoStore, type PathaoStoreCreateResponse, type PathaoStoreListResponse, type PathaoStoreRequest, type PathaoZoneResponse };