@wise/dynamic-flow-client 3.10.0 → 3.11.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.mjs CHANGED
@@ -1269,11 +1269,14 @@ var isStringSchemaWithUpload = (schema) => isStringSchema(schema) && schema.form
1269
1269
  var isSchemaWithPersistAsync = (schema) => "persistAsync" in schema && !isNullish(schema.persistAsync);
1270
1270
 
1271
1271
  // src/revamp/renderers/stepComponentToProps.ts
1272
- var stepComponentToProps = ({ back, external, loadingState, trackEvent }, children) => ({
1272
+ var stepComponentToProps = ({ back, description, error, external, loadingState, title, trackEvent }, children) => ({
1273
1273
  type: "step",
1274
1274
  back,
1275
+ description,
1276
+ error,
1275
1277
  external,
1276
1278
  loadingState,
1279
+ title,
1277
1280
  trackEvent,
1278
1281
  children
1279
1282
  });
@@ -6497,27 +6500,6 @@ var alertLayoutToComponent = (uid, { control, markdown, margin = "md", context =
6497
6500
  context: mapLegacyContext(context)
6498
6501
  });
6499
6502
 
6500
- // src/revamp/domain/components/HeadingComponent.ts
6501
- var createHeadingComponent = (headingProps) => __spreadProps(__spreadValues({
6502
- type: "heading"
6503
- }, headingProps), {
6504
- getSubmittableValue: async () => null,
6505
- getSummary: () => ({}),
6506
- // Noop
6507
- getLocalValue: () => null,
6508
- validate: () => true
6509
- });
6510
-
6511
- // src/revamp/domain/mappers/layout/headingLayoutToComponent.ts
6512
- var headingLayoutToComponent = (uid, { align = "left", margin = "md", size = "md", control, text }) => createHeadingComponent({
6513
- uid,
6514
- align: mapLegacyAlign(align),
6515
- control,
6516
- margin,
6517
- size,
6518
- text
6519
- });
6520
-
6521
6503
  // src/revamp/domain/components/BoxComponent.ts
6522
6504
  var createBoxComponent = (boxProps) => __spreadProps(__spreadValues({}, boxProps), {
6523
6505
  type: "box",
@@ -7761,38 +7743,32 @@ var getComponentForLocalValueKey = (key, component) => {
7761
7743
 
7762
7744
  // src/revamp/domain/components/utils/isPartialLocalValueMatch.ts
7763
7745
  var isPartialLocalValueMatch = (partialValue, component) => {
7764
- if (isArray(partialValue) && component.type === "repeatable") {
7765
- const children = component.getChildren();
7766
- return partialValue.every((value, index) => {
7767
- const childComponent = children[index];
7768
- return childComponent ? isPartialLocalValueMatch(value, childComponent) : false;
7769
- });
7746
+ if (!component) {
7747
+ return false;
7770
7748
  }
7771
7749
  const componentValue = component.getLocalValue();
7772
7750
  if (component.type === "const") {
7773
7751
  return compareLocalValue(partialValue, componentValue);
7774
7752
  }
7775
7753
  if (isObjectLocalValue(partialValue) && isObjectLocalValue(componentValue)) {
7776
- const allKeys = Array.from(
7777
- /* @__PURE__ */ new Set([...Object.keys(partialValue), ...Object.keys(componentValue)])
7778
- );
7779
- const matchingKeys = allKeys.filter(
7780
- (key) => !isNullish(partialValue[key]) && !isNullish(componentValue[key])
7781
- );
7782
- return matchingKeys.length > 0 && matchingKeys.every((key) => {
7783
- const componentForKey = getComponentForLocalValueKey(key, component);
7784
- return componentForKey ? isPartialLocalValueMatch(partialValue[key], componentForKey) : false;
7785
- });
7786
- }
7787
- if (partialValue instanceof File && componentValue instanceof File) {
7788
- return areEquivalentFiles(partialValue, componentValue);
7754
+ return isPartialObjectMatch(partialValue, componentValue, component);
7789
7755
  }
7790
- if ("isPersisted" in component && component.isPersisted) {
7791
- return true;
7792
- }
7793
- return compareLocalValue(partialValue, componentValue);
7756
+ return true;
7757
+ };
7758
+ var isPartialObjectMatch = (partialValue, componentValue, component) => {
7759
+ const resultByKey = getMatchingKeys(partialValue, componentValue).map((key) => {
7760
+ const componentForKey = getComponentForLocalValueKey(key, component);
7761
+ if (componentForKey && componentForKey.type === "const") {
7762
+ return isPartialLocalValueMatch(partialValue[key], componentForKey);
7763
+ }
7764
+ return null;
7765
+ });
7766
+ return resultByKey.includes(true) && !resultByKey.includes(false);
7767
+ };
7768
+ var getMatchingKeys = (a, b) => {
7769
+ const allKeys = Array.from(/* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)]));
7770
+ return allKeys.filter((key) => !isNullish(a[key]) && !isNullish(b[key]));
7794
7771
  };
7795
- var areEquivalentFiles = (fileA, fileB) => fileA.name === fileB.name && fileA.type === fileB.type && fileA.size === fileB.size;
7796
7772
 
7797
7773
  // src/revamp/domain/components/SelectInputComponent.ts
7798
7774
  var createSelectInputComponent = (selectProps, updateComponent) => {
@@ -8118,6 +8094,19 @@ var toBase64 = async (file) => new Promise((resolve, reject) => {
8118
8094
  reader.addEventListener("error", reject);
8119
8095
  reader.readAsDataURL(file);
8120
8096
  });
8097
+ var base64dataUrltoFile = (dataurl, filename) => {
8098
+ if (!isBase64DataUrl(dataurl)) {
8099
+ return null;
8100
+ }
8101
+ const [, base64data] = dataurl.split(",");
8102
+ return new File([base64ToBytes(base64data)], filename, { type: getMimeType(dataurl) });
8103
+ };
8104
+ var isBase64DataUrl = (dataurl) => dataurl.startsWith("data:") && dataurl.includes("base64") && dataurl.includes(",");
8105
+ var getMimeType = (base64dataUrl) => base64dataUrl.substring("data:".length).split(";")[0];
8106
+ var base64ToBytes = (base64) => {
8107
+ const charCodes = atob(base64).split("").map((m) => m.charCodeAt(0));
8108
+ return Uint8Array.from(charCodes);
8109
+ };
8121
8110
 
8122
8111
  // src/revamp/domain/components/UploadInputComponent.ts
8123
8112
  var createUploadInputComponent = (uploadInputProps, updateComponent) => {
@@ -8219,6 +8208,7 @@ var createUploadInputComponent = (uploadInputProps, updateComponent) => {
8219
8208
 
8220
8209
  // src/revamp/domain/mappers/schema/stringSchemaToComponent/stringSchemaToUploadInputComponent.ts
8221
8210
  var stringSchemaToUploadInputComponent = (schemaMapperProps, mapperProps) => {
8211
+ var _a;
8222
8212
  const { schema, localValue, model, required = false } = schemaMapperProps;
8223
8213
  const { accepts, autocompleteHint, maxSize, validationMessages } = schema;
8224
8214
  const { getErrorMessageFunctions, updateComponent, onRefresh, onValueChange } = mapperProps;
@@ -8226,7 +8216,7 @@ var stringSchemaToUploadInputComponent = (schemaMapperProps, mapperProps) => {
8226
8216
  const { performPersistAsync } = getPersistAsyncInitialState(schemaMapperProps, mapperProps);
8227
8217
  const persistedState = performPersistAsync ? getInitialPersistedState(null, model) : getInitialPersistedState();
8228
8218
  const validLocalValue = isFile(localValue) ? localValue : null;
8229
- const value = performPersistAsync ? validLocalValue : null;
8219
+ const value = (_a = getFileFromModel(model)) != null ? _a : validLocalValue;
8230
8220
  return createUploadInputComponent(
8231
8221
  __spreadProps(__spreadValues({}, mapCommonSchemaProps(schemaMapperProps)), {
8232
8222
  accepts,
@@ -8243,6 +8233,7 @@ var stringSchemaToUploadInputComponent = (schemaMapperProps, mapperProps) => {
8243
8233
  updateComponent
8244
8234
  );
8245
8235
  };
8236
+ var getFileFromModel = (model) => isString(model) ? base64dataUrltoFile(model, "") : null;
8246
8237
 
8247
8238
  // src/revamp/domain/components/TextInputComponent.ts
8248
8239
  var createTextInputComponent = (textInputProps, updateComponent) => {
@@ -9228,6 +9219,27 @@ var formLayoutToComponent = (uid, { schemaId, schema: schemaRef, control, margin
9228
9219
  });
9229
9220
  };
9230
9221
 
9222
+ // src/revamp/domain/components/HeadingComponent.ts
9223
+ var createHeadingComponent = (headingProps) => __spreadProps(__spreadValues({
9224
+ type: "heading"
9225
+ }, headingProps), {
9226
+ getSubmittableValue: async () => null,
9227
+ getSummary: () => ({}),
9228
+ // Noop
9229
+ getLocalValue: () => null,
9230
+ validate: () => true
9231
+ });
9232
+
9233
+ // src/revamp/domain/mappers/layout/headingLayoutToComponent.ts
9234
+ var headingLayoutToComponent = (uid, { align = "left", margin = "md", size = "md", control, text }) => createHeadingComponent({
9235
+ uid,
9236
+ align: mapLegacyAlign(align),
9237
+ control,
9238
+ margin,
9239
+ size,
9240
+ text
9241
+ });
9242
+
9231
9243
  // src/revamp/domain/components/ImageComponent.ts
9232
9244
  var createImageComponent = (imageProps) => __spreadProps(__spreadValues({
9233
9245
  type: "image"
@@ -9700,7 +9712,7 @@ var mapStepToComponent = (_a) => {
9700
9712
  ]);
9701
9713
  var _a2, _b2;
9702
9714
  const { httpClient, step, updateComponent } = restProps;
9703
- const { id, navigation, external, key, layout = [], polling } = step;
9715
+ const { id, description, errors, external, key, layout = [], navigation, polling, title } = step;
9704
9716
  const backNavigation = (_a2 = navigation == null ? void 0 : navigation.back) != null ? _a2 : navigation == null ? void 0 : navigation.backButton;
9705
9717
  const back = backNavigation ? {
9706
9718
  title: backNavigation.title,
@@ -9737,34 +9749,21 @@ var mapStepToComponent = (_a) => {
9737
9749
  onRefresh
9738
9750
  }))
9739
9751
  );
9740
- const additionalComponents = makeAdditionalComponents(step, uid, displayStepTitle);
9741
9752
  const stepComponent = createStepComponent({
9742
9753
  uid,
9743
- components: [...additionalComponents, ...layoutComponents],
9744
9754
  back,
9755
+ components: layoutComponents,
9756
+ description,
9757
+ error: errors == null ? void 0 : errors.error,
9745
9758
  external,
9746
9759
  loadingState,
9747
9760
  stepPolling,
9748
9761
  updateComponent,
9762
+ title: displayStepTitle ? title : void 0,
9749
9763
  trackEvent
9750
9764
  });
9751
9765
  return stepComponent;
9752
9766
  };
9753
- var makeAdditionalComponents = (step, uid, displayStepTitle) => {
9754
- const { title, errors } = step;
9755
- const heading = title && displayStepTitle ? headingLayoutToComponent(`${uid}.title`, {
9756
- type: "heading",
9757
- text: title,
9758
- align: "center",
9759
- size: "lg"
9760
- }) : void 0;
9761
- const stepError = (errors == null ? void 0 : errors.error) ? alertLayoutToComponent(`${uid}.global-error`, {
9762
- type: "alert",
9763
- markdown: errors.error,
9764
- context: "negative"
9765
- }) : void 0;
9766
- return [...heading ? [heading] : [], ...stepError ? [stepError] : []];
9767
- };
9768
9767
 
9769
9768
  // src/revamp/flow/executeRefresh.ts
9770
9769
  var executeRefresh = async (props) => {
@@ -12280,7 +12279,7 @@ import { Fragment as Fragment10, jsx as jsx55, jsxs as jsxs20 } from "react/jsx-
12280
12279
  var ReviewRenderer = {
12281
12280
  canRenderType: "review",
12282
12281
  render: ({ callToAction, control, fields, margin, title }) => {
12283
- const orientation = control === "horizontal" ? "HORIZONTAL_RIGHT_ALIGNED" : "VERTICAL_ONE_COLUMN";
12282
+ const orientation = mapControlToDefinitionListLayout(control);
12284
12283
  const action = callToAction ? {
12285
12284
  text: callToAction.title,
12286
12285
  onClick: (event) => {
@@ -12305,6 +12304,21 @@ var ReviewRenderer = {
12305
12304
  }
12306
12305
  };
12307
12306
  var ReviewRenderer_default = ReviewRenderer;
12307
+ var mapControlToDefinitionListLayout = (control) => {
12308
+ switch (control) {
12309
+ case "horizontal":
12310
+ case "horizontal-end-aligned":
12311
+ return "HORIZONTAL_RIGHT_ALIGNED";
12312
+ case "horizontal-start-aligned":
12313
+ return "HORIZONTAL_LEFT_ALIGNED";
12314
+ case "vertical-two-column":
12315
+ return "VERTICAL_TWO_COLUMN";
12316
+ case "vertical":
12317
+ case "vertical-one-column":
12318
+ default:
12319
+ return "VERTICAL_ONE_COLUMN";
12320
+ }
12321
+ };
12308
12322
  var getFieldValue = (value, help, orientation) => {
12309
12323
  if (help) {
12310
12324
  return orientation === "HORIZONTAL_RIGHT_ALIGNED" ? /* @__PURE__ */ jsxs20(Fragment10, { children: [
@@ -12430,13 +12444,14 @@ function BackButton({ title, onClick }) {
12430
12444
  var BackButton_default = BackButton;
12431
12445
 
12432
12446
  // src/revamp/wise/renderers/step/StepRenderer.tsx
12447
+ import { Alert as Alert3 } from "@transferwise/components";
12433
12448
  import { jsx as jsx58, jsxs as jsxs23 } from "react/jsx-runtime";
12434
12449
  var StepRenderer = {
12435
12450
  canRenderType: "step",
12436
12451
  render: StepRendererComponent
12437
12452
  };
12438
12453
  function StepRendererComponent(props) {
12439
- const { back, loadingState, external, trackEvent, children } = props;
12454
+ const { back, description, error, external, loadingState, title, trackEvent, children } = props;
12440
12455
  const value = useMemo4(() => ({ loadingState, trackEvent }), [loadingState, trackEvent]);
12441
12456
  const { requiresUserConfirmation, dismissConfirmation } = useExternal(external == null ? void 0 : external.url);
12442
12457
  if ((external == null ? void 0 : external.url) && requiresUserConfirmation) {
@@ -12444,6 +12459,9 @@ function StepRendererComponent(props) {
12444
12459
  }
12445
12460
  return /* @__PURE__ */ jsxs23(StepRendererContextProvider, { value, children: [
12446
12461
  back ? /* @__PURE__ */ jsx58(BackButton_default, __spreadValues({}, back)) : null,
12462
+ title ? /* @__PURE__ */ jsx58("h2", { className: "text-xs-center m-b-2", children: title }) : void 0,
12463
+ description ? /* @__PURE__ */ jsx58("p", { className: "text-xs-center m-b-2", children: description }) : void 0,
12464
+ error ? /* @__PURE__ */ jsx58(Alert3, { type: "negative", className: "m-b-2", message: error }) : void 0,
12447
12465
  children
12448
12466
  ] });
12449
12467
  }
@@ -13813,7 +13831,7 @@ var import_classnames16 = __toESM(require_classnames());
13813
13831
  import { useEffect as useEffect17, useMemo as useMemo17, useState as useState27 } from "react";
13814
13832
 
13815
13833
  // src/legacy/layout/alert/DynamicAlert.tsx
13816
- import { Alert as Alert3 } from "@transferwise/components";
13834
+ import { Alert as Alert4 } from "@transferwise/components";
13817
13835
 
13818
13836
  // src/legacy/layout/utils/getNavigationOptionMedia.tsx
13819
13837
  import { Avatar as Avatar5, AvatarType as AvatarType4 } from "@transferwise/components";
@@ -13914,7 +13932,7 @@ import { jsx as jsx69 } from "react/jsx-runtime";
13914
13932
  var DynamicAlert = (props) => {
13915
13933
  const alert = props.component;
13916
13934
  return /* @__PURE__ */ jsx69(
13917
- Alert3,
13935
+ Alert4,
13918
13936
  {
13919
13937
  type: mapContextToAlertType(legacy_mapContext(alert.context)),
13920
13938
  className: getMargin2(alert.margin),
@@ -17127,9 +17145,21 @@ var getFieldValue2 = (value, help, orientation) => {
17127
17145
  }
17128
17146
  return value;
17129
17147
  };
17130
- var getReviewLayout = (review) => {
17148
+ var getDefinitionListLayout = (review) => {
17131
17149
  const orientation = review.control || review.orientation;
17132
- return orientation === "horizontal" ? "HORIZONTAL_RIGHT_ALIGNED" : "VERTICAL_ONE_COLUMN";
17150
+ switch (orientation) {
17151
+ case "horizontal":
17152
+ case "horizontal-end-aligned":
17153
+ return "HORIZONTAL_RIGHT_ALIGNED";
17154
+ case "horizontal-start-aligned":
17155
+ return "HORIZONTAL_LEFT_ALIGNED";
17156
+ case "vertical-two-column":
17157
+ return "VERTICAL_TWO_COLUMN";
17158
+ case "vertical":
17159
+ case "vertical-one-column":
17160
+ default:
17161
+ return "VERTICAL_ONE_COLUMN";
17162
+ }
17133
17163
  };
17134
17164
  function DynamicReview(props) {
17135
17165
  const review = props.component;
@@ -17144,7 +17174,7 @@ function DynamicReview(props) {
17144
17174
  }
17145
17175
  }
17146
17176
  });
17147
- const orientation = getReviewLayout(review);
17177
+ const orientation = getDefinitionListLayout(review);
17148
17178
  const callToAction = review.callToAction ? getReviewAction2(review.callToAction.title, review.callToAction.action) : null;
17149
17179
  const legacyCallToAction = !callToAction && review.action ? getReviewAction2(review.action.title || "", review.action) : null;
17150
17180
  return /* @__PURE__ */ jsxs40("div", { className: margin, children: [
@@ -6,19 +6,22 @@ export type StepDomainComponent = BaseComponent & {
6
6
  type: 'step';
7
7
  back?: BackNavigation;
8
8
  components: DomainComponent[];
9
+ description?: string;
10
+ error?: string;
9
11
  external?: Step['external'];
10
12
  loadingState: LoadingState;
13
+ title?: string;
14
+ trackEvent: AnalyticsEventDispatcher<string>;
11
15
  setLoadingState: (loadingState: LoadingState) => void;
12
16
  getChildren: () => DomainComponent[];
13
17
  getLocalValue: () => LocalValue;
14
18
  stop: () => void;
15
- trackEvent: AnalyticsEventDispatcher<string>;
16
19
  };
17
20
  type BackNavigation = {
18
21
  title?: string;
19
22
  onClick: () => void;
20
23
  };
21
- export declare const createStepComponent: (stepProps: Pick<StepDomainComponent, "uid" | "components" | "external" | "trackEvent" | "back" | "loadingState"> & {
24
+ export declare const createStepComponent: (stepProps: Pick<StepDomainComponent, "error" | "uid" | "title" | "components" | "description" | "external" | "trackEvent" | "back" | "loadingState"> & {
22
25
  stepPolling?: StepPolling | undefined;
23
26
  updateComponent: UpdateComponent;
24
27
  }) => StepDomainComponent;
@@ -1 +1,2 @@
1
1
  export declare const toBase64: (file: Blob) => Promise<string>;
2
+ export declare const base64dataUrltoFile: (dataurl: string, filename: string) => File | null;
@@ -1,2 +1,2 @@
1
1
  import type { DomainComponent, LocalValue } from '../../types';
2
- export declare const isPartialLocalValueMatch: (partialValue: LocalValue, component: DomainComponent) => boolean;
2
+ export declare const isPartialLocalValueMatch: (partialValue: LocalValue, component: DomainComponent | null) => boolean;
@@ -1,4 +1,4 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { StepDomainComponent } from '../domain/components/StepDomainComponent';
3
3
  import type { StepRendererProps } from './types';
4
- export declare const stepComponentToProps: ({ back, external, loadingState, trackEvent }: StepDomainComponent, children: ReactNode) => StepRendererProps;
4
+ export declare const stepComponentToProps: ({ back, description, error, external, loadingState, title, trackEvent }: StepDomainComponent, children: ReactNode) => StepRendererProps;
@@ -29,10 +29,13 @@ export type StepRendererProps = {
29
29
  title?: string;
30
30
  onClick: () => void;
31
31
  };
32
+ description?: string;
33
+ error?: string;
32
34
  external?: {
33
35
  url: string;
34
36
  };
35
37
  loadingState: LoadingState;
38
+ title?: string;
36
39
  trackEvent: AnalyticsEventDispatcher<string>;
37
40
  children: ReactNode;
38
41
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wise/dynamic-flow-client",
3
- "version": "3.10.0",
3
+ "version": "3.11.1",
4
4
  "description": "Dynamic Flow web client",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./build/main.min.js",
@@ -44,7 +44,6 @@
44
44
  "@transferwise/formatting": "^2.13.0",
45
45
  "@transferwise/icons": "3.13.0",
46
46
  "@transferwise/neptune-css": "14.10.0",
47
- "@transferwise/neptune-tokens": "8.9.2",
48
47
  "@types/enzyme": "^3.10.18",
49
48
  "@types/jest": "29.5.12",
50
49
  "@types/react": "18",