import { type ApiTypes, Resources } from '@datocms/cma-client'; import { type CancelablePromise, CanceledPromiseError, makeCancelablePromise, } from '@datocms/rest-client-utils'; import { type OnProgressInfo, uploadFileOrBlobAndReturnPath, } from '../utils/uploadFileOrBlobAndReturnPath'; export type OnProgressCreatingUploadObjectInfo = { type: 'CREATING_UPLOAD_OBJECT'; }; export type OnUploadProgressInfo = | OnProgressInfo | OnProgressCreatingUploadObjectInfo; export type CreateUploadFromFileOrBlobSchema = Omit< ApiTypes.UploadCreateSchema, 'path' > & { fileOrBlob: File | Blob; filename?: string; onProgress?: (info: OnUploadProgressInfo) => void; }; export type UpdateUploadFromFileOrBlobSchema = Omit< ApiTypes.UploadUpdateSchema, 'path' > & { fileOrBlob: File | Blob; filename?: string; onProgress?: (info: OnUploadProgressInfo) => void; }; export default class Upload extends Resources.Upload { /** * Create a new upload using a browser File/Blob object * * Read more: https://www.datocms.com/docs/content-management-api/resources/upload/create */ createFromFileOrBlob( body: CreateUploadFromFileOrBlobSchema, ): CancelablePromise { let isCanceledBeforeUpload = false; let uploadPromise: CancelablePromise | undefined; return makeCancelablePromise( async () => { if (isCanceledBeforeUpload) { throw new CanceledPromiseError(); } const { fileOrBlob, filename, onProgress, ...other } = body; uploadPromise = uploadFileOrBlobAndReturnPath(this.client, fileOrBlob, { filename, onProgress, }); const path = await uploadPromise; if (onProgress) { onProgress({ type: 'CREATING_UPLOAD_OBJECT' }); } return this.create({ ...other, path }); }, () => { if (uploadPromise) { uploadPromise.cancel(); } else { isCanceledBeforeUpload = true; } }, ); } /** * Updates an upload asset using a browser File/Blob object * * Read more: https://www.datocms.com/docs/content-management-api/resources/upload/update */ updateFromFileOrBlob( uploadId: string | ApiTypes.UploadData, body: UpdateUploadFromFileOrBlobSchema, ): CancelablePromise { let isCanceledBeforeUpload = false; let uploadPromise: CancelablePromise | undefined; return makeCancelablePromise( async () => { if (isCanceledBeforeUpload) { throw new CanceledPromiseError(); } const { fileOrBlob, filename, onProgress, ...other } = body; uploadPromise = uploadFileOrBlobAndReturnPath(this.client, fileOrBlob, { filename, onProgress, }); const path = await uploadPromise; if (onProgress) { onProgress({ type: 'CREATING_UPLOAD_OBJECT' }); } return this.update(uploadId, { ...other, path }); }, () => { if (uploadPromise) { uploadPromise.cancel(); } else { isCanceledBeforeUpload = true; } }, ); } }