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): add an adapter interface for storage browser #13576

Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { createManagedAuthConfigAdapter } from '../../../src/storageBrowser/managedAuthConfigAdapter';
import { createListLocationsHandler } from '../../../src/storageBrowser/managedAuthConfigAdapter/createListLocationsHandler';
import { createLocationCredentialsHandler } from '../../../src/storageBrowser/managedAuthConfigAdapter/createLocationCredentialsHandler';

jest.mock(
'../../../src/storageBrowser/managedAuthConfigAdapter/createListLocationsHandler',
);
jest.mock(
'../../../src/storageBrowser/managedAuthConfigAdapter/createLocationCredentialsHandler',
);

describe('createManagedAuthConfigAdapter', () => {
const region = 'us-foo-2';
const accountId = 'XXXXXXXXXXXX';
const credentialsProvider = jest.fn();

beforeEach(() => {
jest
.mocked(createListLocationsHandler)
.mockReturnValue('LIST_LOCATIONS_FN' as any);
jest
.mocked(createLocationCredentialsHandler)
.mockReturnValue('GET_LOCATION_CREDENTIALS_FN' as any);
});

afterEach(() => {
jest.clearAllMocks();
});

it('should pass region to the adapter', () => {
expect(createManagedAuthConfigAdapter({ region } as any)).toMatchObject({
region,
});
});

it('should create list locations handler', () => {
expect(
createManagedAuthConfigAdapter({
region,
accountId,
credentialsProvider,
}),
).toMatchObject({
listLocations: 'LIST_LOCATIONS_FN',
});
expect(createListLocationsHandler).toHaveBeenCalledWith({
region,
accountId,
credentialsProvider,
});
});

it('should create get location credentials handler', () => {
expect(
createManagedAuthConfigAdapter({
region,
accountId,
credentialsProvider,
}),
).toMatchObject({
getLocationCredentials: 'GET_LOCATION_CREDENTIALS_FN',
});
expect(createLocationCredentialsHandler).toHaveBeenCalledWith({
region,
accountId,
credentialsProvider,
});
});
});
18 changes: 2 additions & 16 deletions packages/storage/src/storageBrowser/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

/**
* NOTE: The APIs exported from this file are ONLY intended for usage by
* Amplify UI. To use location-related features, please use
* @aws-amplify/ui-react-storage
*/

export {
listCallerAccessGrants,
ListCallerAccessGrantsInput,
ListCallerAccessGrantsOutput,
} from './listCallerAccessGrants';
export { createLocationCredentialsHandler } from './createLocationCredentialsHandler';
export { createLocationCredentialsStore } from './locationCredentialsStore';
export {
managedAuthAdapter,
ManagedAuthAdapterInput,
} from './managedAuthAdapter';
export { createManagedAuthConfigAdapter } from './managedAuthConfigAdapter/createManagedAuthConfigAdapter';
export { GetLocationCredentials, ListLocations } from './types';
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ export interface ListCallerAccessGrantsInput {
accountId: string;
credentialsProvider: CredentialsProvider;
region: string;
options?: {
nextToken?: string;
// Default to 100; If > 1000, API will make multiple API calls.
pageSize?: number;
};
}

export type ListCallerAccessGrantsOutput = ListLocationsOutput<AccessGrant>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import {
CredentialsLocation,
LocationCredentialsHandler,
GetLocationCredentials,
LocationCredentialsStore,
} from '../types';
import { StorageValidationErrorCode } from '../../errors/types/validation';
Expand All @@ -17,7 +17,7 @@ import { createStore, getValue, removeStore } from './registry';
import { validateCredentialsProviderLocation } from './validators';

export const createLocationCredentialsStore = (input: {
handler: LocationCredentialsHandler;
handler: GetLocationCredentials;
}): LocationCredentialsStore => {
const storeSymbol = createStore(input.handler);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// SPDX-License-Identifier: Apache-2.0
import { AWSCredentials } from '@aws-amplify/core/internals/utils';

import { CredentialsLocation, LocationCredentialsHandler } from '../types';
import { CredentialsLocation, GetLocationCredentials } from '../types';
import { assertValidationError } from '../../errors/utils/assertValidationError';
import { StorageValidationErrorCode } from '../../errors/types/validation';

Expand Down Expand Up @@ -33,7 +33,7 @@ const storeRegistry = new WeakMap<
* @internal
*/
export const createStore = (
refreshHandler: LocationCredentialsHandler,
refreshHandler: GetLocationCredentials,
size?: number,
) => {
const storeSymbol = { value: Symbol('LocationCredentialsStore') };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { AWSCredentials } from '@aws-amplify/core/internals/utils';

import { Permission } from '../../providers/s3/types/options';
import { CredentialsLocation, LocationCredentialsHandler } from '../types';
import { CredentialsLocation, GetLocationCredentials } from '../types';
import { assertValidationError } from '../../errors/utils/assertValidationError';
import { StorageValidationErrorCode } from '../../errors/types/validation';

Expand Down Expand Up @@ -35,15 +35,15 @@ const createCacheKey = (location: CredentialsLocation): CacheKey =>
*/
export interface LruLocationCredentialsStore {
capacity: number;
refreshHandler: LocationCredentialsHandler;
refreshHandler: GetLocationCredentials;
values: Map<CacheKey, StoreValue>;
}

/**
* @internal
*/
export const initStore = (
refreshHandler: LocationCredentialsHandler,
refreshHandler: GetLocationCredentials,
size = CREDENTIALS_STORE_DEFAULT_SIZE,
): LruLocationCredentialsStore => {
assertValidationError(
Expand Down Expand Up @@ -117,7 +117,7 @@ export const fetchNewValue = async (
};

const dispatchRefresh = (
refreshHandler: LocationCredentialsHandler,
refreshHandler: GetLocationCredentials,
value: StoreValue,
onRefreshFailure: () => void,
) => {
Expand Down
27 changes: 0 additions & 27 deletions packages/storage/src/storageBrowser/managedAuthAdapter.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { CredentialsProvider, ListLocations } from '../types';

export interface CreateListLocationsHandlerInput {
Copy link
Member

Choose a reason for hiding this comment

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

Should this all be deriving from base type CreateManagedAuthConfigAdapterInput since these handler Input have same type?

accountId: string;
credentialsProvider: CredentialsProvider;
region: string;
}

export const createListLocationsHandler = (
// eslint-disable-next-line unused-imports/no-unused-vars
input: CreateListLocationsHandlerInput,
): ListLocations => {
// TODO(@AllanZhengYP)
throw new Error('Not Implemented');
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { CredentialsProvider, LocationCredentialsHandler } from './types';
import { CredentialsProvider, GetLocationCredentials } from '../types';

interface CreateLocationCredentialsHandlerInput {
accountId: string;
Expand All @@ -12,7 +12,7 @@ interface CreateLocationCredentialsHandlerInput {
export const createLocationCredentialsHandler = (
// eslint-disable-next-line unused-imports/no-unused-vars
input: CreateLocationCredentialsHandlerInput,
): LocationCredentialsHandler => {
): GetLocationCredentials => {
// TODO(@AllanZhengYP)
throw new Error('Not Implemented');
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import {
CredentialsProvider,
GetLocationCredentials,
ListLocations,
} from '../types';

import { createListLocationsHandler } from './createListLocationsHandler';
import { createLocationCredentialsHandler } from './createLocationCredentialsHandler';

interface CreateManagedAuthConfigAdapterInput {
accountId: string;
region: string;
credentialsProvider: CredentialsProvider;
}

interface AuthConfigAdapter {
listLocations: ListLocations;
getLocationCredentials: GetLocationCredentials;
region: string;
}

/**
* Create configuration including handlers to call S3 Access Grant APIs to list and get
* credentials for different locations.
*
* @param options - Configuration options for the adapter.
* @returns - An object containing the handlers to call S3 Access Grant APIs and region
*/
export const createManagedAuthConfigAdapter = ({
credentialsProvider,
region,
accountId,
}: CreateManagedAuthConfigAdapterInput): AuthConfigAdapter => {
const listLocations = createListLocationsHandler({
credentialsProvider,
accountId,
region,
});
const getLocationCredentials = createLocationCredentialsHandler({
credentialsProvider,
accountId,
region,
});

return {
listLocations,
getLocationCredentials,
region,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

export { createManagedAuthConfigAdapter } from './createManagedAuthConfigAdapter';
16 changes: 12 additions & 4 deletions packages/storage/src/storageBrowser/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,19 @@ export interface ListLocationsOutput<T extends LocationAccess> {
nextToken?: string;
}

// Interface for listLocations() handler
export type ListLocations = () => Promise<ListLocationsOutput<LocationAccess>>;
/**
* @internal
*/
export interface ListLocationsInput {
pageSize?: number;
nextToken?: string;
}

export type ListLocations = (
input?: ListLocationsInput,
) => Promise<ListLocationsOutput<LocationAccess>>;

// Interface for getLocationCredentials() handler.
export type LocationCredentialsHandler = (
export type GetLocationCredentials = (
input: CredentialsLocation,
) => Promise<{ credentials: AWSCredentials }>;

Expand Down
Loading