Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(storage): internals list API #13874

58 changes: 58 additions & 0 deletions packages/storage/__tests__/internals/apis/list.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { AmplifyClassV6 } from '@aws-amplify/core';

import { list as advancedList } from '../../../src/internals';
import { list as listInternal } from '../../../src/providers/s3/apis/internal/list';
import { ListAllWithPathOutput } from '../../../src';

jest.mock('../../../src/providers/s3/apis/internal/list');
const mockedListInternal = jest.mocked(listInternal);

describe('list (internals)', () => {
beforeEach(() => {
jest.clearAllMocks();
mockedListInternal.mockResolvedValue({
path: 'output/path/to/mock/object',
items: [],
} as ListAllWithPathOutput);
Samaritan1011001 marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:
is typecasting required here, wondering if we can just mock other required input params

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove it in the next PR.

});

it('should pass advanced option locationCredentialsProvider to internal list', async () => {
expect.assertions(3);
Samaritan1011001 marked this conversation as resolved.
Show resolved Hide resolved
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 advancedList({
path: 'input/path/to/mock/object',
options: {
useAccelerateEndpoint,
bucket,
locationCredentialsProvider,
},
});
expect(mockedListInternal).toHaveBeenCalledTimes(1);
expect(mockedListInternal).toHaveBeenCalledWith(
expect.any(AmplifyClassV6),
{
path: 'input/path/to/mock/object',
options: {
useAccelerateEndpoint,
bucket,
locationCredentialsProvider,
},
},
);
expect(result).toEqual({
path: 'output/path/to/mock/object',
Samaritan1011001 marked this conversation as resolved.
Show resolved Hide resolved
items: [],
});
});
});
19 changes: 19 additions & 0 deletions packages/storage/src/internals/apis/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { Amplify } from '@aws-amplify/core';

import { list as listInternal } from '../../providers/s3/apis/internal/list';
import { ListInternalInput } from '../types/inputs';

/**
* @internal
* List all or paginate files from S3 for a given `path`.
* @param input - The `ListInternalInput` object.
* @returns A list of all objects with path and metadata
* @throws service: `S3Exception` - S3 service errors thrown when checking for existence of bucket
* @throws validation: `StorageValidationErrorCode` - thrown when there are issues with credentials
*/
export function list(input?: ListInternalInput) {
Samaritan1011001 marked this conversation as resolved.
Show resolved Hide resolved
return listInternal(Amplify, input ?? {});
}
1 change: 1 addition & 0 deletions packages/storage/src/internals/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export {

export { getDataAccess } from './apis/getDataAccess';
export { listCallerAccessGrants } from './apis/listCallerAccessGrants';
export { list } from './apis/list';
Samaritan1011001 marked this conversation as resolved.
Show resolved Hide resolved
export { getProperties } from './apis/getProperties';

/*
Expand Down
8 changes: 8 additions & 0 deletions packages/storage/src/internals/types/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
CopyWithPathInput,
GetPropertiesWithPathInput,
} from '../../providers/s3';
import { ListInput } from '../../providers/s3/types/inputs';

import { CredentialsProvider, ListLocationsInput } from './credentials';
import { Permission, PrefixType, Privilege } from './common';
Expand Down Expand Up @@ -40,6 +41,13 @@ export interface GetDataAccessInput {
/**
* @internal
*/
export type ListInternalInput = ExtendInputWithAdvancedOptions<
ListInput,
{
locationCredentialsProvider?: CredentialsProvider;
Samaritan1011001 marked this conversation as resolved.
Show resolved Hide resolved
}
>;

export type GetPropertiesInput = ExtendInputWithAdvancedOptions<
GetPropertiesWithPathInput,
{
Expand Down
20 changes: 5 additions & 15 deletions packages/storage/src/providers/s3/apis/internal/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@ import { AmplifyClassV6 } from '@aws-amplify/core';
import { StorageAction } from '@aws-amplify/core/internals/utils';

import {
ListAllInput,
ListAllOutput,
ListAllWithPathInput,
ListAllWithPathOutput,
ListOutputItem,
ListOutputItemWithPath,
ListPaginateInput,
ListPaginateOutput,
ListPaginateWithPathInput,
ListPaginateWithPathOutput,
} from '../../types';
import {
Expand All @@ -35,6 +31,9 @@ import { logger } from '../../../../utils';
import { DEFAULT_DELIMITER, STORAGE_INPUT_PREFIX } from '../../utils/constants';
import { CommonPrefix } from '../../utils/client/s3data/types';
import { IntegrityError } from '../../../../errors/IntegrityError';
import { ListInput } from '../../types/inputs';
import { ListInternalInput } from '../../../../internals/types/inputs';
import { ListOutput } from '../../types/outputs';

const MAX_PAGE_SIZE = 1000;

Expand All @@ -46,17 +45,8 @@ interface ListInputArgs {

export const list = async (
amplify: AmplifyClassV6,
input:
| ListAllInput
| ListPaginateInput
| ListAllWithPathInput
| ListPaginateWithPathInput,
): Promise<
| ListAllOutput
| ListPaginateOutput
| ListAllWithPathOutput
| ListPaginateWithPathOutput
> => {
input: ListInput | ListInternalInput,
Samaritan1011001 marked this conversation as resolved.
Show resolved Hide resolved
): Promise<ListOutput> => {
const { options = {} } = input;
const {
s3Config,
Expand Down
9 changes: 9 additions & 0 deletions packages/storage/src/providers/s3/types/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ export type ListAllInput = StorageListInputWithPrefix<ListAllWithPrefixOptions>;
export type ListPaginateInput =
StorageListInputWithPrefix<ListPaginateWithPrefixOptions>;

/**
* @internal convinience types.
*/
export type ListInput =
| ListAllInput
| ListPaginateInput
| ListAllWithPathInput
| ListPaginateWithPathInput;

/**
* @deprecated Use {@link RemoveWithPathInput} instead.
* Input type with key for S3 remove API.
Expand Down
9 changes: 9 additions & 0 deletions packages/storage/src/providers/s3/types/outputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ export type ListPaginateWithPathOutput =
nextToken?: string;
};

/**
* @internal convinience types.
*/
export type ListOutput =
| ListAllOutput
| ListPaginateOutput
| ListAllWithPathOutput
| ListPaginateWithPathOutput;

/**
* Output type with path for S3 copy API.
* @deprecated Use {@link CopyWithPathOutput} instead.
Expand Down
Loading