@oxyhq/services 5.13.24 → 5.13.25
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/lib/commonjs/core/RequestManager.js +2 -31
- package/lib/commonjs/core/RequestManager.js.map +1 -1
- package/lib/commonjs/ui/components/FollowButton.js +0 -53
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/utils/asyncUtils.js +23 -3
- package/lib/commonjs/utils/asyncUtils.js.map +1 -1
- package/lib/commonjs/utils/errorUtils.js +13 -18
- package/lib/commonjs/utils/errorUtils.js.map +1 -1
- package/lib/commonjs/utils/validationUtils.js +15 -0
- package/lib/commonjs/utils/validationUtils.js.map +1 -1
- package/lib/module/core/RequestManager.js +2 -31
- package/lib/module/core/RequestManager.js.map +1 -1
- package/lib/module/ui/components/FollowButton.js +1 -54
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/utils/asyncUtils.js +24 -3
- package/lib/module/utils/asyncUtils.js.map +1 -1
- package/lib/module/utils/errorUtils.js +7 -18
- package/lib/module/utils/errorUtils.js.map +1 -1
- package/lib/module/utils/validationUtils.js +14 -0
- package/lib/module/utils/validationUtils.js.map +1 -1
- package/lib/typescript/core/RequestManager.d.ts +0 -4
- package/lib/typescript/core/RequestManager.d.ts.map +1 -1
- package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/utils/asyncUtils.d.ts +4 -0
- package/lib/typescript/utils/asyncUtils.d.ts.map +1 -1
- package/lib/typescript/utils/errorUtils.d.ts +9 -1
- package/lib/typescript/utils/errorUtils.d.ts.map +1 -1
- package/lib/typescript/utils/validationUtils.d.ts +6 -0
- package/lib/typescript/utils/validationUtils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/RequestManager.ts +2 -37
- package/src/ui/components/FollowButton.tsx +0 -53
- package/src/utils/asyncUtils.ts +23 -3
- package/src/utils/errorUtils.ts +7 -26
- package/src/utils/validationUtils.ts +14 -0
|
@@ -4,8 +4,11 @@
|
|
|
4
4
|
* Async utilities for common asynchronous patterns and error handling
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { logger } from './loggerUtils';
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* Wrapper for async operations with automatic error handling
|
|
11
|
+
* Returns null on error instead of throwing
|
|
9
12
|
*/
|
|
10
13
|
export async function withErrorHandling(operation, errorHandler, context) {
|
|
11
14
|
try {
|
|
@@ -14,7 +17,10 @@ export async function withErrorHandling(operation, errorHandler, context) {
|
|
|
14
17
|
if (errorHandler) {
|
|
15
18
|
errorHandler(error);
|
|
16
19
|
} else {
|
|
17
|
-
|
|
20
|
+
logger.error(`Error in ${context || 'operation'}`, error instanceof Error ? error : new Error(String(error)), {
|
|
21
|
+
component: 'asyncUtils',
|
|
22
|
+
method: 'withErrorHandling'
|
|
23
|
+
});
|
|
18
24
|
}
|
|
19
25
|
return null;
|
|
20
26
|
}
|
|
@@ -30,9 +36,22 @@ export async function parallelWithErrorHandling(operations, errorHandler) {
|
|
|
30
36
|
|
|
31
37
|
/**
|
|
32
38
|
* Retry an async operation with exponential backoff
|
|
39
|
+
*
|
|
40
|
+
* By default, does not retry on 4xx errors (client errors).
|
|
41
|
+
* Use shouldRetry callback to customize retry behavior.
|
|
33
42
|
*/
|
|
34
43
|
export async function retryAsync(operation, maxRetries = 3, baseDelay = 1000, shouldRetry) {
|
|
35
44
|
let lastError;
|
|
45
|
+
|
|
46
|
+
// Default shouldRetry: don't retry on 4xx errors
|
|
47
|
+
const defaultShouldRetry = error => {
|
|
48
|
+
// Don't retry on 4xx errors (client errors)
|
|
49
|
+
if (error?.response?.status >= 400 && error?.response?.status < 500) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
};
|
|
54
|
+
const retryCheck = shouldRetry || defaultShouldRetry;
|
|
36
55
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
37
56
|
try {
|
|
38
57
|
return await operation();
|
|
@@ -41,10 +60,12 @@ export async function retryAsync(operation, maxRetries = 3, baseDelay = 1000, sh
|
|
|
41
60
|
if (attempt === maxRetries) {
|
|
42
61
|
break;
|
|
43
62
|
}
|
|
44
|
-
if (
|
|
63
|
+
if (!retryCheck(error)) {
|
|
45
64
|
break;
|
|
46
65
|
}
|
|
47
|
-
|
|
66
|
+
|
|
67
|
+
// Calculate delay with exponential backoff and jitter
|
|
68
|
+
const delay = baseDelay * Math.pow(2, attempt) + Math.random() * 1000;
|
|
48
69
|
await new Promise(resolve => setTimeout(resolve, delay));
|
|
49
70
|
}
|
|
50
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["withErrorHandling","operation","errorHandler","context","error","
|
|
1
|
+
{"version":3,"names":["logger","withErrorHandling","operation","errorHandler","context","error","Error","String","component","method","parallelWithErrorHandling","operations","results","Promise","allSettled","map","op","index","result","status","value","retryAsync","maxRetries","baseDelay","shouldRetry","lastError","defaultShouldRetry","response","retryCheck","attempt","delay","Math","pow","random","resolve","setTimeout","debounceAsync","func","timeoutId","lastPromise","args","reject","clearTimeout","throttleAsync","limit","interval","inThrottle","sequentialWithProgress","onProgress","i","length","push","batchAsync","items","batchSize","processor","batch","slice","createCancellableAsync","abortController","execute","AbortController","signal","cancel","abort","withTimeout","timeoutMs","timeoutMessage","timeoutPromise","_","race","withLoadingState","setLoading","ms","retryOnError","retryableErrors","errorCode","code","message","includes"],"sourceRoot":"../../../src","sources":["utils/asyncUtils.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -15,6 +15,7 @@ export const ErrorCodes = {
|
|
|
15
15
|
MISSING_TOKEN: 'MISSING_TOKEN',
|
|
16
16
|
// Validation errors
|
|
17
17
|
VALIDATION_ERROR: 'VALIDATION_ERROR',
|
|
18
|
+
BAD_REQUEST: 'BAD_REQUEST',
|
|
18
19
|
MISSING_PARAMETER: 'MISSING_PARAMETER',
|
|
19
20
|
INVALID_FORMAT: 'INVALID_FORMAT',
|
|
20
21
|
// Resource errors
|
|
@@ -79,11 +80,12 @@ export function handleHttpError(error) {
|
|
|
79
80
|
|
|
80
81
|
/**
|
|
81
82
|
* Get error code from HTTP status
|
|
83
|
+
* Exported for use in other modules
|
|
82
84
|
*/
|
|
83
|
-
function getErrorCodeFromStatus(status) {
|
|
85
|
+
export function getErrorCodeFromStatus(status) {
|
|
84
86
|
switch (status) {
|
|
85
87
|
case 400:
|
|
86
|
-
return ErrorCodes.
|
|
88
|
+
return ErrorCodes.BAD_REQUEST;
|
|
87
89
|
case 401:
|
|
88
90
|
return ErrorCodes.UNAUTHORIZED;
|
|
89
91
|
case 403:
|
|
@@ -127,21 +129,8 @@ export function logError(error, context) {
|
|
|
127
129
|
|
|
128
130
|
/**
|
|
129
131
|
* Retry function with exponential backoff
|
|
132
|
+
* Re-exports retryAsync for backward compatibility
|
|
133
|
+
* @deprecated Use retryAsync from asyncUtils instead
|
|
130
134
|
*/
|
|
131
|
-
export
|
|
132
|
-
let lastError;
|
|
133
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
134
|
-
try {
|
|
135
|
-
return await fn();
|
|
136
|
-
} catch (error) {
|
|
137
|
-
lastError = error;
|
|
138
|
-
if (attempt === maxRetries) {
|
|
139
|
-
break;
|
|
140
|
-
}
|
|
141
|
-
const delay = baseDelay * 2 ** attempt;
|
|
142
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
throw lastError;
|
|
146
|
-
}
|
|
135
|
+
export { retryAsync as retryWithBackoff } from './asyncUtils';
|
|
147
136
|
//# sourceMappingURL=errorUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ErrorCodes","UNAUTHORIZED","FORBIDDEN","INVALID_TOKEN","MISSING_TOKEN","VALIDATION_ERROR","MISSING_PARAMETER","INVALID_FORMAT","NOT_FOUND","ALREADY_EXISTS","CONFLICT","INTERNAL_ERROR","SERVICE_UNAVAILABLE","TIMEOUT","NETWORK_ERROR","CONNECTION_FAILED","createApiError","message","code","status","details","handleHttpError","error","axiosError","response","data","getErrorCodeFromStatus","Error","String","validateRequiredFields","fields","missing","filter","field","length","join","logError","context","prefix","console","stack","
|
|
1
|
+
{"version":3,"names":["ErrorCodes","UNAUTHORIZED","FORBIDDEN","INVALID_TOKEN","MISSING_TOKEN","VALIDATION_ERROR","BAD_REQUEST","MISSING_PARAMETER","INVALID_FORMAT","NOT_FOUND","ALREADY_EXISTS","CONFLICT","INTERNAL_ERROR","SERVICE_UNAVAILABLE","TIMEOUT","NETWORK_ERROR","CONNECTION_FAILED","createApiError","message","code","status","details","handleHttpError","error","axiosError","response","data","getErrorCodeFromStatus","Error","String","validateRequiredFields","fields","missing","filter","field","length","join","logError","context","prefix","console","stack","retryAsync","retryWithBackoff"],"sourceRoot":"../../../src","sources":["utils/errorUtils.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -134,6 +134,20 @@ export function sanitizeHTML(input) {
|
|
|
134
134
|
return input.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Validate MongoDB ObjectId format
|
|
139
|
+
* Note: This is a basic format check. For full validation, use mongoose.Types.ObjectId.isValid()
|
|
140
|
+
* This function works in environments where mongoose may not be available (e.g., client-side)
|
|
141
|
+
*/
|
|
142
|
+
export function isValidObjectId(id) {
|
|
143
|
+
if (typeof id !== 'string') {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
// MongoDB ObjectId is 24 hex characters
|
|
147
|
+
const OBJECT_ID_REGEX = /^[0-9a-fA-F]{24}$/;
|
|
148
|
+
return OBJECT_ID_REGEX.test(id);
|
|
149
|
+
}
|
|
150
|
+
|
|
137
151
|
/**
|
|
138
152
|
* Validate and sanitize user input
|
|
139
153
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["EMAIL_REGEX","USERNAME_REGEX","PASSWORD_REGEX","isValidEmail","email","test","isValidUsername","username","isValidPassword","password","isRequiredString","value","trim","length","isRequiredNumber","Number","isNaN","isRequiredBoolean","isValidArray","Array","isArray","isValidObject","isValidUUID","uuid","UUID_REGEX","isValidURL","url","URL","isValidDate","dateString","date","Date","getTime","isValidFileSize","size","maxSize","isValidFileType","filename","allowedTypes","extension","split","pop","toLowerCase","includes","sanitizeString","input","replace","sanitizeHTML","validateAndSanitizeUserInput","type","sanitized"],"sourceRoot":"../../../src","sources":["utils/validationUtils.ts"],"mappings":";;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,MAAMA,WAAW,GAAG,4BAA4B;;AAEvD;AACA;AACA;AACA,OAAO,MAAMC,cAAc,GAAG,uBAAuB;;AAErD;AACA;AACA;AACA;AACA,OAAO,MAAMC,cAAc,GAAG,SAAS;;AAEvC;AACA;AACA;AACA,OAAO,SAASC,YAAYA,CAACC,KAAa,EAAW;EACnD,OAAOJ,WAAW,CAACK,IAAI,CAACD,KAAK,CAAC;AAChC;;AAEA;AACA;AACA;AACA,OAAO,SAASE,eAAeA,CAACC,QAAgB,EAAW;EACzD,OAAON,cAAc,CAACI,IAAI,CAACE,QAAQ,CAAC;AACtC;;AAEA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAACC,QAAgB,EAAW;EACzD,OAAOP,cAAc,CAACG,IAAI,CAACI,QAAQ,CAAC;AACtC;;AAEA;AACA;AACA;AACA,OAAO,SAASC,gBAAgBA,CAACC,KAAc,EAAW;EACxD,OAAO,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,CAACC,IAAI,CAAC,CAAC,CAACC,MAAM,GAAG,CAAC;AAC7D;;AAEA;AACA;AACA;AACA,OAAO,SAASC,gBAAgBA,CAACH,KAAc,EAAW;EACxD,OAAO,OAAOA,KAAK,KAAK,QAAQ,IAAI,CAACI,MAAM,CAACC,KAAK,CAACL,KAAK,CAAC;AAC1D;;AAEA;AACA;AACA;AACA,OAAO,SAASM,iBAAiBA,CAACN,KAAc,EAAW;EACzD,OAAO,OAAOA,KAAK,KAAK,SAAS;AACnC;;AAEA;AACA;AACA;AACA,OAAO,SAASO,YAAYA,CAACP,KAAc,EAAW;EACpD,OAAOQ,KAAK,CAACC,OAAO,CAACT,KAAK,CAAC;AAC7B;;AAEA;AACA;AACA;AACA,OAAO,SAASU,aAAaA,CAACV,KAAc,EAAW;EACrD,OAAO,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,KAAK,IAAI,IAAI,CAACQ,KAAK,CAACC,OAAO,CAACT,KAAK,CAAC;AAC7E;;AAEA;AACA;AACA;AACA,OAAO,SAASW,WAAWA,CAACC,IAAY,EAAW;EACjD,MAAMC,UAAU,GAAG,4EAA4E;EAC/F,OAAOA,UAAU,CAACnB,IAAI,CAACkB,IAAI,CAAC;AAC9B;;AAEA;AACA;AACA;AACA,OAAO,SAASE,UAAUA,CAACC,GAAW,EAAW;EAC/C,IAAI;IACF,IAAIC,GAAG,CAACD,GAAG,CAAC;IACZ,OAAO,IAAI;EACb,CAAC,CAAC,MAAM;IACN,OAAO,KAAK;EACd;AACF;;AAEA;AACA;AACA;AACA,OAAO,SAASE,WAAWA,CAACC,UAAkB,EAAW;EACvD,MAAMC,IAAI,GAAG,IAAIC,IAAI,CAACF,UAAU,CAAC;EACjC,OAAO,CAACd,MAAM,CAACC,KAAK,CAACc,IAAI,CAACE,OAAO,CAAC,CAAC,CAAC;AACtC;;AAEA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAACC,IAAY,EAAEC,OAAe,EAAW;EACtE,OAAOD,IAAI,GAAG,CAAC,IAAIA,IAAI,IAAIC,OAAO;AACpC;;AAEA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAACC,QAAgB,EAAEC,YAAsB,EAAW;EACjF,MAAMC,SAAS,GAAGF,QAAQ,CAACG,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC,CAAC,EAAEC,WAAW,CAAC,CAAC;EAC1D,OAAOH,SAAS,GAAGD,YAAY,CAACK,QAAQ,CAACJ,SAAS,CAAC,GAAG,KAAK;AAC7D;;AAEA;AACA;AACA;AACA,OAAO,SAASK,cAAcA,CAACC,KAAa,EAAU;EACpD;EACA,OAAOA,KAAK,CAACjC,IAAI,CAAC,CAAC,CAACkC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;AAC7C;;AAEA;AACA;AACA;AACA,OAAO,SAASC,YAAYA,CAACF,KAAa,EAAU;EAClD,OAAOA,KAAK,CACTC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CACtBA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CACrBA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CACrBA,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CACvBA,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;AAC5B;;AAEA;AACA;AACA;AACA,OAAO,SAASE,4BAA4BA,
|
|
1
|
+
{"version":3,"names":["EMAIL_REGEX","USERNAME_REGEX","PASSWORD_REGEX","isValidEmail","email","test","isValidUsername","username","isValidPassword","password","isRequiredString","value","trim","length","isRequiredNumber","Number","isNaN","isRequiredBoolean","isValidArray","Array","isArray","isValidObject","isValidUUID","uuid","UUID_REGEX","isValidURL","url","URL","isValidDate","dateString","date","Date","getTime","isValidFileSize","size","maxSize","isValidFileType","filename","allowedTypes","extension","split","pop","toLowerCase","includes","sanitizeString","input","replace","sanitizeHTML","isValidObjectId","id","OBJECT_ID_REGEX","validateAndSanitizeUserInput","type","sanitized"],"sourceRoot":"../../../src","sources":["utils/validationUtils.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -34,10 +34,6 @@ export declare class RequestManager {
|
|
|
34
34
|
* Make a request with all performance optimizations
|
|
35
35
|
*/
|
|
36
36
|
request<T>(method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', url: string, data?: any, options?: RequestOptions): Promise<T>;
|
|
37
|
-
/**
|
|
38
|
-
* Exponential backoff retry logic with 4xx error handling
|
|
39
|
-
*/
|
|
40
|
-
private retryWithBackoff;
|
|
41
37
|
/**
|
|
42
38
|
* Update request metrics
|
|
43
39
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RequestManager.d.ts","sourceRoot":"","sources":["../../../src/core/RequestManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,UAAU,CAA6C;IAG/D,OAAO,CAAC,cAAc,CAOpB;gBAGA,UAAU,EAAE;QAAE,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;KAAE,EACtD,MAAM,EAAE,SAAS;IAoBnB;;OAEG;IACG,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,EACnD,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,GAAG,EACV,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"RequestManager.d.ts","sourceRoot":"","sources":["../../../src/core/RequestManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,UAAU,CAA6C;IAG/D,OAAO,CAAC,cAAc,CAOpB;gBAGA,UAAU,EAAE;QAAE,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;KAAE,EACtD,MAAM,EAAE,SAAS;IAoBnB;;OAEG;IACG,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,EACnD,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,GAAG,EACV,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,CAAC,CAAC;IA2Eb;;OAEG;IACH,OAAO,CAAC,aAAa;IAcrB;;OAEG;IACH,UAAU,IAAI,OAAO,IAAI,CAAC,cAAc;IAIxC;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAUjF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FollowButton.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/FollowButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,SAAS,EAGf,MAAM,cAAc,CAAC;AAmBtB,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B;AAED,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA8L7C,CAAC;
|
|
1
|
+
{"version":3,"file":"FollowButton.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/FollowButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,SAAS,EAGf,MAAM,cAAc,CAAC;AAmBtB,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B;AAED,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA8L7C,CAAC;AAGF,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,eAAe,YAAY,CAAC"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* Wrapper for async operations with automatic error handling
|
|
6
|
+
* Returns null on error instead of throwing
|
|
6
7
|
*/
|
|
7
8
|
export declare function withErrorHandling<T>(operation: () => Promise<T>, errorHandler?: (error: any) => void, context?: string): Promise<T | null>;
|
|
8
9
|
/**
|
|
@@ -11,6 +12,9 @@ export declare function withErrorHandling<T>(operation: () => Promise<T>, errorH
|
|
|
11
12
|
export declare function parallelWithErrorHandling<T>(operations: (() => Promise<T>)[], errorHandler?: (error: any, index: number) => void): Promise<(T | null)[]>;
|
|
12
13
|
/**
|
|
13
14
|
* Retry an async operation with exponential backoff
|
|
15
|
+
*
|
|
16
|
+
* By default, does not retry on 4xx errors (client errors).
|
|
17
|
+
* Use shouldRetry callback to customize retry behavior.
|
|
14
18
|
*/
|
|
15
19
|
export declare function retryAsync<T>(operation: () => Promise<T>, maxRetries?: number, baseDelay?: number, shouldRetry?: (error: any) => boolean): Promise<T>;
|
|
16
20
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asyncUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/asyncUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"asyncUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/asyncUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ export declare const ErrorCodes: {
|
|
|
11
11
|
readonly INVALID_TOKEN: "INVALID_TOKEN";
|
|
12
12
|
readonly MISSING_TOKEN: "MISSING_TOKEN";
|
|
13
13
|
readonly VALIDATION_ERROR: "VALIDATION_ERROR";
|
|
14
|
+
readonly BAD_REQUEST: "BAD_REQUEST";
|
|
14
15
|
readonly MISSING_PARAMETER: "MISSING_PARAMETER";
|
|
15
16
|
readonly INVALID_FORMAT: "INVALID_FORMAT";
|
|
16
17
|
readonly NOT_FOUND: "NOT_FOUND";
|
|
@@ -30,6 +31,11 @@ export declare function createApiError(message: string, code?: string, status?:
|
|
|
30
31
|
* Handle common HTTP errors and convert to ApiError
|
|
31
32
|
*/
|
|
32
33
|
export declare function handleHttpError(error: unknown): ApiError;
|
|
34
|
+
/**
|
|
35
|
+
* Get error code from HTTP status
|
|
36
|
+
* Exported for use in other modules
|
|
37
|
+
*/
|
|
38
|
+
export declare function getErrorCodeFromStatus(status: number): string;
|
|
33
39
|
/**
|
|
34
40
|
* Validate required fields and throw error if missing
|
|
35
41
|
*/
|
|
@@ -40,6 +46,8 @@ export declare function validateRequiredFields(data: Record<string, unknown>, fi
|
|
|
40
46
|
export declare function logError(error: unknown, context?: string): void;
|
|
41
47
|
/**
|
|
42
48
|
* Retry function with exponential backoff
|
|
49
|
+
* Re-exports retryAsync for backward compatibility
|
|
50
|
+
* @deprecated Use retryAsync from asyncUtils instead
|
|
43
51
|
*/
|
|
44
|
-
export
|
|
52
|
+
export { retryAsync as retryWithBackoff } from './asyncUtils';
|
|
45
53
|
//# sourceMappingURL=errorUtils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/errorUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"errorUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/errorUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;CA0Bb,CAAC;AAEX;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAkC,EACxC,MAAM,SAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,QAAQ,CAOV;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CA6CxD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqB7D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAU5F;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAQ/D;AAED;;;;GAIG;AACH,OAAO,EAAE,UAAU,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -73,6 +73,12 @@ export declare function sanitizeString(input: string): string;
|
|
|
73
73
|
* Sanitize HTML input
|
|
74
74
|
*/
|
|
75
75
|
export declare function sanitizeHTML(input: string): string;
|
|
76
|
+
/**
|
|
77
|
+
* Validate MongoDB ObjectId format
|
|
78
|
+
* Note: This is a basic format check. For full validation, use mongoose.Types.ObjectId.isValid()
|
|
79
|
+
* This function works in environments where mongoose may not be available (e.g., client-side)
|
|
80
|
+
*/
|
|
81
|
+
export declare function isValidObjectId(id: string): boolean;
|
|
76
82
|
/**
|
|
77
83
|
* Validate and sanitize user input
|
|
78
84
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validationUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/validationUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,WAAW,QAA+B,CAAC;AAExD;;GAEG;AACH,eAAO,MAAM,cAAc,QAA0B,CAAC;AAEtD;;GAEG;AAEH,eAAO,MAAM,cAAc,QAAY,CAAC;AAExC;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAExD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAExD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAErD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGjD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAO/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAGjF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,IAAI,CAiBjH"}
|
|
1
|
+
{"version":3,"file":"validationUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/validationUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,WAAW,QAA+B,CAAC;AAExD;;GAEG;AACH,eAAO,MAAM,cAAc,QAA0B,CAAC;AAEtD;;GAEG;AAEH,eAAO,MAAM,cAAc,QAAY,CAAC;AAExC;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAExD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAExD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAErD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGjD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAO/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAGjF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAOnD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,IAAI,CAiBjH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/services",
|
|
3
|
-
"version": "5.13.
|
|
3
|
+
"version": "5.13.25",
|
|
4
4
|
"description": "Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import type { AxiosInstance } from 'axios';
|
|
9
9
|
import { TTLCache, registerCacheForCleanup } from '../utils/cache';
|
|
10
10
|
import { RequestDeduplicator, RequestQueue, SimpleLogger } from '../utils/requestUtils';
|
|
11
|
-
import {
|
|
11
|
+
import { retryAsync } from '../utils/asyncUtils';
|
|
12
12
|
import type { OxyConfig } from '../models/interfaces';
|
|
13
13
|
|
|
14
14
|
export interface RequestOptions {
|
|
@@ -128,7 +128,7 @@ export class RequestManager {
|
|
|
128
128
|
|
|
129
129
|
// Wrap with retry if enabled
|
|
130
130
|
const requestWithRetry = retry
|
|
131
|
-
? () =>
|
|
131
|
+
? () => retryAsync(requestFn, maxRetries, this.config.retryDelay || 1000)
|
|
132
132
|
: requestFn;
|
|
133
133
|
|
|
134
134
|
// Wrap with deduplication if enabled
|
|
@@ -148,41 +148,6 @@ export class RequestManager {
|
|
|
148
148
|
return result;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
/**
|
|
152
|
-
* Exponential backoff retry logic with 4xx error handling
|
|
153
|
-
*/
|
|
154
|
-
private async retryWithBackoff<T>(
|
|
155
|
-
fn: () => Promise<T>,
|
|
156
|
-
maxRetries: number = 3,
|
|
157
|
-
baseDelay: number = 1000
|
|
158
|
-
): Promise<T> {
|
|
159
|
-
let lastError: any;
|
|
160
|
-
|
|
161
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
162
|
-
try {
|
|
163
|
-
return await fn();
|
|
164
|
-
} catch (error: any) {
|
|
165
|
-
lastError = error;
|
|
166
|
-
|
|
167
|
-
// Don't retry on 4xx errors (client errors)
|
|
168
|
-
if (error.response?.status >= 400 && error.response?.status < 500) {
|
|
169
|
-
throw error;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Don't retry on last attempt
|
|
173
|
-
if (attempt === maxRetries) {
|
|
174
|
-
break;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Calculate delay with exponential backoff and jitter
|
|
178
|
-
const delay = baseDelay * Math.pow(2, attempt) + Math.random() * 1000;
|
|
179
|
-
this.logger.debug(`Retry attempt ${attempt + 1}/${maxRetries} after ${delay}ms`);
|
|
180
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
throw lastError;
|
|
185
|
-
}
|
|
186
151
|
|
|
187
152
|
/**
|
|
188
153
|
* Update request metrics
|
|
@@ -233,59 +233,6 @@ const FollowButton: React.FC<FollowButtonProps> = ({
|
|
|
233
233
|
);
|
|
234
234
|
};
|
|
235
235
|
|
|
236
|
-
const styles = StyleSheet.create({
|
|
237
|
-
// Legacy styles kept for backward compatibility but not used in new implementation
|
|
238
|
-
buttonSmall: {
|
|
239
|
-
paddingVertical: 4,
|
|
240
|
-
paddingHorizontal: 12,
|
|
241
|
-
borderRadius: 16,
|
|
242
|
-
minWidth: 60,
|
|
243
|
-
alignItems: 'center',
|
|
244
|
-
justifyContent: 'center',
|
|
245
|
-
},
|
|
246
|
-
buttonMedium: {
|
|
247
|
-
paddingVertical: 8,
|
|
248
|
-
paddingHorizontal: 20,
|
|
249
|
-
borderRadius: 20,
|
|
250
|
-
minWidth: 90,
|
|
251
|
-
alignItems: 'center',
|
|
252
|
-
justifyContent: 'center',
|
|
253
|
-
},
|
|
254
|
-
buttonLarge: {
|
|
255
|
-
paddingVertical: 12,
|
|
256
|
-
paddingHorizontal: 32,
|
|
257
|
-
borderRadius: 24,
|
|
258
|
-
minWidth: 120,
|
|
259
|
-
alignItems: 'center',
|
|
260
|
-
justifyContent: 'center',
|
|
261
|
-
},
|
|
262
|
-
following: {
|
|
263
|
-
backgroundColor: '#007AFF',
|
|
264
|
-
},
|
|
265
|
-
notFollowing: {
|
|
266
|
-
backgroundColor: '#fff',
|
|
267
|
-
borderWidth: 1,
|
|
268
|
-
borderColor: '#007AFF',
|
|
269
|
-
},
|
|
270
|
-
textSmall: {
|
|
271
|
-
fontSize: 13,
|
|
272
|
-
fontFamily: fontFamilies.phuduMedium,
|
|
273
|
-
},
|
|
274
|
-
textMedium: {
|
|
275
|
-
fontSize: 15,
|
|
276
|
-
fontFamily: fontFamilies.phuduMedium,
|
|
277
|
-
},
|
|
278
|
-
textLarge: {
|
|
279
|
-
fontSize: 18,
|
|
280
|
-
fontFamily: fontFamilies.phuduMedium,
|
|
281
|
-
},
|
|
282
|
-
textFollowing: {
|
|
283
|
-
color: '#fff',
|
|
284
|
-
},
|
|
285
|
-
textNotFollowing: {
|
|
286
|
-
color: '#007AFF',
|
|
287
|
-
},
|
|
288
|
-
});
|
|
289
236
|
|
|
290
237
|
export { FollowButton };
|
|
291
238
|
export default FollowButton;
|
package/src/utils/asyncUtils.ts
CHANGED
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { TTLCache, registerCacheForCleanup } from './cache';
|
|
6
|
+
import { logger } from './loggerUtils';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Wrapper for async operations with automatic error handling
|
|
10
|
+
* Returns null on error instead of throwing
|
|
9
11
|
*/
|
|
10
12
|
export async function withErrorHandling<T>(
|
|
11
13
|
operation: () => Promise<T>,
|
|
@@ -18,7 +20,10 @@ export async function withErrorHandling<T>(
|
|
|
18
20
|
if (errorHandler) {
|
|
19
21
|
errorHandler(error);
|
|
20
22
|
} else {
|
|
21
|
-
|
|
23
|
+
logger.error(`Error in ${context || 'operation'}`, error instanceof Error ? error : new Error(String(error)), {
|
|
24
|
+
component: 'asyncUtils',
|
|
25
|
+
method: 'withErrorHandling',
|
|
26
|
+
});
|
|
22
27
|
}
|
|
23
28
|
return null;
|
|
24
29
|
}
|
|
@@ -44,6 +49,9 @@ export async function parallelWithErrorHandling<T>(
|
|
|
44
49
|
|
|
45
50
|
/**
|
|
46
51
|
* Retry an async operation with exponential backoff
|
|
52
|
+
*
|
|
53
|
+
* By default, does not retry on 4xx errors (client errors).
|
|
54
|
+
* Use shouldRetry callback to customize retry behavior.
|
|
47
55
|
*/
|
|
48
56
|
export async function retryAsync<T>(
|
|
49
57
|
operation: () => Promise<T>,
|
|
@@ -53,6 +61,17 @@ export async function retryAsync<T>(
|
|
|
53
61
|
): Promise<T> {
|
|
54
62
|
let lastError: any;
|
|
55
63
|
|
|
64
|
+
// Default shouldRetry: don't retry on 4xx errors
|
|
65
|
+
const defaultShouldRetry = (error: any): boolean => {
|
|
66
|
+
// Don't retry on 4xx errors (client errors)
|
|
67
|
+
if (error?.response?.status >= 400 && error?.response?.status < 500) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const retryCheck = shouldRetry || defaultShouldRetry;
|
|
74
|
+
|
|
56
75
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
57
76
|
try {
|
|
58
77
|
return await operation();
|
|
@@ -63,11 +82,12 @@ export async function retryAsync<T>(
|
|
|
63
82
|
break;
|
|
64
83
|
}
|
|
65
84
|
|
|
66
|
-
if (
|
|
85
|
+
if (!retryCheck(error)) {
|
|
67
86
|
break;
|
|
68
87
|
}
|
|
69
88
|
|
|
70
|
-
|
|
89
|
+
// Calculate delay with exponential backoff and jitter
|
|
90
|
+
const delay = baseDelay * Math.pow(2, attempt) + Math.random() * 1000;
|
|
71
91
|
await new Promise(resolve => setTimeout(resolve, delay));
|
|
72
92
|
}
|
|
73
93
|
}
|
package/src/utils/errorUtils.ts
CHANGED
|
@@ -16,6 +16,7 @@ export const ErrorCodes = {
|
|
|
16
16
|
|
|
17
17
|
// Validation errors
|
|
18
18
|
VALIDATION_ERROR: 'VALIDATION_ERROR',
|
|
19
|
+
BAD_REQUEST: 'BAD_REQUEST',
|
|
19
20
|
MISSING_PARAMETER: 'MISSING_PARAMETER',
|
|
20
21
|
INVALID_FORMAT: 'INVALID_FORMAT',
|
|
21
22
|
|
|
@@ -103,11 +104,12 @@ export function handleHttpError(error: unknown): ApiError {
|
|
|
103
104
|
|
|
104
105
|
/**
|
|
105
106
|
* Get error code from HTTP status
|
|
107
|
+
* Exported for use in other modules
|
|
106
108
|
*/
|
|
107
|
-
function getErrorCodeFromStatus(status: number): string {
|
|
109
|
+
export function getErrorCodeFromStatus(status: number): string {
|
|
108
110
|
switch (status) {
|
|
109
111
|
case 400:
|
|
110
|
-
return ErrorCodes.
|
|
112
|
+
return ErrorCodes.BAD_REQUEST;
|
|
111
113
|
case 401:
|
|
112
114
|
return ErrorCodes.UNAUTHORIZED;
|
|
113
115
|
case 403:
|
|
@@ -157,28 +159,7 @@ export function logError(error: unknown, context?: string): void {
|
|
|
157
159
|
|
|
158
160
|
/**
|
|
159
161
|
* Retry function with exponential backoff
|
|
162
|
+
* Re-exports retryAsync for backward compatibility
|
|
163
|
+
* @deprecated Use retryAsync from asyncUtils instead
|
|
160
164
|
*/
|
|
161
|
-
export
|
|
162
|
-
fn: () => Promise<T>,
|
|
163
|
-
maxRetries = 3,
|
|
164
|
-
baseDelay = 1000
|
|
165
|
-
): Promise<T> {
|
|
166
|
-
let lastError: unknown;
|
|
167
|
-
|
|
168
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
169
|
-
try {
|
|
170
|
-
return await fn();
|
|
171
|
-
} catch (error) {
|
|
172
|
-
lastError = error;
|
|
173
|
-
|
|
174
|
-
if (attempt === maxRetries) {
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const delay = baseDelay * 2 ** attempt;
|
|
179
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
throw lastError;
|
|
184
|
-
}
|
|
165
|
+
export { retryAsync as retryWithBackoff } from './asyncUtils';
|
|
@@ -137,6 +137,20 @@ export function sanitizeHTML(input: string): string {
|
|
|
137
137
|
.replace(/'/g, ''');
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Validate MongoDB ObjectId format
|
|
142
|
+
* Note: This is a basic format check. For full validation, use mongoose.Types.ObjectId.isValid()
|
|
143
|
+
* This function works in environments where mongoose may not be available (e.g., client-side)
|
|
144
|
+
*/
|
|
145
|
+
export function isValidObjectId(id: string): boolean {
|
|
146
|
+
if (typeof id !== 'string') {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
// MongoDB ObjectId is 24 hex characters
|
|
150
|
+
const OBJECT_ID_REGEX = /^[0-9a-fA-F]{24}$/;
|
|
151
|
+
return OBJECT_ID_REGEX.test(id);
|
|
152
|
+
}
|
|
153
|
+
|
|
140
154
|
/**
|
|
141
155
|
* Validate and sanitize user input
|
|
142
156
|
*/
|