I’m developing an uploading system using Uppy and a Tus server, and I want to upload files to a specific structure within my S3 bucket. I attempted to override the CustomS3Store and implemented a create function where I updated the upload.id to reflect the desired structure, like uploads/filename. However, this approach resulted in an error.
While the info file was created in the correct structure, I encountered a 404 error during the patching process. It appears that the id is being treated as a URL.
To address this, I overrode the getKey, infoKey, uploadIdKey, and partKey function of the S3 store. Although this successfully created the info file in the correct structure, the uploaded file itself ended up being saved in the root directory of the S3 bucket.
// Override the key generation for the actual file
getKey(id) {
return this.uploadPrefix + id;
}
// Override info file key generation
infoKey(id) {
return this.uploadPrefix + id + '.info';
}
// Override part file key generation
partKey(id, withDirectory = false) {
return this.uploadPrefix + id + '.part';
}
// Override the uploadId key generation
uploadIdKey(id) {
return this.uploadPrefix + id + '.uploadId';
}
I attempted another approach by overriding the entire create function to return the upload with a specific storage path. However, I encountered the same 404 error as before. This time, it even failed to create the info file.
async create(upload) {
try {
const filename = upload.metadata?.filename
? encodeURIComponent(upload.metadata.filename.replace(/[^a-zA-Z0-9.-]/g, '_'))
: 'unknown';
const uniqueId = Math.random().toString(36).substring(2);
upload.id = `${uniqueId}-${filename}`;
// Important: Don't include uploadPrefix in the upload.id
upload.storage = {
type: 's3',
bucket: this.bucket,
key: this.getKey(upload.id),
path: this.getKey(upload.id)
};
console.log('Creating upload:', {
id: upload.id,
storage: upload.storage,
metadata: upload.metadata
});
const request = {
Bucket: this.bucket,
Key: upload.storage.key,
Metadata: {
'tus-version': '1.0.0',
...upload.metadata
}
};
if (upload.metadata?.contentType) {
request.ContentType = upload.metadata.contentType;
}
const res = await this.client.createMultipartUpload(request);
upload.storage.uploadId = res.UploadId;
return upload;
} catch (error) {
console.error('Error in create:', error);
throw error;
}
}
How can I solve this problem?