From f60b1fbebe43f0d0cf0a5d0b4391bbd44605f426 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Mon, 9 Sep 2024 15:46:31 -0700 Subject: [PATCH] refactor(storage): add client standard remove api --- .../client/apis/advanced/remove.test.ts | 12 ++++ .../__tests__/client/apis/remove.test.ts | 12 ++++ .../storage/src/client/apis/advanced/index.ts | 5 ++ .../src/client/apis/advanced/remove.ts | 29 ++++++++ .../src/client/apis/advanced/types/index.ts | 4 ++ .../src/client/apis/advanced/types/inputs.ts | 56 +++++++++++++++ .../src/client/apis/advanced/types/options.ts | 13 ++++ .../src/client/apis/advanced/types/outputs.ts | 2 + packages/storage/src/client/apis/index.ts | 5 ++ packages/storage/src/client/apis/remove.ts | 68 +++++++++++++++++++ .../storage/src/client/apis/types/index.ts | 6 ++ .../storage/src/client/apis/types/inputs.ts | 5 ++ .../storage/src/client/apis/types/outputs.ts | 8 +++ .../src/client/apis/utils/constants.ts | 5 ++ .../storage/src/client/apis/utils/index.ts | 6 ++ .../apis/utils/resolveS3ConfigAndInput.ts | 6 ++ .../utils/validateStorageOperationInput.ts | 5 ++ packages/storage/src/utils/index.ts | 1 + packages/storage/src/utils/userAgent.ts | 5 ++ 19 files changed, 253 insertions(+) create mode 100644 packages/storage/__tests__/client/apis/advanced/remove.test.ts create mode 100644 packages/storage/__tests__/client/apis/remove.test.ts create mode 100644 packages/storage/src/client/apis/advanced/index.ts create mode 100644 packages/storage/src/client/apis/advanced/remove.ts create mode 100644 packages/storage/src/client/apis/advanced/types/index.ts create mode 100644 packages/storage/src/client/apis/advanced/types/inputs.ts create mode 100644 packages/storage/src/client/apis/advanced/types/options.ts create mode 100644 packages/storage/src/client/apis/advanced/types/outputs.ts create mode 100644 packages/storage/src/client/apis/index.ts create mode 100644 packages/storage/src/client/apis/remove.ts create mode 100644 packages/storage/src/client/apis/types/index.ts create mode 100644 packages/storage/src/client/apis/types/inputs.ts create mode 100644 packages/storage/src/client/apis/types/outputs.ts create mode 100644 packages/storage/src/client/apis/utils/constants.ts create mode 100644 packages/storage/src/client/apis/utils/index.ts create mode 100644 packages/storage/src/client/apis/utils/resolveS3ConfigAndInput.ts create mode 100644 packages/storage/src/client/apis/utils/validateStorageOperationInput.ts create mode 100644 packages/storage/src/utils/userAgent.ts diff --git a/packages/storage/__tests__/client/apis/advanced/remove.test.ts b/packages/storage/__tests__/client/apis/advanced/remove.test.ts new file mode 100644 index 00000000000..c80929e70b3 --- /dev/null +++ b/packages/storage/__tests__/client/apis/advanced/remove.test.ts @@ -0,0 +1,12 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// TODO(ashwinkumar6): add tests for client advanced API utils +describe('remove advanced API', () => { + describe('Happy Cases', () => { + it.todo('Should call foundational remove API once with correct params'); + }); + describe('Error Cases', () => { + it.todo('Should throw if underlying foundational API throws'); + }); +}); diff --git a/packages/storage/__tests__/client/apis/remove.test.ts b/packages/storage/__tests__/client/apis/remove.test.ts new file mode 100644 index 00000000000..554c67a9480 --- /dev/null +++ b/packages/storage/__tests__/client/apis/remove.test.ts @@ -0,0 +1,12 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// TODO(ashwinkumar6): add tests for client standard API utils +describe('remove standard API', () => { + describe('Happy Cases', () => { + it.todo('Should call advanced remove API once with correct params'); + }); + describe('Error Cases', () => { + it.todo('Should throw if underlying advanced API throws'); + }); +}); diff --git a/packages/storage/src/client/apis/advanced/index.ts b/packages/storage/src/client/apis/advanced/index.ts new file mode 100644 index 00000000000..9edad5f568b --- /dev/null +++ b/packages/storage/src/client/apis/advanced/index.ts @@ -0,0 +1,5 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// public advanced APIs +export { remove } from './remove'; diff --git a/packages/storage/src/client/apis/advanced/remove.ts b/packages/storage/src/client/apis/advanced/remove.ts new file mode 100644 index 00000000000..04f0bd44735 --- /dev/null +++ b/packages/storage/src/client/apis/advanced/remove.ts @@ -0,0 +1,29 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// TODO(ashwinkumar6): import from foundational API +import { deleteObject } from '../../../providers/s3/utils/client/s3data'; + +import { GetPropertiesInput } from './types'; + +export const remove = async (input: GetPropertiesInput): Promise => { + const { bucket, credentialsProvider, path, options } = input; + const { useAccelerateEndpoint, customEndpoint, customUserAgent } = + options ?? {}; + + // TODO(ashwinkumar6): move service call to foundation + // TODO(ashwinkumar6): 'customHeaders' input isn't wired up + await deleteObject( + { + credentials: (await credentialsProvider()).credentials, + region: bucket.region, + userAgentValue: customUserAgent, + useAccelerateEndpoint, + customEndpoint, + }, + { + Bucket: bucket.bucketName, + Key: path, + }, + ); +}; diff --git a/packages/storage/src/client/apis/advanced/types/index.ts b/packages/storage/src/client/apis/advanced/types/index.ts new file mode 100644 index 00000000000..b4ffb185857 --- /dev/null +++ b/packages/storage/src/client/apis/advanced/types/index.ts @@ -0,0 +1,4 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +export { GetPropertiesInput } from './inputs'; diff --git a/packages/storage/src/client/apis/advanced/types/inputs.ts b/packages/storage/src/client/apis/advanced/types/inputs.ts new file mode 100644 index 00000000000..08bc726017f --- /dev/null +++ b/packages/storage/src/client/apis/advanced/types/inputs.ts @@ -0,0 +1,56 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { BucketInfo, CredentialsProvider } from './options'; + +// TODO(aswhinkumar6): finalize on API signature +// Question(aswhinkumar6): should we inherit from standard API interface ? +export interface GetPropertiesInput { + // Question(ashwinkumar6): why not keep bucket and region flat ? + bucket: BucketInfo; + /** + * S3 object key. + */ + path: string; + /** + * Async function resolved to AWS credentials to + * authorize AWS requests. + */ + credentialsProvider: CredentialsProvider; + + options?: { + /** + * Whether to use accelerate endpoint. + * @default false + */ + useAccelerateEndpoint?: boolean; + /** + * [OUT OF SCOPE FOR THIS REVIEW]Additional string to be appended to the user + * agent header. + * + * @internal + */ + customUserAgent?: string; + /** + * [OUT OF SCOPE FOR THIS REVIEW]Custom S3 base host name. The bucket name may be + * added to subdomain. + * + */ + customEndpoint?: string; + /** + * [OUT OF SCOPE FOR THIS REVIEW]After the request has been construct but before + * it's authorized, apply changes to the request + * headers. + */ + customHeaders?(input: { + /** + * Existing headers value of given request. + */ + existingHeaders: Record, string>; + /** + * S3 operation name. e.g. 'headObject' + */ + apiName: string; + }): Promise, string>>; + }; +} diff --git a/packages/storage/src/client/apis/advanced/types/options.ts b/packages/storage/src/client/apis/advanced/types/options.ts new file mode 100644 index 00000000000..9cda87e9135 --- /dev/null +++ b/packages/storage/src/client/apis/advanced/types/options.ts @@ -0,0 +1,13 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { AWSCredentials } from '@aws-amplify/core/internals/utils'; + +export interface BucketInfo { + bucketName: string; + region: string; +} + +export type CredentialsProvider = () => Promise<{ + credentials: AWSCredentials; +}>; diff --git a/packages/storage/src/client/apis/advanced/types/outputs.ts b/packages/storage/src/client/apis/advanced/types/outputs.ts new file mode 100644 index 00000000000..cf1406c9425 --- /dev/null +++ b/packages/storage/src/client/apis/advanced/types/outputs.ts @@ -0,0 +1,2 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 diff --git a/packages/storage/src/client/apis/index.ts b/packages/storage/src/client/apis/index.ts new file mode 100644 index 00000000000..ba58d7b64a6 --- /dev/null +++ b/packages/storage/src/client/apis/index.ts @@ -0,0 +1,5 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// public standard APIs +export { remove } from './remove'; diff --git a/packages/storage/src/client/apis/remove.ts b/packages/storage/src/client/apis/remove.ts new file mode 100644 index 00000000000..34451eef99c --- /dev/null +++ b/packages/storage/src/client/apis/remove.ts @@ -0,0 +1,68 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { Amplify, fetchAuthSession } from '@aws-amplify/core'; +import { StorageAction } from '@aws-amplify/core/internals/utils'; + +import { getStorageUserAgentValue, logger } from '../../utils'; + +import { + RemoveInput, + RemoveOutput, + RemoveWithPathInput, + RemoveWithPathOutput, +} from './types'; +import { + resolveS3ConfigAndInput, + validateStorageOperationInput, +} from './utils'; +import { STORAGE_INPUT_KEY } from './utils/constants'; +import { remove as removeAdvanced } from './advanced/remove'; + +export const remove = async ( + input: RemoveInput | RemoveWithPathInput, +): Promise => { + const { s3Config, keyPrefix, bucket, identityId } = + await resolveS3ConfigAndInput(Amplify, input); + + const { inputType, objectKey } = validateStorageOperationInput( + input, + identityId, + ); + + let finalKey; + if (inputType === STORAGE_INPUT_KEY) { + finalKey = `${keyPrefix}${objectKey}`; + logger.debug(`remove "${objectKey}" from "${finalKey}".`); + } else { + finalKey = objectKey; + logger.debug(`removing object in path "${finalKey}"`); + } + + await removeAdvanced({ + path: finalKey, + bucket: { + bucketName: bucket, + region: s3Config.region, + }, + credentialsProvider: async () => { + return { + // QUESTION(ashwinkumar6): do we throw exception if no credentials + // TODO(ashwinkumar6): move to util + credentials: (await fetchAuthSession()).credentials!, + }; + }, + options: { + useAccelerateEndpoint: s3Config?.useAccelerateEndpoint, + customUserAgent: getStorageUserAgentValue(StorageAction.Remove), + }, + }); + + return inputType === STORAGE_INPUT_KEY + ? { + key: objectKey, + } + : { + path: objectKey, + }; +}; diff --git a/packages/storage/src/client/apis/types/index.ts b/packages/storage/src/client/apis/types/index.ts new file mode 100644 index 00000000000..3e09fd512ae --- /dev/null +++ b/packages/storage/src/client/apis/types/index.ts @@ -0,0 +1,6 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +export { RemoveInput, RemoveWithPathInput } from './inputs'; + +export { RemoveOutput, RemoveWithPathOutput } from './outputs'; diff --git a/packages/storage/src/client/apis/types/inputs.ts b/packages/storage/src/client/apis/types/inputs.ts new file mode 100644 index 00000000000..f6eb527e742 --- /dev/null +++ b/packages/storage/src/client/apis/types/inputs.ts @@ -0,0 +1,5 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// TODO(ashwinkumar6): move type here +export { RemoveInput, RemoveWithPathInput } from '../../../providers/s3/types'; diff --git a/packages/storage/src/client/apis/types/outputs.ts b/packages/storage/src/client/apis/types/outputs.ts new file mode 100644 index 00000000000..a823cdd4e5d --- /dev/null +++ b/packages/storage/src/client/apis/types/outputs.ts @@ -0,0 +1,8 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// TODO(ashwinkumar6): move type here +export { + RemoveOutput, + RemoveWithPathOutput, +} from '../../../providers/s3/types'; diff --git a/packages/storage/src/client/apis/utils/constants.ts b/packages/storage/src/client/apis/utils/constants.ts new file mode 100644 index 00000000000..3841ad4f687 --- /dev/null +++ b/packages/storage/src/client/apis/utils/constants.ts @@ -0,0 +1,5 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// TODO move standard API constants to this file +export { STORAGE_INPUT_KEY } from '../../../providers/s3/utils/constants'; diff --git a/packages/storage/src/client/apis/utils/index.ts b/packages/storage/src/client/apis/utils/index.ts new file mode 100644 index 00000000000..c7fd7b4942a --- /dev/null +++ b/packages/storage/src/client/apis/utils/index.ts @@ -0,0 +1,6 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// Standard API utils +export { validateStorageOperationInput } from './validateStorageOperationInput'; +export { resolveS3ConfigAndInput } from './resolveS3ConfigAndInput'; diff --git a/packages/storage/src/client/apis/utils/resolveS3ConfigAndInput.ts b/packages/storage/src/client/apis/utils/resolveS3ConfigAndInput.ts new file mode 100644 index 00000000000..7c661a70c37 --- /dev/null +++ b/packages/storage/src/client/apis/utils/resolveS3ConfigAndInput.ts @@ -0,0 +1,6 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// TODO(ashwinkumar6): move assertion to this file +// TODO(ashwinkumar6): refactor and cleanup this util +export { resolveS3ConfigAndInput } from '../../../providers/s3/utils'; diff --git a/packages/storage/src/client/apis/utils/validateStorageOperationInput.ts b/packages/storage/src/client/apis/utils/validateStorageOperationInput.ts new file mode 100644 index 00000000000..aa5da05f392 --- /dev/null +++ b/packages/storage/src/client/apis/utils/validateStorageOperationInput.ts @@ -0,0 +1,5 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// TODO(ashwinkumar6): move assertion to this file +export { validateStorageOperationInput } from '../../../providers/s3/utils'; diff --git a/packages/storage/src/utils/index.ts b/packages/storage/src/utils/index.ts index 170a3ee5949..af49d755ae9 100644 --- a/packages/storage/src/utils/index.ts +++ b/packages/storage/src/utils/index.ts @@ -3,3 +3,4 @@ export { resolvePrefix } from './resolvePrefix'; export { logger } from './logger'; +export { getStorageUserAgentValue } from './userAgent'; diff --git a/packages/storage/src/utils/userAgent.ts b/packages/storage/src/utils/userAgent.ts new file mode 100644 index 00000000000..916d1b29945 --- /dev/null +++ b/packages/storage/src/utils/userAgent.ts @@ -0,0 +1,5 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// TODO(ashwinkumar6) move to this file +export { getStorageUserAgentValue } from '../providers/s3/utils/userAgent';