Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@uppy/xhr-upload: introduce hooks similar to tus #5094

Open
wants to merge 15 commits into
base: 4.x
Choose a base branch
from
Open

Conversation

Murderlon
Copy link
Member

@Murderlon Murderlon commented Apr 16, 2024

Closes #5049

@Murderlon Murderlon requested review from mifi and aduh95 April 16, 2024 15:40
@Murderlon Murderlon self-assigned this Apr 16, 2024
Copy link
Contributor

github-actions bot commented Apr 16, 2024

Diff output files
diff --git a/packages/@uppy/utils/lib/fetcher.js b/packages/@uppy/utils/lib/fetcher.js
index d0f29e3..c273c2c 100644
--- a/packages/@uppy/utils/lib/fetcher.js
+++ b/packages/@uppy/utils/lib/fetcher.js
@@ -12,7 +12,7 @@ export function fetcher(url, options) {
     onBeforeRequest = noop,
     onUploadProgress = noop,
     shouldRetry = () => true,
-    onAfterRequest = noop,
+    onAfterResponse = noop,
     onTimeout = noop,
     responseType,
     retries = 3,
@@ -38,7 +38,7 @@ export function fetcher(url, options) {
         reject(new DOMException("Aborted", "AbortError"));
       });
       xhr.onload = async () => {
-        await onAfterRequest(xhr, retryCount);
+        await onAfterResponse(xhr, retryCount);
         if (xhr.status >= 200 && xhr.status < 300) {
           timer.done();
           resolve(xhr);
diff --git a/packages/@uppy/xhr-upload/lib/index.js b/packages/@uppy/xhr-upload/lib/index.js
index 595495e..c593275 100644
--- a/packages/@uppy/xhr-upload/lib/index.js
+++ b/packages/@uppy/xhr-upload/lib/index.js
@@ -45,30 +45,12 @@ const defaultOptions = {
   fieldName: "file",
   method: "post",
   allowedMetaFields: true,
-  responseUrlFieldName: "url",
   bundle: false,
   headers: {},
   timeout: 30 * 1000,
   limit: 5,
   withCredentials: false,
   responseType: "",
-  getResponseData(responseText) {
-    let parsedResponse = {};
-    try {
-      parsedResponse = JSON.parse(responseText);
-    } catch {}
-    return parsedResponse;
-  },
-  getResponseError(_, response) {
-    let error = new Error("Upload error");
-    if (isNetworkError(response)) {
-      error = new NetworkError(error, response);
-    }
-    return error;
-  },
-  validateStatus(status) {
-    return status >= 200 && status < 300;
-  },
 };
 var _getFetcher = _classPrivateFieldLooseKey("getFetcher");
 var _uploadLocalFile = _classPrivateFieldLooseKey("uploadLocalFile");
@@ -155,6 +137,9 @@ export default class XHRUpload extends BasePlugin {
         try {
           const res = await fetcher(url, {
             ...options,
+            onBeforeRequest: this.opts.onBeforeRequest,
+            shouldRetry: this.opts.shouldRetry,
+            onAfterResponse: this.opts.onAfterResponse,
             onTimeout: timeout => {
               const seconds = Math.ceil(timeout / 1000);
               const error = new Error(this.i18n("uploadStalled", {
@@ -174,16 +159,12 @@ export default class XHRUpload extends BasePlugin {
               }
             },
           });
-          if (!this.opts.validateStatus(res.status, res.responseText, res)) {
-            throw new NetworkError(res.statusText, res);
-          }
-          const body = this.opts.getResponseData(res.responseText, res);
-          const uploadURL = body == null ? void 0 : body[this.opts.responseUrlFieldName];
+          const body = JSON.parse(res.responseText);
           for (const file of files) {
             this.uppy.emit("upload-success", file, {
               status: res.status,
               body,
-              uploadURL,
+              uploadURL: body.url,
             });
           }
           return res;
@@ -193,9 +174,8 @@ export default class XHRUpload extends BasePlugin {
           }
           if (error instanceof NetworkError) {
             const request = error.request;
-            const customError = buildResponseError(request, this.opts.getResponseError(request.responseText, request));
             for (const file of files) {
-              this.uppy.emit("upload-error", file, customError);
+              this.uppy.emit("upload-error", file, buildResponseError(request, error));
             }
           }
           throw error;

packages/@uppy/xhr-upload/src/index.ts Outdated Show resolved Hide resolved
packages/@uppy/xhr-upload/src/index.ts Outdated Show resolved Hide resolved
Base automatically changed from xhr-fetcher-refactor to main April 29, 2024 13:39
@Murderlon Murderlon changed the base branch from main to 4.x April 29, 2024 13:56
@Murderlon Murderlon added the 4.0 For the 4.0 major version label Apr 29, 2024
@Murderlon Murderlon requested a review from mifi April 29, 2024 14:10
@Murderlon
Copy link
Member Author

Linters failing because prettier is not enabled for markdown. Enabled here: #5133

* 4.x:
  meta: enable prettier for markdown (#5133)
  @uppy/xhr-upload: do not throw when res is missing url (#5132)
  Release: uppy@4.0.0-beta.4 (#5130)
  meta: fix release script
  Upgrade Yarn to 4.x (#4849)
  @uppy/companion: coerce `requestUrl` to a string (#5128)
  Release: uppy@3.25.0 (#5127)
  meta: enforce use of `.js` extension in `import type` declarations (#5126)
  @uppy/core: add instance ID to generated IDs (#5080)
  @uppy/core: reference updated i18n in Restricter (#5118)
* 4.x:
  Release: uppy@4.0.0-beta.5 (#5141)
  meta: run Prettier in the release workflow
  Release: uppy@3.25.1 (#5139)
  Bump ejs from 3.1.9 to 3.1.10 (#5135)
  Update ru_RU locale  (#5120)
  meta: fix `update-contributors` script (#5137)
  meta: fix `bullet` setting for ReMark
  meta: add prettier to `.md` pre-commit hooks
  @uppy/core: make UppyEventMap more readable
  Format
docs/uploader/xhr.mdx Outdated Show resolved Hide resolved
docs/uploader/xhr.mdx Outdated Show resolved Hide resolved
docs/uploader/xhr.mdx Outdated Show resolved Hide resolved

for (const file of files) {
this.uppy.emit('upload-success', file, {
status: res.status,
body,
uploadURL,
uploadURL: body.url as string | undefined,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this needed if body is already type asseted as B? shouldn't we change type Body so that it instead has url?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we do not know what B is, it's Record<string, unknown>. Maybe we should consider creating specific B generics per uploader, but that's outside of the scope of this PR.

packages/@uppy/xhr-upload/src/index.ts Show resolved Hide resolved
const uploadURL = body?.[this.opts.responseUrlFieldName] as
| string
| undefined
const body = JSON.parse(res.responseText) as B

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const uploadUrl = 'url' in body && typeof body.url === 'string' ? body.url : undefined;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4.0 For the 4.0 major version
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants