@moneylion/react-native-offer-carousel 1.10.1 → 1.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/commonjs/capabilities/configuration/src/brands/checkVisualEligibility.js +13 -11
  3. package/lib/commonjs/capabilities/configuration/src/brands/checkVisualEligibility.js.map +1 -1
  4. package/lib/commonjs/capabilities/configuration/src/brands/createDerivedBrands.js +8 -19
  5. package/lib/commonjs/capabilities/configuration/src/brands/createDerivedBrands.js.map +1 -1
  6. package/lib/commonjs/capabilities/offer-catalog/src/utils/formatUtils.js +36 -21
  7. package/lib/commonjs/capabilities/offer-catalog/src/utils/formatUtils.js.map +1 -1
  8. package/lib/commonjs/capabilities/offer-catalog/src/utils/stats/formatters/annualFee.js +7 -30
  9. package/lib/commonjs/capabilities/offer-catalog/src/utils/stats/formatters/annualFee.js.map +1 -1
  10. package/lib/commonjs/capabilities/offer-catalog/src/utils/stats/formatters/purchaseApr.js +15 -17
  11. package/lib/commonjs/capabilities/offer-catalog/src/utils/stats/formatters/purchaseApr.js.map +1 -1
  12. package/lib/commonjs/capabilities/offer-catalog/src/utils/stats/formatters/recommendedCredit.js +8 -2
  13. package/lib/commonjs/capabilities/offer-catalog/src/utils/stats/formatters/recommendedCredit.js.map +1 -1
  14. package/lib/commonjs/capabilities/offer-catalog/src/utils/stats/index.js +40 -38
  15. package/lib/commonjs/capabilities/offer-catalog/src/utils/stats/index.js.map +1 -1
  16. package/lib/commonjs/capabilities/offers/pipeline/src/sources/ratetables/withDeviceSignals.js +22 -12
  17. package/lib/commonjs/capabilities/offers/pipeline/src/sources/ratetables/withDeviceSignals.js.map +1 -1
  18. package/lib/commonjs/capabilities/ui/elements/src/components/MarkdownText/components.js +22 -10
  19. package/lib/commonjs/capabilities/ui/elements/src/components/MarkdownText/components.js.map +1 -1
  20. package/lib/commonjs/components/DynamicOffers/Render/Offer.js +51 -49
  21. package/lib/commonjs/components/DynamicOffers/Render/Offer.js.map +1 -1
  22. package/lib/commonjs/version.js +1 -1
  23. package/lib/module/capabilities/configuration/src/brands/checkVisualEligibility.js +13 -11
  24. package/lib/module/capabilities/configuration/src/brands/checkVisualEligibility.js.map +1 -1
  25. package/lib/module/capabilities/configuration/src/brands/createDerivedBrands.js +7 -19
  26. package/lib/module/capabilities/configuration/src/brands/createDerivedBrands.js.map +1 -1
  27. package/lib/module/capabilities/offer-catalog/src/utils/formatUtils.js +35 -20
  28. package/lib/module/capabilities/offer-catalog/src/utils/formatUtils.js.map +1 -1
  29. package/lib/module/capabilities/offer-catalog/src/utils/stats/formatters/annualFee.js +7 -30
  30. package/lib/module/capabilities/offer-catalog/src/utils/stats/formatters/annualFee.js.map +1 -1
  31. package/lib/module/capabilities/offer-catalog/src/utils/stats/formatters/purchaseApr.js +15 -17
  32. package/lib/module/capabilities/offer-catalog/src/utils/stats/formatters/purchaseApr.js.map +1 -1
  33. package/lib/module/capabilities/offer-catalog/src/utils/stats/formatters/recommendedCredit.js +8 -2
  34. package/lib/module/capabilities/offer-catalog/src/utils/stats/formatters/recommendedCredit.js.map +1 -1
  35. package/lib/module/capabilities/offer-catalog/src/utils/stats/index.js +40 -38
  36. package/lib/module/capabilities/offer-catalog/src/utils/stats/index.js.map +1 -1
  37. package/lib/module/capabilities/offers/pipeline/src/sources/ratetables/withDeviceSignals.js +22 -11
  38. package/lib/module/capabilities/offers/pipeline/src/sources/ratetables/withDeviceSignals.js.map +1 -1
  39. package/lib/module/capabilities/ui/elements/src/components/MarkdownText/components.js +22 -10
  40. package/lib/module/capabilities/ui/elements/src/components/MarkdownText/components.js.map +1 -1
  41. package/lib/module/components/DynamicOffers/Render/Offer.js +51 -49
  42. package/lib/module/components/DynamicOffers/Render/Offer.js.map +1 -1
  43. package/lib/module/version.js +1 -1
  44. package/lib/typescript/capabilities/configuration/src/brands/checkVisualEligibility.d.ts.map +1 -1
  45. package/lib/typescript/capabilities/configuration/src/brands/createDerivedBrands.d.ts.map +1 -1
  46. package/lib/typescript/capabilities/offer-catalog/src/utils/formatUtils.d.ts.map +1 -1
  47. package/lib/typescript/capabilities/offer-catalog/src/utils/stats/formatters/annualFee.d.ts.map +1 -1
  48. package/lib/typescript/capabilities/offer-catalog/src/utils/stats/formatters/purchaseApr.d.ts.map +1 -1
  49. package/lib/typescript/capabilities/offer-catalog/src/utils/stats/formatters/recommendedCredit.d.ts.map +1 -1
  50. package/lib/typescript/capabilities/offer-catalog/src/utils/stats/index.d.ts.map +1 -1
  51. package/lib/typescript/capabilities/offers/pipeline/src/sources/ratetables/withDeviceSignals.d.ts +4 -192
  52. package/lib/typescript/capabilities/offers/pipeline/src/sources/ratetables/withDeviceSignals.d.ts.map +1 -1
  53. package/lib/typescript/capabilities/ui/elements/src/components/MarkdownText/components.d.ts.map +1 -1
  54. package/lib/typescript/components/DynamicOffers/Render/Offer.d.ts.map +1 -1
  55. package/lib/typescript/version.d.ts +1 -1
  56. package/package.json +2 -7
  57. package/src/capabilities/configuration/src/brands/checkVisualEligibility.ts +22 -16
  58. package/src/capabilities/configuration/src/brands/createDerivedBrands.ts +10 -23
  59. package/src/capabilities/offer-catalog/src/utils/formatUtils.ts +38 -19
  60. package/src/capabilities/offer-catalog/src/utils/stats/formatters/annualFee.ts +19 -46
  61. package/src/capabilities/offer-catalog/src/utils/stats/formatters/purchaseApr.ts +17 -21
  62. package/src/capabilities/offer-catalog/src/utils/stats/formatters/recommendedCredit.ts +11 -8
  63. package/src/capabilities/offer-catalog/src/utils/stats/index.ts +40 -109
  64. package/src/capabilities/offers/pipeline/src/sources/ratetables/withDeviceSignals.ts +26 -17
  65. package/src/capabilities/ui/elements/src/components/MarkdownText/components.tsx +27 -6
  66. package/src/components/DynamicOffers/Render/Offer.tsx +34 -33
  67. package/src/version.ts +1 -1
@@ -1,5 +1,3 @@
1
- import { match } from "ts-pattern";
2
-
3
1
  import {
4
2
  annualFee,
5
3
  creditBureaus,
@@ -29,113 +27,46 @@ export const statsToElementPropsBuilder = (
29
27
  offer: BaseOffer
30
28
  ): StatElementProps[] =>
31
29
  stats
32
- .map((stat) =>
33
- match(stat)
34
- .with(
35
- {
36
- format: "rangeCurrency",
37
- },
38
- fromRangeCurrencyStat(offer)
39
- )
40
- .with(
41
- {
42
- format: "rangeCurrencyUnabbreviated",
43
- },
44
- fromRangeCurrencyUnabbreviatedStat(offer)
45
- )
46
- .with(
47
- {
48
- format: "BureausStat",
49
- },
50
- creditBureaus(offer)
51
- )
52
- .with(
53
- {
54
- format: "rangePercent",
55
- },
56
- fromRangePercentStat(offer)
57
- )
58
- .with(
59
- {
60
- format: "rangeCurrencyOrBasis",
61
- },
62
- fromRangeCurrencyOrBasisStat(offer)
63
- )
64
- .with(
65
- {
66
- format: "common",
67
- },
68
- fromCommonStat(offer)
69
- )
70
- .with(
71
- {
72
- format: "rangeCurrencyByTime",
73
- },
74
- fromRangeCurrencyByTimeStat(offer)
75
- )
76
- .with(
77
- {
78
- format: "freeTrial",
79
- },
80
- fromFreeTrialStat(offer)
81
- )
82
- .with(
83
- {
84
- format: "monthlyOrAnnualCurrency",
85
- },
86
- fromMonthlyOrAnnualCurrencyStat(offer)
87
- )
88
- .with(
89
- {
90
- format: "boolean",
91
- },
92
- fromBooleanStat(offer)
93
- )
94
- .with({ format: "rangeMonths" }, fromRangeMonthsStat(offer))
95
- .with(
96
- {
97
- format: "listStringWithAnd",
98
- },
99
- fromListStringWithAnd(offer)
100
- )
101
- .with(
102
- {
103
- format: "currency",
104
- },
105
- fromCurrencyStat(offer)
106
- )
107
- .with(
108
- {
109
- format: "percentage",
110
- },
111
- fromPercentageStat(offer)
112
- )
113
- .with(
114
- {
115
- format: "recommendedCredit",
116
- },
117
- recommendedCredit(offer)
118
- )
119
- .with(
120
- {
121
- format: "rewardsDisplay",
122
- },
123
- rewardsDisplay(offer)
124
- )
125
- .with(
126
- {
127
- format: "purchaseApr",
128
- },
129
- purchaseApr(offer)
130
- )
131
- .with(
132
- {
133
- format: "annualFee",
134
- },
135
- annualFee(offer)
136
- )
137
- .exhaustive()
138
- )
30
+ .map((stat): StatElementProps => {
31
+ switch (stat.format) {
32
+ case "rangeCurrency":
33
+ return fromRangeCurrencyStat(offer)(stat);
34
+ case "rangeCurrencyUnabbreviated":
35
+ return fromRangeCurrencyUnabbreviatedStat(offer)(stat);
36
+ case "BureausStat":
37
+ return creditBureaus(offer)(stat);
38
+ case "rangePercent":
39
+ return fromRangePercentStat(offer)(stat);
40
+ case "rangeCurrencyOrBasis":
41
+ return fromRangeCurrencyOrBasisStat(offer)(stat);
42
+ case "common":
43
+ return fromCommonStat(offer)(stat);
44
+ case "rangeCurrencyByTime":
45
+ return fromRangeCurrencyByTimeStat(offer)(stat);
46
+ case "freeTrial":
47
+ return fromFreeTrialStat(offer)(stat);
48
+ case "monthlyOrAnnualCurrency":
49
+ return fromMonthlyOrAnnualCurrencyStat(offer)(stat);
50
+ case "boolean":
51
+ return fromBooleanStat(offer)(stat);
52
+ case "rangeMonths":
53
+ return fromRangeMonthsStat(offer)(stat);
54
+ case "listStringWithAnd":
55
+ return fromListStringWithAnd(offer)(stat);
56
+ case "currency":
57
+ return fromCurrencyStat(offer)(stat);
58
+ case "percentage":
59
+ return fromPercentageStat(offer)(stat);
60
+ case "recommendedCredit":
61
+ return recommendedCredit(offer)(stat);
62
+ case "rewardsDisplay":
63
+ return rewardsDisplay(offer)(stat);
64
+ case "purchaseApr":
65
+ return purchaseApr(offer)(stat);
66
+ case "annualFee":
67
+ return annualFee(offer)(stat);
68
+ }
69
+ })
139
70
  .filter((stat) => stat !== null);
140
71
 
141
72
  export type { Stat, StatElementProps } from "./types";
@@ -1,4 +1,3 @@
1
- import defu from "defu";
2
1
  import { get, mapValues } from "radash";
3
2
  import { createDerivedBrands } from "../../../../../configuration/src/brands/createDerivedBrands";
4
3
  import type { CnfContext } from "../../../../../core/src/system/cnfContext/CnfContext";
@@ -63,21 +62,31 @@ export function withDeviceSignals<
63
62
  cnfEnvironment,
64
63
  };
65
64
 
66
- return defu(payload, {
67
- /**
68
- * The leads API required device ID's be in the UUID format. If the string
69
- * we receive here is not in the expected format, we will create an error
70
- * passing it to the API.
71
- */
65
+ // all clientTag values must be arrays of strings
66
+ const toStringArray = (value: unknown): string[] =>
67
+ Array.isArray(value) ? value.map(String) : [String(value)];
68
+
69
+ const defaultClientTags = mapValues(clientTags, toStringArray);
70
+ const payloadClientTags = mapValues(
71
+ (payload.clientTags ?? {}) as Record<string, unknown>,
72
+ toStringArray
73
+ );
74
+
75
+ const mergedClientTags: Record<string, string[]> = { ...defaultClientTags };
76
+ for (const [key, value] of Object.entries(payloadClientTags)) {
77
+ const existing = mergedClientTags[key];
78
+ mergedClientTags[key] = existing ? [...value, ...existing] : value;
79
+ }
80
+
81
+ /**
82
+ * The leads API requires device IDs be in the UUID format. If the string
83
+ * we receive here is not in the expected format, we omit it so the API can
84
+ * reject the request explicitly.
85
+ */
86
+ return {
72
87
  deviceId: isUUIDv4(maybeDeviceId) ? maybeDeviceId : undefined,
73
- sessionInformation: {
74
- ipAddress,
75
- userAgent,
76
- },
77
- clientTags: mapValues(
78
- clientTags,
79
- // all values must be arrays of strings
80
- (value) => (Array.isArray(value) ? value.map(String) : [String(value)])
81
- ),
82
- });
88
+ sessionInformation: { ipAddress, userAgent },
89
+ ...payload,
90
+ clientTags: mergedClientTags,
91
+ };
83
92
  }
@@ -7,12 +7,19 @@ import {
7
7
  type RenderRules,
8
8
  } from "react-native-markdown-display";
9
9
  import Text, {
10
+ type TextProps,
10
11
  type TextWeight,
11
12
  type Variant,
12
13
  } from "../../../../../../components/Text";
13
14
  import type { ThemeColors } from "../../../../../../context/ThemeProvider";
14
15
 
15
- const BoldText = ({ children }: { children: React.ReactNode }) => {
16
+ const BoldText = ({
17
+ children,
18
+ testID,
19
+ }: {
20
+ children: React.ReactNode;
21
+ testID: TextProps["testID"];
22
+ }) => {
16
23
  const processChildren = (_children: React.ReactNode) => {
17
24
  return React.Children.map(_children, (child) => {
18
25
  if (typeof child === "string") {
@@ -20,7 +27,6 @@ const BoldText = ({ children }: { children: React.ReactNode }) => {
20
27
  }
21
28
 
22
29
  if (React.isValidElement(child) && child.type === Text) {
23
- // Use a properly typed props object
24
30
  const newProps = {
25
31
  weight: "bold" as TextWeight,
26
32
  style: child.props.style,
@@ -30,13 +36,21 @@ const BoldText = ({ children }: { children: React.ReactNode }) => {
30
36
  return child;
31
37
  });
32
38
  };
33
- return <>{processChildren(children)}</>;
39
+ return <Text testID={testID}>{processChildren(children)}</Text>;
34
40
  };
35
41
 
36
42
  // Helper to create text variants
37
43
  const createTextVariant =
38
- (props: any) => (_node: ASTNode, children: React.ReactNode) => {
39
- return <Text {...props}>{children}</Text>;
44
+ (props: TextProps) => (node: ASTNode, children: React.ReactNode) => {
45
+ return (
46
+ <Text
47
+ key={node.key || `${node.type}-${node.index}`}
48
+ {...props}
49
+ testID={`${node.type}-${node.index}`}
50
+ >
51
+ {children}
52
+ </Text>
53
+ );
40
54
  };
41
55
 
42
56
  export const createMarkdownComponents = ({
@@ -73,6 +87,7 @@ export const createMarkdownComponents = ({
73
87
  color={color}
74
88
  numberOfLines={numberOfLines}
75
89
  style={styles.bulletList}
90
+ testID={`${node.type}-${node.index}`}
76
91
  >
77
92
  {children}
78
93
  </Text>
@@ -101,6 +116,7 @@ export const createMarkdownComponents = ({
101
116
  color={color}
102
117
  style={styles.linkText}
103
118
  onPress={() => openUrl(node.attributes.href || "")}
119
+ testID={`${node.type}-${node.index}`}
104
120
  >
105
121
  {children}
106
122
  </Text>
@@ -136,6 +152,7 @@ export const createMarkdownComponents = ({
136
152
  variant={variant || "body-3"}
137
153
  weight={weight}
138
154
  color={color}
155
+ testID={`${node.type}-${node.index}`}
139
156
  >
140
157
  <Text variant={"body-1"}>{prefix}• </Text>
141
158
  {children}
@@ -151,6 +168,7 @@ export const createMarkdownComponents = ({
151
168
  variant={variant}
152
169
  weight={weight}
153
170
  color={color}
171
+ testID={`${node.type}-${node.index}`}
154
172
  >
155
173
  {children}
156
174
  </Text>
@@ -158,7 +176,10 @@ export const createMarkdownComponents = ({
158
176
  },
159
177
 
160
178
  strong: (node, children) => (
161
- <BoldText key={node.key || `${node.type}-${node.index}`}>
179
+ <BoldText
180
+ key={node.key || `${node.type}-${node.index}`}
181
+ testID={`${node.type}-${node.index}`}
182
+ >
162
183
  {children}
163
184
  </BoldText>
164
185
  ),
@@ -1,7 +1,5 @@
1
1
  import React, { Fragment } from "react";
2
2
 
3
- import { match } from "ts-pattern";
4
-
5
3
  import type { ProductTypeBuilder } from "../../../builder";
6
4
  import {
7
5
  DefaultOfferCard,
@@ -58,63 +56,66 @@ export const Offer = ({
58
56
  return <></>;
59
57
  }
60
58
 
61
- return (
62
- <Fragment key={`${offerIndex}-${offer.uuid}`}>
63
- {match(builder)
64
- .with({ layout: "defaultOfferCard" }, (layout) => (
59
+ const renderCard = () => {
60
+ if (!builder) {
61
+ if (!fallbackTemplate) return <></>;
62
+ const FallbackTemplate = fallbackTemplate;
63
+ return (
64
+ <FallbackTemplate
65
+ showCardBorder={showCardBorder}
66
+ offerIndex={offerIndex}
67
+ key={`${offerIndex}-${offer.uuid}`}
68
+ offer={offer}
69
+ showProductTypeLabel={showProductTypeLabel}
70
+ fullCardWidth={fullCardWidth}
71
+ isHorizontalScroll={isHorizontalScroll}
72
+ />
73
+ );
74
+ }
75
+ switch (builder.layout) {
76
+ case "defaultOfferCard":
77
+ return (
65
78
  <DefaultOfferCard
66
79
  offerIndex={offerIndex}
67
80
  key={`${offerIndex}-${offer.uuid}`}
68
81
  offer={offer}
69
- productTypeBuilder={layout}
82
+ productTypeBuilder={builder}
70
83
  showCardBorder={showCardBorder}
71
84
  showProductTypeLabel={showProductTypeLabel}
72
85
  fullCardWidth={fullCardWidth}
73
86
  isHorizontalScroll={isHorizontalScroll}
74
87
  />
75
- ))
76
- .with({ layout: "creditCardOfferCard" }, (layout) => (
88
+ );
89
+ case "creditCardOfferCard":
90
+ return (
77
91
  <CreditCardOfferCard
78
92
  offerIndex={offerIndex}
79
93
  key={`${offerIndex}-${offer.uuid}`}
80
94
  offer={offer}
81
- productTypeBuilder={layout}
95
+ productTypeBuilder={builder}
82
96
  showCardBorder={showCardBorder}
83
97
  showProductTypeLabel={showProductTypeLabel}
84
98
  fullCardWidth={fullCardWidth}
85
99
  isHorizontalScroll={isHorizontalScroll}
86
100
  />
87
- ))
88
- .with({ layout: "headlineWithDescriptionCard" }, (layout) => (
101
+ );
102
+ case "headlineWithDescriptionCard":
103
+ return (
89
104
  <HeadlineWithDescriptionCard
90
105
  offerIndex={offerIndex}
91
106
  key={`${offerIndex}-${offer.uuid}`}
92
107
  offer={offer}
93
- productTypeBuilder={layout}
108
+ productTypeBuilder={builder}
94
109
  showCardBorder={showCardBorder}
95
110
  showProductTypeLabel={showProductTypeLabel}
96
111
  fullCardWidth={fullCardWidth}
97
112
  isHorizontalScroll={isHorizontalScroll}
98
113
  />
99
- ))
100
- .with(undefined, () => {
101
- if (!fallbackTemplate) {
102
- return <></>;
103
- }
104
- const FallbackTemplate = fallbackTemplate;
105
- return (
106
- <FallbackTemplate
107
- showCardBorder={showCardBorder}
108
- offerIndex={offerIndex}
109
- key={`${offerIndex}-${offer.uuid}`}
110
- offer={offer}
111
- showProductTypeLabel={showProductTypeLabel}
112
- fullCardWidth={fullCardWidth}
113
- isHorizontalScroll={isHorizontalScroll}
114
- />
115
- );
116
- })
117
- .exhaustive()}
118
- </Fragment>
114
+ );
115
+ }
116
+ };
117
+
118
+ return (
119
+ <Fragment key={`${offerIndex}-${offer.uuid}`}>{renderCard()}</Fragment>
119
120
  );
120
121
  });
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Version is kept in sync with package.json via the sync-version script
2
- export const VERSION = "1.10.1";
2
+ export const VERSION = "1.10.2";