@wise/dynamic-flow-client 4.5.4 → 4.5.5

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
@@ -1875,7 +1875,6 @@ var getComponentAlertProps = (component, rendererMapperProps) => "alert" in comp
1875
1875
  }, rendererMapperProps) : null;
1876
1876
 
1877
1877
  // src/revamp/useDynamicFlowCore.tsx
1878
- var import_dynamic_flow_types2 = require("@wise/dynamic-flow-types");
1879
1878
  var import_react3 = require("react");
1880
1879
  var import_react_intl7 = require("react-intl");
1881
1880
 
@@ -1987,40 +1986,6 @@ var createRootDomainComponent = (updateComponent) => {
1987
1986
  return rootComponent;
1988
1987
  };
1989
1988
 
1990
- // src/revamp/domain/components/step/ExternalConfirmationComponent.ts
1991
- var createExternalConfirmation = (uid, url, updateComponent) => {
1992
- const update = getInputUpdateFunction(updateComponent);
1993
- return {
1994
- type: "external-confirmation",
1995
- uid,
1996
- url,
1997
- status: "initial",
1998
- onSuccess() {
1999
- update(this, (draft) => {
2000
- draft.status = "success";
2001
- });
2002
- },
2003
- onFailure() {
2004
- if (this.status === "initial") {
2005
- update(this, (draft) => {
2006
- draft.status = "failure";
2007
- });
2008
- }
2009
- },
2010
- onCancel() {
2011
- update(this, (draft) => {
2012
- draft.status = "dismissed";
2013
- });
2014
- },
2015
- getSubmittableValue: async () => null,
2016
- getSubmittableValueSync: () => null,
2017
- getLocalValue: () => null,
2018
- getSummary: () => ({}),
2019
- // Noop
2020
- validate: () => true
2021
- };
2022
- };
2023
-
2024
1989
  // src/revamp/domain/features/summary/summary-utils.ts
2025
1990
  var getSummariser = (schema) => (value) => {
2026
1991
  const { summary, icon, image } = schema;
@@ -2057,71 +2022,62 @@ var summaryIfProvides = (summary, { value, icon, image }) => {
2057
2022
  };
2058
2023
  };
2059
2024
 
2060
- // src/revamp/domain/components/step/StepDomainComponent.ts
2061
- var createStepComponent = (stepProps) => {
2062
- const _a = stepProps, { uid, stepPolling, stepRefreshAfter, updateComponent } = _a, rest = __objRest(_a, ["uid", "stepPolling", "stepRefreshAfter", "updateComponent"]);
2025
+ // src/revamp/domain/features/validation/validation-functions.ts
2026
+ var validateComponents = (components) => components.reduce((acc, component) => component.validate() && acc, true);
2027
+ var getLocalValueValidator = (checks) => (currentValue) => checks.map((check) => check(currentValue)).filter(isString);
2028
+
2029
+ // src/revamp/domain/components/ModalContentComponent.ts
2030
+ var createModalContentComponent = (modalProps, updateComponent) => {
2063
2031
  const update = getInputUpdateFunction(updateComponent);
2064
- const component = __spreadProps(__spreadValues({
2065
- uid
2066
- }, rest), {
2067
- type: "step",
2068
- modals: [],
2069
- dismissModal() {
2070
- var _a2;
2071
- (_a2 = this.modals.at(-1)) == null ? void 0 : _a2.close();
2072
- },
2073
- dismissAllModals() {
2074
- this._update((draft) => {
2075
- draft.modals = draft.modals.map((m) => __spreadProps(__spreadValues({}, m), { open: false }));
2076
- });
2077
- },
2078
- showModal(modal) {
2079
- this._update((draft) => {
2080
- draft.modals = [...draft.modals, modal];
2081
- });
2082
- },
2032
+ const modalContentComponent = __spreadProps(__spreadValues({
2033
+ type: "modal-content",
2034
+ open: true
2035
+ }, modalProps), {
2083
2036
  _update(updateFn) {
2084
2037
  update(this, updateFn);
2085
2038
  },
2086
2039
  getChildren() {
2087
- return this.externalConfirmation ? [...this.layoutComponents, this.externalConfirmation] : this.layoutComponents;
2040
+ return this.components;
2088
2041
  },
2089
- getModals() {
2090
- return this.modals;
2042
+ getLocalValue() {
2043
+ return getLocalValues(this.getChildren());
2091
2044
  },
2092
2045
  async getSubmittableValue() {
2093
- return getSubmittableData(this.inputComponents);
2046
+ return getSubmittableData(this.getChildren());
2094
2047
  },
2095
2048
  getSubmittableValueSync() {
2096
- return getSubmittableDataSync(this.inputComponents);
2049
+ return getSubmittableDataSync(this.getChildren());
2097
2050
  },
2098
2051
  getSummary() {
2099
2052
  return summariseFromChildren(this.getChildren());
2100
2053
  },
2101
- getLocalValue() {
2102
- return getLocalValues(this.inputComponents);
2103
- },
2104
2054
  validate() {
2105
- return this.inputComponents.every(
2106
- (inputComponent) => inputComponent.isSchemaReferencedInStep ? inputComponent.validate() : true
2107
- );
2108
- },
2109
- setLoadingState(loadingState) {
2110
- this._update((draft) => {
2111
- draft.loadingState = loadingState;
2112
- });
2055
+ return validateComponents(this.getChildren());
2113
2056
  },
2114
- stop() {
2115
- stepPolling == null ? void 0 : stepPolling.stop();
2116
- stepRefreshAfter == null ? void 0 : stepRefreshAfter.stop();
2117
- this._update((draft) => {
2118
- draft.modals = [];
2057
+ close() {
2058
+ update(this, (draft) => {
2059
+ draft.open = false;
2119
2060
  });
2120
2061
  }
2121
2062
  });
2122
- return component;
2063
+ return modalContentComponent;
2123
2064
  };
2124
2065
 
2066
+ // src/revamp/domain/components/utils/getRandomId.ts
2067
+ var getRandomId = () => Math.random().toString(36).substring(2);
2068
+
2069
+ // src/revamp/domain/components/AlertComponent.ts
2070
+ var createAlertComponent = (alertProps) => __spreadProps(__spreadValues({
2071
+ type: "alert"
2072
+ }, alertProps), {
2073
+ getSubmittableValue: async () => null,
2074
+ getSubmittableValueSync: () => null,
2075
+ getLocalValue: () => null,
2076
+ getSummary: () => ({}),
2077
+ // Noop
2078
+ validate: () => true
2079
+ });
2080
+
2125
2081
  // src/revamp/domain/mappers/utils/behavior-utils.ts
2126
2082
  var getDomainLayerBehavior = ({
2127
2083
  action,
@@ -2161,73 +2117,6 @@ var getActionByReference = ($ref, actions = []) => {
2161
2117
  return action;
2162
2118
  };
2163
2119
 
2164
- // src/revamp/domain/features/polling/getStepPolling.ts
2165
- var getStepPolling = ({
2166
- pollingConfig,
2167
- onBehavior,
2168
- onPoll
2169
- }) => {
2170
- const { interval, delay = interval, maxAttempts, url, onError } = pollingConfig;
2171
- let abortController = new AbortController();
2172
- if (delay == null) {
2173
- throw new Error("Polling configuration must include delay or interval");
2174
- }
2175
- const onErrorBehavior = skipValidation(getDomainLayerBehavior(onError, []));
2176
- let attempts = 0;
2177
- const poll = () => {
2178
- attempts += 1;
2179
- abortController.abort();
2180
- abortController = new AbortController();
2181
- const { signal } = abortController;
2182
- onPoll(url, onErrorBehavior, signal).then((result) => {
2183
- if (result) {
2184
- stop();
2185
- return;
2186
- }
2187
- if (attempts >= maxAttempts && !signal.aborted) {
2188
- void onBehavior(onErrorBehavior);
2189
- stop();
2190
- }
2191
- }).catch(() => {
2192
- });
2193
- };
2194
- const intervalRef = setInterval(poll, delay * 1e3);
2195
- const stop = () => {
2196
- clearTimeout(intervalRef);
2197
- abortController.abort();
2198
- };
2199
- poll();
2200
- return { stop };
2201
- };
2202
-
2203
- // src/revamp/domain/features/refreshAfter/getStepRefreshAfter.ts
2204
- var ONE_SECOND = 1e3;
2205
- var getStepRefreshAfter = ({ refreshAfter, onRefresh }) => {
2206
- const targetTime = new Date(refreshAfter).getTime();
2207
- if (typeof refreshAfter !== "string" || Number.isNaN(targetTime)) {
2208
- throw new Error(`Invalid refreshAfter value: ${String(refreshAfter)}`);
2209
- }
2210
- const timeLeft = Math.max(targetTime - Date.now(), ONE_SECOND);
2211
- const timeout = setTimeout(() => {
2212
- void onRefresh("refreshAfter");
2213
- }, timeLeft);
2214
- return {
2215
- stop: () => clearTimeout(timeout)
2216
- };
2217
- };
2218
-
2219
- // src/revamp/domain/components/AlertComponent.ts
2220
- var createAlertComponent = (alertProps) => __spreadProps(__spreadValues({
2221
- type: "alert"
2222
- }, alertProps), {
2223
- getSubmittableValue: async () => null,
2224
- getSubmittableValueSync: () => null,
2225
- getLocalValue: () => null,
2226
- getSummary: () => ({}),
2227
- // Noop
2228
- validate: () => true
2229
- });
2230
-
2231
2120
  // src/revamp/domain/mappers/utils/call-to-action-utils.ts
2232
2121
  var getDomainLayerCallToAction = (callToAction, onBehavior, stepActions) => {
2233
2122
  if (!callToAction) {
@@ -2334,10 +2223,6 @@ var alertLayoutToComponent = (uid, { control, markdown, margin = "md", context =
2334
2223
  });
2335
2224
  };
2336
2225
 
2337
- // src/revamp/domain/features/validation/validation-functions.ts
2338
- var validateComponents = (components) => components.reduce((acc, component) => component.validate() && acc, true);
2339
- var getLocalValueValidator = (checks) => (currentValue) => checks.map((check) => check(currentValue)).filter(isString);
2340
-
2341
2226
  // src/revamp/domain/components/BoxComponent.ts
2342
2227
  var createBoxComponent = (boxProps) => __spreadProps(__spreadValues({}, boxProps), {
2343
2228
  type: "box",
@@ -3215,8 +3100,171 @@ var mapLayoutToComponent = (uid, layout, mapperProps, inputComponents) => {
3215
3100
  }
3216
3101
  };
3217
3102
 
3218
- // src/revamp/domain/components/utils/getRandomId.ts
3219
- var getRandomId = () => Math.random().toString(36).substring(2);
3103
+ // src/revamp/domain/mappers/layout/modalToContent.ts
3104
+ var modalToContent = (uid, { content, title }, mapperProps, inputComponents) => createModalContentComponent(
3105
+ {
3106
+ uid: `${uid}-modal-${getRandomId()}`,
3107
+ title,
3108
+ components: content.map(
3109
+ (component, index) => mapLayoutToComponent(`${uid}.modal-${index}`, component, mapperProps, inputComponents)
3110
+ )
3111
+ },
3112
+ mapperProps.updateComponent
3113
+ );
3114
+
3115
+ // src/revamp/domain/components/step/ExternalConfirmationComponent.ts
3116
+ var createExternalConfirmation = (uid, url, updateComponent) => {
3117
+ const update = getInputUpdateFunction(updateComponent);
3118
+ return {
3119
+ type: "external-confirmation",
3120
+ uid,
3121
+ url,
3122
+ status: "initial",
3123
+ onSuccess() {
3124
+ update(this, (draft) => {
3125
+ draft.status = "success";
3126
+ });
3127
+ },
3128
+ onFailure() {
3129
+ if (this.status === "initial") {
3130
+ update(this, (draft) => {
3131
+ draft.status = "failure";
3132
+ });
3133
+ }
3134
+ },
3135
+ onCancel() {
3136
+ update(this, (draft) => {
3137
+ draft.status = "dismissed";
3138
+ });
3139
+ },
3140
+ getSubmittableValue: async () => null,
3141
+ getSubmittableValueSync: () => null,
3142
+ getLocalValue: () => null,
3143
+ getSummary: () => ({}),
3144
+ // Noop
3145
+ validate: () => true
3146
+ };
3147
+ };
3148
+
3149
+ // src/revamp/domain/components/step/StepDomainComponent.ts
3150
+ var createStepComponent = (stepProps) => {
3151
+ const _a = stepProps, { uid, stepPolling, stepRefreshAfter, updateComponent } = _a, rest = __objRest(_a, ["uid", "stepPolling", "stepRefreshAfter", "updateComponent"]);
3152
+ const update = getInputUpdateFunction(updateComponent);
3153
+ const component = __spreadProps(__spreadValues({
3154
+ uid
3155
+ }, rest), {
3156
+ type: "step",
3157
+ modals: [],
3158
+ dismissModal() {
3159
+ var _a2;
3160
+ (_a2 = this.modals.at(-1)) == null ? void 0 : _a2.close();
3161
+ },
3162
+ dismissAllModals() {
3163
+ this._update((draft) => {
3164
+ draft.modals = draft.modals.map((m) => __spreadProps(__spreadValues({}, m), { open: false }));
3165
+ });
3166
+ },
3167
+ showModal(modal) {
3168
+ this._update((draft) => {
3169
+ draft.modals = [...draft.modals, modal];
3170
+ });
3171
+ },
3172
+ _update(updateFn) {
3173
+ update(this, updateFn);
3174
+ },
3175
+ getChildren() {
3176
+ return this.externalConfirmation ? [...this.layoutComponents, this.externalConfirmation] : this.layoutComponents;
3177
+ },
3178
+ getModals() {
3179
+ return this.modals;
3180
+ },
3181
+ async getSubmittableValue() {
3182
+ return getSubmittableData(this.inputComponents);
3183
+ },
3184
+ getSubmittableValueSync() {
3185
+ return getSubmittableDataSync(this.inputComponents);
3186
+ },
3187
+ getSummary() {
3188
+ return summariseFromChildren(this.getChildren());
3189
+ },
3190
+ getLocalValue() {
3191
+ return getLocalValues(this.inputComponents);
3192
+ },
3193
+ validate() {
3194
+ return this.inputComponents.every(
3195
+ (inputComponent) => inputComponent.isSchemaReferencedInStep ? inputComponent.validate() : true
3196
+ );
3197
+ },
3198
+ setLoadingState(loadingState) {
3199
+ this._update((draft) => {
3200
+ draft.loadingState = loadingState;
3201
+ });
3202
+ },
3203
+ stop() {
3204
+ stepPolling == null ? void 0 : stepPolling.stop();
3205
+ stepRefreshAfter == null ? void 0 : stepRefreshAfter.stop();
3206
+ this._update((draft) => {
3207
+ draft.modals = [];
3208
+ });
3209
+ }
3210
+ });
3211
+ return component;
3212
+ };
3213
+
3214
+ // src/revamp/domain/features/polling/getStepPolling.ts
3215
+ var getStepPolling = ({
3216
+ pollingConfig,
3217
+ onBehavior,
3218
+ onPoll
3219
+ }) => {
3220
+ const { interval, delay = interval, maxAttempts, url, onError } = pollingConfig;
3221
+ let abortController = new AbortController();
3222
+ if (delay == null) {
3223
+ throw new Error("Polling configuration must include delay or interval");
3224
+ }
3225
+ const onErrorBehavior = skipValidation(getDomainLayerBehavior(onError, []));
3226
+ let attempts = 0;
3227
+ const poll = () => {
3228
+ attempts += 1;
3229
+ abortController.abort();
3230
+ abortController = new AbortController();
3231
+ const { signal } = abortController;
3232
+ onPoll(url, onErrorBehavior, signal).then((result) => {
3233
+ if (result) {
3234
+ stop();
3235
+ return;
3236
+ }
3237
+ if (attempts >= maxAttempts && !signal.aborted) {
3238
+ void onBehavior(onErrorBehavior);
3239
+ stop();
3240
+ }
3241
+ }).catch(() => {
3242
+ });
3243
+ };
3244
+ const intervalRef = setInterval(poll, delay * 1e3);
3245
+ const stop = () => {
3246
+ clearTimeout(intervalRef);
3247
+ abortController.abort();
3248
+ };
3249
+ poll();
3250
+ return { stop };
3251
+ };
3252
+
3253
+ // src/revamp/domain/features/refreshAfter/getStepRefreshAfter.ts
3254
+ var ONE_SECOND = 1e3;
3255
+ var getStepRefreshAfter = ({ refreshAfter, onRefresh }) => {
3256
+ const targetTime = new Date(refreshAfter).getTime();
3257
+ if (typeof refreshAfter !== "string" || Number.isNaN(targetTime)) {
3258
+ throw new Error(`Invalid refreshAfter value: ${String(refreshAfter)}`);
3259
+ }
3260
+ const timeLeft = Math.max(targetTime - Date.now(), ONE_SECOND);
3261
+ const timeout = setTimeout(() => {
3262
+ void onRefresh("refreshAfter");
3263
+ }, timeLeft);
3264
+ return {
3265
+ stop: () => clearTimeout(timeout)
3266
+ };
3267
+ };
3220
3268
 
3221
3269
  // src/revamp/domain/components/utils/isExactLocalValueMatch.ts
3222
3270
  var isExactLocalValueMatch = (valueA, valueB) => {
@@ -6484,6 +6532,34 @@ var formatDateOptions = {
6484
6532
  dateStyle: "long"
6485
6533
  };
6486
6534
 
6535
+ // src/revamp/utils/analyse-step.ts
6536
+ var import_dynamic_flow_types2 = require("@wise/dynamic-flow-types");
6537
+ var analyseStep = (step, logEvent) => {
6538
+ validateStepTypes(step, logEvent);
6539
+ warnWhenPollingWithSchemas(step, logEvent);
6540
+ };
6541
+ var warnWhenPollingWithSchemas = (step, logEvent) => {
6542
+ var _a;
6543
+ const hasPolling = step.polling != null;
6544
+ const hasSchemas = step.schemas != null && step.schemas.length > 0;
6545
+ if (hasPolling && hasSchemas) {
6546
+ logEvent("warning", "DynamicFlow Polling and Schema Warning.", {
6547
+ message: "The provided step is configured with polling and schemas. Actions triggered from a polling response will not contain the schema values in their payload.",
6548
+ stepId: (_a = step.id) != null ? _a : step.key
6549
+ });
6550
+ }
6551
+ };
6552
+ var validateStepTypes = (step, logEvent) => {
6553
+ var _a;
6554
+ const validationResult = (0, import_dynamic_flow_types2.validateStep)(step);
6555
+ if (!validationResult.valid) {
6556
+ logEvent("info", "The provided step does not conform to the specification.", {
6557
+ stepId: (_a = step.id) != null ? _a : step.key,
6558
+ errors: validationResult.errors
6559
+ });
6560
+ }
6561
+ };
6562
+
6487
6563
  // src/revamp/utils/useStableCallback.tsx
6488
6564
  var import_react2 = require("react");
6489
6565
  function useStableCallback(handler) {
@@ -6494,55 +6570,6 @@ function useStableCallback(handler) {
6494
6570
  return (0, import_react2.useCallback)((...args) => ref.current ? ref.current(...args) : null, []);
6495
6571
  }
6496
6572
 
6497
- // src/revamp/domain/components/ModalContentComponent.ts
6498
- var createModalContentComponent = (modalProps, updateComponent) => {
6499
- const update = getInputUpdateFunction(updateComponent);
6500
- const modalContentComponent = __spreadProps(__spreadValues({
6501
- type: "modal-content",
6502
- open: true
6503
- }, modalProps), {
6504
- _update(updateFn) {
6505
- update(this, updateFn);
6506
- },
6507
- getChildren() {
6508
- return this.components;
6509
- },
6510
- getLocalValue() {
6511
- return getLocalValues(this.getChildren());
6512
- },
6513
- async getSubmittableValue() {
6514
- return getSubmittableData(this.getChildren());
6515
- },
6516
- getSubmittableValueSync() {
6517
- return getSubmittableDataSync(this.getChildren());
6518
- },
6519
- getSummary() {
6520
- return summariseFromChildren(this.getChildren());
6521
- },
6522
- validate() {
6523
- return validateComponents(this.getChildren());
6524
- },
6525
- close() {
6526
- update(this, (draft) => {
6527
- draft.open = false;
6528
- });
6529
- }
6530
- });
6531
- return modalContentComponent;
6532
- };
6533
-
6534
- // src/revamp/domain/mappers/layout/modalToContent.ts
6535
- var modalToContent = (uid, { content, title }, mapperProps, inputComponents) => createModalContentComponent(
6536
- {
6537
- uid: `${uid}-modal-${getRandomId()}`,
6538
- title,
6539
- components: content.map(
6540
- (component, index) => mapLayoutToComponent(`${uid}.modal-${index}`, component, mapperProps, inputComponents)
6541
- )
6542
- },
6543
- mapperProps.updateComponent
6544
- );
6545
-
6546
6573
  // src/revamp/useDynamicFlowCore.tsx
6547
6574
  function useDynamicFlowCore(props) {
6548
6575
  const _a = props, { flowId, initialAction, initialStep, displayStepTitle = true } = _a, rest = __objRest(_a, ["flowId", "initialAction", "initialStep", "displayStepTitle"]);
@@ -6611,12 +6638,7 @@ function useDynamicFlowCore(props) {
6611
6638
  rootComponentRef.current.stop();
6612
6639
  stepRef.current = newStep;
6613
6640
  etagRef.current = etag;
6614
- const validationResult = (0, import_dynamic_flow_types2.validateStep)(newStep);
6615
- if (!validationResult.valid) {
6616
- logEvent("info", "The provided step does not conform to the specification.", {
6617
- errors: validationResult.errors
6618
- });
6619
- }
6641
+ analyseStep(newStep, logEvent);
6620
6642
  try {
6621
6643
  const newStepComponent = mapStepToComponent(__spreadValues({
6622
6644
  stepLocalValue: localValue,
package/build/main.mjs CHANGED
@@ -1832,7 +1832,6 @@ var getComponentAlertProps = (component, rendererMapperProps) => "alert" in comp
1832
1832
  }, rendererMapperProps) : null;
1833
1833
 
1834
1834
  // src/revamp/useDynamicFlowCore.tsx
1835
- import { validateStep } from "@wise/dynamic-flow-types";
1836
1835
  import { useCallback as useCallback2, useEffect, useMemo, useRef as useRef2, useState } from "react";
1837
1836
  import { useIntl as useIntl2 } from "react-intl";
1838
1837
 
@@ -1944,40 +1943,6 @@ var createRootDomainComponent = (updateComponent) => {
1944
1943
  return rootComponent;
1945
1944
  };
1946
1945
 
1947
- // src/revamp/domain/components/step/ExternalConfirmationComponent.ts
1948
- var createExternalConfirmation = (uid, url, updateComponent) => {
1949
- const update = getInputUpdateFunction(updateComponent);
1950
- return {
1951
- type: "external-confirmation",
1952
- uid,
1953
- url,
1954
- status: "initial",
1955
- onSuccess() {
1956
- update(this, (draft) => {
1957
- draft.status = "success";
1958
- });
1959
- },
1960
- onFailure() {
1961
- if (this.status === "initial") {
1962
- update(this, (draft) => {
1963
- draft.status = "failure";
1964
- });
1965
- }
1966
- },
1967
- onCancel() {
1968
- update(this, (draft) => {
1969
- draft.status = "dismissed";
1970
- });
1971
- },
1972
- getSubmittableValue: async () => null,
1973
- getSubmittableValueSync: () => null,
1974
- getLocalValue: () => null,
1975
- getSummary: () => ({}),
1976
- // Noop
1977
- validate: () => true
1978
- };
1979
- };
1980
-
1981
1946
  // src/revamp/domain/features/summary/summary-utils.ts
1982
1947
  var getSummariser = (schema) => (value) => {
1983
1948
  const { summary, icon, image } = schema;
@@ -2014,71 +1979,62 @@ var summaryIfProvides = (summary, { value, icon, image }) => {
2014
1979
  };
2015
1980
  };
2016
1981
 
2017
- // src/revamp/domain/components/step/StepDomainComponent.ts
2018
- var createStepComponent = (stepProps) => {
2019
- const _a = stepProps, { uid, stepPolling, stepRefreshAfter, updateComponent } = _a, rest = __objRest(_a, ["uid", "stepPolling", "stepRefreshAfter", "updateComponent"]);
1982
+ // src/revamp/domain/features/validation/validation-functions.ts
1983
+ var validateComponents = (components) => components.reduce((acc, component) => component.validate() && acc, true);
1984
+ var getLocalValueValidator = (checks) => (currentValue) => checks.map((check) => check(currentValue)).filter(isString);
1985
+
1986
+ // src/revamp/domain/components/ModalContentComponent.ts
1987
+ var createModalContentComponent = (modalProps, updateComponent) => {
2020
1988
  const update = getInputUpdateFunction(updateComponent);
2021
- const component = __spreadProps(__spreadValues({
2022
- uid
2023
- }, rest), {
2024
- type: "step",
2025
- modals: [],
2026
- dismissModal() {
2027
- var _a2;
2028
- (_a2 = this.modals.at(-1)) == null ? void 0 : _a2.close();
2029
- },
2030
- dismissAllModals() {
2031
- this._update((draft) => {
2032
- draft.modals = draft.modals.map((m) => __spreadProps(__spreadValues({}, m), { open: false }));
2033
- });
2034
- },
2035
- showModal(modal) {
2036
- this._update((draft) => {
2037
- draft.modals = [...draft.modals, modal];
2038
- });
2039
- },
1989
+ const modalContentComponent = __spreadProps(__spreadValues({
1990
+ type: "modal-content",
1991
+ open: true
1992
+ }, modalProps), {
2040
1993
  _update(updateFn) {
2041
1994
  update(this, updateFn);
2042
1995
  },
2043
1996
  getChildren() {
2044
- return this.externalConfirmation ? [...this.layoutComponents, this.externalConfirmation] : this.layoutComponents;
1997
+ return this.components;
2045
1998
  },
2046
- getModals() {
2047
- return this.modals;
1999
+ getLocalValue() {
2000
+ return getLocalValues(this.getChildren());
2048
2001
  },
2049
2002
  async getSubmittableValue() {
2050
- return getSubmittableData(this.inputComponents);
2003
+ return getSubmittableData(this.getChildren());
2051
2004
  },
2052
2005
  getSubmittableValueSync() {
2053
- return getSubmittableDataSync(this.inputComponents);
2006
+ return getSubmittableDataSync(this.getChildren());
2054
2007
  },
2055
2008
  getSummary() {
2056
2009
  return summariseFromChildren(this.getChildren());
2057
2010
  },
2058
- getLocalValue() {
2059
- return getLocalValues(this.inputComponents);
2060
- },
2061
2011
  validate() {
2062
- return this.inputComponents.every(
2063
- (inputComponent) => inputComponent.isSchemaReferencedInStep ? inputComponent.validate() : true
2064
- );
2065
- },
2066
- setLoadingState(loadingState) {
2067
- this._update((draft) => {
2068
- draft.loadingState = loadingState;
2069
- });
2012
+ return validateComponents(this.getChildren());
2070
2013
  },
2071
- stop() {
2072
- stepPolling == null ? void 0 : stepPolling.stop();
2073
- stepRefreshAfter == null ? void 0 : stepRefreshAfter.stop();
2074
- this._update((draft) => {
2075
- draft.modals = [];
2014
+ close() {
2015
+ update(this, (draft) => {
2016
+ draft.open = false;
2076
2017
  });
2077
2018
  }
2078
2019
  });
2079
- return component;
2020
+ return modalContentComponent;
2080
2021
  };
2081
2022
 
2023
+ // src/revamp/domain/components/utils/getRandomId.ts
2024
+ var getRandomId = () => Math.random().toString(36).substring(2);
2025
+
2026
+ // src/revamp/domain/components/AlertComponent.ts
2027
+ var createAlertComponent = (alertProps) => __spreadProps(__spreadValues({
2028
+ type: "alert"
2029
+ }, alertProps), {
2030
+ getSubmittableValue: async () => null,
2031
+ getSubmittableValueSync: () => null,
2032
+ getLocalValue: () => null,
2033
+ getSummary: () => ({}),
2034
+ // Noop
2035
+ validate: () => true
2036
+ });
2037
+
2082
2038
  // src/revamp/domain/mappers/utils/behavior-utils.ts
2083
2039
  var getDomainLayerBehavior = ({
2084
2040
  action,
@@ -2118,73 +2074,6 @@ var getActionByReference = ($ref, actions = []) => {
2118
2074
  return action;
2119
2075
  };
2120
2076
 
2121
- // src/revamp/domain/features/polling/getStepPolling.ts
2122
- var getStepPolling = ({
2123
- pollingConfig,
2124
- onBehavior,
2125
- onPoll
2126
- }) => {
2127
- const { interval, delay = interval, maxAttempts, url, onError } = pollingConfig;
2128
- let abortController = new AbortController();
2129
- if (delay == null) {
2130
- throw new Error("Polling configuration must include delay or interval");
2131
- }
2132
- const onErrorBehavior = skipValidation(getDomainLayerBehavior(onError, []));
2133
- let attempts = 0;
2134
- const poll = () => {
2135
- attempts += 1;
2136
- abortController.abort();
2137
- abortController = new AbortController();
2138
- const { signal } = abortController;
2139
- onPoll(url, onErrorBehavior, signal).then((result) => {
2140
- if (result) {
2141
- stop();
2142
- return;
2143
- }
2144
- if (attempts >= maxAttempts && !signal.aborted) {
2145
- void onBehavior(onErrorBehavior);
2146
- stop();
2147
- }
2148
- }).catch(() => {
2149
- });
2150
- };
2151
- const intervalRef = setInterval(poll, delay * 1e3);
2152
- const stop = () => {
2153
- clearTimeout(intervalRef);
2154
- abortController.abort();
2155
- };
2156
- poll();
2157
- return { stop };
2158
- };
2159
-
2160
- // src/revamp/domain/features/refreshAfter/getStepRefreshAfter.ts
2161
- var ONE_SECOND = 1e3;
2162
- var getStepRefreshAfter = ({ refreshAfter, onRefresh }) => {
2163
- const targetTime = new Date(refreshAfter).getTime();
2164
- if (typeof refreshAfter !== "string" || Number.isNaN(targetTime)) {
2165
- throw new Error(`Invalid refreshAfter value: ${String(refreshAfter)}`);
2166
- }
2167
- const timeLeft = Math.max(targetTime - Date.now(), ONE_SECOND);
2168
- const timeout = setTimeout(() => {
2169
- void onRefresh("refreshAfter");
2170
- }, timeLeft);
2171
- return {
2172
- stop: () => clearTimeout(timeout)
2173
- };
2174
- };
2175
-
2176
- // src/revamp/domain/components/AlertComponent.ts
2177
- var createAlertComponent = (alertProps) => __spreadProps(__spreadValues({
2178
- type: "alert"
2179
- }, alertProps), {
2180
- getSubmittableValue: async () => null,
2181
- getSubmittableValueSync: () => null,
2182
- getLocalValue: () => null,
2183
- getSummary: () => ({}),
2184
- // Noop
2185
- validate: () => true
2186
- });
2187
-
2188
2077
  // src/revamp/domain/mappers/utils/call-to-action-utils.ts
2189
2078
  var getDomainLayerCallToAction = (callToAction, onBehavior, stepActions) => {
2190
2079
  if (!callToAction) {
@@ -2291,10 +2180,6 @@ var alertLayoutToComponent = (uid, { control, markdown, margin = "md", context =
2291
2180
  });
2292
2181
  };
2293
2182
 
2294
- // src/revamp/domain/features/validation/validation-functions.ts
2295
- var validateComponents = (components) => components.reduce((acc, component) => component.validate() && acc, true);
2296
- var getLocalValueValidator = (checks) => (currentValue) => checks.map((check) => check(currentValue)).filter(isString);
2297
-
2298
2183
  // src/revamp/domain/components/BoxComponent.ts
2299
2184
  var createBoxComponent = (boxProps) => __spreadProps(__spreadValues({}, boxProps), {
2300
2185
  type: "box",
@@ -3172,8 +3057,171 @@ var mapLayoutToComponent = (uid, layout, mapperProps, inputComponents) => {
3172
3057
  }
3173
3058
  };
3174
3059
 
3175
- // src/revamp/domain/components/utils/getRandomId.ts
3176
- var getRandomId = () => Math.random().toString(36).substring(2);
3060
+ // src/revamp/domain/mappers/layout/modalToContent.ts
3061
+ var modalToContent = (uid, { content, title }, mapperProps, inputComponents) => createModalContentComponent(
3062
+ {
3063
+ uid: `${uid}-modal-${getRandomId()}`,
3064
+ title,
3065
+ components: content.map(
3066
+ (component, index) => mapLayoutToComponent(`${uid}.modal-${index}`, component, mapperProps, inputComponents)
3067
+ )
3068
+ },
3069
+ mapperProps.updateComponent
3070
+ );
3071
+
3072
+ // src/revamp/domain/components/step/ExternalConfirmationComponent.ts
3073
+ var createExternalConfirmation = (uid, url, updateComponent) => {
3074
+ const update = getInputUpdateFunction(updateComponent);
3075
+ return {
3076
+ type: "external-confirmation",
3077
+ uid,
3078
+ url,
3079
+ status: "initial",
3080
+ onSuccess() {
3081
+ update(this, (draft) => {
3082
+ draft.status = "success";
3083
+ });
3084
+ },
3085
+ onFailure() {
3086
+ if (this.status === "initial") {
3087
+ update(this, (draft) => {
3088
+ draft.status = "failure";
3089
+ });
3090
+ }
3091
+ },
3092
+ onCancel() {
3093
+ update(this, (draft) => {
3094
+ draft.status = "dismissed";
3095
+ });
3096
+ },
3097
+ getSubmittableValue: async () => null,
3098
+ getSubmittableValueSync: () => null,
3099
+ getLocalValue: () => null,
3100
+ getSummary: () => ({}),
3101
+ // Noop
3102
+ validate: () => true
3103
+ };
3104
+ };
3105
+
3106
+ // src/revamp/domain/components/step/StepDomainComponent.ts
3107
+ var createStepComponent = (stepProps) => {
3108
+ const _a = stepProps, { uid, stepPolling, stepRefreshAfter, updateComponent } = _a, rest = __objRest(_a, ["uid", "stepPolling", "stepRefreshAfter", "updateComponent"]);
3109
+ const update = getInputUpdateFunction(updateComponent);
3110
+ const component = __spreadProps(__spreadValues({
3111
+ uid
3112
+ }, rest), {
3113
+ type: "step",
3114
+ modals: [],
3115
+ dismissModal() {
3116
+ var _a2;
3117
+ (_a2 = this.modals.at(-1)) == null ? void 0 : _a2.close();
3118
+ },
3119
+ dismissAllModals() {
3120
+ this._update((draft) => {
3121
+ draft.modals = draft.modals.map((m) => __spreadProps(__spreadValues({}, m), { open: false }));
3122
+ });
3123
+ },
3124
+ showModal(modal) {
3125
+ this._update((draft) => {
3126
+ draft.modals = [...draft.modals, modal];
3127
+ });
3128
+ },
3129
+ _update(updateFn) {
3130
+ update(this, updateFn);
3131
+ },
3132
+ getChildren() {
3133
+ return this.externalConfirmation ? [...this.layoutComponents, this.externalConfirmation] : this.layoutComponents;
3134
+ },
3135
+ getModals() {
3136
+ return this.modals;
3137
+ },
3138
+ async getSubmittableValue() {
3139
+ return getSubmittableData(this.inputComponents);
3140
+ },
3141
+ getSubmittableValueSync() {
3142
+ return getSubmittableDataSync(this.inputComponents);
3143
+ },
3144
+ getSummary() {
3145
+ return summariseFromChildren(this.getChildren());
3146
+ },
3147
+ getLocalValue() {
3148
+ return getLocalValues(this.inputComponents);
3149
+ },
3150
+ validate() {
3151
+ return this.inputComponents.every(
3152
+ (inputComponent) => inputComponent.isSchemaReferencedInStep ? inputComponent.validate() : true
3153
+ );
3154
+ },
3155
+ setLoadingState(loadingState) {
3156
+ this._update((draft) => {
3157
+ draft.loadingState = loadingState;
3158
+ });
3159
+ },
3160
+ stop() {
3161
+ stepPolling == null ? void 0 : stepPolling.stop();
3162
+ stepRefreshAfter == null ? void 0 : stepRefreshAfter.stop();
3163
+ this._update((draft) => {
3164
+ draft.modals = [];
3165
+ });
3166
+ }
3167
+ });
3168
+ return component;
3169
+ };
3170
+
3171
+ // src/revamp/domain/features/polling/getStepPolling.ts
3172
+ var getStepPolling = ({
3173
+ pollingConfig,
3174
+ onBehavior,
3175
+ onPoll
3176
+ }) => {
3177
+ const { interval, delay = interval, maxAttempts, url, onError } = pollingConfig;
3178
+ let abortController = new AbortController();
3179
+ if (delay == null) {
3180
+ throw new Error("Polling configuration must include delay or interval");
3181
+ }
3182
+ const onErrorBehavior = skipValidation(getDomainLayerBehavior(onError, []));
3183
+ let attempts = 0;
3184
+ const poll = () => {
3185
+ attempts += 1;
3186
+ abortController.abort();
3187
+ abortController = new AbortController();
3188
+ const { signal } = abortController;
3189
+ onPoll(url, onErrorBehavior, signal).then((result) => {
3190
+ if (result) {
3191
+ stop();
3192
+ return;
3193
+ }
3194
+ if (attempts >= maxAttempts && !signal.aborted) {
3195
+ void onBehavior(onErrorBehavior);
3196
+ stop();
3197
+ }
3198
+ }).catch(() => {
3199
+ });
3200
+ };
3201
+ const intervalRef = setInterval(poll, delay * 1e3);
3202
+ const stop = () => {
3203
+ clearTimeout(intervalRef);
3204
+ abortController.abort();
3205
+ };
3206
+ poll();
3207
+ return { stop };
3208
+ };
3209
+
3210
+ // src/revamp/domain/features/refreshAfter/getStepRefreshAfter.ts
3211
+ var ONE_SECOND = 1e3;
3212
+ var getStepRefreshAfter = ({ refreshAfter, onRefresh }) => {
3213
+ const targetTime = new Date(refreshAfter).getTime();
3214
+ if (typeof refreshAfter !== "string" || Number.isNaN(targetTime)) {
3215
+ throw new Error(`Invalid refreshAfter value: ${String(refreshAfter)}`);
3216
+ }
3217
+ const timeLeft = Math.max(targetTime - Date.now(), ONE_SECOND);
3218
+ const timeout = setTimeout(() => {
3219
+ void onRefresh("refreshAfter");
3220
+ }, timeLeft);
3221
+ return {
3222
+ stop: () => clearTimeout(timeout)
3223
+ };
3224
+ };
3177
3225
 
3178
3226
  // src/revamp/domain/components/utils/isExactLocalValueMatch.ts
3179
3227
  var isExactLocalValueMatch = (valueA, valueB) => {
@@ -6441,6 +6489,34 @@ var formatDateOptions = {
6441
6489
  dateStyle: "long"
6442
6490
  };
6443
6491
 
6492
+ // src/revamp/utils/analyse-step.ts
6493
+ import { validateStep } from "@wise/dynamic-flow-types";
6494
+ var analyseStep = (step, logEvent) => {
6495
+ validateStepTypes(step, logEvent);
6496
+ warnWhenPollingWithSchemas(step, logEvent);
6497
+ };
6498
+ var warnWhenPollingWithSchemas = (step, logEvent) => {
6499
+ var _a;
6500
+ const hasPolling = step.polling != null;
6501
+ const hasSchemas = step.schemas != null && step.schemas.length > 0;
6502
+ if (hasPolling && hasSchemas) {
6503
+ logEvent("warning", "DynamicFlow Polling and Schema Warning.", {
6504
+ message: "The provided step is configured with polling and schemas. Actions triggered from a polling response will not contain the schema values in their payload.",
6505
+ stepId: (_a = step.id) != null ? _a : step.key
6506
+ });
6507
+ }
6508
+ };
6509
+ var validateStepTypes = (step, logEvent) => {
6510
+ var _a;
6511
+ const validationResult = validateStep(step);
6512
+ if (!validationResult.valid) {
6513
+ logEvent("info", "The provided step does not conform to the specification.", {
6514
+ stepId: (_a = step.id) != null ? _a : step.key,
6515
+ errors: validationResult.errors
6516
+ });
6517
+ }
6518
+ };
6519
+
6444
6520
  // src/revamp/utils/useStableCallback.tsx
6445
6521
  import { useCallback, useLayoutEffect, useRef } from "react";
6446
6522
  function useStableCallback(handler) {
@@ -6451,55 +6527,6 @@ function useStableCallback(handler) {
6451
6527
  return useCallback((...args) => ref.current ? ref.current(...args) : null, []);
6452
6528
  }
6453
6529
 
6454
- // src/revamp/domain/components/ModalContentComponent.ts
6455
- var createModalContentComponent = (modalProps, updateComponent) => {
6456
- const update = getInputUpdateFunction(updateComponent);
6457
- const modalContentComponent = __spreadProps(__spreadValues({
6458
- type: "modal-content",
6459
- open: true
6460
- }, modalProps), {
6461
- _update(updateFn) {
6462
- update(this, updateFn);
6463
- },
6464
- getChildren() {
6465
- return this.components;
6466
- },
6467
- getLocalValue() {
6468
- return getLocalValues(this.getChildren());
6469
- },
6470
- async getSubmittableValue() {
6471
- return getSubmittableData(this.getChildren());
6472
- },
6473
- getSubmittableValueSync() {
6474
- return getSubmittableDataSync(this.getChildren());
6475
- },
6476
- getSummary() {
6477
- return summariseFromChildren(this.getChildren());
6478
- },
6479
- validate() {
6480
- return validateComponents(this.getChildren());
6481
- },
6482
- close() {
6483
- update(this, (draft) => {
6484
- draft.open = false;
6485
- });
6486
- }
6487
- });
6488
- return modalContentComponent;
6489
- };
6490
-
6491
- // src/revamp/domain/mappers/layout/modalToContent.ts
6492
- var modalToContent = (uid, { content, title }, mapperProps, inputComponents) => createModalContentComponent(
6493
- {
6494
- uid: `${uid}-modal-${getRandomId()}`,
6495
- title,
6496
- components: content.map(
6497
- (component, index) => mapLayoutToComponent(`${uid}.modal-${index}`, component, mapperProps, inputComponents)
6498
- )
6499
- },
6500
- mapperProps.updateComponent
6501
- );
6502
-
6503
6530
  // src/revamp/useDynamicFlowCore.tsx
6504
6531
  function useDynamicFlowCore(props) {
6505
6532
  const _a = props, { flowId, initialAction, initialStep, displayStepTitle = true } = _a, rest = __objRest(_a, ["flowId", "initialAction", "initialStep", "displayStepTitle"]);
@@ -6568,12 +6595,7 @@ function useDynamicFlowCore(props) {
6568
6595
  rootComponentRef.current.stop();
6569
6596
  stepRef.current = newStep;
6570
6597
  etagRef.current = etag;
6571
- const validationResult = validateStep(newStep);
6572
- if (!validationResult.valid) {
6573
- logEvent("info", "The provided step does not conform to the specification.", {
6574
- errors: validationResult.errors
6575
- });
6576
- }
6598
+ analyseStep(newStep, logEvent);
6577
6599
  try {
6578
6600
  const newStepComponent = mapStepToComponent(__spreadValues({
6579
6601
  stepLocalValue: localValue,
@@ -0,0 +1,3 @@
1
+ import { Step } from '@wise/dynamic-flow-types/build/next';
2
+ import { LoggingEventDispatcher } from '../domain/features/events';
3
+ export declare const analyseStep: (step: Step, logEvent: LoggingEventDispatcher) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wise/dynamic-flow-client",
3
- "version": "4.5.4",
3
+ "version": "4.5.5",
4
4
  "description": "Dynamic Flow web client",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./build/main.js",
@@ -85,8 +85,8 @@
85
85
  "tsx": "4.19.4",
86
86
  "typescript": "5.8.3",
87
87
  "webpack": "5.99.8",
88
- "@wise/dynamic-flow-renderers": "0.0.0",
89
- "@wise/dynamic-flow-fixtures": "0.0.1"
88
+ "@wise/dynamic-flow-fixtures": "0.0.1",
89
+ "@wise/dynamic-flow-renderers": "0.0.0"
90
90
  },
91
91
  "peerDependencies": {
92
92
  "@transferwise/components": "^46.92.0",
@@ -102,7 +102,7 @@
102
102
  "classnames": "2.5.1",
103
103
  "react-webcam": "^7.2.0",
104
104
  "screenfull": "^5.2.0",
105
- "@wise/dynamic-flow-types": "3.3.2"
105
+ "@wise/dynamic-flow-types": "3.3.3"
106
106
  },
107
107
  "scripts": {
108
108
  "dev": "pnpm build:visual-tests && storybook dev -p 3003",