@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.
Files changed (118) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +8 -0
  3. package/README.md +75 -0
  4. package/dist/browser-SXR426OQ.cjs +10 -0
  5. package/dist/browser-WD6T5ABJ.js +1 -0
  6. package/dist/chunk-2H5ICKFT.cjs +122 -0
  7. package/dist/chunk-6HF3I2JS.cjs +39 -0
  8. package/dist/chunk-6S5DQDQH.js +212 -0
  9. package/dist/chunk-BMQC27OE.cjs +92 -0
  10. package/dist/chunk-BSGQGINR.cjs +219 -0
  11. package/dist/chunk-CPKZ2CXD.cjs +179 -0
  12. package/dist/chunk-DTKDIMKT.cjs +573 -0
  13. package/dist/chunk-DYE5XJ6Z.cjs +2134 -0
  14. package/dist/chunk-E3ZCNOXG.cjs +74 -0
  15. package/dist/chunk-FEQY2WYY.cjs +2377 -0
  16. package/dist/chunk-FMURBCZ7.js +120 -0
  17. package/dist/chunk-FYQQRULL.js +37 -0
  18. package/dist/chunk-GE4LIVXP.js +133 -0
  19. package/dist/chunk-HFR5HZJZ.js +56 -0
  20. package/dist/chunk-I7ULPCA2.js +72 -0
  21. package/dist/chunk-MHYXDLZR.js +569 -0
  22. package/dist/chunk-N2SLHVAW.cjs +61 -0
  23. package/dist/chunk-OOPDEOTM.js +169 -0
  24. package/dist/chunk-PMBR3OUW.js +2359 -0
  25. package/dist/chunk-QK7HZIVY.cjs +144 -0
  26. package/dist/chunk-T2AQHY7V.cjs +59 -0
  27. package/dist/chunk-TRCP5FUR.js +90 -0
  28. package/dist/chunk-U7KL5M2H.cjs +374 -0
  29. package/dist/chunk-UXNPM54W.js +2108 -0
  30. package/dist/chunk-VV6QCQLL.js +365 -0
  31. package/dist/chunk-ZMS2HXLB.js +56 -0
  32. package/dist/context-shapes-123dd3b6.d.cts +207 -0
  33. package/dist/context-shapes-27b24c8f.d.ts +207 -0
  34. package/dist/contracts-pipeline-cf177270.d.cts +78 -0
  35. package/dist/contracts-pipeline-cf177270.d.ts +78 -0
  36. package/dist/contracts-strategies-378a16b7.d.cts +168 -0
  37. package/dist/contracts-strategies-378a16b7.d.ts +168 -0
  38. package/dist/contracts.cjs +181 -0
  39. package/dist/contracts.d.cts +11 -0
  40. package/dist/contracts.d.ts +11 -0
  41. package/dist/contracts.js +4 -0
  42. package/dist/core-141335ac.d.ts +651 -0
  43. package/dist/core-bea2ceca.d.cts +651 -0
  44. package/dist/create-worker-provider-AA5SRII6.js +58 -0
  45. package/dist/create-worker-provider-KJNUSSTW.cjs +60 -0
  46. package/dist/eligibility-ONLNJ6FB.cjs +10 -0
  47. package/dist/eligibility-ULFC3E4G.js +8 -0
  48. package/dist/error-code-map-9c44a425.d.ts +62 -0
  49. package/dist/error-code-map-dd5becfa.d.cts +62 -0
  50. package/dist/i18n/index.cjs +90 -0
  51. package/dist/i18n/index.d.cts +3 -0
  52. package/dist/i18n/index.d.ts +3 -0
  53. package/dist/i18n/index.js +1 -0
  54. package/dist/index.cjs +1770 -0
  55. package/dist/index.d.cts +280 -0
  56. package/dist/index.d.ts +280 -0
  57. package/dist/index.js +1589 -0
  58. package/dist/internal.cjs +2407 -0
  59. package/dist/internal.d.cts +595 -0
  60. package/dist/internal.d.ts +595 -0
  61. package/dist/internal.js +2275 -0
  62. package/dist/pipeline/index.cjs +10 -0
  63. package/dist/pipeline/index.d.cts +11 -0
  64. package/dist/pipeline/index.d.ts +11 -0
  65. package/dist/pipeline/index.js +1 -0
  66. package/dist/pipeline-worker.cjs +199 -0
  67. package/dist/pipeline-worker.d.cts +2 -0
  68. package/dist/pipeline-worker.d.ts +2 -0
  69. package/dist/pipeline-worker.js +197 -0
  70. package/dist/resolve-locale-81feef21.d.ts +20 -0
  71. package/dist/resolve-locale-9cb63600.d.cts +20 -0
  72. package/dist/resolve-theme-01758105.d.ts +53 -0
  73. package/dist/resolve-theme-66cf8d98.d.cts +53 -0
  74. package/dist/server-mode-drive-controller-b5f8ee12.d.cts +180 -0
  75. package/dist/server-mode-drive-controller-b5f8ee12.d.ts +180 -0
  76. package/dist/steps/compress.cjs +66 -0
  77. package/dist/steps/compress.d.cts +10 -0
  78. package/dist/steps/compress.d.ts +10 -0
  79. package/dist/steps/compress.js +64 -0
  80. package/dist/steps/exif.cjs +44 -0
  81. package/dist/steps/exif.d.cts +5 -0
  82. package/dist/steps/exif.d.ts +5 -0
  83. package/dist/steps/exif.js +42 -0
  84. package/dist/steps/hash.cjs +44 -0
  85. package/dist/steps/hash.d.cts +5 -0
  86. package/dist/steps/hash.d.ts +5 -0
  87. package/dist/steps/hash.js +42 -0
  88. package/dist/steps/heic.cjs +59 -0
  89. package/dist/steps/heic.d.cts +5 -0
  90. package/dist/steps/heic.d.ts +5 -0
  91. package/dist/steps/heic.js +57 -0
  92. package/dist/steps/thumbnail.cjs +54 -0
  93. package/dist/steps/thumbnail.d.cts +10 -0
  94. package/dist/steps/thumbnail.d.ts +10 -0
  95. package/dist/steps/thumbnail.js +52 -0
  96. package/dist/strategies/index.cjs +82 -0
  97. package/dist/strategies/index.d.cts +187 -0
  98. package/dist/strategies/index.d.ts +187 -0
  99. package/dist/strategies/index.js +60 -0
  100. package/dist/strategies/tus-upload.cjs +14 -0
  101. package/dist/strategies/tus-upload.d.cts +15 -0
  102. package/dist/strategies/tus-upload.d.ts +15 -0
  103. package/dist/strategies/tus-upload.js +5 -0
  104. package/dist/theme/index.cjs +38 -0
  105. package/dist/theme/index.d.cts +3 -0
  106. package/dist/theme/index.d.ts +3 -0
  107. package/dist/theme/index.js +1 -0
  108. package/dist/theme-store-2e56a674.d.cts +39 -0
  109. package/dist/theme-store-f13e0315.d.ts +39 -0
  110. package/dist/token-endpoint-5fdb4a35.d.ts +20 -0
  111. package/dist/token-endpoint-a7d15ab6.d.cts +20 -0
  112. package/dist/ui-translations-c5d00392.d.cts +455 -0
  113. package/dist/ui-translations-c5d00392.d.ts +455 -0
  114. package/dist/uploader-props-72242002.d.ts +340 -0
  115. package/dist/uploader-props-7f956e60.d.cts +340 -0
  116. package/dist/vars-d3421f6c.d.cts +240 -0
  117. package/dist/vars-d3421f6c.d.ts +240 -0
  118. package/package.json +182 -0
@@ -0,0 +1,340 @@
1
+ import { a as UploadFile, F as FileSource } from './contracts-pipeline-cf177270.js';
2
+ import { I as ImageEditorOptions } from './core-141335ac.js';
3
+ import { L as LocaleBundle, P as PartialMessages } from './ui-translations-c5d00392.js';
4
+ import { M as MaxFileSizeObject, R as ResumableUploadOptions } from './contracts-strategies-378a16b7.js';
5
+ import { f as UpupThemeConfig } from './vars-d3421f6c.js';
6
+
7
+ declare enum UpupErrorCode {
8
+ AUTH_EXPIRED = "AUTH_EXPIRED",
9
+ AUTH_DENIED = "AUTH_DENIED",
10
+ AUTH_PROVIDER_ERROR = "AUTH_PROVIDER_ERROR",
11
+ FILE_TOO_LARGE = "FILE_TOO_LARGE",
12
+ FILE_TOO_SMALL = "FILE_TOO_SMALL",
13
+ TYPE_MISMATCH = "TYPE_MISMATCH",
14
+ LIMIT_EXCEEDED = "LIMIT_EXCEEDED",
15
+ TOTAL_SIZE_EXCEEDED = "TOTAL_SIZE_EXCEEDED",
16
+ DUPLICATE = "DUPLICATE",
17
+ MIN_FILES_NOT_MET = "MIN_FILES_NOT_MET",
18
+ UPLOAD_FAILED = "UPLOAD_FAILED",
19
+ UPLOAD_ABORTED = "UPLOAD_ABORTED",
20
+ PRESIGN_FAILED = "PRESIGN_FAILED",
21
+ CORS_ERROR = "CORS_ERROR",
22
+ PIPELINE_STEP_FAILED = "PIPELINE_STEP_FAILED",
23
+ HEIC_CONVERSION_FAILED = "HEIC_CONVERSION_FAILED",
24
+ NETWORK_ERROR = "NETWORK_ERROR",
25
+ TIMEOUT = "TIMEOUT",
26
+ STORAGE_ERROR = "STORAGE_ERROR",
27
+ QUOTA_EXCEEDED = "QUOTA_EXCEEDED",
28
+ NO_UPLOAD_TARGET = "NO_UPLOAD_TARGET",
29
+ BAD_REQUEST = "BAD_REQUEST",
30
+ AUTH_REQUIRED = "AUTH_REQUIRED",
31
+ /** The addressed resource is gone server-side — e.g. resuming a multipart
32
+ * upload the storage provider has already completed, aborted, or reaped.
33
+ * Always paired with a 4xx so the client starts fresh instead of retrying
34
+ * something that will never come back. */
35
+ NOT_FOUND = "NOT_FOUND"
36
+ }
37
+ type RestrictionFailedReason = UpupErrorCode.TYPE_MISMATCH | UpupErrorCode.FILE_TOO_LARGE | UpupErrorCode.FILE_TOO_SMALL | UpupErrorCode.LIMIT_EXCEEDED | UpupErrorCode.TOTAL_SIZE_EXCEEDED | UpupErrorCode.DUPLICATE | 'BEFORE_FILE_ADDED_REJECTED';
38
+ declare class UpupError extends Error {
39
+ code: string;
40
+ retryable: boolean;
41
+ /** Optional HTTP status the error originated from (set by uploadErrorFromResponse). */
42
+ status?: number;
43
+ constructor(message: string, code: string, retryable?: boolean);
44
+ }
45
+ declare class UpupAuthError extends UpupError {
46
+ provider: string;
47
+ constructor(message: string, provider: string);
48
+ }
49
+ declare class UpupNetworkError extends UpupError {
50
+ constructor(message: string, status?: number);
51
+ }
52
+ declare class UpupValidationError extends UpupError {
53
+ reason: RestrictionFailedReason;
54
+ file: File;
55
+ constructor(message: string, reason: RestrictionFailedReason, file: File);
56
+ }
57
+ declare class UpupQuotaError extends UpupError {
58
+ limit: number;
59
+ used: number;
60
+ constructor(message: string, limit: number, used: number);
61
+ }
62
+ declare class UpupStorageError extends UpupError {
63
+ provider: string;
64
+ operation: 'presign' | 'upload' | 'multipart-init' | 'multipart-complete' | 'multipart-sign-part' | 'multipart-abort' | 'multipart-resume';
65
+ constructor(message: string, provider: string, operation: UpupStorageError['operation']);
66
+ }
67
+ declare class UpupConfigError extends UpupError {
68
+ constructor(message: string, code?: string);
69
+ }
70
+ /**
71
+ * Best-effort parse of an HTTP error response body into a {code, message}
72
+ * pair. Tries, in order: JSON `{code, error|message}`, S3-style XML
73
+ * `<Error><Code>/<Message></Error>`, then falls back to a truncated text
74
+ * snippet with no code.
75
+ */
76
+ declare function parseErrorBody(body: string | undefined): {
77
+ code?: string;
78
+ message: string;
79
+ };
80
+ interface UploadErrorFromResponseArgs {
81
+ status: number;
82
+ statusText: string;
83
+ body?: string;
84
+ kind: 'storage' | 'auth' | 'network';
85
+ /** Required when kind === 'storage'; ignored otherwise. */
86
+ operation?: UpupStorageError['operation'];
87
+ /** Provider label for storage/auth errors (e.g. 'S3', 'google-drive'). Defaults to 'server'. */
88
+ provider?: string;
89
+ }
90
+ /**
91
+ * Construct a typed, code-carrying error from a failed fetch/XHR response —
92
+ * the client-side half of the server's `{error, code}` convention (and S3's
93
+ * own `<Error><Code>` XML). Picks the error class by `kind`; the resulting
94
+ * `.code` is the server/S3-supplied machine code when present, else falls
95
+ * back to the HTTP status text.
96
+ */
97
+ declare function uploadErrorFromResponse(args: UploadErrorFromResponseArgs): UpupError;
98
+
99
+ type FileUploadResult = {
100
+ file: UploadFile;
101
+ url: string;
102
+ status: 'success' | 'failed' | 'skipped';
103
+ error?: UpupError;
104
+ };
105
+
106
+ declare enum StorageProvider {
107
+ AWS = "aws",
108
+ Azure = "azure",
109
+ BackBlaze = "backblaze",
110
+ DigitalOcean = "digitalocean",
111
+ CloudflareR2 = "r2",
112
+ Wasabi = "wasabi",
113
+ MinIO = "minio",
114
+ GCS = "gcs",
115
+ Supabase = "supabase",
116
+ Hetzner = "hetzner",
117
+ Linode = "linode",
118
+ Vultr = "vultr",
119
+ UpCloud = "upcloud",
120
+ Scaleway = "scaleway",
121
+ OVHcloud = "ovhcloud",
122
+ Alibaba = "alibaba",
123
+ Oracle = "oracle",
124
+ Contabo = "contabo",
125
+ Storj = "storj",
126
+ IDrive = "idrive",
127
+ Ceph = "ceph"
128
+ }
129
+ /**
130
+ * Providers with no S3-compatible API surface (F-657). @useupup/server's storage
131
+ * path (buildS3ClientConfig) always builds an @aws-sdk/client-s3 client — it
132
+ * cannot serve a provider in this set no matter what storage.type is set to.
133
+ * Kept next to the enum so any future non-S3 addition is an explicit,
134
+ * greppable decision; createUpupHandler's construct-time guard is the sole
135
+ * consumer.
136
+ */
137
+ declare const NON_S3_STORAGE_PROVIDERS: ReadonlySet<StorageProvider>;
138
+
139
+ /**
140
+ * String-literal accept-set for the public props: everywhere a prop takes a
141
+ * source id, plain strings ('local', 'googleDrive', …) must typecheck without
142
+ * importing the FileSource enum. Deliberately kept ALONGSIDE FileSource — not
143
+ * an accidental alias (F-726 ruling); the accept-set is pinned by
144
+ * src/__tests__/types/upload-source.test.ts.
145
+ */
146
+ type UploadSource = `${FileSource}`;
147
+ type UploadProvider = StorageProvider | (string & {});
148
+
149
+ /**
150
+ * Shared shape of the UI-package `UploaderProps` across react/vue/svelte/
151
+ * angular. Each framework extends this with its own `icons` (component type
152
+ * differs per framework) and `style` (React.CSSProperties vs
153
+ * Record<string, string>) — the two genuinely framework-specific members.
154
+ *
155
+ * Canonical home for the props all four frameworks hand-authored in
156
+ * parallel; keeping one definition here means a field added to one
157
+ * framework's copy can no longer silently diverge from the others.
158
+ */
159
+ type UploaderBaseProps = {
160
+ /**
161
+ * Storage provider. Optional for local-only selection and generic
162
+ * uploadEndpoint/serverUrl flows. When provided, accepts core provider
163
+ * enum values plus custom provider ids forwarded to user/server code.
164
+ */
165
+ provider?: UploadProvider | undefined;
166
+ /**
167
+ * Upload mode. `'client'` (default) = browser talks to storage
168
+ * directly; server only signs URLs. `'server'` = browser talks only
169
+ * to `serverUrl`, which proxies drive APIs + storage writes. Pick
170
+ * `'server'` when you can't expose OAuth client secrets to the
171
+ * browser or when you need server-side compliance/scanning.
172
+ */
173
+ mode?: 'client' | 'server' | undefined;
174
+ /** Source list. e.g. sources={['local','camera','googleDrive']} */
175
+ sources?: UploadSource[] | undefined;
176
+ /** Endpoint returning presigned upload URLs. */
177
+ uploadEndpoint?: string | undefined;
178
+ /** Server URL for @useupup/server handler. */
179
+ serverUrl?: string | undefined;
180
+ /** Maximum number of files that can be added. Default 10. */
181
+ maxFiles?: number | undefined;
182
+ /** v2: Theme configuration. mode replaces `dark`, tokens/slots replace flat styling overrides. */
183
+ theme?: UpupThemeConfig | undefined;
184
+ /** Folder upload configuration. */
185
+ folderUpload?: {
186
+ /** Traverse directories when a user drops a folder onto the uploader. */
187
+ allowDrop?: boolean;
188
+ /** Show a "Select folder" action in the local device source. */
189
+ showSelectFolderButton?: boolean;
190
+ } | undefined;
191
+ /** CORS configuration. `dangerouslyAutoConfigure` can mutate storage CORS and should only be used for quick setup. */
192
+ cors?: {
193
+ dangerouslyAutoConfigure?: boolean;
194
+ allowedOrigins: string[];
195
+ allowedMethods?: string[];
196
+ allowedHeaders?: string[];
197
+ maxAgeSeconds?: number;
198
+ } | undefined;
199
+ /** Cloud drive configurations. */
200
+ cloudDrives?: {
201
+ googleDrive?: {
202
+ clientId: string;
203
+ apiKey: string;
204
+ appId: string;
205
+ };
206
+ oneDrive?: {
207
+ clientId: string;
208
+ redirectUri?: string;
209
+ };
210
+ dropbox?: {
211
+ clientId: string;
212
+ redirectUri?: string;
213
+ };
214
+ box?: {
215
+ clientId: string;
216
+ redirectUri?: string;
217
+ };
218
+ } | undefined;
219
+ /** v2: Enable automatic image compression before upload. */
220
+ imageCompression?: boolean | undefined;
221
+ /** v2: Generate thumbnails for images/videos before upload. */
222
+ thumbnailGenerator?: boolean | undefined;
223
+ /** v2: Verify file integrity with SHA-256 checksums. */
224
+ checksumVerification?: boolean | undefined;
225
+ /** v2: Offload the file pipeline (hash/heic/exif/thumbnail/compress) to a Web Worker. Unset/true = auto; false = main thread. */
226
+ webWorker?: boolean | undefined;
227
+ /** v2: Convert HEIC/HEIF images to JPEG before upload. */
228
+ heicConversion?: boolean | undefined;
229
+ /** v2: Strip EXIF metadata from images for privacy. */
230
+ stripExifData?: boolean | undefined;
231
+ /** v2: Enable content-based deduplication (prevents same file added twice). */
232
+ contentDeduplication?: boolean | undefined;
233
+ /** v2: Upload files immediately after selection (no upload button needed). Default false. */
234
+ autoUpload?: boolean | undefined;
235
+ /** v2: Maximum concurrent uploads. Default 3. */
236
+ maxConcurrentUploads?: number | undefined;
237
+ /** v2: Enable crash recovery — saves upload state to IndexedDB for resume after page refresh */
238
+ crashRecovery?: boolean | undefined;
239
+ /** v3: React to browser connectivity — going offline mid-upload pauses the
240
+ * run (so multipart sessions persist instead of burning retries against a
241
+ * dead network) and coming back online resumes it, only when the pause was
242
+ * offline-initiated. Default true; `false` restores fail-and-retry. */
243
+ networkAware?: boolean | undefined;
244
+ /** File type filter — MIME patterns, extensions, or preset names (e.g. "images", "documents"). */
245
+ allowedFileTypes?: string | string[] | undefined;
246
+ allowPreview?: boolean | undefined;
247
+ /** v2: Show/hide the upup branding footer. Default true. */
248
+ showBranding?: boolean | undefined;
249
+ /** v3: Quiet completion. When true, a successful run shows ONLY a brief
250
+ * checkmark over the panel — no Done button, summary, or further CTAs — on
251
+ * the assumption the host app takes over via the completion callbacks/events.
252
+ * Default false (the normal Done/continue-after-upload flow). */
253
+ quietCompletion?: boolean | undefined;
254
+ /** v2: Default animation layer. `false` disables all decorative motion
255
+ * (spinner/progress/focus stay). Reduced further automatically under
256
+ * `prefers-reduced-motion`. Default true. */
257
+ animations?: boolean | undefined;
258
+ /** v2: Disable drag-and-drop (keep browse/click functional). Default false. */
259
+ disableDragDrop?: boolean | undefined;
260
+ /** v2: Additional CSS class name applied to the root container */
261
+ className?: string | undefined;
262
+ isProcessing?: boolean | undefined;
263
+ mini?: boolean | undefined;
264
+ maxFileSize?: MaxFileSizeObject | undefined;
265
+ /** v2: Minimum file size. Files smaller than this will be rejected. */
266
+ minFileSize?: MaxFileSizeObject | undefined;
267
+ /** v2: Maximum total size of all files combined. */
268
+ maxTotalFileSize?: MaxFileSizeObject | undefined;
269
+ /** Optional image editor. Pass `true` for defaults or an `ImageEditorOptions` object. */
270
+ imageEditor?: boolean | ImageEditorOptions | undefined;
271
+ metadata?: Record<string, unknown> | undefined;
272
+ maxRetries?: number | undefined;
273
+ resumable?: ResumableUploadOptions | undefined;
274
+ /** i18n configuration. Uses ICU locale bundles from `@useupup/core`. */
275
+ i18n?: {
276
+ /**
277
+ * ICU-enabled locale bundle from `@useupup/core/i18n` (e.g. `import { enUS } from '@useupup/core'`).
278
+ * When provided, enables ICU pluralization, namespaced key overrides, and runtime locale switching.
279
+ * Takes precedence over `locale`.
280
+ */
281
+ bundle?: LocaleBundle;
282
+ /**
283
+ * Locale bundle (e.g. `frFR`) or a BCP-47 locale code string
284
+ * (e.g. 'ar-SA') for lang/dir only.
285
+ */
286
+ locale?: LocaleBundle | string;
287
+ /**
288
+ * Optional fallback locale bundle/code used when the active bundle is
289
+ * missing a message key. String codes are for playground/codegen
290
+ * convenience; pass bundles for translated fallback content.
291
+ */
292
+ fallbackLocale?: LocaleBundle | string;
293
+ /** Per-key overrides merged on top of the locale */
294
+ overrides?: PartialMessages;
295
+ } | undefined;
296
+ onFilesSelected?: ((files: UploadFile[]) => void) | undefined;
297
+ onDoneClicked?: (() => void) | undefined;
298
+ onPrepareFiles?: ((files: UploadFile[]) => Promise<UploadFile[]>) | undefined;
299
+ onFileClick?: ((file: UploadFile) => void) | undefined;
300
+ onIntegrationClick?: ((integrationType: string) => void) | undefined;
301
+ onFileUploadStart?: ((file: UploadFile) => void) | undefined;
302
+ onFileUploadComplete?: ((file: UploadFile, key: string) => void) | undefined;
303
+ onFilesUploadComplete?: ((files: UploadFile[]) => void) | undefined;
304
+ onFileUploadProgress?: ((file: UploadFile, progress: {
305
+ loaded: number;
306
+ total: number;
307
+ percentage: number;
308
+ }) => void) | undefined;
309
+ onFilesUploadProgress?: ((completedFiles: number, totalFiles: number) => void) | undefined;
310
+ /** v2: Called once when the batch upload starts */
311
+ onUploadStart?: (() => void) | undefined;
312
+ /** v2: Called when all uploads complete or fail */
313
+ onUploadComplete?: ((files: UploadFile[]) => void) | undefined;
314
+ /** v2: Called whenever upload status changes (idle → uploading → complete/failed) */
315
+ onStatusChange?: ((status: string) => void) | undefined;
316
+ /** v2: Called when a file is removed. */
317
+ onFileRemoved?: ((file: UploadFile) => void) | undefined;
318
+ onFilesDragOver?: ((files: File[]) => void) | undefined;
319
+ onFilesDragLeave?: ((files: File[]) => void) | undefined;
320
+ onFilesDrop?: ((files: File[]) => void) | undefined;
321
+ onFileTypeMismatch?: ((file: File, acceptedTypes: string) => void) | undefined;
322
+ /** v2: Called when a file is rejected for any reason (type, size, limit). */
323
+ onRestrictionFailed?: ((file: File, reason: 'TYPE_MISMATCH' | 'FILE_TOO_LARGE' | 'FILE_TOO_SMALL' | 'LIMIT_EXCEEDED') => void) | undefined;
324
+ /** v2: Enable clipboard paste uploads (Ctrl+V / Cmd+V). Default false. */
325
+ enablePaste?: boolean | undefined;
326
+ /** v2: Async filter called before each file is added. Return false to reject, a File to replace, or true/undefined to accept. */
327
+ onBeforeFileAdded?: ((file: File) => boolean | File | undefined | Promise<boolean | File | undefined>) | undefined;
328
+ onError?: ((errorMessage: string) => void) | undefined;
329
+ onWarn?: ((warningMessage: string) => void) | undefined;
330
+ /** v2: After each file upload, open an SSE connection to this endpoint.
331
+ * The storage key is appended as ?key=... so the server can identify the file.
332
+ * Use this to wait for server-side processing (virus scan, transcoding, etc.). */
333
+ processingEndpoint?: string | undefined;
334
+ /** v2: Called when the server sends a processing-complete SSE event for a file. */
335
+ onFileProcessed?: ((file: UploadFile, data: Record<string, unknown>) => void) | undefined;
336
+ /** v2: Max milliseconds to wait for the server SSE event before closing. Default 60000. */
337
+ processingTimeout?: number | undefined;
338
+ };
339
+
340
+ export { type FileUploadResult as F, NON_S3_STORAGE_PROVIDERS as N, type RestrictionFailedReason as R, StorageProvider as S, type UploadSource as U, type UploadProvider as a, type UploaderBaseProps as b, UpupErrorCode as c, UpupError as d, UpupAuthError as e, UpupNetworkError as f, UpupValidationError as g, UpupQuotaError as h, UpupStorageError as i, UpupConfigError as j, type UploadErrorFromResponseArgs as k, parseErrorBody as p, uploadErrorFromResponse as u };
@@ -0,0 +1,340 @@
1
+ import { a as UploadFile, F as FileSource } from './contracts-pipeline-cf177270.cjs';
2
+ import { I as ImageEditorOptions } from './core-bea2ceca.cjs';
3
+ import { L as LocaleBundle, P as PartialMessages } from './ui-translations-c5d00392.cjs';
4
+ import { M as MaxFileSizeObject, R as ResumableUploadOptions } from './contracts-strategies-378a16b7.cjs';
5
+ import { f as UpupThemeConfig } from './vars-d3421f6c.cjs';
6
+
7
+ declare enum UpupErrorCode {
8
+ AUTH_EXPIRED = "AUTH_EXPIRED",
9
+ AUTH_DENIED = "AUTH_DENIED",
10
+ AUTH_PROVIDER_ERROR = "AUTH_PROVIDER_ERROR",
11
+ FILE_TOO_LARGE = "FILE_TOO_LARGE",
12
+ FILE_TOO_SMALL = "FILE_TOO_SMALL",
13
+ TYPE_MISMATCH = "TYPE_MISMATCH",
14
+ LIMIT_EXCEEDED = "LIMIT_EXCEEDED",
15
+ TOTAL_SIZE_EXCEEDED = "TOTAL_SIZE_EXCEEDED",
16
+ DUPLICATE = "DUPLICATE",
17
+ MIN_FILES_NOT_MET = "MIN_FILES_NOT_MET",
18
+ UPLOAD_FAILED = "UPLOAD_FAILED",
19
+ UPLOAD_ABORTED = "UPLOAD_ABORTED",
20
+ PRESIGN_FAILED = "PRESIGN_FAILED",
21
+ CORS_ERROR = "CORS_ERROR",
22
+ PIPELINE_STEP_FAILED = "PIPELINE_STEP_FAILED",
23
+ HEIC_CONVERSION_FAILED = "HEIC_CONVERSION_FAILED",
24
+ NETWORK_ERROR = "NETWORK_ERROR",
25
+ TIMEOUT = "TIMEOUT",
26
+ STORAGE_ERROR = "STORAGE_ERROR",
27
+ QUOTA_EXCEEDED = "QUOTA_EXCEEDED",
28
+ NO_UPLOAD_TARGET = "NO_UPLOAD_TARGET",
29
+ BAD_REQUEST = "BAD_REQUEST",
30
+ AUTH_REQUIRED = "AUTH_REQUIRED",
31
+ /** The addressed resource is gone server-side — e.g. resuming a multipart
32
+ * upload the storage provider has already completed, aborted, or reaped.
33
+ * Always paired with a 4xx so the client starts fresh instead of retrying
34
+ * something that will never come back. */
35
+ NOT_FOUND = "NOT_FOUND"
36
+ }
37
+ type RestrictionFailedReason = UpupErrorCode.TYPE_MISMATCH | UpupErrorCode.FILE_TOO_LARGE | UpupErrorCode.FILE_TOO_SMALL | UpupErrorCode.LIMIT_EXCEEDED | UpupErrorCode.TOTAL_SIZE_EXCEEDED | UpupErrorCode.DUPLICATE | 'BEFORE_FILE_ADDED_REJECTED';
38
+ declare class UpupError extends Error {
39
+ code: string;
40
+ retryable: boolean;
41
+ /** Optional HTTP status the error originated from (set by uploadErrorFromResponse). */
42
+ status?: number;
43
+ constructor(message: string, code: string, retryable?: boolean);
44
+ }
45
+ declare class UpupAuthError extends UpupError {
46
+ provider: string;
47
+ constructor(message: string, provider: string);
48
+ }
49
+ declare class UpupNetworkError extends UpupError {
50
+ constructor(message: string, status?: number);
51
+ }
52
+ declare class UpupValidationError extends UpupError {
53
+ reason: RestrictionFailedReason;
54
+ file: File;
55
+ constructor(message: string, reason: RestrictionFailedReason, file: File);
56
+ }
57
+ declare class UpupQuotaError extends UpupError {
58
+ limit: number;
59
+ used: number;
60
+ constructor(message: string, limit: number, used: number);
61
+ }
62
+ declare class UpupStorageError extends UpupError {
63
+ provider: string;
64
+ operation: 'presign' | 'upload' | 'multipart-init' | 'multipart-complete' | 'multipart-sign-part' | 'multipart-abort' | 'multipart-resume';
65
+ constructor(message: string, provider: string, operation: UpupStorageError['operation']);
66
+ }
67
+ declare class UpupConfigError extends UpupError {
68
+ constructor(message: string, code?: string);
69
+ }
70
+ /**
71
+ * Best-effort parse of an HTTP error response body into a {code, message}
72
+ * pair. Tries, in order: JSON `{code, error|message}`, S3-style XML
73
+ * `<Error><Code>/<Message></Error>`, then falls back to a truncated text
74
+ * snippet with no code.
75
+ */
76
+ declare function parseErrorBody(body: string | undefined): {
77
+ code?: string;
78
+ message: string;
79
+ };
80
+ interface UploadErrorFromResponseArgs {
81
+ status: number;
82
+ statusText: string;
83
+ body?: string;
84
+ kind: 'storage' | 'auth' | 'network';
85
+ /** Required when kind === 'storage'; ignored otherwise. */
86
+ operation?: UpupStorageError['operation'];
87
+ /** Provider label for storage/auth errors (e.g. 'S3', 'google-drive'). Defaults to 'server'. */
88
+ provider?: string;
89
+ }
90
+ /**
91
+ * Construct a typed, code-carrying error from a failed fetch/XHR response —
92
+ * the client-side half of the server's `{error, code}` convention (and S3's
93
+ * own `<Error><Code>` XML). Picks the error class by `kind`; the resulting
94
+ * `.code` is the server/S3-supplied machine code when present, else falls
95
+ * back to the HTTP status text.
96
+ */
97
+ declare function uploadErrorFromResponse(args: UploadErrorFromResponseArgs): UpupError;
98
+
99
+ type FileUploadResult = {
100
+ file: UploadFile;
101
+ url: string;
102
+ status: 'success' | 'failed' | 'skipped';
103
+ error?: UpupError;
104
+ };
105
+
106
+ declare enum StorageProvider {
107
+ AWS = "aws",
108
+ Azure = "azure",
109
+ BackBlaze = "backblaze",
110
+ DigitalOcean = "digitalocean",
111
+ CloudflareR2 = "r2",
112
+ Wasabi = "wasabi",
113
+ MinIO = "minio",
114
+ GCS = "gcs",
115
+ Supabase = "supabase",
116
+ Hetzner = "hetzner",
117
+ Linode = "linode",
118
+ Vultr = "vultr",
119
+ UpCloud = "upcloud",
120
+ Scaleway = "scaleway",
121
+ OVHcloud = "ovhcloud",
122
+ Alibaba = "alibaba",
123
+ Oracle = "oracle",
124
+ Contabo = "contabo",
125
+ Storj = "storj",
126
+ IDrive = "idrive",
127
+ Ceph = "ceph"
128
+ }
129
+ /**
130
+ * Providers with no S3-compatible API surface (F-657). @useupup/server's storage
131
+ * path (buildS3ClientConfig) always builds an @aws-sdk/client-s3 client — it
132
+ * cannot serve a provider in this set no matter what storage.type is set to.
133
+ * Kept next to the enum so any future non-S3 addition is an explicit,
134
+ * greppable decision; createUpupHandler's construct-time guard is the sole
135
+ * consumer.
136
+ */
137
+ declare const NON_S3_STORAGE_PROVIDERS: ReadonlySet<StorageProvider>;
138
+
139
+ /**
140
+ * String-literal accept-set for the public props: everywhere a prop takes a
141
+ * source id, plain strings ('local', 'googleDrive', …) must typecheck without
142
+ * importing the FileSource enum. Deliberately kept ALONGSIDE FileSource — not
143
+ * an accidental alias (F-726 ruling); the accept-set is pinned by
144
+ * src/__tests__/types/upload-source.test.ts.
145
+ */
146
+ type UploadSource = `${FileSource}`;
147
+ type UploadProvider = StorageProvider | (string & {});
148
+
149
+ /**
150
+ * Shared shape of the UI-package `UploaderProps` across react/vue/svelte/
151
+ * angular. Each framework extends this with its own `icons` (component type
152
+ * differs per framework) and `style` (React.CSSProperties vs
153
+ * Record<string, string>) — the two genuinely framework-specific members.
154
+ *
155
+ * Canonical home for the props all four frameworks hand-authored in
156
+ * parallel; keeping one definition here means a field added to one
157
+ * framework's copy can no longer silently diverge from the others.
158
+ */
159
+ type UploaderBaseProps = {
160
+ /**
161
+ * Storage provider. Optional for local-only selection and generic
162
+ * uploadEndpoint/serverUrl flows. When provided, accepts core provider
163
+ * enum values plus custom provider ids forwarded to user/server code.
164
+ */
165
+ provider?: UploadProvider | undefined;
166
+ /**
167
+ * Upload mode. `'client'` (default) = browser talks to storage
168
+ * directly; server only signs URLs. `'server'` = browser talks only
169
+ * to `serverUrl`, which proxies drive APIs + storage writes. Pick
170
+ * `'server'` when you can't expose OAuth client secrets to the
171
+ * browser or when you need server-side compliance/scanning.
172
+ */
173
+ mode?: 'client' | 'server' | undefined;
174
+ /** Source list. e.g. sources={['local','camera','googleDrive']} */
175
+ sources?: UploadSource[] | undefined;
176
+ /** Endpoint returning presigned upload URLs. */
177
+ uploadEndpoint?: string | undefined;
178
+ /** Server URL for @useupup/server handler. */
179
+ serverUrl?: string | undefined;
180
+ /** Maximum number of files that can be added. Default 10. */
181
+ maxFiles?: number | undefined;
182
+ /** v2: Theme configuration. mode replaces `dark`, tokens/slots replace flat styling overrides. */
183
+ theme?: UpupThemeConfig | undefined;
184
+ /** Folder upload configuration. */
185
+ folderUpload?: {
186
+ /** Traverse directories when a user drops a folder onto the uploader. */
187
+ allowDrop?: boolean;
188
+ /** Show a "Select folder" action in the local device source. */
189
+ showSelectFolderButton?: boolean;
190
+ } | undefined;
191
+ /** CORS configuration. `dangerouslyAutoConfigure` can mutate storage CORS and should only be used for quick setup. */
192
+ cors?: {
193
+ dangerouslyAutoConfigure?: boolean;
194
+ allowedOrigins: string[];
195
+ allowedMethods?: string[];
196
+ allowedHeaders?: string[];
197
+ maxAgeSeconds?: number;
198
+ } | undefined;
199
+ /** Cloud drive configurations. */
200
+ cloudDrives?: {
201
+ googleDrive?: {
202
+ clientId: string;
203
+ apiKey: string;
204
+ appId: string;
205
+ };
206
+ oneDrive?: {
207
+ clientId: string;
208
+ redirectUri?: string;
209
+ };
210
+ dropbox?: {
211
+ clientId: string;
212
+ redirectUri?: string;
213
+ };
214
+ box?: {
215
+ clientId: string;
216
+ redirectUri?: string;
217
+ };
218
+ } | undefined;
219
+ /** v2: Enable automatic image compression before upload. */
220
+ imageCompression?: boolean | undefined;
221
+ /** v2: Generate thumbnails for images/videos before upload. */
222
+ thumbnailGenerator?: boolean | undefined;
223
+ /** v2: Verify file integrity with SHA-256 checksums. */
224
+ checksumVerification?: boolean | undefined;
225
+ /** v2: Offload the file pipeline (hash/heic/exif/thumbnail/compress) to a Web Worker. Unset/true = auto; false = main thread. */
226
+ webWorker?: boolean | undefined;
227
+ /** v2: Convert HEIC/HEIF images to JPEG before upload. */
228
+ heicConversion?: boolean | undefined;
229
+ /** v2: Strip EXIF metadata from images for privacy. */
230
+ stripExifData?: boolean | undefined;
231
+ /** v2: Enable content-based deduplication (prevents same file added twice). */
232
+ contentDeduplication?: boolean | undefined;
233
+ /** v2: Upload files immediately after selection (no upload button needed). Default false. */
234
+ autoUpload?: boolean | undefined;
235
+ /** v2: Maximum concurrent uploads. Default 3. */
236
+ maxConcurrentUploads?: number | undefined;
237
+ /** v2: Enable crash recovery — saves upload state to IndexedDB for resume after page refresh */
238
+ crashRecovery?: boolean | undefined;
239
+ /** v3: React to browser connectivity — going offline mid-upload pauses the
240
+ * run (so multipart sessions persist instead of burning retries against a
241
+ * dead network) and coming back online resumes it, only when the pause was
242
+ * offline-initiated. Default true; `false` restores fail-and-retry. */
243
+ networkAware?: boolean | undefined;
244
+ /** File type filter — MIME patterns, extensions, or preset names (e.g. "images", "documents"). */
245
+ allowedFileTypes?: string | string[] | undefined;
246
+ allowPreview?: boolean | undefined;
247
+ /** v2: Show/hide the upup branding footer. Default true. */
248
+ showBranding?: boolean | undefined;
249
+ /** v3: Quiet completion. When true, a successful run shows ONLY a brief
250
+ * checkmark over the panel — no Done button, summary, or further CTAs — on
251
+ * the assumption the host app takes over via the completion callbacks/events.
252
+ * Default false (the normal Done/continue-after-upload flow). */
253
+ quietCompletion?: boolean | undefined;
254
+ /** v2: Default animation layer. `false` disables all decorative motion
255
+ * (spinner/progress/focus stay). Reduced further automatically under
256
+ * `prefers-reduced-motion`. Default true. */
257
+ animations?: boolean | undefined;
258
+ /** v2: Disable drag-and-drop (keep browse/click functional). Default false. */
259
+ disableDragDrop?: boolean | undefined;
260
+ /** v2: Additional CSS class name applied to the root container */
261
+ className?: string | undefined;
262
+ isProcessing?: boolean | undefined;
263
+ mini?: boolean | undefined;
264
+ maxFileSize?: MaxFileSizeObject | undefined;
265
+ /** v2: Minimum file size. Files smaller than this will be rejected. */
266
+ minFileSize?: MaxFileSizeObject | undefined;
267
+ /** v2: Maximum total size of all files combined. */
268
+ maxTotalFileSize?: MaxFileSizeObject | undefined;
269
+ /** Optional image editor. Pass `true` for defaults or an `ImageEditorOptions` object. */
270
+ imageEditor?: boolean | ImageEditorOptions | undefined;
271
+ metadata?: Record<string, unknown> | undefined;
272
+ maxRetries?: number | undefined;
273
+ resumable?: ResumableUploadOptions | undefined;
274
+ /** i18n configuration. Uses ICU locale bundles from `@useupup/core`. */
275
+ i18n?: {
276
+ /**
277
+ * ICU-enabled locale bundle from `@useupup/core/i18n` (e.g. `import { enUS } from '@useupup/core'`).
278
+ * When provided, enables ICU pluralization, namespaced key overrides, and runtime locale switching.
279
+ * Takes precedence over `locale`.
280
+ */
281
+ bundle?: LocaleBundle;
282
+ /**
283
+ * Locale bundle (e.g. `frFR`) or a BCP-47 locale code string
284
+ * (e.g. 'ar-SA') for lang/dir only.
285
+ */
286
+ locale?: LocaleBundle | string;
287
+ /**
288
+ * Optional fallback locale bundle/code used when the active bundle is
289
+ * missing a message key. String codes are for playground/codegen
290
+ * convenience; pass bundles for translated fallback content.
291
+ */
292
+ fallbackLocale?: LocaleBundle | string;
293
+ /** Per-key overrides merged on top of the locale */
294
+ overrides?: PartialMessages;
295
+ } | undefined;
296
+ onFilesSelected?: ((files: UploadFile[]) => void) | undefined;
297
+ onDoneClicked?: (() => void) | undefined;
298
+ onPrepareFiles?: ((files: UploadFile[]) => Promise<UploadFile[]>) | undefined;
299
+ onFileClick?: ((file: UploadFile) => void) | undefined;
300
+ onIntegrationClick?: ((integrationType: string) => void) | undefined;
301
+ onFileUploadStart?: ((file: UploadFile) => void) | undefined;
302
+ onFileUploadComplete?: ((file: UploadFile, key: string) => void) | undefined;
303
+ onFilesUploadComplete?: ((files: UploadFile[]) => void) | undefined;
304
+ onFileUploadProgress?: ((file: UploadFile, progress: {
305
+ loaded: number;
306
+ total: number;
307
+ percentage: number;
308
+ }) => void) | undefined;
309
+ onFilesUploadProgress?: ((completedFiles: number, totalFiles: number) => void) | undefined;
310
+ /** v2: Called once when the batch upload starts */
311
+ onUploadStart?: (() => void) | undefined;
312
+ /** v2: Called when all uploads complete or fail */
313
+ onUploadComplete?: ((files: UploadFile[]) => void) | undefined;
314
+ /** v2: Called whenever upload status changes (idle → uploading → complete/failed) */
315
+ onStatusChange?: ((status: string) => void) | undefined;
316
+ /** v2: Called when a file is removed. */
317
+ onFileRemoved?: ((file: UploadFile) => void) | undefined;
318
+ onFilesDragOver?: ((files: File[]) => void) | undefined;
319
+ onFilesDragLeave?: ((files: File[]) => void) | undefined;
320
+ onFilesDrop?: ((files: File[]) => void) | undefined;
321
+ onFileTypeMismatch?: ((file: File, acceptedTypes: string) => void) | undefined;
322
+ /** v2: Called when a file is rejected for any reason (type, size, limit). */
323
+ onRestrictionFailed?: ((file: File, reason: 'TYPE_MISMATCH' | 'FILE_TOO_LARGE' | 'FILE_TOO_SMALL' | 'LIMIT_EXCEEDED') => void) | undefined;
324
+ /** v2: Enable clipboard paste uploads (Ctrl+V / Cmd+V). Default false. */
325
+ enablePaste?: boolean | undefined;
326
+ /** v2: Async filter called before each file is added. Return false to reject, a File to replace, or true/undefined to accept. */
327
+ onBeforeFileAdded?: ((file: File) => boolean | File | undefined | Promise<boolean | File | undefined>) | undefined;
328
+ onError?: ((errorMessage: string) => void) | undefined;
329
+ onWarn?: ((warningMessage: string) => void) | undefined;
330
+ /** v2: After each file upload, open an SSE connection to this endpoint.
331
+ * The storage key is appended as ?key=... so the server can identify the file.
332
+ * Use this to wait for server-side processing (virus scan, transcoding, etc.). */
333
+ processingEndpoint?: string | undefined;
334
+ /** v2: Called when the server sends a processing-complete SSE event for a file. */
335
+ onFileProcessed?: ((file: UploadFile, data: Record<string, unknown>) => void) | undefined;
336
+ /** v2: Max milliseconds to wait for the server SSE event before closing. Default 60000. */
337
+ processingTimeout?: number | undefined;
338
+ };
339
+
340
+ export { type FileUploadResult as F, NON_S3_STORAGE_PROVIDERS as N, type RestrictionFailedReason as R, StorageProvider as S, type UploadSource as U, type UploadProvider as a, type UploaderBaseProps as b, UpupErrorCode as c, UpupError as d, UpupAuthError as e, UpupNetworkError as f, UpupValidationError as g, UpupQuotaError as h, UpupStorageError as i, UpupConfigError as j, type UploadErrorFromResponseArgs as k, parseErrorBody as p, uploadErrorFromResponse as u };