@emailmaker/filemanager 0.10.15 → 0.10.16

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.
@@ -21,6 +21,6 @@ export interface UseFilesAPIActions {
21
21
  handleAddFileByUrl: (url?: string | null, noFolder?: boolean) => Promise<AppFile | void>;
22
22
  handleDroppedFiles: (droppedFiles: globalThis.File[]) => Promise<void>;
23
23
  getFileData: (file: AppFile) => Promise<Blob | undefined>;
24
- uploadFileWithProvider: (file: globalThis.File, targetFolderId?: string) => Promise<void>;
24
+ uploadFileWithProvider: (file: globalThis.File, targetFolderId?: string) => Promise<AppFile | undefined>;
25
25
  }
26
26
  export declare const useFilesAPI: () => UseFilesAPIActions;
@@ -1,8 +1,22 @@
1
+ import { Notify, NotifyEvent } from 'types';
2
+ /**
3
+ * Хук уведомлений
4
+ */
1
5
  export declare const useNotifications: () => {
2
- open: (args: import("antd").NotificationArgsProps) => void;
3
- success: (args: import("antd").NotificationArgsProps) => void;
4
- error: (args: import("antd").NotificationArgsProps) => void;
5
- info: (args: import("antd").NotificationArgsProps) => void;
6
- warning: (args: import("antd").NotificationArgsProps) => void;
7
- destroy(key?: React.Key): void;
6
+ error<Key extends keyof Notify.ErrorMap>(args: Omit<Notify.ErrorEvent, "type" | "id" | "data"> & {
7
+ id: Key;
8
+ } & (Notify.ErrorMap[Key] extends never ? {} : {
9
+ data: Notify.ErrorMap[Key];
10
+ })): void;
11
+ success<Key extends keyof Notify.SuccessMap>(args: Omit<Notify.SuccessEvent, "type" | "id" | "data"> & {
12
+ id: Key;
13
+ } & (Notify.SuccessMap[Key] extends never ? {} : {
14
+ data: Notify.SuccessMap[Key];
15
+ })): void;
16
+ warning<Key extends keyof Notify.WarningMap>(args: Omit<Notify.WarningEvent, "type" | "id" | "data"> & {
17
+ id: Key;
18
+ } & (Notify.WarningMap[Key] extends never ? {} : {
19
+ data: Notify.WarningMap[Key];
20
+ })): void;
21
+ notify: (payload: NotifyEvent, silent?: boolean) => Promise<void>;
8
22
  };
@@ -0,0 +1,247 @@
1
+ interface FilesQueryParams {
2
+ folderId?: string;
3
+ search?: string;
4
+ page?: number;
5
+ limit?: number;
6
+ sortBy?: 'name' | 'size' | 'date' | 'type';
7
+ sortOrder?: 'asc' | 'desc';
8
+ itemType?: 'file' | 'folder' | 'all';
9
+ }
10
+
11
+ interface ItemContextPayload {
12
+ itemIds?: string[];
13
+ itemNames?: string[];
14
+ folderId?: string | null;
15
+ folderName?: string | null;
16
+ }
17
+
18
+ type NotifyPlacement = 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight';
19
+
20
+ type Notify = {
21
+ type: 'success' | 'info' | 'error' | 'warning';
22
+ message: HTMLElement | string;
23
+ description?: HTMLElement | string;
24
+ btn?: HTMLElement | string;
25
+ onClose?: () => void;
26
+ duration?: number | null;
27
+ icon?: HTMLElement | string;
28
+ placement?: NotifyPlacement;
29
+ style?: any;
30
+ className?: string;
31
+ onClick?: () => void;
32
+ closeIcon?: HTMLElement | string;
33
+ props?: any;
34
+ role?: 'alert' | 'status';
35
+ };
36
+
37
+ declare namespace Notify {
38
+ export interface OperationSuccessPayload extends ItemContextPayload {
39
+ successCount: number;
40
+ totalCount: number;
41
+ }
42
+
43
+ export interface OperationErrorDetail {
44
+ itemId?: string;
45
+ itemName?: string;
46
+ reason?: string;
47
+ }
48
+
49
+ export interface OperationErrorPayload extends ItemContextPayload {
50
+ failCount: number;
51
+ totalCount: number;
52
+ errors?: OperationErrorDetail[];
53
+ }
54
+
55
+ export interface SingleItemPayload {
56
+ itemId?: string;
57
+ itemName?: string;
58
+ folderId?: string | null;
59
+ folderName?: string | null;
60
+ }
61
+
62
+ export interface RenameErrorPayload extends SingleItemPayload {
63
+ reason?: string;
64
+ }
65
+
66
+ export interface FileUploadPayload extends SingleItemPayload {
67
+ uploadId?: string;
68
+ }
69
+
70
+ export interface FileUploadErrorPayload extends FileUploadPayload {
71
+ error?: string;
72
+ }
73
+
74
+ export interface UnsupportedFileTypePayload extends FileUploadErrorPayload {
75
+ fileType: string;
76
+ }
77
+
78
+ export interface FolderOperationPayload extends ItemContextPayload {
79
+ folderId?: string | null;
80
+ folderName?: string;
81
+ reason?: string;
82
+ }
83
+
84
+ export interface JsonDataProviderErrorPayload {
85
+ url?: string | null;
86
+ reason?: string;
87
+ }
88
+
89
+ export interface FileUrlValidationErrorPayload {
90
+ url?: string | null;
91
+ reason?: string;
92
+ }
93
+
94
+ export interface ImageFilePayload extends SingleItemPayload {
95
+ thumbnail?: string | null;
96
+ }
97
+
98
+ export interface UrlUploadPayload {
99
+ url?: string | null;
100
+ folderId?: string | null;
101
+ folderName?: string | null;
102
+ }
103
+
104
+ export interface UrlUploadErrorPayload extends UrlUploadPayload {
105
+ reason?: string;
106
+ }
107
+
108
+ export interface FetchFilesErrorPayload {
109
+ params?: FilesQueryParams;
110
+ }
111
+
112
+ interface AIImageGenerationBasePayload {
113
+ request: string;
114
+ taskId?: string | null;
115
+ }
116
+
117
+ export interface AIImageGenerationStartedPayload extends AIImageGenerationBasePayload {
118
+ response?: unknown;
119
+ }
120
+
121
+ export interface AIImageGenerationSuccessPayload extends AIImageGenerationBasePayload {
122
+ images: string[];
123
+ }
124
+
125
+ export interface AIImageGenerationFailedPayload extends AIImageGenerationBasePayload {
126
+ response?: unknown;
127
+ error?: unknown;
128
+ }
129
+
130
+ export type EventBase<TId extends string, TData> = {
131
+ id: TId;
132
+ data?: TData;
133
+ innerException?: unknown;
134
+ message: string;
135
+ placement?: NotifyPlacement;
136
+ description?: string;
137
+
138
+ };
139
+
140
+ export interface ErrorMap {
141
+ FILE_DOWNLOAD_FAILED: ImageFilePayload;
142
+ IMAGE_DOWNLOAD_FAILED: ImageFilePayload;
143
+ IMAGE_SAVE_FAILED: ImageFilePayload;
144
+ EDITOR_INIT_FAILED: never;
145
+
146
+ AI_RESPONSE_INVALID: unknown;
147
+ AI_IMAGE_GENERATION_FAILED: AIImageGenerationFailedPayload;
148
+ AI_IMAGE_GENERATION_LIMIT_EXCEEDED: never;
149
+
150
+ FILES_FETCH_FAILED: FetchFilesErrorPayload;
151
+
152
+ FILES_DELETE_ERROR: OperationErrorPayload;
153
+
154
+ FOLDER_DELETE_ERROR: OperationErrorPayload;
155
+
156
+ FILE_RENAME_DISABLED_BY_CONFIG: SingleItemPayload;
157
+ FILE_RENAME_FAILED: RenameErrorPayload;
158
+
159
+ FOLDER_RENAME_DISABLED_BY_CONFIG: SingleItemPayload;
160
+ FOLDER_RENAME_FAILED: RenameErrorPayload;
161
+
162
+ ITEM_RENAME_FAILED: RenameErrorPayload;
163
+
164
+ FILE_UPLOAD_ITEM_FAILED: FileUploadErrorPayload;
165
+
166
+ FILES_UPLOAD_BATCH_FAILED: OperationErrorPayload;
167
+
168
+ FILES_UPLOAD_URL_VALIDATION_FAILED: UrlUploadPayload;
169
+
170
+ FILES_UPLOAD_URL_NOT_SUPPORTED: UrlUploadPayload;
171
+ FILES_UPLOAD_BY_URL_FAILED: UrlUploadErrorPayload;
172
+
173
+ FILES_UPLOAD_PROVIDER_NOT_CONFIGURED: never;
174
+
175
+ FILES_MOVE_DIRECTORY_NOT_SELECTED: never;
176
+ FILES_MOVE_ERROR: OperationErrorPayload;
177
+
178
+ FILES_COPY_DIRECTORY_NOT_SELECTED: never;
179
+ FILES_COPY_ERROR: OperationErrorPayload;
180
+
181
+ FILES_MOVE_TO_TRASH_ERROR: OperationErrorPayload;
182
+
183
+ FOLDERS_FETCH_FAILED: FolderOperationPayload;
184
+ FOLDER_CREATE_PROVIDER_NOT_CONFIGURED: FolderOperationPayload;
185
+ FOLDER_CREATE_FAILED: FolderOperationPayload;
186
+ FOLDER_CHILDREN_COUNT_FAILED: FolderOperationPayload;
187
+ FOLDER_CHILDREN_FETCH_FAILED: FolderOperationPayload;
188
+
189
+ JSON_DATA_PROVIDER_LOAD_FAILED: JsonDataProviderErrorPayload;
190
+ FILE_URL_VALIDATION_FAILED: FileUrlValidationErrorPayload;
191
+ }
192
+
193
+ export type Error = {
194
+ [K in keyof ErrorMap]: EventBase<K, ErrorMap[K]>;
195
+ }[keyof ErrorMap];
196
+
197
+ export type ErrorEvent = { type: 'error' } & Error;
198
+
199
+ export interface SuccessMap {
200
+ AI_IMAGE_GENERATION_STARTED: AIImageGenerationStartedPayload;
201
+ AI_IMAGE_GENERERATION_SUCCESS: AIImageGenerationSuccessPayload;
202
+
203
+ // EDITOR_IMAGE_DOWNLOAD_SUCCESS: ImageFilePayload;
204
+ IMAGE_UPDATE_SUCCESS: ImageFilePayload;
205
+
206
+ FILES_DELETE_SUCCESS: OperationSuccessPayload;
207
+ FILES_MOVE_SUCCESS: OperationSuccessPayload;
208
+ FILES_COPY_SUCCESS: OperationSuccessPayload;
209
+ FILE_RENAME_SUCCESS: SingleItemPayload;
210
+ FOLDER_RENAME_SUCCESS: SingleItemPayload;
211
+ FOLDER_DELETE_SUCCESS: OperationSuccessPayload;
212
+ FOLDER_CREATE_SUCCESS: FolderOperationPayload;
213
+ FILES_UPLOAD_BATCH_SUCCESS: OperationSuccessPayload;
214
+
215
+ FILE_UPLOAD_ITEM_SUCCESS: FileUploadPayload;
216
+ }
217
+
218
+ export type Success = {
219
+ [K in keyof SuccessMap]: EventBase<K, SuccessMap[K]>;
220
+ }[keyof SuccessMap];
221
+
222
+ export type SuccessEvent = { type: 'success' } & Success;
223
+
224
+ export interface WarningMap {
225
+ FILES_UPLOAD_UNSUPPORTED_TYPE: UnsupportedFileTypePayload;
226
+ FOLDER_OPERATION_VALIDATION_FAILED: FolderOperationPayload;
227
+ }
228
+
229
+ export type Warning = {
230
+ [K in keyof WarningMap]: EventBase<K, WarningMap[K]>;
231
+ }[keyof WarningMap];
232
+
233
+ export type WarningEvent = { type: 'warning' } & Warning;
234
+
235
+ export interface InfoMap {}
236
+
237
+ export type Info = {
238
+ [K in keyof InfoMap]: EventBase<K, InfoMap[K]>;
239
+ }[keyof InfoMap];
240
+
241
+ export type InfoEvent = { type: 'info' } & Info;
242
+ }
243
+
244
+ type NotifyEvent = Notify.SuccessEvent | Notify.ErrorEvent | Notify.WarningEvent | Notify.InfoEvent;
245
+
246
+ export { Notify };
247
+ export type { ItemContextPayload, NotifyEvent, NotifyPlacement };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emailmaker/filemanager",
3
- "version": "0.10.15",
3
+ "version": "0.10.16",
4
4
  "main": "./file-manager.js",
5
5
  "module": "./file-manager.esm.js",
6
6
  "types": "./index.d.ts",
@@ -1,5 +1,5 @@
1
1
  export interface Config {
2
- theme?: 'light' | 'dark';
2
+ theme?: 'light' | 'dark' | 'system';
3
3
  activeTab?: string;
4
4
  showDefaultNotification?: boolean;
5
5
  disableMockServer?: boolean;
package/types.d.ts CHANGED
@@ -2,7 +2,8 @@ import React, { ReactNode, RefObject } from 'react';
2
2
  import { FormInstance } from 'antd/es/form';
3
3
  import { MY_FILES, GIF, STOCK_IMAGES, AI, EDITOR } from './constants';
4
4
  import type { InputRef } from 'antd';
5
- import { NotificationInstance } from 'antd/es/notification/interface';
5
+ import type { Notify, NotifyEvent } from 'notification';
6
+ export * from 'notification';
6
7
  export interface Folder {
7
8
  id: string;
8
9
  name: string;
@@ -110,6 +111,8 @@ export interface CustomIcons {
110
111
  darkMode?: React.ComponentType<IconProps>;
111
112
  aiIcon_2?: React.ComponentType<IconProps>;
112
113
  }
114
+ type MayBePromise<T> = T | Promise<T>;
115
+ export type NotifyListener<T> = (value: T) => MayBePromise<void | false | (NotifyEvent & Notify)>;
113
116
  export interface FileManagerOptions {
114
117
  apiEndpoints?: {
115
118
  getFolders?: string;
@@ -131,13 +134,19 @@ export interface FileManagerOptions {
131
134
  config?: Config;
132
135
  customIcons?: CustomIcons;
133
136
  dragDropIcon?: string;
134
- notification?: Partial<Omit<NotificationInstance, 'destroy'>>;
137
+ handleNotify?: NotifyListener<NotifyEvent>;
138
+ handleError?: NotifyListener<Notify.ErrorEvent>;
139
+ handleSuccess?: NotifyListener<Notify.SuccessEvent>;
135
140
  }
136
141
  /**
137
142
  * Результат операции
138
143
  */
139
144
  export interface OperationResult<T = void> {
140
- id?: string;
145
+ /**
146
+ * Корреляционный идентификатор элемента запроса.
147
+ * Ранее использовалось поле `id`, которое остаётся для обратной совместимости.
148
+ */
149
+ requestId?: string;
141
150
  success?: boolean;
142
151
  data?: T;
143
152
  error?: string;
@@ -150,6 +159,37 @@ export type BatchResult<T> = {
150
159
  error?: string;
151
160
  detailed?: OperationResult<T>[];
152
161
  };
162
+ export type UploadBinary = Blob | globalThis.File;
163
+ export interface UploadFileItemInput {
164
+ /**
165
+ * Произвольный идентификатор для сопоставления результата.
166
+ * Если не указан, сопоставление выполняется по порядку элементов.
167
+ */
168
+ requestId?: string;
169
+ name: string;
170
+ size: number;
171
+ type: string;
172
+ folderId?: string | null;
173
+ /**
174
+ * Бинарные данные файла. При наличии реального File он передается как есть,
175
+ * иначе — Blob (например, после конвертации base64).
176
+ */
177
+ data: UploadBinary;
178
+ extension?: string;
179
+ }
180
+ export interface UploadFileResultData {
181
+ id?: string;
182
+ name?: string;
183
+ folderId?: string | null;
184
+ }
185
+ export interface UploadFilesRequest {
186
+ /**
187
+ * Список загружаемых файлов. Порядок элементов важен — при отсутствии requestId
188
+ * сопоставление результатов выполняется по индексу.
189
+ */
190
+ items: UploadFileItemInput[];
191
+ folderId?: string | null;
192
+ }
153
193
  export interface FileManagerDataProviders {
154
194
  getFileData: (file: File) => Promise<Blob>;
155
195
  getFolders?: (options?: {
@@ -175,17 +215,19 @@ export interface FileManagerDataProviders {
175
215
  }) => Promise<Folder>;
176
216
  renameFolder?: (folderId: string, newName: string) => Promise<Folder>;
177
217
  deleteFolder?: (folderId: string) => Promise<boolean>;
178
- uploadFile: (file: {
218
+ uploadFile?: (file: {
179
219
  name: string;
180
220
  size: number;
181
221
  type: string;
182
222
  folderId?: string | null;
183
- data: Blob | string;
184
- thumbnail?: string;
185
- dimensions?: string;
186
- aspectRatio?: string;
223
+ /**
224
+ * Бинарные данные файла. При наличии real File передается сам File,
225
+ * в остальных случаях — Blob.
226
+ */
227
+ data: UploadBinary;
187
228
  extension?: string;
188
229
  }) => Promise<File>;
230
+ uploadFiles?: (request: UploadFilesRequest) => Promise<BatchResult<UploadFileResultData>>;
189
231
  uploadFileByUrl?: (data: {
190
232
  url: string;
191
233
  folderId?: string | null;
@@ -211,7 +253,11 @@ export interface FileManagerDataProviders {
211
253
  updateFile?: (fileId: string, updates: {
212
254
  name?: string;
213
255
  type?: string;
214
- data?: Blob | string;
256
+ /**
257
+ * Обновленные бинарные данные (File или Blob). Если не переданы —
258
+ * используются старые данные.
259
+ */
260
+ data?: UploadBinary;
215
261
  thumbnail?: string;
216
262
  dimensions?: string;
217
263
  aspectRatio?: string;
@@ -281,7 +327,7 @@ export type CustomTheme = Partial<import('antd/es/theme/interface').AliasToken>
281
327
  [key: string]: string | number | boolean | undefined;
282
328
  };
283
329
  export interface Config {
284
- theme?: 'light' | 'dark';
330
+ theme?: 'light' | 'dark' | 'system';
285
331
  disableMockServer?: boolean;
286
332
  activeTab?: string;
287
333
  showDefaultNotification?: boolean;
@@ -484,7 +530,9 @@ export interface FileManagerProps {
484
530
  };
485
531
  customIcons?: CustomIcons;
486
532
  dragDropIcon?: string;
487
- notification?: Partial<Omit<NotificationInstance, 'destroy'>>;
533
+ handleNotify?: NotifyListener<NotifyEvent>;
534
+ handleError?: NotifyListener<Notify.ErrorEvent>;
535
+ handleSuccess?: NotifyListener<Notify.SuccessEvent>;
488
536
  }
489
537
  export interface SafeImageProps {
490
538
  src?: string;
@@ -495,4 +543,3 @@ export interface SafeImageProps {
495
543
  preview?: boolean;
496
544
  file?: File;
497
545
  }
498
- export {};
@@ -0,0 +1 @@
1
+ export declare const ensureBlobFromData: (data: Blob | string, fallbackMimeType?: string) => Blob;
@@ -1,4 +1,4 @@
1
- import { FileManagerDataProviders, File, Folder, Config } from '../types';
1
+ import { FileManagerDataProviders, File, Folder, Config, UploadFilesRequest, UploadFileResultData, BatchResult, UploadBinary } from '../types';
2
2
  export declare class JSONDataProvider implements FileManagerDataProviders {
3
3
  private files;
4
4
  private folders;
@@ -36,12 +36,10 @@ export declare class JSONDataProvider implements FileManagerDataProviders {
36
36
  size: number;
37
37
  type: string;
38
38
  folderId?: string | null;
39
- data: Blob | string;
40
- thumbnail?: string;
41
- dimensions?: string;
42
- aspectRatio?: string;
39
+ data: UploadBinary;
43
40
  extension?: string;
44
41
  }) => Promise<File>;
42
+ uploadFiles: (request: UploadFilesRequest) => Promise<BatchResult<UploadFileResultData>>;
45
43
  uploadFileByUrl: (data: {
46
44
  url: string;
47
45
  folderId?: string | null;
@@ -50,7 +48,7 @@ export declare class JSONDataProvider implements FileManagerDataProviders {
50
48
  updateFile: (fileId: string, updates: {
51
49
  name?: string;
52
50
  type?: string;
53
- data?: Blob | string;
51
+ data?: UploadBinary;
54
52
  thumbnail?: string;
55
53
  dimensions?: string;
56
54
  aspectRatio?: string;
@@ -3,6 +3,6 @@ export declare const switchThemeVariables: (token?: {}) => void;
3
3
  /** Применяет кастомную тему к CSS переменным */
4
4
  export declare const applyCustomTheme: (config?: Config) => void;
5
5
  /** Устанавливает тему (светлая/темная) */
6
- export declare const setTheme: (theme: "light" | "dark") => void;
6
+ export declare const setTheme: (theme: "light" | "dark" | "system") => void;
7
7
  /** Получает текущую тему */
8
8
  export declare const getCurrentTheme: () => "light" | "dark";