@exyconn/common 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +259 -0
  2. package/dist/client/http/index.d.mts +85 -0
  3. package/dist/client/http/index.d.ts +85 -0
  4. package/dist/client/http/index.js +127 -0
  5. package/dist/client/http/index.js.map +1 -0
  6. package/dist/client/http/index.mjs +109 -0
  7. package/dist/client/http/index.mjs.map +1 -0
  8. package/dist/client/index.d.mts +7 -0
  9. package/dist/client/index.d.ts +7 -0
  10. package/dist/client/index.js +964 -0
  11. package/dist/client/index.js.map +1 -0
  12. package/dist/client/index.mjs +889 -0
  13. package/dist/client/index.mjs.map +1 -0
  14. package/dist/client/logger/index.d.mts +53 -0
  15. package/dist/client/logger/index.d.ts +53 -0
  16. package/dist/client/logger/index.js +120 -0
  17. package/dist/client/logger/index.js.map +1 -0
  18. package/dist/client/logger/index.mjs +116 -0
  19. package/dist/client/logger/index.mjs.map +1 -0
  20. package/dist/client/utils/index.d.mts +285 -0
  21. package/dist/client/utils/index.d.ts +285 -0
  22. package/dist/client/utils/index.js +403 -0
  23. package/dist/client/utils/index.js.map +1 -0
  24. package/dist/client/utils/index.mjs +362 -0
  25. package/dist/client/utils/index.mjs.map +1 -0
  26. package/dist/index-BNdT-2X4.d.ts +229 -0
  27. package/dist/index-CcrANHAQ.d.mts +59 -0
  28. package/dist/index-ClWtDfwk.d.ts +833 -0
  29. package/dist/index-DSW6JfD-.d.mts +833 -0
  30. package/dist/index-Du0LLt9f.d.mts +229 -0
  31. package/dist/index-iTKxFa78.d.ts +59 -0
  32. package/dist/index.d.mts +171 -0
  33. package/dist/index.d.ts +171 -0
  34. package/dist/index.js +3806 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/index.mjs +3792 -0
  37. package/dist/index.mjs.map +1 -0
  38. package/dist/response.types-D--UhLJq.d.mts +67 -0
  39. package/dist/response.types-D--UhLJq.d.ts +67 -0
  40. package/dist/server/db/index.d.mts +38 -0
  41. package/dist/server/db/index.d.ts +38 -0
  42. package/dist/server/db/index.js +68 -0
  43. package/dist/server/db/index.js.map +1 -0
  44. package/dist/server/db/index.mjs +60 -0
  45. package/dist/server/db/index.mjs.map +1 -0
  46. package/dist/server/enums/index.d.mts +46 -0
  47. package/dist/server/enums/index.d.ts +46 -0
  48. package/dist/server/enums/index.js +48 -0
  49. package/dist/server/enums/index.js.map +1 -0
  50. package/dist/server/enums/index.mjs +43 -0
  51. package/dist/server/enums/index.mjs.map +1 -0
  52. package/dist/server/index.d.mts +9 -0
  53. package/dist/server/index.d.ts +9 -0
  54. package/dist/server/index.js +569 -0
  55. package/dist/server/index.js.map +1 -0
  56. package/dist/server/index.mjs +523 -0
  57. package/dist/server/index.mjs.map +1 -0
  58. package/dist/server/logger/index.d.mts +34 -0
  59. package/dist/server/logger/index.d.ts +34 -0
  60. package/dist/server/logger/index.js +125 -0
  61. package/dist/server/logger/index.js.map +1 -0
  62. package/dist/server/logger/index.mjs +113 -0
  63. package/dist/server/logger/index.mjs.map +1 -0
  64. package/dist/server/middleware/index.d.mts +56 -0
  65. package/dist/server/middleware/index.d.ts +56 -0
  66. package/dist/server/middleware/index.js +128 -0
  67. package/dist/server/middleware/index.js.map +1 -0
  68. package/dist/server/middleware/index.mjs +118 -0
  69. package/dist/server/middleware/index.mjs.map +1 -0
  70. package/dist/server/response/index.d.mts +86 -0
  71. package/dist/server/response/index.d.ts +86 -0
  72. package/dist/server/response/index.js +140 -0
  73. package/dist/server/response/index.js.map +1 -0
  74. package/dist/server/response/index.mjs +126 -0
  75. package/dist/server/response/index.mjs.map +1 -0
  76. package/dist/server/utils/index.d.mts +69 -0
  77. package/dist/server/utils/index.d.ts +69 -0
  78. package/dist/server/utils/index.js +114 -0
  79. package/dist/server/utils/index.js.map +1 -0
  80. package/dist/server/utils/index.mjs +106 -0
  81. package/dist/server/utils/index.mjs.map +1 -0
  82. package/dist/shared/index.d.mts +4 -0
  83. package/dist/shared/index.d.ts +4 -0
  84. package/dist/shared/index.js +933 -0
  85. package/dist/shared/index.js.map +1 -0
  86. package/dist/shared/index.mjs +612 -0
  87. package/dist/shared/index.mjs.map +1 -0
  88. package/package.json +202 -0
package/README.md ADDED
@@ -0,0 +1,259 @@
1
+ # @exyconn/common
2
+
3
+ Common utilities, hooks, types, and data shared across all Exyconn projects (botify.life, exyconn.com, partywings.fun, sibera.work, spentiva.com).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @exyconn/common
9
+ # or
10
+ yarn add @exyconn/common
11
+ # or
12
+ pnpm add @exyconn/common
13
+ ```
14
+
15
+ ## Features
16
+
17
+ - ���️ **Server utilities** - Response helpers, middleware, logging, database connections
18
+ - ��� **Client utilities** - HTTP clients, React hooks, response parsing
19
+ - ��� **Shared types** - TypeScript interfaces for API responses, users, etc.
20
+ - ��� **Data modules** - Countries, currencies, phone codes, timezones, brand logos
21
+ - ✅ **Validation** - Common patterns, regex, and validation helpers
22
+ - ��� **Date utilities** - Enhanced date-fns with timezone support
23
+
24
+ ## Usage
25
+
26
+ ### Import Everything
27
+
28
+ ```typescript
29
+ import { server, client, shared, data } from '@exyconn/common';
30
+ ```
31
+
32
+ ### Server-side
33
+
34
+ ```typescript
35
+ // Response helpers
36
+ import { successResponse, errorResponse, paginatedResponse } from '@exyconn/common/server/response';
37
+
38
+ // Status codes & messages
39
+ import { STATUS_CODES, STATUS_MESSAGES } from '@exyconn/common/server/enums';
40
+
41
+ // Winston logger
42
+ import { createLogger, logger } from '@exyconn/common/server/logger';
43
+
44
+ // MongoDB connection
45
+ import { connectDB } from '@exyconn/common/server/db';
46
+
47
+ // Auth middleware
48
+ import { authMiddleware, apiKeyMiddleware } from '@exyconn/common/server/middleware';
49
+ ```
50
+
51
+ ### Client-side
52
+
53
+ ```typescript
54
+ // HTTP client
55
+ import { createHttpClient, httpGet, httpPost } from '@exyconn/common/client/http';
56
+
57
+ // React hooks
58
+ import {
59
+ useLocalStorage,
60
+ useDebounce,
61
+ useCopyToClipboard,
62
+ usePageTitle,
63
+ useSnackbar,
64
+ useMediaQuery,
65
+ useIsMobile,
66
+ useThemeDetector,
67
+ useInterval,
68
+ useOnClickOutside,
69
+ useWindowSize
70
+ } from '@exyconn/common/client/hooks';
71
+
72
+ // Utils
73
+ import {
74
+ formatDate,
75
+ copyToClipboard,
76
+ toSlug,
77
+ isSuccessResponse,
78
+ getErrorMessage
79
+ } from '@exyconn/common/client/utils';
80
+ ```
81
+
82
+ ### Shared Types
83
+
84
+ ```typescript
85
+ import type {
86
+ ApiResponse,
87
+ PaginatedResponse,
88
+ User,
89
+ AuthResponse,
90
+ JwtPayload
91
+ } from '@exyconn/common/shared/types';
92
+ ```
93
+
94
+ ### Validation
95
+
96
+ ```typescript
97
+ import {
98
+ VALIDATION_PATTERNS,
99
+ VALIDATION_MESSAGES,
100
+ isValidEmail,
101
+ isValidPassword,
102
+ isValidPhone,
103
+ isValidUrl
104
+ } from '@exyconn/common/shared/validation';
105
+ ```
106
+
107
+ ### Date/Time Utilities
108
+
109
+ ```typescript
110
+ import {
111
+ formatDate,
112
+ formatDateTime,
113
+ formatDateInTimezone,
114
+ formatRelativeTime,
115
+ formatSmartDate,
116
+ toTimezone,
117
+ fromTimezone,
118
+ nowInTimezone,
119
+ addTime,
120
+ subtractTime,
121
+ getDayBoundaries,
122
+ getAge,
123
+ isWeekend,
124
+ DATE_FORMATS
125
+ } from '@exyconn/common/shared';
126
+ ```
127
+
128
+ ### Data Modules
129
+
130
+ ```typescript
131
+ // Countries with nested states/cities
132
+ import {
133
+ countries,
134
+ getCountryByCode,
135
+ getStatesByCountry,
136
+ getCitiesByState,
137
+ searchCountries
138
+ } from '@exyconn/common/data/countries';
139
+
140
+ // Currencies
141
+ import {
142
+ currencies,
143
+ getCurrencyByCode,
144
+ formatCurrency,
145
+ formatCurrencyNative
146
+ } from '@exyconn/common/data/currencies';
147
+
148
+ // Phone codes
149
+ import { phoneCodes, getPhoneCodeByCountry } from '@exyconn/common/data/phone-codes';
150
+
151
+ // Timezones
152
+ import {
153
+ timezones,
154
+ getTimezoneByCode,
155
+ searchTimezones,
156
+ getCommonTimezones
157
+ } from '@exyconn/common/data/timezones';
158
+
159
+ // Brand logos (all 5 companies)
160
+ import {
161
+ brands,
162
+ getBrandByName,
163
+ getAllBrands
164
+ } from '@exyconn/common/data/logos';
165
+ ```
166
+
167
+ ## Data Module Details
168
+
169
+ ### Countries
170
+ - 50+ countries with full details
171
+ - Nested states/cities for major countries
172
+ - Includes phone codes, currencies, timezones
173
+
174
+ ### Currencies
175
+ - 100+ world currencies
176
+ - Symbol, name, and native formatting
177
+ - formatCurrency(amount, code) helper
178
+
179
+ ### Phone Codes
180
+ - 190+ international phone codes
181
+ - Country flags (emoji)
182
+
183
+ ### Timezones
184
+ - 65+ timezones with UTC offsets
185
+ - Common timezone presets
186
+ - Search and filter functions
187
+
188
+ ### Brand Logos
189
+ All 5 Exyconn company brands with light/dark mode support:
190
+ - **botify.life** - AI/Bot platform
191
+ - **exyconn.com** - Main Exyconn brand
192
+ - **partywings.fun** - Event platform
193
+ - **sibera.work** - Work management
194
+ - **spentiva.com** - Finance platform
195
+
196
+ ## React Hooks
197
+
198
+ | Hook | Description |
199
+ |------|-------------|
200
+ | useLocalStorage | Persist state in localStorage with cross-tab sync |
201
+ | useDebounce | Debounce a value with configurable delay |
202
+ | useCopyToClipboard | Copy text to clipboard with status |
203
+ | usePageTitle | Set document title with suffix |
204
+ | useSnackbar | Toast/snackbar notification state |
205
+ | useMediaQuery | Track media query matches |
206
+ | useIsMobile / useIsDesktop | Responsive breakpoint hooks |
207
+ | useThemeDetector | Detect system light/dark mode |
208
+ | useInterval | Safely run intervals with cleanup |
209
+ | useOnClickOutside | Detect clicks outside element |
210
+ | useWindowSize | Track window dimensions |
211
+
212
+ ## Peer Dependencies
213
+
214
+ All peer dependencies are optional - only install what you need:
215
+
216
+ ```json
217
+ {
218
+ "axios": "^1.6.0",
219
+ "date-fns": "^3.0.0",
220
+ "date-fns-tz": "^3.0.0",
221
+ "express": "^4.18.0",
222
+ "jsonwebtoken": "^9.0.0",
223
+ "mongoose": "^8.0.0",
224
+ "react": "^18.0.0",
225
+ "winston": "^3.11.0"
226
+ }
227
+ ```
228
+
229
+ ## Package Exports
230
+
231
+ ```
232
+ @exyconn/common
233
+ ├── /server # Server-side utilities
234
+ │ ├── /response # Response helpers
235
+ │ ├── /enums # Status codes/messages
236
+ │ ├── /logger # Winston logger
237
+ │ ├── /db # Database connections
238
+ │ ├── /middleware # Auth middleware
239
+ │ └── /utils # Server utilities
240
+ ├── /client # Client-side utilities
241
+ │ ├── /http # Axios HTTP client
242
+ │ ├── /hooks # React hooks
243
+ │ ├── /logger # Browser logger
244
+ │ └── /utils # Client utilities
245
+ ├── /shared # Shared between server/client
246
+ │ ├── /types # TypeScript types
247
+ │ ├── /validation # Validation patterns
248
+ │ └── /utils # Date-time utilities
249
+ └── /data # Static data modules
250
+ ├── /countries # Countries with cities
251
+ ├── /currencies # World currencies
252
+ ├── /phone-codes # Phone codes
253
+ ├── /timezones # Timezones
254
+ └── /logos # Brand logos
255
+ ```
256
+
257
+ ## License
258
+
259
+ MIT © Exyconn
@@ -0,0 +1,85 @@
1
+ import { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
2
+
3
+ /**
4
+ * HTTP Client Configuration Options
5
+ */
6
+ interface HttpClientOptions {
7
+ baseURL: string;
8
+ timeout?: number;
9
+ withCredentials?: boolean;
10
+ getAuthToken?: () => string | null;
11
+ onUnauthorized?: () => void;
12
+ onServerError?: (error: AxiosError) => void;
13
+ }
14
+ /**
15
+ * Create configured Axios instance
16
+ */
17
+ declare const createHttpClient: (options: HttpClientOptions) => AxiosInstance;
18
+ /**
19
+ * Default request config helpers
20
+ */
21
+ declare const withFormData: () => AxiosRequestConfig;
22
+ declare const withTimeout: (ms: number) => AxiosRequestConfig;
23
+ declare const withAbortSignal: (signal: AbortSignal) => AxiosRequestConfig;
24
+
25
+ /**
26
+ * Standard API Response Structure
27
+ */
28
+ interface ApiResponse<T = unknown> {
29
+ success: boolean;
30
+ message: string;
31
+ data?: T;
32
+ error?: string;
33
+ statusCode?: number;
34
+ }
35
+ /**
36
+ * Paginated Response Structure
37
+ */
38
+ interface PaginatedResponse<T = unknown> extends ApiResponse<T[]> {
39
+ pagination: {
40
+ total: number;
41
+ page: number;
42
+ limit: number;
43
+ totalPages: number;
44
+ hasNextPage: boolean;
45
+ hasPrevPage: boolean;
46
+ };
47
+ }
48
+ /**
49
+ * Parse successful API response
50
+ */
51
+ declare const parseResponse: <T>(response: AxiosResponse<ApiResponse<T>>) => T | null;
52
+ /**
53
+ * Parse API response with full metadata
54
+ */
55
+ declare const parseFullResponse: <T>(response: AxiosResponse<ApiResponse<T>>) => ApiResponse<T>;
56
+ /**
57
+ * Parse error from API response
58
+ */
59
+ declare const parseError: (error: AxiosError<ApiResponse>) => string;
60
+ /**
61
+ * Check if response is successful
62
+ */
63
+ declare const isSuccess: <T>(response: AxiosResponse<ApiResponse<T>>) => boolean;
64
+ /**
65
+ * Check if error is a specific status code
66
+ */
67
+ declare const isStatusError: (error: AxiosError, statusCode: number) => boolean;
68
+ /**
69
+ * Check if error is unauthorized (401)
70
+ */
71
+ declare const isUnauthorized: (error: AxiosError) => boolean;
72
+ /**
73
+ * Check if error is forbidden (403)
74
+ */
75
+ declare const isForbidden: (error: AxiosError) => boolean;
76
+ /**
77
+ * Check if error is not found (404)
78
+ */
79
+ declare const isNotFound: (error: AxiosError) => boolean;
80
+ /**
81
+ * Check if error is server error (5xx)
82
+ */
83
+ declare const isServerError: (error: AxiosError) => boolean;
84
+
85
+ export { type ApiResponse, type HttpClientOptions, type PaginatedResponse, createHttpClient, isForbidden, isNotFound, isServerError, isStatusError, isSuccess, isUnauthorized, parseError, parseFullResponse, parseResponse, withAbortSignal, withFormData, withTimeout };
@@ -0,0 +1,85 @@
1
+ import { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
2
+
3
+ /**
4
+ * HTTP Client Configuration Options
5
+ */
6
+ interface HttpClientOptions {
7
+ baseURL: string;
8
+ timeout?: number;
9
+ withCredentials?: boolean;
10
+ getAuthToken?: () => string | null;
11
+ onUnauthorized?: () => void;
12
+ onServerError?: (error: AxiosError) => void;
13
+ }
14
+ /**
15
+ * Create configured Axios instance
16
+ */
17
+ declare const createHttpClient: (options: HttpClientOptions) => AxiosInstance;
18
+ /**
19
+ * Default request config helpers
20
+ */
21
+ declare const withFormData: () => AxiosRequestConfig;
22
+ declare const withTimeout: (ms: number) => AxiosRequestConfig;
23
+ declare const withAbortSignal: (signal: AbortSignal) => AxiosRequestConfig;
24
+
25
+ /**
26
+ * Standard API Response Structure
27
+ */
28
+ interface ApiResponse<T = unknown> {
29
+ success: boolean;
30
+ message: string;
31
+ data?: T;
32
+ error?: string;
33
+ statusCode?: number;
34
+ }
35
+ /**
36
+ * Paginated Response Structure
37
+ */
38
+ interface PaginatedResponse<T = unknown> extends ApiResponse<T[]> {
39
+ pagination: {
40
+ total: number;
41
+ page: number;
42
+ limit: number;
43
+ totalPages: number;
44
+ hasNextPage: boolean;
45
+ hasPrevPage: boolean;
46
+ };
47
+ }
48
+ /**
49
+ * Parse successful API response
50
+ */
51
+ declare const parseResponse: <T>(response: AxiosResponse<ApiResponse<T>>) => T | null;
52
+ /**
53
+ * Parse API response with full metadata
54
+ */
55
+ declare const parseFullResponse: <T>(response: AxiosResponse<ApiResponse<T>>) => ApiResponse<T>;
56
+ /**
57
+ * Parse error from API response
58
+ */
59
+ declare const parseError: (error: AxiosError<ApiResponse>) => string;
60
+ /**
61
+ * Check if response is successful
62
+ */
63
+ declare const isSuccess: <T>(response: AxiosResponse<ApiResponse<T>>) => boolean;
64
+ /**
65
+ * Check if error is a specific status code
66
+ */
67
+ declare const isStatusError: (error: AxiosError, statusCode: number) => boolean;
68
+ /**
69
+ * Check if error is unauthorized (401)
70
+ */
71
+ declare const isUnauthorized: (error: AxiosError) => boolean;
72
+ /**
73
+ * Check if error is forbidden (403)
74
+ */
75
+ declare const isForbidden: (error: AxiosError) => boolean;
76
+ /**
77
+ * Check if error is not found (404)
78
+ */
79
+ declare const isNotFound: (error: AxiosError) => boolean;
80
+ /**
81
+ * Check if error is server error (5xx)
82
+ */
83
+ declare const isServerError: (error: AxiosError) => boolean;
84
+
85
+ export { type ApiResponse, type HttpClientOptions, type PaginatedResponse, createHttpClient, isForbidden, isNotFound, isServerError, isStatusError, isSuccess, isUnauthorized, parseError, parseFullResponse, parseResponse, withAbortSignal, withFormData, withTimeout };
@@ -0,0 +1,127 @@
1
+ 'use strict';
2
+
3
+ var axios = require('axios');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var axios__default = /*#__PURE__*/_interopDefault(axios);
8
+
9
+ // src/client/http/axios-instance.ts
10
+ var createHttpClient = (options) => {
11
+ const {
12
+ baseURL,
13
+ timeout = 3e4,
14
+ withCredentials = true,
15
+ getAuthToken,
16
+ onUnauthorized,
17
+ onServerError
18
+ } = options;
19
+ const instance = axios__default.default.create({
20
+ baseURL,
21
+ timeout,
22
+ withCredentials,
23
+ headers: {
24
+ "Content-Type": "application/json"
25
+ }
26
+ });
27
+ instance.interceptors.request.use(
28
+ (config) => {
29
+ if (getAuthToken) {
30
+ const token = getAuthToken();
31
+ if (token && config.headers) {
32
+ config.headers.Authorization = `Bearer ${token}`;
33
+ }
34
+ }
35
+ return config;
36
+ },
37
+ (error) => Promise.reject(error)
38
+ );
39
+ instance.interceptors.response.use(
40
+ (response) => response,
41
+ (error) => {
42
+ if (error.response) {
43
+ const status = error.response.status;
44
+ if (status === 401 && onUnauthorized) {
45
+ onUnauthorized();
46
+ }
47
+ if (status >= 500 && onServerError) {
48
+ onServerError(error);
49
+ }
50
+ }
51
+ return Promise.reject(error);
52
+ }
53
+ );
54
+ return instance;
55
+ };
56
+ var withFormData = () => ({
57
+ headers: {
58
+ "Content-Type": "multipart/form-data"
59
+ }
60
+ });
61
+ var withTimeout = (ms) => ({
62
+ timeout: ms
63
+ });
64
+ var withAbortSignal = (signal) => ({
65
+ signal
66
+ });
67
+
68
+ // src/client/http/response-parser.ts
69
+ var parseResponse = (response) => {
70
+ if (response.data?.success && response.data?.data !== void 0) {
71
+ return response.data.data;
72
+ }
73
+ return null;
74
+ };
75
+ var parseFullResponse = (response) => {
76
+ return response.data;
77
+ };
78
+ var parseError = (error) => {
79
+ if (error.response?.data?.message) {
80
+ return error.response.data.message;
81
+ }
82
+ if (error.response?.data?.error) {
83
+ return error.response.data.error;
84
+ }
85
+ if (error.code === "ERR_NETWORK") {
86
+ return "Network error. Please check your connection.";
87
+ }
88
+ if (error.code === "ECONNABORTED") {
89
+ return "Request timed out. Please try again.";
90
+ }
91
+ return error.message || "An unexpected error occurred.";
92
+ };
93
+ var isSuccess = (response) => {
94
+ return response.data?.success === true;
95
+ };
96
+ var isStatusError = (error, statusCode) => {
97
+ return error.response?.status === statusCode;
98
+ };
99
+ var isUnauthorized = (error) => {
100
+ return isStatusError(error, 401);
101
+ };
102
+ var isForbidden = (error) => {
103
+ return isStatusError(error, 403);
104
+ };
105
+ var isNotFound = (error) => {
106
+ return isStatusError(error, 404);
107
+ };
108
+ var isServerError = (error) => {
109
+ const status = error.response?.status;
110
+ return status !== void 0 && status >= 500;
111
+ };
112
+
113
+ exports.createHttpClient = createHttpClient;
114
+ exports.isForbidden = isForbidden;
115
+ exports.isNotFound = isNotFound;
116
+ exports.isServerError = isServerError;
117
+ exports.isStatusError = isStatusError;
118
+ exports.isSuccess = isSuccess;
119
+ exports.isUnauthorized = isUnauthorized;
120
+ exports.parseError = parseError;
121
+ exports.parseFullResponse = parseFullResponse;
122
+ exports.parseResponse = parseResponse;
123
+ exports.withAbortSignal = withAbortSignal;
124
+ exports.withFormData = withFormData;
125
+ exports.withTimeout = withTimeout;
126
+ //# sourceMappingURL=index.js.map
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/client/http/axios-instance.ts","../../../src/client/http/response-parser.ts"],"names":["axios"],"mappings":"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","file":"index.js","sourcesContent":["import axios, { AxiosInstance, AxiosRequestConfig, AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios';\r\n\r\n/**\r\n * HTTP Client Configuration Options\r\n */\r\nexport interface HttpClientOptions {\r\n baseURL: string;\r\n timeout?: number;\r\n withCredentials?: boolean;\r\n getAuthToken?: () => string | null;\r\n onUnauthorized?: () => void;\r\n onServerError?: (error: AxiosError) => void;\r\n}\r\n\r\n/**\r\n * Create configured Axios instance\r\n */\r\nexport const createHttpClient = (options: HttpClientOptions): AxiosInstance => {\r\n const {\r\n baseURL,\r\n timeout = 30000,\r\n withCredentials = true,\r\n getAuthToken,\r\n onUnauthorized,\r\n onServerError,\r\n } = options;\r\n\r\n const instance = axios.create({\r\n baseURL,\r\n timeout,\r\n withCredentials,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n });\r\n\r\n // Request interceptor - add auth token\r\n instance.interceptors.request.use(\r\n (config: InternalAxiosRequestConfig) => {\r\n if (getAuthToken) {\r\n const token = getAuthToken();\r\n if (token && config.headers) {\r\n config.headers.Authorization = `Bearer ${token}`;\r\n }\r\n }\r\n return config;\r\n },\r\n (error: unknown) => Promise.reject(error)\r\n );\r\n\r\n // Response interceptor - handle errors\r\n instance.interceptors.response.use(\r\n (response: AxiosResponse) => response,\r\n (error: AxiosError) => {\r\n if (error.response) {\r\n const status = error.response.status;\r\n\r\n // Handle 401 Unauthorized\r\n if (status === 401 && onUnauthorized) {\r\n onUnauthorized();\r\n }\r\n\r\n // Handle 5xx Server Errors\r\n if (status >= 500 && onServerError) {\r\n onServerError(error);\r\n }\r\n }\r\n\r\n return Promise.reject(error);\r\n }\r\n );\r\n\r\n return instance;\r\n};\r\n\r\n/**\r\n * Default request config helpers\r\n */\r\nexport const withFormData = (): AxiosRequestConfig => ({\r\n headers: {\r\n 'Content-Type': 'multipart/form-data',\r\n },\r\n});\r\n\r\nexport const withTimeout = (ms: number): AxiosRequestConfig => ({\r\n timeout: ms,\r\n});\r\n\r\nexport const withAbortSignal = (signal: AbortSignal): AxiosRequestConfig => ({\r\n signal,\r\n});\r\n\r\nexport default {\r\n createHttpClient,\r\n withFormData,\r\n withTimeout,\r\n withAbortSignal,\r\n};\r\n","import { AxiosResponse, AxiosError } from 'axios';\r\n\r\n/**\r\n * Standard API Response Structure\r\n */\r\nexport interface ApiResponse<T = unknown> {\r\n success: boolean;\r\n message: string;\r\n data?: T;\r\n error?: string;\r\n statusCode?: number;\r\n}\r\n\r\n/**\r\n * Paginated Response Structure\r\n */\r\nexport interface PaginatedResponse<T = unknown> extends ApiResponse<T[]> {\r\n pagination: {\r\n total: number;\r\n page: number;\r\n limit: number;\r\n totalPages: number;\r\n hasNextPage: boolean;\r\n hasPrevPage: boolean;\r\n };\r\n}\r\n\r\n/**\r\n * Parse successful API response\r\n */\r\nexport const parseResponse = <T>(response: AxiosResponse<ApiResponse<T>>): T | null => {\r\n if (response.data?.success && response.data?.data !== undefined) {\r\n return response.data.data;\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * Parse API response with full metadata\r\n */\r\nexport const parseFullResponse = <T>(response: AxiosResponse<ApiResponse<T>>): ApiResponse<T> => {\r\n return response.data;\r\n};\r\n\r\n/**\r\n * Parse error from API response\r\n */\r\nexport const parseError = (error: AxiosError<ApiResponse>): string => {\r\n // Check for API error message\r\n if (error.response?.data?.message) {\r\n return error.response.data.message;\r\n }\r\n\r\n if (error.response?.data?.error) {\r\n return error.response.data.error;\r\n }\r\n\r\n // Check for network error\r\n if (error.code === 'ERR_NETWORK') {\r\n return 'Network error. Please check your connection.';\r\n }\r\n\r\n // Check for timeout\r\n if (error.code === 'ECONNABORTED') {\r\n return 'Request timed out. Please try again.';\r\n }\r\n\r\n // Default error message\r\n return error.message || 'An unexpected error occurred.';\r\n};\r\n\r\n/**\r\n * Check if response is successful\r\n */\r\nexport const isSuccess = <T>(response: AxiosResponse<ApiResponse<T>>): boolean => {\r\n return response.data?.success === true;\r\n};\r\n\r\n/**\r\n * Check if error is a specific status code\r\n */\r\nexport const isStatusError = (error: AxiosError, statusCode: number): boolean => {\r\n return error.response?.status === statusCode;\r\n};\r\n\r\n/**\r\n * Check if error is unauthorized (401)\r\n */\r\nexport const isUnauthorized = (error: AxiosError): boolean => {\r\n return isStatusError(error, 401);\r\n};\r\n\r\n/**\r\n * Check if error is forbidden (403)\r\n */\r\nexport const isForbidden = (error: AxiosError): boolean => {\r\n return isStatusError(error, 403);\r\n};\r\n\r\n/**\r\n * Check if error is not found (404)\r\n */\r\nexport const isNotFound = (error: AxiosError): boolean => {\r\n return isStatusError(error, 404);\r\n};\r\n\r\n/**\r\n * Check if error is server error (5xx)\r\n */\r\nexport const isServerError = (error: AxiosError): boolean => {\r\n const status = error.response?.status;\r\n return status !== undefined && status >= 500;\r\n};\r\n\r\nexport default {\r\n parseResponse,\r\n parseFullResponse,\r\n parseError,\r\n isSuccess,\r\n isStatusError,\r\n isUnauthorized,\r\n isForbidden,\r\n isNotFound,\r\n isServerError,\r\n};\r\n"]}
@@ -0,0 +1,109 @@
1
+ import axios from 'axios';
2
+
3
+ // src/client/http/axios-instance.ts
4
+ var createHttpClient = (options) => {
5
+ const {
6
+ baseURL,
7
+ timeout = 3e4,
8
+ withCredentials = true,
9
+ getAuthToken,
10
+ onUnauthorized,
11
+ onServerError
12
+ } = options;
13
+ const instance = axios.create({
14
+ baseURL,
15
+ timeout,
16
+ withCredentials,
17
+ headers: {
18
+ "Content-Type": "application/json"
19
+ }
20
+ });
21
+ instance.interceptors.request.use(
22
+ (config) => {
23
+ if (getAuthToken) {
24
+ const token = getAuthToken();
25
+ if (token && config.headers) {
26
+ config.headers.Authorization = `Bearer ${token}`;
27
+ }
28
+ }
29
+ return config;
30
+ },
31
+ (error) => Promise.reject(error)
32
+ );
33
+ instance.interceptors.response.use(
34
+ (response) => response,
35
+ (error) => {
36
+ if (error.response) {
37
+ const status = error.response.status;
38
+ if (status === 401 && onUnauthorized) {
39
+ onUnauthorized();
40
+ }
41
+ if (status >= 500 && onServerError) {
42
+ onServerError(error);
43
+ }
44
+ }
45
+ return Promise.reject(error);
46
+ }
47
+ );
48
+ return instance;
49
+ };
50
+ var withFormData = () => ({
51
+ headers: {
52
+ "Content-Type": "multipart/form-data"
53
+ }
54
+ });
55
+ var withTimeout = (ms) => ({
56
+ timeout: ms
57
+ });
58
+ var withAbortSignal = (signal) => ({
59
+ signal
60
+ });
61
+
62
+ // src/client/http/response-parser.ts
63
+ var parseResponse = (response) => {
64
+ if (response.data?.success && response.data?.data !== void 0) {
65
+ return response.data.data;
66
+ }
67
+ return null;
68
+ };
69
+ var parseFullResponse = (response) => {
70
+ return response.data;
71
+ };
72
+ var parseError = (error) => {
73
+ if (error.response?.data?.message) {
74
+ return error.response.data.message;
75
+ }
76
+ if (error.response?.data?.error) {
77
+ return error.response.data.error;
78
+ }
79
+ if (error.code === "ERR_NETWORK") {
80
+ return "Network error. Please check your connection.";
81
+ }
82
+ if (error.code === "ECONNABORTED") {
83
+ return "Request timed out. Please try again.";
84
+ }
85
+ return error.message || "An unexpected error occurred.";
86
+ };
87
+ var isSuccess = (response) => {
88
+ return response.data?.success === true;
89
+ };
90
+ var isStatusError = (error, statusCode) => {
91
+ return error.response?.status === statusCode;
92
+ };
93
+ var isUnauthorized = (error) => {
94
+ return isStatusError(error, 401);
95
+ };
96
+ var isForbidden = (error) => {
97
+ return isStatusError(error, 403);
98
+ };
99
+ var isNotFound = (error) => {
100
+ return isStatusError(error, 404);
101
+ };
102
+ var isServerError = (error) => {
103
+ const status = error.response?.status;
104
+ return status !== void 0 && status >= 500;
105
+ };
106
+
107
+ export { createHttpClient, isForbidden, isNotFound, isServerError, isStatusError, isSuccess, isUnauthorized, parseError, parseFullResponse, parseResponse, withAbortSignal, withFormData, withTimeout };
108
+ //# sourceMappingURL=index.mjs.map
109
+ //# sourceMappingURL=index.mjs.map