Skip to content

Commit

Permalink
@uppy/aws-s3,@uppy/aws-s3-multipart: update types (#4611)
Browse files Browse the repository at this point in the history
  • Loading branch information
aduh95 authored Aug 8, 2023
1 parent fa389f2 commit 39e870f
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 59 deletions.
159 changes: 129 additions & 30 deletions packages/@uppy/aws-s3-multipart/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,28 @@ import type { BasePlugin, PluginOptions, UppyFile } from '@uppy/core'

type MaybePromise<T> = T | Promise<T>

export type AwsS3UploadParameters = {
method: 'POST'
url: string
fields: Record<string, string>
expires?: number
headers?: Record<string, string>
} | {
method?: 'PUT'
url: string
fields?: never
expires?: number
headers?: Record<string, string>
}

export interface AwsS3Part {
PartNumber?: number
Size?: number
ETag?: string
}
/**
* @deprecated use {@link AwsS3UploadParameters} instead
*/
export interface AwsS3SignedPart {
url: string
headers?: Record<string, string>
Expand All @@ -22,44 +39,126 @@ export interface AwsS3STSResponse {
region: string
}

export interface AwsS3MultipartOptions extends PluginOptions {
companionHeaders?: { [type: string]: string }
companionUrl?: string
companionCookiesRule?: string
type AWSS3NonMultipartWithCompanionMandatory = {
getUploadParameters?: never
}

type AWSS3NonMultipartWithoutCompanionMandatory = {
getUploadParameters: (
file: UppyFile
) => MaybePromise<AwsS3UploadParameters>
}
type AWSS3NonMultipartWithCompanion = AWSS3WithCompanion &
AWSS3NonMultipartWithCompanionMandatory &
{
shouldUseMultipart: false
createMultipartUpload?: never
listParts?: never
signPart?: never
abortMultipartUpload?: never
completeMultipartUpload?: never
}

type AWSS3NonMultipartWithoutCompanion = AWSS3WithoutCompanion &
AWSS3NonMultipartWithoutCompanionMandatory &
{
shouldUseMultipart: false
createMultipartUpload?: never
listParts?: never
signPart?: never
abortMultipartUpload?: never
completeMultipartUpload?: never
}

type AWSS3MultipartWithCompanionMandatory = {
getChunkSize?: (file: UppyFile) => number
createMultipartUpload?: never
listParts?: never
signPart?: never
abortMultipartUpload?: never
completeMultipartUpload?: never
}
type AWSS3MultipartWithoutCompanionMandatory = {
getChunkSize?: (file: UppyFile) => number
createMultipartUpload: (
file: UppyFile
) => MaybePromise<{ uploadId: string; key: string }>
listParts: (
file: UppyFile,
opts: { uploadId: string; key: string; signal: AbortSignal }
) => MaybePromise<AwsS3Part[]>
signPart: (
file: UppyFile,
opts: { uploadId: string; key: string; partNumber: number; body: Blob; signal: AbortSignal }
) => MaybePromise<AwsS3UploadParameters>
abortMultipartUpload: (
file: UppyFile,
opts: { uploadId: string; key: string; signal: AbortSignal }
) => MaybePromise<void>
completeMultipartUpload: (
file: UppyFile,
opts: { uploadId: string; key: string; parts: AwsS3Part[]; signal: AbortSignal }
) => MaybePromise<{ location?: string }>
}
type AWSS3MultipartWithoutCompanion = AWSS3WithoutCompanion &
AWSS3MultipartWithoutCompanionMandatory &
{
shouldUseMultipart?: true
getUploadParameters?: never
}

type AWSS3MultipartWithCompanion = AWSS3WithCompanion &
AWSS3MultipartWithCompanionMandatory &
{
shouldUseMultipart?: true
getUploadParameters?: never
}

type AWSS3MaybeMultipartWithCompanion = AWSS3WithCompanion &
AWSS3MultipartWithCompanionMandatory &
AWSS3NonMultipartWithCompanionMandatory &
{
shouldUseMultipart: ((file: UppyFile) => boolean)
}

type AWSS3MaybeMultipartWithoutCompanion = AWSS3WithoutCompanion &
AWSS3MultipartWithoutCompanionMandatory &
AWSS3NonMultipartWithoutCompanionMandatory &
{
shouldUseMultipart: ((file: UppyFile) => boolean)
}

type AWSS3WithCompanion = {
companionUrl: string
companionHeaders?: Record<string, string>
companionCookiesRule?: string
getTemporarySecurityCredentials?: true
}
type AWSS3WithoutCompanion = {
companionUrl?: never
companionHeaders?: never
companionCookiesRule?: never
getTemporarySecurityCredentials?: (options?: {signal?: AbortSignal}) => MaybePromise<AwsS3STSResponse>
}

interface _AwsS3MultipartOptions extends PluginOptions {
allowedMetaFields?: string[] | null
getChunkSize?: (file: UppyFile) => number
createMultipartUpload?: (
file: UppyFile
) => MaybePromise<{ uploadId: string; key: string }>
listParts?: (
file: UppyFile,
opts: { uploadId: string; key: string; signal: AbortSignal }
) => MaybePromise<AwsS3Part[]>
signPart?: (
file: UppyFile,
opts: { uploadId: string; key: string; partNumber: number; body: Blob; signal: AbortSignal }
) => MaybePromise<AwsS3SignedPart>
limit?: number
retryDelays?: number[] | null
/** @deprecated Use signPart instead */
prepareUploadParts?: (
file: UppyFile,
partData: { uploadId: string; key: string; parts: [{ number: number, chunk: Blob }] }
) => MaybePromise<{ presignedUrls: Record<number, string>, headers?: Record<number, Record<string, string>> }>
abortMultipartUpload?: (
file: UppyFile,
opts: { uploadId: string; key: string; signal: AbortSignal }
) => MaybePromise<void>
completeMultipartUpload?: (
file: UppyFile,
opts: { uploadId: string; key: string; parts: AwsS3Part[]; signal: AbortSignal }
) => MaybePromise<{ location?: string }>
limit?: number
shouldUseMultipart?: boolean | ((file: UppyFile) => boolean)
retryDelays?: number[] | null
getUploadParameters?: (
file: UppyFile
) => MaybePromise<{ url: string }>
}

export type AwsS3MultipartOptions = _AwsS3MultipartOptions & (AWSS3NonMultipartWithCompanion |
AWSS3NonMultipartWithoutCompanion |
AWSS3MultipartWithCompanion |
AWSS3MultipartWithoutCompanion |
AWSS3MaybeMultipartWithCompanion |
AWSS3MaybeMultipartWithoutCompanion)

declare class AwsS3Multipart extends BasePlugin<
AwsS3MultipartOptions
> {}
Expand Down
20 changes: 11 additions & 9 deletions packages/@uppy/aws-s3-multipart/types/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { AwsS3Part } from '..'
{
const uppy = new Uppy()
uppy.use(AwsS3Multipart, {
shouldUseMultipart: true,
createMultipartUpload (file) {
expectType<UppyFile>(file)
return { uploadId: '', key: '' }
Expand All @@ -17,12 +18,13 @@ import type { AwsS3Part } from '..'
expectType<string>(opts.key)
return []
},
prepareUploadParts (file, partData) {
signPart (file, opts) {
expectType<UppyFile>(file)
expectType<string>(partData.uploadId)
expectType<string>(partData.key)
expectType<[{number: number, chunk: Blob}]>(partData.parts)
return { presignedUrls: {} }
expectType<string>(opts.uploadId)
expectType<string>(opts.key)
expectType<Blob>(opts.body)
expectType<AbortSignal>(opts.signal)
return { url: '' }
},
abortMultipartUpload (file, opts) {
expectType<UppyFile>(file)
Expand All @@ -41,8 +43,8 @@ import type { AwsS3Part } from '..'

{
const uppy = new Uppy()
expectError(uppy.use(AwsS3Multipart, { getChunkSize: 100 }))
expectError(uppy.use(AwsS3Multipart, { getChunkSize: () => 'not a number' }))
uppy.use(AwsS3Multipart, { getChunkSize: () => 100 })
uppy.use(AwsS3Multipart, { getChunkSize: (file) => file.size })
expectError(uppy.use(AwsS3Multipart, { companionUrl: '', getChunkSize: 100 }))
expectError(uppy.use(AwsS3Multipart, { companionUrl: '', getChunkSize: () => 'not a number' }))
uppy.use(AwsS3Multipart, { companionUrl: '', getChunkSize: () => 100 })
uppy.use(AwsS3Multipart, { companionUrl: '', getChunkSize: (file) => file.size })
}
37 changes: 19 additions & 18 deletions packages/@uppy/aws-s3/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
import { AwsS3MultipartOptions } from '@uppy/aws-s3-multipart'
import type { BasePlugin, Locale, PluginOptions, UppyFile } from '@uppy/core'

type MaybePromise<T> = T | Promise<T>

export interface AwsS3UploadParameters {
method?: string
url: string
fields?: { [type: string]: string }
headers?: { [type: string]: string }
export type AwsS3UploadParameters = {
method?: 'POST'
url: string
fields?: Record<string, string>
expires?: number
headers?: Record<string, string>
} | {
method: 'PUT'
url: string
fields?: never
expires?: number
headers?: Record<string, string>
}

export interface AwsS3Options extends PluginOptions {
interface LegacyAwsS3Options extends PluginOptions {
shouldUseMultipart?: never
companionUrl?: string | null
companionHeaders?: Record<string, string>
allowedMetaFields?: Array<string> | null
getUploadParameters?: (file: UppyFile) => MaybePromise<{
method?: 'POST'
url: string
fields?: Record<string, string>
headers?: Record<string, string>
} | {
method: 'PUT'
url: string
fields: never
headers?: Record<string, string>
}>
getUploadParameters?: (file: UppyFile) => MaybePromise<AwsS3UploadParameters>
limit?: number
/** @deprecated this option will not be supported in future versions of this plugin */
getResponseData?: (responseText: string, response: XMLHttpRequest) => void
locale?: Locale,
timeout?: number
}
}

export type AwsS3Options = LegacyAwsS3Options | AwsS3MultipartOptions;

declare class AwsS3 extends BasePlugin<AwsS3Options> {}

Expand Down
63 changes: 61 additions & 2 deletions packages/@uppy/aws-s3/types/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,72 @@
import { Uppy, UppyFile } from '@uppy/core'
import { expectType } from 'tsd'
import { expectType, expectError } from 'tsd'
import type { AwsS3Part } from '@uppy/aws-s3-multipart'
import AwsS3 from '..'

{
const uppy = new Uppy()
uppy.use(AwsS3, {
getUploadParameters (file) {
expectType<UppyFile>(file)
return { method: 'POST', url: '', fields: {}, headers: {} }
return { method: 'POST', url: '' }
},
})
expectError(uppy.use(AwsS3, {
shouldUseMultipart: false,
getUploadParameters (file) {
expectType<UppyFile>(file)
return { method: 'POST', url: '' }
},
}))
uppy.use(AwsS3, {
shouldUseMultipart: false,
getUploadParameters (file) {
expectType<UppyFile>(file)
return { method: 'POST', url: '', fields: {} }
},
})
expectError(uppy.use(AwsS3, {
shouldUseMultipart: true,
getUploadParameters (file) {
expectType<UppyFile>(file)
return { method: 'PUT', url: '' }
},
}))
uppy.use(AwsS3, {
shouldUseMultipart: () => Math.random() > 0.5,
getUploadParameters (file) {
expectType<UppyFile>(file)
return { method: 'PUT', url: '' }
},
createMultipartUpload (file) {
expectType<UppyFile>(file)
return { uploadId: '', key: '' }
},
listParts (file, opts) {
expectType<UppyFile>(file)
expectType<string>(opts.uploadId)
expectType<string>(opts.key)
return []
},
signPart (file, opts) {
expectType<UppyFile>(file)
expectType<string>(opts.uploadId)
expectType<string>(opts.key)
expectType<Blob>(opts.body)
expectType<AbortSignal>(opts.signal)
return { url: '' }
},
abortMultipartUpload (file, opts) {
expectType<UppyFile>(file)
expectType<string>(opts.uploadId)
expectType<string>(opts.key)
},
completeMultipartUpload (file, opts) {
expectType<UppyFile>(file)
expectType<string>(opts.uploadId)
expectType<string>(opts.key)
expectType<AwsS3Part>(opts.parts[0])
return {}
},
})
}

0 comments on commit 39e870f

Please sign in to comment.