repzo 1.0.227 → 1.0.229
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 +34 -0
- package/changelog.md +5 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +59 -28
- package/lib/types/index.d.ts +10 -1
- package/package.json +1 -1
- package/src/index.ts +66 -28
- package/src/types/index.ts +16 -1
package/README.md
CHANGED
|
@@ -26,7 +26,21 @@ npm install repzo
|
|
|
26
26
|
|
|
27
27
|
```typescript
|
|
28
28
|
import Repzo from "repzo";
|
|
29
|
+
|
|
30
|
+
// Basic initialization
|
|
29
31
|
const repzo = new Repzo("my-repzo-api-key");
|
|
32
|
+
|
|
33
|
+
// With options (staging environment, custom timeout, retry logic)
|
|
34
|
+
const repzoWithOptions = new Repzo("my-repzo-api-key", {
|
|
35
|
+
env: "staging", // 'production', 'staging', or 'local'
|
|
36
|
+
timeout: 60000, // Request timeout in milliseconds
|
|
37
|
+
retryAttempts: 3, // Number of retry attempts (default: 3)
|
|
38
|
+
headers: {
|
|
39
|
+
"Custom-Header": "value",
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Find clients
|
|
30
44
|
let clients = repzo.client.find({ search: "Mecca" });
|
|
31
45
|
|
|
32
46
|
// Example usage with type safety
|
|
@@ -39,6 +53,26 @@ const params: Service.Client.Find.Params = {
|
|
|
39
53
|
// Your API implementation here
|
|
40
54
|
```
|
|
41
55
|
|
|
56
|
+
### Retry Logic
|
|
57
|
+
|
|
58
|
+
The SDK includes automatic retry logic for failed requests:
|
|
59
|
+
|
|
60
|
+
- **Default Behavior**: Automatically retries failed requests up to 3 times
|
|
61
|
+
- **Exponential Backoff**: Uses exponential backoff strategy (2^attempt seconds)
|
|
62
|
+
- **401 Protection**: Never retries on 401 (Unauthorized) errors
|
|
63
|
+
- **Configurable**: Set custom retry attempts via `retryAttempts` option
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
// Default: 3 retry attempts
|
|
67
|
+
const repzo = new Repzo("api-key");
|
|
68
|
+
|
|
69
|
+
// Custom: 5 retry attempts
|
|
70
|
+
const repzoCustom = new Repzo("api-key", { retryAttempts: 5 });
|
|
71
|
+
|
|
72
|
+
// Disable retries: 1 attempt only
|
|
73
|
+
const repzoNoRetry = new Repzo("api-key", { retryAttempts: 1 });
|
|
74
|
+
```
|
|
75
|
+
|
|
42
76
|
## 📖 Documentation
|
|
43
77
|
|
|
44
78
|
This SDK provides **three levels of documentation**:
|
package/changelog.md
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
### Added
|
|
6
6
|
|
|
7
|
+
- add: Automatic retry logic for HTTP requests with exponential backoff (default: 3 attempts, configurable via `retryAttempts` option)
|
|
8
|
+
- add: `retryAttempts` option to SDK constructor for configuring retry behavior @mkhamis
|
|
9
|
+
- add: 401 error protection - authentication errors are never retried @mkhamis
|
|
7
10
|
- add: asset-part-type, asset-part, asset-part-unit, asset-part-transfer, asset-part-receival, return-asset-part-unit & store-asset-part-unit @maramalshen
|
|
8
11
|
- update adjustInventory @maramalshen
|
|
9
12
|
- update FullInvoice with ubl keys @maramalshen
|
|
@@ -14,6 +17,8 @@
|
|
|
14
17
|
|
|
15
18
|
### Changed
|
|
16
19
|
|
|
20
|
+
- All HTTP methods (\_fetch, \_create, \_update, \_patch, \_delete) now support automatic retry with exponential backoff @mkhamis
|
|
21
|
+
|
|
17
22
|
### Fixed
|
|
18
23
|
|
|
19
24
|
### Removed
|
package/lib/index.d.ts
CHANGED
|
@@ -123,6 +123,7 @@ export default class Repzo {
|
|
|
123
123
|
private svAPIEndpoint;
|
|
124
124
|
headers: Headers;
|
|
125
125
|
private timeout;
|
|
126
|
+
private retryAttempts;
|
|
126
127
|
constructor(apiKey: string, options?: Options);
|
|
127
128
|
private static _end_points;
|
|
128
129
|
static get END_POINTS(): {
|
|
@@ -242,6 +243,7 @@ export default class Repzo {
|
|
|
242
243
|
readonly PROMOTIONS: "promotions";
|
|
243
244
|
readonly COMPARE_INVOICE_TO_WAREHOUSE: "compare-invoice-to-warehouse";
|
|
244
245
|
};
|
|
246
|
+
private _retryRequest;
|
|
245
247
|
private _fetch;
|
|
246
248
|
private _create;
|
|
247
249
|
private _update;
|
package/lib/index.js
CHANGED
|
@@ -2338,52 +2338,83 @@ class Repzo {
|
|
|
2338
2338
|
else {
|
|
2339
2339
|
this.timeout = 180000;
|
|
2340
2340
|
}
|
|
2341
|
+
this.retryAttempts = options?.retryAttempts ?? 3;
|
|
2341
2342
|
}
|
|
2342
2343
|
static get END_POINTS() {
|
|
2343
2344
|
return Repzo._end_points;
|
|
2344
2345
|
}
|
|
2345
|
-
async
|
|
2346
|
-
|
|
2347
|
-
|
|
2346
|
+
async _retryRequest(requestFn, attempt = 1) {
|
|
2347
|
+
try {
|
|
2348
|
+
return await requestFn();
|
|
2349
|
+
}
|
|
2350
|
+
catch (error) {
|
|
2351
|
+
// Don't retry on 401 (Unauthorized) errors
|
|
2352
|
+
if (error?.response?.status === 401) {
|
|
2353
|
+
throw error;
|
|
2354
|
+
}
|
|
2355
|
+
// Retry if we haven't exceeded the retry attempts
|
|
2356
|
+
if (attempt < this.retryAttempts) {
|
|
2357
|
+
// Exponential backoff: wait 2^attempt seconds before retrying
|
|
2358
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
2359
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
2360
|
+
return this._retryRequest(requestFn, attempt + 1);
|
|
2361
|
+
}
|
|
2362
|
+
// If all retries failed, throw the error
|
|
2363
|
+
throw error;
|
|
2348
2364
|
}
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2365
|
+
}
|
|
2366
|
+
async _fetch(baseUrl, path, params) {
|
|
2367
|
+
return this._retryRequest(async () => {
|
|
2368
|
+
if (params) {
|
|
2369
|
+
params = normalizeParams(params);
|
|
2370
|
+
}
|
|
2371
|
+
let res = await axios.get(`${baseUrl}/${path}`, {
|
|
2372
|
+
params,
|
|
2373
|
+
headers: this.headers,
|
|
2374
|
+
timeout: this.timeout,
|
|
2375
|
+
});
|
|
2376
|
+
return res.data;
|
|
2353
2377
|
});
|
|
2354
|
-
return res.data;
|
|
2355
2378
|
}
|
|
2356
2379
|
async _create(baseUrl, path, body, params) {
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2380
|
+
return this._retryRequest(async () => {
|
|
2381
|
+
let res = await axios.post(`${baseUrl}/${path}`, body, {
|
|
2382
|
+
params,
|
|
2383
|
+
headers: this.headers,
|
|
2384
|
+
timeout: this.timeout,
|
|
2385
|
+
});
|
|
2386
|
+
return res.data;
|
|
2361
2387
|
});
|
|
2362
|
-
return res.data;
|
|
2363
2388
|
}
|
|
2364
2389
|
async _update(baseUrl, path, body, params) {
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2390
|
+
return this._retryRequest(async () => {
|
|
2391
|
+
let res = await axios.put(`${baseUrl}/${path}`, body, {
|
|
2392
|
+
params,
|
|
2393
|
+
headers: this.headers,
|
|
2394
|
+
timeout: this.timeout,
|
|
2395
|
+
});
|
|
2396
|
+
return res.data;
|
|
2369
2397
|
});
|
|
2370
|
-
return res.data;
|
|
2371
2398
|
}
|
|
2372
2399
|
async _patch(baseUrl, path, body, params) {
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2400
|
+
return this._retryRequest(async () => {
|
|
2401
|
+
let res = await axios.put(`${baseUrl}/${path}`, body, {
|
|
2402
|
+
params,
|
|
2403
|
+
headers: this.headers,
|
|
2404
|
+
timeout: this.timeout,
|
|
2405
|
+
});
|
|
2406
|
+
return res.data;
|
|
2377
2407
|
});
|
|
2378
|
-
return res.data;
|
|
2379
2408
|
}
|
|
2380
2409
|
async _delete(baseUrl, path, params) {
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2410
|
+
return this._retryRequest(async () => {
|
|
2411
|
+
let res = await axios.delete(`${baseUrl}/${path}`, {
|
|
2412
|
+
params,
|
|
2413
|
+
headers: this.headers,
|
|
2414
|
+
timeout: this.timeout,
|
|
2415
|
+
});
|
|
2416
|
+
return res.data;
|
|
2385
2417
|
});
|
|
2386
|
-
return res.data;
|
|
2387
2418
|
}
|
|
2388
2419
|
}
|
|
2389
2420
|
Repzo._end_points = end_points;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface Options {
|
|
|
12
12
|
[key: string]: string;
|
|
13
13
|
};
|
|
14
14
|
timeout?: number | undefined;
|
|
15
|
+
retryAttempts?: number;
|
|
15
16
|
}
|
|
16
17
|
export interface Headers {
|
|
17
18
|
"api-key": string;
|
|
@@ -6631,6 +6632,8 @@ export declare namespace Service {
|
|
|
6631
6632
|
shipping_charge?: number;
|
|
6632
6633
|
payment_charge?: number;
|
|
6633
6634
|
total_with_charges?: number;
|
|
6635
|
+
media?: StringId[];
|
|
6636
|
+
signature?: StringId;
|
|
6634
6637
|
createdAt: string;
|
|
6635
6638
|
updatedAt: string;
|
|
6636
6639
|
__v: number;
|
|
@@ -6738,6 +6741,8 @@ export declare namespace Service {
|
|
|
6738
6741
|
shipping_charge?: number;
|
|
6739
6742
|
payment_charge?: number;
|
|
6740
6743
|
total_with_charges?: number;
|
|
6744
|
+
media?: StringId[];
|
|
6745
|
+
signature?: StringId;
|
|
6741
6746
|
}
|
|
6742
6747
|
export interface UpdateBody {
|
|
6743
6748
|
_id?: string;
|
|
@@ -6848,6 +6853,8 @@ export declare namespace Service {
|
|
|
6848
6853
|
shipping_charge?: number;
|
|
6849
6854
|
payment_charge?: number;
|
|
6850
6855
|
total_with_charges?: number;
|
|
6856
|
+
media?: StringId[];
|
|
6857
|
+
signature?: StringId;
|
|
6851
6858
|
createdAt?: string;
|
|
6852
6859
|
updatedAt?: string;
|
|
6853
6860
|
__v?: number;
|
|
@@ -7010,8 +7017,10 @@ export declare namespace Service {
|
|
|
7010
7017
|
return_reason?: string | ReturnReason.Schema;
|
|
7011
7018
|
teams?: string[] | Team.TeamSchema[];
|
|
7012
7019
|
route?: string | Route.RouteSchema;
|
|
7020
|
+
media?: StringId[] | PopulatedMediaStorage[];
|
|
7021
|
+
signature?: StringId | PopulatedMediaStorage;
|
|
7013
7022
|
};
|
|
7014
|
-
type PopulatedKeys = "custom_status" | "return_reason" | "teams" | "route";
|
|
7023
|
+
type PopulatedKeys = "custom_status" | "return_reason" | "teams" | "route" | "media" | "signature";
|
|
7015
7024
|
type ProformaStatus = "pending" | "approved" | "processing" | "rejected";
|
|
7016
7025
|
type VariantSortingKeys = "product_sku" | "product_barcode" | "variant_name" | "product_name" | "variant_sku" | "variant_barcode";
|
|
7017
7026
|
export namespace Find {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -230,6 +230,7 @@ export default class Repzo {
|
|
|
230
230
|
private svAPIEndpoint: string;
|
|
231
231
|
headers: Headers;
|
|
232
232
|
private timeout: number;
|
|
233
|
+
private retryAttempts: number;
|
|
233
234
|
constructor(apiKey: string, options?: Options) {
|
|
234
235
|
this.svAPIEndpoint =
|
|
235
236
|
!options?.env || options?.env == "production"
|
|
@@ -251,22 +252,51 @@ export default class Repzo {
|
|
|
251
252
|
} else {
|
|
252
253
|
this.timeout = 180000;
|
|
253
254
|
}
|
|
255
|
+
this.retryAttempts = options?.retryAttempts ?? 3;
|
|
254
256
|
}
|
|
255
257
|
|
|
256
258
|
private static _end_points = end_points;
|
|
257
259
|
public static get END_POINTS() {
|
|
258
260
|
return Repzo._end_points;
|
|
259
261
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
262
|
+
|
|
263
|
+
private async _retryRequest<T>(
|
|
264
|
+
requestFn: () => Promise<T>,
|
|
265
|
+
attempt: number = 1,
|
|
266
|
+
): Promise<T> {
|
|
267
|
+
try {
|
|
268
|
+
return await requestFn();
|
|
269
|
+
} catch (error: any) {
|
|
270
|
+
// Don't retry on 401 (Unauthorized) errors
|
|
271
|
+
if (error?.response?.status === 401) {
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Retry if we haven't exceeded the retry attempts
|
|
276
|
+
if (attempt < this.retryAttempts) {
|
|
277
|
+
// Exponential backoff: wait 2^attempt seconds before retrying
|
|
278
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
279
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
280
|
+
return this._retryRequest(requestFn, attempt + 1);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// If all retries failed, throw the error
|
|
284
|
+
throw error;
|
|
263
285
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
private async _fetch(baseUrl: string, path: string, params?: Params) {
|
|
289
|
+
return this._retryRequest(async () => {
|
|
290
|
+
if (params) {
|
|
291
|
+
params = normalizeParams(params);
|
|
292
|
+
}
|
|
293
|
+
let res: any = await axios.get(`${baseUrl}/${path}`, {
|
|
294
|
+
params,
|
|
295
|
+
headers: this.headers,
|
|
296
|
+
timeout: this.timeout,
|
|
297
|
+
});
|
|
298
|
+
return res.data;
|
|
268
299
|
});
|
|
269
|
-
return res.data;
|
|
270
300
|
}
|
|
271
301
|
|
|
272
302
|
private async _create(
|
|
@@ -275,12 +305,14 @@ export default class Repzo {
|
|
|
275
305
|
body: Data,
|
|
276
306
|
params?: Params,
|
|
277
307
|
) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
308
|
+
return this._retryRequest(async () => {
|
|
309
|
+
let res: any = await axios.post(`${baseUrl}/${path}`, body, {
|
|
310
|
+
params,
|
|
311
|
+
headers: this.headers,
|
|
312
|
+
timeout: this.timeout,
|
|
313
|
+
});
|
|
314
|
+
return res.data;
|
|
282
315
|
});
|
|
283
|
-
return res.data;
|
|
284
316
|
}
|
|
285
317
|
|
|
286
318
|
private async _update(
|
|
@@ -289,12 +321,14 @@ export default class Repzo {
|
|
|
289
321
|
body: Data,
|
|
290
322
|
params?: Params,
|
|
291
323
|
) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
324
|
+
return this._retryRequest(async () => {
|
|
325
|
+
let res: any = await axios.put(`${baseUrl}/${path}`, body, {
|
|
326
|
+
params,
|
|
327
|
+
headers: this.headers,
|
|
328
|
+
timeout: this.timeout,
|
|
329
|
+
});
|
|
330
|
+
return res.data;
|
|
296
331
|
});
|
|
297
|
-
return res.data;
|
|
298
332
|
}
|
|
299
333
|
|
|
300
334
|
private async _patch(
|
|
@@ -303,21 +337,25 @@ export default class Repzo {
|
|
|
303
337
|
body: Data,
|
|
304
338
|
params?: Params,
|
|
305
339
|
) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
340
|
+
return this._retryRequest(async () => {
|
|
341
|
+
let res: any = await axios.put(`${baseUrl}/${path}`, body, {
|
|
342
|
+
params,
|
|
343
|
+
headers: this.headers,
|
|
344
|
+
timeout: this.timeout,
|
|
345
|
+
});
|
|
346
|
+
return res.data;
|
|
310
347
|
});
|
|
311
|
-
return res.data;
|
|
312
348
|
}
|
|
313
349
|
|
|
314
350
|
private async _delete(baseUrl: string, path: string, params?: Params) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
351
|
+
return this._retryRequest(async () => {
|
|
352
|
+
let res: any = await axios.delete(`${baseUrl}/${path}`, {
|
|
353
|
+
params,
|
|
354
|
+
headers: this.headers,
|
|
355
|
+
timeout: this.timeout,
|
|
356
|
+
});
|
|
357
|
+
return res.data;
|
|
319
358
|
});
|
|
320
|
-
return res.data;
|
|
321
359
|
}
|
|
322
360
|
|
|
323
361
|
available_services = availableService;
|
package/src/types/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface Options {
|
|
|
11
11
|
env?: "staging" | "local" | "production";
|
|
12
12
|
headers?: { [key: string]: string };
|
|
13
13
|
timeout?: number | undefined;
|
|
14
|
+
retryAttempts?: number;
|
|
14
15
|
}
|
|
15
16
|
export interface Headers {
|
|
16
17
|
"api-key": string;
|
|
@@ -7191,6 +7192,8 @@ export namespace Service {
|
|
|
7191
7192
|
shipping_charge?: number;
|
|
7192
7193
|
payment_charge?: number;
|
|
7193
7194
|
total_with_charges?: number;
|
|
7195
|
+
media?: StringId[];
|
|
7196
|
+
signature?: StringId;
|
|
7194
7197
|
createdAt: string;
|
|
7195
7198
|
updatedAt: string;
|
|
7196
7199
|
__v: number;
|
|
@@ -7290,6 +7293,8 @@ export namespace Service {
|
|
|
7290
7293
|
shipping_charge?: number;
|
|
7291
7294
|
payment_charge?: number;
|
|
7292
7295
|
total_with_charges?: number;
|
|
7296
|
+
media?: StringId[];
|
|
7297
|
+
signature?: StringId;
|
|
7293
7298
|
}
|
|
7294
7299
|
export interface UpdateBody {
|
|
7295
7300
|
_id?: string;
|
|
@@ -7392,6 +7397,8 @@ export namespace Service {
|
|
|
7392
7397
|
shipping_charge?: number;
|
|
7393
7398
|
payment_charge?: number;
|
|
7394
7399
|
total_with_charges?: number;
|
|
7400
|
+
media?: StringId[];
|
|
7401
|
+
signature?: StringId;
|
|
7395
7402
|
createdAt?: string;
|
|
7396
7403
|
updatedAt?: string;
|
|
7397
7404
|
__v?: number;
|
|
@@ -7539,8 +7546,16 @@ export namespace Service {
|
|
|
7539
7546
|
return_reason?: string | ReturnReason.Schema;
|
|
7540
7547
|
teams?: string[] | Team.TeamSchema[];
|
|
7541
7548
|
route?: string | Route.RouteSchema;
|
|
7549
|
+
media?: StringId[] | PopulatedMediaStorage[];
|
|
7550
|
+
signature?: StringId | PopulatedMediaStorage;
|
|
7542
7551
|
};
|
|
7543
|
-
type PopulatedKeys =
|
|
7552
|
+
type PopulatedKeys =
|
|
7553
|
+
| "custom_status"
|
|
7554
|
+
| "return_reason"
|
|
7555
|
+
| "teams"
|
|
7556
|
+
| "route"
|
|
7557
|
+
| "media"
|
|
7558
|
+
| "signature";
|
|
7544
7559
|
type ProformaStatus = "pending" | "approved" | "processing" | "rejected";
|
|
7545
7560
|
type VariantSortingKeys =
|
|
7546
7561
|
| "product_sku"
|