UNPKG

3.98 kBJavaScriptView Raw
1import { assertValidationError } from '../../../errors/utils/assertValidationError.mjs';
2import { StorageValidationErrorCode } from '../../../errors/types/validation.mjs';
3import { resolvePrefix } from '../../../utils/resolvePrefix.mjs';
4import { DEFAULT_ACCESS_LEVEL, LOCAL_TESTING_S3_ENDPOINT } from './constants.mjs';
5
6// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
7// SPDX-License-Identifier: Apache-2.0
8/**
9 * resolve the common input options for S3 API handlers from Amplify configuration and library options.
10 *
11 * @param {AmplifyClassV6} amplify The Amplify instance.
12 * @param {S3ApiOptions} apiOptions The input options for S3 provider.
13 * @returns {Promise<ResolvedS3ConfigAndInput>} The resolved common input options for S3 API handlers.
14 * @throws A `StorageError` with `error.name` from `StorageValidationErrorCode` indicating invalid
15 * configurations or Amplify library options.
16 *
17 * @internal
18 */
19const resolveS3ConfigAndInput = async (amplify, apiOptions) => {
20 /**
21 * IdentityId is always cached in memory so we can safely make calls here. It
22 * should be stable even for unauthenticated users, regardless of credentials.
23 */
24 const { identityId } = await amplify.Auth.fetchAuthSession();
25 assertValidationError(!!identityId, StorageValidationErrorCode.NoIdentityId);
26 /**
27 * A credentials provider function instead of a static credentials object is
28 * used because the long-running tasks like multipart upload may span over the
29 * credentials expiry. Auth.fetchAuthSession() automatically refreshes the
30 * credentials if they are expired.
31 */
32 const credentialsProvider = async () => {
33 const { credentials } = await amplify.Auth.fetchAuthSession();
34 assertValidationError(!!credentials, StorageValidationErrorCode.NoCredentials);
35 return credentials;
36 };
37 const { bucket: defaultBucket, region: defaultRegion, dangerouslyConnectToHttpEndpointForTesting, buckets, } = amplify.getConfig()?.Storage?.S3 ?? {};
38 const { bucket = defaultBucket, region = defaultRegion } = (apiOptions?.bucket && resolveBucketConfig(apiOptions, buckets)) || {};
39 assertValidationError(!!bucket, StorageValidationErrorCode.NoBucket);
40 assertValidationError(!!region, StorageValidationErrorCode.NoRegion);
41 const { defaultAccessLevel, prefixResolver = resolvePrefix, isObjectLockEnabled, } = amplify.libraryOptions?.Storage?.S3 ?? {};
42 const keyPrefix = await prefixResolver({
43 accessLevel: apiOptions?.accessLevel ?? defaultAccessLevel ?? DEFAULT_ACCESS_LEVEL,
44 // use conditional assign to make tsc happy because StorageOptions is a union type that may not have targetIdentityId
45 targetIdentityId: apiOptions?.accessLevel === 'protected'
46 ? (apiOptions?.targetIdentityId ?? identityId)
47 : identityId,
48 });
49 return {
50 s3Config: {
51 credentials: credentialsProvider,
52 region,
53 useAccelerateEndpoint: apiOptions?.useAccelerateEndpoint,
54 ...(dangerouslyConnectToHttpEndpointForTesting
55 ? {
56 customEndpoint: LOCAL_TESTING_S3_ENDPOINT,
57 forcePathStyle: true,
58 }
59 : {}),
60 },
61 bucket,
62 keyPrefix,
63 identityId,
64 isObjectLockEnabled,
65 };
66};
67const resolveBucketConfig = (apiOptions, buckets) => {
68 if (typeof apiOptions.bucket === 'string') {
69 const bucketConfig = buckets?.[apiOptions.bucket];
70 assertValidationError(!!bucketConfig, StorageValidationErrorCode.InvalidStorageBucket);
71 return { bucket: bucketConfig.bucketName, region: bucketConfig.region };
72 }
73 if (typeof apiOptions.bucket === 'object') {
74 return {
75 bucket: apiOptions.bucket.bucketName,
76 region: apiOptions.bucket.region,
77 };
78 }
79};
80
81export { resolveS3ConfigAndInput };
82//# sourceMappingURL=resolveS3ConfigAndInput.mjs.map