@onivoro/isomorphic-common 24.0.0 → 24.0.1
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 +184 -288
- package/package.json +1 -1
- package/tsconfig.lib.json +2 -1
- package/dist/libs/isomorphic/axios/libs/isomorphic/axios/README.md +0 -314
- package/dist/libs/isomorphic/axios/libs/isomorphic/axios/package.json +0 -10
- package/dist/libs/isomorphic/common/libs/isomorphic/common/README.md +0 -393
- package/dist/libs/isomorphic/common/libs/isomorphic/common/package.json +0 -10
- package/dist/libs/server/common/libs/server/common/README.md +0 -322
- package/dist/libs/server/common/libs/server/common/package.json +0 -12
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
# @onivoro/isomorphic-axios
|
|
2
|
-
|
|
3
|
-
HTTP client utilities and Axios configuration for both browser and server environments. This package provides a comprehensive set of tools for creating configurable Axios instances with built-in retry logic, error handling, and request/response interceptors that work seamlessly across client and server codebases.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @onivoro/isomorphic-axios
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Features
|
|
12
|
-
|
|
13
|
-
- **Isomorphic Design**: Works identically in browser and Node.js environments
|
|
14
|
-
- **Advanced Axios Factory**: Create pre-configured Axios instances with custom interceptors
|
|
15
|
-
- **Retry Logic**: Built-in request retry mechanism with configurable delays
|
|
16
|
-
- **Error Handling**: Flexible error handling with status-specific handlers
|
|
17
|
-
- **Header Management**: Dynamic header setting based on request context
|
|
18
|
-
- **API Client Factory**: Streamlined creation of API clients from OpenAPI specs
|
|
19
|
-
- **TypeScript Support**: Full TypeScript support with comprehensive type definitions
|
|
20
|
-
|
|
21
|
-
## Quick Start
|
|
22
|
-
|
|
23
|
-
### Basic Axios Instance Creation
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
import { createAxiosInstance } from '@onivoro/isomorphic-axios';
|
|
27
|
-
|
|
28
|
-
// Create a simple axios instance
|
|
29
|
-
const apiClient = createAxiosInstance({
|
|
30
|
-
apiUrl: 'https://api.example.com',
|
|
31
|
-
accessToken: 'your-token-here'
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// Use the instance
|
|
35
|
-
const response = await apiClient.get('/users');
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Advanced Axios Factory with Custom Configuration
|
|
39
|
-
|
|
40
|
-
```typescript
|
|
41
|
-
import { axiosInstanceFactory } from '@onivoro/isomorphic-axios';
|
|
42
|
-
|
|
43
|
-
const axiosInstance = axiosInstanceFactory({
|
|
44
|
-
headerSetters: {
|
|
45
|
-
'Authorization': (req) => `Bearer ${getToken()}`,
|
|
46
|
-
'X-API-Key': (req) => process.env.API_KEY,
|
|
47
|
-
'Content-Type': (req) => 'application/json'
|
|
48
|
-
},
|
|
49
|
-
errorHandlers: {
|
|
50
|
-
401: async (error, response) => {
|
|
51
|
-
// Handle unauthorized errors
|
|
52
|
-
await refreshToken();
|
|
53
|
-
return retry(error);
|
|
54
|
-
},
|
|
55
|
-
500: async (error, response) => {
|
|
56
|
-
// Handle server errors
|
|
57
|
-
console.error('Server error:', response?.data);
|
|
58
|
-
throw error;
|
|
59
|
-
},
|
|
60
|
-
0: async (error, response) => {
|
|
61
|
-
// Default error handler
|
|
62
|
-
console.error('Request failed:', error.message);
|
|
63
|
-
throw error;
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
beforeRetryHandlers: {
|
|
67
|
-
429: async (error, response) => {
|
|
68
|
-
// Handle rate limiting before retry
|
|
69
|
-
const retryAfter = response?.headers['retry-after'];
|
|
70
|
-
if (retryAfter) {
|
|
71
|
-
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
axiosConfigOverride: {
|
|
76
|
-
timeout: 10000,
|
|
77
|
-
retry: 3,
|
|
78
|
-
retryDelay: 2000
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Usage Examples
|
|
84
|
-
|
|
85
|
-
### Creating API Clients
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
import { createApi } from '@onivoro/isomorphic-axios';
|
|
89
|
-
import { DefaultApi } from './generated-client';
|
|
90
|
-
|
|
91
|
-
// Create an API client from generated OpenAPI client
|
|
92
|
-
const apiClient = createApi(DefaultApi, {
|
|
93
|
-
apiUrl: 'https://api.example.com',
|
|
94
|
-
accessToken: 'your-token'
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// Use the generated API methods
|
|
98
|
-
const users = await apiClient.getUsers();
|
|
99
|
-
const user = await apiClient.createUser({ name: 'John Doe' });
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Manual Retry Logic
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
import { retryAxiosCall } from '@onivoro/isomorphic-axios';
|
|
106
|
-
import axios from 'axios';
|
|
107
|
-
|
|
108
|
-
const instance = axios.create();
|
|
109
|
-
|
|
110
|
-
instance.interceptors.response.use(
|
|
111
|
-
response => response,
|
|
112
|
-
async (error) => {
|
|
113
|
-
if (shouldRetry(error)) {
|
|
114
|
-
return retryAxiosCall(error, instance);
|
|
115
|
-
}
|
|
116
|
-
throw error;
|
|
117
|
-
}
|
|
118
|
-
);
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### Environment-Specific Configuration
|
|
122
|
-
|
|
123
|
-
```typescript
|
|
124
|
-
import { createAxiosInstance } from '@onivoro/isomorphic-axios';
|
|
125
|
-
|
|
126
|
-
// Browser environment
|
|
127
|
-
const browserClient = createAxiosInstance({
|
|
128
|
-
apiUrl: window.location.origin + '/api',
|
|
129
|
-
accessToken: localStorage.getItem('token')
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
// Server environment
|
|
133
|
-
const serverClient = createAxiosInstance({
|
|
134
|
-
apiUrl: process.env.INTERNAL_API_URL,
|
|
135
|
-
accessToken: process.env.SERVICE_TOKEN
|
|
136
|
-
});
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Request/Response Interceptors
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
import { axiosInstanceFactory } from '@onivoro/isomorphic-axios';
|
|
143
|
-
|
|
144
|
-
const client = axiosInstanceFactory({
|
|
145
|
-
headerSetters: {
|
|
146
|
-
'X-Request-ID': () => generateRequestId(),
|
|
147
|
-
'X-User-Agent': () => getUserAgent(),
|
|
148
|
-
'X-Timestamp': () => new Date().toISOString()
|
|
149
|
-
},
|
|
150
|
-
errorHandlers: {
|
|
151
|
-
// Retry on network errors
|
|
152
|
-
0: async (error) => {
|
|
153
|
-
if (error.code === 'NETWORK_ERROR') {
|
|
154
|
-
throw new Error('Network connection failed');
|
|
155
|
-
}
|
|
156
|
-
throw error;
|
|
157
|
-
},
|
|
158
|
-
// Handle authentication errors
|
|
159
|
-
401: async (error) => {
|
|
160
|
-
await signOut();
|
|
161
|
-
window.location.href = '/login';
|
|
162
|
-
throw error;
|
|
163
|
-
},
|
|
164
|
-
// Handle validation errors
|
|
165
|
-
422: async (error) => {
|
|
166
|
-
const validationErrors = error.response?.data?.errors;
|
|
167
|
-
throw new ValidationError(validationErrors);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
## API Reference
|
|
174
|
-
|
|
175
|
-
### Functions
|
|
176
|
-
|
|
177
|
-
#### `axiosInstanceFactory<TData>(params)`
|
|
178
|
-
|
|
179
|
-
Creates a fully configured Axios instance with interceptors, retry logic, and error handling.
|
|
180
|
-
|
|
181
|
-
**Parameters:**
|
|
182
|
-
- `headerSetters`: Object mapping header names to functions that return header values
|
|
183
|
-
- `errorHandlers`: Object mapping HTTP status codes to error handling functions
|
|
184
|
-
- `beforeRetryHandlers`: Object mapping status codes to functions called before retries
|
|
185
|
-
- `axiosConfigOverride`: Optional Axios configuration overrides
|
|
186
|
-
|
|
187
|
-
**Returns:** Configured Axios instance
|
|
188
|
-
|
|
189
|
-
#### `createApi<TApi>(DefaultApi, config)`
|
|
190
|
-
|
|
191
|
-
Creates an API client instance from a generated OpenAPI client class.
|
|
192
|
-
|
|
193
|
-
**Parameters:**
|
|
194
|
-
- `DefaultApi`: Constructor function for the generated API client
|
|
195
|
-
- `config`: API configuration object with `apiUrl` and optional `accessToken`
|
|
196
|
-
|
|
197
|
-
**Returns:** Configured API client instance
|
|
198
|
-
|
|
199
|
-
#### `createAxiosInstance(config)`
|
|
200
|
-
|
|
201
|
-
Creates a simple Axios instance with basic authentication and URL configuration.
|
|
202
|
-
|
|
203
|
-
**Parameters:**
|
|
204
|
-
- `config`: Configuration object with `apiUrl` and optional `accessToken`
|
|
205
|
-
|
|
206
|
-
**Returns:** Configured Axios instance
|
|
207
|
-
|
|
208
|
-
#### `retryAxiosCall<TData>(error, instance)`
|
|
209
|
-
|
|
210
|
-
Manually retry a failed Axios request with exponential backoff.
|
|
211
|
-
|
|
212
|
-
**Parameters:**
|
|
213
|
-
- `error`: The error object from the failed request
|
|
214
|
-
- `instance`: The Axios instance to use for the retry
|
|
215
|
-
|
|
216
|
-
**Returns:** Promise resolving to the retry response
|
|
217
|
-
|
|
218
|
-
### Types
|
|
219
|
-
|
|
220
|
-
#### `TApiConfig`
|
|
221
|
-
|
|
222
|
-
Configuration interface for API clients:
|
|
223
|
-
```typescript
|
|
224
|
-
interface TApiConfig {
|
|
225
|
-
apiUrl: string;
|
|
226
|
-
accessToken?: string;
|
|
227
|
-
}
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
#### `THeaderSetterMap<TData>`
|
|
231
|
-
|
|
232
|
-
Map of header names to functions that set header values:
|
|
233
|
-
```typescript
|
|
234
|
-
type THeaderSetterMap<TData> = {
|
|
235
|
-
[headerName: string]: (request: AxiosRequestConfig) => string;
|
|
236
|
-
};
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
#### `TErrorHandlerMap<TData>`
|
|
240
|
-
|
|
241
|
-
Map of HTTP status codes to error handling functions:
|
|
242
|
-
```typescript
|
|
243
|
-
type TErrorHandlerMap<TData> = {
|
|
244
|
-
[statusCode: number]: TErrorHandler<TData>;
|
|
245
|
-
};
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
### Constants
|
|
249
|
-
|
|
250
|
-
#### `defaultAxiosConfig`
|
|
251
|
-
|
|
252
|
-
Default Axios configuration with sensible defaults:
|
|
253
|
-
```typescript
|
|
254
|
-
{
|
|
255
|
-
timeout: 30000,
|
|
256
|
-
retry: 2,
|
|
257
|
-
retryDelay: 1000
|
|
258
|
-
}
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
## Advanced Configuration
|
|
262
|
-
|
|
263
|
-
### Custom Error Recovery
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
import { axiosInstanceFactory } from '@onivoro/isomorphic-axios';
|
|
267
|
-
|
|
268
|
-
const resilientClient = axiosInstanceFactory({
|
|
269
|
-
errorHandlers: {
|
|
270
|
-
// Implement circuit breaker pattern
|
|
271
|
-
0: async (error) => {
|
|
272
|
-
if (circuitBreaker.isOpen()) {
|
|
273
|
-
throw new Error('Circuit breaker is open');
|
|
274
|
-
}
|
|
275
|
-
circuitBreaker.recordFailure();
|
|
276
|
-
throw error;
|
|
277
|
-
}
|
|
278
|
-
},
|
|
279
|
-
beforeRetryHandlers: {
|
|
280
|
-
// Implement exponential backoff with jitter
|
|
281
|
-
0: async (error) => {
|
|
282
|
-
const attempt = error.config.__retryCount || 0;
|
|
283
|
-
const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
|
|
284
|
-
const jitter = Math.random() * 1000;
|
|
285
|
-
await new Promise(resolve => setTimeout(resolve, delay + jitter));
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### Request/Response Logging
|
|
292
|
-
|
|
293
|
-
```typescript
|
|
294
|
-
const debugClient = axiosInstanceFactory({
|
|
295
|
-
headerSetters: {
|
|
296
|
-
'X-Debug-Mode': () => process.env.NODE_ENV === 'development' ? 'true' : 'false'
|
|
297
|
-
},
|
|
298
|
-
errorHandlers: {
|
|
299
|
-
0: async (error) => {
|
|
300
|
-
console.error('Request failed:', {
|
|
301
|
-
url: error.config?.url,
|
|
302
|
-
method: error.config?.method,
|
|
303
|
-
status: error.response?.status,
|
|
304
|
-
data: error.response?.data
|
|
305
|
-
});
|
|
306
|
-
throw error;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
});
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
## License
|
|
313
|
-
|
|
314
|
-
MIT
|
|
@@ -1,393 +0,0 @@
|
|
|
1
|
-
# @onivoro/isomorphic-common
|
|
2
|
-
|
|
3
|
-
Common utilities, functions, types, and constants shared between browser and server environments. This comprehensive library provides essential building blocks for TypeScript applications with a focus on type safety, reliability, and consistent behavior across different runtime environments.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @onivoro/isomorphic-common
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Features
|
|
12
|
-
|
|
13
|
-
- **Isomorphic Design**: Works identically in browser and Node.js environments
|
|
14
|
-
- **String Manipulation**: Case conversion, formatting, and validation utilities
|
|
15
|
-
- **Array Operations**: Chunking, sorting, deduplication, and transformation functions
|
|
16
|
-
- **Date/Time Utilities**: Calendar operations, offset calculations, and formatting
|
|
17
|
-
- **Financial Functions**: Currency formatting, money calculations, and validation
|
|
18
|
-
- **Type Utilities**: Advanced TypeScript type helpers and interfaces
|
|
19
|
-
- **Validation Functions**: Data validation and parsing utilities
|
|
20
|
-
- **Testing Helpers**: Mock functions and test arrangement utilities
|
|
21
|
-
- **Constants**: Common values, regex patterns, and configuration constants
|
|
22
|
-
|
|
23
|
-
## Quick Start
|
|
24
|
-
|
|
25
|
-
### String Operations
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
import {
|
|
29
|
-
camelCase,
|
|
30
|
-
kebabCase,
|
|
31
|
-
snakeCase,
|
|
32
|
-
upperFirst,
|
|
33
|
-
sanitizeFilename,
|
|
34
|
-
formatUsd
|
|
35
|
-
} from '@onivoro/isomorphic-common';
|
|
36
|
-
|
|
37
|
-
// Case conversions
|
|
38
|
-
camelCase('hello world'); // 'helloWorld'
|
|
39
|
-
kebabCase('Hello World'); // 'hello-world'
|
|
40
|
-
snakeCase('Hello World'); // 'hello_world'
|
|
41
|
-
upperFirst('hello'); // 'Hello'
|
|
42
|
-
|
|
43
|
-
// File operations
|
|
44
|
-
sanitizeFilename('My File/Name?.txt'); // 'My File Name .txt'
|
|
45
|
-
|
|
46
|
-
// Currency formatting
|
|
47
|
-
formatUsd(1234.56); // '$1,234.56'
|
|
48
|
-
formatUsd('1234.56'); // '$1,234.56'
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Array Manipulation
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
import {
|
|
55
|
-
chunk,
|
|
56
|
-
toUniqueArray,
|
|
57
|
-
removeElementAtIndex,
|
|
58
|
-
sortByName,
|
|
59
|
-
sortById,
|
|
60
|
-
sortNumbers
|
|
61
|
-
} from '@onivoro/isomorphic-common';
|
|
62
|
-
|
|
63
|
-
// Chunking arrays
|
|
64
|
-
chunk([1, 2, 3, 4, 5, 6], 3); // [[1, 2], [3, 4], [5, 6]]
|
|
65
|
-
|
|
66
|
-
// Remove duplicates
|
|
67
|
-
toUniqueArray([1, 2, 2, 3, 3, 4]); // [1, 2, 3, 4]
|
|
68
|
-
|
|
69
|
-
// Remove element by index
|
|
70
|
-
removeElementAtIndex(['a', 'b', 'c'], 1); // ['a', 'c']
|
|
71
|
-
|
|
72
|
-
// Sorting utilities
|
|
73
|
-
sortByName([{name: 'Bob'}, {name: 'Alice'}]); // [{name: 'Alice'}, {name: 'Bob'}]
|
|
74
|
-
sortById([{id: 3}, {id: 1}, {id: 2}]); // [{id: 1}, {id: 2}, {id: 3}]
|
|
75
|
-
sortNumbers([3, 1, 4, 1, 5]); // [1, 1, 3, 4, 5]
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Date and Time Operations
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
import {
|
|
82
|
-
addOffset,
|
|
83
|
-
subtractOffset,
|
|
84
|
-
getDateRangeForMonth,
|
|
85
|
-
splitDateRangeIntoDays,
|
|
86
|
-
isValidDate,
|
|
87
|
-
tryParseDate,
|
|
88
|
-
toCalendarDate,
|
|
89
|
-
fromCalendarDate
|
|
90
|
-
} from '@onivoro/isomorphic-common';
|
|
91
|
-
|
|
92
|
-
// Date offset calculations
|
|
93
|
-
const date = new Date('2023-01-15');
|
|
94
|
-
addOffset(date, 7); // Add 7 days
|
|
95
|
-
subtractOffset(date, 2); // Subtract 2 days
|
|
96
|
-
|
|
97
|
-
// Monthly date ranges
|
|
98
|
-
getDateRangeForMonth(2023, 0); // January 2023 range
|
|
99
|
-
|
|
100
|
-
// Date validation
|
|
101
|
-
isValidDate(new Date('2023-01-15')); // true
|
|
102
|
-
isValidDate(new Date('invalid')); // false
|
|
103
|
-
|
|
104
|
-
// Safe date parsing
|
|
105
|
-
tryParseDate('2023-01-15'); // Date object or null
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### Financial and Money Operations
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
import {
|
|
112
|
-
money,
|
|
113
|
-
toDollarsAndCents,
|
|
114
|
-
round,
|
|
115
|
-
formatUsd
|
|
116
|
-
} from '@onivoro/isomorphic-common';
|
|
117
|
-
|
|
118
|
-
// Money calculations (in cents)
|
|
119
|
-
const price = money(19.99); // 1999 cents
|
|
120
|
-
const tax = money(price * 0.08); // Calculate tax
|
|
121
|
-
const total = price + tax;
|
|
122
|
-
|
|
123
|
-
// Convert back to dollars
|
|
124
|
-
toDollarsAndCents(total); // { dollars: 21, cents: 59 }
|
|
125
|
-
|
|
126
|
-
// Rounding
|
|
127
|
-
round(19.999, 2); // 20.00
|
|
128
|
-
round(19.994, 2); // 19.99
|
|
129
|
-
|
|
130
|
-
// Currency display
|
|
131
|
-
formatUsd(total / 100); // '$21.59'
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
## Usage Examples
|
|
135
|
-
|
|
136
|
-
### Data Transformation
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
import {
|
|
140
|
-
mapEnumToOptions,
|
|
141
|
-
mapEntitiesToOptions,
|
|
142
|
-
convertObjectToLiteral,
|
|
143
|
-
propertiestoArray
|
|
144
|
-
} from '@onivoro/isomorphic-common';
|
|
145
|
-
|
|
146
|
-
enum Status {
|
|
147
|
-
ACTIVE = 'active',
|
|
148
|
-
INACTIVE = 'inactive',
|
|
149
|
-
PENDING = 'pending'
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Convert enum to dropdown options
|
|
153
|
-
const statusOptions = mapEnumToOptions(Status);
|
|
154
|
-
// [{ label: 'Active', value: 'active' }, ...]
|
|
155
|
-
|
|
156
|
-
// Convert entities to options
|
|
157
|
-
const users = [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }];
|
|
158
|
-
const userOptions = mapEntitiesToOptions(users, 'name', 'id');
|
|
159
|
-
// [{ label: 'John', value: 1 }, { label: 'Jane', value: 2 }]
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Boolean and String Parsing
|
|
163
|
-
|
|
164
|
-
```typescript
|
|
165
|
-
import {
|
|
166
|
-
parseBool,
|
|
167
|
-
fromBooleanString,
|
|
168
|
-
toBooleanString,
|
|
169
|
-
fromCsvString,
|
|
170
|
-
toCsvString
|
|
171
|
-
} from '@onivoro/isomorphic-common';
|
|
172
|
-
|
|
173
|
-
// Boolean parsing
|
|
174
|
-
parseBool('true'); // true
|
|
175
|
-
parseBool('1'); // true
|
|
176
|
-
parseBool('yes'); // true
|
|
177
|
-
parseBool('false'); // false
|
|
178
|
-
|
|
179
|
-
// CSV operations
|
|
180
|
-
const items = fromCsvString('apple,banana,cherry');
|
|
181
|
-
// ['apple', 'banana', 'cherry']
|
|
182
|
-
|
|
183
|
-
toCsvString(['apple', 'banana', 'cherry']);
|
|
184
|
-
// 'apple,banana,cherry'
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### Testing Utilities
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
import {
|
|
191
|
-
arrangeActAssert,
|
|
192
|
-
mockCalls
|
|
193
|
-
} from '@onivoro/isomorphic-common';
|
|
194
|
-
|
|
195
|
-
// Test structure helper
|
|
196
|
-
const testCase = arrangeActAssert({
|
|
197
|
-
arrange: () => ({ input: 'test data' }),
|
|
198
|
-
act: (arranged) => processData(arranged.input),
|
|
199
|
-
assert: (result) => expect(result).toBeTruthy()
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// Mock function calls tracking
|
|
203
|
-
const mockTracker = mockCalls();
|
|
204
|
-
mockTracker.track('functionName', ['arg1', 'arg2']);
|
|
205
|
-
mockTracker.getCalls('functionName'); // [['arg1', 'arg2']]
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## API Reference
|
|
209
|
-
|
|
210
|
-
### String Functions
|
|
211
|
-
|
|
212
|
-
#### Case Conversion
|
|
213
|
-
- `camelCase(string)` - Convert to camelCase
|
|
214
|
-
- `kebabCase(string)` - Convert to kebab-case
|
|
215
|
-
- `snakeCase(string)` - Convert to snake_case
|
|
216
|
-
- `upperFirst(string)` - Capitalize first letter
|
|
217
|
-
|
|
218
|
-
#### String Utilities
|
|
219
|
-
- `sanitizeFilename(filename)` - Remove invalid filename characters
|
|
220
|
-
- `removeAlphaChars(string)` - Remove alphabetic characters
|
|
221
|
-
- `words(string)` - Split string into words array
|
|
222
|
-
- `toString(value)` - Convert value to string safely
|
|
223
|
-
|
|
224
|
-
### Array Functions
|
|
225
|
-
|
|
226
|
-
#### Array Manipulation
|
|
227
|
-
- `chunk<T>(array, numDivisions)` - Split array into chunks
|
|
228
|
-
- `toUniqueArray<T>(array)` - Remove duplicate elements
|
|
229
|
-
- `removeElementAtIndex<T>(array, index)` - Remove element by index
|
|
230
|
-
|
|
231
|
-
#### Sorting Functions
|
|
232
|
-
- `sortByName<T>(array)` - Sort objects by name property
|
|
233
|
-
- `sortById<T>(array)` - Sort objects by id property
|
|
234
|
-
- `sortByFullName<T>(array)` - Sort objects by full name
|
|
235
|
-
- `sortByCreatedAt<T>(array)` - Sort objects by creation date
|
|
236
|
-
- `sortNumbers(array)` - Sort numeric array
|
|
237
|
-
|
|
238
|
-
### Date/Time Functions
|
|
239
|
-
|
|
240
|
-
#### Date Operations
|
|
241
|
-
- `addOffset(date, days)` - Add days to date
|
|
242
|
-
- `subtractOffset(date, days)` - Subtract days from date
|
|
243
|
-
- `getDateRangeForMonth(year, month)` - Get month's date range
|
|
244
|
-
- `getDateLastMonth()` - Get previous month's date
|
|
245
|
-
- `splitDateRangeIntoDays(start, end)` - Split range into daily intervals
|
|
246
|
-
|
|
247
|
-
#### Date Utilities
|
|
248
|
-
- `isValidDate(date)` - Check if date is valid
|
|
249
|
-
- `tryParseDate(string)` - Safely parse date string
|
|
250
|
-
- `toCalendarDate(date)` - Convert to calendar format
|
|
251
|
-
- `fromCalendarDate(string)` - Parse calendar date string
|
|
252
|
-
- `useDate(date)` - React hook for date handling
|
|
253
|
-
|
|
254
|
-
#### Time Constants
|
|
255
|
-
- `MILLIS_PER_MINUTE` - Milliseconds in a minute
|
|
256
|
-
- `MILLIS_PER_HOUR` - Milliseconds in an hour
|
|
257
|
-
- `MILLIS_PER_DAY` - Milliseconds in a day
|
|
258
|
-
|
|
259
|
-
### Financial Functions
|
|
260
|
-
|
|
261
|
-
#### Money Operations
|
|
262
|
-
- `money(amount)` - Convert dollars to cents
|
|
263
|
-
- `toDollarsAndCents(cents)` - Convert cents to dollars/cents object
|
|
264
|
-
- `formatUsd(amount)` - Format as USD currency
|
|
265
|
-
- `round(number, precision)` - Round to decimal places
|
|
266
|
-
|
|
267
|
-
### Type Utilities
|
|
268
|
-
|
|
269
|
-
#### Interfaces
|
|
270
|
-
- `ILookup<T>` - Key-value lookup interface
|
|
271
|
-
- `IAccessToken` - Access token structure
|
|
272
|
-
- `IEntityProvider<T>` - Entity provider interface
|
|
273
|
-
|
|
274
|
-
#### Type Helpers
|
|
275
|
-
- `KeysOf<T>` - Extract keys of type T
|
|
276
|
-
- `Createable<T>` - Type for creatable entities
|
|
277
|
-
- `Nameable` - Type for entities with name property
|
|
278
|
-
- `Company` - Company type definition
|
|
279
|
-
|
|
280
|
-
### Data Transformation
|
|
281
|
-
|
|
282
|
-
#### Enum Utilities
|
|
283
|
-
- `mapEnumToOptions(enum)` - Convert enum to option array
|
|
284
|
-
- `mapEnumToArrayOfValues(enum)` - Convert enum to value array
|
|
285
|
-
- `mapEnumToLookupArray(enum)` - Convert enum to lookup array
|
|
286
|
-
|
|
287
|
-
#### Object Utilities
|
|
288
|
-
- `convertObjectToLiteral(object)` - Convert to literal object
|
|
289
|
-
- `propertiesToArray(object)` - Convert properties to array
|
|
290
|
-
- `mapEntitiesToOptions(entities, labelKey, valueKey)` - Convert entities to options
|
|
291
|
-
|
|
292
|
-
### Validation Functions
|
|
293
|
-
|
|
294
|
-
#### Data Validation
|
|
295
|
-
- `parseBool(value)` - Parse boolean from various formats
|
|
296
|
-
- `isSymbol(value)` - Check if value is symbol
|
|
297
|
-
- `tryJsonParse(string)` - Safely parse JSON
|
|
298
|
-
- `tryJsonStringify(object)` - Safely stringify JSON
|
|
299
|
-
|
|
300
|
-
#### String Validation
|
|
301
|
-
- `fromBooleanString(string)` - Convert string to boolean
|
|
302
|
-
- `toBooleanString(boolean)` - Convert boolean to string
|
|
303
|
-
- `fromCsvString(string)` - Parse CSV string
|
|
304
|
-
- `toCsvString(array)` - Convert array to CSV
|
|
305
|
-
|
|
306
|
-
### Utility Functions
|
|
307
|
-
|
|
308
|
-
#### General Utilities
|
|
309
|
-
- `sleep(milliseconds)` - Async sleep function
|
|
310
|
-
- `getTag(value)` - Get object type tag
|
|
311
|
-
- `getUserFullName(user)` - Get user's full name
|
|
312
|
-
- `toDecimalBase(number, base)` - Convert to decimal base
|
|
313
|
-
|
|
314
|
-
#### Testing Helpers
|
|
315
|
-
- `arrangeActAssert(config)` - Structure test cases
|
|
316
|
-
- `mockCalls()` - Track mock function calls
|
|
317
|
-
|
|
318
|
-
### Constants
|
|
319
|
-
|
|
320
|
-
#### Headers and Authentication
|
|
321
|
-
- `API_ID_HEADER` - API ID header constant
|
|
322
|
-
- `API_KEY_HEADER` - API key header constant
|
|
323
|
-
- `AUTH_COOKIE_NAME` - Authentication cookie name
|
|
324
|
-
|
|
325
|
-
#### Regular Expressions
|
|
326
|
-
- `REGEXES` - Common regex patterns object
|
|
327
|
-
|
|
328
|
-
## Advanced Usage
|
|
329
|
-
|
|
330
|
-
### Custom Type Guards
|
|
331
|
-
|
|
332
|
-
```typescript
|
|
333
|
-
import { isSymbol, isValidDate } from '@onivoro/isomorphic-common';
|
|
334
|
-
|
|
335
|
-
function processValue(value: unknown) {
|
|
336
|
-
if (isSymbol(value)) {
|
|
337
|
-
return value.toString();
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
if (value instanceof Date && isValidDate(value)) {
|
|
341
|
-
return value.toISOString();
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
return String(value);
|
|
345
|
-
}
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
### Complex Data Transformations
|
|
349
|
-
|
|
350
|
-
```typescript
|
|
351
|
-
import {
|
|
352
|
-
chunk,
|
|
353
|
-
mapEntitiesToOptions,
|
|
354
|
-
sortByName,
|
|
355
|
-
toUniqueArray
|
|
356
|
-
} from '@onivoro/isomorphic-common';
|
|
357
|
-
|
|
358
|
-
function processUserData(users: User[]) {
|
|
359
|
-
return chunk(
|
|
360
|
-
toUniqueArray(
|
|
361
|
-
sortByName(users)
|
|
362
|
-
),
|
|
363
|
-
10 // Process in batches of 10
|
|
364
|
-
).map(batch =>
|
|
365
|
-
mapEntitiesToOptions(batch, 'fullName', 'id')
|
|
366
|
-
);
|
|
367
|
-
}
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
### Date Range Operations
|
|
371
|
-
|
|
372
|
-
```typescript
|
|
373
|
-
import {
|
|
374
|
-
getDateRangeForMonth,
|
|
375
|
-
splitDateRangeIntoDays,
|
|
376
|
-
addOffset,
|
|
377
|
-
subtractOffset
|
|
378
|
-
} from '@onivoro/isomorphic-common';
|
|
379
|
-
|
|
380
|
-
function getMonthlyReportDates(year: number, month: number) {
|
|
381
|
-
const { start, end } = getDateRangeForMonth(year, month);
|
|
382
|
-
|
|
383
|
-
// Add buffer days
|
|
384
|
-
const reportStart = subtractOffset(start, 1);
|
|
385
|
-
const reportEnd = addOffset(end, 1);
|
|
386
|
-
|
|
387
|
-
return splitDateRangeIntoDays(reportStart, reportEnd);
|
|
388
|
-
}
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
## License
|
|
392
|
-
|
|
393
|
-
MIT
|