Skip to content

Commit

Permalink
feat(storage): attempt to remove scope from the types
Browse files Browse the repository at this point in the history
  • Loading branch information
AllanZhengYP committed Jul 2, 2024
1 parent 80ecee7 commit 33426e4
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 55 deletions.
15 changes: 10 additions & 5 deletions packages/storage/src/providers/s3/types/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,30 @@ import {
export type Permission = 'READ' | 'READWRITE' | 'WRITE';

/**
* @internal
* Whether the bucket path points to a prefix or an object
* If it's 'PREFIX', it points a prefix or folder. For example the list() API's
* bucket path points to prefix or folder
* If it's 'OBJECT', the bucket path points to an object.
*/
export type LocationType = 'PREFIX' | 'OBJECT' | 'BUCKET';
type SubLocationType = 'PREFIX' | 'OBJECT';

/**
* Refer to either prefix a object resources that locates under a given bucket.
*
* @internal
*/
export interface BucketLocation {
export interface SubLocation {
bucket: string;
path: string;
type: LocationType;
type: SubLocationType;
}

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

Expand Down
133 changes: 83 additions & 50 deletions packages/storage/src/storage-browser/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,81 +4,114 @@
import { AWSCredentials } from '@aws-amplify/core/internals/utils';

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

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

interface BucketLocation {
type: 'BUCKET';
bucket: string;
}

type Locations = BucketLocation | SubLocation;

/**
* @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: LocationType;
export type LocationAccess = Locations & {
/**
* The type of access granted to your Storage data. Can be either of READ,
* WRITE or READWRITE
*/
readonly permission: Permission;
}

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;
export type AccessGrant = 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;
}

/**
* @internal
*/
export interface ListLocationsOutput<T extends LocationAccess> {
locations: T[];
nextToken?: string;
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 type LocationCredentialsHandler = (
input: LocationAccess,
) => Promise<{ credentials: AWSCredentials }>;

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.
*/
getProvider(option: LocationAccess): 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;
/**
* 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.
*/
getProvider(option: LocationAccess): 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;
}

const listLocations: ListLocations = async () => ({
locations: [
{
permission: 'READ',
bucket: 'bucket',
path: 'path',
type: 'PREFIX',
},
{
permission: 'READ',
bucket: 'bucket',
path: 'file',
type: 'OBJECT',
},
],
});

const getLocationCredentials: LocationCredentialsHandler = async input => {
if (
input.type === 'PREFIX' &&
input.bucket === 'bucket' &&
input.path === 'path' &&
input.permission === 'READ'
) {
return {
credentials:
'Temp credentials to read `s3://bucket/path*`' as any as AWSCredentials,
};
} else if (
input.type === 'OBJECT' &&
input.bucket === 'bucket' &&
input.path === 'file' &&
input.permission === 'READ'
) {
return {
credentials:
'Temp credentials to read `s3://bucket/file`' as any as AWSCredentials,
};
} else throw new Error('');
};

0 comments on commit 33426e4

Please sign in to comment.