From b076fae59236735b0bf9c0200d5a86487c1e4bf2 Mon Sep 17 00:00:00 2001 From: Mitja P Date: Wed, 5 Feb 2025 22:05:10 +0100 Subject: [PATCH 1/4] @tus/s3-store: add `maxMultipartParts` option --- packages/s3-store/src/index.ts | 11 +++++++++-- packages/s3-store/test/index.ts | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/s3-store/src/index.ts b/packages/s3-store/src/index.ts index 7d10f016..b589394c 100644 --- a/packages/s3-store/src/index.ts +++ b/packages/s3-store/src/index.ts @@ -37,6 +37,10 @@ export type Options = { * Can not be lower than 5MiB or more than 5GiB. */ minPartSize?: number + /** + * The maximum number of parts allowed in a multipart upload. Defaults to 10,000. + */ + maxMultipartParts?: number useTags?: boolean maxConcurrentPartUploads?: number cache?: KvStore @@ -97,13 +101,13 @@ export class S3Store extends DataStore { protected expirationPeriodInMilliseconds = 0 protected useTags = true protected partUploadSemaphore: Semaphore - public maxMultipartParts = 10_000 as const + public maxMultipartParts = 10_000 public minPartSize = 5_242_880 // 5MiB public maxUploadSize = 5_497_558_138_880 as const // 5TiB constructor(options: Options) { super() - const {partSize, minPartSize, s3ClientConfig} = options + const { maxMultipartParts, partSize, minPartSize, s3ClientConfig } = options const {bucket, ...restS3ClientConfig} = s3ClientConfig this.extensions = [ 'creation', @@ -117,6 +121,9 @@ export class S3Store extends DataStore { if (minPartSize) { this.minPartSize = minPartSize } + if (maxMultipartParts) { + this.maxMultipartParts = maxMultipartParts + } this.expirationPeriodInMilliseconds = options.expirationPeriodInMilliseconds ?? 0 this.useTags = options.useTags ?? true this.cache = options.cache ?? new MemoryKvStore() diff --git a/packages/s3-store/test/index.ts b/packages/s3-store/test/index.ts index 014892f3..54a714f3 100644 --- a/packages/s3-store/test/index.ts +++ b/packages/s3-store/test/index.ts @@ -278,6 +278,22 @@ describe('S3DataStore', () => { } }) + it.only('should use default maxMultipartParts when not specified', function () { + const store = new S3Store({ + s3ClientConfig, + }) + assert.equal(store.maxMultipartParts, 10000) + }) + + it.only('should use custom maxMultipartParts when specified', function () { + const customMaxParts = 5000 + const store = new S3Store({ + s3ClientConfig, + maxMultipartParts: customMaxParts, + }) + assert.equal(store.maxMultipartParts, customMaxParts) + }) + shared.shouldHaveStoreMethods() shared.shouldCreateUploads() shared.shouldRemoveUploads() // Termination extension From b8c3605441841a0408d8d46cd21a240e3840d766 Mon Sep 17 00:00:00 2001 From: Mitja P Date: Wed, 5 Feb 2025 22:23:08 +0100 Subject: [PATCH 2/4] Add changeset entry --- .changeset/tricky-emus-fail.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tricky-emus-fail.md diff --git a/.changeset/tricky-emus-fail.md b/.changeset/tricky-emus-fail.md new file mode 100644 index 00000000..679fd026 --- /dev/null +++ b/.changeset/tricky-emus-fail.md @@ -0,0 +1,5 @@ +--- +"@tus/s3-store": minor +--- + +Add `maxMultipartParts` option. This can be used when using S3-compatible storage provider with different part number limitations. From 3acb76d699db0a57a12797ff8a9bb74799bc50d7 Mon Sep 17 00:00:00 2001 From: Mitja P Date: Wed, 5 Feb 2025 22:29:52 +0100 Subject: [PATCH 3/4] remove .only keyword in test --- packages/s3-store/test/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/s3-store/test/index.ts b/packages/s3-store/test/index.ts index 54a714f3..4a8e31af 100644 --- a/packages/s3-store/test/index.ts +++ b/packages/s3-store/test/index.ts @@ -278,14 +278,14 @@ describe('S3DataStore', () => { } }) - it.only('should use default maxMultipartParts when not specified', function () { + it('should use default maxMultipartParts when not specified', function () { const store = new S3Store({ s3ClientConfig, }) assert.equal(store.maxMultipartParts, 10000) }) - it.only('should use custom maxMultipartParts when specified', function () { + it('should use custom maxMultipartParts when specified', function () { const customMaxParts = 5000 const store = new S3Store({ s3ClientConfig, From f3ee9d2bde3618bb10f4200230057f7362729165 Mon Sep 17 00:00:00 2001 From: Mitja P Date: Wed, 5 Feb 2025 22:37:01 +0100 Subject: [PATCH 4/4] fix formatting --- packages/s3-store/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/s3-store/src/index.ts b/packages/s3-store/src/index.ts index b589394c..40e1367c 100644 --- a/packages/s3-store/src/index.ts +++ b/packages/s3-store/src/index.ts @@ -107,7 +107,7 @@ export class S3Store extends DataStore { constructor(options: Options) { super() - const { maxMultipartParts, partSize, minPartSize, s3ClientConfig } = options + const {maxMultipartParts, partSize, minPartSize, s3ClientConfig} = options const {bucket, ...restS3ClientConfig} = s3ClientConfig this.extensions = [ 'creation',