@player-ui/player 0.8.0--canary.307.9621 → 0.8.0-next.0

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 (214) hide show
  1. package/dist/Player.native.js +11630 -0
  2. package/dist/Player.native.js.map +1 -0
  3. package/dist/cjs/index.cjs +5626 -0
  4. package/dist/cjs/index.cjs.map +1 -0
  5. package/dist/{index.esm.js → index.legacy-esm.js} +2044 -1667
  6. package/dist/{index.cjs.js → index.mjs} +2052 -1761
  7. package/dist/index.mjs.map +1 -0
  8. package/package.json +29 -63
  9. package/src/__tests__/data.test.ts +498 -0
  10. package/src/__tests__/flow.test.ts +312 -0
  11. package/src/__tests__/helpers/action-exp.plugin.ts +22 -0
  12. package/src/__tests__/helpers/actions.flow.ts +67 -0
  13. package/src/__tests__/helpers/binding.plugin.ts +125 -0
  14. package/src/__tests__/helpers/expression.plugin.ts +88 -0
  15. package/src/__tests__/helpers/transform-plugin.ts +19 -0
  16. package/src/__tests__/helpers/validation.flow.ts +56 -0
  17. package/src/__tests__/player.test.ts +597 -0
  18. package/src/__tests__/string-resolver.test.ts +186 -0
  19. package/src/__tests__/validation.test.ts +3555 -0
  20. package/src/__tests__/view.test.ts +715 -0
  21. package/src/binding/__tests__/binding.test.ts +113 -0
  22. package/src/binding/__tests__/index.test.ts +208 -0
  23. package/src/binding/__tests__/resolver.test.ts +83 -0
  24. package/src/binding/binding.ts +6 -6
  25. package/src/binding/index.ts +34 -34
  26. package/src/binding/resolver.ts +19 -19
  27. package/src/binding/utils.ts +7 -7
  28. package/src/binding-grammar/__tests__/parser.test.ts +64 -0
  29. package/src/binding-grammar/__tests__/test-utils/ast-cases.ts +198 -0
  30. package/src/binding-grammar/__tests__/test-utils/perf-test.ts +66 -0
  31. package/src/binding-grammar/ast.ts +11 -11
  32. package/src/binding-grammar/custom/index.ts +19 -22
  33. package/src/binding-grammar/ebnf/index.ts +20 -21
  34. package/src/binding-grammar/ebnf/types.ts +13 -13
  35. package/src/binding-grammar/index.ts +4 -4
  36. package/src/binding-grammar/parsimmon/index.ts +14 -14
  37. package/src/controllers/constants/__tests__/index.test.ts +106 -0
  38. package/src/controllers/constants/index.ts +3 -3
  39. package/src/controllers/constants/utils.ts +4 -4
  40. package/src/controllers/data/controller.ts +22 -22
  41. package/src/controllers/data/index.ts +1 -1
  42. package/src/controllers/data/utils.ts +7 -7
  43. package/src/controllers/flow/__tests__/controller.test.ts +195 -0
  44. package/src/controllers/flow/__tests__/flow.test.ts +381 -0
  45. package/src/controllers/flow/controller.ts +13 -13
  46. package/src/controllers/flow/flow.ts +23 -23
  47. package/src/controllers/flow/index.ts +2 -2
  48. package/src/controllers/index.ts +5 -5
  49. package/src/controllers/validation/binding-tracker.ts +71 -59
  50. package/src/controllers/validation/controller.ts +104 -104
  51. package/src/controllers/validation/index.ts +2 -2
  52. package/src/controllers/view/asset-transform.ts +20 -20
  53. package/src/controllers/view/controller.ts +27 -27
  54. package/src/controllers/view/index.ts +4 -4
  55. package/src/controllers/view/store.ts +3 -3
  56. package/src/controllers/view/types.ts +7 -7
  57. package/src/data/__tests__/__snapshots__/dependency-tracker.test.ts.snap +64 -0
  58. package/src/data/__tests__/dependency-tracker.test.ts +146 -0
  59. package/src/data/__tests__/local-model.test.ts +46 -0
  60. package/src/data/__tests__/model.test.ts +78 -0
  61. package/src/data/dependency-tracker.ts +16 -16
  62. package/src/data/index.ts +4 -4
  63. package/src/data/local-model.ts +6 -6
  64. package/src/data/model.ts +17 -17
  65. package/src/data/noop-model.ts +1 -1
  66. package/src/expressions/__tests__/__snapshots__/parser.test.ts.snap +854 -0
  67. package/src/expressions/__tests__/evaluator-functions.test.ts +47 -0
  68. package/src/expressions/__tests__/evaluator.test.ts +410 -0
  69. package/src/expressions/__tests__/parser.test.ts +115 -0
  70. package/src/expressions/__tests__/utils.test.ts +44 -0
  71. package/src/expressions/evaluator-functions.ts +6 -6
  72. package/src/expressions/evaluator.ts +71 -67
  73. package/src/expressions/index.ts +4 -4
  74. package/src/expressions/parser.ts +102 -105
  75. package/src/expressions/types.ts +29 -21
  76. package/src/expressions/utils.ts +32 -21
  77. package/src/index.ts +13 -13
  78. package/src/logger/__tests__/consoleLogger.test.ts +46 -0
  79. package/src/logger/__tests__/noopLogger.test.ts +13 -0
  80. package/src/logger/__tests__/proxyLogger.test.ts +31 -0
  81. package/src/logger/__tests__/tapableLogger.test.ts +41 -0
  82. package/src/logger/consoleLogger.ts +9 -9
  83. package/src/logger/index.ts +5 -5
  84. package/src/logger/noopLogger.ts +1 -1
  85. package/src/logger/proxyLogger.ts +6 -6
  86. package/src/logger/tapableLogger.ts +7 -7
  87. package/src/logger/types.ts +2 -2
  88. package/src/player.ts +60 -58
  89. package/src/plugins/default-exp-plugin.ts +10 -10
  90. package/src/plugins/default-view-plugin.ts +29 -0
  91. package/src/plugins/flow-exp-plugin.ts +6 -6
  92. package/src/schema/__tests__/schema.test.ts +243 -0
  93. package/src/schema/index.ts +2 -2
  94. package/src/schema/schema.ts +24 -24
  95. package/src/schema/types.ts +4 -4
  96. package/src/string-resolver/__tests__/index.test.ts +361 -0
  97. package/src/string-resolver/index.ts +17 -17
  98. package/src/types.ts +17 -17
  99. package/src/utils/__tests__/replaceParams.test.ts +33 -0
  100. package/src/utils/index.ts +1 -1
  101. package/src/utils/replaceParams.ts +1 -1
  102. package/src/validator/__tests__/binding-map-splice.test.ts +53 -0
  103. package/src/validator/__tests__/validation-middleware.test.ts +127 -0
  104. package/src/validator/binding-map-splice.ts +5 -5
  105. package/src/validator/index.ts +4 -4
  106. package/src/validator/registry.ts +1 -1
  107. package/src/validator/types.ts +13 -13
  108. package/src/validator/validation-middleware.ts +15 -15
  109. package/src/view/__tests__/view.immutable.test.ts +269 -0
  110. package/src/view/__tests__/view.test.ts +959 -0
  111. package/src/view/builder/index.test.ts +69 -0
  112. package/src/view/builder/index.ts +3 -3
  113. package/src/view/index.ts +5 -5
  114. package/src/view/parser/__tests__/__snapshots__/parser.test.ts.snap +394 -0
  115. package/src/view/parser/__tests__/parser.test.ts +264 -0
  116. package/src/view/parser/index.ts +43 -33
  117. package/src/view/parser/types.ts +11 -11
  118. package/src/view/parser/utils.ts +5 -5
  119. package/src/view/plugins/__tests__/__snapshots__/template.test.ts.snap +278 -0
  120. package/src/view/plugins/__tests__/applicability.test.ts +265 -0
  121. package/src/view/plugins/__tests__/string.test.ts +122 -0
  122. package/src/view/plugins/__tests__/template.test.ts +724 -0
  123. package/src/view/plugins/applicability.ts +19 -19
  124. package/src/view/plugins/index.ts +4 -5
  125. package/src/view/plugins/options.ts +1 -1
  126. package/src/view/plugins/string-resolver.ts +22 -22
  127. package/src/view/plugins/switch.ts +22 -23
  128. package/src/view/plugins/template-plugin.ts +26 -27
  129. package/src/view/resolver/__tests__/dependencies.test.ts +321 -0
  130. package/src/view/resolver/__tests__/edgecases.test.ts +626 -0
  131. package/src/view/resolver/index.ts +42 -42
  132. package/src/view/resolver/types.ts +21 -20
  133. package/src/view/resolver/utils.ts +9 -9
  134. package/src/view/view.ts +32 -22
  135. package/types/binding/binding.d.ts +50 -0
  136. package/types/binding/index.d.ts +29 -0
  137. package/types/binding/resolver.d.ts +26 -0
  138. package/types/binding/utils.d.ts +12 -0
  139. package/types/binding-grammar/ast.d.ts +67 -0
  140. package/types/binding-grammar/custom/index.d.ts +4 -0
  141. package/types/binding-grammar/ebnf/index.d.ts +4 -0
  142. package/types/binding-grammar/ebnf/types.d.ts +75 -0
  143. package/types/binding-grammar/index.d.ts +5 -0
  144. package/types/binding-grammar/parsimmon/index.d.ts +4 -0
  145. package/types/controllers/constants/index.d.ts +45 -0
  146. package/types/controllers/constants/utils.d.ts +6 -0
  147. package/types/controllers/data/controller.d.ts +45 -0
  148. package/types/controllers/data/index.d.ts +2 -0
  149. package/types/controllers/data/utils.d.ts +14 -0
  150. package/types/controllers/flow/controller.d.ts +25 -0
  151. package/types/controllers/flow/flow.d.ts +50 -0
  152. package/types/controllers/flow/index.d.ts +3 -0
  153. package/types/controllers/index.d.ts +6 -0
  154. package/types/controllers/validation/binding-tracker.d.ts +32 -0
  155. package/types/controllers/validation/controller.d.ts +151 -0
  156. package/types/controllers/validation/index.d.ts +3 -0
  157. package/types/controllers/view/asset-transform.d.ts +19 -0
  158. package/types/controllers/view/controller.d.ts +37 -0
  159. package/types/controllers/view/index.d.ts +5 -0
  160. package/types/controllers/view/store.d.ts +20 -0
  161. package/types/controllers/view/types.d.ts +16 -0
  162. package/types/data/dependency-tracker.d.ts +49 -0
  163. package/types/data/index.d.ts +5 -0
  164. package/types/data/local-model.d.ts +16 -0
  165. package/types/data/model.d.ts +86 -0
  166. package/types/data/noop-model.d.ts +13 -0
  167. package/types/expressions/evaluator-functions.d.ts +15 -0
  168. package/types/expressions/evaluator.d.ts +52 -0
  169. package/types/expressions/index.d.ts +5 -0
  170. package/types/expressions/parser.d.ts +10 -0
  171. package/types/expressions/types.d.ts +144 -0
  172. package/types/expressions/utils.d.ts +12 -0
  173. package/types/index.d.ts +14 -0
  174. package/types/logger/consoleLogger.d.ts +17 -0
  175. package/types/logger/index.d.ts +6 -0
  176. package/types/logger/noopLogger.d.ts +10 -0
  177. package/types/logger/proxyLogger.d.ts +15 -0
  178. package/types/logger/tapableLogger.d.ts +23 -0
  179. package/types/logger/types.d.ts +6 -0
  180. package/types/player.d.ts +101 -0
  181. package/types/plugins/default-exp-plugin.d.ts +9 -0
  182. package/types/plugins/default-view-plugin.d.ts +9 -0
  183. package/types/plugins/flow-exp-plugin.d.ts +11 -0
  184. package/types/schema/index.d.ts +3 -0
  185. package/types/schema/schema.d.ts +36 -0
  186. package/types/schema/types.d.ts +38 -0
  187. package/types/string-resolver/index.d.ts +30 -0
  188. package/types/types.d.ts +73 -0
  189. package/types/utils/index.d.ts +2 -0
  190. package/types/utils/replaceParams.d.ts +9 -0
  191. package/types/validator/binding-map-splice.d.ts +10 -0
  192. package/types/validator/index.d.ts +5 -0
  193. package/types/validator/registry.d.ts +11 -0
  194. package/types/validator/types.d.ts +53 -0
  195. package/types/validator/validation-middleware.d.ts +36 -0
  196. package/types/view/builder/index.d.ts +35 -0
  197. package/types/view/index.d.ts +6 -0
  198. package/types/view/parser/index.d.ts +52 -0
  199. package/types/view/parser/types.d.ts +109 -0
  200. package/types/view/parser/utils.d.ts +6 -0
  201. package/types/view/plugins/applicability.d.ts +10 -0
  202. package/types/view/plugins/index.d.ts +5 -0
  203. package/types/view/plugins/options.d.ts +4 -0
  204. package/types/view/plugins/string-resolver.d.ts +13 -0
  205. package/types/view/plugins/switch.d.ts +14 -0
  206. package/types/view/plugins/template-plugin.d.ts +33 -0
  207. package/types/view/resolver/index.d.ts +73 -0
  208. package/types/view/resolver/types.d.ts +129 -0
  209. package/types/view/resolver/utils.d.ts +11 -0
  210. package/types/view/view.d.ts +37 -0
  211. package/dist/index.d.ts +0 -1814
  212. package/dist/player.dev.js +0 -11472
  213. package/dist/player.prod.js +0 -2
  214. package/src/view/plugins/plugin.ts +0 -21
@@ -0,0 +1,264 @@
1
+ import { describe, expect, beforeEach, test } from "vitest";
2
+ import { BindingParser } from "../../../binding";
3
+ import { LocalModel, withParser } from "../../../data";
4
+ import { SchemaController } from "../../../schema";
5
+ import { NodeType, Parser } from "../index";
6
+ import { SwitchPlugin, ApplicabilityPlugin, TemplatePlugin } from "../..";
7
+ import type { Options } from "../../plugins/options";
8
+ import { ExpressionEvaluator } from "../../../expressions";
9
+ import type { DataModelWithParser } from "../../../data";
10
+
11
+ const parseBinding = new BindingParser().parse;
12
+ describe("generates the correct AST", () => {
13
+ let model: DataModelWithParser;
14
+ let expressionEvaluator: ExpressionEvaluator;
15
+ let options: Options;
16
+ let parser: Parser;
17
+
18
+ beforeEach(() => {
19
+ model = withParser(new LocalModel(), parseBinding);
20
+ expressionEvaluator = new ExpressionEvaluator({
21
+ model,
22
+ });
23
+ parser = new Parser();
24
+ options = {
25
+ evaluate: expressionEvaluator.evaluate,
26
+ schema: new SchemaController(),
27
+ data: {
28
+ format: (binding, val) => val,
29
+ formatValue: (val) => val,
30
+ model,
31
+ },
32
+ };
33
+ new TemplatePlugin(options).applyParser(parser);
34
+ new ApplicabilityPlugin().applyParser(parser);
35
+ new SwitchPlugin(options).applyParser(parser);
36
+ });
37
+
38
+ test("works with basic objects", () => {
39
+ expect(parser.parseObject({ foo: "bar" })).toStrictEqual({
40
+ type: NodeType.Value,
41
+ value: {
42
+ foo: "bar",
43
+ },
44
+ });
45
+ });
46
+
47
+ test("works with objects that have symbols", () => {
48
+ const testSymbol = Symbol("foo");
49
+ expect(parser.parseObject({ [testSymbol]: "bar" })).toStrictEqual({
50
+ type: NodeType.Value,
51
+ value: {
52
+ [testSymbol]: "bar",
53
+ },
54
+ });
55
+ });
56
+
57
+ test("works with applicability things", () => {
58
+ expect(
59
+ parser.parseObject({ foo: "bar", applicability: "{{baz}}" }),
60
+ ).toMatchSnapshot();
61
+
62
+ expect(
63
+ parser.parseObject({
64
+ asset: {
65
+ values: [
66
+ {
67
+ applicability: "{{foo}}",
68
+ value: "foo",
69
+ },
70
+ {
71
+ value: "bar",
72
+ },
73
+ ],
74
+ },
75
+ }),
76
+ ).toMatchSnapshot();
77
+
78
+ expect(
79
+ parser.parseObject({
80
+ asset: {
81
+ someProp: {
82
+ applicability: "{{foo}}",
83
+ label: {
84
+ value: "label",
85
+ },
86
+ description: {
87
+ value: "description",
88
+ },
89
+ },
90
+ },
91
+ }),
92
+ ).toMatchSnapshot();
93
+
94
+ expect(
95
+ parser.parseObject({
96
+ asset: {
97
+ someProp: {
98
+ asset: {
99
+ applicability: "{{foo}}",
100
+ type: "someAsset",
101
+ },
102
+ },
103
+ },
104
+ }),
105
+ ).toMatchSnapshot();
106
+ });
107
+
108
+ test("parses an object", () => {
109
+ expect(parser.parseObject({ asset: { type: "bar" } })).toMatchSnapshot();
110
+ });
111
+
112
+ test("parses an exp array", () => {
113
+ expect(
114
+ parser.parseObject(
115
+ {
116
+ id: "foo",
117
+ type: "action",
118
+ exp: ['{{please}} = "work"'],
119
+ },
120
+ NodeType.Asset,
121
+ ),
122
+ ).toMatchSnapshot();
123
+ });
124
+
125
+ test("keeps null values when parsing object", () => {
126
+ expect(parser.parseObject({ foo: "bar", baz: null })).toStrictEqual({
127
+ type: NodeType.Value,
128
+ value: {
129
+ foo: "bar",
130
+ baz: null,
131
+ },
132
+ });
133
+ });
134
+ });
135
+
136
+ describe("parseView", () => {
137
+ let model: DataModelWithParser;
138
+ let expressionEvaluator: ExpressionEvaluator;
139
+ let options: Options;
140
+ let parser: Parser;
141
+
142
+ beforeEach(() => {
143
+ model = withParser(new LocalModel(), parseBinding);
144
+ expressionEvaluator = new ExpressionEvaluator({
145
+ model,
146
+ });
147
+ parser = new Parser();
148
+ options = {
149
+ evaluate: expressionEvaluator.evaluate,
150
+ schema: new SchemaController(),
151
+ data: {
152
+ format: (binding, val) => val,
153
+ formatValue: (val) => val,
154
+ model,
155
+ },
156
+ };
157
+ new TemplatePlugin(options).applyParser(parser);
158
+ new ApplicabilityPlugin().applyParser(parser);
159
+ new SwitchPlugin(options).applyParser(parser);
160
+ });
161
+
162
+ test("parses a simple view", () => {
163
+ expect(
164
+ parser.parseView({
165
+ id: "foo-view",
166
+ type: "viewtype",
167
+ fields: {
168
+ asset: {
169
+ id: "foo-asset",
170
+ type: "collection",
171
+ values: [
172
+ {
173
+ asset: {
174
+ id: "text-asset",
175
+ type: "text",
176
+ value: "bar",
177
+ },
178
+ },
179
+ {
180
+ asset: {
181
+ applicability: "foo.bar",
182
+ id: "input-asset",
183
+ type: "input",
184
+ },
185
+ },
186
+ {},
187
+ ],
188
+ },
189
+ },
190
+ } as any),
191
+ ).toMatchSnapshot();
192
+ });
193
+ });
194
+
195
+ describe("generates the correct AST when using switch plugin", () => {
196
+ const toughStaticSwitchView = {
197
+ id: "toughView",
198
+ type: "view",
199
+ title: {
200
+ staticSwitch: [
201
+ {
202
+ case: "'true'",
203
+ asset: {
204
+ id: "businessprofile-tile-screen-yoy-subtitle",
205
+ type: "text",
206
+ value:
207
+ "If it's changed since last year, let us know. Feel free to pick more than one.",
208
+ },
209
+ },
210
+ ],
211
+ },
212
+ };
213
+
214
+ const toughStaticSwitchMultiNodeView = {
215
+ id: "toughView",
216
+ type: "view",
217
+ title: {
218
+ asset: {
219
+ id: "someMultiNode",
220
+ type: "type",
221
+ values: [
222
+ {
223
+ staticSwitch: [
224
+ {
225
+ case: "'true'",
226
+ asset: {
227
+ id: "businessprofile-tile-screen-yoy-subtitle-1",
228
+ type: "text",
229
+ value:
230
+ "If it's changed since last year, let us know. Feel free to pick more than one.",
231
+ },
232
+ },
233
+ ],
234
+ },
235
+ {
236
+ asset: {
237
+ id: "businessprofile-tile-screen-yoy-subtitle-2",
238
+ type: "text",
239
+ value: "More text",
240
+ },
241
+ },
242
+ ],
243
+ },
244
+ },
245
+ };
246
+
247
+ const switchPlugin = new SwitchPlugin({
248
+ evaluate: () => {
249
+ return true;
250
+ },
251
+ } as any);
252
+ const parser = new Parser();
253
+ switchPlugin.applyParser(parser);
254
+
255
+ test("works with asset wrapped objects", () => {
256
+ expect(parser.parseObject(toughStaticSwitchView)).toMatchSnapshot();
257
+ });
258
+
259
+ test("works with objects in a multiNode", () => {
260
+ expect(
261
+ parser.parseObject(toughStaticSwitchMultiNodeView),
262
+ ).toMatchSnapshot();
263
+ });
264
+ });
@@ -1,12 +1,12 @@
1
- import { omit, setIn } from 'timm';
2
- import { SyncBailHook, SyncWaterfallHook } from 'tapable-ts';
3
- import type { Template } from '@player-ui/types';
4
- import type { AnyAssetType, Node } from './types';
5
- import { NodeType } from './types';
6
- import { getNodeID, hasAsync } from './utils';
1
+ import { omit, setIn } from "timm";
2
+ import { SyncBailHook, SyncWaterfallHook } from "tapable-ts";
3
+ import type { Template } from "@player-ui/types";
4
+ import type { AnyAssetType, Node } from "./types";
5
+ import { NodeType } from "./types";
6
+ import { getNodeID, hasAsync } from "./utils";
7
7
 
8
- export * from './types';
9
- export * from './utils';
8
+ export * from "./types";
9
+ export * from "./utils";
10
10
 
11
11
  export const EMPTY_NODE: Node.Empty = {
12
12
  type: NodeType.Empty,
@@ -59,7 +59,7 @@ export class Parser {
59
59
  obj: object,
60
60
  nodeType: Node.ChildrenTypes,
61
61
  parseOptions: ParseObjectOptions,
62
- determinedNodeType: NodeType | null
62
+ determinedNodeType: NodeType | null,
63
63
  ],
64
64
  Node.Node
65
65
  >(),
@@ -69,7 +69,7 @@ export class Parser {
69
69
  const viewNode = this.parseObject(value, NodeType.View);
70
70
 
71
71
  if (!viewNode) {
72
- throw new Error('Unable to parse object into a view');
72
+ throw new Error("Unable to parse object into a view");
73
73
  }
74
74
 
75
75
  return viewNode as Node.View;
@@ -78,9 +78,9 @@ export class Parser {
78
78
  private parseAsync(
79
79
  obj: object,
80
80
  type: Node.ChildrenTypes,
81
- options: ParseObjectOptions
81
+ options: ParseObjectOptions,
82
82
  ): Node.Node | null {
83
- const parsedAsync = this.parseObject(omit(obj, 'async'), type, options);
83
+ const parsedAsync = this.parseObject(omit(obj, "async"), type, options);
84
84
  const parsedNodeId = getNodeID(parsedAsync);
85
85
  if (parsedAsync !== null && parsedNodeId) {
86
86
  return this.createASTNode(
@@ -89,7 +89,7 @@ export class Parser {
89
89
  type: NodeType.Async,
90
90
  value: parsedAsync,
91
91
  },
92
- obj
92
+ obj,
93
93
  );
94
94
  }
95
95
 
@@ -114,17 +114,21 @@ export class Parser {
114
114
  */
115
115
  private hasTemplateValues(obj: any, localKey: string) {
116
116
  return (
117
- Object.hasOwnProperty.call(obj, 'template') &&
117
+ Object.hasOwnProperty.call(obj, "template") &&
118
118
  Array.isArray(obj?.template) &&
119
119
  obj.template.length &&
120
120
  obj.template.find((tmpl: any) => tmpl.output === localKey)
121
121
  );
122
122
  }
123
123
 
124
+ private hasSwitchKey(localKey: string) {
125
+ return localKey === ("staticSwitch" || "dynamicSwitch");
126
+ }
127
+
124
128
  public parseObject(
125
129
  obj: object,
126
130
  type: Node.ChildrenTypes = NodeType.Value,
127
- options: ParseObjectOptions = { templateDepth: 0 }
131
+ options: ParseObjectOptions = { templateDepth: 0 },
128
132
  ): Node.Node | null {
129
133
  const nodeType = this.hooks.determineNodeType.call(obj);
130
134
 
@@ -133,19 +137,22 @@ export class Parser {
133
137
  obj,
134
138
  type,
135
139
  options,
136
- nodeType
140
+ nodeType,
137
141
  );
138
142
  if (parsedNode) {
139
143
  return parsedNode;
140
144
  }
141
145
  }
142
146
 
147
+ /**
148
+ *
149
+ */
143
150
  const parseLocalObject = (
144
151
  currentValue: any,
145
152
  objToParse: unknown,
146
- path: string[] = []
153
+ path: string[] = [],
147
154
  ): NestedObj => {
148
- if (typeof objToParse !== 'object' || objToParse === null) {
155
+ if (typeof objToParse !== "object" || objToParse === null) {
149
156
  return { value: objToParse, children: [] };
150
157
  }
151
158
 
@@ -173,11 +180,11 @@ export class Parser {
173
180
  const newValue = objEntries.reduce((accumulation, current): NestedObj => {
174
181
  const { children, ...rest } = accumulation;
175
182
  const [localKey, localValue] = current;
176
- if (localKey === 'asset' && typeof localValue === 'object') {
183
+ if (localKey === "asset" && typeof localValue === "object") {
177
184
  const assetAST = this.parseObject(
178
185
  localValue,
179
186
  NodeType.Asset,
180
- options
187
+ options,
181
188
  );
182
189
 
183
190
  if (assetAST) {
@@ -186,7 +193,7 @@ export class Parser {
186
193
  children: [
187
194
  ...children,
188
195
  {
189
- path: [...path, 'asset'],
196
+ path: [...path, "asset"],
190
197
  value: assetAST,
191
198
  },
192
199
  ],
@@ -206,7 +213,7 @@ export class Parser {
206
213
  template: template.value,
207
214
  dynamic: template.dynamic ?? false,
208
215
  },
209
- template
216
+ template,
210
217
  );
211
218
 
212
219
  if (templateAST?.type === NodeType.MultiNode) {
@@ -233,14 +240,18 @@ export class Parser {
233
240
  children: [...children, ...templateChildren],
234
241
  } as NestedObj;
235
242
  } else if (
236
- localValue &&
237
- this.hooks.determineNodeType.call(localValue) === NodeType.Switch
243
+ (localValue &&
244
+ this.hooks.determineNodeType.call(localValue) ===
245
+ NodeType.Switch) ||
246
+ this.hasSwitchKey(localKey)
238
247
  ) {
239
248
  const localSwitch = this.hooks.parseNode.call(
240
- localValue,
249
+ this.hasSwitchKey(localKey)
250
+ ? { [localKey]: localValue }
251
+ : localValue,
241
252
  NodeType.Value,
242
253
  options,
243
- NodeType.Switch
254
+ NodeType.Switch,
244
255
  );
245
256
 
246
257
  if (
@@ -279,7 +290,7 @@ export class Parser {
279
290
  const localAsync = this.parseAsync(
280
291
  localValue,
281
292
  NodeType.Value,
282
- options
293
+ options,
283
294
  );
284
295
  if (localAsync) {
285
296
  children.push({
@@ -290,7 +301,7 @@ export class Parser {
290
301
  } else if (localValue && Array.isArray(localValue)) {
291
302
  const childValues = localValue
292
303
  .map((childVal) =>
293
- this.parseObject(childVal, NodeType.Value, options)
304
+ this.parseObject(childVal, NodeType.Value, options),
294
305
  )
295
306
  .filter((child): child is Node.Node => !!child);
296
307
 
@@ -301,7 +312,7 @@ export class Parser {
301
312
  override: !this.hasTemplateValues(localObj, localKey),
302
313
  values: childValues,
303
314
  },
304
- localValue
315
+ localValue,
305
316
  );
306
317
 
307
318
  if (multiNode?.type === NodeType.MultiNode) {
@@ -310,7 +321,6 @@ export class Parser {
310
321
  v.parent = multiNode;
311
322
  });
312
323
  }
313
-
314
324
  if (multiNode) {
315
325
  return {
316
326
  ...rest,
@@ -324,7 +334,7 @@ export class Parser {
324
334
  };
325
335
  }
326
336
  }
327
- } else if (localValue && typeof localValue === 'object') {
337
+ } else if (localValue && typeof localValue === "object") {
328
338
  const determineNodeType =
329
339
  this.hooks.determineNodeType.call(localValue);
330
340
 
@@ -333,7 +343,7 @@ export class Parser {
333
343
  localValue,
334
344
  NodeType.Value,
335
345
  options,
336
- determineNodeType
346
+ determineNodeType,
337
347
  );
338
348
  if (parsedNode) {
339
349
  return {
@@ -361,7 +371,7 @@ export class Parser {
361
371
  const value = setIn(
362
372
  accumulation.value,
363
373
  [...path, localKey],
364
- localValue
374
+ localValue,
365
375
  );
366
376
 
367
377
  return {
@@ -1,17 +1,17 @@
1
- import type { Asset as AssetType, Expression, Binding } from '@player-ui/types';
1
+ import type { Asset as AssetType, Expression, Binding } from "@player-ui/types";
2
2
 
3
3
  export type AnyAssetType = AssetType<string>;
4
4
  export enum NodeType {
5
- Asset = 'asset',
6
- View = 'view',
7
- Applicability = 'applicability',
8
- Template = 'template',
9
- Value = 'value',
10
- MultiNode = 'multi-node',
11
- Switch = 'switch',
12
- Async = 'async',
13
- Unknown = 'unknown',
14
- Empty = 'empty',
5
+ Asset = "asset",
6
+ View = "view",
7
+ Applicability = "applicability",
8
+ Template = "template",
9
+ Value = "value",
10
+ MultiNode = "multi-node",
11
+ Switch = "switch",
12
+ Async = "async",
13
+ Unknown = "unknown",
14
+ Empty = "empty",
15
15
  }
16
16
  export declare namespace Node {
17
17
  export type ChildrenTypes = NodeType.Asset | NodeType.Value | NodeType.View;
@@ -1,8 +1,8 @@
1
- import type { Node } from './types';
1
+ import type { Node } from "./types";
2
2
 
3
3
  /** Check to see if the object contains async */
4
4
  export function hasAsync(obj: object): boolean {
5
- return Object.prototype.hasOwnProperty.call(obj, 'async');
5
+ return Object.prototype.hasOwnProperty.call(obj, "async");
6
6
  }
7
7
 
8
8
  /** Get the ID of the Node if there is one */
@@ -12,9 +12,9 @@ export function getNodeID(node?: Node.Node | null): string | undefined {
12
12
  }
13
13
 
14
14
  if (
15
- 'value' in node &&
16
- typeof node.value === 'object' &&
17
- typeof node.value?.id === 'string'
15
+ "value" in node &&
16
+ typeof node.value === "object" &&
17
+ typeof node.value?.id === "string"
18
18
  ) {
19
19
  return node.value.id;
20
20
  }