@useupup/core 3.3.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/LICENSE +21 -0
- package/NOTICE +8 -0
- package/README.md +75 -0
- package/dist/browser-SXR426OQ.cjs +10 -0
- package/dist/browser-WD6T5ABJ.js +1 -0
- package/dist/chunk-2H5ICKFT.cjs +122 -0
- package/dist/chunk-6HF3I2JS.cjs +39 -0
- package/dist/chunk-6S5DQDQH.js +212 -0
- package/dist/chunk-BMQC27OE.cjs +92 -0
- package/dist/chunk-BSGQGINR.cjs +219 -0
- package/dist/chunk-CPKZ2CXD.cjs +179 -0
- package/dist/chunk-DTKDIMKT.cjs +573 -0
- package/dist/chunk-DYE5XJ6Z.cjs +2134 -0
- package/dist/chunk-E3ZCNOXG.cjs +74 -0
- package/dist/chunk-FEQY2WYY.cjs +2377 -0
- package/dist/chunk-FMURBCZ7.js +120 -0
- package/dist/chunk-FYQQRULL.js +37 -0
- package/dist/chunk-GE4LIVXP.js +133 -0
- package/dist/chunk-HFR5HZJZ.js +56 -0
- package/dist/chunk-I7ULPCA2.js +72 -0
- package/dist/chunk-MHYXDLZR.js +569 -0
- package/dist/chunk-N2SLHVAW.cjs +61 -0
- package/dist/chunk-OOPDEOTM.js +169 -0
- package/dist/chunk-PMBR3OUW.js +2359 -0
- package/dist/chunk-QK7HZIVY.cjs +144 -0
- package/dist/chunk-T2AQHY7V.cjs +59 -0
- package/dist/chunk-TRCP5FUR.js +90 -0
- package/dist/chunk-U7KL5M2H.cjs +374 -0
- package/dist/chunk-UXNPM54W.js +2108 -0
- package/dist/chunk-VV6QCQLL.js +365 -0
- package/dist/chunk-ZMS2HXLB.js +56 -0
- package/dist/context-shapes-123dd3b6.d.cts +207 -0
- package/dist/context-shapes-27b24c8f.d.ts +207 -0
- package/dist/contracts-pipeline-cf177270.d.cts +78 -0
- package/dist/contracts-pipeline-cf177270.d.ts +78 -0
- package/dist/contracts-strategies-378a16b7.d.cts +168 -0
- package/dist/contracts-strategies-378a16b7.d.ts +168 -0
- package/dist/contracts.cjs +181 -0
- package/dist/contracts.d.cts +11 -0
- package/dist/contracts.d.ts +11 -0
- package/dist/contracts.js +4 -0
- package/dist/core-141335ac.d.ts +651 -0
- package/dist/core-bea2ceca.d.cts +651 -0
- package/dist/create-worker-provider-AA5SRII6.js +58 -0
- package/dist/create-worker-provider-KJNUSSTW.cjs +60 -0
- package/dist/eligibility-ONLNJ6FB.cjs +10 -0
- package/dist/eligibility-ULFC3E4G.js +8 -0
- package/dist/error-code-map-9c44a425.d.ts +62 -0
- package/dist/error-code-map-dd5becfa.d.cts +62 -0
- package/dist/i18n/index.cjs +90 -0
- package/dist/i18n/index.d.cts +3 -0
- package/dist/i18n/index.d.ts +3 -0
- package/dist/i18n/index.js +1 -0
- package/dist/index.cjs +1770 -0
- package/dist/index.d.cts +280 -0
- package/dist/index.d.ts +280 -0
- package/dist/index.js +1589 -0
- package/dist/internal.cjs +2407 -0
- package/dist/internal.d.cts +595 -0
- package/dist/internal.d.ts +595 -0
- package/dist/internal.js +2275 -0
- package/dist/pipeline/index.cjs +10 -0
- package/dist/pipeline/index.d.cts +11 -0
- package/dist/pipeline/index.d.ts +11 -0
- package/dist/pipeline/index.js +1 -0
- package/dist/pipeline-worker.cjs +199 -0
- package/dist/pipeline-worker.d.cts +2 -0
- package/dist/pipeline-worker.d.ts +2 -0
- package/dist/pipeline-worker.js +197 -0
- package/dist/resolve-locale-81feef21.d.ts +20 -0
- package/dist/resolve-locale-9cb63600.d.cts +20 -0
- package/dist/resolve-theme-01758105.d.ts +53 -0
- package/dist/resolve-theme-66cf8d98.d.cts +53 -0
- package/dist/server-mode-drive-controller-b5f8ee12.d.cts +180 -0
- package/dist/server-mode-drive-controller-b5f8ee12.d.ts +180 -0
- package/dist/steps/compress.cjs +66 -0
- package/dist/steps/compress.d.cts +10 -0
- package/dist/steps/compress.d.ts +10 -0
- package/dist/steps/compress.js +64 -0
- package/dist/steps/exif.cjs +44 -0
- package/dist/steps/exif.d.cts +5 -0
- package/dist/steps/exif.d.ts +5 -0
- package/dist/steps/exif.js +42 -0
- package/dist/steps/hash.cjs +44 -0
- package/dist/steps/hash.d.cts +5 -0
- package/dist/steps/hash.d.ts +5 -0
- package/dist/steps/hash.js +42 -0
- package/dist/steps/heic.cjs +59 -0
- package/dist/steps/heic.d.cts +5 -0
- package/dist/steps/heic.d.ts +5 -0
- package/dist/steps/heic.js +57 -0
- package/dist/steps/thumbnail.cjs +54 -0
- package/dist/steps/thumbnail.d.cts +10 -0
- package/dist/steps/thumbnail.d.ts +10 -0
- package/dist/steps/thumbnail.js +52 -0
- package/dist/strategies/index.cjs +82 -0
- package/dist/strategies/index.d.cts +187 -0
- package/dist/strategies/index.d.ts +187 -0
- package/dist/strategies/index.js +60 -0
- package/dist/strategies/tus-upload.cjs +14 -0
- package/dist/strategies/tus-upload.d.cts +15 -0
- package/dist/strategies/tus-upload.d.ts +15 -0
- package/dist/strategies/tus-upload.js +5 -0
- package/dist/theme/index.cjs +38 -0
- package/dist/theme/index.d.cts +3 -0
- package/dist/theme/index.d.ts +3 -0
- package/dist/theme/index.js +1 -0
- package/dist/theme-store-2e56a674.d.cts +39 -0
- package/dist/theme-store-f13e0315.d.ts +39 -0
- package/dist/token-endpoint-5fdb4a35.d.ts +20 -0
- package/dist/token-endpoint-a7d15ab6.d.cts +20 -0
- package/dist/ui-translations-c5d00392.d.cts +455 -0
- package/dist/ui-translations-c5d00392.d.ts +455 -0
- package/dist/uploader-props-72242002.d.ts +340 -0
- package/dist/uploader-props-7f956e60.d.cts +340 -0
- package/dist/vars-d3421f6c.d.cts +240 -0
- package/dist/vars-d3421f6c.d.ts +240 -0
- package/package.json +182 -0
|
@@ -0,0 +1,651 @@
|
|
|
1
|
+
import { a as UploadFile, c as UploadStatus, F as FileSource, P as PipelineStep } from './contracts-pipeline-cf177270.cjs';
|
|
2
|
+
import { h as UploadResult, M as MaxFileSizeObject, R as ResumableUploadOptions } from './contracts-strategies-378a16b7.cjs';
|
|
3
|
+
import { L as LocaleBundle, a as UpupLocaleCode } from './ui-translations-c5d00392.cjs';
|
|
4
|
+
|
|
5
|
+
type ImageEditorOptions = {
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
display?: 'inline' | 'modal';
|
|
8
|
+
autoOpen?: 'never' | 'single' | 'always';
|
|
9
|
+
output?: {
|
|
10
|
+
mimeType?: string;
|
|
11
|
+
quality?: number;
|
|
12
|
+
fileName?: (original: File) => string;
|
|
13
|
+
};
|
|
14
|
+
tabs?: ('Adjust' | 'Annotate' | 'Filters' | 'Finetune' | 'Resize' | 'Watermark')[];
|
|
15
|
+
tools?: ('Crop' | 'Rotate' | 'Flip' | 'Brightness' | 'Contrast' | 'HSV' | 'Blur' | 'Text' | 'Line' | 'Rect' | 'Ellipse' | 'Polygon' | 'Pen' | 'Arrow' | 'Image')[];
|
|
16
|
+
onOpen?: (file: UploadFile) => void;
|
|
17
|
+
onCancel?: (file: UploadFile) => void;
|
|
18
|
+
onSave?: (editedFile: UploadFile, originalFile: UploadFile) => void;
|
|
19
|
+
};
|
|
20
|
+
type ResolvedImageEditorOptions = Required<Pick<ImageEditorOptions, 'enabled' | 'autoOpen' | 'display'>> & Omit<ImageEditorOptions, 'enabled' | 'autoOpen' | 'display'>;
|
|
21
|
+
type ImageCompressionOptions = {
|
|
22
|
+
quality?: number;
|
|
23
|
+
maxWidth?: number;
|
|
24
|
+
maxHeight?: number;
|
|
25
|
+
mimeType?: string;
|
|
26
|
+
convertSize?: number;
|
|
27
|
+
};
|
|
28
|
+
type ThumbnailGeneratorOptions = {
|
|
29
|
+
thumbnailWidth?: number;
|
|
30
|
+
thumbnailHeight?: number;
|
|
31
|
+
thumbnailType?: string;
|
|
32
|
+
waitForThumbnailsBeforeUpload?: boolean;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
interface CoreEvents {
|
|
36
|
+
'state-change': {
|
|
37
|
+
status?: UploadStatus;
|
|
38
|
+
error?: Error;
|
|
39
|
+
files?: Map<string, UploadFile>;
|
|
40
|
+
progress?: {
|
|
41
|
+
totalFiles: number;
|
|
42
|
+
completedFiles: number;
|
|
43
|
+
percentage: number;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
'upload-start': {
|
|
47
|
+
retry?: boolean;
|
|
48
|
+
fileId?: string;
|
|
49
|
+
};
|
|
50
|
+
'file-upload-start': {
|
|
51
|
+
file: UploadFile;
|
|
52
|
+
};
|
|
53
|
+
'upload-progress': {
|
|
54
|
+
fileId: string;
|
|
55
|
+
loaded: number;
|
|
56
|
+
total: number;
|
|
57
|
+
};
|
|
58
|
+
'upload-success': {
|
|
59
|
+
file: UploadFile;
|
|
60
|
+
result: UploadResult;
|
|
61
|
+
};
|
|
62
|
+
'upload-error': {
|
|
63
|
+
error: Error;
|
|
64
|
+
file?: UploadFile;
|
|
65
|
+
};
|
|
66
|
+
'upload-all-complete': UploadFile[];
|
|
67
|
+
'upload-pause': Record<string, never>;
|
|
68
|
+
'upload-resume': Record<string, never>;
|
|
69
|
+
'upload-cancel': Record<string, never>;
|
|
70
|
+
'files-added': UploadFile[];
|
|
71
|
+
'file-removed': UploadFile;
|
|
72
|
+
'file-rejected': {
|
|
73
|
+
count: number;
|
|
74
|
+
};
|
|
75
|
+
'file-replaced': {
|
|
76
|
+
file: UploadFile;
|
|
77
|
+
};
|
|
78
|
+
'files-cleared': Record<string, never>;
|
|
79
|
+
'files-set': {
|
|
80
|
+
count: number;
|
|
81
|
+
};
|
|
82
|
+
'files-reordered': {
|
|
83
|
+
fileIds: string[];
|
|
84
|
+
};
|
|
85
|
+
'restriction-failed': {
|
|
86
|
+
error: unknown;
|
|
87
|
+
};
|
|
88
|
+
'plugin-registered': {
|
|
89
|
+
name: string;
|
|
90
|
+
};
|
|
91
|
+
'options-updated': {
|
|
92
|
+
partial: Partial<CoreOptions>;
|
|
93
|
+
};
|
|
94
|
+
retry: {
|
|
95
|
+
fileId?: string | undefined;
|
|
96
|
+
};
|
|
97
|
+
'snapshot-restored': {
|
|
98
|
+
count: number;
|
|
99
|
+
status: UploadStatus;
|
|
100
|
+
};
|
|
101
|
+
'crash-recovery-restored': Record<string, never>;
|
|
102
|
+
destroyed: Record<string, never>;
|
|
103
|
+
done: Record<string, never>;
|
|
104
|
+
'state-reset': Record<string, never>;
|
|
105
|
+
'auto-upload': {
|
|
106
|
+
count: number;
|
|
107
|
+
};
|
|
108
|
+
'connection-online': Record<string, never>;
|
|
109
|
+
'connection-offline': Record<string, never>;
|
|
110
|
+
'image-editor-open': {
|
|
111
|
+
file: UploadFile;
|
|
112
|
+
};
|
|
113
|
+
'image-editor-cancel': {
|
|
114
|
+
file: UploadFile;
|
|
115
|
+
};
|
|
116
|
+
'image-editor-save': {
|
|
117
|
+
file: UploadFile;
|
|
118
|
+
original: UploadFile;
|
|
119
|
+
};
|
|
120
|
+
'drag-over': Record<string, never>;
|
|
121
|
+
'drag-leave': Record<string, never>;
|
|
122
|
+
drop: {
|
|
123
|
+
files: File[];
|
|
124
|
+
};
|
|
125
|
+
'folder-drop-blocked': {
|
|
126
|
+
acceptedFiles: number;
|
|
127
|
+
};
|
|
128
|
+
paste: {
|
|
129
|
+
files: File[];
|
|
130
|
+
};
|
|
131
|
+
'pipeline-start': {
|
|
132
|
+
fileId: string;
|
|
133
|
+
steps: string[];
|
|
134
|
+
};
|
|
135
|
+
'pipeline-step': {
|
|
136
|
+
fileId: string;
|
|
137
|
+
step: string;
|
|
138
|
+
};
|
|
139
|
+
'pipeline-complete': {
|
|
140
|
+
fileId: string;
|
|
141
|
+
};
|
|
142
|
+
'pipeline-error': {
|
|
143
|
+
scope: string;
|
|
144
|
+
name: string;
|
|
145
|
+
message: string;
|
|
146
|
+
};
|
|
147
|
+
'source-click': {
|
|
148
|
+
sourceId: FileSource;
|
|
149
|
+
};
|
|
150
|
+
'source-view-cancel': {
|
|
151
|
+
sourceId: FileSource | undefined;
|
|
152
|
+
};
|
|
153
|
+
'browse-files': Record<string, never>;
|
|
154
|
+
'folder-select': {
|
|
155
|
+
count: number;
|
|
156
|
+
};
|
|
157
|
+
'url-submit': {
|
|
158
|
+
url: string;
|
|
159
|
+
};
|
|
160
|
+
'url-fetch': {
|
|
161
|
+
file: File;
|
|
162
|
+
};
|
|
163
|
+
'url-fetch-cancel': {
|
|
164
|
+
url: string;
|
|
165
|
+
};
|
|
166
|
+
'camera-capture': {
|
|
167
|
+
dataUrl: string;
|
|
168
|
+
};
|
|
169
|
+
'camera-confirm': {
|
|
170
|
+
file: File;
|
|
171
|
+
};
|
|
172
|
+
'file-preview-open': {
|
|
173
|
+
fileId: string;
|
|
174
|
+
fileName: string;
|
|
175
|
+
};
|
|
176
|
+
'file-preview-close': {
|
|
177
|
+
fileId: string;
|
|
178
|
+
fileName: string;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
type EventHandler<T = unknown> = (payload: T) => void;
|
|
183
|
+
declare class EventEmitter<TEvents extends object = Record<string, unknown>> {
|
|
184
|
+
private handlers;
|
|
185
|
+
on<K extends string & keyof TEvents>(event: K, handler: EventHandler<TEvents[K]>): () => void;
|
|
186
|
+
on(event: string, handler: EventHandler): () => void;
|
|
187
|
+
off(event: string, handler: EventHandler): void;
|
|
188
|
+
emit<K extends string & keyof TEvents>(event: K, payload: TEvents[K]): void;
|
|
189
|
+
emit(event: string, payload?: unknown): void;
|
|
190
|
+
removeAllListeners(event?: string): void;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
interface UpupPlugin {
|
|
194
|
+
/** Unique name — used for deduplication and debugging */
|
|
195
|
+
name: string;
|
|
196
|
+
/**
|
|
197
|
+
* Called once when the plugin is registered, with core's event bus. The one
|
|
198
|
+
* plugin lifecycle hook (F-607) — a plugin subscribes to core events and
|
|
199
|
+
* emits its own through this emitter. Optional: a plugin that only needs
|
|
200
|
+
* registration (dedup + storage) may omit it.
|
|
201
|
+
*/
|
|
202
|
+
init?(emitter: EventEmitter): void;
|
|
203
|
+
}
|
|
204
|
+
type ExtensionMethods = Record<string, (...args: unknown[]) => unknown>;
|
|
205
|
+
declare class PluginManager {
|
|
206
|
+
private plugins;
|
|
207
|
+
private extensions;
|
|
208
|
+
register(plugin: UpupPlugin): void;
|
|
209
|
+
registerExtension(name: string, methods: ExtensionMethods): void;
|
|
210
|
+
getPlugin(name: string): UpupPlugin | undefined;
|
|
211
|
+
getExtension(name: string): ExtensionMethods | undefined;
|
|
212
|
+
getExtensions(): Record<string, ExtensionMethods>;
|
|
213
|
+
destroy(): void;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* @param bytes assign keyword depend on size
|
|
218
|
+
*/
|
|
219
|
+
declare const bytesToSize: (bytes: number) => string;
|
|
220
|
+
/**
|
|
221
|
+
* @param size
|
|
222
|
+
* @param unit
|
|
223
|
+
*/
|
|
224
|
+
declare const sizeToBytes: (size: number, unit?: "B" | "KB" | "MB" | "GB" | "TB" | "PB" | "EB" | "ZB" | "YB") => number;
|
|
225
|
+
/**
|
|
226
|
+
* @param file
|
|
227
|
+
* @param sizeLimit
|
|
228
|
+
* @param mode
|
|
229
|
+
*/
|
|
230
|
+
declare function checkFileSize(file: File, sizeLimit: MaxFileSizeObject | undefined, mode?: 'max' | 'min'): boolean;
|
|
231
|
+
/**
|
|
232
|
+
* Maximum file size (in bytes) for which text-based preview is allowed.
|
|
233
|
+
* Files exceeding this threshold will show a static icon instead of rendering content,
|
|
234
|
+
* preventing the browser from freezing on large text files (e.g. 3MB+ JSON).
|
|
235
|
+
*/
|
|
236
|
+
declare const PREVIEW_MAX_TEXT_SIZE: number;
|
|
237
|
+
/**
|
|
238
|
+
* Maximum number of characters to render in the preview portal for text files.
|
|
239
|
+
* Content beyond this limit is truncated with an indicator.
|
|
240
|
+
*/
|
|
241
|
+
declare const PREVIEW_TEXT_TRUNCATE_LENGTH = 100000;
|
|
242
|
+
/**
|
|
243
|
+
* Determines whether a file is a text-based file that could be previewed as text.
|
|
244
|
+
*/
|
|
245
|
+
declare function fileGetIsText(fileType: string | undefined, fileName?: string): boolean;
|
|
246
|
+
/**
|
|
247
|
+
* Returns true if a text file is small enough to safely preview inline.
|
|
248
|
+
*/
|
|
249
|
+
declare function fileCanPreviewText(fileType: string | undefined, fileName: string | undefined, fileSize: number | undefined): boolean;
|
|
250
|
+
declare function fileGetIsImage(fileType?: string): boolean;
|
|
251
|
+
declare function fileGetIsPdf(fileType: string | undefined, fileName?: string): boolean;
|
|
252
|
+
declare function fileGetExtension(fileType: string | undefined, fileName?: string): string;
|
|
253
|
+
declare function fileIs3D(ext: string): boolean;
|
|
254
|
+
type FileProgress = {
|
|
255
|
+
id: string;
|
|
256
|
+
loaded: number;
|
|
257
|
+
total: number;
|
|
258
|
+
};
|
|
259
|
+
type FilesProgressMap = Record<string, FileProgress>;
|
|
260
|
+
declare function searchDriveFiles<T extends {
|
|
261
|
+
name: string;
|
|
262
|
+
}>(files: T[], searchTerm: string, options?: {
|
|
263
|
+
caseSensitive?: boolean;
|
|
264
|
+
exactMatch?: boolean;
|
|
265
|
+
maxResults?: number;
|
|
266
|
+
}): T[];
|
|
267
|
+
|
|
268
|
+
interface GoogleDriveConfig {
|
|
269
|
+
clientId: string;
|
|
270
|
+
apiKey: string;
|
|
271
|
+
appId: string;
|
|
272
|
+
}
|
|
273
|
+
interface OneDriveConfig {
|
|
274
|
+
clientId: string;
|
|
275
|
+
redirectUri?: string;
|
|
276
|
+
}
|
|
277
|
+
interface DropboxConfig {
|
|
278
|
+
clientId: string;
|
|
279
|
+
redirectUri?: string;
|
|
280
|
+
}
|
|
281
|
+
interface BoxConfig {
|
|
282
|
+
clientId: string;
|
|
283
|
+
redirectUri?: string;
|
|
284
|
+
}
|
|
285
|
+
/** Public cloud-drive configuration — identical shape from framework props down to plugins. */
|
|
286
|
+
interface CloudDrivesConfig {
|
|
287
|
+
googleDrive?: GoogleDriveConfig;
|
|
288
|
+
oneDrive?: OneDriveConfig;
|
|
289
|
+
dropbox?: DropboxConfig;
|
|
290
|
+
box?: BoxConfig;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
interface FileManagerOptions {
|
|
294
|
+
allowedFileTypes?: string | undefined;
|
|
295
|
+
limit?: number | undefined;
|
|
296
|
+
maxFileSize?: MaxFileSizeObject | undefined;
|
|
297
|
+
minFileSize?: MaxFileSizeObject | undefined;
|
|
298
|
+
maxTotalFileSize?: MaxFileSizeObject | undefined;
|
|
299
|
+
contentDeduplication?: boolean | undefined;
|
|
300
|
+
onBeforeFileAdded?: ((file: File) => boolean | File | undefined | Promise<boolean | File | undefined>) | undefined;
|
|
301
|
+
}
|
|
302
|
+
declare class FileManager {
|
|
303
|
+
private files;
|
|
304
|
+
private options;
|
|
305
|
+
constructor(options: FileManagerOptions);
|
|
306
|
+
updateOptions(options: Partial<FileManagerOptions>): void;
|
|
307
|
+
getFiles(): ReadonlyMap<string, UploadFile>;
|
|
308
|
+
/**
|
|
309
|
+
* Immutable file-status transition: produce a NEW UploadFile carrying the patch,
|
|
310
|
+
* store and return it. FileManager is the sole writer of a file's status/key/metadata
|
|
311
|
+
* (F-144), and the new reference lets the orchestrator's ref-diff projection track the
|
|
312
|
+
* transition (F-145).
|
|
313
|
+
*
|
|
314
|
+
* Constraint: object-spread (`{ ...prev }`) would strip File's blob data and methods —
|
|
315
|
+
* they live in internal slots / on the prototype, not as own-enumerable props — leaving
|
|
316
|
+
* a plain object that breaks `xhr.send(file)` in the direct-upload strategy. So we
|
|
317
|
+
* re-wrap the same backing bytes into a fresh File (a view, not a copy) and copy the
|
|
318
|
+
* UploadFile fields onto it — mirroring `cloneUploadFile` (steps/image-utils.ts). Do
|
|
319
|
+
* NOT "simplify" this back to a spread.
|
|
320
|
+
*/
|
|
321
|
+
updateFile(id: string, patch: Partial<UploadFile>): UploadFile | undefined;
|
|
322
|
+
private validateFile;
|
|
323
|
+
private collectAcceptedFiles;
|
|
324
|
+
private deduplicateByContent;
|
|
325
|
+
private assertBatchFits;
|
|
326
|
+
addFiles(nativeFiles: File[]): Promise<UploadFile[]>;
|
|
327
|
+
removeFile(id: string): UploadFile | undefined;
|
|
328
|
+
replaceFile(id: string, file: File | UploadFile): UploadFile;
|
|
329
|
+
removeAll(): void;
|
|
330
|
+
/** Bulk-apply pipeline-produced files (already UploadFile with status/key set). */
|
|
331
|
+
applyProcessed(files: UploadFile[]): void;
|
|
332
|
+
/** Re-instate a prior snapshot: clear and repopulate from entries. */
|
|
333
|
+
restore(entries: [string, UploadFile][]): void;
|
|
334
|
+
setFiles(nativeFiles: File[]): Promise<UploadFile[]>;
|
|
335
|
+
reorderFiles(fileIds: string[]): void;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
interface PersistentStorage {
|
|
339
|
+
get(key: string): Promise<unknown>;
|
|
340
|
+
set(key: string, value: unknown): Promise<void>;
|
|
341
|
+
delete(key: string): Promise<void>;
|
|
342
|
+
}
|
|
343
|
+
declare class CrashRecoveryManager {
|
|
344
|
+
private storage;
|
|
345
|
+
constructor(storage: PersistentStorage);
|
|
346
|
+
save(snapshot: unknown): Promise<void>;
|
|
347
|
+
restore(): Promise<unknown>;
|
|
348
|
+
clear(): Promise<void>;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* IndexedDB-based storage for browser environments.
|
|
352
|
+
* Falls back gracefully when IndexedDB is unavailable (SSR, privacy mode).
|
|
353
|
+
*/
|
|
354
|
+
declare class IndexedDBStorage implements PersistentStorage {
|
|
355
|
+
private dbName;
|
|
356
|
+
private storeName;
|
|
357
|
+
/** ONE cached connection for the storage's lifetime — never closed after
|
|
358
|
+
* an operation. Firefox ties Blob/File handles read from IndexedDB to
|
|
359
|
+
* the connection they were read over: with the old open-per-operation /
|
|
360
|
+
* close-on-complete lifecycle, the File revived by the crash-recovery
|
|
361
|
+
* restore lost its backing store shortly after the restore's transaction
|
|
362
|
+
* closed, and mid-resume slice reads rejected with AbortError ("The
|
|
363
|
+
* operation was aborted") — a Firefox-only reload-resume stall reproduced
|
|
364
|
+
* against both MinIO and Backblaze B2 (Chromium materializes IndexedDB
|
|
365
|
+
* blobs independently of the connection and never failed). The cache
|
|
366
|
+
* still yields: `versionchange` (a deleteDatabase/upgrade elsewhere)
|
|
367
|
+
* closes and drops it so the other context is never blocked, and a
|
|
368
|
+
* browser-initiated `close` drops it so the next operation reopens. */
|
|
369
|
+
private dbPromise;
|
|
370
|
+
constructor(dbName?: string);
|
|
371
|
+
private getDB;
|
|
372
|
+
/** Close and release the cached connection. Safe at any time — the next
|
|
373
|
+
* operation reopens. `UpupCore.destroy()` calls this so an unmounted
|
|
374
|
+
* uploader doesn't keep the database held open (pending transactions
|
|
375
|
+
* still drain first per the IndexedDB spec, so a queued snapshot write
|
|
376
|
+
* is never cut off mid-transaction). */
|
|
377
|
+
close(): void;
|
|
378
|
+
get(key: string): Promise<unknown>;
|
|
379
|
+
set(key: string, value: unknown): Promise<void>;
|
|
380
|
+
delete(key: string): Promise<void>;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
interface UpupCorsConfig {
|
|
384
|
+
dangerouslyAutoConfigure?: boolean;
|
|
385
|
+
allowedOrigins: string[];
|
|
386
|
+
allowedMethods?: string[];
|
|
387
|
+
allowedHeaders?: string[];
|
|
388
|
+
maxAgeSeconds?: number;
|
|
389
|
+
}
|
|
390
|
+
interface CrashRecoveryOptions {
|
|
391
|
+
storage?: PersistentStorage;
|
|
392
|
+
}
|
|
393
|
+
interface CoreOptions extends FileManagerOptions {
|
|
394
|
+
uploadEndpoint?: string | undefined;
|
|
395
|
+
serverUrl?: string | undefined;
|
|
396
|
+
provider?: string | undefined;
|
|
397
|
+
mode?: 'client' | 'server' | undefined;
|
|
398
|
+
plugins?: UpupPlugin[] | undefined;
|
|
399
|
+
pipeline?: PipelineStep[] | undefined;
|
|
400
|
+
resumable?: ResumableUploadOptions | undefined;
|
|
401
|
+
heicConversion?: boolean | undefined;
|
|
402
|
+
stripExifData?: boolean | undefined;
|
|
403
|
+
imageCompression?: boolean | object | undefined;
|
|
404
|
+
thumbnailGenerator?: boolean | object | undefined;
|
|
405
|
+
checksumVerification?: boolean | undefined;
|
|
406
|
+
/**
|
|
407
|
+
* Web Worker offload for the file pipeline (hash/heic/exif/thumbnail/compress).
|
|
408
|
+
* Unset/`true` = auto (workers used when supported, transparent main-thread
|
|
409
|
+
* fallback otherwise). `false` = force the main thread.
|
|
410
|
+
*/
|
|
411
|
+
webWorker?: boolean | undefined;
|
|
412
|
+
/**
|
|
413
|
+
* Web-worker task timeout in ms. Default 30000. On timeout the task falls
|
|
414
|
+
* back to main-thread processing (it never fails the file).
|
|
415
|
+
*/
|
|
416
|
+
workerTimeoutMs?: number | undefined;
|
|
417
|
+
maxRetries?: number | undefined;
|
|
418
|
+
maxConcurrentUploads?: number | undefined;
|
|
419
|
+
autoUpload?: boolean | undefined;
|
|
420
|
+
/**
|
|
421
|
+
* React to browser connectivity: going offline mid-upload pauses the run
|
|
422
|
+
* (so multipart sessions persist instead of burning retries against a dead
|
|
423
|
+
* network), and coming back online resumes it — only when the pause was
|
|
424
|
+
* offline-initiated, never overriding a pause the user chose. Default on;
|
|
425
|
+
* `false` restores the fail-and-retry behavior. No-op outside a browser.
|
|
426
|
+
*/
|
|
427
|
+
networkAware?: boolean | undefined;
|
|
428
|
+
fastAbortThreshold?: number | undefined;
|
|
429
|
+
isSuccessfulCall?: ((response: {
|
|
430
|
+
status: number;
|
|
431
|
+
headers: Record<string, string>;
|
|
432
|
+
body: unknown;
|
|
433
|
+
}) => boolean | Promise<boolean>) | undefined;
|
|
434
|
+
crashRecovery?: boolean | CrashRecoveryOptions | undefined;
|
|
435
|
+
onError?: ((error: string | Error) => void) | undefined;
|
|
436
|
+
metadata?: Record<string, unknown> | undefined;
|
|
437
|
+
cors?: UpupCorsConfig | undefined;
|
|
438
|
+
/**
|
|
439
|
+
* i18n configuration. Accepts either:
|
|
440
|
+
* - a full LocaleBundle (`import { enUS } from './contracts'`) — also
|
|
441
|
+
* drives the file-pipeline translator (`context.t` inside pipeline
|
|
442
|
+
* steps), not just the UI translator.
|
|
443
|
+
* - a BCP 47 locale code string (e.g. `'fr-FR'`) — resolves to lang/dir
|
|
444
|
+
* only until a locale registry exists; consumers are responsible for
|
|
445
|
+
* resolving codes to bundles via `i18n.loadLocale`.
|
|
446
|
+
*/
|
|
447
|
+
locale?: LocaleBundle | UpupLocaleCode | undefined;
|
|
448
|
+
cloudDrives?: CloudDrivesConfig | undefined;
|
|
449
|
+
}
|
|
450
|
+
type ValidationResult = {
|
|
451
|
+
file: File;
|
|
452
|
+
valid: boolean;
|
|
453
|
+
errors: Array<{
|
|
454
|
+
code: string;
|
|
455
|
+
message: string;
|
|
456
|
+
}>;
|
|
457
|
+
};
|
|
458
|
+
type UploadOptions = {
|
|
459
|
+
checksumVerification?: boolean;
|
|
460
|
+
imageCompression?: boolean | object;
|
|
461
|
+
heicConversion?: boolean;
|
|
462
|
+
stripExifData?: boolean;
|
|
463
|
+
maxRetries?: number;
|
|
464
|
+
metadata?: Record<string, string>;
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
declare class UpupCore {
|
|
468
|
+
private emitter;
|
|
469
|
+
private pluginManager;
|
|
470
|
+
private fileManager;
|
|
471
|
+
private pipelineEngine;
|
|
472
|
+
private uploadManager;
|
|
473
|
+
private _status;
|
|
474
|
+
private _error;
|
|
475
|
+
private crashRecovery;
|
|
476
|
+
private crashRecoveryStorage;
|
|
477
|
+
private crashRecoveryUnsubscribe;
|
|
478
|
+
/** Every crash-recovery storage write flows through this one promise chain.
|
|
479
|
+
* Blob snapshots of large files make IndexedDB puts slow; fire-and-forget
|
|
480
|
+
* save/clear calls complete out of order, so a save started before
|
|
481
|
+
* completion can land after the completion clear and resurrect a finished
|
|
482
|
+
* upload as a resumable one. FIFO ordering makes the last requested op the
|
|
483
|
+
* last applied op. */
|
|
484
|
+
private crashRecoveryChain;
|
|
485
|
+
/** True while a snapshot sync is queued but not yet run. Progress ticks
|
|
486
|
+
* arrive far faster than a large snapshot writes; coalescing them into the
|
|
487
|
+
* one queued sync (which reads state at write time) keeps it to at most
|
|
488
|
+
* one write in flight plus one pending, instead of N stacked blob puts. */
|
|
489
|
+
private crashRecoverySyncQueued;
|
|
490
|
+
private fileOverrides;
|
|
491
|
+
private pauseRequested;
|
|
492
|
+
private cancelRequested;
|
|
493
|
+
private destroyed;
|
|
494
|
+
/** True only while the CURRENT pause was made by the offline handler —
|
|
495
|
+
* the one case `online` may resume. A pause the user chose stays theirs. */
|
|
496
|
+
private offlinePausedRun;
|
|
497
|
+
private detachNetworkListeners;
|
|
498
|
+
private activeRun;
|
|
499
|
+
private workerProvider;
|
|
500
|
+
options: CoreOptions;
|
|
501
|
+
constructor(options: CoreOptions);
|
|
502
|
+
/** Connectivity reactions (`networkAware`, default on): `offline` pauses
|
|
503
|
+
* an active run — with `persist` on, that keeps the multipart session
|
|
504
|
+
* alive instead of burning whole-run retries against a dead network —
|
|
505
|
+
* and `online` resumes it, but ONLY when this handler made the pause.
|
|
506
|
+
* SSR/node-safe: without a window this installs nothing. */
|
|
507
|
+
private installNetworkAwareness;
|
|
508
|
+
/** The one projection of CoreOptions the FileManager consumes — construction
|
|
509
|
+
* and updateOptions() must stay in lockstep, so both call this. */
|
|
510
|
+
private fileManagerOptions;
|
|
511
|
+
get files(): ReadonlyMap<string, UploadFile>;
|
|
512
|
+
get status(): UploadStatus;
|
|
513
|
+
get error(): Error | null;
|
|
514
|
+
get progress(): {
|
|
515
|
+
totalFiles: number;
|
|
516
|
+
completedFiles: number;
|
|
517
|
+
percentage: number;
|
|
518
|
+
};
|
|
519
|
+
/**
|
|
520
|
+
* Crash-recovery persistence is best-effort by design — a failed save/clear
|
|
521
|
+
* must never break an upload. But full silence hides a dead durability
|
|
522
|
+
* opt-in (F-734): surface failures dev-only, matching the worker-fallback
|
|
523
|
+
* convention in maybeCreateWorkerProvider().
|
|
524
|
+
*/
|
|
525
|
+
private warnCrashRecoveryFailure;
|
|
526
|
+
private configureCrashRecovery;
|
|
527
|
+
/** Queue a snapshot write that reads files/status at WRITE time, not at
|
|
528
|
+
* event time — so the write that runs last always reflects the state that
|
|
529
|
+
* came last, and a completion observed while a save is queued turns that
|
|
530
|
+
* queued write into the clear instead of racing it. */
|
|
531
|
+
private queueCrashRecoverySync;
|
|
532
|
+
/** Queue an unconditional clear behind any in-flight snapshot write. The
|
|
533
|
+
* default manager is captured at call time so a clear requested before
|
|
534
|
+
* disable/destroy still applies after the field is nulled. */
|
|
535
|
+
private queueCrashRecoveryClear;
|
|
536
|
+
private enqueueCrashRecoveryOp;
|
|
537
|
+
private disableCrashRecovery;
|
|
538
|
+
use(plugin: UpupPlugin): this;
|
|
539
|
+
registerExtension(name: string, methods: ExtensionMethods): void;
|
|
540
|
+
getPlugin(name: string): UpupPlugin | undefined;
|
|
541
|
+
getExtension(name: string): ExtensionMethods | undefined;
|
|
542
|
+
get ext(): Record<string, ExtensionMethods>;
|
|
543
|
+
addFiles(files: File[], overrides?: Partial<UploadOptions>): Promise<void>;
|
|
544
|
+
/**
|
|
545
|
+
* Discard the persisted multipart sessions of files the user just threw
|
|
546
|
+
* away (cancel / removeFile / removeAll), aborting them server-side on the
|
|
547
|
+
* way out. With `resumable.persist` on, a failed or cancelled upload
|
|
548
|
+
* deliberately keeps its server-side parts alive for a later resume — so
|
|
549
|
+
* an explicit discard is the ONE place that has to say "no, really, drop
|
|
550
|
+
* it", or the user pays storage for parts nothing will ever finish.
|
|
551
|
+
*
|
|
552
|
+
* Fire-and-forget and fully swallowed: cancelling must never throw or wait.
|
|
553
|
+
*/
|
|
554
|
+
private discardPersistedMultipartSessions;
|
|
555
|
+
removeFile(id: string): void;
|
|
556
|
+
removeAll(): void;
|
|
557
|
+
setFiles(files: File[]): Promise<void>;
|
|
558
|
+
/** Update options after construction (e.g. when React props change). */
|
|
559
|
+
updateOptions(partial: Partial<CoreOptions>): void;
|
|
560
|
+
reorderFiles(fileIds: string[]): void;
|
|
561
|
+
private maybeCreateWorkerProvider;
|
|
562
|
+
private hasUploadTarget;
|
|
563
|
+
private createUploadManager;
|
|
564
|
+
private markFilesReady;
|
|
565
|
+
private updatePendingFileStatuses;
|
|
566
|
+
private markUnsuccessfulFilesFailed;
|
|
567
|
+
private uploadFiles;
|
|
568
|
+
validateFiles(files: File[]): Promise<ValidationResult[]>;
|
|
569
|
+
upload(): Promise<UploadFile[]>;
|
|
570
|
+
private resetRunFlags;
|
|
571
|
+
private runUpload;
|
|
572
|
+
/**
|
|
573
|
+
* The single terminal-failure path shared by all three run flavors
|
|
574
|
+
* (runUpload / runRetry / resume). They previously diverged (F-729): only
|
|
575
|
+
* runUpload marked leftover files FAILED, and resume never invoked
|
|
576
|
+
* options.onError — a retry/resume failure looked different to consumers
|
|
577
|
+
* than the identical first-run failure for no reason.
|
|
578
|
+
*/
|
|
579
|
+
private terminalRunFailure;
|
|
580
|
+
replaceFile(id: string, file: File | UploadFile): void;
|
|
581
|
+
/**
|
|
582
|
+
* Pause in-flight uploads by aborting the current abort controller.
|
|
583
|
+
* Note: This cancels active HTTP requests. Resume will re-upload
|
|
584
|
+
* files that were in progress — true pause/resume of partial uploads
|
|
585
|
+
* requires multipart upload support.
|
|
586
|
+
*/
|
|
587
|
+
pause(): void;
|
|
588
|
+
/**
|
|
589
|
+
* Resume uploads after a pause. Re-uploads files that did not
|
|
590
|
+
* complete successfully (those without a `key` set).
|
|
591
|
+
*/
|
|
592
|
+
resume(): void;
|
|
593
|
+
cancel(): void;
|
|
594
|
+
retry(fileId?: string): Promise<UploadFile[]>;
|
|
595
|
+
private runRetry;
|
|
596
|
+
/**
|
|
597
|
+
* Bare event names are the typed CoreEvents catalog and nothing else —
|
|
598
|
+
* the untyped string overload is gone (F-723), so an unknown bare event is
|
|
599
|
+
* now a compile error at the emit/subscribe site. Namespaced drive-plugin
|
|
600
|
+
* events ('<provider>:<event>', e.g. 'google-drive:files-loaded') are
|
|
601
|
+
* dynamic by design — plugins emit them through core's bus (see use()) —
|
|
602
|
+
* and keep a template-literal passthrough.
|
|
603
|
+
*/
|
|
604
|
+
on<K extends keyof CoreEvents>(event: K, handler: (payload: CoreEvents[K]) => void): () => void;
|
|
605
|
+
on(event: `${string}:${string}`, handler: (payload: unknown) => void): () => void;
|
|
606
|
+
off<K extends keyof CoreEvents>(event: K, handler: (payload: CoreEvents[K]) => void): void;
|
|
607
|
+
off(event: `${string}:${string}`, handler: (payload: unknown) => void): void;
|
|
608
|
+
emit<K extends keyof CoreEvents>(event: K, payload: CoreEvents[K]): void;
|
|
609
|
+
emit(event: `${string}:${string}`, data?: unknown): void;
|
|
610
|
+
getSnapshot(): {
|
|
611
|
+
files: [string, UploadFile][];
|
|
612
|
+
status: UploadStatus;
|
|
613
|
+
};
|
|
614
|
+
restore(snapshot: {
|
|
615
|
+
files: [string, UploadFile][];
|
|
616
|
+
status: UploadStatus;
|
|
617
|
+
}): void;
|
|
618
|
+
restoreFromCrashRecovery(): Promise<boolean>;
|
|
619
|
+
/** `resumable.autoResume` continues a crash-restored upload without the
|
|
620
|
+
* explicit Resume click. Off by default on purpose: closing a tab is an
|
|
621
|
+
* ambiguous signal — as often "cancel" as "oops" — so silently resuming
|
|
622
|
+
* a transfer the user may have meant to kill is an integrator's call,
|
|
623
|
+
* never the library's. Deferred a tick so the host finishes mounting
|
|
624
|
+
* (the same guard autoUpload's timer carries, F-148), and re-checked at
|
|
625
|
+
* fire time: the user may have discarded the restore in between. */
|
|
626
|
+
private maybeScheduleAutoResume;
|
|
627
|
+
/** A restored PAUSED file rendered "0 B of N" even when most of it was
|
|
628
|
+
* already in storage — the persisted multipart session knows the real
|
|
629
|
+
* offset, but nothing replayed it into the progress pipeline until the
|
|
630
|
+
* user actually hit resume. Emit it here so the restored UI opens at the
|
|
631
|
+
* byte count the resume will continue from. Same session gates as
|
|
632
|
+
* tryResume (scope), minus the server round-trip: this is display-only
|
|
633
|
+
* and must not spend a request; the authoritative recheck still happens
|
|
634
|
+
* on resume. */
|
|
635
|
+
/** A finished multipart upload can die in the window between its
|
|
636
|
+
* synchronous session removal and the asynchronous IndexedDB snapshot
|
|
637
|
+
* clear — the next visit then restores a file the server already
|
|
638
|
+
* assembled, offering a Resume that would re-upload all of it. The
|
|
639
|
+
* session store is the tiebreaker: init writes the session synchronously
|
|
640
|
+
* before the first byte moves and completion removes it synchronously,
|
|
641
|
+
* so an UPLOADING-status file of multipart size with no session is a
|
|
642
|
+
* stale snapshot, not a crashed upload. PROCESSING files never had a
|
|
643
|
+
* session and stay restorable; so does everything below the multipart
|
|
644
|
+
* threshold or outside persist mode. */
|
|
645
|
+
private isStaleMultipartRestore;
|
|
646
|
+
private seedRestoredProgress;
|
|
647
|
+
clearCrashRecovery(): Promise<void>;
|
|
648
|
+
destroy(): void;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
export { type BoxConfig as B, type CoreEvents as C, type DropboxConfig as D, EventEmitter as E, type FilesProgressMap as F, type GoogleDriveConfig as G, type ImageEditorOptions as I, type OneDriveConfig as O, PluginManager as P, type ResolvedImageEditorOptions as R, type ThumbnailGeneratorOptions as T, UpupCore as U, type ValidationResult as V, type ImageCompressionOptions as a, type CloudDrivesConfig as b, type UpupPlugin as c, type CoreOptions as d, type UploadOptions as e, type UpupCorsConfig as f, type ExtensionMethods as g, type FileProgress as h, FileManager as i, CrashRecoveryManager as j, IndexedDBStorage as k, type PersistentStorage as l, bytesToSize as m, checkFileSize as n, PREVIEW_MAX_TEXT_SIZE as o, PREVIEW_TEXT_TRUNCATE_LENGTH as p, fileGetIsImage as q, fileGetIsPdf as r, sizeToBytes as s, fileGetIsText as t, fileCanPreviewText as u, fileGetExtension as v, fileIs3D as w, searchDriveFiles as x };
|