@applicaster/zapp-react-native-utils 15.1.7-alpha.1530511842 → 15.1.8

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.
@@ -0,0 +1,61 @@
1
+ import { decorateFeed } from "../feedDecorator";
2
+
3
+ const preferenceFeed = (selectMode: string) =>
4
+ ({
5
+ id: "agree-component",
6
+ title: "I agree to the terms",
7
+ type: { value: "feed" },
8
+ extensions: {
9
+ role: "preference_editor",
10
+ preference_editor_options: {
11
+ key: "agree",
12
+ scope: "screen",
13
+ select_mode: selectMode,
14
+ },
15
+ },
16
+ entry: [
17
+ {
18
+ id: "I agree to the terms-agree",
19
+ title: "I agree to the terms",
20
+ type: { value: "action" },
21
+ extensions: { tag: "true" },
22
+ },
23
+ ],
24
+ }) as unknown as ZappFeed;
25
+
26
+ describe("decorateFeed", () => {
27
+ it("decorates single select feeds with screenSetVariable", () => {
28
+ const decorated = decorateFeed(preferenceFeed("single"));
29
+
30
+ expect(decorated.extensions.behavior).toEqual(
31
+ expect.objectContaining({
32
+ select_mode: "single",
33
+ current_selection: "@{screen/agree}",
34
+ })
35
+ );
36
+
37
+ expect(decorated.entry[0].extensions.tap_actions.actions[0].type).toBe(
38
+ "screenSetVariable"
39
+ );
40
+ });
41
+
42
+ it("decorates multi select feeds with screenToggleFlag", () => {
43
+ const decorated = decorateFeed(preferenceFeed("multi"));
44
+
45
+ expect(decorated.extensions.behavior.select_mode).toBe("multi");
46
+
47
+ expect(decorated.entry[0].extensions.tap_actions.actions[0].type).toBe(
48
+ "screenToggleFlag"
49
+ );
50
+ });
51
+
52
+ it("leaves a feed without the preference_editor role untouched", () => {
53
+ const feed = preferenceFeed("single");
54
+ feed.extensions.role = undefined;
55
+
56
+ const decorated = decorateFeed(feed);
57
+
58
+ expect(decorated.extensions.behavior).toBeUndefined();
59
+ expect(decorated.entry[0].extensions.tap_actions).toBeUndefined();
60
+ });
61
+ });
@@ -159,13 +159,13 @@ export const decorateFeed = (feed: ZappFeed) => {
159
159
 
160
160
  const decoratedFeed = R.clone(feed);
161
161
 
162
- const isSingleSelect =
163
- (feed.extensions?.["preference_editor_options"]?.select_mode ||
164
- feed.extensions?.["behavior"]?.select_mode) === "single";
162
+ const selectMode =
163
+ feed.extensions?.preference_editor_options?.select_mode ||
164
+ feed.extensions?.behavior?.select_mode;
165
165
 
166
- if (isSingleSelect) {
166
+ if (selectMode === "single") {
167
167
  return makeSingleSelect(feed, key, decoratedFeed);
168
- } else {
169
- return makeMultiSelect(feed, key, decoratedFeed);
170
168
  }
169
+
170
+ return makeMultiSelect(feed, key, decoratedFeed);
171
171
  };
@@ -65,11 +65,38 @@ export const isEmptyOrNil = (value: any): boolean =>
65
65
  */
66
66
  export const getLabel = (dataKeyValue, customDataKeyValue) => (entry) => {
67
67
  const label = getKeyForLabel(dataKeyValue, customDataKeyValue);
68
- const isPath = label && R.length(label) > 0;
69
- const fallback = isEmptyOrNil(label) ? "" : R.head(label);
68
+ const isPath = label && label.length > 0;
69
+
70
+ // An unresolved key is rendered as-is, because a data key is allowed to be a
71
+ // literal label ("More") rather than a path. Fall back to the whole key
72
+ // instead of its first segment: "extensions.section" reads as an unresolved
73
+ // path, while "extensions" reads as a legitimate label and hides the problem.
74
+ const fallback = isEmptyOrNil(label) ? "" : label.join(".");
70
75
 
71
76
  try {
72
- return isPath ? R.pathOr(fallback, label, entry) : fallback;
77
+ if (!isPath) {
78
+ return fallback;
79
+ }
80
+
81
+ const resolved = label.reduce(
82
+ (value, key) => (value == null ? undefined : value[key]),
83
+ entry
84
+ );
85
+
86
+ if (isNotNil(resolved)) {
87
+ return resolved;
88
+ }
89
+
90
+ // A multi-segment key is unambiguously a path, so failing to resolve it is
91
+ // a misconfiguration rather than someone typing a literal label.
92
+ if (label.length > 1) {
93
+ cellUtilsLogger.warning({
94
+ message: `getLabel: data key "${fallback}" was not found on the entry, rendering the key itself`,
95
+ data: { dataKeyValue, customDataKeyValue, entryId: entry?.id },
96
+ });
97
+ }
98
+
99
+ return fallback;
73
100
  } catch (error) {
74
101
  cellUtilsLogger.warning({
75
102
  data: { error, dataKeyValue, customDataKeyValue },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-utils",
3
- "version": "15.1.7-alpha.1530511842",
3
+ "version": "15.1.8",
4
4
  "description": "Applicaster Zapp React Native utilities package",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "homepage": "https://github.com/applicaster/quickbrick#readme",
29
29
  "dependencies": {
30
- "@applicaster/applicaster-types": "15.1.7-alpha.1530511842",
30
+ "@applicaster/applicaster-types": "15.1.8",
31
31
  "buffer": "^5.2.1",
32
32
  "camelize": "^1.0.0",
33
33
  "dayjs": "^1.11.10",