@aws-amplify/ui-react-core 1.0.5 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/esm/Authenticator/context/AuthenticatorContext.js +4 -1
  2. package/dist/esm/Authenticator/context/AuthenticatorProvider.js +8 -4
  3. package/dist/esm/Authenticator/hooks/constants.js +26 -0
  4. package/dist/esm/Authenticator/hooks/useAuthenticator/constants.js +3 -13
  5. package/dist/esm/Authenticator/hooks/useAuthenticator/useAuthenticator.js +13 -12
  6. package/dist/esm/Authenticator/hooks/useAuthenticator/utils.js +32 -15
  7. package/dist/esm/Authenticator/hooks/useAuthenticatorInitMachine/useAuthenticatorInitMachine.js +17 -0
  8. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/constants.js +73 -0
  9. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.js +52 -0
  10. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/utils.js +89 -0
  11. package/dist/esm/Authenticator/hooks/utils.js +24 -0
  12. package/dist/esm/InAppMessaging/context/InAppMessagingContext/InAppMessagingContext.js +5 -0
  13. package/dist/esm/InAppMessaging/context/InAppMessagingProvider/InAppMessagingProvider.js +26 -0
  14. package/dist/esm/InAppMessaging/hooks/useInAppMessaging/useInAppMessaging.js +19 -0
  15. package/dist/esm/InAppMessaging/hooks/useMessage/useMessage.js +78 -0
  16. package/dist/esm/InAppMessaging/hooks/useMessage/utils.js +43 -0
  17. package/dist/esm/InAppMessaging/utils/handleMessageAction.js +16 -0
  18. package/dist/esm/components/RenderNothing/RenderNothing.js +8 -0
  19. package/dist/esm/hooks/useHasValueUpdated.js +13 -0
  20. package/dist/esm/hooks/usePreviousValue.js +13 -0
  21. package/dist/esm/index.js +13 -1
  22. package/dist/esm/node_modules/tslib/tslib.es6.js +38 -0
  23. package/dist/esm/utils/index.js +5 -2
  24. package/dist/index.js +638 -6
  25. package/dist/{esm/Authenticator/hooks/useAuthenticator/types.js → types/Authenticator/context/__tests__/AuthenticatorProvider.test.d.ts} +0 -0
  26. package/dist/types/Authenticator/hooks/__mock__/components.d.ts +7 -0
  27. package/dist/types/Authenticator/hooks/__tests__/utils.spec.d.ts +1 -0
  28. package/dist/types/Authenticator/hooks/constants.d.ts +3 -0
  29. package/dist/types/Authenticator/hooks/index.d.ts +4 -0
  30. package/dist/types/Authenticator/hooks/types.d.ts +123 -0
  31. package/dist/types/Authenticator/hooks/useAuthenticator/__mock__/useAuthenticator.d.ts +4 -0
  32. package/dist/types/Authenticator/hooks/useAuthenticator/__tests__/useAuthenticator.spec.d.ts +1 -0
  33. package/dist/types/Authenticator/hooks/useAuthenticator/__tests__/utils.spec.d.ts +1 -0
  34. package/dist/types/Authenticator/hooks/useAuthenticator/constants.d.ts +0 -2
  35. package/dist/types/Authenticator/hooks/useAuthenticator/index.d.ts +1 -1
  36. package/dist/types/Authenticator/hooks/useAuthenticator/types.d.ts +3 -11
  37. package/dist/types/Authenticator/hooks/useAuthenticator/useAuthenticator.d.ts +2 -2
  38. package/dist/types/Authenticator/hooks/useAuthenticator/utils.d.ts +7 -6
  39. package/dist/types/Authenticator/hooks/useAuthenticatorInitMachine/__tests__/useAuthenticatorInitMachine.spec.d.ts +1 -0
  40. package/dist/types/Authenticator/hooks/useAuthenticatorInitMachine/index.d.ts +1 -0
  41. package/dist/types/Authenticator/hooks/useAuthenticatorInitMachine/useAuthenticatorInitMachine.d.ts +4 -0
  42. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/__tests__/useAuthenticatorRoute.spec.d.ts +1 -0
  43. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/__tests__/utils.spec.d.ts +1 -0
  44. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/constants.d.ts +4 -0
  45. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/index.d.ts +2 -0
  46. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/types.d.ts +38 -0
  47. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.d.ts +11 -0
  48. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/utils.d.ts +17 -0
  49. package/dist/types/Authenticator/hooks/utils.d.ts +4 -0
  50. package/dist/types/Authenticator/index.d.ts +3 -2
  51. package/dist/types/InAppMessaging/context/InAppMessagingContext/InAppMessagingContext.d.ts +9 -0
  52. package/dist/types/InAppMessaging/context/InAppMessagingContext/index.d.ts +1 -0
  53. package/dist/types/InAppMessaging/context/InAppMessagingProvider/InAppMessagingProvider.d.ts +5 -0
  54. package/dist/types/InAppMessaging/context/InAppMessagingProvider/__tests__/InAppMessagingProvider.spec.d.ts +1 -0
  55. package/dist/types/InAppMessaging/context/InAppMessagingProvider/index.d.ts +1 -0
  56. package/dist/types/InAppMessaging/context/index.d.ts +2 -0
  57. package/dist/types/InAppMessaging/hooks/index.d.ts +2 -0
  58. package/dist/types/InAppMessaging/hooks/useInAppMessaging/__tests__/useInAppMessaging.spec.d.ts +1 -0
  59. package/dist/types/InAppMessaging/hooks/useInAppMessaging/index.d.ts +1 -0
  60. package/dist/types/InAppMessaging/hooks/useInAppMessaging/useInAppMessaging.d.ts +7 -0
  61. package/dist/types/InAppMessaging/hooks/useMessage/__tests__/useMessage.spec.d.ts +1 -0
  62. package/dist/types/InAppMessaging/hooks/useMessage/__tests__/utils.spec.d.ts +1 -0
  63. package/dist/types/InAppMessaging/hooks/useMessage/index.d.ts +1 -0
  64. package/dist/types/InAppMessaging/hooks/useMessage/types.d.ts +18 -0
  65. package/dist/types/InAppMessaging/hooks/useMessage/useMessage.d.ts +9 -0
  66. package/dist/types/InAppMessaging/hooks/useMessage/utils.d.ts +9 -0
  67. package/dist/{esm/Authenticator/index.js → types/InAppMessaging/index.d.ts} +3 -1
  68. package/dist/types/InAppMessaging/types.d.ts +52 -0
  69. package/dist/types/InAppMessaging/utils/__tests__/handleMessageAction.spec.d.ts +1 -0
  70. package/dist/types/InAppMessaging/utils/handleMessageAction.d.ts +9 -0
  71. package/dist/types/InAppMessaging/utils/index.d.ts +1 -0
  72. package/dist/types/__tests__/index.spec.d.ts +1 -0
  73. package/dist/types/components/RenderNothing/RenderNothing.d.ts +4 -0
  74. package/dist/types/components/RenderNothing/__tests__/RenderNothing.spec.d.ts +1 -0
  75. package/dist/types/components/RenderNothing/index.d.ts +1 -0
  76. package/dist/types/components/index.d.ts +1 -0
  77. package/dist/types/hooks/__tests__/useHasValueUpdated.spec.d.ts +1 -0
  78. package/dist/types/hooks/__tests__/usePreviousValue.spec.d.ts +1 -0
  79. package/dist/types/hooks/index.d.ts +2 -0
  80. package/dist/types/hooks/useHasValueUpdated.d.ts +1 -0
  81. package/dist/types/hooks/usePreviousValue.d.ts +1 -0
  82. package/dist/types/index.d.ts +3 -1
  83. package/dist/types/utils/__tests__/index.spec.d.ts +1 -0
  84. package/package.json +13 -8
  85. package/dist/Authenticator/context/AuthenticatorContext.js +0 -11
  86. package/dist/Authenticator/context/AuthenticatorProvider.js +0 -26
  87. package/dist/Authenticator/context/index.js +0 -10
  88. package/dist/Authenticator/hooks/index.js +0 -4
  89. package/dist/Authenticator/hooks/useAuthenticator/constants.js +0 -16
  90. package/dist/Authenticator/hooks/useAuthenticator/index.js +0 -8
  91. package/dist/Authenticator/hooks/useAuthenticator/types.js +0 -2
  92. package/dist/Authenticator/hooks/useAuthenticator/useAuthenticator.js +0 -38
  93. package/dist/Authenticator/hooks/useAuthenticator/utils.js +0 -53
  94. package/dist/Authenticator/index.js +0 -5
  95. package/dist/esm/Authenticator/context/index.js +0 -2
  96. package/dist/esm/Authenticator/hooks/index.js +0 -1
  97. package/dist/esm/Authenticator/hooks/useAuthenticator/index.js +0 -1
  98. package/dist/utils/index.js +0 -20
@@ -1,7 +1,10 @@
1
1
  import React from 'react';
2
+
2
3
  /**
3
4
  * AuthenticatorContext serves static reference to the auth machine service.
4
5
  *
5
6
  * https://xstate.js.org/docs/recipes/react.html#context-provider
6
7
  */
7
- export const AuthenticatorContext = React.createContext(null);
8
+ const AuthenticatorContext = React.createContext(null);
9
+
10
+ export { AuthenticatorContext };
@@ -1,8 +1,10 @@
1
- import React, { useContext, useEffect, useMemo } from 'react';
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useContext, useMemo, useEffect } from 'react';
2
3
  import { useInterpret } from '@xstate/react';
3
4
  import { createAuthenticatorMachine, listenToAuthHub } from '@aws-amplify/ui';
4
- import { AuthenticatorContext } from './AuthenticatorContext';
5
- export default function AuthenticatorProvider({ children, }) {
5
+ import { AuthenticatorContext } from './AuthenticatorContext.js';
6
+
7
+ function AuthenticatorProvider({ children, }) {
6
8
  /**
7
9
  * Based on use cases, developer might already have added another Provider
8
10
  * outside Authenticator. In that case, we sync the two providers by just
@@ -18,5 +20,7 @@ export default function AuthenticatorProvider({ children, }) {
18
20
  const unsubscribe = listenToAuthHub(activeService);
19
21
  return unsubscribe;
20
22
  }, [activeService]);
21
- return (React.createElement(AuthenticatorContext.Provider, { value: value }, children));
23
+ return (jsx(AuthenticatorContext.Provider, Object.assign({ value: value }, { children: children })));
22
24
  }
25
+
26
+ export { AuthenticatorProvider as default };
@@ -0,0 +1,26 @@
1
+ const COMPONENT_ROUTE_KEYS = [
2
+ 'confirmResetPassword',
3
+ 'confirmSignIn',
4
+ 'confirmSignUp',
5
+ 'confirmVerifyUser',
6
+ 'forceNewPassword',
7
+ 'resetPassword',
8
+ 'setupTOTP',
9
+ 'signIn',
10
+ 'signUp',
11
+ 'verifyUser',
12
+ ];
13
+ const COMPONENT_ROUTE_NAMES = [
14
+ 'ConfirmResetPassword',
15
+ 'ConfirmSignIn',
16
+ 'ConfirmSignUp',
17
+ 'ConfirmVerifyUser',
18
+ 'ForceNewPassword',
19
+ 'ResetPassword',
20
+ 'SetupTOTP',
21
+ 'SignIn',
22
+ 'SignUp',
23
+ 'VerifyUser',
24
+ ];
25
+
26
+ export { COMPONENT_ROUTE_KEYS, COMPONENT_ROUTE_NAMES };
@@ -1,13 +1,3 @@
1
- export const USE_AUTHENTICATOR_ERROR = '`useAuthenticator` must be used inside an `Authenticator.Provider`.';
2
- export const COMPONENT_ROUTE_KEYS = [
3
- 'signIn',
4
- 'signUp',
5
- 'forceNewPassword',
6
- 'confirmResetPassword',
7
- 'confirmSignIn',
8
- 'confirmSignUp',
9
- 'confirmVerifyUser',
10
- 'resetPassword',
11
- 'setupTOTP',
12
- 'verifyUser',
13
- ];
1
+ const USE_AUTHENTICATOR_ERROR = '`useAuthenticator` must be used inside an `Authenticator.Provider`.';
2
+
3
+ export { USE_AUTHENTICATOR_ERROR };
@@ -1,14 +1,16 @@
1
- import { __rest } from "tslib";
1
+ import { __rest } from '../../../node_modules/tslib/tslib.es6.js';
2
2
  import React, { useCallback, useMemo } from 'react';
3
3
  import { useSelector } from '@xstate/react';
4
4
  import { getServiceFacade } from '@aws-amplify/ui';
5
- import { AuthenticatorContext } from '../../context';
6
- import { USE_AUTHENTICATOR_ERROR } from './constants';
7
- import { defaultComparator, getComparator, getLegacyFields, getTotpSecretCodeCallback, } from './utils';
5
+ import 'react/jsx-runtime';
6
+ import { AuthenticatorContext } from '../../context/AuthenticatorContext.js';
7
+ import { USE_AUTHENTICATOR_ERROR } from './constants.js';
8
+ import { getMachineFields, getTotpSecretCodeCallback, getComparator, defaultComparator } from './utils.js';
9
+
8
10
  /**
9
11
  * [📖 Docs](https://ui.docs.amplify.aws/react/connected-components/authenticator/headless#useauthenticator-hook)
10
12
  */
11
- export default function useAuthenticator(selector) {
13
+ function useAuthenticator(selector) {
12
14
  const context = React.useContext(AuthenticatorContext);
13
15
  if (!context) {
14
16
  throw new Error(USE_AUTHENTICATOR_ERROR);
@@ -18,18 +20,17 @@ export default function useAuthenticator(selector) {
18
20
  const xstateSelector = useCallback((state) => (Object.assign({}, getServiceFacade({ send, state }))), [send]);
19
21
  const comparator = selector ? getComparator(selector) : defaultComparator;
20
22
  const facade = useSelector(service, xstateSelector, comparator);
21
- const { route, user } = facade, rest = __rest(facade, ["route", "user"]);
23
+ const { route, unverifiedContactMethods, user } = facade, rest = __rest(facade, ["route", "unverifiedContactMethods", "user"]);
22
24
  // do not memoize output. `service.getSnapshot` reference remains stable preventing
23
25
  // `fields` from updating with current form state on value changes
24
26
  const serviceSnapshot = service.getSnapshot();
25
27
  // legacy `formFields` values required until form state is removed from state machine
26
- const fields = useMemo(() => getLegacyFields(route, serviceSnapshot), [route, serviceSnapshot]);
28
+ const fields = useMemo(() => getMachineFields(route, serviceSnapshot, unverifiedContactMethods), [route, serviceSnapshot, unverifiedContactMethods]);
27
29
  return Object.assign(Object.assign({}, rest), { getTotpSecretCode: getTotpSecretCodeCallback(user), route,
30
+ unverifiedContactMethods,
28
31
  user,
29
32
  /** @deprecated For internal use only */
30
- fields,
31
- /** @deprecated For internal use only */
32
- _state: serviceSnapshot,
33
- /** @deprecated For internal use only */
34
- _send: send });
33
+ fields });
35
34
  }
35
+
36
+ export { useAuthenticator as default };
@@ -1,14 +1,16 @@
1
- import { __awaiter } from "tslib";
1
+ import { __awaiter } from '../../../node_modules/tslib/tslib.es6.js';
2
2
  import { Auth } from 'aws-amplify';
3
- import { getSortedFormFields, } from '@aws-amplify/ui';
4
- import { areEmptyArrays, areEmptyObjects } from '../../../utils';
5
- import { COMPONENT_ROUTE_KEYS } from './constants';
6
- export const defaultComparator = () => false;
3
+ import { getSortedFormFields } from '@aws-amplify/ui';
4
+ import isString from 'lodash/isString';
5
+ import { areEmptyArrays, areEmptyObjects } from '../../../utils/index.js';
6
+ import { isComponentRouteKey } from '../utils.js';
7
+
8
+ const defaultComparator = () => false;
7
9
  /**
8
10
  * Does an ordering and shallow comparison of each array value,
9
11
  * plus a value equality check for empty objects and arrays.
10
12
  */
11
- export function areSelectorDepsEqual(currentDeps, nextDeps) {
13
+ function areSelectorDepsEqual(currentDeps, nextDeps) {
12
14
  if (currentDeps.length !== nextDeps.length) {
13
15
  return false;
14
16
  }
@@ -21,24 +23,39 @@ export function areSelectorDepsEqual(currentDeps, nextDeps) {
21
23
  return currentDep === nextDep;
22
24
  });
23
25
  }
24
- export const getComparator = (selector) => (currentFacade, nextFacade) => {
26
+ const getComparator = (selector) => (currentFacade, nextFacade) => {
25
27
  const currentSelectorDeps = selector(currentFacade);
26
28
  const nextSelectorDeps = selector(nextFacade);
27
29
  // Shallow compare the array values
28
30
  return areSelectorDepsEqual(currentSelectorDeps, nextSelectorDeps);
29
31
  };
30
- export const getTotpSecretCodeCallback = (user) => function getTotpSecretCode() {
32
+ const getTotpSecretCodeCallback = (user) => function getTotpSecretCode() {
31
33
  return __awaiter(this, void 0, void 0, function* () {
32
34
  return yield Auth.setupTOTP(user);
33
35
  });
34
36
  };
35
- export const isComponentRouteKey = (route) => COMPONENT_ROUTE_KEYS.some((componentRoute) => componentRoute === route);
36
37
  const flattenFormFields = (fields) => fields.flatMap(([name, options]) => (Object.assign({ name }, options)));
38
+ const convertContactMethodsToFields = (unverifiedContactMethods) => {
39
+ return (unverifiedContactMethods &&
40
+ Object.entries(unverifiedContactMethods).map(([name, value]) => {
41
+ const valueIsString = isString(value);
42
+ if (!valueIsString || !name) {
43
+ return {};
44
+ }
45
+ return { name, label: value, type: 'radio', value };
46
+ }));
47
+ };
37
48
  /**
38
- * Retrieves legacy form field values from state machine for routes that have fields
49
+ * Retrieves default and custom (RWA only, to be updated) form field values from state machine
50
+ * for subcomponent routes that render fields
39
51
  */
40
- export const getLegacyFields = (route, state) =>
41
- // verifyUser is a component route, but does not have form fields
42
- isComponentRouteKey(route) && route !== 'verifyUser'
43
- ? flattenFormFields(getSortedFormFields(route, state))
44
- : [];
52
+ const getMachineFields = (route, state, unverifiedContactMethods) => {
53
+ if (isComponentRouteKey(route)) {
54
+ return route === 'verifyUser'
55
+ ? convertContactMethodsToFields(unverifiedContactMethods)
56
+ : flattenFormFields(getSortedFormFields(route, state));
57
+ }
58
+ return [];
59
+ };
60
+
61
+ export { areSelectorDepsEqual, defaultComparator, getComparator, getMachineFields, getTotpSecretCodeCallback };
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import useAuthenticator from '../useAuthenticator/useAuthenticator.js';
3
+
4
+ // only select `route` from machine context
5
+ const routeSelector = ({ route }) => [route];
6
+ function useAuthenticatorInitMachine(data) {
7
+ const { route, initializeMachine } = useAuthenticator(routeSelector);
8
+ const hasInitialized = React.useRef(false);
9
+ React.useEffect(() => {
10
+ if (!hasInitialized.current && route === 'setup') {
11
+ initializeMachine(data);
12
+ hasInitialized.current = true;
13
+ }
14
+ }, [initializeMachine, route, data]);
15
+ }
16
+
17
+ export { useAuthenticatorInitMachine as default, routeSelector };
@@ -0,0 +1,73 @@
1
+ const EVENT_HANDLER_KEY_MAP = {
2
+ updateBlur: 'handleBlur',
3
+ updateForm: 'handleChange',
4
+ submitForm: 'handleSubmit',
5
+ };
6
+ const COMMON_ROUTE_MACHINE_KEYS = [
7
+ 'error',
8
+ 'isPending',
9
+ 'submitForm',
10
+ 'updateBlur',
11
+ 'updateForm',
12
+ ];
13
+ const CONFIRM_RESET_PASSWORD_MACHINE_KEYS = [
14
+ ...COMMON_ROUTE_MACHINE_KEYS,
15
+ 'resendCode',
16
+ 'validationErrors',
17
+ ];
18
+ const CONFIRM_SIGN_IN_MACHINE_KEYS = [
19
+ ...COMMON_ROUTE_MACHINE_KEYS,
20
+ 'toSignIn',
21
+ 'user',
22
+ ];
23
+ const CONFIRM_SIGN_UP_MACHINE_KEYS = [
24
+ ...COMMON_ROUTE_MACHINE_KEYS,
25
+ 'codeDeliveryDetails',
26
+ 'resendCode',
27
+ ];
28
+ const CONFIRM_VERIFY_USER_MACHINE_KEYS = [
29
+ ...COMMON_ROUTE_MACHINE_KEYS,
30
+ 'skipVerification',
31
+ ];
32
+ const FORCE_NEW_PASSWORD_MACHINE_KEYS = [
33
+ ...COMMON_ROUTE_MACHINE_KEYS,
34
+ 'toSignIn',
35
+ 'validationErrors',
36
+ ];
37
+ const RESET_PASSWORD_MACHINE_KEYS = [
38
+ ...COMMON_ROUTE_MACHINE_KEYS,
39
+ 'toSignIn',
40
+ ];
41
+ const SIGN_IN_MACHINE_KEYS = [
42
+ ...COMMON_ROUTE_MACHINE_KEYS,
43
+ 'toFederatedSignIn',
44
+ 'toResetPassword',
45
+ 'toSignUp',
46
+ ];
47
+ const SIGN_UP_MACHINE_KEYS = [
48
+ ...COMMON_ROUTE_MACHINE_KEYS,
49
+ 'toSignIn',
50
+ 'validationErrors',
51
+ ];
52
+ const SETUP_TOTP_MACHINE_KEYS = [
53
+ ...COMMON_ROUTE_MACHINE_KEYS,
54
+ 'toSignIn',
55
+ ];
56
+ const VERIFY_USER_MACHINE_KEYS = [
57
+ ...COMMON_ROUTE_MACHINE_KEYS,
58
+ 'skipVerification',
59
+ ];
60
+ const MACHINE_PROP_KEYS = {
61
+ confirmResetPassword: CONFIRM_RESET_PASSWORD_MACHINE_KEYS,
62
+ confirmSignIn: CONFIRM_SIGN_IN_MACHINE_KEYS,
63
+ confirmSignUp: CONFIRM_SIGN_UP_MACHINE_KEYS,
64
+ confirmVerifyUser: CONFIRM_VERIFY_USER_MACHINE_KEYS,
65
+ forceNewPassword: FORCE_NEW_PASSWORD_MACHINE_KEYS,
66
+ signIn: SIGN_IN_MACHINE_KEYS,
67
+ signUp: SIGN_UP_MACHINE_KEYS,
68
+ resetPassword: RESET_PASSWORD_MACHINE_KEYS,
69
+ setupTOTP: SETUP_TOTP_MACHINE_KEYS,
70
+ verifyUser: VERIFY_USER_MACHINE_KEYS,
71
+ };
72
+
73
+ export { EVENT_HANDLER_KEY_MAP, MACHINE_PROP_KEYS };
@@ -0,0 +1,52 @@
1
+ import { useMemo } from 'react';
2
+ import useAuthenticator from '../useAuthenticator/useAuthenticator.js';
3
+ import { getRouteMachineSelector, resolveDefault, resolveVerifyUserRoute, resolveSignUpRoute, resolveSignInRoute, resolveSetupTOTPRoute, resolveResetPasswordRoute, resolveForceNewPasswordRoute, resolveConfirmVerifyUserRoute, resolveConfirmSignUpRoute, resolveConfirmSignInRoute, resolveConfirmResetPasswordRoute, routeSelector } from './utils.js';
4
+
5
+ function useAuthenticatorRoute({ components, }) {
6
+ const { route } = useAuthenticator(routeSelector);
7
+ const routeMachineSelector = useMemo(() => getRouteMachineSelector(route), [route]);
8
+ // `useAuthenticator` exposes both state machine (example: `toSignIn`) and non-state machine
9
+ // props (example: `getTotpSecretCode`). `routeSelector` specifies which state machine props
10
+ // should be returned for a specific route.
11
+ // Only state machine props specified by the current `routeSelector` will have their current value
12
+ // returned by `useAuthenticator`, non-machine props returned will always be the current value
13
+ const routeSelectorProps = useAuthenticator(routeMachineSelector);
14
+ const { ConfirmResetPassword, ConfirmSignIn, ConfirmSignUp, ConfirmVerifyUser, ForceNewPassword, ResetPassword, SetupTOTP, SignIn, SignUp, VerifyUser, } = components;
15
+ switch (route) {
16
+ case 'confirmResetPassword': {
17
+ return resolveConfirmResetPasswordRoute(ConfirmResetPassword, routeSelectorProps);
18
+ }
19
+ case 'confirmSignIn': {
20
+ return resolveConfirmSignInRoute(ConfirmSignIn, routeSelectorProps);
21
+ }
22
+ case 'confirmSignUp': {
23
+ return resolveConfirmSignUpRoute(ConfirmSignUp, routeSelectorProps);
24
+ }
25
+ case 'confirmVerifyUser': {
26
+ return resolveConfirmVerifyUserRoute(ConfirmVerifyUser, routeSelectorProps);
27
+ }
28
+ case 'forceNewPassword': {
29
+ return resolveForceNewPasswordRoute(ForceNewPassword, routeSelectorProps);
30
+ }
31
+ case 'resetPassword': {
32
+ return resolveResetPasswordRoute(ResetPassword, routeSelectorProps);
33
+ }
34
+ case 'setupTOTP': {
35
+ return resolveSetupTOTPRoute(SetupTOTP, routeSelectorProps);
36
+ }
37
+ case 'signIn': {
38
+ return resolveSignInRoute(SignIn, routeSelectorProps);
39
+ }
40
+ case 'signUp': {
41
+ return resolveSignUpRoute(SignUp, routeSelectorProps);
42
+ }
43
+ case 'verifyUser': {
44
+ return resolveVerifyUserRoute(VerifyUser, routeSelectorProps);
45
+ }
46
+ default: {
47
+ return resolveDefault();
48
+ }
49
+ }
50
+ }
51
+
52
+ export { useAuthenticatorRoute as default };
@@ -0,0 +1,89 @@
1
+ import { __rest } from '../../../node_modules/tslib/tslib.es6.js';
2
+ import RenderNothing from '../../../components/RenderNothing/RenderNothing.js';
3
+ import { isComponentRouteKey } from '../utils.js';
4
+ import { MACHINE_PROP_KEYS, EVENT_HANDLER_KEY_MAP } from './constants.js';
5
+
6
+ // only select `route` from machine context
7
+ const routeSelector = ({ route }) => [route];
8
+ const createSelector = (selectorKeys) => (context) => {
9
+ const dependencies = selectorKeys.map((key) => context[key]);
10
+ // route should always be part of deps, so hook knows when route changes.
11
+ return [...dependencies, context.route];
12
+ };
13
+ const getRouteMachineSelector = (route) => isComponentRouteKey(route)
14
+ ? createSelector(MACHINE_PROP_KEYS[route])
15
+ : routeSelector;
16
+ const isFormEventHandlerKey = (key) => ['updateBlur', 'updateForm', 'submitForm'].includes(key);
17
+ const convertEventHandlerKey = (key) => EVENT_HANDLER_KEY_MAP[key];
18
+ const getConvertedMachineProps = (route, context) => MACHINE_PROP_KEYS[route].reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [isFormEventHandlerKey(key) ? convertEventHandlerKey(key) : key]: context[key] })), {});
19
+ function resolveConfirmResetPasswordRoute(Component, props) {
20
+ return {
21
+ Component,
22
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmResetPassword', props)),
23
+ };
24
+ }
25
+ function resolveConfirmSignInRoute(Component, props) {
26
+ const _a = getConvertedMachineProps('confirmSignIn', props), { user } = _a, machineProps = __rest(_a, ["user"]);
27
+ // prior to the `confirmSignIn` route, `user.username` is populated
28
+ const challengeName = user.challengeName;
29
+ return { Component, props: Object.assign(Object.assign(Object.assign({}, Component), machineProps), { challengeName }) };
30
+ }
31
+ function resolveConfirmSignUpRoute(Component, props) {
32
+ return {
33
+ Component,
34
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmSignUp', props)),
35
+ };
36
+ }
37
+ function resolveConfirmVerifyUserRoute(Component, props) {
38
+ return {
39
+ Component,
40
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmVerifyUser', props)),
41
+ };
42
+ }
43
+ function resolveForceNewPasswordRoute(Component, props) {
44
+ return {
45
+ Component,
46
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('forceNewPassword', props)),
47
+ };
48
+ }
49
+ function resolveResetPasswordRoute(Component, props) {
50
+ return {
51
+ Component,
52
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('resetPassword', props)),
53
+ };
54
+ }
55
+ function resolveSetupTOTPRoute(Component, _a) {
56
+ var { getTotpSecretCode } = _a, props = __rest(_a, ["getTotpSecretCode"]);
57
+ return {
58
+ Component,
59
+ props: Object.assign(Object.assign(Object.assign({}, Component), getConvertedMachineProps('setupTOTP', props)), { getTotpSecretCode }),
60
+ };
61
+ }
62
+ function resolveSignInRoute(Component, props) {
63
+ // default `hideSignUp` to false
64
+ const hideSignUp = false;
65
+ return {
66
+ Component,
67
+ props: Object.assign(Object.assign(Object.assign({}, Component), getConvertedMachineProps('signIn', props)), { hideSignUp }),
68
+ };
69
+ }
70
+ function resolveSignUpRoute(Component, props) {
71
+ return {
72
+ Component,
73
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('signUp', props)),
74
+ };
75
+ }
76
+ function resolveVerifyUserRoute(Component, props) {
77
+ return {
78
+ Component,
79
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('verifyUser', props)),
80
+ };
81
+ }
82
+ function resolveDefault() {
83
+ return {
84
+ Component: RenderNothing,
85
+ props: {},
86
+ };
87
+ }
88
+
89
+ export { getRouteMachineSelector, resolveConfirmResetPasswordRoute, resolveConfirmSignInRoute, resolveConfirmSignUpRoute, resolveConfirmVerifyUserRoute, resolveDefault, resolveForceNewPasswordRoute, resolveResetPasswordRoute, resolveSetupTOTPRoute, resolveSignInRoute, resolveSignUpRoute, resolveVerifyUserRoute, routeSelector };
@@ -0,0 +1,24 @@
1
+ import { COMPONENT_ROUTE_KEYS, COMPONENT_ROUTE_NAMES } from './constants.js';
2
+
3
+ const isComponentRouteKey = (route) => COMPONENT_ROUTE_KEYS.some((componentRoute) => componentRoute === route);
4
+ function resolveAuthenticatorComponents(defaults, overrides) {
5
+ if (!overrides) {
6
+ return defaults;
7
+ }
8
+ return COMPONENT_ROUTE_NAMES.reduce((components, route) => {
9
+ const Default = defaults[route];
10
+ const Override = overrides[route];
11
+ if (typeof Override !== 'function') {
12
+ return Object.assign(Object.assign({}, components), { [route]: Default });
13
+ }
14
+ const { Footer, FormFields, Header } = Default;
15
+ // cast to allow assigning of component slots
16
+ const Component = Override;
17
+ Component.Footer = Footer;
18
+ Component.FormFields = FormFields;
19
+ Component.Header = Header;
20
+ return Object.assign(Object.assign({}, components), { [route]: Component });
21
+ }, {});
22
+ }
23
+
24
+ export { isComponentRouteKey, resolveAuthenticatorComponents };
@@ -0,0 +1,5 @@
1
+ import { createContext } from 'react';
2
+
3
+ const InAppMessagingContext = createContext(null);
4
+
5
+ export { InAppMessagingContext as default };
@@ -0,0 +1,26 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useState, useEffect, useCallback, useMemo } from 'react';
3
+ import { Notifications } from '@aws-amplify/notifications';
4
+ import InAppMessagingContext from '../InAppMessagingContext/InAppMessagingContext.js';
5
+
6
+ const { InAppMessaging } = Notifications;
7
+ function InAppMessagingProvider({ children, }) {
8
+ const [message, setMessage] = useState(null);
9
+ useEffect(() => {
10
+ const listener = InAppMessaging.onMessageReceived((message) => {
11
+ setMessage(message);
12
+ });
13
+ return listener.remove;
14
+ }, []);
15
+ const clearMessage = useCallback(() => {
16
+ setMessage(null);
17
+ }, []);
18
+ const value = useMemo(() => ({
19
+ clearMessage,
20
+ displayMessage: setMessage,
21
+ message,
22
+ }), [clearMessage, message]);
23
+ return (jsx(InAppMessagingContext.Provider, Object.assign({ value: value }, { children: children })));
24
+ }
25
+
26
+ export { InAppMessagingProvider as default };
@@ -0,0 +1,19 @@
1
+ import { useContext } from 'react';
2
+ import InAppMessagingContext from '../../context/InAppMessagingContext/InAppMessagingContext.js';
3
+ import 'react/jsx-runtime';
4
+ import '@aws-amplify/notifications';
5
+
6
+ /**
7
+ * Utility hook used to access the InAppMessagingContext values
8
+ *
9
+ * @returns {InAppMessagingContextType} InAppMessaging context values
10
+ */
11
+ function useInAppMessaging() {
12
+ const inAppMessagingContext = useContext(InAppMessagingContext);
13
+ if (!inAppMessagingContext) {
14
+ throw new Error('InAppMessagingContext is empty, did you forget the InAppMessagingProvider?');
15
+ }
16
+ return inAppMessagingContext;
17
+ }
18
+
19
+ export { useInAppMessaging as default };
@@ -0,0 +1,78 @@
1
+ import { ConsoleLogger } from '@aws-amplify/core';
2
+ import { InAppMessageInteractionEvent, Notifications } from '@aws-amplify/notifications';
3
+ import isNil from 'lodash/isNil';
4
+ import RenderNothing from '../../../components/RenderNothing/RenderNothing.js';
5
+ import useInAppMessaging from '../useInAppMessaging/useInAppMessaging.js';
6
+ import { getContentProps, getPositionProp } from './utils.js';
7
+
8
+ const EMPTY_PROPS = Object.freeze({});
9
+ const logger = new ConsoleLogger('Notifications.InAppMessaging');
10
+ const { InAppMessaging } = Notifications;
11
+ /**
12
+ * Utility hook for parsing a message and retrieving its corresponding UI component and props
13
+ *
14
+ * @param {UseMessageParams} props - platform specific UI components, action handler, and styles
15
+ * @returns {UseMessage} message UI component and props
16
+ */
17
+ function useMessage({ components, onMessageAction, }) {
18
+ const { clearMessage, message } = useInAppMessaging();
19
+ const { BannerMessage, CarouselMessage, FullScreenMessage, ModalMessage } = components;
20
+ if (isNil(message)) {
21
+ return {
22
+ Component: RenderNothing,
23
+ props: EMPTY_PROPS,
24
+ };
25
+ }
26
+ const { content, layout } = message;
27
+ const onActionCallback = () => {
28
+ InAppMessaging.notifyMessageInteraction(message, InAppMessageInteractionEvent.MESSAGE_ACTION_TAKEN);
29
+ clearMessage();
30
+ };
31
+ const onClose = () => {
32
+ InAppMessaging.notifyMessageInteraction(message, InAppMessageInteractionEvent.MESSAGE_DISMISSED);
33
+ clearMessage();
34
+ };
35
+ const onDisplay = () => {
36
+ InAppMessaging.notifyMessageInteraction(message, InAppMessageInteractionEvent.MESSAGE_DISPLAYED);
37
+ };
38
+ switch (layout) {
39
+ case 'BOTTOM_BANNER':
40
+ case 'MIDDLE_BANNER':
41
+ case 'TOP_BANNER': {
42
+ const props = Object.assign(Object.assign({}, getContentProps(content === null || content === void 0 ? void 0 : content[0], onMessageAction, onActionCallback)), { layout,
43
+ onClose,
44
+ onDisplay, position: getPositionProp(layout) });
45
+ return { Component: BannerMessage, props };
46
+ }
47
+ case 'CAROUSEL': {
48
+ const props = {
49
+ data: content === null || content === void 0 ? void 0 : content.map((item) => getContentProps(item, onMessageAction, onActionCallback)),
50
+ layout,
51
+ onClose,
52
+ onDisplay,
53
+ };
54
+ return { Component: CarouselMessage, props };
55
+ }
56
+ case 'FULL_SCREEN': {
57
+ const props = Object.assign(Object.assign({}, getContentProps(content === null || content === void 0 ? void 0 : content[0], onMessageAction, onActionCallback)), { layout,
58
+ onClose,
59
+ onDisplay });
60
+ return { Component: FullScreenMessage, props };
61
+ }
62
+ case 'MODAL': {
63
+ const props = Object.assign(Object.assign({}, getContentProps(content === null || content === void 0 ? void 0 : content[0], onMessageAction, onActionCallback)), { layout,
64
+ onClose,
65
+ onDisplay });
66
+ return { Component: ModalMessage, props };
67
+ }
68
+ default: {
69
+ logger.info(`Received unknown InAppMessage layout: ${layout}`);
70
+ return {
71
+ Component: RenderNothing,
72
+ props: EMPTY_PROPS,
73
+ };
74
+ }
75
+ }
76
+ }
77
+
78
+ export { EMPTY_PROPS, useMessage as default };
@@ -0,0 +1,43 @@
1
+ import { __rest } from '../../../node_modules/tslib/tslib.es6.js';
2
+ import { ConsoleLogger } from '@aws-amplify/core';
3
+
4
+ const logger = new ConsoleLogger('Notifications.InAppMessaging');
5
+ const positions = {
6
+ BOTTOM_BANNER: 'bottom',
7
+ MIDDLE_BANNER: 'middle',
8
+ TOP_BANNER: 'top',
9
+ };
10
+ const getPositionProp = (layout) => positions[layout];
11
+ const getActionHandler = (actionParams, onMessageAction, onActionCallback) => ({
12
+ onAction() {
13
+ try {
14
+ onMessageAction(actionParams);
15
+ }
16
+ catch (e) {
17
+ logger.error(`Message action failure: ${e}`);
18
+ }
19
+ finally {
20
+ onActionCallback();
21
+ }
22
+ },
23
+ });
24
+ const getButtonProps = (_a, onMessageAction, onActionCallback) => {
25
+ var { action, url } = _a, baseButtonProps = __rest(_a, ["action", "url"]);
26
+ return (Object.assign(Object.assign({}, baseButtonProps), getActionHandler({ action, url }, onMessageAction, onActionCallback)));
27
+ };
28
+ const getContentProps = (content, onMessageAction, onActionCallback) => {
29
+ const props = {};
30
+ if (!content) {
31
+ return props;
32
+ }
33
+ const { primaryButton, secondaryButton } = content, restContent = __rest(content, ["primaryButton", "secondaryButton"]);
34
+ if (primaryButton) {
35
+ props.primaryButton = getButtonProps(primaryButton, onMessageAction, onActionCallback);
36
+ }
37
+ if (secondaryButton) {
38
+ props.secondaryButton = getButtonProps(secondaryButton, onMessageAction, onActionCallback);
39
+ }
40
+ return Object.assign(Object.assign({}, props), restContent);
41
+ };
42
+
43
+ export { getActionHandler, getContentProps, getPositionProp };
@@ -0,0 +1,16 @@
1
+ import { ConsoleLogger } from '@aws-amplify/core';
2
+ import isString from 'lodash/isString';
3
+
4
+ const logger = new ConsoleLogger('Notifications.InAppMessaging');
5
+ const handleMessageAction = ({ action, handleMessageLinkAction, url, }) => {
6
+ logger.info(`Handle action: ${action}`);
7
+ if (action === 'LINK' || action === 'DEEP_LINK') {
8
+ if (!isString(url)) {
9
+ logger.warn(`url must be of type string: ${url}`);
10
+ return;
11
+ }
12
+ handleMessageLinkAction(url);
13
+ }
14
+ };
15
+
16
+ export { handleMessageAction as default };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Utility component for rendering nothing.
3
+ */
4
+ function RenderNothing(_) {
5
+ return null;
6
+ }
7
+
8
+ export { RenderNothing as default };