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: migrate to TS #4892

Merged
merged 5 commits into from
Jan 29, 2024
Merged

@uppy/xhr-upload: migrate to TS #4892

merged 5 commits into from
Jan 29, 2024

Conversation

Murderlon
Copy link
Member

@Murderlon Murderlon commented Jan 25, 2024

No description provided.

@Murderlon Murderlon requested review from mifi, arturi and aduh95 January 25, 2024 12:23
@Murderlon Murderlon self-assigned this Jan 25, 2024
Copy link
Contributor

github-actions bot commented Jan 25, 2024

Diff output files
diff --git a/packages/@uppy/xhr-upload/lib/index.js b/packages/@uppy/xhr-upload/lib/index.js
index 9152ae8..a864f43 100644
--- a/packages/@uppy/xhr-upload/lib/index.js
+++ b/packages/@uppy/xhr-upload/lib/index.js
@@ -9,7 +9,7 @@ function _classPrivateFieldLooseKey(name) {
   return "__private_" + id++ + "_" + name;
 }
 import BasePlugin from "@uppy/core/lib/BasePlugin.js";
-import EventManager from "@uppy/utils/lib/EventManager";
+import EventManager from "@uppy/core/lib/EventManager.js";
 import { filterFilesToEmitUploadStarted, filterNonFailedFiles } from "@uppy/utils/lib/fileFilters";
 import isNetworkError from "@uppy/utils/lib/isNetworkError";
 import NetworkError from "@uppy/utils/lib/NetworkError";
@@ -40,6 +40,33 @@ function setTypeInBlob(file) {
   const dataWithUpdatedType = file.data.slice(0, file.data.size, file.meta.type);
   return dataWithUpdatedType;
 }
+const defaultOptions = {
+  endpoint: "",
+  formData: true,
+  fieldName: "file",
+  method: "post",
+  allowedMetaFields: null,
+  responseUrlFieldName: "url",
+  bundle: false,
+  headers: {},
+  timeout: 30 * 1000,
+  limit: 5,
+  withCredentials: false,
+  responseType: "",
+  getResponseData(responseText) {
+    return JSON.parse(responseText);
+  },
+  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 _uploadLocalFile = _classPrivateFieldLooseKey("uploadLocalFile");
 var _uploadBundle = _classPrivateFieldLooseKey("uploadBundle");
 var _getCompanionClientArgs = _classPrivateFieldLooseKey("getCompanionClientArgs");
@@ -47,7 +74,11 @@ var _uploadFiles = _classPrivateFieldLooseKey("uploadFiles");
 var _handleUpload = _classPrivateFieldLooseKey("handleUpload");
 export default class XHRUpload extends BasePlugin {
   constructor(uppy, _opts) {
-    super(uppy, _opts);
+    super(uppy, {
+      ...defaultOptions,
+      fieldName: _opts.bundle ? "files[]" : "file",
+      ..._opts,
+    });
     Object.defineProperty(this, _uploadFiles, {
       value: _uploadFiles2,
     });
@@ -94,44 +125,7 @@ export default class XHRUpload extends BasePlugin {
     });
     this.type = "uploader";
     this.id = this.opts.id || "XHRUpload";
-    this.title = "XHRUpload";
     this.defaultLocale = locale;
-    const defaultOptions = {
-      formData: true,
-      fieldName: _opts.bundle ? "files[]" : "file",
-      method: "post",
-      allowedMetaFields: null,
-      responseUrlFieldName: "url",
-      bundle: false,
-      headers: {},
-      timeout: 30 * 1000,
-      limit: 5,
-      withCredentials: false,
-      responseType: "",
-      getResponseData(responseText) {
-        let parsedResponse = {};
-        try {
-          parsedResponse = JSON.parse(responseText);
-        } catch (err) {
-          uppy.log(err);
-        }
-        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;
-      },
-    };
-    this.opts = {
-      ...defaultOptions,
-      ..._opts,
-    };
     this.i18nInit();
     if (internalRateLimitedQueue in this.opts) {
       this.requests = this.opts[internalRateLimitedQueue];
@@ -141,6 +135,9 @@ export default class XHRUpload extends BasePlugin {
     if (this.opts.bundle && !this.opts.formData) {
       throw new Error("`opts.formData` must be true when `opts.bundle` is enabled.");
     }
+    if (this.opts.bundle && typeof this.opts.headers === "function") {
+      throw new Error("`opts.headers` can not be a function when the `bundle: true` option is set.");
+    }
     if ((_opts == null ? void 0 : _opts.allowedMetaFields) === undefined && "metaFields" in this.opts) {
       throw new Error("The `metaFields` option has been renamed to `allowedMetaFields`.");
     }
@@ -173,10 +170,11 @@ export default class XHRUpload extends BasePlugin {
   addMetadata(formData, meta, opts) {
     const allowedMetaFields = Array.isArray(opts.allowedMetaFields) ? opts.allowedMetaFields : Object.keys(meta);
     allowedMetaFields.forEach(item => {
-      if (Array.isArray(meta[item])) {
-        meta[item].forEach(subItem => formData.append(item, subItem));
+      const value = meta[item];
+      if (Array.isArray(value)) {
+        value.forEach(subItem => formData.append(item, subItem));
       } else {
-        formData.append(item, meta[item]);
+        formData.append(item, value);
       }
     });
   }
@@ -239,6 +237,7 @@ export default class XHRUpload extends BasePlugin {
 }
 async function _uploadLocalFile2(file, current, total) {
   const opts = this.getOptions(file);
+  const uploadStarted = Date.now();
   this.uppy.log(`uploading ${current} of ${total}`);
   return new Promise((resolve, reject) => {
     const data = opts.formData ? this.createFormDataUpload(file, opts) : file.data;
@@ -262,6 +261,7 @@ async function _uploadLocalFile2(file, current, total) {
       if (ev.lengthComputable) {
         this.uppy.emit("upload-progress", file, {
           uploader: this,
+          uploadStarted,
           bytesUploaded: ev.loaded,
           bytesTotal: ev.total,
         });
@@ -349,6 +349,7 @@ function _uploadBundle2(files) {
     const {
       method,
     } = this.opts;
+    const uploadStarted = Date.now();
     const optsFromState = this.uppy.getState().xhrUpload;
     const formData = this.createBundledUpload(files, {
       ...this.opts,
@@ -376,17 +377,18 @@ function _uploadBundle2(files) {
       files.forEach(file => {
         this.uppy.emit("upload-progress", file, {
           uploader: this,
+          uploadStarted,
           bytesUploaded: ev.loaded / ev.total * file.size,
           bytesTotal: file.size,
         });
       });
     });
-    xhr.addEventListener("load", ev => {
+    xhr.addEventListener("load", () => {
       timer.done();
-      if (this.opts.validateStatus(ev.target.status, xhr.responseText, xhr)) {
+      if (this.opts.validateStatus(xhr.status, xhr.responseText, xhr)) {
         const body = this.opts.getResponseData(xhr.responseText, xhr);
         const uploadResp = {
-          status: ev.target.status,
+          status: xhr.status,
           body,
         };
         files.forEach(file => {
@@ -394,8 +396,7 @@ function _uploadBundle2(files) {
         });
         return resolve();
       }
-      const error = this.opts.getResponseError(xhr.responseText, xhr) || new Error("Upload error");
-      error.request = xhr;
+      const error = this.opts.getResponseError(xhr.responseText, xhr) || new NetworkError("Upload error", xhr);
       emitError(error);
       return reject(error);
     });
@@ -418,17 +419,19 @@ function _uploadBundle2(files) {
     if (this.opts.responseType !== "") {
       xhr.responseType = this.opts.responseType;
     }
-    Object.keys(this.opts.headers).forEach(header => {
-      xhr.setRequestHeader(header, this.opts.headers[header]);
+    const headers = this.opts.headers;
+    Object.keys(headers).forEach(header => {
+      xhr.setRequestHeader(header, headers[header]);
     });
     xhr.send(formData);
   });
 }
 function _getCompanionClientArgs2(file) {
+  var _file$remote;
   const opts = this.getOptions(file);
   const allowedMetaFields = Array.isArray(opts.allowedMetaFields) ? opts.allowedMetaFields : Object.keys(file.meta);
   return {
-    ...file.remote.body,
+    ...((_file$remote = file.remote) == null ? void 0 : _file$remote.body),
     protocol: "multipart",
     endpoint: opts.endpoint,
     size: file.data.size,
@@ -441,7 +444,7 @@ function _getCompanionClientArgs2(file) {
 }
 async function _uploadFiles2(files) {
   await Promise.allSettled(files.map((file, i) => {
-    const current = parseInt(i, 10) + 1;
+    const current = i + 1;
     const total = files.length;
     if (file.isRemote) {
       const getQueue = () => this.requests;

@@ -382,20 +472,20 @@ export default class XHRUpload extends BasePlugin {

files.forEach((file) => {
this.uppy.emit('upload-progress', file, {
uploader: this,
Copy link
Member Author

Choose a reason for hiding this comment

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

Removed uploader as it's used nowhere.

Copy link
Contributor

Choose a reason for hiding this comment

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

It might be used by users – it might have been added as a response to a user request. You also added uploadStarted?

Copy link
Member Author

Choose a reason for hiding this comment

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

I can't be typed properly but maybe we should leave it was any and ts-expect-error. I added uploadStarted because it was a bug that it was not present.

timer.done()

if (this.opts.validateStatus(ev.target.status, xhr.responseText, xhr)) {
if (this.opts.validateStatus(xhr.status, xhr.responseText, xhr)) {
Copy link
Member Author

Choose a reason for hiding this comment

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

the same as ev.target.status but now TS is happy


if (this.opts.bundle && typeof this.opts.headers === 'function') {
throw new Error(
'`opts.headers` can not be a function when the `bundle: true` option is set.',
Copy link
Member Author

Choose a reason for hiding this comment

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

added a new error instead of a runtime crash.

Comment on lines +31 to +32
// TODO: figure out what else is in this type
xhrUpload?: { headers: Record<string, string> }
Copy link
Member Author

Choose a reason for hiding this comment

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

not sure what this type is supposed to be and why we have it in files and uppy state.

Copy link
Contributor

@aduh95 aduh95 left a comment

Choose a reason for hiding this comment

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

There's a CI failure, otherwise LGTM

packages/@uppy/xhr-upload/src/index.ts Show resolved Hide resolved
packages/@uppy/xhr-upload/src/index.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@aduh95 aduh95 Jan 25, 2024

Choose a reason for hiding this comment

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

Is is OK make that change in a separate PR as it's very likely going to be a pain for AWS as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

If you think this PR is ready to go I can also just merge it in here? If it's blocking and not approved I can do separate PR.

@Murderlon Murderlon requested a review from aduh95 January 26, 2024 09:31
super(uppy, opts)
this.type = 'uploader'
this.id = this.opts.id || 'XHRUpload'
this.title = 'XHRUpload'
Copy link
Contributor

Choose a reason for hiding this comment

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

Just to be sure, we're getting rid of the title property on the none-UIPlugins plugins, correct?

Copy link
Member Author

Choose a reason for hiding this comment

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

Indeed, title was just a copy paste mistake on non-UI plugins.

@Murderlon Murderlon merged commit c51032c into main Jan 29, 2024
16 checks passed
@Murderlon Murderlon deleted the xhr-upload-ts branch January 29, 2024 09:12
@github-actions github-actions bot mentioned this pull request Feb 19, 2024
github-actions bot added a commit that referenced this pull request Feb 19, 2024
| Package                   | Version | Package                   | Version |
| ------------------------- | ------- | ------------------------- | ------- |
| @uppy/audio               |   1.1.5 | @uppy/remote-sources      |   1.1.1 |
| @uppy/aws-s3              |   3.6.1 | @uppy/status-bar          |   3.2.6 |
| @uppy/aws-s3-multipart    |  3.10.1 | @uppy/store-default       |   3.2.1 |
| @uppy/companion           |  4.12.1 | @uppy/store-redux         |   3.0.6 |
| @uppy/companion-client    |   3.7.1 | @uppy/svelte              |   3.1.2 |
| @uppy/compressor          |   1.1.0 | @uppy/thumbnail-generator |   3.0.7 |
| @uppy/core                |   3.9.0 | @uppy/transloadit         |   3.5.0 |
| @uppy/dashboard           |   3.7.2 | @uppy/tus                 |   3.5.1 |
| @uppy/drop-target         |   2.0.3 | @uppy/utils               |   5.7.1 |
| @uppy/form                |   3.1.0 | @uppy/vue                 |   1.1.1 |
| @uppy/golden-retriever    |   3.1.2 | @uppy/webcam              |   3.3.5 |
| @uppy/image-editor        |   2.4.1 | @uppy/xhr-upload          |   3.6.1 |
| @uppy/locales             |   3.5.1 | uppy                      |  3.22.0 |
| @uppy/provider-views      |   3.9.0 |                           |         |

-  @uppy/aws-s3-multipart,@uppy/aws-s3,@uppy/companion-client,@uppy/tus,@uppy/xhr-upload: update `uppyfile` objects before emitting events (antoine du hamel / #4928)
- @uppy/transloadit: add `clientname` option (marius / #4920)
- @uppy/thumbnail-generator: fix broken previews after cropping (evgenia karunus / #4926)
- @uppy/compressor: upgrade compressorjs (merlijn vos / #4924)
- @uppy/companion: fix companion dns and allow redirects from http->https again (mikael finstad / #4895)
- @uppy/dashboard: autoopenfileeditor - rename "edit file" to "edit image" (evgenia karunus / #4925)
- meta: resolve jsx to preact in shared tsconfig (merlijn vos / #4923)
- @uppy/image-editor: image editor: make compressor work after the image editor, too (evgenia karunus / #4918)
- meta: exclude `tsconfig` files from npm bundles (antoine du hamel / #4916)
- @uppy/compressor: migrate to ts (mikael finstad / #4907)
- @uppy/provider-views: update uppy-providerbrowser-viewtype--list.scss (aditya patadia / #4913)
- @uppy/tus: migrate to ts (merlijn vos / #4899)
- meta: bump yarn version (antoine du hamel / #4906)
- meta: validate `defaultoptions` for stricter option types (antoine du hamel / #4901)
- @uppy/dashboard: Uncouple native camera and video buttons from the `disableLocalFiles` option (jake mcallister / #4894)
- meta: put experimental ternaries in .prettierrc.js (merlijn vos / #4900)
- @uppy/xhr-upload: migrate to ts (merlijn vos / #4892)
- @uppy/drop-target: refactor to typescript (artur paikin / #4863)
- meta: fix missing line return in js2ts script (antoine du hamel)
- meta: disable `@typescript-eslint/no-empty-function` lint rule (antoine du hamel / #4891)
- @uppy/companion-client: fix tests and linter (antoine du hamel / #4890)
- @uppy/companion-client: migrate to ts (merlijn vos / #4864)
- meta: prettier 3.0.3 -> 3.2.4 (antoine du hamel / #4889)
- @uppy/image-editor: migrate to ts (merlijn vos / #4880)
- meta: fix race condition in `e2e.yml` (antoine du hamel)
- @uppy/core: add utility type to help define plugin option types (antoine du hamel / #4885)
- meta: merge `output-watcher` and `e2e` workflows (antoine du hamel / #4886)
- @uppy/status-bar: fix `statusbaroptions` type (antoine du hamel / #4883)
- @uppy/core: improve types of .use() (merlijn vos / #4882)
- @uppy/audio: fix `audiooptions` (antoine du hamel / #4884)
- meta: upgrade vite and vitest (antoine du hamel / #4881)
- meta: fix `yarn build:clean` (antoine du hamel)
- @uppy/audio: refactor to typescript (antoine du hamel / #4860)
- @uppy/status-bar: refactor to typescript (antoine du hamel / #4839)
- @uppy/core: add `plugintarget` type and mark options as optional (antoine du hamel / #4874)
- meta: improve output watcher diff (antoine du hamel / #4876)
- meta: minify the output watcher diff further (antoine du hamel)
- meta: remove comments from output watcher (mikael finstad / #4875)
- @uppy/utils: improve types for `finddomelement` (antoine du hamel / #4873)
- @uppy/code: allow plugins to type `pluginstate` (antoine du hamel / #4872)
- meta: build(deps): bump follow-redirects from 1.15.1 to 1.15.4 (dependabot[bot] / #4862)
- meta: add `output-watcher` gha to help check output diff (antoine du hamel / #4868)
- meta: generate locale pack from output file (antoine du hamel / #4867)
- meta: comment on what we want to do about close, resetprogress, clearuploadedfiles, etc in the next major (artur paikin / #4865)
- meta: fix `yarn build:clean` (antoine du hamel / #4866)
- meta: use `explicit-module-boundary-types` lint rule (antoine du hamel / #4858)
- @uppy/form: use requestsubmit (merlijn vos / #4852)
- @uppy/provider-views: add referrerpolicy to images (merlijn vos / #4853)
- @uppy/core: add `debuglogger` as export in manual types (antoine du hamel / #4831)
- meta: fix `js2ts` script (antoine du hamel / #4846)
- @uppy/xhr-upload: show remove button (merlijn vos / #4851)
- meta: upgrade `@transloadit/prettier-bytes` (antoine du hamel / #4850)
- @uppy/core: add missing requiredmetafields key in restrictions (darthf1 / #4819)
- @uppy/companion,@uppy/tus: bump `tus-js-client` version range (merlijn vos / #4848)
- meta: build(deps): bump aws/aws-sdk-php from 3.272.1 to 3.288.1 in /examples/aws-php (dependabot[bot] / #4838)
- @uppy/dashboard: fix `typeerror` when `file.remote` is nullish (antoine du hamel / #4825)
- meta: fix `js2ts` script (antoine du hamel / #4844)
- @uppy/locales: fix "save" button translation in hr_hr.ts (žan žlender / #4830)
- meta: fix linting of `.tsx` files (antoine du hamel / #4843)
- @uppy/core: fix types (antoine du hamel / #4842)
- @uppy/utils: improve `preprocess` and `postprocess` types (antoine du hamel / #4841)
- meta: fix `yarn build:clean` (mikael finstad / #4840)
- meta: dev: remove extensions from vite aliases (antoine du hamel)
- meta: fix `"e2e"` script (antoine du hamel)
- @uppy/core: refactor to ts (murderlon)
- meta: fix typescript ci (antoine du hamel)
- meta: fix clean script (mikael finstad / #4820)
- @uppy/companion-client: fix `typeerror` (antoine du hamel)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants