Skip to content

Commit

Permalink
feat(storage): add base types for storage browser (#13528)
Browse files Browse the repository at this point in the history
* feat(storage): add base types

* fix(storage): address feedbacks

Co-authored-by: israx <[email protected]>
  • Loading branch information
AllanZhengYP and israx authored Jun 26, 2024
1 parent 614e38e commit 3fc169e
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 0 deletions.
23 changes: 23 additions & 0 deletions packages/storage/src/providers/s3/types/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import { StorageAccessLevel } from '@aws-amplify/core';
import { AWSCredentials } from '@aws-amplify/core/internals/utils';
import { SigningOptions } from '@aws-amplify/core/internals/aws-client-utils';

import { TransferProgressEvent } from '../../../types';
Expand All @@ -10,12 +11,34 @@ import {
StorageListPaginateOptions,
} from '../../../types/options';

/**
* @internal
*/
export type Permission = 'READ' | 'READWRITE' | 'WRITE';

/**
* @internal
*/
export type LocationCredentialsProvider = (options: {
forceRefresh?: boolean;
locations: { bucket: string; path: string }[];
permission: Permission;
}) => Promise<{ credentials: AWSCredentials }>;

interface CommonOptions {
/**
* Whether to use accelerate endpoint.
* @default false
*/
useAccelerateEndpoint?: boolean;

/**
* Async function returning AWS credentials for an API call. This function
* is invoked with S3 locations(bucket and path).
* If omitted, the global credentials configured in Amplify Auth
* would be used.
*/
locationCredentialsProvider?: LocationCredentialsProvider;
}

/** @deprecated This may be removed in the next major version. */
Expand Down
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, LocationCredentialsHandler } from './types';

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

export const createLocationCredentialsHandler = (
// eslint-disable-next-line unused-imports/no-unused-vars
input: CreateLocationCredentialsHandlerInput,
): LocationCredentialsHandler => {
// TODO(@AllanZhengYP)
throw new Error('Not Implemented');
};
10 changes: 10 additions & 0 deletions packages/storage/src/storage-browser/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

export {
listCallerAccessGrants,
ListCallerAccessGrantsInput,
ListCallerAccessGrantsOutput,
} from './listCallerAccessGrants';
export { createLocationCredentialsHandler } from './createLocationCredentialsHandler';
export { createLocationCredentialsStore } from './locationCredentialsStore/createLocationCredentialsStore';
25 changes: 25 additions & 0 deletions packages/storage/src/storage-browser/listCallerAccessGrants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { AccessGrant, CredentialsProvider, ListLocationsOutput } from './types';

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>;

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

import { LocationCredentialsHandler, LocationCredentialsStore } from '../types';

// eslint-disable-next-line unused-imports/no-unused-vars
export const createLocationCredentialsStore = (input: {
handler: LocationCredentialsHandler;
}): LocationCredentialsStore => {
// TODO(@AllanZhengYP)
throw new Error('Not Implemented');
};
91 changes: 91 additions & 0 deletions packages/storage/src/storage-browser/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { AWSCredentials } from '@aws-amplify/core/internals/utils';

import {
LocationCredentialsProvider,
Permission,
} from '../providers/s3/types/options';

/**
* @internal
*/
export type CredentialsProvider = (options?: {
forceRefresh?: boolean;
}) => Promise<{ credentials: AWSCredentials }>;

type LocationAccessType = 'BUCKET' | 'PREFIX' | 'OBJECT';

/**
* @internal
*/
export interface LocationAccess {
/**
* Scope of storage location. For S3 service, it's the S3 path of the data to
* which the access is granted.
*
* @example 's3://MY-BUCKET-NAME/prefix/*'
*/
readonly scope: string;
/**
* The type of access granted to your Storage data. Can be either of READ,
* WRITE or READWRITE
*/
readonly permission: Permission;
/**
* parse location type parsed from scope format:
* * bucket: `'s3://<bucket>/*'`
* * prefix: `'s3://<bucket>/<prefix-with-path>*'`
* * object: `'s3://<bucket>/<prefix-with-path>/<object>'`
*/
readonly type: LocationAccessType;
}

export interface AccessGrant extends LocationAccess {
/**
* The Amazon Resource Name (ARN) of an AWS IAM Identity Center application
* associated with your Identity Center instance. If the grant includes an
* application ARN, the grantee can only access the S3 data through this
* application.
*/
readonly applicationArn: string | undefined;
}

/**
* @internal
*/
export interface ListLocationsOutput<T extends LocationAccess> {
locations: T[];
nextToken?: string;
}

// Interface for listLocations() handler
export type ListLocations = () => Promise<ListLocationsOutput<LocationAccess>>;

// Interface for getLocationCredentials() handler.
export type LocationCredentialsHandler = (input: {
scope: string;
permission: Permission;
}) => Promise<{ credentials: AWSCredentials; scope?: string }>;

export interface LocationCredentialsStore {
/**
* Get location-specific credentials. It uses a cache internally to optimize performance when
* getting credentials for the same location. It will refresh credentials if they expire or
* when forced to.
*
* If specific credentials scope `option` is omitted, the store will attempt to resolve
* locations-specific credentials from the input bucket and full path.
*/
getProvider(option?: {
scope: string;
permission: Permission;
}): LocationCredentialsProvider;
/**
* Invalidate cached credentials and force subsequent calls to get location-specific
* credentials to throw. It also makes subsequent calls to `getCredentialsProviderForLocation`
* to throw.
*/
destroy(): void;
}

0 comments on commit 3fc169e

Please sign in to comment.