Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/providers/interface/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ export abstract class StorageServiceProvider<ID> {
expiresIn: ExpiresIn
): SignedUploadUrlRequest<ID>

abstract getData(fileId: ID): GetDataRequest<ID>
/**
*
* @param fileId
* @param optimistic If true, the provider will return the data without checking the existence of the file
*/
abstract getData(fileId: ID, optimistic?: boolean): GetDataRequest<ID>

abstract delete(fileId: ID): DeleteRequest
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ describe('S3ProviderConfigurationParser', () => {
bucketPath: [bareMinimumConfig.bucketPath],
},
acl: ObjectCannedACL.bucket_owner_full_control,
optimisticFileDataResponse: true,
})
})

Expand Down
65 changes: 40 additions & 25 deletions packages/providers/s3/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,53 +97,68 @@ export class S3Provider<ID> extends StorageServiceProvider<ID> {
}
}

private async createFileUrls(fileId: ID): Promise<string[]> {
if (!this.configuration.optimisticFileDataResponse) {
const existingKeys = await this.buckets.resource.existingKeys(
fileId
)
private async createFileUrls(
fileId: ID,
optimistic: boolean
): Promise<string[]> {
if (optimistic) {
return this.buckets.resource.getSignedDownloadUrls(fileId)
}

if (existingKeys.length === 0) {
return []
} else {
return this.buckets.resource.getSignedDownloadUrls(
fileId,
existingKeys as unknown as S3ResourceBucketPath
)
}
const existingKeys = await this.buckets.resource.existingKeys(fileId)

if (existingKeys.length > 0) {
return this.buckets.resource.getSignedDownloadUrls(
fileId,
existingKeys as unknown as S3ResourceBucketPath
)
}

return this.buckets.resource.getSignedDownloadUrls(fileId)
return []
}

async getData(fileId: ID): GetDataRequest<ID> {
async getData(fileId: ID, optimistic = false): GetDataRequest<ID> {
// TODO: Refactor the file check

const variants = await this.createFileUrls(fileId)
const variants = await this.createFileUrls(fileId, optimistic)

if (variants.length === 0) {
if (
variants.length ===
this.configuration.resourceBucket.bucketPath.length
) {
return {
id: fileId,
variants: [],
status: FileStatus.NOT_FOUND,
variants,
status: FileStatus.PROCESSED,
}
}

if (
variants.length !==
this.configuration.resourceBucket.bucketPath.length
) {
if (variants.length > 0) {
return {
id: fileId,
variants,
status: FileStatus.UPLOADED,
}
}

if (!optimistic && !this.buckets.upload.equals(this.buckets.resource)) {
const existsInUploadBucket = await this.buckets.upload.keyExists(
this.buckets.upload.keyResolver.resolve(fileId)
)

if (existsInUploadBucket) {
return {
id: fileId,
variants: [],
status: FileStatus.UPLOADED,
}
}
}

return {
id: fileId,
variants,
status: FileStatus.PROCESSED,
variants: [],
status: FileStatus.NOT_FOUND,
}
}

Expand Down
9 changes: 0 additions & 9 deletions packages/providers/s3/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,6 @@ export interface S3ProviderConfiguration extends S3DefaultBucketConfiguration {
* @see https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl
*/
acl?: ObjectCannedACL
/**
* Whether the file response should be optimistic or not.
*
* @default true
* @description If set to false it will make an additional request to the S3 API to check if the file exists.
* If the file does not exist, the `status` property of the response will be set to `NOT_FOUND`.
* If the file does exist, the `status` property of the response will be set to `PROCESSED`.
*/
optimisticFileDataResponse?: boolean
}

export interface S3ProviderConfigurationParsed
Expand Down
24 changes: 23 additions & 1 deletion packages/providers/s3/src/utils/s3-bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
import { ExpiresIn } from 'shared-types'
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'

class S3Bucket<
abstract class S3Bucket<
Config extends
| Required<S3DefaultBucketConfiguration>
| Required<S3ResourceBucketConfiguration>,
Expand All @@ -42,6 +42,12 @@ class S3Bucket<
this.path = s3Config.bucketPath
}

abstract equals(
bucket: this extends S3UploadBucket<ID>
? S3ResourceBucket<ID>
: S3UploadBucket<ID>
): boolean

async keyExists(
key: string,
commandInput?: Omit<HeadObjectCommandInput, 'Bucket' | 'Key'>
Expand Down Expand Up @@ -72,6 +78,14 @@ export class S3UploadBucket<ID> extends S3Bucket<
Required<S3DefaultBucketConfiguration>,
ID
> {
equals(bucket: S3ResourceBucket<ID>): boolean {
return (
this.name === bucket.name &&
this.region === bucket.region &&
this.path === bucket.path[0]
)
}

async getSignedUploadUrl(
fileId: ID,
expiresIn: ExpiresIn,
Expand All @@ -93,6 +107,14 @@ export class S3ResourceBucket<ID> extends S3Bucket<
Required<S3ResourceBucketConfiguration>,
ID
> {
equals(bucket: S3UploadBucket<ID>): boolean {
return (
this.name === bucket.name &&
this.region === bucket.region &&
this.path[0] === bucket.path
)
}

async getSignedDownloadUrl(
key: string,
commandInput?: Omit<GetObjectCommandInput, 'Bucket' | 'Key'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export class S3ProviderConfigurationParser {
bucketPath: z.array(z.string()).nonempty(),
}),
acl: z.nativeEnum(ObjectCannedACL),
optimisticFileDataResponse: z.boolean(),
}
)

Expand Down Expand Up @@ -86,8 +85,6 @@ export class S3ProviderConfigurationParser {
...s3DefaultBucketConfiguration,
resourceBucket: s3DefaultResourceBucketConfiguration,
acl: configuration.acl ?? ObjectCannedACL.bucket_owner_full_control,
optimisticFileDataResponse:
configuration.optimisticFileDataResponse ?? true,
}
}
}
3 changes: 2 additions & 1 deletion packages/server/core/src/upload-wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ export class UploadWizard<ID = DefaultID> {

async getData(fileId: ID): Promise<MediaFile<ID>> {
const { status, variants } = await this.storageServiceProvider.getData(
fileId
fileId,
true
)

if (status === FileStatus.NOT_FOUND) {
Expand Down