From 7722573e8a001ec7a67ece2b406a0457bb096d17 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Wed, 2 Oct 2024 16:56:41 -0700 Subject: [PATCH] feat(internal-remove): add new internal remove api --- .../__tests__/internals/apis/remove.test.ts | 59 +++++++++++++++++++ packages/storage/src/internals/apis/remove.ts | 30 ++++++++++ packages/storage/src/internals/index.ts | 3 + .../storage/src/internals/types/inputs.ts | 11 ++++ .../storage/src/internals/types/outputs.ts | 10 +++- .../src/providers/s3/apis/internal/remove.ts | 11 ++-- 6 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 packages/storage/__tests__/internals/apis/remove.test.ts create mode 100644 packages/storage/src/internals/apis/remove.ts diff --git a/packages/storage/__tests__/internals/apis/remove.test.ts b/packages/storage/__tests__/internals/apis/remove.test.ts new file mode 100644 index 00000000000..df3a5d7d58a --- /dev/null +++ b/packages/storage/__tests__/internals/apis/remove.test.ts @@ -0,0 +1,59 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import { AmplifyClassV6 } from '@aws-amplify/core'; + +import { remove as advancedRemove } from '../../../src/internals'; +import { remove as removeInternal } from '../../../src/providers/s3/apis/internal/remove'; + +jest.mock('../../../src/providers/s3/apis/internal/remove'); +const mockedRemoveInternal = jest.mocked(removeInternal); + +describe('remove (internal)', () => { + beforeEach(() => { + mockedRemoveInternal.mockResolvedValue({ + path: 'output/path/to/mock/object', + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should pass advanced option locationCredentialsProvider to internal remove', async () => { + const useAccelerateEndpoint = true; + const bucket = { bucketName: 'bucket', region: 'us-east-1' }; + const locationCredentialsProvider = async () => ({ + credentials: { + accessKeyId: 'akid', + secretAccessKey: 'secret', + sessionToken: 'token', + expiration: new Date(), + }, + }); + + const result = await advancedRemove({ + path: 'input/path/to/mock/object', + options: { + useAccelerateEndpoint, + bucket, + locationCredentialsProvider, + }, + }); + + expect(mockedRemoveInternal).toHaveBeenCalledTimes(1); + expect(mockedRemoveInternal).toHaveBeenCalledWith( + expect.any(AmplifyClassV6), + { + path: 'input/path/to/mock/object', + options: { + useAccelerateEndpoint, + bucket, + locationCredentialsProvider, + }, + }, + ); + expect(result).toEqual({ + path: 'output/path/to/mock/object', + }); + }); +}); diff --git a/packages/storage/src/internals/apis/remove.ts b/packages/storage/src/internals/apis/remove.ts new file mode 100644 index 00000000000..c80ea97bba3 --- /dev/null +++ b/packages/storage/src/internals/apis/remove.ts @@ -0,0 +1,30 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { Amplify } from '@aws-amplify/core'; + +import { remove as removeInternal } from '../../providers/s3/apis/internal/remove'; +import { RemoveInput } from '../types/inputs'; +import { RemoveOutput } from '../types/outputs'; + +/** + * Remove a file from your S3 bucket. + * @param input - The `RemoveWithPathInput` object. + * @return Output containing the removed object path. + * @throws service: `S3Exception` - S3 service errors thrown while while removing the object. + * @throws validation: `StorageValidationErrorCode` - Validation errors thrown + * when there is no path or path is empty or path has a leading slash. + * + * @internal + */ +export const remove = (input: RemoveInput): Promise => + removeInternal(Amplify, { + path: input.path, + options: { + useAccelerateEndpoint: input?.options?.useAccelerateEndpoint, + bucket: input?.options?.bucket, + locationCredentialsProvider: input?.options?.locationCredentialsProvider, + }, + // Type casting is necessary because `removeInternal` supports both Gen1 and Gen2 signatures, but here + // given in input can only be Gen2 signature, the return can only ben Gen2 signature. + }) as Promise; diff --git a/packages/storage/src/internals/index.ts b/packages/storage/src/internals/index.ts index 6ca2bdba6dd..a514ad88547 100644 --- a/packages/storage/src/internals/index.ts +++ b/packages/storage/src/internals/index.ts @@ -13,16 +13,19 @@ export { ListCallerAccessGrantsInput, GetPropertiesInput, CopyInput, + RemoveInput, } from './types/inputs'; export { GetDataAccessOutput, ListCallerAccessGrantsOutput, GetPropertiesOutput, + RemoveOutput, } from './types/outputs'; export { getDataAccess } from './apis/getDataAccess'; export { listCallerAccessGrants } from './apis/listCallerAccessGrants'; export { getProperties } from './apis/getProperties'; +export { remove } from './apis/remove'; /* CredentialsStore exports diff --git a/packages/storage/src/internals/types/inputs.ts b/packages/storage/src/internals/types/inputs.ts index 8e813c28e4a..f8a36943066 100644 --- a/packages/storage/src/internals/types/inputs.ts +++ b/packages/storage/src/internals/types/inputs.ts @@ -9,6 +9,7 @@ import { import { CopyWithPathInput, GetPropertiesWithPathInput, + RemoveWithPathInput, } from '../../providers/s3'; import { CredentialsProvider, ListLocationsInput } from './credentials'; @@ -37,6 +38,16 @@ export interface GetDataAccessInput { scope: string; } +/** + * @internal + */ +export type RemoveInput = ExtendInputWithAdvancedOptions< + RemoveWithPathInput, + { + locationCredentialsProvider?: CredentialsProvider; + } +>; + /** * @internal */ diff --git a/packages/storage/src/internals/types/outputs.ts b/packages/storage/src/internals/types/outputs.ts index 0a47381ff69..cf1e96acfe2 100644 --- a/packages/storage/src/internals/types/outputs.ts +++ b/packages/storage/src/internals/types/outputs.ts @@ -1,7 +1,10 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -import { GetPropertiesWithPathOutput } from '../../providers/s3/types'; +import { + GetPropertiesWithPathOutput, + RemoveWithPathOutput, +} from '../../providers/s3/types'; import { ListLocationsOutput, LocationCredentials } from './credentials'; @@ -19,3 +22,8 @@ export type GetDataAccessOutput = LocationCredentials; * @internal */ export type GetPropertiesOutput = GetPropertiesWithPathOutput; + +/** + * @internal + */ +export type RemoveOutput = RemoveWithPathOutput; diff --git a/packages/storage/src/providers/s3/apis/internal/remove.ts b/packages/storage/src/providers/s3/apis/internal/remove.ts index d73a13346e4..ed867ad2c36 100644 --- a/packages/storage/src/providers/s3/apis/internal/remove.ts +++ b/packages/storage/src/providers/s3/apis/internal/remove.ts @@ -4,12 +4,7 @@ import { AmplifyClassV6 } from '@aws-amplify/core'; import { StorageAction } from '@aws-amplify/core/internals/utils'; -import { - RemoveInput, - RemoveOutput, - RemoveWithPathInput, - RemoveWithPathOutput, -} from '../../types'; +import { RemoveInput, RemoveOutput, RemoveWithPathOutput } from '../../types'; import { resolveS3ConfigAndInput, validateStorageOperationInput, @@ -18,10 +13,12 @@ import { deleteObject } from '../../utils/client/s3data'; import { getStorageUserAgentValue } from '../../utils/userAgent'; import { logger } from '../../../../utils'; import { STORAGE_INPUT_KEY } from '../../utils/constants'; +// TODO: Remove this interface when we move to public advanced APIs. +import { RemoveInput as RemoveWithPathInputWithAdvancedOptions } from '../../../../internals'; export const remove = async ( amplify: AmplifyClassV6, - input: RemoveInput | RemoveWithPathInput, + input: RemoveInput | RemoveWithPathInputWithAdvancedOptions, ): Promise => { const { s3Config, keyPrefix, bucket, identityId } = await resolveS3ConfigAndInput(amplify, input);