@ibdop/platform-kit 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.
- package/README.md +63 -0
- package/dist/components/ErrorBoundary.d.ts +68 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/Notification.d.ts +46 -0
- package/dist/components/Notification.d.ts.map +1 -0
- package/dist/components/VersionInfo.d.ts +18 -0
- package/dist/components/VersionInfo.d.ts.map +1 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +9 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/useApi.d.ts +65 -0
- package/dist/hooks/useApi.d.ts.map +1 -0
- package/dist/hooks/useInfoData.d.ts +35 -0
- package/dist/hooks/useInfoData.d.ts.map +1 -0
- package/dist/hooks/usePermissions.d.ts +23 -0
- package/dist/hooks/usePermissions.d.ts.map +1 -0
- package/dist/hooks/useShellAuth.d.ts +23 -0
- package/dist/hooks/useShellAuth.d.ts.map +1 -0
- package/dist/hooks/useV1Config.d.ts +27 -0
- package/dist/hooks/useV1Config.d.ts.map +1 -0
- package/dist/index.cjs.js +18 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.es.js +1500 -0
- package/dist/index.umd.js +18 -0
- package/dist/services/api.d.ts +59 -0
- package/dist/services/api.d.ts.map +1 -0
- package/dist/services/index.d.ts +8 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/logger.d.ts +41 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/types/index.d.ts +178 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +90 -0
- package/src/components/ErrorBoundary.tsx +292 -0
- package/src/components/Notification.tsx +297 -0
- package/src/components/VersionInfo.tsx +271 -0
- package/src/components/index.ts +14 -0
- package/src/global.d.ts +40 -0
- package/src/hooks/index.ts +13 -0
- package/src/hooks/useApi.ts +314 -0
- package/src/hooks/useInfoData.ts +124 -0
- package/src/hooks/usePermissions.ts +88 -0
- package/src/hooks/useShellAuth.ts +145 -0
- package/src/hooks/useV1Config.ts +112 -0
- package/src/index.ts +17 -0
- package/src/services/api.ts +290 -0
- package/src/services/index.ts +9 -0
- package/src/services/logger.ts +71 -0
- package/src/types/index.ts +215 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Service - Централизованный API клиент
|
|
3
|
+
*
|
|
4
|
+
* Предоставляет axios клиент с interceptors для auth и error handling
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import axios, { AxiosInstance, AxiosError, InternalAxiosRequestConfig } from 'axios'
|
|
8
|
+
import type { ApiError, ApiResponse } from '../types'
|
|
9
|
+
|
|
10
|
+
// MF Name for logging
|
|
11
|
+
const MF_NAME = 'platform-kit'
|
|
12
|
+
|
|
13
|
+
// Development mode flag
|
|
14
|
+
const isDev = import.meta.env?.DEV === true || import.meta.env?.MODE === 'development'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Logger for API
|
|
18
|
+
*/
|
|
19
|
+
const logger = {
|
|
20
|
+
log: (...args: unknown[]) => {
|
|
21
|
+
if (isDev) console.log(`[${MF_NAME}]`, ...args)
|
|
22
|
+
},
|
|
23
|
+
warn: (...args: unknown[]) => {
|
|
24
|
+
if (isDev) console.warn(`[${MF_NAME}]`, ...args)
|
|
25
|
+
},
|
|
26
|
+
error: (...args: unknown[]) => {
|
|
27
|
+
console.error(`[${MF_NAME}]`, ...args)
|
|
28
|
+
},
|
|
29
|
+
info: (...args: unknown[]) => {
|
|
30
|
+
if (isDev) console.info(`[${MF_NAME}]`, ...args)
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Interface для конфигурации API клиента
|
|
36
|
+
*/
|
|
37
|
+
export interface ApiConfig {
|
|
38
|
+
timeout?: number
|
|
39
|
+
baseURL?: string
|
|
40
|
+
name?: string
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Interface для ответа ошибки API
|
|
45
|
+
*/
|
|
46
|
+
export interface ApiErrorResponse {
|
|
47
|
+
message?: string
|
|
48
|
+
code?: string
|
|
49
|
+
status?: number
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Получить состояние авторизации из shell
|
|
54
|
+
*/
|
|
55
|
+
function getAuthState(): { isAuthenticated: boolean; user?: { profile?: { access_token?: string } } } | null {
|
|
56
|
+
if (typeof window === 'undefined') {
|
|
57
|
+
return { isAuthenticated: false }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Try __SHELL_AUTH_INSTANCE__
|
|
61
|
+
const shellAuth = (window as unknown as { __SHELL_AUTH_INSTANCE__?: { isAuthenticated: boolean; user?: { profile?: { access_token?: string } } } }).__SHELL_AUTH_INSTANCE__
|
|
62
|
+
if (shellAuth) {
|
|
63
|
+
return shellAuth
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Try __SHELL_AUTH__ format
|
|
67
|
+
const shellAuth2 = (window as unknown as { __SHELL_AUTH__?: { authInstance?: { isAuthenticated: boolean; user?: { profile?: { access_token?: string } } } } }).__SHELL_AUTH__
|
|
68
|
+
if (shellAuth2?.authInstance) {
|
|
69
|
+
return shellAuth2.authInstance
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return { isAuthenticated: false }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Получить mfeName из window
|
|
77
|
+
*/
|
|
78
|
+
function getMfeName(): string {
|
|
79
|
+
if (typeof window !== 'undefined') {
|
|
80
|
+
const win = window as unknown as { __MF_NAME__?: string }
|
|
81
|
+
if (win.__MF_NAME__) return win.__MF_NAME__
|
|
82
|
+
}
|
|
83
|
+
return MF_NAME
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Обработка ошибок авторизации - редирект на логин
|
|
88
|
+
*/
|
|
89
|
+
function handleAuthError(): void {
|
|
90
|
+
if (typeof window === 'undefined') return
|
|
91
|
+
|
|
92
|
+
const shellAuth = (window as unknown as { __SHELL_AUTH_INSTANCE__?: { signinRedirect?: () => Promise<void> } }).__SHELL_AUTH_INSTANCE__
|
|
93
|
+
|
|
94
|
+
if (shellAuth?.signinRedirect) {
|
|
95
|
+
shellAuth.signinRedirect().catch((err) => {
|
|
96
|
+
logger.error('Failed to redirect to login:', err)
|
|
97
|
+
})
|
|
98
|
+
} else {
|
|
99
|
+
window.location.href = '/'
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Форматирование API ошибки в консистентную структуру
|
|
105
|
+
*/
|
|
106
|
+
function formatApiError(error: AxiosError<ApiErrorResponse>): ApiError {
|
|
107
|
+
const response = error.response
|
|
108
|
+
|
|
109
|
+
let errorType: ApiError['type'] = 'unknown'
|
|
110
|
+
|
|
111
|
+
if (!response) {
|
|
112
|
+
errorType = 'network'
|
|
113
|
+
} else if (response.status === 401) {
|
|
114
|
+
errorType = 'unauthorized'
|
|
115
|
+
} else if (response.status === 403) {
|
|
116
|
+
errorType = 'forbidden'
|
|
117
|
+
} else if (response.status === 404) {
|
|
118
|
+
errorType = 'not_found'
|
|
119
|
+
} else if (response.status >= 500) {
|
|
120
|
+
errorType = 'server'
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
message: response?.data?.message ?? error.message ?? 'Unknown error',
|
|
125
|
+
code: response?.data?.code,
|
|
126
|
+
status: response?.status,
|
|
127
|
+
type: errorType,
|
|
128
|
+
timestamp: Date.now(),
|
|
129
|
+
url: error.config?.url,
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Создание API клиента с interceptors
|
|
135
|
+
*
|
|
136
|
+
* @param config - конфигурация клиента
|
|
137
|
+
* @returns AxiosInstance
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* const api = createApiClient({ timeout: 10000 })
|
|
142
|
+
* const response = await api.get('/api/users')
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
export function createApiClient(config: ApiConfig = {}): AxiosInstance {
|
|
146
|
+
const clientName = config.name || MF_NAME
|
|
147
|
+
|
|
148
|
+
const clientLogger = {
|
|
149
|
+
log: (...args: unknown[]) => logger.log(`[API:${clientName}]`, ...args),
|
|
150
|
+
warn: (...args: unknown[]) => logger.warn(`[API:${clientName}]`, ...args),
|
|
151
|
+
error: (...args: unknown[]) => logger.error(`[API:${clientName}]`, ...args),
|
|
152
|
+
info: (...args: unknown[]) => logger.info(`[API:${clientName}]`, ...args),
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const client = axios.create({
|
|
156
|
+
timeout: config.timeout ?? 10000,
|
|
157
|
+
baseURL: config.baseURL ?? '',
|
|
158
|
+
headers: {
|
|
159
|
+
'Content-Type': 'application/json',
|
|
160
|
+
},
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
// Request interceptor - добавление auth токена
|
|
164
|
+
client.interceptors.request.use(
|
|
165
|
+
(config: InternalAxiosRequestConfig) => {
|
|
166
|
+
const authState = getAuthState()
|
|
167
|
+
|
|
168
|
+
// Attach token ONLY if user is authenticated
|
|
169
|
+
if (authState?.isAuthenticated) {
|
|
170
|
+
const token = authState.user?.profile?.access_token
|
|
171
|
+
if (token && config.headers) {
|
|
172
|
+
config.headers.Authorization = `Bearer ${token}`
|
|
173
|
+
clientLogger.info('Auth token attached')
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
clientLogger.info('User not authenticated - request without token')
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
clientLogger.log(`${config.method?.toUpperCase()} ${config.url}`)
|
|
180
|
+
return config
|
|
181
|
+
},
|
|
182
|
+
(error: AxiosError) => {
|
|
183
|
+
clientLogger.error('Request interceptor error:', error.message)
|
|
184
|
+
return Promise.reject(error)
|
|
185
|
+
}
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
// Response interceptor - обработка ошибок
|
|
189
|
+
client.interceptors.response.use(
|
|
190
|
+
(response) => {
|
|
191
|
+
clientLogger.log(`Response ${response.status}:`, response.config.url)
|
|
192
|
+
return response
|
|
193
|
+
},
|
|
194
|
+
(error: AxiosError<ApiErrorResponse>) => {
|
|
195
|
+
const status = error.response?.status
|
|
196
|
+
const url = error.config?.url
|
|
197
|
+
|
|
198
|
+
// Categorize errors
|
|
199
|
+
if (status === 401) {
|
|
200
|
+
clientLogger.warn('401 Unauthorized - triggering re-auth')
|
|
201
|
+
handleAuthError()
|
|
202
|
+
} else if (status === 403) {
|
|
203
|
+
clientLogger.warn('403 Forbidden - insufficient permissions')
|
|
204
|
+
} else if (status === 404) {
|
|
205
|
+
clientLogger.warn('404 Not found:', url)
|
|
206
|
+
} else if (status === 429) {
|
|
207
|
+
clientLogger.warn('429 Rate limited')
|
|
208
|
+
} else if (status === 500) {
|
|
209
|
+
clientLogger.error('500 Server error:', url)
|
|
210
|
+
} else if (!error.response) {
|
|
211
|
+
clientLogger.error('Network error - backend may be unavailable:', url)
|
|
212
|
+
} else {
|
|
213
|
+
clientLogger.warn(`Error ${status}:`, error.message)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return Promise.reject(formatApiError(error))
|
|
217
|
+
}
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
return client
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Default API client instance
|
|
224
|
+
export const api = createApiClient()
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* GET запрос
|
|
228
|
+
*/
|
|
229
|
+
export async function get<T>(
|
|
230
|
+
url: string,
|
|
231
|
+
params?: Record<string, unknown>,
|
|
232
|
+
client: AxiosInstance = api
|
|
233
|
+
): Promise<ApiResponse<T>> {
|
|
234
|
+
const response = await client.get<T>(url, { params })
|
|
235
|
+
return {
|
|
236
|
+
data: response.data,
|
|
237
|
+
status: response.status,
|
|
238
|
+
ok: response.status >= 200 && response.status < 300,
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* POST запрос
|
|
244
|
+
*/
|
|
245
|
+
export async function post<T>(
|
|
246
|
+
url: string,
|
|
247
|
+
data?: unknown,
|
|
248
|
+
client: AxiosInstance = api
|
|
249
|
+
): Promise<ApiResponse<T>> {
|
|
250
|
+
const response = await client.post<T>(url, data)
|
|
251
|
+
return {
|
|
252
|
+
data: response.data,
|
|
253
|
+
status: response.status,
|
|
254
|
+
ok: response.status >= 200 && response.status < 300,
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* PUT запрос
|
|
260
|
+
*/
|
|
261
|
+
export async function put<T>(
|
|
262
|
+
url: string,
|
|
263
|
+
data?: unknown,
|
|
264
|
+
client: AxiosInstance = api
|
|
265
|
+
): Promise<ApiResponse<T>> {
|
|
266
|
+
const response = await client.put<T>(url, data)
|
|
267
|
+
return {
|
|
268
|
+
data: response.data,
|
|
269
|
+
status: response.status,
|
|
270
|
+
ok: response.status >= 200 && response.status < 300,
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* DELETE запрос
|
|
276
|
+
*/
|
|
277
|
+
export async function del<T>(
|
|
278
|
+
url: string,
|
|
279
|
+
client: AxiosInstance = api
|
|
280
|
+
): Promise<ApiResponse<T>> {
|
|
281
|
+
const response = await client.delete<T>(url)
|
|
282
|
+
return {
|
|
283
|
+
data: response.data,
|
|
284
|
+
status: response.status,
|
|
285
|
+
ok: response.status >= 200 && response.status < 300,
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Export logger for use in other modules
|
|
290
|
+
export { logger }
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Services barrel export
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { api, createApiClient, get, post, put, del } from './api'
|
|
6
|
+
export type { ApiConfig, ApiErrorResponse } from './api'
|
|
7
|
+
|
|
8
|
+
export { createMfLogger, authLogger, apiLogger, errorLogger, infoLogger } from './logger'
|
|
9
|
+
export type { Logger, LoggerOptions } from './logger'
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger Service - Централизованный логгер
|
|
3
|
+
*
|
|
4
|
+
* Предоставляет фабрику логгеров с MF именем для консистентного логирования
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Development mode flag
|
|
8
|
+
const isDev = import.meta.env?.DEV === true || import.meta.env?.MODE === 'development'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Interface для логгера
|
|
12
|
+
*/
|
|
13
|
+
export interface Logger {
|
|
14
|
+
log: (...args: unknown[]) => void
|
|
15
|
+
warn: (...args: unknown[]) => void
|
|
16
|
+
error: (...args: unknown[]) => void
|
|
17
|
+
info: (...args: unknown[]) => void
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Logger options
|
|
22
|
+
*/
|
|
23
|
+
export interface LoggerOptions {
|
|
24
|
+
prefix?: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Создание логгера с MF именем
|
|
29
|
+
*
|
|
30
|
+
* @param mfeName - имя MF для префикса
|
|
31
|
+
* @param options - опции
|
|
32
|
+
* @returns Logger
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const logger = createMfLogger('mf-home')
|
|
37
|
+
* logger.log('Info message')
|
|
38
|
+
* logger.warn('Warning message')
|
|
39
|
+
* logger.error('Error message')
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export function createMfLogger(mfeName: string, options?: LoggerOptions): Logger {
|
|
43
|
+
const prefix = options?.prefix ? `[${options.prefix}]` : `[${mfeName}]`
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
log: (...args: unknown[]) => {
|
|
47
|
+
if (isDev) {
|
|
48
|
+
console.log(prefix, ...args)
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
warn: (...args: unknown[]) => {
|
|
52
|
+
if (isDev) {
|
|
53
|
+
console.warn(prefix, ...args)
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
error: (...args: unknown[]) => {
|
|
57
|
+
console.error(prefix, ...args)
|
|
58
|
+
},
|
|
59
|
+
info: (...args: unknown[]) => {
|
|
60
|
+
if (isDev) {
|
|
61
|
+
console.info(prefix, ...args)
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Pre-created loggers for common modules
|
|
68
|
+
export const authLogger = createMfLogger('platform-kit', { prefix: 'AUTH' })
|
|
69
|
+
export const apiLogger = createMfLogger('platform-kit', { prefix: 'API' })
|
|
70
|
+
export const errorLogger = createMfLogger('platform-kit', { prefix: 'ERROR' })
|
|
71
|
+
export const infoLogger = createMfLogger('platform-kit', { prefix: 'INFO' })
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// Type definitions for Platform Kit
|
|
2
|
+
|
|
3
|
+
// ==================== Auth Types ====================
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Shell Auth User Profile
|
|
7
|
+
*/
|
|
8
|
+
export interface ShellUserProfile {
|
|
9
|
+
email?: string
|
|
10
|
+
name?: string
|
|
11
|
+
preferred_username?: string
|
|
12
|
+
roles?: string[]
|
|
13
|
+
realm_roles?: string[]
|
|
14
|
+
groups?: string[]
|
|
15
|
+
access_token?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Shell Auth User
|
|
20
|
+
*/
|
|
21
|
+
export interface ShellUser {
|
|
22
|
+
access_token?: string
|
|
23
|
+
expires_at?: number
|
|
24
|
+
id_token?: string
|
|
25
|
+
profile?: ShellUserProfile
|
|
26
|
+
session_state?: string
|
|
27
|
+
token_type?: string
|
|
28
|
+
[key: string]: unknown
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Shell Auth State
|
|
33
|
+
*/
|
|
34
|
+
export interface ShellAuth {
|
|
35
|
+
user: ShellUser | null
|
|
36
|
+
isAuthenticated: boolean
|
|
37
|
+
isLoading: boolean
|
|
38
|
+
signinRedirect: () => Promise<void>
|
|
39
|
+
removeUser?: () => Promise<void>
|
|
40
|
+
error?: string
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ==================== API Types ====================
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* API Error types
|
|
47
|
+
*/
|
|
48
|
+
export type ApiErrorType =
|
|
49
|
+
| 'network'
|
|
50
|
+
| 'unauthorized'
|
|
51
|
+
| 'forbidden'
|
|
52
|
+
| 'not_found'
|
|
53
|
+
| 'server'
|
|
54
|
+
| 'client'
|
|
55
|
+
| 'unknown'
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* API Error interface
|
|
59
|
+
*/
|
|
60
|
+
export interface ApiError {
|
|
61
|
+
message: string
|
|
62
|
+
code?: string
|
|
63
|
+
status?: number
|
|
64
|
+
type: ApiErrorType
|
|
65
|
+
timestamp: number
|
|
66
|
+
url?: string
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Generic API Response wrapper
|
|
71
|
+
*/
|
|
72
|
+
export interface ApiResponse<T> {
|
|
73
|
+
data: T
|
|
74
|
+
status: number
|
|
75
|
+
ok: boolean
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Interface для конфигурации useApi
|
|
80
|
+
*/
|
|
81
|
+
export interface UseApiConfig<T = never> {
|
|
82
|
+
notifyOnError?: boolean
|
|
83
|
+
notifyOnSuccess?: boolean
|
|
84
|
+
successMessage?: string
|
|
85
|
+
errorContext?: string
|
|
86
|
+
onSuccess?: (data: T) => void
|
|
87
|
+
onError?: (error: ApiError) => void
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Interface для результата useApi
|
|
92
|
+
*/
|
|
93
|
+
export interface UseApiResult<T> {
|
|
94
|
+
data: T | null
|
|
95
|
+
error: ApiError | null
|
|
96
|
+
isLoading: boolean
|
|
97
|
+
isError: boolean
|
|
98
|
+
isSuccess: boolean
|
|
99
|
+
execute: () => Promise<T | null>
|
|
100
|
+
reset: () => void
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ==================== Info Types ====================
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* MF Info Data from info.json
|
|
107
|
+
*/
|
|
108
|
+
export interface InfoData {
|
|
109
|
+
APP_NAME?: string
|
|
110
|
+
BUILD_VERSION?: string
|
|
111
|
+
IMAGE_VERSION?: string
|
|
112
|
+
BUILD_DATE?: string
|
|
113
|
+
GIT_COMMIT?: string
|
|
114
|
+
GIT_BRANCH?: string
|
|
115
|
+
COMMIT_SHA?: string
|
|
116
|
+
CI_JOB_URL?: string
|
|
117
|
+
CI_PIPELINE_URL?: string
|
|
118
|
+
CI_COMMIT_AUTHOR?: string
|
|
119
|
+
CI_COMMIT_TIMESTAMP?: string
|
|
120
|
+
CI_COMMIT_MESSAGE?: string
|
|
121
|
+
CI_PROJECT_URL?: string
|
|
122
|
+
CI_JOB_NAME?: string
|
|
123
|
+
CI_RUNNER_ID?: string
|
|
124
|
+
CONTAINER_ID?: string
|
|
125
|
+
CONTAINER_NAME?: string
|
|
126
|
+
[key: string]: string | undefined
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ==================== Config Types ====================
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* V1 Config from sessionStorage
|
|
133
|
+
*/
|
|
134
|
+
export interface V1ConfigData {
|
|
135
|
+
authority: string
|
|
136
|
+
client_id: string
|
|
137
|
+
environment: string
|
|
138
|
+
front_k8s_ms_info_service_url?: string
|
|
139
|
+
mf_info?: Record<string, boolean>
|
|
140
|
+
urls?: Record<string, string>
|
|
141
|
+
[key: string]: unknown
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ==================== Permission Types ====================
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* MF Permissions configuration
|
|
148
|
+
*/
|
|
149
|
+
export interface MfPermissionsConfig {
|
|
150
|
+
canView: string[]
|
|
151
|
+
canEdit: string[]
|
|
152
|
+
canDelete: string[]
|
|
153
|
+
canAdmin: string[]
|
|
154
|
+
canViewSensitiveData: string[]
|
|
155
|
+
canExportData: string[]
|
|
156
|
+
canManageUsers: string[]
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* User permissions result
|
|
161
|
+
*/
|
|
162
|
+
export interface MfPermissions {
|
|
163
|
+
canView: boolean
|
|
164
|
+
canEdit: boolean
|
|
165
|
+
canDelete: boolean
|
|
166
|
+
canAdmin: boolean
|
|
167
|
+
canViewSensitiveData: boolean
|
|
168
|
+
canExportData: boolean
|
|
169
|
+
canManageUsers: boolean
|
|
170
|
+
[key: string]: boolean
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ==================== Notification Types ====================
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Notification types
|
|
177
|
+
*/
|
|
178
|
+
export type NotificationType = 'info' | 'success' | 'warning' | 'error'
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Notification payload
|
|
182
|
+
*/
|
|
183
|
+
export interface NotificationPayload {
|
|
184
|
+
type: NotificationType
|
|
185
|
+
title: string
|
|
186
|
+
message: string
|
|
187
|
+
duration?: number
|
|
188
|
+
mfeName?: string
|
|
189
|
+
timestamp: number
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// ==================== MFE Event Types ====================
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* MFE Error Event detail
|
|
196
|
+
*/
|
|
197
|
+
export interface MFEErrorEventDetail {
|
|
198
|
+
mfeName: string
|
|
199
|
+
error: Error | string
|
|
200
|
+
stack?: string
|
|
201
|
+
componentStack?: string
|
|
202
|
+
timestamp: number
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* MFE Notification Event detail
|
|
207
|
+
*/
|
|
208
|
+
export interface MFENotificationEventDetail {
|
|
209
|
+
type: NotificationType
|
|
210
|
+
title: string
|
|
211
|
+
message: string
|
|
212
|
+
mfeName: string
|
|
213
|
+
timestamp: number
|
|
214
|
+
duration?: number
|
|
215
|
+
}
|