@umituz/react-native-design-system 4.25.8 → 4.25.10
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/package.json +1 -1
- package/src/atoms/AtomicAvatar.tsx +0 -5
- package/src/atoms/AtomicInput.tsx +0 -2
- package/src/atoms/AtomicProgress.tsx +0 -5
- package/src/atoms/AtomicTextArea.tsx +0 -4
- package/src/atoms/card/AtomicCard.tsx +111 -54
- package/src/atoms/input/types.ts +0 -2
- package/src/atoms/skeleton/AtomicSkeleton.tsx +2 -2
- package/src/image/presentation/components/ImageGallery.tsx +16 -15
- package/src/image/presentation/components/editor/StickerPickerSheet.tsx +4 -7
- package/src/index.ts +5 -0
- package/src/layouts/ScreenHeader/ScreenHeader.tsx +0 -2
- package/src/loading/presentation/providers/LoadingProvider.tsx +13 -4
- package/src/molecules/SearchBar/SearchBar.tsx +0 -2
- package/src/molecules/SearchBar/SearchSuggestions.tsx +1 -1
- package/src/molecules/SearchBar/types.ts +0 -1
- package/src/molecules/StepHeader/StepHeader.tsx +1 -1
- package/src/molecules/avatar/Avatar.tsx +76 -71
- package/src/molecules/avatar/AvatarGroup.tsx +1 -1
- package/src/molecules/calendar/presentation/components/CalendarDayCell.tsx +2 -3
- package/src/molecules/calendar/presentation/components/CalendarWeekdayHeader.tsx +1 -1
- package/src/molecules/countdown/components/Countdown.tsx +14 -11
- package/src/molecules/info-grid/InfoGrid.tsx +2 -2
- package/src/onboarding/presentation/components/BackgroundImageCollage.tsx +2 -2
- package/src/onboarding/presentation/components/OnboardingBackground.tsx +63 -49
- package/src/onboarding/presentation/components/OnboardingSlide.tsx +2 -2
- package/src/theme/infrastructure/providers/DesignSystemProvider.tsx +3 -1
- package/src/gallery/gallery-download.service.ts +0 -69
- package/src/gallery/gallery-save.service.ts +0 -80
- package/src/gallery/index.ts +0 -3
- package/src/gallery/types.ts +0 -11
- package/src/image/domain/entities/EditorTypes.ts +0 -23
- package/src/image/domain/entities/editor/EditorConfigTypes.ts +0 -35
- package/src/image/domain/entities/editor/EditorElementTypes.ts +0 -60
- package/src/image/domain/entities/editor/EditorFilterTypes.ts +0 -9
- package/src/image/domain/entities/editor/EditorLayerTypes.ts +0 -34
- package/src/image/domain/entities/editor/EditorStateTypes.ts +0 -35
- package/src/image/domain/entities/editor/EditorToolTypes.ts +0 -33
- package/src/image/infrastructure/services/ImageEditorService.ts +0 -134
- package/src/image/infrastructure/utils/ImageAnalysisUtils.ts +0 -120
- package/src/image/infrastructure/utils/ImageEditorHistoryUtils.ts +0 -63
- package/src/image/infrastructure/utils/LayerManager.ts +0 -65
- package/src/media/infrastructure/hooks/useGenericMediaGeneration.ts +0 -170
- package/src/molecules/ConfirmationModal.tsx +0 -42
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.types.ts +0 -64
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.utils.ts +0 -56
- package/src/molecules/calendar/infrastructure/storage/EventActions.ts +0 -140
- package/src/molecules/calendar/infrastructure/storage/NavigationActions.ts +0 -118
- package/src/molecules/calendar/presentation/hooks/useCalendar.ts +0 -185
- package/src/molecules/confirmation-modal/index.ts +0 -7
- package/src/molecules/listitem/index.ts +0 -6
- package/src/molecules/navigation/components/index.ts +0 -4
- package/src/molecules/navigation/utils/NavigationTheme.ts +0 -21
- package/src/presentation/utils/variants/compound.ts +0 -34
- package/src/services/api/ApiClient.ts +0 -180
- package/src/services/api/index.ts +0 -9
- package/src/services/api/types/ApiTypes.ts +0 -50
- package/src/services/api/utils/requestBuilder.ts +0 -92
- package/src/services/api/utils/responseHandler.ts +0 -130
- package/src/storage/cache/index.ts +0 -28
- package/src/theme/core/tokens/BorderRadius.ts +0 -16
- package/src/utilities/clipboard/ClipboardUtils.ts +0 -67
- package/src/utilities/clipboard/index.ts +0 -5
- package/src/utilities/index.ts +0 -6
- package/src/utilities/sharing/domain/entities/Share.ts +0 -104
- package/src/utilities/sharing/domain/entities/SharingUtils.ts +0 -111
- package/src/utilities/sharing/index.ts +0 -33
- package/src/utilities/sharing/infrastructure/services/SharingService.ts +0 -165
- package/src/utilities/sharing/presentation/hooks/useSharing.ts +0 -116
- package/src/utils/colorMapper.ts +0 -193
- package/src/utils/errors/adapters/CacheErrorAdapter.ts +0 -68
- package/src/utils/errors/adapters/ImageErrorAdapter.ts +0 -91
- package/src/utils/errors/adapters/StorageErrorAdapter.ts +0 -107
- package/src/utils/formatHelper.ts +0 -16
- package/src/utils/formatters/dateFormatter.ts +0 -64
- package/src/utils/formatters/numberFormatter.ts +0 -130
- package/src/utils/index.ts +0 -16
- package/src/utils/styleComposer.ts +0 -94
- package/src/utils/validationHelper.ts +0 -16
- package/src/utils/validators/dataValidators.ts +0 -111
- package/src/utils/validators/numericValidators.ts +0 -106
- package/src/utils/validators/stringValidators.ts +0 -85
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useCalendar Hook
|
|
3
|
-
*
|
|
4
|
-
* Main hook for calendar functionality.
|
|
5
|
-
* Provides calendar state, events, and actions.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* ```tsx
|
|
9
|
-
* const {
|
|
10
|
-
* days,
|
|
11
|
-
* events,
|
|
12
|
-
* selectedDate,
|
|
13
|
-
* viewMode,
|
|
14
|
-
* actions
|
|
15
|
-
* } = useCalendar();
|
|
16
|
-
*
|
|
17
|
-
* // Navigate calendar
|
|
18
|
-
* actions.navigateMonth('next');
|
|
19
|
-
*
|
|
20
|
-
* // Add event
|
|
21
|
-
* actions.addEvent({
|
|
22
|
-
* title: 'Team Meeting',
|
|
23
|
-
* date: '2024-10-30',
|
|
24
|
-
* time: '14:00',
|
|
25
|
-
* });
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
import { useMemo, useEffect } from 'react';
|
|
30
|
-
import { useCalendarStore, type CalendarViewMode } from '../../infrastructure/storage/CalendarStore';
|
|
31
|
-
import type { CalendarDay } from '../../domain/entities/CalendarDay.entity';
|
|
32
|
-
import type { CalendarEvent, CreateCalendarEventRequest, UpdateCalendarEventRequest } from '../../domain/entities/CalendarEvent.entity';
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Calendar hook return type
|
|
36
|
-
*/
|
|
37
|
-
export interface UseCalendarReturn {
|
|
38
|
-
// Calendar data
|
|
39
|
-
days: CalendarDay[];
|
|
40
|
-
events: CalendarEvent[];
|
|
41
|
-
selectedDate: Date;
|
|
42
|
-
currentMonth: Date;
|
|
43
|
-
viewMode: CalendarViewMode;
|
|
44
|
-
|
|
45
|
-
// Computed data
|
|
46
|
-
selectedDateEvents: CalendarEvent[];
|
|
47
|
-
currentMonthEvents: CalendarEvent[];
|
|
48
|
-
|
|
49
|
-
// State
|
|
50
|
-
isLoading: boolean;
|
|
51
|
-
error: string | null;
|
|
52
|
-
|
|
53
|
-
// Actions
|
|
54
|
-
actions: {
|
|
55
|
-
loadEvents: () => Promise<void>;
|
|
56
|
-
addEvent: (request: CreateCalendarEventRequest) => Promise<void>;
|
|
57
|
-
updateEvent: (request: UpdateCalendarEventRequest) => Promise<void>;
|
|
58
|
-
deleteEvent: (id: string) => Promise<void>;
|
|
59
|
-
completeEvent: (id: string) => Promise<void>;
|
|
60
|
-
uncompleteEvent: (id: string) => Promise<void>;
|
|
61
|
-
setSelectedDate: (date: Date) => void;
|
|
62
|
-
goToToday: () => void;
|
|
63
|
-
navigateMonth: (direction: 'prev' | 'next') => void;
|
|
64
|
-
setCurrentMonth: (date: Date) => void;
|
|
65
|
-
setViewMode: (mode: CalendarViewMode) => void;
|
|
66
|
-
getEventsForDate: (date: Date) => CalendarEvent[];
|
|
67
|
-
getEventsForMonth: (year: number, month: number) => CalendarEvent[];
|
|
68
|
-
clearError: () => void;
|
|
69
|
-
clearAllEvents: () => Promise<void>;
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Main calendar hook
|
|
75
|
-
*/
|
|
76
|
-
export const useCalendarPresentation = (): UseCalendarReturn => {
|
|
77
|
-
const store = useCalendarStore();
|
|
78
|
-
const {
|
|
79
|
-
events,
|
|
80
|
-
selectedDate,
|
|
81
|
-
currentMonth,
|
|
82
|
-
viewMode,
|
|
83
|
-
isLoading,
|
|
84
|
-
error,
|
|
85
|
-
actions,
|
|
86
|
-
} = store;
|
|
87
|
-
|
|
88
|
-
// Load events on mount
|
|
89
|
-
useEffect(() => {
|
|
90
|
-
actions.loadEvents();
|
|
91
|
-
}, [actions.loadEvents]);
|
|
92
|
-
|
|
93
|
-
// Get events for selected date
|
|
94
|
-
const selectedDateEvents = useMemo(() => {
|
|
95
|
-
return events.filter(event => {
|
|
96
|
-
const eventDate = new Date(event.date);
|
|
97
|
-
return eventDate.toDateString() === selectedDate.toDateString();
|
|
98
|
-
});
|
|
99
|
-
}, [selectedDate, events]);
|
|
100
|
-
|
|
101
|
-
// Get events for current month
|
|
102
|
-
const currentMonthEvents = useMemo(() => {
|
|
103
|
-
const year = currentMonth.getFullYear();
|
|
104
|
-
const month = currentMonth.getMonth();
|
|
105
|
-
return events.filter(event => {
|
|
106
|
-
const eventDate = new Date(event.date);
|
|
107
|
-
return eventDate.getFullYear() === year && eventDate.getMonth() === month;
|
|
108
|
-
});
|
|
109
|
-
}, [currentMonth, events]);
|
|
110
|
-
|
|
111
|
-
return {
|
|
112
|
-
days: store.days,
|
|
113
|
-
events,
|
|
114
|
-
selectedDate,
|
|
115
|
-
currentMonth,
|
|
116
|
-
viewMode,
|
|
117
|
-
selectedDateEvents,
|
|
118
|
-
currentMonthEvents,
|
|
119
|
-
isLoading,
|
|
120
|
-
error,
|
|
121
|
-
actions,
|
|
122
|
-
};
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Hook for calendar navigation
|
|
127
|
-
* Lightweight hook for just navigation actions
|
|
128
|
-
*/
|
|
129
|
-
export const useCalendarNavigation = () => {
|
|
130
|
-
const store = useCalendarStore();
|
|
131
|
-
const {
|
|
132
|
-
selectedDate,
|
|
133
|
-
currentMonth,
|
|
134
|
-
actions: { setSelectedDate, navigateMonth, goToToday, setCurrentMonth },
|
|
135
|
-
} = store;
|
|
136
|
-
|
|
137
|
-
return {
|
|
138
|
-
selectedDate,
|
|
139
|
-
currentMonth,
|
|
140
|
-
setSelectedDate,
|
|
141
|
-
navigateMonth,
|
|
142
|
-
goToToday,
|
|
143
|
-
setCurrentMonth,
|
|
144
|
-
};
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Hook for calendar events only
|
|
149
|
-
* Lightweight hook for just event operations
|
|
150
|
-
*/
|
|
151
|
-
export const useCalendarEvents = () => {
|
|
152
|
-
const store = useCalendarStore();
|
|
153
|
-
const {
|
|
154
|
-
events,
|
|
155
|
-
isLoading,
|
|
156
|
-
error,
|
|
157
|
-
actions: {
|
|
158
|
-
loadEvents,
|
|
159
|
-
addEvent,
|
|
160
|
-
updateEvent,
|
|
161
|
-
deleteEvent,
|
|
162
|
-
completeEvent,
|
|
163
|
-
uncompleteEvent,
|
|
164
|
-
clearError,
|
|
165
|
-
},
|
|
166
|
-
} = store;
|
|
167
|
-
|
|
168
|
-
return {
|
|
169
|
-
events,
|
|
170
|
-
isLoading,
|
|
171
|
-
error,
|
|
172
|
-
loadEvents,
|
|
173
|
-
addEvent,
|
|
174
|
-
updateEvent,
|
|
175
|
-
deleteEvent,
|
|
176
|
-
completeEvent,
|
|
177
|
-
uncompleteEvent,
|
|
178
|
-
clearError,
|
|
179
|
-
};
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
// Re-export for convenience
|
|
183
|
-
export { useCalendar, useCalendarStore } from '../../infrastructure/storage/CalendarStore';
|
|
184
|
-
export type { CalendarViewMode } from '../../infrastructure/storage/CalendarStore';
|
|
185
|
-
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { DefaultTheme as NavigationDefaultTheme, DarkTheme as NavigationDarkTheme, Theme } from '@react-navigation/native';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Create a navigation theme based on design tokens and mode
|
|
5
|
-
*/
|
|
6
|
-
export const createNavigationTheme = (colors: Record<string, string>, mode: 'light' | 'dark'): Theme => {
|
|
7
|
-
const baseTheme = mode === 'dark' ? NavigationDarkTheme : NavigationDefaultTheme;
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
...baseTheme,
|
|
11
|
-
colors: {
|
|
12
|
-
...baseTheme.colors,
|
|
13
|
-
primary: colors.primary ?? baseTheme.colors.primary,
|
|
14
|
-
background: colors.backgroundPrimary ?? baseTheme.colors.background,
|
|
15
|
-
card: colors.surface ?? baseTheme.colors.card,
|
|
16
|
-
text: colors.textPrimary ?? baseTheme.colors.text,
|
|
17
|
-
border: colors.border ?? baseTheme.colors.border,
|
|
18
|
-
notification: colors.error ?? baseTheme.colors.notification,
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { Style, VariantConfig, VariantProps, createVariants } from './core';
|
|
2
|
-
|
|
3
|
-
export interface CompoundVariant<T extends Record<string, Record<string, Style>>> {
|
|
4
|
-
conditions: Partial<VariantProps<T>>;
|
|
5
|
-
style: Style;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface AdvancedVariantConfig<T extends Record<string, Record<string, Style>>>
|
|
9
|
-
extends VariantConfig<T> {
|
|
10
|
-
compoundVariants?: CompoundVariant<T>[];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function createAdvancedVariants<T extends Record<string, Record<string, Style>>>(
|
|
14
|
-
config: AdvancedVariantConfig<T>
|
|
15
|
-
) {
|
|
16
|
-
const baseVariantFn = createVariants(config);
|
|
17
|
-
|
|
18
|
-
return (props: VariantProps<T> = {}): Style => {
|
|
19
|
-
let result = baseVariantFn(props);
|
|
20
|
-
|
|
21
|
-
if (config.compoundVariants) {
|
|
22
|
-
config.compoundVariants.forEach(compound => {
|
|
23
|
-
const conditionsMet = Object.entries(compound.conditions).every(
|
|
24
|
-
([key, value]) => props[key as keyof T] === value
|
|
25
|
-
);
|
|
26
|
-
if (conditionsMet) {
|
|
27
|
-
result = { ...result, ...compound.style };
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
}
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* API Client
|
|
3
|
-
* Centralized HTTP client for API communication
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type {
|
|
7
|
-
ApiClientConfig,
|
|
8
|
-
ApiRequestConfig,
|
|
9
|
-
ApiResponse,
|
|
10
|
-
HttpMethod,
|
|
11
|
-
} from './types/ApiTypes';
|
|
12
|
-
import {
|
|
13
|
-
buildURL,
|
|
14
|
-
buildRequestConfig,
|
|
15
|
-
} from './utils/requestBuilder';
|
|
16
|
-
import {
|
|
17
|
-
parseResponse,
|
|
18
|
-
handleHttpError,
|
|
19
|
-
handleNetworkError,
|
|
20
|
-
isSuccessfulResponse,
|
|
21
|
-
fetchWithTimeout,
|
|
22
|
-
} from './utils/responseHandler';
|
|
23
|
-
import { retryWithBackoff, isNetworkError, isRetryableHttpStatus } from '../../utils/async';
|
|
24
|
-
import { ErrorHandler } from '../../utils/errors';
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Applies interceptors to a value
|
|
28
|
-
*/
|
|
29
|
-
async function applyInterceptors<T>(
|
|
30
|
-
value: T,
|
|
31
|
-
interceptors: Array<(value: T) => T | Promise<T>> | undefined
|
|
32
|
-
): Promise<T> {
|
|
33
|
-
let result = value;
|
|
34
|
-
for (const interceptor of interceptors || []) {
|
|
35
|
-
result = await interceptor(result);
|
|
36
|
-
}
|
|
37
|
-
return result;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export class ApiClient {
|
|
41
|
-
private config: ApiClientConfig;
|
|
42
|
-
|
|
43
|
-
constructor(config: ApiClientConfig) {
|
|
44
|
-
this.config = {
|
|
45
|
-
timeout: 30000,
|
|
46
|
-
...config,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Makes an HTTP request with automatic retry for retryable errors
|
|
52
|
-
*/
|
|
53
|
-
async request<T>(requestConfig: ApiRequestConfig): Promise<ApiResponse<T>> {
|
|
54
|
-
try {
|
|
55
|
-
const config = await applyInterceptors(requestConfig, this.config.requestInterceptors);
|
|
56
|
-
|
|
57
|
-
const fullURL = config.url.startsWith('http')
|
|
58
|
-
? config.url
|
|
59
|
-
: buildURL(this.config.baseURL, config.url, config.params);
|
|
60
|
-
|
|
61
|
-
const fetchOptions = buildRequestConfig({
|
|
62
|
-
...config,
|
|
63
|
-
headers: { ...this.config.headers, ...config.headers },
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// Retry only for GET requests and retryable errors
|
|
67
|
-
const shouldRetry = config.method === 'GET';
|
|
68
|
-
const timeout = config.timeout || this.config.timeout || 30000;
|
|
69
|
-
|
|
70
|
-
const response = shouldRetry
|
|
71
|
-
? await retryWithBackoff(
|
|
72
|
-
() => fetchWithTimeout(fullURL, fetchOptions, timeout),
|
|
73
|
-
{
|
|
74
|
-
maxRetries: 3,
|
|
75
|
-
baseDelay: 1000,
|
|
76
|
-
shouldRetry: (error) => {
|
|
77
|
-
// Retry on network errors
|
|
78
|
-
if (isNetworkError(error as Error)) return true;
|
|
79
|
-
|
|
80
|
-
// Retry on specific HTTP status codes (5xx, 429, 408)
|
|
81
|
-
if ('status' in error && typeof error.status === 'number') {
|
|
82
|
-
return isRetryableHttpStatus(error.status);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return false;
|
|
86
|
-
},
|
|
87
|
-
onRetry: (error, attempt, delay) => {
|
|
88
|
-
if (__DEV__) {
|
|
89
|
-
ErrorHandler.log({
|
|
90
|
-
name: 'ApiRetry',
|
|
91
|
-
message: `Retrying API request (attempt ${attempt}) after ${delay}ms`,
|
|
92
|
-
context: { url: fullURL, error: error.message },
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
}
|
|
97
|
-
)
|
|
98
|
-
: await fetchWithTimeout(fullURL, fetchOptions, timeout);
|
|
99
|
-
|
|
100
|
-
if (!isSuccessfulResponse(response)) {
|
|
101
|
-
const error = await handleHttpError(response);
|
|
102
|
-
throw await applyInterceptors(error, this.config.errorInterceptors);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
let parsedResponse = await parseResponse<T>(response);
|
|
106
|
-
parsedResponse = await applyInterceptors(parsedResponse, this.config.responseInterceptors);
|
|
107
|
-
|
|
108
|
-
return parsedResponse;
|
|
109
|
-
} catch (error) {
|
|
110
|
-
const apiError = handleNetworkError(error);
|
|
111
|
-
ErrorHandler.log(apiError);
|
|
112
|
-
throw await applyInterceptors(apiError, this.config.errorInterceptors);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Makes an HTTP request with a specific method
|
|
118
|
-
*/
|
|
119
|
-
private requestWithMethod<T>(
|
|
120
|
-
method: HttpMethod,
|
|
121
|
-
url: string,
|
|
122
|
-
bodyOrParams?: any,
|
|
123
|
-
config?: Partial<ApiRequestConfig>
|
|
124
|
-
): Promise<ApiResponse<T>> {
|
|
125
|
-
const requestData: ApiRequestConfig = {
|
|
126
|
-
url,
|
|
127
|
-
method,
|
|
128
|
-
...(method === 'GET' || method === 'DELETE' ? { params: bodyOrParams } : { body: bodyOrParams }),
|
|
129
|
-
...config,
|
|
130
|
-
};
|
|
131
|
-
return this.request<T>(requestData);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
get<T>(url: string, params?: Record<string, string | number | boolean | undefined>, config?: Partial<ApiRequestConfig>): Promise<ApiResponse<T>> {
|
|
135
|
-
return this.requestWithMethod<T>('GET', url, params, config);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
post<T>(url: string, body?: any, config?: Partial<ApiRequestConfig>): Promise<ApiResponse<T>> {
|
|
139
|
-
return this.requestWithMethod<T>('POST', url, body, config);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
put<T>(url: string, body?: any, config?: Partial<ApiRequestConfig>): Promise<ApiResponse<T>> {
|
|
143
|
-
return this.requestWithMethod<T>('PUT', url, body, config);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
patch<T>(url: string, body?: any, config?: Partial<ApiRequestConfig>): Promise<ApiResponse<T>> {
|
|
147
|
-
return this.requestWithMethod<T>('PATCH', url, body, config);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
delete<T>(url: string, config?: Partial<ApiRequestConfig>): Promise<ApiResponse<T>> {
|
|
151
|
-
return this.requestWithMethod<T>('DELETE', url, undefined, config);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
updateConfig(updates: Partial<ApiClientConfig>): void {
|
|
155
|
-
this.config = { ...this.config, ...updates };
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
getConfig(): ApiClientConfig {
|
|
159
|
-
return { ...this.config };
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
let apiClientInstance: ApiClient | null = null;
|
|
164
|
-
|
|
165
|
-
export function createApiClient(config: ApiClientConfig): ApiClient {
|
|
166
|
-
if (!apiClientInstance) {
|
|
167
|
-
apiClientInstance = new ApiClient(config);
|
|
168
|
-
}
|
|
169
|
-
return apiClientInstance;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export function getApiClient(): ApiClient | null {
|
|
173
|
-
return apiClientInstance;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export function resetApiClient(): void {
|
|
177
|
-
apiClientInstance = null;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* API Service Types
|
|
3
|
-
* Type definitions for API communication
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
7
|
-
|
|
8
|
-
export interface ApiRequestConfig {
|
|
9
|
-
url: string;
|
|
10
|
-
method: HttpMethod;
|
|
11
|
-
headers?: Record<string, string>;
|
|
12
|
-
params?: Record<string, string | number | boolean | undefined>;
|
|
13
|
-
body?: any;
|
|
14
|
-
timeout?: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface ApiResponse<T = any> {
|
|
18
|
-
data: T;
|
|
19
|
-
status: number;
|
|
20
|
-
statusText: string;
|
|
21
|
-
headers: Record<string, string>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface ApiError {
|
|
25
|
-
message: string;
|
|
26
|
-
status?: number;
|
|
27
|
-
code?: string;
|
|
28
|
-
details?: any;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface RequestInterceptor {
|
|
32
|
-
(config: ApiRequestConfig): ApiRequestConfig | Promise<ApiRequestConfig>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface ResponseInterceptor {
|
|
36
|
-
(response: ApiResponse): ApiResponse | Promise<ApiResponse>;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface ErrorInterceptor {
|
|
40
|
-
(error: ApiError): ApiError | Promise<ApiError>;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface ApiClientConfig {
|
|
44
|
-
baseURL: string;
|
|
45
|
-
timeout?: number;
|
|
46
|
-
headers?: Record<string, string>;
|
|
47
|
-
requestInterceptors?: RequestInterceptor[];
|
|
48
|
-
responseInterceptors?: ResponseInterceptor[];
|
|
49
|
-
errorInterceptors?: ErrorInterceptor[];
|
|
50
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Request Builder Utility
|
|
3
|
-
* Builds HTTP requests with proper configuration
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { ApiRequestConfig, HttpMethod } from '../types/ApiTypes';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Builds query string from params object
|
|
10
|
-
*
|
|
11
|
-
* @param params - Query parameters
|
|
12
|
-
* @returns Query string
|
|
13
|
-
*/
|
|
14
|
-
export function buildQueryString(params: Record<string, string | number | boolean | undefined>): string {
|
|
15
|
-
const searchParams = new URLSearchParams();
|
|
16
|
-
|
|
17
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
18
|
-
if (value !== undefined) {
|
|
19
|
-
searchParams.append(key, String(value));
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const queryString = searchParams.toString();
|
|
24
|
-
return queryString ? `?${queryString}` : '';
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Builds full URL with query parameters
|
|
29
|
-
*
|
|
30
|
-
* @param baseURL - Base URL
|
|
31
|
-
* @param path - Request path
|
|
32
|
-
* @param params - Query parameters
|
|
33
|
-
* @returns Full URL
|
|
34
|
-
*/
|
|
35
|
-
export function buildURL(
|
|
36
|
-
baseURL: string,
|
|
37
|
-
path: string,
|
|
38
|
-
params?: Record<string, string | number | boolean | undefined>
|
|
39
|
-
): string {
|
|
40
|
-
const cleanPath = path.startsWith('/') ? path : `/${path}`;
|
|
41
|
-
const fullURL = `${baseURL}${cleanPath}`;
|
|
42
|
-
|
|
43
|
-
if (params) {
|
|
44
|
-
return `${fullURL}${buildQueryString(params)}`;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return fullURL;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Builds request configuration
|
|
52
|
-
*
|
|
53
|
-
* @param config - Request configuration
|
|
54
|
-
* @returns Built fetch options
|
|
55
|
-
*/
|
|
56
|
-
export function buildRequestConfig(config: ApiRequestConfig): RequestInit {
|
|
57
|
-
const options: RequestInit = {
|
|
58
|
-
method: config.method,
|
|
59
|
-
headers: {
|
|
60
|
-
'Content-Type': 'application/json',
|
|
61
|
-
...config.headers,
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
if (config.body) {
|
|
66
|
-
options.body = JSON.stringify(config.body);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return options;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Creates a request builder function for a specific base URL
|
|
74
|
-
*
|
|
75
|
-
* @param baseURL - Base URL for all requests
|
|
76
|
-
* @returns Request builder function
|
|
77
|
-
*/
|
|
78
|
-
export function createRequestBuilder(baseURL: string) {
|
|
79
|
-
return (
|
|
80
|
-
path: string,
|
|
81
|
-
method: HttpMethod,
|
|
82
|
-
params?: Record<string, string | number | boolean | undefined>,
|
|
83
|
-
body?: any,
|
|
84
|
-
headers?: Record<string, string>
|
|
85
|
-
): ApiRequestConfig => ({
|
|
86
|
-
url: buildURL(baseURL, path, params),
|
|
87
|
-
method,
|
|
88
|
-
params,
|
|
89
|
-
body,
|
|
90
|
-
headers,
|
|
91
|
-
});
|
|
92
|
-
}
|