Skip to content

Commit 5e6acbb

Browse files
chore(gen2-storage): Update StorageImage API (aws-amplify#5171)
Co-authored-by: Caleb Pollman <[email protected]>
1 parent 10d5061 commit 5e6acbb

File tree

5 files changed

+342
-56
lines changed

5 files changed

+342
-56
lines changed

.changeset/big-owls-nail.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@aws-amplify/ui-react-storage": minor
3+
"@aws-amplify/ui-react": patch
4+
---
5+
6+
chore(gen2-storage): Update StorageImage API.
7+
8+
Updates the StorageImage component to work with both gen1 and gen2 props. Accepts either `imgKey` or `path` props.

packages/react-storage/jest.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const config: Config = {
1111
],
1212
coverageThreshold: {
1313
global: {
14-
branches: 50,
14+
branches: 85,
1515
functions: 87,
1616
lines: 93,
1717
statements: 93,
Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,101 @@
11
import * as React from 'react';
22

3-
import { classNames, ComponentClassName, isUndefined } from '@aws-amplify/ui';
3+
import { classNames, ComponentClassName } from '@aws-amplify/ui';
44
import { Image } from '@aws-amplify/ui-react';
5-
import { useStorageURL } from '@aws-amplify/ui-react/internal';
6-
import { useSetUserAgent } from '@aws-amplify/ui-react-core';
5+
import { useDeprecationWarning } from '@aws-amplify/ui-react/internal';
6+
import { useGetUrl, useSetUserAgent } from '@aws-amplify/ui-react-core';
77

88
import { VERSION } from '../../version';
9-
import type { StorageImageProps } from './types';
9+
import type { StorageImageProps, StorageImagePathProps } from './types';
10+
11+
export const MISSING_REQUIRED_PROP_MESSAGE =
12+
'`StorageImage` requires either an `imgKey` or `path` prop.';
13+
14+
export const HAS_DEPRECATED_PROPS_MESSAGE =
15+
'`imgKey`, `accessLevel`, and `identityId` will be replaced with `path` in a future major version.';
16+
17+
export const HAS_PATH_AND_KEY_MESSAGE =
18+
'`imgKey` is ignored when both `imgKey` and `path` props are provided.';
19+
20+
export const HAS_PATH_AND_UNSUPPORTED_OPTIONS_MESSAGE =
21+
'``accessLevel` and `identityId` are ignored when the `path` prop is provided.';
22+
23+
const getDeprecationMessage = ({
24+
hasImgkey,
25+
hasPath,
26+
hasDeprecatedOptions,
27+
}: {
28+
hasImgkey: boolean;
29+
hasPath: boolean;
30+
hasDeprecatedOptions: boolean;
31+
}): string => {
32+
let message = '';
33+
34+
if (hasPath && hasImgkey) {
35+
message = HAS_PATH_AND_KEY_MESSAGE;
36+
} else if (hasPath && hasDeprecatedOptions) {
37+
message = HAS_PATH_AND_UNSUPPORTED_OPTIONS_MESSAGE;
38+
} else if (hasImgkey) {
39+
message = HAS_DEPRECATED_PROPS_MESSAGE;
40+
}
41+
42+
return message;
43+
};
1044

1145
export const StorageImage = ({
1246
accessLevel,
1347
className,
1448
fallbackSrc,
1549
identityId,
1650
imgKey,
51+
path,
1752
onStorageGetError,
18-
validateObjectExistence,
53+
onGetUrlError,
54+
validateObjectExistence = true,
1955
...rest
20-
}: StorageImageProps): JSX.Element => {
21-
const resolvedValidateObjectExistence = isUndefined(validateObjectExistence)
22-
? true
23-
: validateObjectExistence;
24-
const options = React.useMemo(
25-
() => ({
26-
accessLevel,
27-
targetIdentityId: identityId,
28-
validateObjectExistence: resolvedValidateObjectExistence,
29-
}),
30-
[accessLevel, identityId, resolvedValidateObjectExistence]
31-
);
56+
}: StorageImageProps | StorageImagePathProps): JSX.Element => {
57+
const hasImgkey = !!imgKey;
58+
const hasPath = !!path;
59+
const hasDeprecatedOptions = !!accessLevel || !!identityId;
60+
61+
const message = getDeprecationMessage({
62+
hasDeprecatedOptions,
63+
hasImgkey,
64+
hasPath,
65+
});
66+
useDeprecationWarning({ message, shouldWarn: !!message });
67+
68+
if (!hasImgkey && !hasPath) {
69+
throw new Error(MISSING_REQUIRED_PROP_MESSAGE);
70+
}
3271

3372
useSetUserAgent({
3473
componentName: 'StorageImage',
3574
packageName: 'react-storage',
3675
version: VERSION,
3776
});
3877

39-
const url = useStorageURL({
40-
key: imgKey,
41-
options,
42-
fallbackURL: fallbackSrc,
43-
onStorageGetError,
44-
});
78+
const onError = onGetUrlError ?? onStorageGetError;
79+
const input = React.useMemo(
80+
() => ({
81+
...(path ? { path } : { key: imgKey! }), // if `path` is falsy `imgKey` exists
82+
onError,
83+
options: {
84+
accessLevel,
85+
targetIdentityId: identityId,
86+
validateObjectExistence,
87+
},
88+
}),
89+
[accessLevel, imgKey, identityId, onError, path, validateObjectExistence]
90+
);
91+
92+
const { url } = useGetUrl(input);
4593

4694
return (
4795
<Image
4896
{...rest}
4997
className={classNames(ComponentClassName.StorageImage, className)}
50-
src={url}
98+
src={url?.toString() ?? fallbackSrc}
5199
/>
52100
);
53101
};

0 commit comments

Comments
 (0)