@wise/dynamic-flow-client 3.2.2 → 3.3.1

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.
package/build/main.js CHANGED
@@ -3484,13 +3484,14 @@ var logInvalidTypeFallbackWarning = ({
3484
3484
  };
3485
3485
 
3486
3486
  // src/legacy/formControl/utils/getAutocompleteString.ts
3487
- var getAutocompleteString = (hints) => {
3488
- const validHints = hints.filter((hint) => autocompleteTokenMap[hint]);
3489
- if (validHints.length === 0) {
3490
- return "off";
3491
- }
3492
- return validHints.map((hint) => autocompleteTokenMap[hint]).join(" ");
3493
- };
3487
+ var getAutocompleteString = (hints, { prefix = "", suffix = "" } = {}) => {
3488
+ const autoCompleteString = hints.map((hint) => {
3489
+ const builtHint = `${prefix}${hint}${suffix}`;
3490
+ return isAutocompleteToken(builtHint) ? autocompleteTokenMap[builtHint] : void 0;
3491
+ }).filter((str) => str).join(" ");
3492
+ return autoCompleteString || "off";
3493
+ };
3494
+ var isAutocompleteToken = (str) => Object.keys(autocompleteTokenMap).some((hint) => hint === str);
3494
3495
  var autocompleteTokenMap = {
3495
3496
  on: "on",
3496
3497
  name: "name",
@@ -3563,15 +3564,12 @@ var import_jsx_runtime27 = require("react/jsx-runtime");
3563
3564
  var _FormControl = class _FormControl extends import_react16.PureComponent {
3564
3565
  constructor(props) {
3565
3566
  super(props);
3566
- this.getAutocompleteValue = () => {
3567
+ this.getAutocompleteValue = ({ prefix = "", suffix = "" } = {}) => {
3567
3568
  const { autoComplete, autocompleteHint } = this.props;
3568
3569
  if (isArray(autocompleteHint)) {
3569
- return getAutocompleteString(autocompleteHint);
3570
+ return getAutocompleteString(autocompleteHint, { prefix, suffix });
3570
3571
  }
3571
- if (autoComplete === true) {
3572
- return "on";
3573
- }
3574
- return "off";
3572
+ return autoComplete ? "on" : "off";
3575
3573
  };
3576
3574
  this.handleOnChange = (value, metadata) => {
3577
3575
  this.props.onChange(value, void 0, metadata);
@@ -3802,6 +3800,8 @@ var _FormControl = class _FormControl extends import_react16.PureComponent {
3802
3800
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3803
3801
  import_components13.DateInput,
3804
3802
  {
3803
+ dayAutoComplete: this.getAutocompleteValue({ suffix: "-day" }),
3804
+ yearAutoComplete: this.getAutocompleteValue({ suffix: "-year" }),
3805
3805
  disabled,
3806
3806
  size,
3807
3807
  value: getSafeDateOrStringValue(value),
@@ -8014,7 +8014,7 @@ var th_default = {
8014
8014
  // src/i18n/tr.json
8015
8015
  var tr_default = {
8016
8016
  "dynamicFlows.ArraySchema.addItem": "Kaydet",
8017
- "dynamicFlows.ArraySchema.addItemTitle": "\xD6\u011Fe ekle",
8017
+ "dynamicFlows.ArraySchema.addItemTitle": "\xD6ge ekle",
8018
8018
  "dynamicFlows.ArraySchema.editItem": "Kaydet",
8019
8019
  "dynamicFlows.ArraySchema.maxItemsError": "L\xFCtfen {maxItems} veya daha az ekleme yap\u0131n",
8020
8020
  "dynamicFlows.ArraySchema.minItemsError": "L\xFCtfen en az {minItems} ekleme yap\u0131n.",
@@ -8045,7 +8045,7 @@ var tr_default = {
8045
8045
  "dynamicFlows.DynamicExternal.retryTitle": "Pencereyi yeniden a\xE7",
8046
8046
  "dynamicFlows.DynamicParagraph.copied": "Panoya kopyaland\u0131",
8047
8047
  "dynamicFlows.DynamicParagraph.copy": "Kopyala",
8048
- "dynamicFlows.ErrorBoundary.errorAlert": "Bir \u015Fey yanl\u0131\u015F gitti.",
8048
+ "dynamicFlows.ErrorBoundary.errorAlert": "Bir sorun olu\u015Ftu.",
8049
8049
  "dynamicFlows.ErrorBoundary.retry": "Tekrar dene",
8050
8050
  "dynamicFlows.ExternalConfirmation.cancel": "\u0130ptal edin",
8051
8051
  "dynamicFlows.ExternalConfirmation.description": "L\xFCtfen yeni bir taray\u0131c\u0131 sekmesinde **{origin}** a\xE7mak istedi\u011Finizi onaylay\u0131n.",
@@ -8249,7 +8249,7 @@ function $1746a345f3d73bb7$export$f680877a34711e37(deterministicId) {
8249
8249
  return deterministicId || (id ? `radix-${id}` : "");
8250
8250
  }
8251
8251
 
8252
- // ../../node_modules/.pnpm/@wise+forms@0.3.1_@transferwise+components@46.17.2_@types+react@18.0.29_react@18.2.0/node_modules/@wise/forms/dist/index.esm.js
8252
+ // ../../node_modules/.pnpm/@wise+forms@0.3.3_@transferwise+components@46.20.1_@types+react@18.0.29_react@18.2.0/node_modules/@wise/forms/dist/index.esm.js
8253
8253
  var import_components39 = require("@transferwise/components");
8254
8254
  var import_classnames9 = __toESM(require_classnames());
8255
8255
  var import_react49 = require("react");
@@ -8261,11 +8261,13 @@ var FormControlDescribedByProvider = FormControlDescribedByContext.Provider;
8261
8261
  var FormControlInvalidContext = /* @__PURE__ */ (0, import_react49.createContext)(void 0);
8262
8262
  var FormControlInvalidProvider = FormControlInvalidContext.Provider;
8263
8263
  var Label = ({
8264
+ id,
8264
8265
  htmlFor,
8265
8266
  className,
8266
8267
  children
8267
8268
  }) => {
8268
8269
  return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("label", {
8270
+ id,
8269
8271
  htmlFor,
8270
8272
  className: (0, import_classnames9.default)("control-label d-flex flex-column gap-y-1 m-b-0", className),
8271
8273
  children
@@ -8282,7 +8284,7 @@ var Field = ({
8282
8284
  const hasError = Boolean(error);
8283
8285
  const hasHint = Boolean(hint) && !hasError;
8284
8286
  const fallbackInputId = $1746a345f3d73bb7$export$f680877a34711e37();
8285
- const inputId = id != null ? id : fallbackInputId;
8287
+ const inputId = id !== null ? id != null ? id : fallbackInputId : void 0;
8286
8288
  const descriptionId = $1746a345f3d73bb7$export$f680877a34711e37();
8287
8289
  return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(InputIdContextProvider, {
8288
8290
  value: inputId,
@@ -9981,33 +9983,6 @@ var getWiseRenderers = () => [
9981
9983
  var import_react58 = require("react");
9982
9984
  var import_react_intl35 = require("react-intl");
9983
9985
 
9984
- // src/revamp/domain/features/events/getAnalyticsEventDispatcher.ts
9985
- var getAnalyticsEventDispatcher = ({
9986
- flowId,
9987
- stepId,
9988
- analytics,
9989
- onEvent
9990
- }) => {
9991
- const metadata = __spreadValues(__spreadValues({
9992
- flowId
9993
- }, stepId ? { stepId } : {}), analytics != null ? analytics : {});
9994
- return (eventName, properties = {}) => {
9995
- try {
9996
- onEvent == null ? void 0 : onEvent(`${eventNamePrefix}${eventName}`, __spreadValues(__spreadValues({}, metadata), properties));
9997
- } catch (e) {
9998
- }
9999
- };
10000
- };
10001
- var eventNamePrefix = "Dynamic Flow - ";
10002
-
10003
- // src/revamp/domain/features/events/getLogggingEventDispatcher.ts
10004
- var getLoggingEventDispatcher = (onLog) => (level, message, extra = {}) => {
10005
- try {
10006
- onLog == null ? void 0 : onLog(level, message, extra);
10007
- } catch (e) {
10008
- }
10009
- };
10010
-
10011
9986
  // src/revamp/utils/type-validators.ts
10012
9987
  var isString2 = (value) => typeof value === "string";
10013
9988
  var isNumber3 = (value) => typeof value === "number" && !Number.isNaN(value);
@@ -10020,87 +9995,12 @@ var isUndefined3 = (value) => typeof value === "undefined";
10020
9995
  var isNullish3 = (v) => isNull3(v) || isUndefined3(v);
10021
9996
  var isFile = (value) => value instanceof File;
10022
9997
 
10023
- // src/revamp/flow/response-utils.ts
10024
- var assertResponseIsValid2 = (response) => {
10025
- if (!isResponse2(response)) {
10026
- throw new Error("Incorrect type of response from fetch. Expected object of type Response.");
10027
- }
10028
- if (response.bodyUsed) {
10029
- throw new Error(
10030
- "The body of the provided Response object has already been used. Every request must respond with a new Response object."
10031
- );
10032
- }
10033
- };
10034
- var isResponse2 = (response) => typeof response === "object" && response !== null && "clone" in response && "bodyUsed" in response;
10035
- var parseResponseBodyAsJsonElement = async (response) => {
10036
- try {
10037
- return await response.json();
10038
- } catch (e) {
10039
- return null;
10040
- }
10041
- };
10042
- function assertActionResponseBody(body) {
10043
- if (!isObject2(body) || !isObject2(body.action)) {
10044
- throw new Error(
10045
- "Incorrect response body in action response. Expected an object satisfying the type { action: Action }."
10046
- );
10047
- }
10048
- }
10049
- function isErrorResponseBody(body) {
10050
- return Boolean(
10051
- isObject2(body) && (body.refreshFormUrl || body.refreshUrl || body.validation || body.error || body.analytics)
10052
- );
10053
- }
10054
- function assertStepResponseBody(body) {
10055
- if (!isObject2(body)) {
10056
- throw new Error("Incorrect response body in step response. Expected an object.");
10057
- }
10058
- }
10059
-
10060
- // src/revamp/flow/executeRefresh.ts
10061
- var executeRefresh = async (props) => {
10062
- const { abortSignal, url, model, schemaId, etag, httpClient, trackEvent } = props;
10063
- trackEvent("Refresh Triggered", { schema: schemaId });
10064
- try {
10065
- const response = await httpClient(url != null ? url : "", {
10066
- method: "POST",
10067
- body: JSON.stringify(model),
10068
- headers: __spreadValues({
10069
- "Content-Type": "application/json"
10070
- }, etag ? { "If-None-Match": etag } : {}),
10071
- signal: abortSignal
10072
- });
10073
- if (response.status === 304) {
10074
- trackEvent("Refresh Succeeded", { schema: schemaId });
10075
- return { type: "noop" };
10076
- }
10077
- if (!response.ok) {
10078
- const responseBody = await parseResponseBodyAsJsonElement(response).catch(() => ({}));
10079
- const body2 = isErrorResponseBody(responseBody) ? responseBody : {};
10080
- trackEvent("Refresh Failed", __spreadValues({ schema: schemaId }, body2.analytics));
10081
- return { type: "error", body: body2 };
10082
- }
10083
- const newEtag = response.headers.get("etag") || null;
10084
- const body = await parseResponseBodyAsJsonElement(response);
10085
- assertStepResponseBody(body);
10086
- trackEvent("Refresh Succeeded", { schema: schemaId });
10087
- return { type: "refresh-step", step: body, etag: newEtag };
10088
- } catch (error) {
10089
- if (error instanceof DOMException && error.name === "AbortError") {
10090
- trackEvent("Refresh Aborted", { schema: schemaId });
10091
- return { type: "noop" };
10092
- }
10093
- trackEvent("Refresh Failed", { schema: schemaId });
10094
- return { type: "error", body: {} };
10095
- }
10096
- };
10097
-
10098
9998
  // src/revamp/utils/type-utils.ts
10099
9999
  var hasChildren = (component) => "getChildren" in component && typeof component.getChildren === "function";
10100
10000
  var isColumnsComponent = (component) => Object.hasOwnProperty.call(component, "startComponents") && Object.hasOwnProperty.call(component, "endComponents");
10101
10001
  var isHiddenComponent = (component) => "hidden" in component && component.hidden;
10102
10002
  var isRepeatableComponent = (component) => Object.hasOwnProperty.call(component, "editableComponent");
10103
- var isObjectLocalValue = (value) => value != null && typeof value === "object" && !Array.isArray(value);
10003
+ var isObjectLocalValue = (value) => value != null && typeof value === "object" && !Array.isArray(value) && !(value instanceof File);
10104
10004
  var isObjectModel2 = (model) => model != null && typeof model === "object" && !Array.isArray(model);
10105
10005
  var isArrayModel2 = (model) => Array.isArray(model);
10106
10006
  var isAllOfSchema2 = (schema) => "allOf" in schema && !isNullish3(schema.allOf);
@@ -10147,125 +10047,6 @@ var mergeModels = (valueA, valueB) => {
10147
10047
  return valueB;
10148
10048
  };
10149
10049
 
10150
- // src/revamp/flow/getResponseType.ts
10151
- var responseTypes = ["step", "action", "exit"];
10152
- var getResponseType = async (response) => {
10153
- var _a, _b;
10154
- assertResponseIsValid2(response);
10155
- if ((_a = response.headers) == null ? void 0 : _a.has("X-Df-Response-Type")) {
10156
- const type = response.headers.get("X-Df-Response-Type");
10157
- assertDFResponseType(type);
10158
- return type;
10159
- }
10160
- if ((_b = response.headers) == null ? void 0 : _b.has("X-Df-Exit")) {
10161
- return "exit";
10162
- }
10163
- const jsonBody = await parseResponseBodyAsJsonElement(response.clone());
10164
- if (isObject2(jsonBody) && jsonBody.action) {
10165
- return "action";
10166
- }
10167
- return "step";
10168
- };
10169
- function assertDFResponseType(type) {
10170
- if (!responseTypes.includes(type)) {
10171
- throw new Error(
10172
- "Unsupported X-Df-Response-Type. Allowed values are 'step', 'action', 'exit', 'error'."
10173
- );
10174
- }
10175
- }
10176
-
10177
- // src/revamp/flow/executeSubmission.ts
10178
- var executeSubmission = async (props) => {
10179
- const { httpClient, trackEvent } = props;
10180
- const triggerAction = async (action, model, isInitial) => {
10181
- const { exit, url, method = "POST", result = null, id: actionId } = action;
10182
- const trackSubmissionEvent = !isInitial ? trackEvent : () => {
10183
- };
10184
- trackSubmissionEvent("Action Triggered", { actionId });
10185
- if (exit && !url) {
10186
- trackSubmissionEvent("Action Succeeded", { actionId });
10187
- return { type: "complete", result };
10188
- }
10189
- try {
10190
- const response = await httpClient(url != null ? url : "", {
10191
- method,
10192
- body: method === "GET" ? void 0 : JSON.stringify(model),
10193
- headers: { "Content-Type": "application/json" }
10194
- });
10195
- if (!response.ok) {
10196
- return await handleErrorResponse(response, actionId);
10197
- }
10198
- const responseType = await getResponseType(response);
10199
- const body = await parseResponseBodyAsJsonElement(response);
10200
- if (exit) {
10201
- return { type: "complete", result: mergeModels(result, body) };
10202
- }
10203
- switch (responseType) {
10204
- case "step": {
10205
- const etag = response.headers.get("etag") || null;
10206
- assertStepResponseBody(body);
10207
- trackSubmissionEvent("Action Succeeded", { actionId });
10208
- return { type: "replace-step", step: body, etag };
10209
- }
10210
- case "exit": {
10211
- trackSubmissionEvent("Action Succeeded", { actionId });
10212
- return { type: "complete", result: mergeModels(result, body) };
10213
- }
10214
- case "action": {
10215
- assertActionResponseBody(body);
10216
- trackSubmissionEvent("Action Succeeded", { actionId });
10217
- return await triggerAction(body.action, null, false);
10218
- }
10219
- default: {
10220
- throw new Error(`Unsupported response type: ${String(responseType)}`);
10221
- }
10222
- }
10223
- } catch (error) {
10224
- trackSubmissionEvent("Action Failed", { actionId });
10225
- throw error;
10226
- }
10227
- };
10228
- const handleErrorResponse = async (response, actionId) => {
10229
- const body = await parseResponseBodyAsJsonElement(response);
10230
- if (isErrorResponseBody(body)) {
10231
- const refreshUrl = body.refreshUrl || body.refreshFormUrl;
10232
- const { error, validation, analytics } = body;
10233
- trackEvent("Action Failed", __spreadValues({ actionId }, analytics));
10234
- const errors = { error, validation };
10235
- return refreshUrl ? { type: "refresh", body: { refreshUrl, errors } } : { type: "error", body: { errors, analytics } };
10236
- }
10237
- trackEvent("Action Failed", { actionId });
10238
- return { type: "error", body: {} };
10239
- };
10240
- return triggerAction(props.action, props.model, props.isInitial);
10241
- };
10242
-
10243
- // src/revamp/renderers/CoreContainerRenderer.tsx
10244
- var import_jsx_runtime117 = require("react/jsx-runtime");
10245
- var CoreContainerRenderer = {
10246
- canRenderType: "container",
10247
- render: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_jsx_runtime117.Fragment, { children })
10248
- };
10249
-
10250
- // src/revamp/renderers/StepRenderer.tsx
10251
- var import_react56 = require("react");
10252
- var import_jsx_runtime118 = require("react/jsx-runtime");
10253
- var StepRenderer = {
10254
- canRenderType: "step",
10255
- render: StepRendererComponent
10256
- };
10257
- function StepRendererComponent({ children, loadingState }) {
10258
- const value = (0, import_react56.useMemo)(() => ({ loadingState }), [loadingState]);
10259
- return /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(LoadingContextProvider, { value, children });
10260
- }
10261
-
10262
- // src/revamp/step/Step.tsx
10263
- var import_react57 = require("react");
10264
-
10265
- // src/revamp/domain/features/validation/validation-functions.ts
10266
- var validateComponents = (components) => components.reduce((acc, component) => component.validate() && acc, true);
10267
- var getLocalValueValidator = (checks) => (currentValue) => checks.map((check) => check(currentValue)).filter(isString2);
10268
-
10269
10050
  // src/revamp/domain/features/summary/summary-utils.ts
10270
10051
  var getSummariser = (schema) => (value) => {
10271
10052
  const { summary, icon, image } = schema;
@@ -10302,45 +10083,63 @@ var summaryIfProvides = (summary, { value, icon, image }) => {
10302
10083
  };
10303
10084
  };
10304
10085
 
10305
- // src/revamp/domain/components/StepDomainComponent.ts
10306
- var createStepComponent = (containerProps) => __spreadProps(__spreadValues({}, containerProps), {
10307
- type: "step",
10308
- getChildren() {
10309
- return this.components;
10310
- },
10311
- async getSubmittableValue() {
10312
- return getSubmittableData(this.components);
10313
- },
10314
- getSummary() {
10315
- return summariseFromChildren(this.getChildren());
10316
- },
10317
- getLocalValue() {
10318
- return getLocalValues(this.components);
10319
- },
10320
- validate() {
10321
- return validateComponents(this.getChildren());
10322
- }
10323
- });
10324
- var createEmptyStepComponent = () => createStepComponent({
10325
- uid: "",
10326
- loadingState: "idle",
10327
- components: []
10328
- });
10086
+ // src/revamp/domain/features/validation/validation-functions.ts
10087
+ var validateComponents = (components) => components.reduce((acc, component) => component.validate() && acc, true);
10088
+ var getLocalValueValidator = (checks) => (currentValue) => checks.map((check) => check(currentValue)).filter(isString2);
10329
10089
 
10330
- // src/revamp/domain/components/AlertComponent.ts
10331
- var createAlertComponent = (alertProps) => __spreadProps(__spreadValues({
10332
- type: "alert"
10333
- }, alertProps), {
10334
- getSubmittableValue: async () => null,
10335
- getLocalValue: () => null,
10336
- getSummary: () => ({}),
10337
- // Noop
10338
- validate: () => true
10339
- });
10090
+ // src/revamp/domain/components/utils/component-utils.ts
10091
+ var getInputUpdateFunction = (uid, updateComponent) => (updateFn) => {
10092
+ updateComponent(uid, (draft) => {
10093
+ const draftState = draft;
10094
+ updateFn(draftState);
10095
+ });
10096
+ };
10340
10097
 
10341
- // src/revamp/domain/mappers/utils/legacy-utils.ts
10342
- var mapLegacyContext = (context) => {
10343
- switch (context) {
10098
+ // src/revamp/domain/components/StepDomainComponent.ts
10099
+ var createStepComponent = (stepProps) => {
10100
+ const _a = stepProps, { uid, updateComponent } = _a, rest = __objRest(_a, ["uid", "updateComponent"]);
10101
+ const update = getInputUpdateFunction(uid, updateComponent);
10102
+ return __spreadProps(__spreadValues({
10103
+ uid
10104
+ }, rest), {
10105
+ type: "step",
10106
+ getChildren() {
10107
+ return this.components;
10108
+ },
10109
+ async getSubmittableValue() {
10110
+ return getSubmittableData(this.components);
10111
+ },
10112
+ getSummary() {
10113
+ return summariseFromChildren(this.getChildren());
10114
+ },
10115
+ getLocalValue() {
10116
+ return getLocalValues(this.components);
10117
+ },
10118
+ validate() {
10119
+ return validateComponents(this.getChildren());
10120
+ },
10121
+ setLoadingState(loadingState) {
10122
+ update((draft) => {
10123
+ draft.loadingState = loadingState;
10124
+ });
10125
+ }
10126
+ });
10127
+ };
10128
+
10129
+ // src/revamp/domain/components/AlertComponent.ts
10130
+ var createAlertComponent = (alertProps) => __spreadProps(__spreadValues({
10131
+ type: "alert"
10132
+ }, alertProps), {
10133
+ getSubmittableValue: async () => null,
10134
+ getLocalValue: () => null,
10135
+ getSummary: () => ({}),
10136
+ // Noop
10137
+ validate: () => true
10138
+ });
10139
+
10140
+ // src/revamp/domain/mappers/utils/legacy-utils.ts
10141
+ var mapLegacyContext = (context) => {
10142
+ switch (context) {
10344
10143
  case "success":
10345
10144
  return "positive";
10346
10145
  case "failure":
@@ -10582,14 +10381,6 @@ var createDividerComponent = (props) => __spreadProps(__spreadValues({
10582
10381
  // src/revamp/domain/mappers/layout/dividerLayoutToComponent.ts
10583
10382
  var dividerLayoutToComponent = (uid, { control, margin = "md" }) => createDividerComponent({ uid, control, margin });
10584
10383
 
10585
- // src/revamp/domain/components/utils/component-utils.ts
10586
- var getInputUpdateFunction = (uid, updateComponent) => (updateFn) => {
10587
- updateComponent(uid, (draft) => {
10588
- const draftState = draft;
10589
- updateFn(draftState);
10590
- });
10591
- };
10592
-
10593
10384
  // src/revamp/domain/features/utils/http-utils.ts
10594
10385
  function constructPayload({
10595
10386
  value,
@@ -11041,6 +10832,43 @@ var autocompleteTokenMap2 = {
11041
10832
  pager: "pager"
11042
10833
  };
11043
10834
 
10835
+ // src/revamp/flow/response-utils.ts
10836
+ var assertResponseIsValid2 = (response) => {
10837
+ if (!isResponse2(response)) {
10838
+ throw new Error("Incorrect type of response from fetch. Expected object of type Response.");
10839
+ }
10840
+ if (response.bodyUsed) {
10841
+ throw new Error(
10842
+ "The body of the provided Response object has already been used. Every request must respond with a new Response object."
10843
+ );
10844
+ }
10845
+ };
10846
+ var isResponse2 = (response) => typeof response === "object" && response !== null && "clone" in response && "bodyUsed" in response;
10847
+ var parseResponseBodyAsJsonElement = async (response) => {
10848
+ try {
10849
+ return await response.json();
10850
+ } catch (e) {
10851
+ return null;
10852
+ }
10853
+ };
10854
+ function assertActionResponseBody(body) {
10855
+ if (!isObject2(body) || !isObject2(body.action)) {
10856
+ throw new Error(
10857
+ "Incorrect response body in action response. Expected an object satisfying the type { action: Action }."
10858
+ );
10859
+ }
10860
+ }
10861
+ function isErrorResponseBody(body) {
10862
+ return Boolean(
10863
+ isObject2(body) && (body.refreshFormUrl || body.refreshUrl || body.validation || body.error || body.analytics)
10864
+ );
10865
+ }
10866
+ function assertStepResponseBody(body) {
10867
+ if (!isObject2(body)) {
10868
+ throw new Error("Incorrect response body in step response. Expected an object.");
10869
+ }
10870
+ }
10871
+
11044
10872
  // src/revamp/domain/features/utils/response-utils.ts
11045
10873
  var getAnalyticsFromErrorResponse = (json) => {
11046
10874
  if (!isErrorResponseBody(json)) {
@@ -11583,6 +11411,22 @@ var integerSchemaToComponent = (schemaMapperProps, mapperProps) => {
11583
11411
  );
11584
11412
  };
11585
11413
 
11414
+ // src/revamp/domain/components/utils/getComponentForLocalValueKey.ts
11415
+ var getComponentForLocalValueKey = (key, component) => {
11416
+ if (component.type === "object") {
11417
+ return component.componentMap[key];
11418
+ }
11419
+ if (component.type === "select") {
11420
+ const selectedChild = component.getSelectedChild();
11421
+ return selectedChild ? getComponentForLocalValueKey(key, selectedChild) : null;
11422
+ }
11423
+ const child = hasChildren(component) ? [...component.getChildren()].reverse().find((c) => {
11424
+ const v = c.getLocalValue();
11425
+ return isObjectLocalValue(v) && key in v;
11426
+ }) : void 0;
11427
+ return child ? getComponentForLocalValueKey(key, child) : null;
11428
+ };
11429
+
11586
11430
  // src/revamp/domain/components/utils/isPartialLocalValueMatch.ts
11587
11431
  var isPartialLocalValueMatch = (partialValue, component) => {
11588
11432
  if (isArray2(partialValue) && component.type === "repeatable") {
@@ -11592,18 +11436,19 @@ var isPartialLocalValueMatch = (partialValue, component) => {
11592
11436
  return childComponent ? isPartialLocalValueMatch(value, childComponent) : false;
11593
11437
  });
11594
11438
  }
11595
- if (isObjectLocalValue(partialValue) && component.type === "object") {
11439
+ const componentValue = component.getLocalValue();
11440
+ if (isObjectLocalValue(partialValue) && isObjectLocalValue(componentValue)) {
11596
11441
  const allKeys = Array.from(
11597
- /* @__PURE__ */ new Set([...Object.keys(partialValue), ...Object.keys(component.componentMap)])
11442
+ /* @__PURE__ */ new Set([...Object.keys(partialValue), ...Object.keys(componentValue)])
11598
11443
  );
11599
11444
  const matchingKeys = allKeys.filter(
11600
- (key) => !isNullish3(partialValue[key]) && !isNullish3(component.componentMap[key])
11601
- );
11602
- return matchingKeys.every(
11603
- (key) => isPartialLocalValueMatch(partialValue[key], component.componentMap[key])
11445
+ (key) => !isNullish3(partialValue[key]) && !isNullish3(componentValue[key])
11604
11446
  );
11447
+ return matchingKeys.every((key) => {
11448
+ const componentForKey = getComponentForLocalValueKey(key, component);
11449
+ return componentForKey ? isPartialLocalValueMatch(partialValue[key], componentForKey) : false;
11450
+ });
11605
11451
  }
11606
- const componentValue = component.getLocalValue();
11607
11452
  if (partialValue instanceof File && componentValue instanceof File) {
11608
11453
  return areEquivalentFiles(partialValue, componentValue);
11609
11454
  }
@@ -12810,7 +12655,8 @@ var formLayoutToComponent = (uid, { schemaId, schema: schemaRef, control, margin
12810
12655
  schema,
12811
12656
  model: model != null ? model : null,
12812
12657
  localValue: stepLocalValue,
12813
- validationErrors: errors == null ? void 0 : errors.validation
12658
+ validationErrors: errors == null ? void 0 : errors.validation,
12659
+ required: true
12814
12660
  },
12815
12661
  mapperProps
12816
12662
  )
@@ -13242,9 +13088,47 @@ var mapStepToComponent = (_a) => {
13242
13088
  "loadingState",
13243
13089
  "displayStepTitle"
13244
13090
  ]);
13245
- const { id, key, title, layout = [], errors } = mapperProps.step;
13091
+ var _a2;
13092
+ const { step, updateComponent } = mapperProps;
13093
+ const { id, key, layout = [] } = step;
13094
+ const refreshUrl = (_a2 = step.refreshUrl) != null ? _a2 : step.refreshFormUrl;
13246
13095
  const stepId = id || key;
13096
+ if (stepId === void 0) {
13097
+ throw new Error("Step must have an id or a key");
13098
+ }
13247
13099
  const uid = stepId != null ? stepId : "step";
13100
+ const onAction = async (action) => {
13101
+ try {
13102
+ await stepComponent.getSubmittableValue();
13103
+ const skipValidation = action.method === "GET" || Boolean(action.skipValidation);
13104
+ const canSubmit = skipValidation || stepComponent.validate();
13105
+ if (canSubmit) {
13106
+ void mapperProps.onAction(action);
13107
+ }
13108
+ } catch (e) {
13109
+ if (true) {
13110
+ console.log("\u274C:", "Failed to get submittable data");
13111
+ }
13112
+ }
13113
+ };
13114
+ const onRefresh = async (schemaId, url) => mapperProps.onRefresh(schemaId, url != null ? url : refreshUrl);
13115
+ const layoutComponents = layout.map(
13116
+ (layoutComponent, index) => mapLayoutToComponent(`${uid}.layout-${index}`, layoutComponent, __spreadProps(__spreadValues({}, mapperProps), {
13117
+ onAction,
13118
+ onRefresh
13119
+ }))
13120
+ );
13121
+ const additionalComponents = makeAdditionalComponents(mapperProps.step, uid, displayStepTitle);
13122
+ const stepComponent = createStepComponent({
13123
+ uid,
13124
+ loadingState,
13125
+ components: [...additionalComponents, ...layoutComponents],
13126
+ updateComponent
13127
+ });
13128
+ return stepComponent;
13129
+ };
13130
+ var makeAdditionalComponents = (step, uid, displayStepTitle) => {
13131
+ const { title, errors } = step;
13248
13132
  const heading = title && displayStepTitle ? headingLayoutToComponent(`${uid}.title`, {
13249
13133
  type: "heading",
13250
13134
  text: title,
@@ -13256,144 +13140,158 @@ var mapStepToComponent = (_a) => {
13256
13140
  markdown: errors.error,
13257
13141
  context: "negative"
13258
13142
  }) : void 0;
13259
- const additionalComponents = [...heading ? [heading] : [], ...stepError ? [stepError] : []];
13260
- const layoutComponents = layout.map(
13261
- (layoutComponent, index) => mapLayoutToComponent(`${uid}.layout-${index}`, layoutComponent, mapperProps)
13262
- );
13263
- if (stepId === void 0) {
13264
- throw new Error("Step must have an id or a key");
13143
+ return [...heading ? [heading] : [], ...stepError ? [stepError] : []];
13144
+ };
13145
+
13146
+ // src/revamp/flow/executeRefresh.ts
13147
+ var executeRefresh = async (props) => {
13148
+ const { abortSignal, url, model, schemaId, etag, httpClient, trackEvent } = props;
13149
+ trackEvent("Refresh Triggered", { schema: schemaId });
13150
+ try {
13151
+ const response = await httpClient(url != null ? url : "", {
13152
+ method: "POST",
13153
+ body: JSON.stringify(model),
13154
+ headers: __spreadValues({
13155
+ "Content-Type": "application/json"
13156
+ }, etag ? { "If-None-Match": etag } : {}),
13157
+ signal: abortSignal
13158
+ });
13159
+ if (response.status === 304) {
13160
+ trackEvent("Refresh Succeeded", { schema: schemaId });
13161
+ return { type: "noop" };
13162
+ }
13163
+ if (!response.ok) {
13164
+ const responseBody = await parseResponseBodyAsJsonElement(response).catch(() => ({}));
13165
+ const body2 = isErrorResponseBody(responseBody) ? responseBody : {};
13166
+ trackEvent("Refresh Failed", __spreadValues({ schema: schemaId }, body2.analytics));
13167
+ return { type: "error", body: body2 };
13168
+ }
13169
+ const newEtag = response.headers.get("etag") || null;
13170
+ const body = await parseResponseBodyAsJsonElement(response);
13171
+ assertStepResponseBody(body);
13172
+ trackEvent("Refresh Succeeded", { schema: schemaId });
13173
+ return { type: "refresh-step", step: body, etag: newEtag };
13174
+ } catch (error) {
13175
+ if (error instanceof DOMException && error.name === "AbortError") {
13176
+ trackEvent("Refresh Aborted", { schema: schemaId });
13177
+ return { type: "noop" };
13178
+ }
13179
+ trackEvent("Refresh Failed", { schema: schemaId });
13180
+ return { type: "error", body: {} };
13265
13181
  }
13266
- return createStepComponent({
13267
- uid,
13268
- loadingState,
13269
- components: [...additionalComponents, ...layoutComponents]
13270
- });
13271
13182
  };
13272
13183
 
13273
- // src/revamp/utils/findComponent.ts
13274
- var findComponent = (components, id) => {
13275
- const flattened = flattenComponents(components);
13276
- const matching = flattened.filter((component) => component.uid === id);
13277
- if (matching.length === 1) {
13278
- return matching[0];
13184
+ // src/revamp/flow/getResponseType.ts
13185
+ var responseTypes = ["step", "action", "exit"];
13186
+ var getResponseType = async (response) => {
13187
+ var _a, _b;
13188
+ assertResponseIsValid2(response);
13189
+ if ((_a = response.headers) == null ? void 0 : _a.has("X-Df-Response-Type")) {
13190
+ const type = response.headers.get("X-Df-Response-Type");
13191
+ assertDFResponseType(type);
13192
+ return type;
13279
13193
  }
13280
- if (matching.length > 1) {
13281
- throw new Error(`Multiple components with the same uid: ${id}`);
13194
+ if ((_b = response.headers) == null ? void 0 : _b.has("X-Df-Exit")) {
13195
+ return "exit";
13282
13196
  }
13283
- throw new Error(`Failed to find any components with uid: ${id}`);
13197
+ const jsonBody = await parseResponseBodyAsJsonElement(response.clone());
13198
+ if (isObject2(jsonBody) && jsonBody.action) {
13199
+ return "action";
13200
+ }
13201
+ return "step";
13284
13202
  };
13285
- var flattenComponents = (components) => components.reduce((acc, component) => {
13286
- if (hasChildren(component)) {
13287
- return [...acc, component, ...flattenComponents(component.getChildren())];
13203
+ function assertDFResponseType(type) {
13204
+ if (!responseTypes.includes(type)) {
13205
+ throw new Error(
13206
+ "Unsupported X-Df-Response-Type. Allowed values are 'step', 'action', 'exit', 'error'."
13207
+ );
13288
13208
  }
13289
- return [...acc, component];
13290
- }, []);
13209
+ }
13291
13210
 
13292
- // src/revamp/step/Step.tsx
13293
- var import_jsx_runtime119 = require("react/jsx-runtime");
13294
- var emptyStepComponent = createEmptyStepComponent();
13295
- function Step({
13296
- localValue: initialLocalValue,
13297
- step,
13298
- displayStepTitle = true,
13299
- loadingState,
13300
- getErrorMessageFunctions,
13301
- render,
13302
- httpClient,
13303
- trackEvent,
13304
- logEvent,
13305
- triggerSubmission,
13306
- triggerRefresh
13307
- }) {
13308
- var _a;
13309
- const [stepComponent, setStepComponent] = (0, import_react57.useState)(emptyStepComponent);
13310
- const stepComponentRef = (0, import_react57.useRef)(emptyStepComponent);
13311
- const updateComponent = (0, import_react57.useCallback)(
13312
- (id, update) => {
13313
- update(findComponent([stepComponentRef.current], id));
13314
- setStepComponent(() => {
13315
- const newStepDomainComponent = __spreadValues({}, stepComponentRef.current);
13316
- stepComponentRef.current = newStepDomainComponent;
13317
- return newStepDomainComponent;
13211
+ // src/revamp/flow/executeSubmission.ts
13212
+ var executeSubmission = async (props) => {
13213
+ const { httpClient, trackEvent } = props;
13214
+ const triggerAction = async (action, model, isInitial) => {
13215
+ const { exit, url, method = "POST", result = null, id: actionId } = action;
13216
+ const trackSubmissionEvent = !isInitial ? trackEvent : () => {
13217
+ };
13218
+ trackSubmissionEvent("Action Triggered", { actionId });
13219
+ if (exit && !url) {
13220
+ trackSubmissionEvent("Action Succeeded", { actionId });
13221
+ return { type: "complete", result };
13222
+ }
13223
+ try {
13224
+ const response = await httpClient(url != null ? url : "", {
13225
+ method,
13226
+ body: method === "GET" ? void 0 : JSON.stringify(model),
13227
+ headers: { "Content-Type": "application/json" }
13318
13228
  });
13319
- },
13320
- []
13321
- );
13322
- (0, import_react57.useEffect)(() => {
13323
- setStepComponent(() => {
13324
- const newStepDomainComponent = __spreadProps(__spreadValues({}, stepComponentRef.current), { loadingState });
13325
- stepComponentRef.current = newStepDomainComponent;
13326
- return newStepDomainComponent;
13327
- });
13328
- }, [loadingState]);
13329
- const onAction = (0, import_react57.useCallback)(
13330
- async (action) => {
13331
- var _a2;
13332
- const skipValidation = action.method === "GET" || Boolean(action.skipValidation);
13333
- const canSubmit = skipValidation || stepComponentRef.current.validate();
13334
- if (canSubmit) {
13335
- try {
13336
- const model = await stepComponentRef.current.getSubmittableValue();
13337
- const payload = mergeModels(model, (_a2 = action.data) != null ? _a2 : null);
13338
- const localValue = stepComponentRef.current.getLocalValue();
13339
- void triggerSubmission(action, payload, localValue);
13340
- } catch (e) {
13341
- if (true) {
13342
- console.log("\u274C:", "Failed to get submittable data");
13343
- }
13344
- }
13229
+ if (!response.ok) {
13230
+ return await handleErrorResponse(response, actionId);
13345
13231
  }
13346
- },
13347
- [triggerSubmission]
13348
- );
13349
- const onRefresh = (0, import_react57.useCallback)(
13350
- async (schemaId, url) => {
13351
- var _a2;
13352
- const refreshUrl = (_a2 = url != null ? url : step.refreshUrl) != null ? _a2 : step.refreshFormUrl;
13353
- if (refreshUrl) {
13354
- const model = await stepComponentRef.current.getSubmittableValue();
13355
- const localValue = stepComponentRef.current.getLocalValue();
13356
- void triggerRefresh({ refreshUrl, model, localValue, schemaId });
13232
+ const responseType = await getResponseType(response);
13233
+ const body = await parseResponseBodyAsJsonElement(response);
13234
+ if (exit) {
13235
+ return { type: "complete", result: mergeModels(result, body) };
13357
13236
  }
13358
- },
13359
- [step.refreshUrl, step.refreshFormUrl, triggerRefresh]
13360
- );
13361
- (0, import_react57.useEffect)(() => {
13362
- const initialComponent = mapStepToComponent({
13363
- stepLocalValue: initialLocalValue,
13364
- step,
13365
- displayStepTitle,
13366
- loadingState,
13367
- updateComponent,
13368
- getErrorMessageFunctions,
13369
- trackEvent,
13370
- logEvent,
13371
- httpClient,
13372
- onAction,
13373
- onRefresh
13374
- });
13375
- setStepComponent(initialComponent);
13376
- stepComponentRef.current = initialComponent;
13377
- if (step.key) {
13378
- logEvent("warning", 'Step.key is deprecated, please use "id" instead');
13237
+ switch (responseType) {
13238
+ case "step": {
13239
+ const etag = response.headers.get("etag") || null;
13240
+ assertStepResponseBody(body);
13241
+ trackSubmissionEvent("Action Succeeded", { actionId });
13242
+ return { type: "replace-step", step: body, etag };
13243
+ }
13244
+ case "exit": {
13245
+ trackSubmissionEvent("Action Succeeded", { actionId });
13246
+ return { type: "complete", result: mergeModels(result, body) };
13247
+ }
13248
+ case "action": {
13249
+ assertActionResponseBody(body);
13250
+ trackSubmissionEvent("Action Succeeded", { actionId });
13251
+ return await triggerAction(body.action, null, false);
13252
+ }
13253
+ default: {
13254
+ throw new Error(`Unsupported response type: ${String(responseType)}`);
13255
+ }
13256
+ }
13257
+ } catch (error) {
13258
+ trackSubmissionEvent("Action Failed", { actionId });
13259
+ throw error;
13379
13260
  }
13380
- }, [
13381
- step,
13382
- displayStepTitle,
13383
- updateComponent,
13384
- onAction,
13385
- getErrorMessageFunctions,
13386
- httpClient,
13387
- trackEvent,
13388
- logEvent,
13389
- onRefresh
13390
- ]);
13391
- (0, import_react57.useEffect)(() => {
13392
- trackEvent("Step Shown");
13393
- }, [(_a = step.id) != null ? _a : step.key]);
13394
- return /* @__PURE__ */ (0, import_jsx_runtime119.jsx)(import_jsx_runtime119.Fragment, { children: render(stepComponent) });
13261
+ };
13262
+ const handleErrorResponse = async (response, actionId) => {
13263
+ const body = await parseResponseBodyAsJsonElement(response);
13264
+ if (isErrorResponseBody(body)) {
13265
+ const refreshUrl = body.refreshUrl || body.refreshFormUrl;
13266
+ const { error, validation, analytics } = body;
13267
+ trackEvent("Action Failed", __spreadValues({ actionId }, analytics));
13268
+ const errors = { error, validation };
13269
+ return refreshUrl ? { type: "refresh", body: { refreshUrl, errors } } : { type: "error", body: { errors, analytics } };
13270
+ }
13271
+ trackEvent("Action Failed", { actionId });
13272
+ return { type: "error", body: {} };
13273
+ };
13274
+ return triggerAction(props.action, props.model, props.isInitial);
13275
+ };
13276
+
13277
+ // src/revamp/renderers/CoreContainerRenderer.tsx
13278
+ var import_jsx_runtime117 = require("react/jsx-runtime");
13279
+ var CoreContainerRenderer = {
13280
+ canRenderType: "container",
13281
+ render: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_jsx_runtime117.Fragment, { children })
13282
+ };
13283
+
13284
+ // src/revamp/renderers/StepRenderer.tsx
13285
+ var import_react56 = require("react");
13286
+ var import_jsx_runtime118 = require("react/jsx-runtime");
13287
+ var StepRenderer = {
13288
+ canRenderType: "step",
13289
+ render: StepRendererComponent
13290
+ };
13291
+ function StepRendererComponent({ children, loadingState }) {
13292
+ const value = (0, import_react56.useMemo)(() => ({ loadingState }), [loadingState]);
13293
+ return /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(LoadingContextProvider, { value, children });
13395
13294
  }
13396
- var Step_default = Step;
13397
13295
 
13398
13296
  // src/revamp/renderers/stepComponentToProps.ts
13399
13297
  var stepComponentToProps = ({ loadingState }, children) => ({
@@ -13887,8 +13785,8 @@ var componentToRendererProps = (component, nestedContent) => {
13887
13785
  }
13888
13786
  };
13889
13787
 
13890
- // src/revamp/step/utils/getRenderFunction.tsx
13891
- var import_jsx_runtime120 = require("react/jsx-runtime");
13788
+ // src/revamp/renderers/getRenderFunction.tsx
13789
+ var import_jsx_runtime119 = require("react/jsx-runtime");
13892
13790
  var getRenderFunction = (renderers2) => {
13893
13791
  function ComponentRenderer(props) {
13894
13792
  const { type } = props;
@@ -13927,7 +13825,7 @@ var getRenderFunction = (renderers2) => {
13927
13825
  children: component.getChildren().map(render)
13928
13826
  };
13929
13827
  };
13930
- const render = (component) => /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(
13828
+ const render = (component) => /* @__PURE__ */ (0, import_jsx_runtime119.jsx)(
13931
13829
  ComponentRenderer,
13932
13830
  __spreadValues({}, componentToRendererProps(component, getNestedContent(component))),
13933
13831
  component.uid
@@ -13935,7 +13833,7 @@ var getRenderFunction = (renderers2) => {
13935
13833
  return render;
13936
13834
  };
13937
13835
 
13938
- // src/revamp/step/utils/getSchemaErrorMessageFunction.ts
13836
+ // src/revamp/renderers/getSchemaErrorMessageFunction.ts
13939
13837
  var import_formatting2 = require("@transferwise/formatting");
13940
13838
  function getSchemaErrorMessageFunction(formatMessage, locale) {
13941
13839
  return (validationMessages) => createErrorMessageFunctions(validationMessages != null ? validationMessages : {}, formatMessage, locale);
@@ -14021,196 +13919,250 @@ var formatDateOptions = {
14021
13919
  dateStyle: "long"
14022
13920
  };
14023
13921
 
13922
+ // src/revamp/utils/findComponent.ts
13923
+ var findComponent = (components, id) => {
13924
+ const flattened = flattenComponents(components);
13925
+ const matching = flattened.filter((component) => component.uid === id);
13926
+ if (matching.length === 1) {
13927
+ return matching[0];
13928
+ }
13929
+ if (matching.length > 1) {
13930
+ throw new Error(`Multiple components with the same uid: ${id}`);
13931
+ }
13932
+ throw new Error(`Failed to find any components with uid: ${id}`);
13933
+ };
13934
+ var flattenComponents = (components) => components.reduce((acc, component) => {
13935
+ if (hasChildren(component)) {
13936
+ return [...acc, component, ...flattenComponents(component.getChildren())];
13937
+ }
13938
+ return [...acc, component];
13939
+ }, []);
13940
+
13941
+ // src/revamp/utils/useStableCallback.tsx
13942
+ var import_react57 = require("react");
13943
+ function useStableCallback(handler) {
13944
+ const ref = (0, import_react57.useRef)(handler);
13945
+ (0, import_react57.useLayoutEffect)(() => {
13946
+ ref.current = handler;
13947
+ });
13948
+ return (0, import_react57.useCallback)((...args) => ref.current ? ref.current(...args) : null, []);
13949
+ }
13950
+
14024
13951
  // src/revamp/DynamicFlowCore.tsx
14025
- var import_jsx_runtime121 = require("react/jsx-runtime");
13952
+ var import_jsx_runtime120 = require("react/jsx-runtime");
14026
13953
  function DynamicFlowCore(props) {
14027
- var _a;
14028
- const {
14029
- flowId,
14030
- displayStepTitle,
14031
- httpClient,
14032
- initialAction,
14033
- initialStep,
14034
- renderers: renderers2,
14035
- onCompletion,
14036
- onError,
14037
- onEvent,
14038
- onLog
14039
- } = props;
13954
+ const _a = props, { flowId, initialAction, initialStep, renderers: renderers2, displayStepTitle = true } = _a, rest = __objRest(_a, ["flowId", "initialAction", "initialStep", "renderers", "displayStepTitle"]);
13955
+ const httpClient = useStableCallback(rest.httpClient);
13956
+ const onCompletion = useStableCallback(rest.onCompletion);
13957
+ const onError = useStableCallback(rest.onError);
13958
+ const onEvent = useStableCallback(rest.onEvent);
13959
+ const onLog = useStableCallback(rest.onLog);
14040
13960
  const { formatMessage, locale } = (0, import_react_intl35.useIntl)();
14041
13961
  const getErrorMessageFunctions = (0, import_react58.useMemo)(
14042
13962
  () => getSchemaErrorMessageFunction(formatMessage, locale),
14043
13963
  [formatMessage, locale]
14044
13964
  );
14045
- (0, import_react58.useEffect)(() => {
14046
- var _a2;
14047
- if (!initialStep && initialAction) {
14048
- void triggerSubmission(initialAction, (_a2 = initialAction.data) != null ? _a2 : {}, null);
14049
- }
14050
- }, []);
14051
- const [step, setStep] = (0, import_react58.useState)(initialStep != null ? initialStep : null);
14052
- const localValueRef = (0, import_react58.useRef)(null);
14053
- const [etag, setEtag] = (0, import_react58.useState)(null);
13965
+ const [stepComponent, setStepComponent] = (0, import_react58.useState)(null);
13966
+ const stepComponentRef = (0, import_react58.useRef)(null);
13967
+ const stepRef = (0, import_react58.useRef)(initialStep != null ? initialStep : null);
13968
+ const etagRef = (0, import_react58.useRef)(null);
14054
13969
  const abortControllerRef = (0, import_react58.useRef)(new AbortController());
14055
- const [loadingState, setLoadingState] = (0, import_react58.useState)(initialStep ? "idle" : "loading");
14056
13970
  const abortCurrentAndGetNewAbortSignal = () => {
14057
13971
  abortControllerRef.current.abort();
14058
13972
  abortControllerRef.current = new AbortController();
14059
13973
  return abortControllerRef.current.signal;
14060
13974
  };
14061
- const stepId = (_a = step == null ? void 0 : step.id) != null ? _a : step == null ? void 0 : step.key;
14062
- const stepAnalytics = step == null ? void 0 : step.analytics;
14063
- const trackEvent = (0, import_react58.useMemo)(
14064
- () => getAnalyticsEventDispatcher({ flowId, stepId, analytics: stepAnalytics, onEvent }),
13975
+ (0, import_react58.useEffect)(() => {
13976
+ trackEvent("Flow Started");
13977
+ if (!initialStep && initialAction) {
13978
+ void onAction(initialAction);
13979
+ }
13980
+ if (initialStep && !initialAction) {
13981
+ initialiseWithStep(initialStep, null);
13982
+ trackEvent("Step Shown");
13983
+ }
13984
+ }, []);
13985
+ const initialiseWithStep = (0, import_react58.useCallback)(
13986
+ (newStep, etag) => {
13987
+ var _a2, _b;
13988
+ stepRef.current = newStep;
13989
+ etagRef.current = etag;
13990
+ const updateComponent = (id, update) => {
13991
+ const currentStepComponent = stepComponentRef.current;
13992
+ if (currentStepComponent) {
13993
+ update(findComponent([currentStepComponent], id));
13994
+ setStepComponent(() => {
13995
+ const newStepDomainComponent = __spreadValues({}, currentStepComponent);
13996
+ stepComponentRef.current = newStepDomainComponent;
13997
+ return newStepDomainComponent;
13998
+ });
13999
+ }
14000
+ };
14001
+ try {
14002
+ const newStepComponent = mapStepToComponent({
14003
+ stepLocalValue: (_b = (_a2 = stepComponentRef.current) == null ? void 0 : _a2.getLocalValue()) != null ? _b : null,
14004
+ step: newStep,
14005
+ displayStepTitle,
14006
+ loadingState: "idle",
14007
+ updateComponent,
14008
+ getErrorMessageFunctions,
14009
+ trackEvent,
14010
+ logEvent,
14011
+ httpClient,
14012
+ onAction,
14013
+ onRefresh
14014
+ });
14015
+ setStepComponent(() => {
14016
+ stepComponentRef.current = newStepComponent;
14017
+ return newStepComponent;
14018
+ });
14019
+ } catch (error) {
14020
+ closeWithError(error);
14021
+ }
14022
+ },
14065
14023
  // eslint-disable-next-line react-hooks/exhaustive-deps
14066
- [flowId, stepId, JSON.stringify(stepAnalytics), onEvent]
14024
+ []
14025
+ );
14026
+ const trackEvent = (0, import_react58.useCallback)(
14027
+ (eventName, properties) => {
14028
+ var _a2, _b, _c, _d;
14029
+ const stepId = (_c = (_a2 = stepRef.current) == null ? void 0 : _a2.id) != null ? _c : (_b = stepRef.current) == null ? void 0 : _b.key;
14030
+ const analytics = (_d = stepRef.current) == null ? void 0 : _d.analytics;
14031
+ const metadata = __spreadValues(__spreadValues(__spreadValues({
14032
+ flowId
14033
+ }, stepId ? { stepId } : {}), analytics), properties);
14034
+ try {
14035
+ onEvent == null ? void 0 : onEvent(`Dynamic Flow - ${eventName}`, __spreadValues({}, metadata));
14036
+ } catch (e) {
14037
+ }
14038
+ },
14039
+ // eslint-disable-next-line react-hooks/exhaustive-deps
14040
+ []
14041
+ );
14042
+ const logEvent = (0, import_react58.useCallback)(
14043
+ (level, message, properties) => {
14044
+ try {
14045
+ onLog == null ? void 0 : onLog(level, message, properties != null ? properties : {});
14046
+ } catch (e) {
14047
+ }
14048
+ },
14049
+ // eslint-disable-next-line react-hooks/exhaustive-deps
14050
+ []
14067
14051
  );
14068
- const logEvent = (0, import_react58.useMemo)(() => getLoggingEventDispatcher(onLog), [onLog]);
14069
- (0, import_react58.useEffect)(() => trackEvent("Flow Started"), []);
14070
14052
  const closeWithError = (0, import_react58.useCallback)(
14071
14053
  (error, analytics) => {
14072
14054
  trackEvent("Flow Failed", __spreadValues({}, analytics));
14073
14055
  onError(error);
14074
14056
  },
14075
- [onError, trackEvent]
14057
+ // eslint-disable-next-line react-hooks/exhaustive-deps
14058
+ []
14076
14059
  );
14077
- const triggerSubmission = (0, import_react58.useCallback)(
14078
- async (action, model, localValue) => {
14079
- if (true) {
14080
- console.log("\u23EF\uFE0F triggerSubmission", JSON.stringify({ action, model }, null, 2));
14081
- }
14082
- try {
14083
- setLoadingState("loading");
14084
- const command = await executeSubmission({
14085
- action,
14086
- model,
14087
- isInitial: step === null,
14088
- httpClient,
14089
- trackEvent
14090
- });
14091
- switch (command.type) {
14092
- case "complete": {
14093
- localValueRef.current = null;
14094
- onCompletion(command.result);
14095
- trackEvent("Flow Succeeded");
14096
- break;
14097
- }
14098
- case "replace-step": {
14099
- localValueRef.current = null;
14100
- setLoadingState("idle");
14101
- setStep(command.step);
14102
- setEtag(command.etag);
14103
- break;
14104
- }
14105
- case "error": {
14106
- setLoadingState("idle");
14107
- const genericErrorMessage = getErrorMessageFunctions().genericErrorWithRetry();
14108
- const { errors = { error: genericErrorMessage } } = command.body;
14109
- if (step) {
14110
- setStep(__spreadProps(__spreadValues({}, step), { errors }));
14111
- } else {
14112
- closeWithError(new Error("Initial request failed"), {});
14113
- }
14114
- break;
14060
+ const onAction = (0, import_react58.useCallback)(async (action) => {
14061
+ var _a2, _b, _c, _d, _e;
14062
+ try {
14063
+ (_a2 = stepComponentRef.current) == null ? void 0 : _a2.setLoadingState("loading");
14064
+ const model = (_c = await ((_b = stepComponentRef.current) == null ? void 0 : _b.getSubmittableValue())) != null ? _c : null;
14065
+ const payload = mergeModels(model, (_d = action.data) != null ? _d : null);
14066
+ const command = await executeSubmission({
14067
+ action,
14068
+ model: payload,
14069
+ isInitial: stepRef.current === null,
14070
+ httpClient,
14071
+ trackEvent
14072
+ });
14073
+ switch (command.type) {
14074
+ case "complete": {
14075
+ onCompletion(command.result);
14076
+ trackEvent("Flow Succeeded");
14077
+ break;
14078
+ }
14079
+ case "replace-step": {
14080
+ initialiseWithStep(command.step, command.etag);
14081
+ trackEvent("Step Shown");
14082
+ break;
14083
+ }
14084
+ case "error": {
14085
+ const genericErrorMessage = getErrorMessageFunctions().genericErrorWithRetry();
14086
+ const { errors = { error: genericErrorMessage } } = command.body;
14087
+ if (stepRef.current) {
14088
+ initialiseWithStep(__spreadProps(__spreadValues({}, stepRef.current), { errors }), etagRef.current);
14089
+ } else {
14090
+ closeWithError(new Error("Initial request failed"), {});
14115
14091
  }
14116
- case "refresh": {
14117
- const { refreshUrl, errors = {} } = command.body;
14118
- try {
14119
- localValueRef.current = localValue;
14120
- const refreshCommand = await executeRefresh({
14121
- abortSignal: abortCurrentAndGetNewAbortSignal(),
14122
- url: refreshUrl,
14123
- model,
14124
- etag,
14125
- httpClient,
14126
- trackEvent
14127
- });
14128
- switch (refreshCommand.type) {
14129
- case "refresh-step":
14130
- setLoadingState("idle");
14131
- setStep(__spreadProps(__spreadValues({}, refreshCommand.step), { errors }));
14132
- setEtag(refreshCommand.etag);
14133
- break;
14134
- default:
14135
- throw new Error("Failed to refresh");
14136
- }
14137
- } catch (e) {
14138
- closeWithError(e, {});
14092
+ break;
14093
+ }
14094
+ case "refresh": {
14095
+ const { refreshUrl, errors = {} } = command.body;
14096
+ try {
14097
+ (_e = stepComponentRef.current) == null ? void 0 : _e.setLoadingState("loading");
14098
+ const refreshCommand = await executeRefresh({
14099
+ abortSignal: abortCurrentAndGetNewAbortSignal(),
14100
+ url: refreshUrl,
14101
+ model,
14102
+ etag: etagRef.current,
14103
+ httpClient,
14104
+ trackEvent
14105
+ });
14106
+ switch (refreshCommand.type) {
14107
+ case "refresh-step":
14108
+ initialiseWithStep(__spreadProps(__spreadValues({}, refreshCommand.step), { errors }), refreshCommand.etag);
14109
+ break;
14110
+ default:
14111
+ throw new Error("Failed to refresh");
14139
14112
  }
14140
- break;
14113
+ } catch (e) {
14114
+ closeWithError(e, {});
14141
14115
  }
14116
+ break;
14142
14117
  }
14143
- } catch (error) {
14144
- closeWithError(error);
14145
- }
14146
- },
14147
- [httpClient, trackEvent, onCompletion, getErrorMessageFunctions, step, etag, closeWithError]
14148
- );
14149
- const triggerRefresh = (0, import_react58.useCallback)(
14150
- async ({
14151
- refreshUrl,
14152
- model,
14153
- localValue,
14154
- schemaId
14155
- }) => {
14156
- if (true) {
14157
- console.log("\u23EF\uFE0F triggerRefresh", JSON.stringify({ refreshUrl, model, schemaId }, null, 2));
14158
14118
  }
14119
+ } catch (error) {
14120
+ closeWithError(error);
14121
+ }
14122
+ }, []);
14123
+ const onRefresh = (0, import_react58.useCallback)(
14124
+ async (schemaId, refreshUrl = "") => {
14125
+ var _a2, _b, _c, _d;
14159
14126
  try {
14160
- localValueRef.current = localValue;
14161
- setLoadingState("loading");
14127
+ (_a2 = stepComponentRef.current) == null ? void 0 : _a2.setLoadingState("loading");
14128
+ const model = (_c = await ((_b = stepComponentRef.current) == null ? void 0 : _b.getSubmittableValue())) != null ? _c : null;
14162
14129
  const command = await executeRefresh({
14163
14130
  abortSignal: abortCurrentAndGetNewAbortSignal(),
14164
14131
  url: refreshUrl,
14165
14132
  model,
14166
14133
  schemaId,
14167
- etag,
14134
+ etag: etagRef.current,
14168
14135
  httpClient,
14169
14136
  trackEvent
14170
14137
  });
14171
- setLoadingState("idle");
14172
14138
  switch (command.type) {
14173
14139
  case "refresh-step":
14174
- setStep(command.step);
14175
- setEtag(command.etag);
14140
+ initialiseWithStep(command.step, command.etag);
14176
14141
  break;
14177
14142
  case "error": {
14178
14143
  closeWithError(new Error("Failed to refresh"), command.body.analytics);
14179
14144
  break;
14180
14145
  }
14181
14146
  case "noop":
14147
+ (_d = stepComponentRef.current) == null ? void 0 : _d.setLoadingState("idle");
14182
14148
  break;
14183
14149
  }
14184
14150
  } catch (error) {
14185
14151
  closeWithError(error, void 0);
14186
14152
  }
14187
14153
  },
14188
- [etag, httpClient, trackEvent, closeWithError]
14154
+ // eslint-disable-next-line react-hooks/exhaustive-deps
14155
+ []
14189
14156
  );
14190
14157
  const render = (0, import_react58.useMemo)(
14191
14158
  () => getRenderFunction([CoreContainerRenderer, ...renderers2, StepRenderer]),
14192
14159
  [renderers2]
14193
14160
  );
14194
- return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(ErrorBoundary_default, { onError: closeWithError, children: step ? /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
14195
- Step_default,
14196
- {
14197
- displayStepTitle,
14198
- step,
14199
- localValue: localValueRef.current,
14200
- loadingState,
14201
- getErrorMessageFunctions,
14202
- render,
14203
- httpClient,
14204
- trackEvent,
14205
- logEvent,
14206
- triggerSubmission,
14207
- triggerRefresh
14208
- }
14209
- ) : null });
14161
+ return /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(ErrorBoundary_default, { onError: closeWithError, children: stepComponent ? render(stepComponent) : null });
14210
14162
  }
14211
14163
 
14212
14164
  // src/revamp/DynamicFlowWise.tsx
14213
- var import_jsx_runtime122 = require("react/jsx-runtime");
14165
+ var import_jsx_runtime121 = require("react/jsx-runtime");
14214
14166
  var renderers = getWiseRenderers();
14215
14167
  function DynamicFlowWise(props) {
14216
14168
  const { httpClient } = props;
@@ -14219,7 +14171,7 @@ function DynamicFlowWise(props) {
14219
14171
  () => makeWiseHttpClient(httpClient, locale),
14220
14172
  [httpClient, locale]
14221
14173
  );
14222
- return /* @__PURE__ */ (0, import_jsx_runtime122.jsx)(HttpClientProvider, { httpClient: wiseHttpClient, children: /* @__PURE__ */ (0, import_jsx_runtime122.jsx)(DynamicFlowCore, __spreadProps(__spreadValues({}, props), { renderers })) });
14174
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(HttpClientProvider, { httpClient: wiseHttpClient, children: /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(DynamicFlowCore, __spreadProps(__spreadValues({}, props), { renderers })) });
14223
14175
  }
14224
14176
  var DynamicFlowWise_default = DynamicFlowWise;
14225
14177
  var makeWiseHttpClient = (httpClient, locale) => async (input, init) => httpClient(