@aws-amplify/ui-react-core 2.0.0 → 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 (46) hide show
  1. package/dist/esm/Authenticator/hooks/constants.js +26 -0
  2. package/dist/esm/Authenticator/hooks/useAuthenticator/constants.js +1 -13
  3. package/dist/esm/Authenticator/hooks/useAuthenticator/useAuthenticator.js +4 -3
  4. package/dist/esm/Authenticator/hooks/useAuthenticator/utils.js +23 -9
  5. package/dist/esm/Authenticator/hooks/useAuthenticatorInitMachine/useAuthenticatorInitMachine.js +17 -0
  6. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/constants.js +73 -0
  7. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.js +52 -0
  8. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/utils.js +89 -0
  9. package/dist/esm/Authenticator/hooks/utils.js +24 -0
  10. package/dist/esm/InAppMessaging/hooks/useMessage/useMessage.js +3 -3
  11. package/dist/esm/components/RenderNothing/RenderNothing.js +2 -2
  12. package/dist/esm/hooks/useHasValueUpdated.js +13 -0
  13. package/dist/esm/hooks/usePreviousValue.js +13 -0
  14. package/dist/esm/index.js +5 -0
  15. package/dist/index.js +322 -32
  16. package/dist/types/Authenticator/hooks/__mock__/components.d.ts +7 -0
  17. package/dist/types/Authenticator/hooks/__tests__/utils.spec.d.ts +1 -0
  18. package/dist/types/Authenticator/hooks/constants.d.ts +3 -0
  19. package/dist/types/Authenticator/hooks/index.d.ts +4 -0
  20. package/dist/types/Authenticator/hooks/types.d.ts +123 -0
  21. package/dist/types/Authenticator/hooks/useAuthenticator/__mock__/useAuthenticator.d.ts +4 -0
  22. package/dist/types/Authenticator/hooks/useAuthenticator/constants.d.ts +0 -2
  23. package/dist/types/Authenticator/hooks/useAuthenticator/index.d.ts +1 -1
  24. package/dist/types/Authenticator/hooks/useAuthenticator/types.d.ts +2 -2
  25. package/dist/types/Authenticator/hooks/useAuthenticator/useAuthenticator.d.ts +2 -2
  26. package/dist/types/Authenticator/hooks/useAuthenticator/utils.d.ts +7 -6
  27. package/dist/types/Authenticator/hooks/useAuthenticatorInitMachine/__tests__/useAuthenticatorInitMachine.spec.d.ts +1 -0
  28. package/dist/types/Authenticator/hooks/useAuthenticatorInitMachine/index.d.ts +1 -0
  29. package/dist/types/Authenticator/hooks/useAuthenticatorInitMachine/useAuthenticatorInitMachine.d.ts +4 -0
  30. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/__tests__/useAuthenticatorRoute.spec.d.ts +1 -0
  31. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/__tests__/utils.spec.d.ts +1 -0
  32. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/constants.d.ts +4 -0
  33. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/index.d.ts +2 -0
  34. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/types.d.ts +38 -0
  35. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.d.ts +11 -0
  36. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/utils.d.ts +17 -0
  37. package/dist/types/Authenticator/hooks/utils.d.ts +4 -0
  38. package/dist/types/Authenticator/index.d.ts +3 -2
  39. package/dist/types/components/RenderNothing/RenderNothing.d.ts +1 -1
  40. package/dist/types/hooks/__tests__/useHasValueUpdated.spec.d.ts +1 -0
  41. package/dist/types/hooks/__tests__/usePreviousValue.spec.d.ts +1 -0
  42. package/dist/types/hooks/index.d.ts +2 -0
  43. package/dist/types/hooks/useHasValueUpdated.d.ts +1 -0
  44. package/dist/types/hooks/usePreviousValue.d.ts +1 -0
  45. package/dist/types/index.d.ts +2 -1
  46. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -7,20 +7,22 @@ var React = require('react');
7
7
  var react = require('@xstate/react');
8
8
  var ui = require('@aws-amplify/ui');
9
9
  var awsAmplify = require('aws-amplify');
10
+ var isString = require('lodash/isString');
10
11
  var isEmpty = require('lodash/isEmpty');
11
12
  var isObject = require('lodash/isObject');
12
13
  var notifications = require('@aws-amplify/notifications');
13
14
  var core = require('@aws-amplify/core');
14
15
  var isNil = require('lodash/isNil');
15
- var isString = require('lodash/isString');
16
+ var isUndefined = require('lodash/isUndefined');
16
17
 
17
18
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
18
19
 
19
20
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
21
+ var isString__default = /*#__PURE__*/_interopDefaultLegacy(isString);
20
22
  var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
21
23
  var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
22
24
  var isNil__default = /*#__PURE__*/_interopDefaultLegacy(isNil);
23
- var isString__default = /*#__PURE__*/_interopDefaultLegacy(isString);
25
+ var isUndefined__default = /*#__PURE__*/_interopDefaultLegacy(isUndefined);
24
26
 
25
27
  /**
26
28
  * AuthenticatorContext serves static reference to the auth machine service.
@@ -86,18 +88,6 @@ function __awaiter(thisArg, _arguments, P, generator) {
86
88
  }
87
89
 
88
90
  const USE_AUTHENTICATOR_ERROR = '`useAuthenticator` must be used inside an `Authenticator.Provider`.';
89
- const COMPONENT_ROUTE_KEYS = [
90
- 'signIn',
91
- 'signUp',
92
- 'forceNewPassword',
93
- 'confirmResetPassword',
94
- 'confirmSignIn',
95
- 'confirmSignUp',
96
- 'confirmVerifyUser',
97
- 'resetPassword',
98
- 'setupTOTP',
99
- 'verifyUser',
100
- ];
101
91
 
102
92
  function isEmptyArray(value) {
103
93
  return Array.isArray(value) && isEmpty__default["default"](value);
@@ -112,6 +102,52 @@ function areEmptyObjects(...values) {
112
102
  return values.every(isEmptyObject);
113
103
  }
114
104
 
105
+ const COMPONENT_ROUTE_KEYS = [
106
+ 'confirmResetPassword',
107
+ 'confirmSignIn',
108
+ 'confirmSignUp',
109
+ 'confirmVerifyUser',
110
+ 'forceNewPassword',
111
+ 'resetPassword',
112
+ 'setupTOTP',
113
+ 'signIn',
114
+ 'signUp',
115
+ 'verifyUser',
116
+ ];
117
+ const COMPONENT_ROUTE_NAMES = [
118
+ 'ConfirmResetPassword',
119
+ 'ConfirmSignIn',
120
+ 'ConfirmSignUp',
121
+ 'ConfirmVerifyUser',
122
+ 'ForceNewPassword',
123
+ 'ResetPassword',
124
+ 'SetupTOTP',
125
+ 'SignIn',
126
+ 'SignUp',
127
+ 'VerifyUser',
128
+ ];
129
+
130
+ const isComponentRouteKey = (route) => COMPONENT_ROUTE_KEYS.some((componentRoute) => componentRoute === route);
131
+ function resolveAuthenticatorComponents(defaults, overrides) {
132
+ if (!overrides) {
133
+ return defaults;
134
+ }
135
+ return COMPONENT_ROUTE_NAMES.reduce((components, route) => {
136
+ const Default = defaults[route];
137
+ const Override = overrides[route];
138
+ if (typeof Override !== 'function') {
139
+ return Object.assign(Object.assign({}, components), { [route]: Default });
140
+ }
141
+ const { Footer, FormFields, Header } = Default;
142
+ // cast to allow assigning of component slots
143
+ const Component = Override;
144
+ Component.Footer = Footer;
145
+ Component.FormFields = FormFields;
146
+ Component.Header = Header;
147
+ return Object.assign(Object.assign({}, components), { [route]: Component });
148
+ }, {});
149
+ }
150
+
115
151
  const defaultComparator = () => false;
116
152
  /**
117
153
  * Does an ordering and shallow comparison of each array value,
@@ -141,16 +177,29 @@ const getTotpSecretCodeCallback = (user) => function getTotpSecretCode() {
141
177
  return yield awsAmplify.Auth.setupTOTP(user);
142
178
  });
143
179
  };
144
- const isComponentRouteKey = (route) => COMPONENT_ROUTE_KEYS.some((componentRoute) => componentRoute === route);
145
180
  const flattenFormFields = (fields) => fields.flatMap(([name, options]) => (Object.assign({ name }, options)));
181
+ const convertContactMethodsToFields = (unverifiedContactMethods) => {
182
+ return (unverifiedContactMethods &&
183
+ Object.entries(unverifiedContactMethods).map(([name, value]) => {
184
+ const valueIsString = isString__default["default"](value);
185
+ if (!valueIsString || !name) {
186
+ return {};
187
+ }
188
+ return { name, label: value, type: 'radio', value };
189
+ }));
190
+ };
146
191
  /**
147
- * Retrieves legacy form field values from state machine for routes that have fields
192
+ * Retrieves default and custom (RWA only, to be updated) form field values from state machine
193
+ * for subcomponent routes that render fields
148
194
  */
149
- const getLegacyFields = (route, state) =>
150
- // verifyUser is a component route, but does not have form fields
151
- isComponentRouteKey(route) && route !== 'verifyUser'
152
- ? flattenFormFields(ui.getSortedFormFields(route, state))
153
- : [];
195
+ const getMachineFields = (route, state, unverifiedContactMethods) => {
196
+ if (isComponentRouteKey(route)) {
197
+ return route === 'verifyUser'
198
+ ? convertContactMethodsToFields(unverifiedContactMethods)
199
+ : flattenFormFields(ui.getSortedFormFields(route, state));
200
+ }
201
+ return [];
202
+ };
154
203
 
155
204
  /**
156
205
  * [📖 Docs](https://ui.docs.amplify.aws/react/connected-components/authenticator/headless#useauthenticator-hook)
@@ -165,18 +214,241 @@ function useAuthenticator(selector) {
165
214
  const xstateSelector = React.useCallback((state) => (Object.assign({}, ui.getServiceFacade({ send, state }))), [send]);
166
215
  const comparator = selector ? getComparator(selector) : defaultComparator;
167
216
  const facade = react.useSelector(service, xstateSelector, comparator);
168
- const { route, user } = facade, rest = __rest(facade, ["route", "user"]);
217
+ const { route, unverifiedContactMethods, user } = facade, rest = __rest(facade, ["route", "unverifiedContactMethods", "user"]);
169
218
  // do not memoize output. `service.getSnapshot` reference remains stable preventing
170
219
  // `fields` from updating with current form state on value changes
171
220
  const serviceSnapshot = service.getSnapshot();
172
221
  // legacy `formFields` values required until form state is removed from state machine
173
- const fields = React.useMemo(() => getLegacyFields(route, serviceSnapshot), [route, serviceSnapshot]);
222
+ const fields = React.useMemo(() => getMachineFields(route, serviceSnapshot, unverifiedContactMethods), [route, serviceSnapshot, unverifiedContactMethods]);
174
223
  return Object.assign(Object.assign({}, rest), { getTotpSecretCode: getTotpSecretCodeCallback(user), route,
224
+ unverifiedContactMethods,
175
225
  user,
176
226
  /** @deprecated For internal use only */
177
227
  fields });
178
228
  }
179
229
 
230
+ /**
231
+ * Utility component for rendering nothing.
232
+ */
233
+ function RenderNothing(_) {
234
+ return null;
235
+ }
236
+
237
+ const EVENT_HANDLER_KEY_MAP = {
238
+ updateBlur: 'handleBlur',
239
+ updateForm: 'handleChange',
240
+ submitForm: 'handleSubmit',
241
+ };
242
+ const COMMON_ROUTE_MACHINE_KEYS = [
243
+ 'error',
244
+ 'isPending',
245
+ 'submitForm',
246
+ 'updateBlur',
247
+ 'updateForm',
248
+ ];
249
+ const CONFIRM_RESET_PASSWORD_MACHINE_KEYS = [
250
+ ...COMMON_ROUTE_MACHINE_KEYS,
251
+ 'resendCode',
252
+ 'validationErrors',
253
+ ];
254
+ const CONFIRM_SIGN_IN_MACHINE_KEYS = [
255
+ ...COMMON_ROUTE_MACHINE_KEYS,
256
+ 'toSignIn',
257
+ 'user',
258
+ ];
259
+ const CONFIRM_SIGN_UP_MACHINE_KEYS = [
260
+ ...COMMON_ROUTE_MACHINE_KEYS,
261
+ 'codeDeliveryDetails',
262
+ 'resendCode',
263
+ ];
264
+ const CONFIRM_VERIFY_USER_MACHINE_KEYS = [
265
+ ...COMMON_ROUTE_MACHINE_KEYS,
266
+ 'skipVerification',
267
+ ];
268
+ const FORCE_NEW_PASSWORD_MACHINE_KEYS = [
269
+ ...COMMON_ROUTE_MACHINE_KEYS,
270
+ 'toSignIn',
271
+ 'validationErrors',
272
+ ];
273
+ const RESET_PASSWORD_MACHINE_KEYS = [
274
+ ...COMMON_ROUTE_MACHINE_KEYS,
275
+ 'toSignIn',
276
+ ];
277
+ const SIGN_IN_MACHINE_KEYS = [
278
+ ...COMMON_ROUTE_MACHINE_KEYS,
279
+ 'toFederatedSignIn',
280
+ 'toResetPassword',
281
+ 'toSignUp',
282
+ ];
283
+ const SIGN_UP_MACHINE_KEYS = [
284
+ ...COMMON_ROUTE_MACHINE_KEYS,
285
+ 'toSignIn',
286
+ 'validationErrors',
287
+ ];
288
+ const SETUP_TOTP_MACHINE_KEYS = [
289
+ ...COMMON_ROUTE_MACHINE_KEYS,
290
+ 'toSignIn',
291
+ ];
292
+ const VERIFY_USER_MACHINE_KEYS = [
293
+ ...COMMON_ROUTE_MACHINE_KEYS,
294
+ 'skipVerification',
295
+ ];
296
+ const MACHINE_PROP_KEYS = {
297
+ confirmResetPassword: CONFIRM_RESET_PASSWORD_MACHINE_KEYS,
298
+ confirmSignIn: CONFIRM_SIGN_IN_MACHINE_KEYS,
299
+ confirmSignUp: CONFIRM_SIGN_UP_MACHINE_KEYS,
300
+ confirmVerifyUser: CONFIRM_VERIFY_USER_MACHINE_KEYS,
301
+ forceNewPassword: FORCE_NEW_PASSWORD_MACHINE_KEYS,
302
+ signIn: SIGN_IN_MACHINE_KEYS,
303
+ signUp: SIGN_UP_MACHINE_KEYS,
304
+ resetPassword: RESET_PASSWORD_MACHINE_KEYS,
305
+ setupTOTP: SETUP_TOTP_MACHINE_KEYS,
306
+ verifyUser: VERIFY_USER_MACHINE_KEYS,
307
+ };
308
+
309
+ // only select `route` from machine context
310
+ const routeSelector$1 = ({ route }) => [route];
311
+ const createSelector = (selectorKeys) => (context) => {
312
+ const dependencies = selectorKeys.map((key) => context[key]);
313
+ // route should always be part of deps, so hook knows when route changes.
314
+ return [...dependencies, context.route];
315
+ };
316
+ const getRouteMachineSelector = (route) => isComponentRouteKey(route)
317
+ ? createSelector(MACHINE_PROP_KEYS[route])
318
+ : routeSelector$1;
319
+ const isFormEventHandlerKey = (key) => ['updateBlur', 'updateForm', 'submitForm'].includes(key);
320
+ const convertEventHandlerKey = (key) => EVENT_HANDLER_KEY_MAP[key];
321
+ const getConvertedMachineProps = (route, context) => MACHINE_PROP_KEYS[route].reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [isFormEventHandlerKey(key) ? convertEventHandlerKey(key) : key]: context[key] })), {});
322
+ function resolveConfirmResetPasswordRoute(Component, props) {
323
+ return {
324
+ Component,
325
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmResetPassword', props)),
326
+ };
327
+ }
328
+ function resolveConfirmSignInRoute(Component, props) {
329
+ const _a = getConvertedMachineProps('confirmSignIn', props), { user } = _a, machineProps = __rest(_a, ["user"]);
330
+ // prior to the `confirmSignIn` route, `user.username` is populated
331
+ const challengeName = user.challengeName;
332
+ return { Component, props: Object.assign(Object.assign(Object.assign({}, Component), machineProps), { challengeName }) };
333
+ }
334
+ function resolveConfirmSignUpRoute(Component, props) {
335
+ return {
336
+ Component,
337
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmSignUp', props)),
338
+ };
339
+ }
340
+ function resolveConfirmVerifyUserRoute(Component, props) {
341
+ return {
342
+ Component,
343
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmVerifyUser', props)),
344
+ };
345
+ }
346
+ function resolveForceNewPasswordRoute(Component, props) {
347
+ return {
348
+ Component,
349
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('forceNewPassword', props)),
350
+ };
351
+ }
352
+ function resolveResetPasswordRoute(Component, props) {
353
+ return {
354
+ Component,
355
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('resetPassword', props)),
356
+ };
357
+ }
358
+ function resolveSetupTOTPRoute(Component, _a) {
359
+ var { getTotpSecretCode } = _a, props = __rest(_a, ["getTotpSecretCode"]);
360
+ return {
361
+ Component,
362
+ props: Object.assign(Object.assign(Object.assign({}, Component), getConvertedMachineProps('setupTOTP', props)), { getTotpSecretCode }),
363
+ };
364
+ }
365
+ function resolveSignInRoute(Component, props) {
366
+ // default `hideSignUp` to false
367
+ const hideSignUp = false;
368
+ return {
369
+ Component,
370
+ props: Object.assign(Object.assign(Object.assign({}, Component), getConvertedMachineProps('signIn', props)), { hideSignUp }),
371
+ };
372
+ }
373
+ function resolveSignUpRoute(Component, props) {
374
+ return {
375
+ Component,
376
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('signUp', props)),
377
+ };
378
+ }
379
+ function resolveVerifyUserRoute(Component, props) {
380
+ return {
381
+ Component,
382
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('verifyUser', props)),
383
+ };
384
+ }
385
+ function resolveDefault() {
386
+ return {
387
+ Component: RenderNothing,
388
+ props: {},
389
+ };
390
+ }
391
+
392
+ function useAuthenticatorRoute({ components, }) {
393
+ const { route } = useAuthenticator(routeSelector$1);
394
+ const routeMachineSelector = React.useMemo(() => getRouteMachineSelector(route), [route]);
395
+ // `useAuthenticator` exposes both state machine (example: `toSignIn`) and non-state machine
396
+ // props (example: `getTotpSecretCode`). `routeSelector` specifies which state machine props
397
+ // should be returned for a specific route.
398
+ // Only state machine props specified by the current `routeSelector` will have their current value
399
+ // returned by `useAuthenticator`, non-machine props returned will always be the current value
400
+ const routeSelectorProps = useAuthenticator(routeMachineSelector);
401
+ const { ConfirmResetPassword, ConfirmSignIn, ConfirmSignUp, ConfirmVerifyUser, ForceNewPassword, ResetPassword, SetupTOTP, SignIn, SignUp, VerifyUser, } = components;
402
+ switch (route) {
403
+ case 'confirmResetPassword': {
404
+ return resolveConfirmResetPasswordRoute(ConfirmResetPassword, routeSelectorProps);
405
+ }
406
+ case 'confirmSignIn': {
407
+ return resolveConfirmSignInRoute(ConfirmSignIn, routeSelectorProps);
408
+ }
409
+ case 'confirmSignUp': {
410
+ return resolveConfirmSignUpRoute(ConfirmSignUp, routeSelectorProps);
411
+ }
412
+ case 'confirmVerifyUser': {
413
+ return resolveConfirmVerifyUserRoute(ConfirmVerifyUser, routeSelectorProps);
414
+ }
415
+ case 'forceNewPassword': {
416
+ return resolveForceNewPasswordRoute(ForceNewPassword, routeSelectorProps);
417
+ }
418
+ case 'resetPassword': {
419
+ return resolveResetPasswordRoute(ResetPassword, routeSelectorProps);
420
+ }
421
+ case 'setupTOTP': {
422
+ return resolveSetupTOTPRoute(SetupTOTP, routeSelectorProps);
423
+ }
424
+ case 'signIn': {
425
+ return resolveSignInRoute(SignIn, routeSelectorProps);
426
+ }
427
+ case 'signUp': {
428
+ return resolveSignUpRoute(SignUp, routeSelectorProps);
429
+ }
430
+ case 'verifyUser': {
431
+ return resolveVerifyUserRoute(VerifyUser, routeSelectorProps);
432
+ }
433
+ default: {
434
+ return resolveDefault();
435
+ }
436
+ }
437
+ }
438
+
439
+ // only select `route` from machine context
440
+ const routeSelector = ({ route }) => [route];
441
+ function useAuthenticatorInitMachine(data) {
442
+ const { route, initializeMachine } = useAuthenticator(routeSelector);
443
+ const hasInitialized = React__default["default"].useRef(false);
444
+ React__default["default"].useEffect(() => {
445
+ if (!hasInitialized.current && route === 'setup') {
446
+ initializeMachine(data);
447
+ hasInitialized.current = true;
448
+ }
449
+ }, [initializeMachine, route, data]);
450
+ }
451
+
180
452
  const InAppMessagingContext = React.createContext(null);
181
453
 
182
454
  const { InAppMessaging: InAppMessaging$1 } = notifications.Notifications;
@@ -212,13 +484,6 @@ function useInAppMessaging() {
212
484
  return inAppMessagingContext;
213
485
  }
214
486
 
215
- /**
216
- * Utility component for rendering nothing.
217
- */
218
- function RenderNothng(_) {
219
- return null;
220
- }
221
-
222
487
  const logger$2 = new core.ConsoleLogger('Notifications.InAppMessaging');
223
488
  const positions = {
224
489
  BOTTOM_BANNER: 'bottom',
@@ -272,7 +537,7 @@ function useMessage({ components, onMessageAction, }) {
272
537
  const { BannerMessage, CarouselMessage, FullScreenMessage, ModalMessage } = components;
273
538
  if (isNil__default["default"](message)) {
274
539
  return {
275
- Component: RenderNothng,
540
+ Component: RenderNothing,
276
541
  props: EMPTY_PROPS,
277
542
  };
278
543
  }
@@ -321,7 +586,7 @@ function useMessage({ components, onMessageAction, }) {
321
586
  default: {
322
587
  logger$1.info(`Received unknown InAppMessage layout: ${layout}`);
323
588
  return {
324
- Component: RenderNothng,
589
+ Component: RenderNothing,
325
590
  props: EMPTY_PROPS,
326
591
  };
327
592
  }
@@ -340,9 +605,34 @@ const handleMessageAction = ({ action, handleMessageLinkAction, url, }) => {
340
605
  }
341
606
  };
342
607
 
608
+ function usePreviousValue(value) {
609
+ const previous = React.useRef();
610
+ // update ref post render
611
+ React.useEffect(() => {
612
+ previous.current = value;
613
+ }, [value]);
614
+ // return previous ref
615
+ return previous.current;
616
+ }
617
+
618
+ function useHasValueUpdated(value, ignoreFirstRender = false) {
619
+ const previous = usePreviousValue(value);
620
+ const shouldIgnoreChange = isUndefined__default["default"](previous) && ignoreFirstRender;
621
+ if (shouldIgnoreChange) {
622
+ return false;
623
+ }
624
+ return previous !== value;
625
+ }
626
+
343
627
  exports.AuthenticatorProvider = AuthenticatorProvider;
344
628
  exports.InAppMessagingProvider = InAppMessagingProvider;
345
629
  exports.handleMessageAction = handleMessageAction;
630
+ exports.isAuthenticatorComponentRouteKey = isComponentRouteKey;
631
+ exports.resolveAuthenticatorComponents = resolveAuthenticatorComponents;
346
632
  exports.useAuthenticator = useAuthenticator;
633
+ exports.useAuthenticatorInitMachine = useAuthenticatorInitMachine;
634
+ exports.useAuthenticatorRoute = useAuthenticatorRoute;
635
+ exports.useHasValueUpdated = useHasValueUpdated;
347
636
  exports.useInAppMessaging = useInAppMessaging;
348
637
  exports.useMessage = useMessage;
638
+ exports.usePreviousValue = usePreviousValue;
@@ -0,0 +1,7 @@
1
+ import { Defaults, Overrides } from '../types';
2
+ declare type DefaultComponents<P> = Defaults<P>;
3
+ export declare const DEFAULTS: DefaultComponents<{}>;
4
+ export declare const OVERRIDES: Overrides;
5
+ export declare const INVALID_SIGN_IN_OVERRIDES: Overrides;
6
+ export declare const INVALID_OVERRIDES: Overrides<{}, {}>;
7
+ export {};
@@ -0,0 +1,3 @@
1
+ import { AuthenticatorRouteComponentKey, AuthenticatorRouteComponentName } from './types';
2
+ export declare const COMPONENT_ROUTE_KEYS: AuthenticatorRouteComponentKey[];
3
+ export declare const COMPONENT_ROUTE_NAMES: AuthenticatorRouteComponentName[];
@@ -1 +1,5 @@
1
1
  export * from './useAuthenticator';
2
+ export * from './useAuthenticatorRoute';
3
+ export * from './useAuthenticatorInitMachine';
4
+ export * from './utils';
5
+ export * from './types';
@@ -0,0 +1,123 @@
1
+ import React from 'react';
2
+ import { AuthChallengeName, AuthenticatorServiceFacade, LegacyFormFieldOptions } from '@aws-amplify/ui';
3
+ export declare type AuthenticatorRouteComponentKey = 'confirmResetPassword' | 'confirmSignIn' | 'confirmSignUp' | 'confirmVerifyUser' | 'forceNewPassword' | 'resetPassword' | 'setupTOTP' | 'signIn' | 'signUp' | 'verifyUser';
4
+ export declare type AuthenticatorLegacyField = LegacyFormFieldOptions;
5
+ export declare type AuthenticatorLegacyFields = AuthenticatorLegacyField[];
6
+ /**
7
+ * These are the "facades" that we provide, which contains contexts respective
8
+ * to current authenticator state.
9
+ */
10
+ export declare type AuthenticatorMachineContext = AuthenticatorServiceFacade;
11
+ export declare type AuthenticatorMachineContextKey = keyof AuthenticatorMachineContext;
12
+ export declare type AuthenticatorRouteComponentName = Capitalize<AuthenticatorRouteComponentKey>;
13
+ export declare type GetTotpSecretCode = () => Promise<string>;
14
+ interface HeaderProps {
15
+ children?: React.ReactNode;
16
+ }
17
+ interface FooterProps {
18
+ children?: React.ReactNode;
19
+ }
20
+ declare type FormFieldsProps = {
21
+ isPending: AuthenticatorMachineContext['isPending'];
22
+ validationErrors?: AuthenticatorMachineContext['validationErrors'];
23
+ };
24
+ export declare type FooterComponent<Props = {}> = React.ComponentType<FooterProps & Props>;
25
+ export declare type FormFieldsComponent<FieldType, Props = {}> = React.ComponentType<FormFieldsProps & {
26
+ fields: FieldType[];
27
+ } & Props>;
28
+ export declare type HeaderComponent<Props = {}> = React.ComponentType<HeaderProps & Props>;
29
+ export interface ComponentSlots<FieldType = {}> {
30
+ Footer: FooterComponent;
31
+ Header: HeaderComponent;
32
+ FormFields: FormFieldsComponent<FieldType>;
33
+ }
34
+ /**
35
+ * Common component prop types used for both RWA and RNA implementations
36
+ */
37
+ export declare type CommonRouteProps = {
38
+ error?: AuthenticatorMachineContext['error'];
39
+ isPending: AuthenticatorMachineContext['isPending'];
40
+ handleBlur: AuthenticatorMachineContext['updateBlur'];
41
+ handleChange: AuthenticatorMachineContext['updateForm'];
42
+ handleSubmit: AuthenticatorMachineContext['submitForm'];
43
+ };
44
+ /**
45
+ * Base Route component props
46
+ */
47
+ export declare type ConfirmResetPasswordBaseProps<FieldType = {}> = {
48
+ resendCode: AuthenticatorMachineContext['resendCode'];
49
+ validationErrors?: AuthenticatorMachineContext['validationErrors'];
50
+ } & CommonRouteProps & ComponentSlots<FieldType>;
51
+ export declare type ConfirmSignInBaseProps<FieldType = {}> = {
52
+ challengeName: AuthChallengeName;
53
+ toSignIn: AuthenticatorMachineContext['toSignIn'];
54
+ } & CommonRouteProps & ComponentSlots<FieldType>;
55
+ export declare type ConfirmSignUpBaseProps<FieldType = {}> = {
56
+ codeDeliveryDetails: AuthenticatorMachineContext['codeDeliveryDetails'];
57
+ resendCode: AuthenticatorMachineContext['resendCode'];
58
+ } & CommonRouteProps & ComponentSlots<FieldType>;
59
+ export declare type ConfirmVerifyUserProps<FieldType = {}> = {
60
+ skipVerification: AuthenticatorMachineContext['skipVerification'];
61
+ } & CommonRouteProps & ComponentSlots<FieldType>;
62
+ export declare type ForceResetPasswordBaseProps<FieldType = {}> = {
63
+ toSignIn: AuthenticatorMachineContext['toSignIn'];
64
+ validationErrors?: AuthenticatorMachineContext['validationErrors'];
65
+ } & CommonRouteProps & ComponentSlots<FieldType>;
66
+ export declare type ResetPasswordBaseProps<FieldType = {}> = {
67
+ toSignIn: AuthenticatorMachineContext['toSignIn'];
68
+ } & CommonRouteProps & ComponentSlots<FieldType>;
69
+ export declare type SetupTOTPBaseProps<FieldType = {}> = {
70
+ getTotpSecretCode: GetTotpSecretCode;
71
+ toSignIn: AuthenticatorMachineContext['toSignIn'];
72
+ } & CommonRouteProps & ComponentSlots<FieldType>;
73
+ export declare type SignInBaseProps<FieldType = {}> = {
74
+ hideSignUp?: boolean;
75
+ toFederatedSignIn: AuthenticatorMachineContext['toFederatedSignIn'];
76
+ toResetPassword: AuthenticatorMachineContext['toResetPassword'];
77
+ toSignUp: AuthenticatorMachineContext['toSignUp'];
78
+ } & CommonRouteProps & ComponentSlots<FieldType>;
79
+ export declare type SignUpBaseProps<FieldType = {}> = {
80
+ hideSignIn?: boolean;
81
+ toFederatedSignIn: AuthenticatorMachineContext['toFederatedSignIn'];
82
+ toSignIn: AuthenticatorMachineContext['toSignIn'];
83
+ validationErrors?: AuthenticatorMachineContext['validationErrors'];
84
+ } & CommonRouteProps & ComponentSlots<FieldType>;
85
+ export declare type VerifyUserProps<FieldType = {}> = {
86
+ skipVerification: AuthenticatorMachineContext['skipVerification'];
87
+ } & CommonRouteProps & ComponentSlots<FieldType>;
88
+ export interface DefaultProps<FieldType = {}> {
89
+ ConfirmSignIn: ConfirmSignInBaseProps<FieldType>;
90
+ ConfirmSignUp: ConfirmSignUpBaseProps<FieldType>;
91
+ ConfirmResetPassword: ConfirmResetPasswordBaseProps<FieldType>;
92
+ ConfirmVerifyUser: ConfirmVerifyUserProps<FieldType>;
93
+ ForceNewPassword: ForceResetPasswordBaseProps<FieldType>;
94
+ ResetPassword: ResetPasswordBaseProps<FieldType>;
95
+ SetupTOTP: SetupTOTPBaseProps<FieldType>;
96
+ SignIn: SignInBaseProps<FieldType>;
97
+ SignUp: SignUpBaseProps<FieldType>;
98
+ VerifyUser: VerifyUserProps<FieldType>;
99
+ }
100
+ /**
101
+ * common types extended for default component types/implementations and override component types
102
+ */
103
+ declare type BaseComponent<ComponentRouteProps = {}, FieldType = {}, Props = {}> = React.ComponentType<ComponentSlots<FieldType> & ComponentRouteProps & {
104
+ fields: FieldType[];
105
+ } & Props>;
106
+ /**
107
+ * Authenticator Route Component Default types
108
+ */
109
+ export declare type Defaults<FieldType = {}, PlatformProps = {}> = {
110
+ [Key in AuthenticatorRouteComponentName]: BaseComponent<DefaultProps<FieldType>[Key], FieldType, PlatformProps> & ComponentSlots<FieldType>;
111
+ };
112
+ export declare type Overrides<FieldType = {}, PlatformProps = {}> = {
113
+ [Key in AuthenticatorRouteComponentName]?: BaseComponent<DefaultProps<FieldType>[Key], FieldType, PlatformProps>;
114
+ };
115
+ /**
116
+ * Default Route Component union type
117
+ */
118
+ export declare type DefaultComponentType<FieldType = {}> = Defaults<FieldType>[keyof Defaults<FieldType>];
119
+ /**
120
+ * Default Route Component union type
121
+ */
122
+ export declare type DefaultPropsType<FieldType = {}> = DefaultProps<FieldType>[keyof DefaultProps<FieldType>];
123
+ export {};
@@ -0,0 +1,4 @@
1
+ import { AuthenticatorMachineContext } from '../../types';
2
+ import { UseAuthenticator } from '../types';
3
+ export declare const mockMachineContext: AuthenticatorMachineContext;
4
+ export declare const mockUseAuthenticatorOutput: UseAuthenticator;
@@ -1,3 +1 @@
1
- import { AuthenticatorRouteComponentKey } from './types';
2
1
  export declare const USE_AUTHENTICATOR_ERROR = "`useAuthenticator` must be used inside an `Authenticator.Provider`.";
3
- export declare const COMPONENT_ROUTE_KEYS: AuthenticatorRouteComponentKey[];
@@ -1,2 +1,2 @@
1
1
  export { default as useAuthenticator } from './useAuthenticator';
2
- export { UseAuthenticator } from './types';
2
+ export { UseAuthenticator, UseAuthenticatorSelector } from './types';
@@ -13,11 +13,11 @@ export declare type AuthenticatorLegacyFields = LegacyFormFieldOptions[];
13
13
  * Selector accepts current facade values and returns an array of
14
14
  * desired value(s) that should trigger re-render.
15
15
  */
16
- export declare type Selector = (context: AuthenticatorMachineContext) => AuthenticatorMachineContext[AuthenticatorMachineContextKey][];
16
+ export declare type UseAuthenticatorSelector = (context: AuthenticatorMachineContext) => AuthenticatorMachineContext[AuthenticatorMachineContextKey][];
17
17
  export interface UseAuthenticator extends AuthenticatorServiceFacade {
18
18
  getTotpSecretCode: () => Promise<string>;
19
19
  /** @deprecated For internal use only */
20
20
  fields: AuthenticatorLegacyFields;
21
21
  }
22
- export declare type Comparator = (currentFacade: AuthenticatorServiceFacade, nextFacade: AuthenticatorServiceFacade) => boolean;
22
+ export declare type Comparator = (currentMachineContext: AuthenticatorMachineContext, nextMachineContext: AuthenticatorMachineContext) => boolean;
23
23
  export {};
@@ -1,5 +1,5 @@
1
- import { Selector, UseAuthenticator } from './types';
1
+ import { UseAuthenticatorSelector, UseAuthenticator } from './types';
2
2
  /**
3
3
  * [📖 Docs](https://ui.docs.amplify.aws/react/connected-components/authenticator/headless#useauthenticator-hook)
4
4
  */
5
- export default function useAuthenticator(selector?: Selector): UseAuthenticator;
5
+ export default function useAuthenticator(selector?: UseAuthenticatorSelector): UseAuthenticator;
@@ -1,15 +1,16 @@
1
- import { AmplifyUser, AuthenticatorRoute, AuthMachineState } from '@aws-amplify/ui';
2
- import { AuthenticatorRouteComponentKey, AuthenticatorLegacyFields, Comparator, Selector } from './types';
1
+ import { AmplifyUser, AuthenticatorRoute, AuthMachineState, UnverifiedContactMethods } from '@aws-amplify/ui';
2
+ import { AuthenticatorLegacyFields } from '../types';
3
+ import { Comparator, UseAuthenticatorSelector } from './types';
3
4
  export declare const defaultComparator: () => false;
4
5
  /**
5
6
  * Does an ordering and shallow comparison of each array value,
6
7
  * plus a value equality check for empty objects and arrays.
7
8
  */
8
9
  export declare function areSelectorDepsEqual<T>(currentDeps: T[], nextDeps: T[]): boolean;
9
- export declare const getComparator: (selector: Selector) => Comparator;
10
+ export declare const getComparator: (selector: UseAuthenticatorSelector) => Comparator;
10
11
  export declare const getTotpSecretCodeCallback: (user: AmplifyUser) => () => Promise<string>;
11
- export declare const isComponentRouteKey: (route: AuthenticatorRoute) => route is AuthenticatorRouteComponentKey;
12
12
  /**
13
- * Retrieves legacy form field values from state machine for routes that have fields
13
+ * Retrieves default and custom (RWA only, to be updated) form field values from state machine
14
+ * for subcomponent routes that render fields
14
15
  */
15
- export declare const getLegacyFields: (route: AuthenticatorRoute, state: AuthMachineState) => AuthenticatorLegacyFields;
16
+ export declare const getMachineFields: (route: AuthenticatorRoute, state: AuthMachineState, unverifiedContactMethods: UnverifiedContactMethods) => AuthenticatorLegacyFields;
@@ -0,0 +1 @@
1
+ export { default as useAuthenticatorInitMachine } from './useAuthenticatorInitMachine';
@@ -0,0 +1,4 @@
1
+ import { AuthenticatorMachineOptions } from '@aws-amplify/ui';
2
+ import { UseAuthenticatorSelector } from '../useAuthenticator';
3
+ export declare const routeSelector: UseAuthenticatorSelector;
4
+ export default function useAuthenticatorInitMachine(data: AuthenticatorMachineOptions): void;