@depup/uploadthing 7.7.4-depup.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/README.md +33 -0
- package/changes.json +18 -0
- package/client/index.cjs +331 -0
- package/client/index.d.cts +36 -0
- package/client/index.d.cts.map +1 -0
- package/client/index.d.ts +36 -0
- package/client/index.d.ts.map +1 -0
- package/client/index.js +286 -0
- package/client/index.js.map +1 -0
- package/client-future/index.cjs +426 -0
- package/client-future/index.d.cts +373 -0
- package/client-future/index.d.cts.map +1 -0
- package/client-future/index.d.ts +373 -0
- package/client-future/index.d.ts.map +1 -0
- package/client-future/index.js +383 -0
- package/client-future/index.js.map +1 -0
- package/dist/chunk-CUT6urMc.cjs +30 -0
- package/dist/deprecations-DPGpmqha.cjs +13 -0
- package/dist/deprecations-pLmw6Ytd.js +8 -0
- package/dist/deprecations-pLmw6Ytd.js.map +1 -0
- package/dist/package-BQ_k22T9.cjs +11 -0
- package/dist/package-DpScpvTA.js +6 -0
- package/dist/package-DpScpvTA.js.map +1 -0
- package/dist/shared-schemas-BmG5ARoX.js +82 -0
- package/dist/shared-schemas-BmG5ARoX.js.map +1 -0
- package/dist/shared-schemas-CG9VaBtT.cjs +129 -0
- package/dist/to-web-request-BQtxSXgE.cjs +98 -0
- package/dist/to-web-request-DhP0wXG-.js +87 -0
- package/dist/to-web-request-DhP0wXG-.js.map +1 -0
- package/dist/types-Bs3w2d_3.d.ts +627 -0
- package/dist/types-Bs3w2d_3.d.ts.map +1 -0
- package/dist/types-DiVC1t2V.d.cts +625 -0
- package/dist/types-DiVC1t2V.d.cts.map +1 -0
- package/dist/upload-builder-BUa7tovh.d.cts +32 -0
- package/dist/upload-builder-BUa7tovh.d.cts.map +1 -0
- package/dist/upload-builder-BcFawEj0.d.ts +32 -0
- package/dist/upload-builder-BcFawEj0.d.ts.map +1 -0
- package/dist/upload-builder-BlFOAnsv.js +699 -0
- package/dist/upload-builder-BlFOAnsv.js.map +1 -0
- package/dist/upload-builder-D6Ken9H0.cjs +794 -0
- package/dist/ut-reporter-BHoyNnzW.cjs +120 -0
- package/dist/ut-reporter-Dlppchbx.js +103 -0
- package/dist/ut-reporter-Dlppchbx.js.map +1 -0
- package/effect-platform/index.cjs +22 -0
- package/effect-platform/index.d.cts +54 -0
- package/effect-platform/index.d.cts.map +1 -0
- package/effect-platform/index.d.ts +54 -0
- package/effect-platform/index.d.ts.map +1 -0
- package/effect-platform/index.js +19 -0
- package/effect-platform/index.js.map +1 -0
- package/express/index.cjs +30 -0
- package/express/index.d.cts +28 -0
- package/express/index.d.cts.map +1 -0
- package/express/index.d.ts +28 -0
- package/express/index.d.ts.map +1 -0
- package/express/index.js +27 -0
- package/express/index.js.map +1 -0
- package/fastify/index.cjs +27 -0
- package/fastify/index.d.cts +28 -0
- package/fastify/index.d.cts.map +1 -0
- package/fastify/index.d.ts +28 -0
- package/fastify/index.d.ts.map +1 -0
- package/fastify/index.js +24 -0
- package/fastify/index.js.map +1 -0
- package/h3/index.cjs +20 -0
- package/h3/index.d.cts +28 -0
- package/h3/index.d.cts.map +1 -0
- package/h3/index.d.ts +28 -0
- package/h3/index.d.ts.map +1 -0
- package/h3/index.js +17 -0
- package/h3/index.js.map +1 -0
- package/next/index.cjs +22 -0
- package/next/index.d.cts +30 -0
- package/next/index.d.cts.map +1 -0
- package/next/index.d.ts +30 -0
- package/next/index.d.ts.map +1 -0
- package/next/index.js +19 -0
- package/next/index.js.map +1 -0
- package/next-legacy/index.cjs +28 -0
- package/next-legacy/index.d.cts +28 -0
- package/next-legacy/index.d.cts.map +1 -0
- package/next-legacy/index.d.ts +28 -0
- package/next-legacy/index.d.ts.map +1 -0
- package/next-legacy/index.js +25 -0
- package/next-legacy/index.js.map +1 -0
- package/package.json +210 -0
- package/remix/index.cjs +22 -0
- package/remix/index.d.cts +30 -0
- package/remix/index.d.cts.map +1 -0
- package/remix/index.d.ts +30 -0
- package/remix/index.d.ts.map +1 -0
- package/remix/index.js +19 -0
- package/remix/index.js.map +1 -0
- package/server/index.cjs +414 -0
- package/server/index.d.cts +211 -0
- package/server/index.d.cts.map +1 -0
- package/server/index.d.ts +213 -0
- package/server/index.d.ts.map +1 -0
- package/server/index.js +405 -0
- package/server/index.js.map +1 -0
- package/tw/index.cjs +70 -0
- package/tw/index.d.cts +29 -0
- package/tw/index.d.cts.map +1 -0
- package/tw/index.d.ts +29 -0
- package/tw/index.d.ts.map +1 -0
- package/tw/index.js +74 -0
- package/tw/index.js.map +1 -0
- package/tw/v4.css +11 -0
- package/types/index.cjs +3 -0
- package/types/index.d.cts +2 -0
- package/types/index.d.ts +2 -0
- package/types/index.js +3 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import { version } from "../dist/package-DpScpvTA.js";
|
|
2
|
+
import { createDeferred, createUTReporter, generateTraceHeaders } from "../dist/ut-reporter-Dlppchbx.js";
|
|
3
|
+
import * as Arr from "effect/Array";
|
|
4
|
+
import * as Micro from "effect/Micro";
|
|
5
|
+
import { FetchContext, UploadAbortedError, UploadAbortedError as UploadAbortedError$1, UploadPausedError, UploadPausedError as UploadPausedError$1, createIdentityProxy, fetchEff, generateClientDropzoneAccept, generateMimeTypes, generatePermittedFileTypes, resolveMaybeUrlArg } from "@uploadthing/shared";
|
|
6
|
+
import * as Predicate from "effect/Predicate";
|
|
7
|
+
|
|
8
|
+
//#region src/_internal/client-future.ts
|
|
9
|
+
/**
|
|
10
|
+
* Error indicating the XHR request failed
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
var XHRError = class extends Micro.TaggedError("XHRError") {};
|
|
14
|
+
/**
|
|
15
|
+
* Error indicating the upload was rejected during upload to the storage provider
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
var UTStorageError = class extends Micro.TaggedError("UTStorageError") {};
|
|
19
|
+
/**
|
|
20
|
+
* Error indicating the request to your UploadThing server failed
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
var UTServerError = class extends Micro.TaggedError("UTServerError") {};
|
|
24
|
+
/**
|
|
25
|
+
* Predicate function to check if a file is pending
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
function isPendingFile(file) {
|
|
29
|
+
return file.status === "pending";
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Predicate function to check if a file is uploading
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
function isUploadingFile(file) {
|
|
36
|
+
return file.status === "uploading";
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Predicate function to check if a file is failed
|
|
40
|
+
* @public
|
|
41
|
+
*/
|
|
42
|
+
function isFailedFile(file) {
|
|
43
|
+
return file.status === "failed";
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Predicate function to check if a file is uploaded
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
function isUploadedFile(file) {
|
|
50
|
+
return file.status === "uploaded";
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
function makePendingFile(file) {
|
|
56
|
+
return Object.assign(file, {
|
|
57
|
+
status: "pending",
|
|
58
|
+
sent: 0,
|
|
59
|
+
key: null,
|
|
60
|
+
customId: null
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Modifies a pending file to an uploading file in place
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
function transitionToUploading(file, rangeStart) {
|
|
68
|
+
const uploadingFile = file;
|
|
69
|
+
uploadingFile.sent = rangeStart;
|
|
70
|
+
uploadingFile.status = "uploading";
|
|
71
|
+
return uploadingFile;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Modifies an uploading file to an uploaded file in place
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
function transitionToUploaded(file, xhrResult) {
|
|
78
|
+
const uploadedFile = file;
|
|
79
|
+
uploadedFile.status = "uploaded";
|
|
80
|
+
uploadedFile.data = xhrResult.serverData;
|
|
81
|
+
uploadedFile.hash = xhrResult.fileHash;
|
|
82
|
+
uploadedFile.url = xhrResult.ufsUrl;
|
|
83
|
+
return uploadedFile;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Modifies a pending or uploading file to a failed file in place
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
function transitionToFailed(file, reason) {
|
|
90
|
+
const failedFile = file;
|
|
91
|
+
failedFile.status = "failed";
|
|
92
|
+
failedFile.reason = reason;
|
|
93
|
+
return failedFile;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Upload a file to the storage provider
|
|
97
|
+
* Throughout the upload, the file's status and progress will be updated
|
|
98
|
+
* @remarks This function never rejects
|
|
99
|
+
* @internal
|
|
100
|
+
*/
|
|
101
|
+
function uploadFile(url, { file, files, XHRImpl,...options }) {
|
|
102
|
+
return fetchEff(url, {
|
|
103
|
+
method: "HEAD",
|
|
104
|
+
headers: options.traceHeaders
|
|
105
|
+
}).pipe(Micro.map(({ headers }) => Number.parseInt(headers.get("x-ut-range-start") ?? "0")), Micro.map((rangeStart) => transitionToUploading(file, rangeStart)), Micro.tap((uploadingFile) => {
|
|
106
|
+
options.onEvent({
|
|
107
|
+
type: "upload-started",
|
|
108
|
+
file: uploadingFile,
|
|
109
|
+
files
|
|
110
|
+
});
|
|
111
|
+
}), Micro.flatMap((uploadingFile) => Micro.async((resume) => {
|
|
112
|
+
const xhr = new XHRImpl();
|
|
113
|
+
xhr.open("PUT", url, true);
|
|
114
|
+
const rangeStart = uploadingFile.sent;
|
|
115
|
+
xhr.setRequestHeader("Range", `bytes=${rangeStart}-`);
|
|
116
|
+
xhr.setRequestHeader("x-uploadthing-version", version);
|
|
117
|
+
xhr.setRequestHeader("b3", options.traceHeaders.b3);
|
|
118
|
+
xhr.setRequestHeader("traceparent", options.traceHeaders.traceparent);
|
|
119
|
+
xhr.responseType = "json";
|
|
120
|
+
xhr.upload.addEventListener("progress", (ev) => {
|
|
121
|
+
uploadingFile.sent = rangeStart + ev.loaded;
|
|
122
|
+
options.onEvent({
|
|
123
|
+
type: "upload-progress",
|
|
124
|
+
file: uploadingFile,
|
|
125
|
+
files
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
xhr.addEventListener("load", () => {
|
|
129
|
+
if (xhr.status > 299 || Predicate.hasProperty(xhr.response, "error")) resume(new UTStorageError({
|
|
130
|
+
message: String(xhr.response.error),
|
|
131
|
+
response: xhr.response
|
|
132
|
+
}));
|
|
133
|
+
else {
|
|
134
|
+
const uploadedFile = transitionToUploaded(uploadingFile, xhr.response);
|
|
135
|
+
options.onEvent({
|
|
136
|
+
type: "upload-completed",
|
|
137
|
+
file: uploadedFile,
|
|
138
|
+
files
|
|
139
|
+
});
|
|
140
|
+
resume(Micro.succeed(uploadedFile));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
xhr.addEventListener("error", () => {
|
|
144
|
+
resume(new XHRError({
|
|
145
|
+
message: `XHR failed ${xhr.status} ${xhr.statusText}`,
|
|
146
|
+
xhr
|
|
147
|
+
}));
|
|
148
|
+
});
|
|
149
|
+
const formData = new FormData();
|
|
150
|
+
/**
|
|
151
|
+
* iOS/React Native FormData handling requires special attention:
|
|
152
|
+
*
|
|
153
|
+
* Issue: In React Native, iOS crashes with "attempt to insert nil object" when appending File directly
|
|
154
|
+
* to FormData. This happens because iOS tries to create NSDictionary from the file object and expects
|
|
155
|
+
* specific structure {uri, type, name}.
|
|
156
|
+
*
|
|
157
|
+
*
|
|
158
|
+
* Note: Don't try to use Blob or modify File object - iOS specifically needs plain object
|
|
159
|
+
* with these properties to create valid NSDictionary.
|
|
160
|
+
*/
|
|
161
|
+
if ("uri" in file) formData.append("file", {
|
|
162
|
+
uri: file.uri,
|
|
163
|
+
type: file.type,
|
|
164
|
+
name: file.name,
|
|
165
|
+
...rangeStart > 0 && { range: rangeStart }
|
|
166
|
+
});
|
|
167
|
+
else formData.append("file", rangeStart > 0 ? file.slice(rangeStart) : file);
|
|
168
|
+
xhr.send(formData);
|
|
169
|
+
return Micro.sync(() => xhr.abort());
|
|
170
|
+
})), Micro.catchAll((error) => {
|
|
171
|
+
const failedFile = transitionToFailed(file, error);
|
|
172
|
+
options.onEvent({
|
|
173
|
+
type: "upload-failed",
|
|
174
|
+
file: failedFile,
|
|
175
|
+
files
|
|
176
|
+
});
|
|
177
|
+
return Micro.succeed(failedFile);
|
|
178
|
+
}));
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Request presigned URLs from your server for a set of files
|
|
182
|
+
* @internal
|
|
183
|
+
*/
|
|
184
|
+
function requestPresignedUrls(options) {
|
|
185
|
+
const reportEventToUT = createUTReporter({
|
|
186
|
+
endpoint: String(options.endpoint),
|
|
187
|
+
package: options.package,
|
|
188
|
+
url: options.url,
|
|
189
|
+
headers: options.headers,
|
|
190
|
+
traceHeaders: options.traceHeaders
|
|
191
|
+
});
|
|
192
|
+
return reportEventToUT("upload", {
|
|
193
|
+
input: options.input,
|
|
194
|
+
files: options.files.map((f) => ({
|
|
195
|
+
name: f.name,
|
|
196
|
+
size: f.size,
|
|
197
|
+
type: f.type,
|
|
198
|
+
lastModified: f.lastModified
|
|
199
|
+
}))
|
|
200
|
+
}).pipe(Micro.mapError((error) => new UTServerError({
|
|
201
|
+
message: error.message,
|
|
202
|
+
cause: error,
|
|
203
|
+
data: error.data
|
|
204
|
+
})));
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Upload a set of files to the storage provider
|
|
208
|
+
* @internal
|
|
209
|
+
*/
|
|
210
|
+
function uploadFiles(endpoint, options) {
|
|
211
|
+
const pendingFiles = options.files.map(makePendingFile);
|
|
212
|
+
const traceHeaders = generateTraceHeaders();
|
|
213
|
+
return requestPresignedUrls({
|
|
214
|
+
endpoint,
|
|
215
|
+
files: options.files,
|
|
216
|
+
url: options.url,
|
|
217
|
+
input: options.input,
|
|
218
|
+
headers: options.headers,
|
|
219
|
+
package: options.package,
|
|
220
|
+
traceHeaders
|
|
221
|
+
}).pipe(Micro.map(Arr.zip(pendingFiles)), Micro.tap((pairs) => {
|
|
222
|
+
for (const [presigned, file] of pairs) {
|
|
223
|
+
file.key = presigned.key;
|
|
224
|
+
file.customId = presigned.customId;
|
|
225
|
+
}
|
|
226
|
+
options.onEvent({
|
|
227
|
+
type: "presigned-received",
|
|
228
|
+
files: pendingFiles
|
|
229
|
+
});
|
|
230
|
+
}), Micro.flatMap((pairs) => Micro.forEach(pairs, ([presigned, file]) => uploadFile(presigned.url, {
|
|
231
|
+
file,
|
|
232
|
+
files: pendingFiles,
|
|
233
|
+
input: options.input,
|
|
234
|
+
onEvent: options.onEvent,
|
|
235
|
+
XHRImpl: globalThis.XMLHttpRequest,
|
|
236
|
+
traceHeaders
|
|
237
|
+
}), { concurrency: 6 })));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
//#endregion
|
|
241
|
+
//#region src/client-future.ts
|
|
242
|
+
const version$1 = version;
|
|
243
|
+
/**
|
|
244
|
+
* Generate a typed uploader for a given FileRouter
|
|
245
|
+
* @public
|
|
246
|
+
* @remarks This API is not covered by semver
|
|
247
|
+
*/
|
|
248
|
+
const future_genUploader = (initOpts) => {
|
|
249
|
+
const routeRegistry = createIdentityProxy();
|
|
250
|
+
const controllableUpload = async (slug, options) => {
|
|
251
|
+
const endpoint = typeof slug === "function" ? slug(routeRegistry) : slug;
|
|
252
|
+
const fetchFn = initOpts?.fetch ?? window.fetch;
|
|
253
|
+
const traceHeaders = generateTraceHeaders();
|
|
254
|
+
const pExit = await requestPresignedUrls({
|
|
255
|
+
endpoint: String(endpoint),
|
|
256
|
+
files: options.files,
|
|
257
|
+
url: resolveMaybeUrlArg(initOpts?.url),
|
|
258
|
+
input: options.input,
|
|
259
|
+
headers: options.headers,
|
|
260
|
+
traceHeaders
|
|
261
|
+
}).pipe(Micro.provideService(FetchContext, fetchFn), (effect) => Micro.runPromiseExit(effect, options.signal && { signal: options.signal }));
|
|
262
|
+
if (pExit._tag === "Failure") throw Micro.causeSquash(pExit.cause);
|
|
263
|
+
const presigneds = pExit.value;
|
|
264
|
+
const pendingFiles = options.files.map(makePendingFile);
|
|
265
|
+
options.onEvent({
|
|
266
|
+
type: "presigned-received",
|
|
267
|
+
files: pendingFiles
|
|
268
|
+
});
|
|
269
|
+
const uploads = /* @__PURE__ */ new Map();
|
|
270
|
+
const uploadEffect = (file, presigned) => uploadFile(presigned.url, {
|
|
271
|
+
file,
|
|
272
|
+
files: pendingFiles,
|
|
273
|
+
input: options.input,
|
|
274
|
+
onEvent: options.onEvent,
|
|
275
|
+
traceHeaders,
|
|
276
|
+
XHRImpl: globalThis.XMLHttpRequest
|
|
277
|
+
}).pipe(Micro.provideService(FetchContext, fetchFn));
|
|
278
|
+
for (const [presigned, file] of Arr.zip(presigneds, pendingFiles)) {
|
|
279
|
+
file.key = presigned.key;
|
|
280
|
+
file.customId = presigned.customId;
|
|
281
|
+
const deferred = createDeferred();
|
|
282
|
+
uploads.set(file, {
|
|
283
|
+
presigned,
|
|
284
|
+
deferred
|
|
285
|
+
});
|
|
286
|
+
Micro.runPromiseExit(uploadEffect(file, presigned), { signal: deferred.ac.signal }).then((result) => {
|
|
287
|
+
if (result._tag === "Success") return deferred.resolve(result.value);
|
|
288
|
+
else if (result.cause._tag === "Interrupt") throw new UploadPausedError$1();
|
|
289
|
+
throw Micro.causeSquash(result.cause);
|
|
290
|
+
}).catch((err) => {
|
|
291
|
+
if (err instanceof UploadPausedError$1) return;
|
|
292
|
+
deferred.reject(err);
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Pause an ongoing upload
|
|
297
|
+
* @param file The file upload you want to pause. Can be omitted to pause all files
|
|
298
|
+
*/
|
|
299
|
+
const pauseUpload = (file) => {
|
|
300
|
+
const files = Arr.ensure(file ?? options.files);
|
|
301
|
+
for (const file$1 of files) {
|
|
302
|
+
const upload = uploads.get(file$1);
|
|
303
|
+
if (!upload) return;
|
|
304
|
+
if (upload.deferred.ac.signal.aborted) return;
|
|
305
|
+
upload.deferred.ac.abort();
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* Abort an upload
|
|
310
|
+
* @param file The file upload you want to abort. Can be omitted to abort all files
|
|
311
|
+
*/
|
|
312
|
+
const abortUpload = (file) => {
|
|
313
|
+
const files = Arr.ensure(file ?? options.files);
|
|
314
|
+
for (const file$1 of files) {
|
|
315
|
+
const upload = uploads.get(file$1);
|
|
316
|
+
if (!upload) throw "No upload found";
|
|
317
|
+
if (upload.deferred.ac.signal.aborted === false) {
|
|
318
|
+
upload.deferred.ac.abort();
|
|
319
|
+
const failedFile = transitionToFailed(file$1, new UploadAbortedError$1());
|
|
320
|
+
upload.deferred.resolve(failedFile);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
options.onEvent({
|
|
324
|
+
type: "upload-aborted",
|
|
325
|
+
files
|
|
326
|
+
});
|
|
327
|
+
};
|
|
328
|
+
options.signal?.addEventListener("abort", () => {
|
|
329
|
+
abortUpload();
|
|
330
|
+
});
|
|
331
|
+
/**
|
|
332
|
+
* Resume a paused upload
|
|
333
|
+
* @param file The file upload you want to resume. Can be omitted to resume all files
|
|
334
|
+
*/
|
|
335
|
+
const resumeUpload = (file) => {
|
|
336
|
+
const files = Arr.ensure(file ?? options.files);
|
|
337
|
+
for (const file$1 of files) {
|
|
338
|
+
const upload = uploads.get(file$1);
|
|
339
|
+
if (!upload) throw "No upload found";
|
|
340
|
+
upload.deferred.ac = new AbortController();
|
|
341
|
+
Micro.runPromiseExit(uploadEffect(file$1, upload.presigned), { signal: upload.deferred.ac.signal }).then((result) => {
|
|
342
|
+
if (result._tag === "Success") return upload.deferred.resolve(result.value);
|
|
343
|
+
else if (result.cause._tag === "Interrupt") throw new UploadPausedError$1();
|
|
344
|
+
throw Micro.causeSquash(result.cause);
|
|
345
|
+
}).catch((err) => {
|
|
346
|
+
if (err instanceof UploadPausedError$1) return;
|
|
347
|
+
upload.deferred.reject(err);
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
/**
|
|
352
|
+
* Wait for an upload to complete
|
|
353
|
+
* @param file The file upload you want to wait for. Can be omitted to wait for all files
|
|
354
|
+
*/
|
|
355
|
+
const done = async (file) => {
|
|
356
|
+
const promises = [];
|
|
357
|
+
const files = Arr.ensure(file ?? options.files);
|
|
358
|
+
for (const file$1 of files) {
|
|
359
|
+
const upload = uploads.get(file$1);
|
|
360
|
+
if (!upload) throw "No upload found";
|
|
361
|
+
promises.push(upload.deferred.promise);
|
|
362
|
+
}
|
|
363
|
+
const results = await Promise.all(promises);
|
|
364
|
+
return file ? results[0] : results;
|
|
365
|
+
};
|
|
366
|
+
return {
|
|
367
|
+
pauseUpload,
|
|
368
|
+
abortUpload,
|
|
369
|
+
resumeUpload,
|
|
370
|
+
done
|
|
371
|
+
};
|
|
372
|
+
};
|
|
373
|
+
const uploadFiles$1 = (slug, opts) => controllableUpload(slug, opts).then((_) => _.done());
|
|
374
|
+
return {
|
|
375
|
+
uploadFiles: uploadFiles$1,
|
|
376
|
+
createUpload: controllableUpload,
|
|
377
|
+
routeRegistry
|
|
378
|
+
};
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
//#endregion
|
|
382
|
+
export { UTServerError, UTStorageError, UploadAbortedError, UploadPausedError, XHRError, future_genUploader, generateClientDropzoneAccept, generateMimeTypes, generatePermittedFileTypes, isFailedFile, isPendingFile, isUploadedFile, isUploadingFile, makePendingFile, requestPresignedUrls, transitionToFailed, uploadFile, uploadFiles, version$1 as version };
|
|
383
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["file: AnyFile<TRoute>","file: File","file: PendingFile","rangeStart: number","file: UploadingFile","xhrResult: UploadPutResult","file: PendingFile | UploadingFile","reason: UploadThingClientError<TRoute[\"$types\"][\"errorShape\"]>","url: string","options: RequestPresignedUrlsOptions<TRouter, TEndpoint>","endpoint: TEndpoint","options: UploadFilesOptions<TRouter[TEndpoint]>","version","initOpts?: GenerateUploaderOptions","slug: EndpointArg<TRouter, TEndpoint>","options: Omit<\n UploadFilesOptions<TRouter[TEndpoint]>,\n keyof GenerateUploaderOptions\n >","fetchFn: FetchEsque","file: PendingFile","presigned: NewPresignedUrl","UploadPausedError","file?: File","file","UploadAbortedError","file?: T","uploadFiles","opts: Omit<\n UploadFilesOptions<TRouter[TEndpoint]>,\n keyof GenerateUploaderOptions\n >"],"sources":["../src/_internal/client-future.ts","../src/client-future.ts"],"sourcesContent":["import * as Arr from \"effect/Array\";\nimport type { LazyArg } from \"effect/Function\";\nimport * as Micro from \"effect/Micro\";\nimport * as Predicate from \"effect/Predicate\";\n\nimport { fetchEff } from \"@uploadthing/shared\";\nimport type {\n FetchContext,\n FetchError,\n MaybePromise,\n UploadAbortedError,\n} from \"@uploadthing/shared\";\n\nimport { version } from \"../../package.json\";\nimport type {\n AnyFileRoute,\n FileRouter as AnyFileRouter,\n NewPresignedUrl,\n} from \"../types\";\nimport type { TraceHeaders } from \"./random-hex\";\nimport { generateTraceHeaders } from \"./random-hex\";\nimport type { UploadPutResult } from \"./types\";\nimport { createUTReporter } from \"./ut-reporter\";\n\n/**\n * Error indicating the XHR request failed\n * @public\n */\nexport class XHRError extends Micro.TaggedError(\"XHRError\")<{\n message: string;\n xhr: unknown;\n}> {}\n\n/**\n * Error indicating the network request failed\n * @public\n */\nexport type NetworkError = XHRError | FetchError;\n\n/**\n * Error indicating the upload was rejected during upload to the storage provider\n * @public\n */\nexport class UTStorageError extends Micro.TaggedError(\"UTStorageError\")<{\n message: string;\n response: unknown;\n}> {}\n\n/**\n * Error indicating the request to your UploadThing server failed\n * @public\n */\nexport class UTServerError<TErrorShape> extends Micro.TaggedError(\n \"UTServerError\",\n)<{\n message: string;\n cause: unknown;\n /**\n * Matches the shape returned by your error formatter\n */\n data: TErrorShape;\n}> {}\n\n/**\n * Error indicating the upload failed\n * @public\n */\nexport type UploadThingClientError<TErrorShape> =\n | UploadAbortedError\n | NetworkError\n | UTStorageError\n | UTServerError<TErrorShape>;\n\n/**\n * A file that has not started uploading yet.\n * Can either be pending for the presigned request to resolve,\n * or pending for the browser to schedule the network request.\n * @public\n */\nexport interface PendingFile extends File {\n status: \"pending\";\n /**\n * How many bytes of the file has been uploaded\n * @example 0\n */\n sent: number;\n /**\n * The key of the file. Null before the presigned request resolves.\n */\n key: string | null;\n /**\n * The customId of the file. Null before the presigned request resolves, then present if your file route sets it\n */\n customId: string | null;\n}\n\n/**\n * A file that is currently uploading.\n * @public\n */\nexport interface UploadingFile extends File {\n status: \"uploading\";\n /**\n * How many bytes of the file has been uploaded\n * @example 2500\n */\n sent: number;\n /**\n * The key of the file.\n */\n key: string;\n /**\n * The customId of the file, if your file route sets it\n */\n customId: string | null;\n}\n\n/**\n * A file that failed to upload.\n * @public\n */\nexport interface FailedFile<TRoute extends AnyFileRoute> extends File {\n status: \"failed\";\n /**\n * How many bytes of the file were uploaded before the upload failed.\n * @example 2500\n */\n sent: number;\n /**\n * The key of the file.\n */\n key: string;\n /**\n * The customId of the file, if your file route sets it\n */\n customId: string | null;\n /**\n * The error that occurred during the upload.\n */\n reason: UploadThingClientError<TRoute[\"$types\"][\"errorShape\"]>;\n}\n\n/**\n * A file that has been uploaded successfully.\n * @public\n */\nexport interface UploadedFile<TRoute extends AnyFileRoute> extends File {\n status: \"uploaded\";\n /**\n * How many bytes of the file has been uploaded.\n * @example 10000\n */\n sent: number;\n /**\n * The key of the file.\n */\n key: string;\n /**\n * The customId of the file, if your file route sets it\n */\n customId: string | null;\n /**\n * The url of the file.\n * @example \"https://APP_ID.ufs.sh/f/KEY\"\n */\n url: string;\n /**\n * The data returned by the serverside `onUploadComplete` callback.\n * @example { uploadedBy: \"user_123\" }\n */\n data: TRoute[\"$types\"][\"output\"];\n /**\n * The hash ( <> checksum ) of the file.\n */\n hash: string;\n}\n\n/**\n * A web file with additional state properties\n * @public\n */\nexport type AnyFile<TFileRoute extends AnyFileRoute> =\n | PendingFile\n | UploadingFile\n | FailedFile<TFileRoute>\n | UploadedFile<TFileRoute>;\n\n/**\n * Predicate function to check if a file is pending\n * @public\n */\nexport function isPendingFile<TRoute extends AnyFileRoute = AnyFileRoute>(\n file: AnyFile<TRoute>,\n): file is PendingFile {\n return file.status === \"pending\";\n}\n\n/**\n * Predicate function to check if a file is uploading\n * @public\n */\nexport function isUploadingFile<TRoute extends AnyFileRoute = AnyFileRoute>(\n file: AnyFile<TRoute>,\n): file is UploadingFile {\n return file.status === \"uploading\";\n}\n\n/**\n * Predicate function to check if a file is failed\n * @public\n */\nexport function isFailedFile<TRoute extends AnyFileRoute = AnyFileRoute>(\n file: AnyFile<TRoute>,\n): file is FailedFile<TRoute> {\n return file.status === \"failed\";\n}\n\n/**\n * Predicate function to check if a file is uploaded\n * @public\n */\nexport function isUploadedFile<TRoute extends AnyFileRoute = AnyFileRoute>(\n file: AnyFile<TRoute>,\n): file is UploadedFile<TRoute> {\n return file.status === \"uploaded\";\n}\n\n/**\n * @internal\n */\nexport function makePendingFile(file: File): PendingFile {\n return Object.assign(file, {\n status: \"pending\" as const,\n sent: 0,\n key: null,\n customId: null,\n });\n}\n\n/**\n * Modifies a pending file to an uploading file in place\n * @internal\n */\nfunction transitionToUploading(\n file: PendingFile,\n rangeStart: number,\n): UploadingFile {\n const uploadingFile = file as unknown as UploadingFile;\n uploadingFile.sent = rangeStart;\n uploadingFile.status = \"uploading\";\n return uploadingFile;\n}\n\n/**\n * Modifies an uploading file to an uploaded file in place\n * @internal\n */\nfunction transitionToUploaded<TRoute extends AnyFileRoute>(\n file: UploadingFile,\n xhrResult: UploadPutResult,\n): UploadedFile<TRoute> {\n const uploadedFile = file as unknown as UploadedFile<TRoute>;\n uploadedFile.status = \"uploaded\";\n uploadedFile.data = xhrResult.serverData;\n uploadedFile.hash = xhrResult.fileHash;\n uploadedFile.url = xhrResult.ufsUrl;\n return uploadedFile;\n}\n\n/**\n * Modifies a pending or uploading file to a failed file in place\n * @internal\n */\nexport function transitionToFailed<TRoute extends AnyFileRoute>(\n file: PendingFile | UploadingFile,\n reason: UploadThingClientError<TRoute[\"$types\"][\"errorShape\"]>,\n): FailedFile<TRoute> {\n const failedFile = file as unknown as FailedFile<TRoute>;\n failedFile.status = \"failed\";\n failedFile.reason = reason;\n return failedFile;\n}\n\n/**\n * Event emitted when the presigned URLs have been retrieved from your server\n * @public\n */\nexport interface PresignedReceivedEvent<TRoute extends AnyFileRoute> {\n type: \"presigned-received\";\n /**\n * All files that are being uploaded as part of this action.\n */\n files: AnyFile<TRoute>[];\n}\n\n/**\n * Event emitted when a file starts uploading\n * @public\n */\nexport interface UploadStartedEvent<TRoute extends AnyFileRoute> {\n type: \"upload-started\";\n /**\n * The file that started uploading.\n */\n file: UploadingFile;\n /**\n * All files that are being uploaded as part of this action.\n */\n files: AnyFile<TRoute>[];\n}\n\n/**\n * Event emitted when a file is uploading and received a progress update\n * @public\n */\nexport interface UploadProgressEvent<TRoute extends AnyFileRoute> {\n type: \"upload-progress\";\n /**\n * The file that is currently uploading and received a progress update.\n */\n file: UploadingFile;\n /**\n * All files that are being uploaded as part of this action.\n */\n files: AnyFile<TRoute>[];\n}\n\n/**\n * Event emitted when a file has finished uploading\n * @public\n */\nexport interface UploadCompletedEvent<TRoute extends AnyFileRoute> {\n type: \"upload-completed\";\n /**\n * The file that finished uploading.\n */\n file: UploadedFile<TRoute>;\n /**\n * All files that are being uploaded as part of this action.\n */\n files: AnyFile<TRoute>[];\n}\n\n/**\n * Event emitted when a file failed to upload\n * @public\n */\nexport interface UploadFailedEvent<TRoute extends AnyFileRoute> {\n type: \"upload-failed\";\n /**\n * The file that failed to upload.\n */\n file: FailedFile<TRoute>;\n /**\n * All files that are being uploaded as part of this action.\n */\n files: AnyFile<TRoute>[];\n}\n\nexport interface UploadAbortedEvent<TRoute extends AnyFileRoute> {\n type: \"upload-aborted\";\n files: AnyFile<TRoute>[];\n}\n\n/**\n * Event emitted throughout the upload process\n * @public\n */\nexport type UploadEvent<TRoute extends AnyFileRoute> =\n | PresignedReceivedEvent<TRoute>\n | UploadStartedEvent<TRoute>\n | UploadProgressEvent<TRoute>\n | UploadCompletedEvent<TRoute>\n | UploadFailedEvent<TRoute>\n | UploadAbortedEvent<TRoute>;\n\nexport interface UploadFileOptions<TRoute extends AnyFileRoute> {\n file: PendingFile;\n files: AnyFile<TRoute>[];\n input: TRoute[\"$types\"][\"input\"];\n onEvent: (event: UploadEvent<TRoute>) => void;\n traceHeaders: TraceHeaders;\n\n XHRImpl: new () => XMLHttpRequest;\n}\n\n/**\n * Upload a file to the storage provider\n * Throughout the upload, the file's status and progress will be updated\n * @remarks This function never rejects\n * @internal\n */\nexport function uploadFile<TRoute extends AnyFileRoute>(\n url: string,\n { file, files, XHRImpl, ...options }: UploadFileOptions<TRoute>,\n): Micro.Micro<UploadedFile<TRoute> | FailedFile<TRoute>, never, FetchContext> {\n return fetchEff(url, { method: \"HEAD\", headers: options.traceHeaders }).pipe(\n Micro.map(({ headers }) =>\n Number.parseInt(headers.get(\"x-ut-range-start\") ?? \"0\"),\n ),\n Micro.map((rangeStart) => transitionToUploading(file, rangeStart)),\n Micro.tap((uploadingFile) => {\n options.onEvent({\n type: \"upload-started\",\n file: uploadingFile,\n files,\n });\n }),\n Micro.flatMap((uploadingFile) =>\n Micro.async<UploadedFile<TRoute>, XHRError | UTStorageError>((resume) => {\n const xhr = new XHRImpl();\n xhr.open(\"PUT\", url, true);\n\n const rangeStart = uploadingFile.sent;\n xhr.setRequestHeader(\"Range\", `bytes=${rangeStart}-`);\n xhr.setRequestHeader(\"x-uploadthing-version\", version);\n xhr.setRequestHeader(\"b3\", options.traceHeaders.b3);\n xhr.setRequestHeader(\"traceparent\", options.traceHeaders.traceparent);\n xhr.responseType = \"json\";\n\n xhr.upload.addEventListener(\"progress\", (ev) => {\n uploadingFile.sent = rangeStart + ev.loaded;\n options.onEvent({\n type: \"upload-progress\",\n file: uploadingFile,\n files,\n });\n });\n xhr.addEventListener(\"load\", () => {\n if (\n xhr.status > 299 ||\n Predicate.hasProperty(xhr.response, \"error\")\n ) {\n resume(\n new UTStorageError({\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n message: String(xhr.response.error),\n response: xhr.response,\n }),\n );\n } else {\n const uploadedFile = transitionToUploaded<TRoute>(\n uploadingFile,\n xhr.response as UploadPutResult,\n );\n options.onEvent({\n type: \"upload-completed\",\n file: uploadedFile,\n files,\n });\n resume(Micro.succeed(uploadedFile));\n }\n });\n xhr.addEventListener(\"error\", () => {\n resume(\n new XHRError({\n message: `XHR failed ${xhr.status} ${xhr.statusText}`,\n xhr: xhr,\n }),\n );\n });\n\n const formData = new FormData();\n /**\n * iOS/React Native FormData handling requires special attention:\n *\n * Issue: In React Native, iOS crashes with \"attempt to insert nil object\" when appending File directly\n * to FormData. This happens because iOS tries to create NSDictionary from the file object and expects\n * specific structure {uri, type, name}.\n *\n *\n * Note: Don't try to use Blob or modify File object - iOS specifically needs plain object\n * with these properties to create valid NSDictionary.\n */\n if (\"uri\" in file) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n formData.append(\"file\", {\n uri: file.uri as string,\n type: file.type,\n name: file.name,\n ...(rangeStart > 0 && { range: rangeStart }),\n } as any);\n } else {\n formData.append(\n \"file\",\n rangeStart > 0 ? file.slice(rangeStart) : file,\n );\n }\n xhr.send(formData);\n\n return Micro.sync(() => xhr.abort());\n }),\n ),\n Micro.catchAll((error) => {\n const failedFile = transitionToFailed<TRoute>(file, error);\n options.onEvent({\n type: \"upload-failed\",\n file: failedFile,\n files,\n });\n return Micro.succeed(failedFile);\n }),\n );\n}\n\nexport interface RequestPresignedUrlsOptions<\n TRouter extends AnyFileRouter,\n TEndpoint extends keyof TRouter,\n> {\n /**\n * The URL to your UploadThing server endpoint\n * @example URL { https://www.example.com/api/uploadthing }\n */\n url: URL;\n /**\n * The slug to your UploadThing FileRoute\n * @example \"imageUploader\"\n */\n endpoint: TEndpoint;\n /**\n * The files to request presigned URLs for\n */\n files: File[];\n /**\n * The route input for the endpoint\n */\n input?: TRouter[TEndpoint][\"$types\"][\"input\"];\n /**\n * Custom headers to send with the request\n * @example { Authorization: \"Bearer 123\" }\n */\n headers?: HeadersInit | LazyArg<MaybePromise<HeadersInit>> | undefined;\n /**\n * Custom trace headers to send with the request\n */\n traceHeaders: TraceHeaders;\n /**\n * The uploadthing package that is making this request, used to identify the client in the server logs\n * @example \"@uploadthing/react\"\n */\n package?: string | undefined;\n}\n\n/**\n * Request presigned URLs from your server for a set of files\n * @internal\n */\nexport function requestPresignedUrls<\n TRouter extends AnyFileRouter,\n TEndpoint extends keyof TRouter,\n>(\n options: RequestPresignedUrlsOptions<TRouter, TEndpoint>,\n): Micro.Micro<\n ReadonlyArray<NewPresignedUrl>,\n UTServerError<TRouter[TEndpoint][\"$types\"][\"errorShape\"]>,\n FetchContext\n> {\n const reportEventToUT = createUTReporter({\n endpoint: String(options.endpoint),\n package: options.package,\n url: options.url,\n headers: options.headers,\n traceHeaders: options.traceHeaders,\n });\n\n return reportEventToUT(\"upload\", {\n input: options.input,\n files: options.files.map((f) => ({\n name: f.name,\n size: f.size,\n type: f.type,\n lastModified: f.lastModified,\n })),\n }).pipe(\n Micro.mapError(\n (error) =>\n new UTServerError({\n message: error.message,\n cause: error,\n data: error.data,\n }),\n ),\n );\n}\n\nexport interface UploadFilesOptions<TRoute extends AnyFileRoute> {\n url: URL;\n files: File[];\n input?: TRoute[\"$types\"][\"input\"];\n onEvent: (event: UploadEvent<TRoute>) => void;\n headers?: HeadersInit | LazyArg<MaybePromise<HeadersInit>> | undefined;\n package?: string | undefined;\n signal?: AbortSignal | undefined;\n}\n\n/**\n * Upload a set of files to the storage provider\n * @internal\n */\nexport function uploadFiles<\n TRouter extends AnyFileRouter,\n TEndpoint extends keyof TRouter,\n>(endpoint: TEndpoint, options: UploadFilesOptions<TRouter[TEndpoint]>) {\n const pendingFiles = options.files.map(makePendingFile);\n const traceHeaders = generateTraceHeaders();\n return requestPresignedUrls({\n endpoint: endpoint,\n files: options.files,\n url: options.url,\n input: options.input,\n headers: options.headers,\n package: options.package,\n traceHeaders,\n }).pipe(\n Micro.map(Arr.zip(pendingFiles)),\n Micro.tap((pairs) => {\n for (const [presigned, file] of pairs) {\n file.key = presigned.key;\n file.customId = presigned.customId;\n }\n options.onEvent({\n type: \"presigned-received\",\n files: pendingFiles,\n });\n }),\n Micro.flatMap((pairs) =>\n Micro.forEach(\n pairs,\n ([presigned, file]) =>\n uploadFile(presigned.url, {\n file,\n files: pendingFiles,\n input: options.input,\n onEvent: options.onEvent,\n XHRImpl: globalThis.XMLHttpRequest,\n traceHeaders,\n }),\n { concurrency: 6 },\n ),\n ),\n );\n}\n","import * as Arr from \"effect/Array\";\nimport * as Micro from \"effect/Micro\";\n\nimport type { FetchEsque } from \"@uploadthing/shared\";\nimport {\n createIdentityProxy,\n FetchContext,\n resolveMaybeUrlArg,\n UploadAbortedError,\n UploadPausedError,\n} from \"@uploadthing/shared\";\n\nimport * as pkgJson from \"../package.json\";\nimport type {\n AnyFile,\n FailedFile,\n PendingFile,\n UploadedFile,\n UploadFilesOptions,\n UploadingFile,\n} from \"./_internal/client-future\";\nimport {\n makePendingFile,\n requestPresignedUrls,\n transitionToFailed,\n uploadFile,\n} from \"./_internal/client-future\";\nimport type { Deferred } from \"./_internal/deferred\";\nimport { createDeferred } from \"./_internal/deferred\";\nimport { generateTraceHeaders } from \"./_internal/random-hex\";\nimport type {\n EndpointArg,\n FileRouter,\n GenerateUploaderOptions,\n inferEndpointInput,\n NewPresignedUrl,\n RouteRegistry,\n} from \"./types\";\n\nexport const version = pkgJson.version;\n\nexport {\n /** @public */\n generateClientDropzoneAccept,\n /** @public */\n generateMimeTypes,\n /** @public */\n generatePermittedFileTypes,\n /** @public */\n UploadAbortedError,\n /** @public */\n UploadPausedError,\n} from \"@uploadthing/shared\";\n\nexport * from \"./_internal/client-future\";\n\n/**\n * Generate a typed uploader for a given FileRouter\n * @public\n * @remarks This API is not covered by semver\n */\nexport const future_genUploader = <TRouter extends FileRouter>(\n initOpts?: GenerateUploaderOptions,\n) => {\n const routeRegistry = createIdentityProxy<RouteRegistry<TRouter>>();\n\n const controllableUpload = async <TEndpoint extends keyof TRouter>(\n slug: EndpointArg<TRouter, TEndpoint>,\n options: Omit<\n UploadFilesOptions<TRouter[TEndpoint]>,\n keyof GenerateUploaderOptions\n >,\n ) => {\n const endpoint = typeof slug === \"function\" ? slug(routeRegistry) : slug;\n const fetchFn: FetchEsque = initOpts?.fetch ?? window.fetch;\n\n const traceHeaders = generateTraceHeaders();\n const pExit = await requestPresignedUrls({\n endpoint: String(endpoint),\n files: options.files,\n url: resolveMaybeUrlArg(initOpts?.url),\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n input: (options as any).input as inferEndpointInput<TRouter[TEndpoint]>,\n headers: options.headers,\n traceHeaders,\n }).pipe(Micro.provideService(FetchContext, fetchFn), (effect) =>\n Micro.runPromiseExit(\n effect,\n options.signal && { signal: options.signal },\n ),\n );\n if (pExit._tag === \"Failure\") throw Micro.causeSquash(pExit.cause);\n const presigneds = pExit.value;\n const pendingFiles = options.files.map(makePendingFile);\n\n options.onEvent({\n type: \"presigned-received\",\n files: pendingFiles,\n });\n\n const uploads = new Map<\n File,\n {\n presigned: NewPresignedUrl;\n deferred: Deferred<AnyFile<TRouter[TEndpoint]>>;\n }\n >();\n\n const uploadEffect = (file: PendingFile, presigned: NewPresignedUrl) =>\n uploadFile(presigned.url, {\n file,\n files: pendingFiles,\n input: options.input,\n onEvent: options.onEvent,\n traceHeaders,\n XHRImpl: globalThis.XMLHttpRequest,\n }).pipe(Micro.provideService(FetchContext, fetchFn));\n\n for (const [presigned, file] of Arr.zip(presigneds, pendingFiles)) {\n file.key = presigned.key;\n file.customId = presigned.customId;\n\n const deferred = createDeferred<AnyFile<TRouter[TEndpoint]>>();\n uploads.set(file, { presigned, deferred });\n\n void Micro.runPromiseExit(uploadEffect(file, presigned), {\n signal: deferred.ac.signal,\n })\n .then((result) => {\n if (result._tag === \"Success\") {\n return deferred.resolve(result.value);\n } else if (result.cause._tag === \"Interrupt\") {\n throw new UploadPausedError();\n }\n throw Micro.causeSquash(result.cause);\n })\n .catch((err) => {\n if (err instanceof UploadPausedError) return;\n deferred.reject(err);\n });\n }\n\n /**\n * Pause an ongoing upload\n * @param file The file upload you want to pause. Can be omitted to pause all files\n */\n const pauseUpload = (file?: File) => {\n const files = Arr.ensure(file ?? options.files);\n for (const file of files) {\n const upload = uploads.get(file);\n if (!upload) return;\n\n if (upload.deferred.ac.signal.aborted) {\n // Noop if it's already paused\n return;\n }\n\n upload.deferred.ac.abort();\n }\n };\n\n /**\n * Abort an upload\n * @param file The file upload you want to abort. Can be omitted to abort all files\n */\n const abortUpload = (file?: File) => {\n const files = Arr.ensure(file ?? options.files);\n for (const file of files) {\n const upload = uploads.get(file);\n if (!upload) throw \"No upload found\";\n\n if (upload.deferred.ac.signal.aborted === false) {\n upload.deferred.ac.abort();\n const failedFile = transitionToFailed(\n file as UploadingFile | PendingFile,\n new UploadAbortedError(),\n );\n upload.deferred.resolve(failedFile);\n }\n }\n\n options.onEvent({\n type: \"upload-aborted\",\n // transitionToFailed mutates inline so this is fine\n files: files as FailedFile<TRouter[TEndpoint]>[],\n });\n };\n\n options.signal?.addEventListener(\"abort\", () => {\n abortUpload();\n });\n\n /**\n * Resume a paused upload\n * @param file The file upload you want to resume. Can be omitted to resume all files\n */\n const resumeUpload = (file?: File) => {\n const files = Arr.ensure(file ?? options.files);\n for (const file of files) {\n const upload = uploads.get(file);\n if (!upload) throw \"No upload found\";\n\n upload.deferred.ac = new AbortController();\n void Micro.runPromiseExit(\n uploadEffect(file as PendingFile, upload.presigned),\n {\n signal: upload.deferred.ac.signal,\n },\n )\n .then((result) => {\n if (result._tag === \"Success\") {\n return upload.deferred.resolve(result.value);\n } else if (result.cause._tag === \"Interrupt\") {\n throw new UploadPausedError();\n }\n throw Micro.causeSquash(result.cause);\n })\n .catch((err) => {\n if (err instanceof UploadPausedError) return;\n upload.deferred.reject(err);\n });\n }\n };\n\n /**\n * Wait for an upload to complete\n * @param file The file upload you want to wait for. Can be omitted to wait for all files\n */\n const done = async <T extends AnyFile<TRouter[TEndpoint]> | void = void>(\n file?: T,\n ): Promise<\n T extends AnyFile<TRouter[TEndpoint]>\n ? UploadedFile<TRouter[TEndpoint]> | FailedFile<TRouter[TEndpoint]>\n : (UploadedFile<TRouter[TEndpoint]> | FailedFile<TRouter[TEndpoint]>)[]\n > => {\n const promises = [];\n\n const files = Arr.ensure(file ?? options.files);\n for (const file of files) {\n const upload = uploads.get(file);\n if (!upload) throw \"No upload found\";\n\n promises.push(upload.deferred.promise);\n }\n\n const results = await Promise.all(promises);\n return (file ? results[0] : results) as never;\n };\n\n return { pauseUpload, abortUpload, resumeUpload, done };\n };\n\n const uploadFiles = <TEndpoint extends keyof TRouter>(\n slug: EndpointArg<TRouter, TEndpoint>,\n opts: Omit<\n UploadFilesOptions<TRouter[TEndpoint]>,\n keyof GenerateUploaderOptions\n >,\n ) => controllableUpload(slug, opts).then((_) => _.done());\n\n return {\n uploadFiles,\n createUpload: controllableUpload,\n /**\n * Identity object that can be used instead of raw strings\n * that allows \"Go to definition\" in your IDE to bring you\n * to the backend definition of a route.\n */\n routeRegistry,\n };\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
|
|
25
|
+
Object.defineProperty(exports, '__toESM', {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function () {
|
|
28
|
+
return __toESM;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/_internal/deprecations.ts
|
|
3
|
+
const logDeprecationWarning = (message) => {
|
|
4
|
+
console.warn(`⚠️ [uploadthing][deprecated] ${message}`);
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
//#endregion
|
|
8
|
+
Object.defineProperty(exports, 'logDeprecationWarning', {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () {
|
|
11
|
+
return logDeprecationWarning;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deprecations-pLmw6Ytd.js","names":["message: string"],"sources":["../src/_internal/deprecations.ts"],"sourcesContent":["export const logDeprecationWarning = (message: string) => {\n // eslint-disable-next-line no-console\n console.warn(`⚠️ [uploadthing][deprecated] ${message}`);\n};\n"],"mappings":";AAAA,MAAa,wBAAwB,CAACA,YAAoB;CAExD,QAAQ,KAAK,CAAC,6BAA6B,EAAE,SAAS,CAAC;AACxD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-DpScpvTA.js","names":[],"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"uploadthing\",\n \"version\": \"7.7.4\",\n \"type\": \"module\",\n \"sideEffects\": false,\n \"engines\": {\n \"node\": \">=18.13.0\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"github:pingdotgg/uploadthing\",\n \"directory\": \"packages/uploadthing\"\n },\n \"license\": \"MIT\",\n \"exports\": {\n \"./package.json\": \"./package.json\",\n \"./client\": {\n \"import\": {\n \"types\": \"./client/index.d.ts\",\n \"default\": \"./client/index.js\"\n },\n \"require\": {\n \"types\": \"./client/index.d.cts\",\n \"default\": \"./client/index.cjs\"\n }\n },\n \"./client-future\": {\n \"import\": {\n \"types\": \"./client-future/index.d.ts\",\n \"default\": \"./client-future/index.js\"\n },\n \"require\": {\n \"types\": \"./client-future/index.d.cts\",\n \"default\": \"./client-future/index.cjs\"\n }\n },\n \"./server\": {\n \"import\": {\n \"types\": \"./server/index.d.ts\",\n \"default\": \"./server/index.js\"\n },\n \"require\": {\n \"types\": \"./server/index.d.cts\",\n \"default\": \"./server/index.cjs\"\n }\n },\n \"./next\": {\n \"import\": {\n \"types\": \"./next/index.d.ts\",\n \"default\": \"./next/index.js\"\n },\n \"require\": {\n \"types\": \"./next/index.d.cts\",\n \"default\": \"./next/index.cjs\"\n }\n },\n \"./next-legacy\": {\n \"import\": {\n \"types\": \"./next-legacy/index.d.ts\",\n \"default\": \"./next-legacy/index.js\"\n },\n \"require\": {\n \"types\": \"./next-legacy/index.d.cts\",\n \"default\": \"./next-legacy/index.cjs\"\n }\n },\n \"./effect-platform\": {\n \"import\": {\n \"types\": \"./effect-platform/index.d.ts\",\n \"default\": \"./effect-platform/index.js\"\n },\n \"require\": {\n \"types\": \"./effect-platform/index.d.cts\",\n \"default\": \"./effect-platform/index.cjs\"\n }\n },\n \"./tw\": {\n \"browser\": \"./tw/index.browser.js\",\n \"import\": {\n \"types\": \"./tw/index.d.ts\",\n \"default\": \"./tw/index.js\"\n },\n \"require\": {\n \"types\": \"./tw/index.d.cts\",\n \"default\": \"./tw/index.cjs\"\n }\n },\n \"./tw/v4\": \"./tw/v4.css\",\n \"./fastify\": {\n \"import\": {\n \"types\": \"./fastify/index.d.ts\",\n \"default\": \"./fastify/index.js\"\n },\n \"require\": {\n \"types\": \"./fastify/index.d.cts\",\n \"default\": \"./fastify/index.cjs\"\n }\n },\n \"./express\": {\n \"import\": {\n \"types\": \"./express/index.d.ts\",\n \"default\": \"./express/index.js\"\n },\n \"require\": {\n \"types\": \"./express/index.d.cts\",\n \"default\": \"./express/index.cjs\"\n }\n },\n \"./h3\": {\n \"import\": {\n \"types\": \"./h3/index.d.ts\",\n \"default\": \"./h3/index.js\"\n },\n \"require\": {\n \"types\": \"./h3/index.d.cts\",\n \"default\": \"./h3/index.cjs\"\n }\n },\n \"./remix\": {\n \"import\": {\n \"types\": \"./remix/index.d.ts\",\n \"default\": \"./remix/index.js\"\n },\n \"require\": {\n \"types\": \"./remix/index.d.cts\",\n \"default\": \"./remix/index.cjs\"\n }\n },\n \"./types\": {\n \"types\": \"./types/index.d.ts\",\n \"default\": \"./types/index.js\"\n }\n },\n \"files\": [\n \"client\",\n \"client-future\",\n \"dist\",\n \"effect-platform\",\n \"express\",\n \"fastify\",\n \"h3\",\n \"next\",\n \"next-legacy\",\n \"remix\",\n \"server\",\n \"types\",\n \"tw\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"lint\": \"eslint src test --max-warnings 0\",\n \"build\": \"tsdown\",\n \"clean\": \"git clean -xdf client express fastify h3 internal next next-legacy server tw node_modules\",\n \"dev\": \"tsdown --no-clean\",\n \"prepack\": \"bun ../../.github/replace-workspace-protocol.ts\",\n \"test\": \"vitest run\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@effect/platform\": \"0.90.3\",\n \"@standard-schema/spec\": \"1.0.0-beta.4\",\n \"@uploadthing/mime-types\": \"workspace:*\",\n \"@uploadthing/shared\": \"workspace:*\",\n \"effect\": \"3.17.7\"\n },\n \"devDependencies\": {\n \"@effect/vitest\": \"0.25.1\",\n \"@remix-run/server-runtime\": \"^2.12.0\",\n \"@types/body-parser\": \"^1.19.5\",\n \"@types/express\": \"^5.0.0\",\n \"@types/express-serve-static-core\": \"^5.0.3\",\n \"@types/react\": \"19.1.2\",\n \"@uploadthing/eslint-config\": \"workspace:*\",\n \"@uploadthing/tsconfig\": \"workspace:*\",\n \"@uploadthing/vitest-config\": \"workspace:*\",\n \"@vitest/coverage-istanbul\": \"3.2.4\",\n \"body-parser\": \"^1.20.2\",\n \"eslint\": \"9.25.1\",\n \"express\": \"^5.0.1\",\n \"fastify\": \"^5.2.0\",\n \"h3\": \"^1.13.0\",\n \"msw\": \"2.7.5\",\n \"next\": \"15.3.1\",\n \"solid-js\": \"^1.9.3\",\n \"tailwindcss\": \"^3.4.16\",\n \"tsdown\": \"0.14.1\",\n \"typescript\": \"5.8.3\",\n \"valibot\": \"1.0.0-beta.9\",\n \"vitest\": \"3.2.4\",\n \"vue\": \"^3.4.21\",\n \"wait-on\": \"^8.0.1\",\n \"zod\": \"^3.24.1\"\n },\n \"peerDependencies\": {\n \"express\": \"*\",\n \"h3\": \"*\",\n \"tailwindcss\": \"^3.0.0 || ^4.0.0-beta.0\"\n },\n \"peerDependenciesMeta\": {\n \"next\": {\n \"optional\": true\n },\n \"express\": {\n \"optional\": true\n },\n \"fastify\": {\n \"optional\": true\n },\n \"h3\": {\n \"optional\": true\n },\n \"tailwindcss\": {\n \"optional\": true\n }\n }\n}\n"],"mappings":";cAEa"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { ValidACLs, ValidContentDispositions } from "@uploadthing/shared";
|
|
2
|
+
import * as S from "effect/Schema";
|
|
3
|
+
|
|
4
|
+
//#region src/_internal/shared-schemas.ts
|
|
5
|
+
const ContentDispositionSchema = S.Literal(...ValidContentDispositions);
|
|
6
|
+
const ACLSchema = S.Literal(...ValidACLs);
|
|
7
|
+
/**
|
|
8
|
+
* Valid options for the `?actionType` query param
|
|
9
|
+
*/
|
|
10
|
+
const ActionType = S.Literal("upload");
|
|
11
|
+
/**
|
|
12
|
+
* Valid options for the `uploadthing-hook` header
|
|
13
|
+
* for requests coming from UT server
|
|
14
|
+
*/
|
|
15
|
+
const UploadThingHook = S.Literal("callback", "error");
|
|
16
|
+
/**
|
|
17
|
+
* =============================================================================
|
|
18
|
+
* =========================== Configuration ===================================
|
|
19
|
+
* =============================================================================
|
|
20
|
+
*/
|
|
21
|
+
const DecodeString = S.transform(S.Uint8ArrayFromSelf, S.String, {
|
|
22
|
+
decode: (data) => new TextDecoder().decode(data),
|
|
23
|
+
encode: (data) => new TextEncoder().encode(data)
|
|
24
|
+
});
|
|
25
|
+
const ParsedToken = S.Struct({
|
|
26
|
+
apiKey: S.Redacted(S.String.pipe(S.startsWith("sk_"))),
|
|
27
|
+
appId: S.String,
|
|
28
|
+
regions: S.NonEmptyArray(S.String),
|
|
29
|
+
ingestHost: S.String.pipe(S.optionalWith({ default: () => "ingest.uploadthing.com" }))
|
|
30
|
+
});
|
|
31
|
+
const UploadThingToken = S.Uint8ArrayFromBase64.pipe(S.compose(DecodeString), S.compose(S.parseJson(ParsedToken)));
|
|
32
|
+
/**
|
|
33
|
+
* =============================================================================
|
|
34
|
+
* ======================== File Type Hierarchy ===============================
|
|
35
|
+
* =============================================================================
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Properties from the web File object, this is what the client sends when initiating an upload
|
|
39
|
+
*/
|
|
40
|
+
var FileUploadData = class extends S.Class("FileUploadData")({
|
|
41
|
+
name: S.String,
|
|
42
|
+
size: S.Number,
|
|
43
|
+
type: S.String,
|
|
44
|
+
lastModified: S.Number.pipe(S.optional)
|
|
45
|
+
}) {};
|
|
46
|
+
/**
|
|
47
|
+
* `.middleware()` can add a customId to the incoming file data
|
|
48
|
+
*/
|
|
49
|
+
var FileUploadDataWithCustomId = class extends FileUploadData.extend("FileUploadDataWithCustomId")({ customId: S.NullOr(S.String) }) {};
|
|
50
|
+
/**
|
|
51
|
+
* When files are uploaded, we get back
|
|
52
|
+
* - a key
|
|
53
|
+
* - URLs for the file
|
|
54
|
+
* - the hash (md5-hex) of the uploaded file's contents
|
|
55
|
+
*/
|
|
56
|
+
var UploadedFileData = class extends FileUploadDataWithCustomId.extend("UploadedFileData")({
|
|
57
|
+
key: S.String,
|
|
58
|
+
url: S.String,
|
|
59
|
+
appUrl: S.String,
|
|
60
|
+
ufsUrl: S.String,
|
|
61
|
+
fileHash: S.String
|
|
62
|
+
}) {};
|
|
63
|
+
var MetadataFetchStreamPart = class extends S.Class("MetadataFetchStreamPart")({
|
|
64
|
+
payload: S.String,
|
|
65
|
+
signature: S.String,
|
|
66
|
+
hook: UploadThingHook
|
|
67
|
+
}) {};
|
|
68
|
+
var MetadataFetchResponse = class extends S.Class("MetadataFetchResponse")({ ok: S.Boolean }) {};
|
|
69
|
+
var CallbackResultResponse = class extends S.Class("CallbackResultResponse")({ ok: S.Boolean }) {};
|
|
70
|
+
/**
|
|
71
|
+
* =============================================================================
|
|
72
|
+
* ======================== Client Action Payloads ============================
|
|
73
|
+
* =============================================================================
|
|
74
|
+
*/
|
|
75
|
+
var UploadActionPayload = class extends S.Class("UploadActionPayload")({
|
|
76
|
+
files: S.Array(FileUploadData),
|
|
77
|
+
input: S.Unknown
|
|
78
|
+
}) {};
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
81
|
+
export { ActionType, CallbackResultResponse, MetadataFetchResponse, MetadataFetchStreamPart, UploadActionPayload, UploadThingHook, UploadThingToken, UploadedFileData };
|
|
82
|
+
//# sourceMappingURL=shared-schemas-BmG5ARoX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-schemas-BmG5ARoX.js","names":[],"sources":["../src/_internal/shared-schemas.ts"],"sourcesContent":["import * as S from \"effect/Schema\";\n\nimport type { Json } from \"@uploadthing/shared\";\nimport { ValidACLs, ValidContentDispositions } from \"@uploadthing/shared\";\n\nexport const ContentDispositionSchema = S.Literal(...ValidContentDispositions);\nexport const ACLSchema = S.Literal(...ValidACLs);\n\n/**\n * Valid options for the `?actionType` query param\n */\nexport const ActionType = S.Literal(\"upload\");\n\n/**\n * Valid options for the `uploadthing-hook` header\n * for requests coming from UT server\n */\nexport const UploadThingHook = S.Literal(\"callback\", \"error\");\n\n/**\n * =============================================================================\n * =========================== Configuration ===================================\n * =============================================================================\n */\nconst DecodeString = S.transform(S.Uint8ArrayFromSelf, S.String, {\n decode: (data) => new TextDecoder().decode(data),\n encode: (data) => new TextEncoder().encode(data),\n});\n\nexport const ParsedToken = S.Struct({\n apiKey: S.Redacted(S.String.pipe(S.startsWith(\"sk_\"))),\n appId: S.String,\n regions: S.NonEmptyArray(S.String),\n ingestHost: S.String.pipe(\n S.optionalWith({ default: () => \"ingest.uploadthing.com\" }),\n ),\n});\n\nexport const UploadThingToken = S.Uint8ArrayFromBase64.pipe(\n S.compose(DecodeString),\n S.compose(S.parseJson(ParsedToken)),\n);\n\n/**\n * =============================================================================\n * ======================== File Type Hierarchy ===============================\n * =============================================================================\n */\n\n/**\n * Properties from the web File object, this is what the client sends when initiating an upload\n */\nexport class FileUploadData extends S.Class<FileUploadData>(\"FileUploadData\")({\n name: S.String,\n size: S.Number,\n type: S.String,\n lastModified: S.Number.pipe(S.optional),\n}) {}\n\n/**\n * `.middleware()` can add a customId to the incoming file data\n */\nexport class FileUploadDataWithCustomId extends FileUploadData.extend<FileUploadDataWithCustomId>(\n \"FileUploadDataWithCustomId\",\n)({\n customId: S.NullOr(S.String),\n}) {}\n\n/**\n * When files are uploaded, we get back\n * - a key\n * - URLs for the file\n * - the hash (md5-hex) of the uploaded file's contents\n */\nexport class UploadedFileData extends FileUploadDataWithCustomId.extend<UploadedFileData>(\n \"UploadedFileData\",\n)({\n key: S.String,\n /**\n * @deprecated\n * This field will be removed in uploadthing v9. Use `ufsUrl` instead.\n */\n url: S.String,\n /**\n * @deprecated\n * This field will be removed in uploadthing v9. Use `ufsUrl` instead.\n */\n appUrl: S.String,\n ufsUrl: S.String,\n fileHash: S.String,\n}) {}\n\n/**\n * When the client has uploaded a file and polled for data returned by `.onUploadComplete()`\n */\nexport interface ClientUploadedFileData<T> extends UploadedFileData {\n /**\n * Matches what's returned from the serverside `onUploadComplete` callback\n */\n readonly serverData: T;\n}\n\n/**\n * =============================================================================\n * ======================== Server Response Schemas ============================\n * =============================================================================\n */\n\nexport class NewPresignedUrl extends S.Class<NewPresignedUrl>(\n \"NewPresignedUrl\",\n)({\n url: S.String,\n key: S.String,\n customId: S.NullOr(S.String),\n name: S.String,\n}) {}\n\nexport class MetadataFetchStreamPart extends S.Class<MetadataFetchStreamPart>(\n \"MetadataFetchStreamPart\",\n)({\n payload: S.String,\n signature: S.String,\n hook: UploadThingHook,\n}) {}\n\nexport class MetadataFetchResponse extends S.Class<MetadataFetchResponse>(\n \"MetadataFetchResponse\",\n)({\n ok: S.Boolean,\n}) {}\n\nexport class CallbackResultResponse extends S.Class<CallbackResultResponse>(\n \"CallbackResultResponse\",\n)({\n ok: S.Boolean,\n}) {}\n\n/**\n * =============================================================================\n * ======================== Client Action Payloads ============================\n * =============================================================================\n */\n\nexport class UploadActionPayload extends S.Class<UploadActionPayload>(\n \"UploadActionPayload\",\n)({\n files: S.Array(FileUploadData),\n input: S.Unknown as S.Schema<Json>,\n}) {}\n"],"mappings":";;;;AAKA,MAAa,2BAA2B,EAAE,QAAQ,GAAG,yBAAyB;AAC9E,MAAa,YAAY,EAAE,QAAQ,GAAG,UAAU;;;;AAKhD,MAAa,aAAa,EAAE,QAAQ,SAAS;;;;;AAM7C,MAAa,kBAAkB,EAAE,QAAQ,YAAY,QAAQ;;;;;;AAO7D,MAAM,eAAe,EAAE,UAAU,EAAE,oBAAoB,EAAE,QAAQ;CAC/D,QAAQ,CAAC,SAAS,IAAI,cAAc,OAAO,KAAK;CAChD,QAAQ,CAAC,SAAS,IAAI,cAAc,OAAO,KAAK;AACjD,EAAC;AAEF,MAAa,cAAc,EAAE,OAAO;CAClC,QAAQ,EAAE,SAAS,EAAE,OAAO,KAAK,EAAE,WAAW,MAAM,CAAC,CAAC;CACtD,OAAO,EAAE;CACT,SAAS,EAAE,cAAc,EAAE,OAAO;CAClC,YAAY,EAAE,OAAO,KACnB,EAAE,aAAa,EAAE,SAAS,MAAM,yBAA0B,EAAC,CAC5D;AACF,EAAC;AAEF,MAAa,mBAAmB,EAAE,qBAAqB,KACrD,EAAE,QAAQ,aAAa,EACvB,EAAE,QAAQ,EAAE,UAAU,YAAY,CAAC,CACpC;;;;;;;;;AAWD,IAAa,iBAAb,cAAoC,EAAE,MAAsB,iBAAiB,CAAC;CAC5E,MAAM,EAAE;CACR,MAAM,EAAE;CACR,MAAM,EAAE;CACR,cAAc,EAAE,OAAO,KAAK,EAAE,SAAS;AACxC,EAAC,CAAC,CAAE;;;;AAKL,IAAa,6BAAb,cAAgD,eAAe,OAC7D,6BACD,CAAC,EACA,UAAU,EAAE,OAAO,EAAE,OAAO,CAC7B,EAAC,CAAC,CAAE;;;;;;;AAQL,IAAa,mBAAb,cAAsC,2BAA2B,OAC/D,mBACD,CAAC;CACA,KAAK,EAAE;CAKP,KAAK,EAAE;CAKP,QAAQ,EAAE;CACV,QAAQ,EAAE;CACV,UAAU,EAAE;AACb,EAAC,CAAC,CAAE;AA2BL,IAAa,0BAAb,cAA6C,EAAE,MAC7C,0BACD,CAAC;CACA,SAAS,EAAE;CACX,WAAW,EAAE;CACb,MAAM;AACP,EAAC,CAAC,CAAE;AAEL,IAAa,wBAAb,cAA2C,EAAE,MAC3C,wBACD,CAAC,EACA,IAAI,EAAE,QACP,EAAC,CAAC,CAAE;AAEL,IAAa,yBAAb,cAA4C,EAAE,MAC5C,yBACD,CAAC,EACA,IAAI,EAAE,QACP,EAAC,CAAC,CAAE;;;;;;AAQL,IAAa,sBAAb,cAAyC,EAAE,MACzC,sBACD,CAAC;CACA,OAAO,EAAE,MAAM,eAAe;CAC9B,OAAO,EAAE;AACV,EAAC,CAAC,CAAE"}
|