@aws-amplify/ui-react-core 2.1.32 → 3.0.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 (82) hide show
  1. package/dist/esm/Authenticator/context/AuthenticatorProvider.mjs +5 -6
  2. package/dist/esm/Authenticator/hooks/constants.mjs +4 -4
  3. package/dist/esm/Authenticator/hooks/useAuthenticator/useAuthenticator.mjs +14 -11
  4. package/dist/esm/Authenticator/hooks/useAuthenticator/utils.mjs +10 -18
  5. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/constants.mjs +7 -4
  6. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.mjs +6 -6
  7. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/utils.mjs +47 -18
  8. package/dist/esm/Authenticator/hooks/utils.mjs +2 -2
  9. package/dist/esm/components/FormCore/FormProvider.mjs +15 -0
  10. package/dist/esm/components/FormCore/useField.mjs +20 -0
  11. package/dist/esm/components/FormCore/useForm.mjs +51 -0
  12. package/dist/esm/components/FormCore/withFormProvider.mjs +15 -0
  13. package/dist/esm/hooks/useSetUserAgent.mjs +15 -0
  14. package/dist/esm/hooks/useTimeout.mjs +22 -0
  15. package/dist/esm/index.mjs +7 -0
  16. package/dist/esm/utils/createContextUtilities.mjs +80 -0
  17. package/dist/index.js +284 -96
  18. package/dist/types/Authenticator/hooks/types.d.ts +10 -7
  19. package/dist/types/Authenticator/hooks/useAuthenticator/types.d.ts +1 -3
  20. package/dist/types/Authenticator/hooks/useAuthenticator/utils.d.ts +2 -3
  21. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/types.d.ts +3 -3
  22. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.d.ts +2 -2
  23. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/utils.d.ts +2 -2
  24. package/dist/types/components/FormCore/FormProvider.d.ts +4 -0
  25. package/dist/types/components/FormCore/index.d.ts +5 -0
  26. package/dist/types/components/FormCore/types.d.ts +217 -0
  27. package/dist/types/components/FormCore/useControlledField.d.ts +9 -0
  28. package/dist/types/components/FormCore/useField.d.ts +9 -0
  29. package/dist/types/components/FormCore/useForm.d.ts +12 -0
  30. package/dist/types/components/FormCore/withFormProvider.d.ts +8 -0
  31. package/dist/types/components/index.d.ts +1 -0
  32. package/dist/types/hooks/index.d.ts +2 -0
  33. package/dist/types/hooks/useSetUserAgent.d.ts +2 -0
  34. package/dist/types/hooks/useTimeout.d.ts +4 -0
  35. package/dist/types/index.d.ts +3 -2
  36. package/dist/types/types/index.d.ts +1 -1
  37. package/dist/types/types/types.d.ts +2 -0
  38. package/dist/types/utils/createContextUtilities.d.ts +26 -18
  39. package/package.json +11 -29
  40. package/src/Authenticator/context/AuthenticatorContext.tsx +17 -0
  41. package/src/Authenticator/context/AuthenticatorProvider.tsx +82 -0
  42. package/src/Authenticator/context/index.ts +2 -0
  43. package/src/Authenticator/hooks/constants.ts +30 -0
  44. package/src/Authenticator/hooks/index.ts +5 -0
  45. package/src/Authenticator/hooks/types.ts +218 -0
  46. package/src/Authenticator/hooks/useAuthenticator/__mock__/useAuthenticator.ts +66 -0
  47. package/src/Authenticator/hooks/useAuthenticator/constants.ts +2 -0
  48. package/src/Authenticator/hooks/useAuthenticator/index.ts +2 -0
  49. package/src/Authenticator/hooks/useAuthenticator/types.ts +48 -0
  50. package/src/Authenticator/hooks/useAuthenticator/useAuthenticator.ts +72 -0
  51. package/src/Authenticator/hooks/useAuthenticator/utils.ts +97 -0
  52. package/src/Authenticator/hooks/useAuthenticatorInitMachine/index.ts +1 -0
  53. package/src/Authenticator/hooks/useAuthenticatorInitMachine/useAuthenticatorInitMachine.tsx +25 -0
  54. package/src/Authenticator/hooks/useAuthenticatorRoute/constants.ts +107 -0
  55. package/src/Authenticator/hooks/useAuthenticatorRoute/index.ts +2 -0
  56. package/src/Authenticator/hooks/useAuthenticatorRoute/types.ts +111 -0
  57. package/src/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.ts +126 -0
  58. package/src/Authenticator/hooks/useAuthenticatorRoute/utils.ts +204 -0
  59. package/src/Authenticator/hooks/utils.ts +38 -0
  60. package/src/Authenticator/index.ts +23 -0
  61. package/src/components/FormCore/FormProvider.tsx +37 -0
  62. package/src/components/FormCore/index.ts +13 -0
  63. package/src/components/FormCore/types.ts +277 -0
  64. package/src/components/FormCore/useControlledField.ts +73 -0
  65. package/src/components/FormCore/useField.ts +25 -0
  66. package/src/components/FormCore/useForm.ts +84 -0
  67. package/src/components/FormCore/withFormProvider.tsx +31 -0
  68. package/src/components/RenderNothing/RenderNothing.tsx +6 -0
  69. package/src/components/RenderNothing/index.ts +1 -0
  70. package/src/components/index.ts +15 -0
  71. package/src/hooks/index.ts +8 -0
  72. package/src/hooks/useDeprecationWarning.ts +27 -0
  73. package/src/hooks/useHasValueUpdated.ts +28 -0
  74. package/src/hooks/usePreviousValue.ts +15 -0
  75. package/src/hooks/useSetUserAgent.ts +18 -0
  76. package/src/hooks/useTimeout.ts +30 -0
  77. package/src/index.ts +48 -0
  78. package/src/types/index.ts +1 -0
  79. package/src/types/types.ts +3 -0
  80. package/src/utils/createContextUtilities.tsx +131 -0
  81. package/src/utils/index.ts +1 -0
  82. package/dist/esm/node_modules/tslib/tslib.es6.mjs +0 -38
package/dist/index.js CHANGED
@@ -4,8 +4,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var React = require('react');
6
6
  var react = require('@xstate/react');
7
- var awsAmplify = require('aws-amplify');
7
+ var auth = require('aws-amplify/auth');
8
8
  var ui = require('@aws-amplify/ui');
9
+ var reactHookForm = require('react-hook-form');
9
10
 
10
11
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11
12
 
@@ -30,43 +31,6 @@ function _interopNamespace(e) {
30
31
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
31
32
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
32
33
 
33
- /******************************************************************************
34
- Copyright (c) Microsoft Corporation.
35
-
36
- Permission to use, copy, modify, and/or distribute this software for any
37
- purpose with or without fee is hereby granted.
38
-
39
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
40
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
41
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
42
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
43
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
44
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
45
- PERFORMANCE OF THIS SOFTWARE.
46
- ***************************************************************************** */
47
-
48
- function __rest(s, e) {
49
- var t = {};
50
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
51
- t[p] = s[p];
52
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
53
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
54
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
55
- t[p[i]] = s[p[i]];
56
- }
57
- return t;
58
- }
59
-
60
- function __awaiter(thisArg, _arguments, P, generator) {
61
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
62
- return new (P || (P = Promise))(function (resolve, reject) {
63
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
64
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
65
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
66
- step((generator = generator.apply(thisArg, _arguments || [])).next());
67
- });
68
- }
69
-
70
34
  /**
71
35
  * AuthenticatorContext serves static reference to the auth machine service.
72
36
  *
@@ -74,9 +38,9 @@ function __awaiter(thisArg, _arguments, P, generator) {
74
38
  */
75
39
  const AuthenticatorContext = React__default["default"].createContext(null);
76
40
 
77
- const createHubHandler = (options) => (data, service) => __awaiter(void 0, void 0, void 0, function* () {
78
- yield ui.defaultAuthHubHandler(data, service, options);
79
- });
41
+ const createHubHandler = (options) => async (data, service) => {
42
+ await ui.defaultAuthHubHandler(data, service, options);
43
+ };
80
44
  function AuthenticatorProvider({ children, }) {
81
45
  // `authStatus` is exposed by `useAuthenticator` but should not be derived directly from the
82
46
  // state machine as the machine only updates on `Authenticator` initiated events, which
@@ -85,7 +49,7 @@ function AuthenticatorProvider({ children, }) {
85
49
  const [authStatus, setAuthStatus] = React__default["default"].useState('configuring');
86
50
  // only run on first render
87
51
  React__default["default"].useEffect(() => {
88
- awsAmplify.Auth.currentAuthenticatedUser()
52
+ auth.getCurrentUser()
89
53
  .then(() => {
90
54
  setAuthStatus('authenticated');
91
55
  })
@@ -125,8 +89,8 @@ const COMPONENT_ROUTE_KEYS = [
125
89
  'confirmSignUp',
126
90
  'confirmVerifyUser',
127
91
  'forceNewPassword',
128
- 'resetPassword',
129
- 'setupTOTP',
92
+ 'forgotPassword',
93
+ 'setupTotp',
130
94
  'signIn',
131
95
  'signUp',
132
96
  'verifyUser',
@@ -137,8 +101,8 @@ const COMPONENT_ROUTE_NAMES = [
137
101
  'ConfirmSignUp',
138
102
  'ConfirmVerifyUser',
139
103
  'ForceNewPassword',
140
- 'ResetPassword',
141
- 'SetupTOTP',
104
+ 'ForgotPassword',
105
+ 'SetupTotp',
142
106
  'SignIn',
143
107
  'SignUp',
144
108
  'VerifyUser',
@@ -153,7 +117,7 @@ function resolveAuthenticatorComponents(defaults, overrides) {
153
117
  const Default = defaults[route];
154
118
  const Override = overrides[route];
155
119
  if (typeof Override !== 'function') {
156
- return Object.assign(Object.assign({}, components), { [route]: Default });
120
+ return { ...components, [route]: Default };
157
121
  }
158
122
  const { Footer, FormFields, Header } = Default;
159
123
  // cast to allow assigning of component slots
@@ -161,7 +125,7 @@ function resolveAuthenticatorComponents(defaults, overrides) {
161
125
  Component.Footer = Footer;
162
126
  Component.FormFields = FormFields;
163
127
  Component.Header = Header;
164
- return Object.assign(Object.assign({}, components), { [route]: Component });
128
+ return { ...components, [route]: Component };
165
129
  }, {});
166
130
  }
167
131
 
@@ -189,19 +153,13 @@ const getComparator = (selector) => (currentFacade, nextFacade) => {
189
153
  // Shallow compare the array values
190
154
  return areSelectorDepsEqual(currentSelectorDeps, nextSelectorDeps);
191
155
  };
192
- const getQRFields = (state) => {
193
- var _a, _b, _c;
194
- return (Object.assign({}, (_c = (_b = (_a = ui.getActorContext(state)) === null || _a === void 0 ? void 0 : _a.formFields) === null || _b === void 0 ? void 0 : _b.setupTOTP) === null || _c === void 0 ? void 0 : _c.QR));
195
- };
196
- const getTotpSecretCodeCallback = (user) => function getTotpSecretCode() {
197
- return __awaiter(this, void 0, void 0, function* () {
198
- return yield awsAmplify.Auth.setupTOTP(user);
199
- });
200
- };
201
- const flattenFormFields = (fields) => fields.flatMap(([name, options]) => (Object.assign({ name }, options)));
202
- const convertContactMethodsToFields = (unverifiedContactMethods) => {
203
- return (unverifiedContactMethods &&
204
- Object.entries(unverifiedContactMethods).map(([name, value]) => {
156
+ const getQRFields = (state) => ({
157
+ ...ui.getActorContext(state)?.formFields?.setupTotp?.QR,
158
+ });
159
+ const flattenFormFields = (fields) => fields.flatMap(([name, options]) => ({ name, ...options }));
160
+ const convertContactMethodsToFields = (unverifiedUserAttributes) => {
161
+ return (unverifiedUserAttributes &&
162
+ Object.entries(unverifiedUserAttributes).map(([name, value]) => {
205
163
  const valueIsString = ui.isString(value);
206
164
  if (!valueIsString || !name) {
207
165
  return {};
@@ -213,10 +171,10 @@ const convertContactMethodsToFields = (unverifiedContactMethods) => {
213
171
  * Retrieves default and custom (RWA only, to be updated) form field values from state machine
214
172
  * for subcomponent routes that render fields
215
173
  */
216
- const getMachineFields = (route, state, unverifiedContactMethods) => {
174
+ const getMachineFields = (route, state, unverifiedUserAttributes) => {
217
175
  if (isComponentRouteKey(route)) {
218
176
  return route === 'verifyUser'
219
- ? convertContactMethodsToFields(unverifiedContactMethods)
177
+ ? convertContactMethodsToFields(unverifiedUserAttributes)
220
178
  : flattenFormFields(ui.getSortedFormFields(route, state));
221
179
  }
222
180
  return [];
@@ -232,27 +190,116 @@ function useAuthenticator(selector) {
232
190
  }
233
191
  const { service } = context;
234
192
  const { send } = service;
235
- const xstateSelector = React.useCallback((state) => (Object.assign({}, ui.getServiceFacade({ send, state }))), [send]);
193
+ const xstateSelector = React.useCallback((state) => ({ ...ui.getServiceFacade({ send, state }) }), [send]);
236
194
  const comparator = selector ? getComparator(selector) : defaultComparator;
237
195
  // the purpose of `context.authStatus`is to intentionally override `facade.authStatus`. `facade.authStatus` does
238
196
  // not update on external sign in events (for example when a user is not using the `Authenticator`).
239
197
  const { authStatus } = context;
240
198
  const facade = react.useSelector(service, xstateSelector, comparator);
241
- const { route, totpSecretCode, unverifiedContactMethods, user } = facade, rest = __rest(facade, ["route", "totpSecretCode", "unverifiedContactMethods", "user"]);
199
+ const { route, totpSecretCode, unverifiedUserAttributes, user, ...rest } = facade;
242
200
  // do not memoize output. `service.getSnapshot` reference remains stable preventing
243
201
  // `fields` from updating with current form state on value changes
244
202
  const serviceSnapshot = service.getSnapshot();
245
- // legacy `QRFields` values only used for SetupTOTP page to retrieve issuer information, will be removed in future
246
- const QRFields = route === 'setupTOTP' ? getQRFields(serviceSnapshot) : null;
203
+ // legacy `QRFields` values only used for SetupTotp page to retrieve issuer information, will be removed in future
204
+ const QRFields = route === 'setupTotp' ? getQRFields(serviceSnapshot) : null;
247
205
  // legacy `formFields` values required until form state is removed from state machine
248
- const fields = getMachineFields(route, serviceSnapshot, unverifiedContactMethods);
249
- return Object.assign(Object.assign({}, rest), { authStatus,
206
+ const fields = getMachineFields(route, serviceSnapshot, unverifiedUserAttributes);
207
+ return {
208
+ ...rest,
209
+ authStatus,
250
210
  route,
251
211
  totpSecretCode,
252
- unverifiedContactMethods,
212
+ unverifiedUserAttributes,
253
213
  user,
254
214
  /** @deprecated For internal use only */
255
- fields, getTotpSecretCode: getTotpSecretCodeCallback(user), QRFields });
215
+ fields,
216
+ QRFields,
217
+ };
218
+ }
219
+
220
+ const DEFAULT_ERROR_MESSAGE$1 = '`useForm` must be called inside a `FormProvider`';
221
+ /**
222
+ * Utility hook corresponding to `FormProvider`, must be used within a `FormProvider`
223
+ *
224
+ * @internal Extend for public export. `useForm` and `UseForm` are an abstraction layer
225
+ * on top of `useFormContext` and `UseFormReturn`, imported from `react-hook-form`
226
+ *
227
+ * @param options optional parameters
228
+ * @returns `Form` utilities
229
+ */
230
+ function useForm(options = {}) {
231
+ const formContext = reactHookForm.useFormContext();
232
+ const { errorMessage, onSubmit: _onSubmit } = options;
233
+ if (!formContext) {
234
+ throw new Error(errorMessage ?? DEFAULT_ERROR_MESSAGE$1);
235
+ }
236
+ const { formState, getFieldState: _getFieldState, getValues, handleSubmit, register, reset, setValue, } = formContext;
237
+ // Do not memoize, `formState` updates on all events
238
+ const getFieldState = (name) => {
239
+ const { error, ...fieldState } = _getFieldState(name, formState);
240
+ const { message: errorMessage } = error ?? {};
241
+ return { ...fieldState, errorMessage, hasError: !!errorMessage };
242
+ };
243
+ // memoize `registerField` and `setFormValue` together,
244
+ // `register` and `setValue` maintain stable references
245
+ const { registerField, setFormValue } = React__default["default"].useMemo(() => {
246
+ return {
247
+ registerField: ({ name, ...options }) => register(name, options),
248
+ setFormValue: ({ name, value, ...options }) => setValue(name, value, options),
249
+ };
250
+ }, [register, setValue]);
251
+ const onSubmit = React__default["default"].useCallback((event) => {
252
+ const handler = _onSubmit ? handleSubmit(_onSubmit) : ui.noop;
253
+ handler(event);
254
+ }, [_onSubmit, handleSubmit]);
255
+ return {
256
+ getFieldState,
257
+ getValues,
258
+ isValid: formState.isValid,
259
+ onSubmit,
260
+ registerField,
261
+ reset,
262
+ setFormValue,
263
+ };
264
+ }
265
+
266
+ const DEFAULT_ERROR_MESSAGE = '`useField` must be used within a `FormProvider`';
267
+ /**
268
+ * `Field` integration hook for usage with React `Field` components.
269
+ *
270
+ * @param params Requires `name`, all additional params optional
271
+ * @returns `Form` aware `Field` event handlers and state values
272
+ */
273
+ function useField(params) {
274
+ const { getFieldState, registerField } = useForm({
275
+ errorMessage: DEFAULT_ERROR_MESSAGE,
276
+ });
277
+ return {
278
+ ...registerField(params),
279
+ ...getFieldState(params.name),
280
+ };
281
+ }
282
+
283
+ const DEFAULT_MODE = 'onTouched';
284
+ const FormProvider = React__default["default"].forwardRef(function FormProvider({ children, defaultValues, mode = DEFAULT_MODE }, ref) {
285
+ const formProviderProps = reactHookForm.useForm({
286
+ defaultValues,
287
+ mode,
288
+ });
289
+ const { getValues, reset } = formProviderProps;
290
+ React__default["default"].useImperativeHandle(ref, () => ({ getValues, reset: () => reset(defaultValues) }), [defaultValues, getValues, reset]);
291
+ return (React__default["default"].createElement(reactHookForm.FormProvider, { ...formProviderProps }, children));
292
+ });
293
+
294
+ /**
295
+ * @param Child `Form` base component wrapped inside `FormProvider`
296
+ * @returns Composed `Form` component exposing `FormContext` values to descendents
297
+ */
298
+ function withFormProvider(Child) {
299
+ return React__default["default"].forwardRef(function Form({ defaultValues, mode, ...props }, ref) {
300
+ return (React__default["default"].createElement(FormProvider, { defaultValues: defaultValues, mode: mode, ref: ref },
301
+ React__default["default"].createElement(Child, { ...props })));
302
+ });
256
303
  }
257
304
 
258
305
  /**
@@ -282,8 +329,8 @@ const CONFIRM_RESET_PASSWORD_MACHINE_KEYS = [
282
329
  ];
283
330
  const CONFIRM_SIGN_IN_MACHINE_KEYS = [
284
331
  ...COMMON_ROUTE_MACHINE_KEYS,
332
+ 'challengeName',
285
333
  'toSignIn',
286
- 'user',
287
334
  ];
288
335
  const CONFIRM_SIGN_UP_MACHINE_KEYS = [
289
336
  ...COMMON_ROUTE_MACHINE_KEYS,
@@ -306,13 +353,15 @@ const RESET_PASSWORD_MACHINE_KEYS = [
306
353
  ];
307
354
  const SIGN_IN_MACHINE_KEYS = [
308
355
  ...COMMON_ROUTE_MACHINE_KEYS,
356
+ 'socialProviders',
309
357
  'toFederatedSignIn',
310
- 'toResetPassword',
358
+ 'toForgotPassword',
311
359
  'toSignUp',
312
360
  ];
313
361
  const SIGN_UP_MACHINE_KEYS = [
314
362
  ...COMMON_ROUTE_MACHINE_KEYS,
315
363
  'hasValidationErrors',
364
+ 'socialProviders',
316
365
  'toSignIn',
317
366
  'validationErrors',
318
367
  ];
@@ -320,6 +369,7 @@ const SETUP_TOTP_MACHINE_KEYS = [
320
369
  ...COMMON_ROUTE_MACHINE_KEYS,
321
370
  'toSignIn',
322
371
  'totpSecretCode',
372
+ 'username',
323
373
  ];
324
374
  const VERIFY_USER_MACHINE_KEYS = [
325
375
  ...COMMON_ROUTE_MACHINE_KEYS,
@@ -333,8 +383,8 @@ const MACHINE_PROP_KEYS = {
333
383
  forceNewPassword: FORCE_NEW_PASSWORD_MACHINE_KEYS,
334
384
  signIn: SIGN_IN_MACHINE_KEYS,
335
385
  signUp: SIGN_UP_MACHINE_KEYS,
336
- resetPassword: RESET_PASSWORD_MACHINE_KEYS,
337
- setupTOTP: SETUP_TOTP_MACHINE_KEYS,
386
+ forgotPassword: RESET_PASSWORD_MACHINE_KEYS,
387
+ setupTotp: SETUP_TOTP_MACHINE_KEYS,
338
388
  verifyUser: VERIFY_USER_MACHINE_KEYS,
339
389
  };
340
390
 
@@ -350,47 +400,66 @@ const getRouteMachineSelector = (route) => isComponentRouteKey(route)
350
400
  : routeSelector$1;
351
401
  const isFormEventHandlerKey = (key) => ['updateBlur', 'updateForm', 'submitForm'].includes(key);
352
402
  const convertEventHandlerKey = (key) => EVENT_HANDLER_KEY_MAP[key];
353
- const getConvertedMachineProps = (route, context) => MACHINE_PROP_KEYS[route].reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [isFormEventHandlerKey(key) ? convertEventHandlerKey(key) : key]: context[key] })), {});
403
+ const getConvertedMachineProps = (route, context) => MACHINE_PROP_KEYS[route].reduce((acc, key) => ({
404
+ ...acc,
405
+ [isFormEventHandlerKey(key) ? convertEventHandlerKey(key) : key]: context[key],
406
+ }), {});
354
407
  function resolveConfirmResetPasswordRoute(Component, props) {
355
408
  return {
356
409
  Component,
357
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmResetPassword', props)),
410
+ props: {
411
+ ...Component,
412
+ ...getConvertedMachineProps('confirmResetPassword', props),
413
+ },
358
414
  };
359
415
  }
360
416
  function resolveConfirmSignInRoute(Component, props) {
361
- const _a = getConvertedMachineProps('confirmSignIn', props), { user } = _a, machineProps = __rest(_a, ["user"]);
362
- // prior to the `confirmSignIn` route, `user.username` is populated
363
- const challengeName = user.challengeName;
364
- return { Component, props: Object.assign(Object.assign(Object.assign({}, Component), machineProps), { challengeName }) };
417
+ const { challengeName, ...machineProps } = getConvertedMachineProps('confirmSignIn', props);
418
+ return { Component, props: { ...Component, ...machineProps, challengeName } };
365
419
  }
366
420
  function resolveConfirmSignUpRoute(Component, props) {
367
421
  return {
368
422
  Component,
369
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmSignUp', props)),
423
+ props: {
424
+ ...Component,
425
+ ...getConvertedMachineProps('confirmSignUp', props),
426
+ },
370
427
  };
371
428
  }
372
429
  function resolveConfirmVerifyUserRoute(Component, props) {
373
430
  return {
374
431
  Component,
375
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmVerifyUser', props)),
432
+ props: {
433
+ ...Component,
434
+ ...getConvertedMachineProps('confirmVerifyUser', props),
435
+ },
376
436
  };
377
437
  }
378
438
  function resolveForceNewPasswordRoute(Component, props) {
379
439
  return {
380
440
  Component,
381
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('forceNewPassword', props)),
441
+ props: {
442
+ ...Component,
443
+ ...getConvertedMachineProps('forceNewPassword', props),
444
+ },
382
445
  };
383
446
  }
384
- function resolveResetPasswordRoute(Component, props) {
447
+ function resolveForgotPasswordRoute(Component, props) {
385
448
  return {
386
449
  Component,
387
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('resetPassword', props)),
450
+ props: {
451
+ ...Component,
452
+ ...getConvertedMachineProps('forgotPassword', props),
453
+ },
388
454
  };
389
455
  }
390
- function resolveSetupTOTPRoute(Component, props) {
456
+ function resolveSetupTotpRoute(Component, props) {
391
457
  return {
392
458
  Component,
393
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('setupTOTP', props)),
459
+ props: {
460
+ ...Component,
461
+ ...getConvertedMachineProps('setupTotp', props),
462
+ },
394
463
  };
395
464
  }
396
465
  function resolveSignInRoute(Component, props) {
@@ -398,19 +467,26 @@ function resolveSignInRoute(Component, props) {
398
467
  const hideSignUp = false;
399
468
  return {
400
469
  Component,
401
- props: Object.assign(Object.assign(Object.assign({}, Component), getConvertedMachineProps('signIn', props)), { hideSignUp }),
470
+ props: {
471
+ ...Component,
472
+ ...getConvertedMachineProps('signIn', props),
473
+ hideSignUp,
474
+ },
402
475
  };
403
476
  }
404
477
  function resolveSignUpRoute(Component, props) {
405
478
  return {
406
479
  Component,
407
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('signUp', props)),
480
+ props: { ...Component, ...getConvertedMachineProps('signUp', props) },
408
481
  };
409
482
  }
410
483
  function resolveVerifyUserRoute(Component, props) {
411
484
  return {
412
485
  Component,
413
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('verifyUser', props)),
486
+ props: {
487
+ ...Component,
488
+ ...getConvertedMachineProps('verifyUser', props),
489
+ },
414
490
  };
415
491
  }
416
492
  function resolveDefault() {
@@ -429,7 +505,7 @@ function useAuthenticatorRoute({ components, }) {
429
505
  // Only state machine props specified by the current `routeSelector` will have their current value
430
506
  // returned by `useAuthenticator`, non-machine props returned will always be the current value
431
507
  const routeSelectorProps = useAuthenticator(routeMachineSelector);
432
- const { ConfirmResetPassword, ConfirmSignIn, ConfirmSignUp, ConfirmVerifyUser, ForceNewPassword, ResetPassword, SetupTOTP, SignIn, SignUp, VerifyUser, } = components;
508
+ const { ConfirmResetPassword, ConfirmSignIn, ConfirmSignUp, ConfirmVerifyUser, ForceNewPassword, ForgotPassword, SetupTotp, SignIn, SignUp, VerifyUser, } = components;
433
509
  switch (route) {
434
510
  case 'confirmResetPassword': {
435
511
  return resolveConfirmResetPasswordRoute(ConfirmResetPassword, routeSelectorProps);
@@ -446,11 +522,11 @@ function useAuthenticatorRoute({ components, }) {
446
522
  case 'forceNewPassword': {
447
523
  return resolveForceNewPasswordRoute(ForceNewPassword, routeSelectorProps);
448
524
  }
449
- case 'resetPassword': {
450
- return resolveResetPasswordRoute(ResetPassword, routeSelectorProps);
525
+ case 'forgotPassword': {
526
+ return resolveForgotPasswordRoute(ForgotPassword, routeSelectorProps);
451
527
  }
452
- case 'setupTOTP': {
453
- return resolveSetupTOTPRoute(SetupTOTP, routeSelectorProps);
528
+ case 'setupTotp': {
529
+ return resolveSetupTotpRoute(SetupTotp, routeSelectorProps);
454
530
  }
455
531
  case 'signIn': {
456
532
  return resolveSignInRoute(SignIn, routeSelectorProps);
@@ -528,13 +604,125 @@ function useHasValueUpdated(value, ignoreFirstRender = false) {
528
604
  return previous !== value;
529
605
  }
530
606
 
607
+ function useSetUserAgent({ componentName, packageName, version, }) {
608
+ React.useEffect(() => {
609
+ const clearUserAgent = ui.setUserAgent({
610
+ componentName,
611
+ packageName,
612
+ version,
613
+ });
614
+ return clearUserAgent;
615
+ }, [componentName, packageName, version]);
616
+ }
617
+
618
+ function useTimeout({ callback, delay, }) {
619
+ const storedCallback = React__default["default"].useRef(callback);
620
+ React__default["default"].useLayoutEffect(() => {
621
+ storedCallback.current = callback;
622
+ }, [callback]);
623
+ React__default["default"].useEffect(() => {
624
+ if (!ui.isTypedFunction(storedCallback.current) || !delay) {
625
+ return;
626
+ }
627
+ const timeoutId = setTimeout(() => {
628
+ storedCallback.current?.();
629
+ }, delay);
630
+ return () => {
631
+ clearTimeout(timeoutId);
632
+ };
633
+ }, [delay]);
634
+ }
635
+
636
+ const INVALID_OPTIONS_MESSAGE = 'an `errorMessage` or a `defaultValue` must be provided in `options`';
637
+ /**
638
+ * Uses `ContextType`/`Name` generics and `options` to create:
639
+ * - `${Name}Context`: React Context of type `ContextType`
640
+ * - `Provider${Name}`: React Context `Provider` component exposing the `ContextType`
641
+ * as optional props
642
+ * - `use${Name}`: Utility Hook exposing the values of `ContextType`. Allows
643
+ * params with `errorMessage` for granular error messaging
644
+ *
645
+ * @template ContextType Type definition of the Context.
646
+ * > For most use cases the keys of `ContextType` should not be optional in
647
+ * preference of explicit `undefined` to avoid optional types on the
648
+ * Utility Hook return
649
+ *
650
+ * @param options Context utility options. Requires a `contextName`, and
651
+ * either a `defaultValue` of `ContextType` **or** an `errorMessage`
652
+ * allowing for differing behaviors of the Utility Hook when used outside a
653
+ * parent `Provider`:
654
+ *
655
+ * - `defaultValue`: Ensures the Utility Hook returns a default value for
656
+ * scenarios **where the missing context values should not impact usage**
657
+ * - `errorMessage`: Ensures the Utility Hook throws an error for
658
+ * scenarios **where the missing context values should prevent** usage
659
+ *
660
+ * @returns `Context`, `Provider` Component and `useContext` Utility Hook
661
+ *
662
+ * @usage
663
+ * ```ts
664
+ * interface StuffContextType {
665
+ * things: number;
666
+ * }
667
+ *
668
+ * // with `defaultValue`
669
+ * const defaultValue: StuffContextType = { things: 7 };
670
+ *
671
+ * const { StuffProvider, useStuff } = createContextUtilities({
672
+ * contextName: 'Stuff',
673
+ * defaultValue,
674
+ * });
675
+ *
676
+ * // with `errorMessage`
677
+ * const { StuffProvider, useStuff } = createContextUtilities<StuffContextType>({
678
+ * contextName: 'Stuff',
679
+ * errorMessage: '`useStuff` must be used in a `StuffProvider`'
680
+ * });
681
+ * ```
682
+ */
683
+ function createContextUtilities(options) {
684
+ const { contextName, defaultValue, errorMessage } = options ?? {};
685
+ if (ui.isUndefined(defaultValue) && !ui.isString(errorMessage)) {
686
+ throw new Error(INVALID_OPTIONS_MESSAGE);
687
+ }
688
+ const Context = React__default["default"].createContext(defaultValue);
689
+ function Provider(props) {
690
+ const { children, ...context } = props;
691
+ const value = React__default["default"].useMemo(() => context,
692
+ // Unpack `context` for the dep array; using `[context]` results in
693
+ // evaluation on every render
694
+ // eslint-disable-next-line react-hooks/exhaustive-deps
695
+ Object.values(context));
696
+ return React__default["default"].createElement(Context.Provider, { value: value }, children);
697
+ }
698
+ Provider.displayName = `${contextName}Provider`;
699
+ return {
700
+ [`use${contextName}`]: function (params) {
701
+ const context = React__default["default"].useContext(Context);
702
+ if (ui.isUndefined(context)) {
703
+ throw new Error(params?.errorMessage ?? errorMessage);
704
+ }
705
+ return context;
706
+ },
707
+ [`${contextName}Provider`]: Provider,
708
+ [`${contextName}Context`]: Context,
709
+ };
710
+ }
711
+
531
712
  exports.AuthenticatorProvider = AuthenticatorProvider;
713
+ exports.FormProvider = FormProvider;
532
714
  exports.RenderNothing = RenderNothing;
715
+ exports.createContextUtilities = createContextUtilities;
533
716
  exports.isAuthenticatorComponentRouteKey = isComponentRouteKey;
534
717
  exports.resolveAuthenticatorComponents = resolveAuthenticatorComponents;
535
718
  exports.useAuthenticator = useAuthenticator;
536
719
  exports.useAuthenticatorInitMachine = useAuthenticatorInitMachine;
537
720
  exports.useAuthenticatorRoute = useAuthenticatorRoute;
538
721
  exports.useDeprecationWarning = useDeprecationWarning;
722
+ exports.useField = useField;
723
+ exports.useForm = useForm;
539
724
  exports.useHasValueUpdated = useHasValueUpdated;
540
725
  exports.usePreviousValue = usePreviousValue;
726
+ exports.useSetUserAgent = useSetUserAgent;
727
+ exports.useTimeout = useTimeout;
728
+ exports.withFormProvider = withFormProvider;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import { AuthChallengeName, AuthenticatorServiceFacade, LegacyFormFieldOptions } from '@aws-amplify/ui';
2
+ import { ChallengeName, AuthenticatorServiceFacade, LegacyFormFieldOptions } from '@aws-amplify/ui';
3
3
  import { UseAuthenticator } from './useAuthenticator';
4
- export type AuthenticatorRouteComponentKey = 'confirmResetPassword' | 'confirmSignIn' | 'confirmSignUp' | 'confirmVerifyUser' | 'forceNewPassword' | 'resetPassword' | 'setupTOTP' | 'signIn' | 'signUp' | 'verifyUser';
4
+ export type AuthenticatorRouteComponentKey = 'confirmResetPassword' | 'confirmSignIn' | 'confirmSignUp' | 'confirmVerifyUser' | 'forceNewPassword' | 'forgotPassword' | 'setupTotp' | 'signIn' | 'signUp' | 'verifyUser';
5
5
  export type AuthenticatorLegacyField = LegacyFormFieldOptions;
6
6
  export type AuthenticatorLegacyFields = AuthenticatorLegacyField[];
7
7
  /**
@@ -52,7 +52,7 @@ export type ConfirmResetPasswordBaseProps<FieldType = {}> = {
52
52
  resendCode: UseAuthenticator['resendCode'];
53
53
  } & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
54
54
  export type ConfirmSignInBaseProps<FieldType = {}> = {
55
- challengeName: AuthChallengeName;
55
+ challengeName: ChallengeName | undefined;
56
56
  toSignIn: UseAuthenticator['toSignIn'];
57
57
  } & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
58
58
  export type ConfirmSignUpBaseProps<FieldType = {}> = {
@@ -68,18 +68,21 @@ export type ForceResetPasswordBaseProps<FieldType = {}> = {
68
68
  export type ResetPasswordBaseProps<FieldType = {}> = {
69
69
  toSignIn: UseAuthenticator['toSignIn'];
70
70
  } & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
71
- export type SetupTOTPBaseProps<FieldType = {}> = {
71
+ export type SetupTotpBaseProps<FieldType = {}> = {
72
72
  toSignIn: UseAuthenticator['toSignIn'];
73
73
  totpSecretCode: UseAuthenticator['totpSecretCode'];
74
+ username: UseAuthenticator['username'];
74
75
  } & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
75
76
  export type SignInBaseProps<FieldType = {}> = {
76
77
  hideSignUp?: boolean;
78
+ socialProviders?: UseAuthenticator['socialProviders'];
77
79
  toFederatedSignIn: UseAuthenticator['toFederatedSignIn'];
78
- toResetPassword: UseAuthenticator['toResetPassword'];
80
+ toForgotPassword: UseAuthenticator['toForgotPassword'];
79
81
  toSignUp: UseAuthenticator['toSignUp'];
80
82
  } & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
81
83
  export type SignUpBaseProps<FieldType = {}> = {
82
84
  hideSignIn?: boolean;
85
+ socialProviders?: UseAuthenticator['socialProviders'];
83
86
  toFederatedSignIn: UseAuthenticator['toFederatedSignIn'];
84
87
  toSignIn: UseAuthenticator['toSignIn'];
85
88
  } & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
@@ -92,8 +95,8 @@ export interface DefaultProps<FieldType = {}> {
92
95
  ConfirmResetPassword: ConfirmResetPasswordBaseProps<FieldType>;
93
96
  ConfirmVerifyUser: ConfirmVerifyUserProps<FieldType>;
94
97
  ForceNewPassword: ForceResetPasswordBaseProps<FieldType>;
95
- ResetPassword: ResetPasswordBaseProps<FieldType>;
96
- SetupTOTP: SetupTOTPBaseProps<FieldType>;
98
+ ForgotPassword: ResetPasswordBaseProps<FieldType>;
99
+ SetupTotp: SetupTotpBaseProps<FieldType>;
97
100
  SignIn: SignInBaseProps<FieldType>;
98
101
  SignUp: SignUpBaseProps<FieldType>;
99
102
  VerifyUser: VerifyUserProps<FieldType>;
@@ -5,7 +5,7 @@ import { AuthenticatorServiceFacade, LegacyFormFieldOptions } from '@aws-amplify
5
5
  */
6
6
  type AuthenticatorMachineContext = AuthenticatorServiceFacade;
7
7
  type AuthenticatorMachineContextKey = keyof AuthenticatorMachineContext;
8
- export type AuthenticatorRouteComponentKey = 'signIn' | 'signUp' | 'forceNewPassword' | 'confirmResetPassword' | 'confirmSignIn' | 'confirmSignUp' | 'confirmVerifyUser' | 'resetPassword' | 'setupTOTP' | 'verifyUser';
8
+ export type AuthenticatorRouteComponentKey = 'signIn' | 'signUp' | 'forceNewPassword' | 'confirmResetPassword' | 'confirmSignIn' | 'confirmSignUp' | 'confirmVerifyUser' | 'forgotPassword' | 'setupTotp' | 'verifyUser';
9
9
  export type AuthenticatorLegacyFields = LegacyFormFieldOptions[];
10
10
  /**
11
11
  * Inspired from https://xstate.js.org/docs/packages/xstate-react/#useselector-actor-selector-compare-getsnapshot.
@@ -18,8 +18,6 @@ export interface UseAuthenticator extends AuthenticatorServiceFacade {
18
18
  /** @deprecated For internal use only */
19
19
  fields: AuthenticatorLegacyFields;
20
20
  /** @deprecated For internal use only */
21
- getTotpSecretCode: () => Promise<string>;
22
- /** @deprecated For internal use only */
23
21
  QRFields: {
24
22
  totpIssuer?: string;
25
23
  totpUsername?: string;
@@ -1,4 +1,4 @@
1
- import { AmplifyUser, AuthenticatorRoute, AuthMachineState, UnverifiedContactMethods } from '@aws-amplify/ui';
1
+ import { AuthenticatorRoute, AuthMachineState, UnverifiedUserAttributes } from '@aws-amplify/ui';
2
2
  import { AuthenticatorLegacyFields } from '../types';
3
3
  import { Comparator, UseAuthenticatorSelector } from './types';
4
4
  export declare const defaultComparator: () => false;
@@ -12,9 +12,8 @@ export declare const getQRFields: (state: AuthMachineState) => {
12
12
  totpIssuer?: string;
13
13
  totpUsername?: string;
14
14
  };
15
- export declare const getTotpSecretCodeCallback: (user: AmplifyUser) => () => Promise<string>;
16
15
  /**
17
16
  * Retrieves default and custom (RWA only, to be updated) form field values from state machine
18
17
  * for subcomponent routes that render fields
19
18
  */
20
- export declare const getMachineFields: (route: AuthenticatorRoute, state: AuthMachineState, unverifiedContactMethods: UnverifiedContactMethods) => AuthenticatorLegacyFields;
19
+ export declare const getMachineFields: (route: AuthenticatorRoute, state: AuthMachineState, unverifiedUserAttributes: UnverifiedUserAttributes) => AuthenticatorLegacyFields;