@uppy/aws-s3: refactor to private fields (#3076)

This commit is contained in:
Antoine du Hamel 2021-08-09 15:54:03 +02:00 committed by GitHub
parent efde0eb76b
commit 0f9709bb10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -26,10 +26,8 @@
*/
const { BasePlugin } = require('@uppy/core')
const Translator = require('@uppy/utils/lib/Translator')
const { RateLimitedQueue, internalRateLimitedQueue } = require('@uppy/utils/lib/RateLimitedQueue')
const settle = require('@uppy/utils/lib/settle')
const hasProperty = require('@uppy/utils/lib/hasProperty')
const { RequestClient } = require('@uppy/companion-client')
const MiniXHRUpload = require('./MiniXHRUpload')
const isXml = require('./isXml')
@ -62,12 +60,49 @@ function assertServerError (res) {
return res
}
function validateParameters (file, params) {
const valid = params != null
&& typeof params.url === 'string'
&& (typeof params.fields === 'object' || params.fields == null)
if (!valid) {
const err = new TypeError(`AwsS3: got incorrect result from 'getUploadParameters()' for file '${file.name}', expected an object '{ url, method, fields, headers }' but got '${JSON.stringify(params)}' instead.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format.`)
throw err
}
const methodIsValid = params.method == null || /^p(u|os)t$/i.test(params.method)
if (!methodIsValid) {
const err = new TypeError(`AwsS3: got incorrect method from 'getUploadParameters()' for file '${file.name}', expected 'put' or 'post' but got '${params.method}' instead.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format.`)
throw err
}
}
// Get the error data from a failed XMLHttpRequest instance.
// `content` is the S3 response as a string.
// `xhr` is the XMLHttpRequest instance.
function defaultGetResponseError (content, xhr) {
// If no response, we don't have a specific error message, use the default.
if (!isXml(content, xhr)) {
return undefined
}
const error = getXmlValue(content, 'Message')
return new Error(error)
}
// warning deduplication flag: see `getResponseData()` XHRUpload option definition
let warnedSuccessActionStatus = false
module.exports = class AwsS3 extends BasePlugin {
// eslint-disable-next-line global-require
static VERSION = require('../package.json').version
#client
#requests
#uploader
constructor (uppy, opts) {
super(uppy, opts)
this.type = 'uploader'
@ -89,9 +124,8 @@ module.exports = class AwsS3 extends BasePlugin {
this.opts = { ...defaultOptions, ...opts }
this.client = new RequestClient(uppy, opts)
this.handleUpload = this.handleUpload.bind(this)
this.requests = new RateLimitedQueue(this.opts.limit)
this.#client = new RequestClient(uppy, opts)
this.#requests = new RateLimitedQueue(this.opts.limit)
}
getUploadParameters (file) {
@ -108,31 +142,11 @@ module.exports = class AwsS3 extends BasePlugin {
)
const query = new URLSearchParams({ filename, type, ...metadata })
return this.client.get(`s3/params?${query}`)
return this.#client.get(`s3/params?${query}`)
.then(assertServerError)
}
validateParameters (file, params) {
const valid = typeof params === 'object' && params
&& typeof params.url === 'string'
&& (typeof params.fields === 'object' || params.fields == null)
if (!valid) {
const err = new TypeError(`AwsS3: got incorrect result from 'getUploadParameters()' for file '${file.name}', expected an object '{ url, method, fields, headers }' but got '${JSON.stringify(params)}' instead.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format.`)
console.error(err)
throw err
}
const methodIsValid = params.method == null || /^(put|post)$/i.test(params.method)
if (!methodIsValid) {
const err = new TypeError(`AwsS3: got incorrect method from 'getUploadParameters()' for file '${file.name}', expected 'put' or 'post' but got '${params.method}' instead.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format.`)
console.error(err)
throw err
}
}
handleUpload (fileIDs) {
#handleUpload = (fileIDs) => {
/**
* keep track of `getUploadParameters()` responses
* so we can cancel the calls individually using just a file ID
@ -143,9 +157,7 @@ module.exports = class AwsS3 extends BasePlugin {
function onremove (file) {
const { id } = file
if (hasProperty(paramsPromises, id)) {
paramsPromises[id].abort()
}
paramsPromises[id]?.abort()
}
this.uppy.on('file-removed', onremove)
@ -154,7 +166,7 @@ module.exports = class AwsS3 extends BasePlugin {
this.uppy.emit('upload-started', file)
})
const getUploadParameters = this.requests.wrapPromiseFunction((file) => {
const getUploadParameters = this.#requests.wrapPromiseFunction((file) => {
return this.opts.getUploadParameters(file)
})
@ -166,7 +178,7 @@ module.exports = class AwsS3 extends BasePlugin {
delete paramsPromises[id]
const file = this.uppy.getFile(id)
this.validateParameters(file, params)
validateParameters(file, params)
const {
method = 'post',
@ -190,23 +202,22 @@ module.exports = class AwsS3 extends BasePlugin {
xhrUpload: xhrOpts,
})
return this._uploader.uploadFile(file.id, index, numberOfFiles)
return this.#uploader.uploadFile(file.id, index, numberOfFiles)
}).catch((error) => {
delete paramsPromises[id]
const file = this.uppy.getFile(id)
this.uppy.emit('upload-error', file, error)
})
})).then((settled) => {
})).finally(() => {
// cleanup.
this.uppy.off('file-removed', onremove)
return settled
})
}
install () {
const { uppy } = this
this.uppy.addUploader(this.handleUpload)
uppy.addUploader(this.#handleUpload)
// Get the response data from a successful XMLHttpRequest instance.
// `content` is the S3 response as a string.
@ -247,24 +258,12 @@ module.exports = class AwsS3 extends BasePlugin {
}
}
// Get the error data from a failed XMLHttpRequest instance.
// `content` is the S3 response as a string.
// `xhr` is the XMLHttpRequest instance.
function defaultGetResponseError (content, xhr) {
// If no response, we don't have a specific error message, use the default.
if (!isXml(content, xhr)) {
return
}
const error = getXmlValue(content, 'Message')
return new Error(error)
}
const xhrOptions = {
fieldName: 'file',
responseUrlFieldName: 'location',
timeout: this.opts.timeout,
// Share the rate limiting queue with XHRUpload.
[internalRateLimitedQueue]: this.requests,
[internalRateLimitedQueue]: this.#requests,
responseType: 'text',
getResponseData: this.opts.getResponseData || defaultGetResponseData,
getResponseError: defaultGetResponseError,
@ -273,12 +272,12 @@ module.exports = class AwsS3 extends BasePlugin {
// Only for MiniXHRUpload, remove once we can depend on XHRUpload directly again
xhrOptions.i18n = this.i18n
// Revert to `this.uppy.use(XHRUpload)` once the big comment block at the top of
// Revert to `uppy.use(XHRUpload)` once the big comment block at the top of
// this file is solved
this._uploader = new MiniXHRUpload(this.uppy, xhrOptions)
this.#uploader = new MiniXHRUpload(uppy, xhrOptions)
}
uninstall () {
this.uppy.removeUploader(this.handleUpload)
this.uppy.removeUploader(this.#handleUpload)
}
}