@player-tools/fluent 0.12.1--canary.241.6077
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/dist/cjs/index.cjs +2396 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/index.legacy-esm.js +2276 -0
- package/dist/index.mjs +2276 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +38 -0
- package/src/core/base-builder/__tests__/fluent-builder-base.test.ts +2423 -0
- package/src/core/base-builder/__tests__/fluent-partial.test.ts +179 -0
- package/src/core/base-builder/__tests__/id-generator.test.ts +658 -0
- package/src/core/base-builder/__tests__/registry.test.ts +534 -0
- package/src/core/base-builder/__tests__/resolution-mixed-arrays.test.ts +319 -0
- package/src/core/base-builder/__tests__/resolution-pipeline.test.ts +416 -0
- package/src/core/base-builder/__tests__/resolution-switches.test.ts +468 -0
- package/src/core/base-builder/__tests__/resolution-templates.test.ts +255 -0
- package/src/core/base-builder/__tests__/switch.test.ts +815 -0
- package/src/core/base-builder/__tests__/template.test.ts +596 -0
- package/src/core/base-builder/__tests__/value-extraction.test.ts +200 -0
- package/src/core/base-builder/__tests__/value-storage.test.ts +459 -0
- package/src/core/base-builder/conditional/index.ts +64 -0
- package/src/core/base-builder/context.ts +152 -0
- package/src/core/base-builder/errors.ts +69 -0
- package/src/core/base-builder/fluent-builder-base.ts +308 -0
- package/src/core/base-builder/guards.ts +137 -0
- package/src/core/base-builder/id/generator.ts +290 -0
- package/src/core/base-builder/id/registry.ts +152 -0
- package/src/core/base-builder/index.ts +72 -0
- package/src/core/base-builder/resolution/path-resolver.ts +116 -0
- package/src/core/base-builder/resolution/pipeline.ts +103 -0
- package/src/core/base-builder/resolution/steps/__tests__/nested-asset-wrappers.test.ts +206 -0
- package/src/core/base-builder/resolution/steps/asset-id.ts +77 -0
- package/src/core/base-builder/resolution/steps/asset-wrappers.ts +64 -0
- package/src/core/base-builder/resolution/steps/builders.ts +84 -0
- package/src/core/base-builder/resolution/steps/mixed-arrays.ts +95 -0
- package/src/core/base-builder/resolution/steps/nested-asset-wrappers.ts +124 -0
- package/src/core/base-builder/resolution/steps/static-values.ts +35 -0
- package/src/core/base-builder/resolution/steps/switches.ts +71 -0
- package/src/core/base-builder/resolution/steps/templates.ts +40 -0
- package/src/core/base-builder/resolution/value-resolver.ts +333 -0
- package/src/core/base-builder/storage/auxiliary-storage.ts +82 -0
- package/src/core/base-builder/storage/value-storage.ts +282 -0
- package/src/core/base-builder/types.ts +266 -0
- package/src/core/base-builder/utils.ts +10 -0
- package/src/core/flow/__tests__/index.test.ts +292 -0
- package/src/core/flow/index.ts +118 -0
- package/src/core/index.ts +8 -0
- package/src/core/mocks/generated/action.builder.ts +92 -0
- package/src/core/mocks/generated/choice-item.builder.ts +120 -0
- package/src/core/mocks/generated/choice.builder.ts +134 -0
- package/src/core/mocks/generated/collection.builder.ts +93 -0
- package/src/core/mocks/generated/field-collection.builder.ts +86 -0
- package/src/core/mocks/generated/index.ts +10 -0
- package/src/core/mocks/generated/info.builder.ts +64 -0
- package/src/core/mocks/generated/input.builder.ts +63 -0
- package/src/core/mocks/generated/overview-collection.builder.ts +65 -0
- package/src/core/mocks/generated/splash-collection.builder.ts +93 -0
- package/src/core/mocks/generated/text.builder.ts +47 -0
- package/src/core/mocks/index.ts +1 -0
- package/src/core/mocks/types/action.ts +92 -0
- package/src/core/mocks/types/choice.ts +129 -0
- package/src/core/mocks/types/collection.ts +140 -0
- package/src/core/mocks/types/info.ts +7 -0
- package/src/core/mocks/types/input.ts +7 -0
- package/src/core/mocks/types/text.ts +5 -0
- package/src/core/schema/__tests__/index.test.ts +127 -0
- package/src/core/schema/index.ts +195 -0
- package/src/core/schema/types.ts +7 -0
- package/src/core/switch/__tests__/index.test.ts +156 -0
- package/src/core/switch/index.ts +81 -0
- package/src/core/tagged-template/README.md +448 -0
- package/src/core/tagged-template/__tests__/extract-bindings-from-schema.test.ts +207 -0
- package/src/core/tagged-template/__tests__/index.test.ts +190 -0
- package/src/core/tagged-template/__tests__/schema-std-integration.test.ts +580 -0
- package/src/core/tagged-template/binding.ts +95 -0
- package/src/core/tagged-template/expression.ts +92 -0
- package/src/core/tagged-template/extract-bindings-from-schema.ts +120 -0
- package/src/core/tagged-template/index.ts +5 -0
- package/src/core/tagged-template/std.ts +472 -0
- package/src/core/tagged-template/types.ts +123 -0
- package/src/core/template/__tests__/index.test.ts +380 -0
- package/src/core/template/index.ts +196 -0
- package/src/core/utils/index.ts +160 -0
- package/src/fp/README.md +411 -0
- package/src/fp/__tests__/index.test.ts +1178 -0
- package/src/fp/index.ts +386 -0
- package/src/gen/common.ts +15 -0
- package/src/index.ts +5 -0
- package/src/types.ts +203 -0
- package/types/core/base-builder/conditional/index.d.ts +21 -0
- package/types/core/base-builder/context.d.ts +39 -0
- package/types/core/base-builder/errors.d.ts +45 -0
- package/types/core/base-builder/fluent-builder-base.d.ts +147 -0
- package/types/core/base-builder/guards.d.ts +58 -0
- package/types/core/base-builder/id/generator.d.ts +69 -0
- package/types/core/base-builder/id/registry.d.ts +93 -0
- package/types/core/base-builder/index.d.ts +9 -0
- package/types/core/base-builder/resolution/path-resolver.d.ts +15 -0
- package/types/core/base-builder/resolution/pipeline.d.ts +27 -0
- package/types/core/base-builder/resolution/steps/asset-id.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/asset-wrappers.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/builders.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/mixed-arrays.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/nested-asset-wrappers.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/static-values.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/switches.d.ts +15 -0
- package/types/core/base-builder/resolution/steps/templates.d.ts +14 -0
- package/types/core/base-builder/resolution/value-resolver.d.ts +62 -0
- package/types/core/base-builder/storage/auxiliary-storage.d.ts +50 -0
- package/types/core/base-builder/storage/value-storage.d.ts +82 -0
- package/types/core/base-builder/types.d.ts +183 -0
- package/types/core/base-builder/utils.d.ts +2 -0
- package/types/core/flow/index.d.ts +23 -0
- package/types/core/index.d.ts +8 -0
- package/types/core/mocks/index.d.ts +2 -0
- package/types/core/mocks/types/action.d.ts +58 -0
- package/types/core/mocks/types/choice.d.ts +95 -0
- package/types/core/mocks/types/collection.d.ts +102 -0
- package/types/core/mocks/types/info.d.ts +7 -0
- package/types/core/mocks/types/input.d.ts +7 -0
- package/types/core/mocks/types/text.d.ts +5 -0
- package/types/core/schema/index.d.ts +34 -0
- package/types/core/schema/types.d.ts +5 -0
- package/types/core/switch/index.d.ts +21 -0
- package/types/core/tagged-template/binding.d.ts +19 -0
- package/types/core/tagged-template/expression.d.ts +11 -0
- package/types/core/tagged-template/extract-bindings-from-schema.d.ts +7 -0
- package/types/core/tagged-template/index.d.ts +6 -0
- package/types/core/tagged-template/std.d.ts +174 -0
- package/types/core/tagged-template/types.d.ts +69 -0
- package/types/core/template/index.d.ts +97 -0
- package/types/core/utils/index.d.ts +47 -0
- package/types/fp/index.d.ts +149 -0
- package/types/gen/common.d.ts +6 -0
- package/types/index.d.ts +3 -0
- package/types/types.d.ts +163 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { flow } from "..";
|
|
3
|
+
import { Flow } from "@player-ui/types";
|
|
4
|
+
import { text } from "../../mocks";
|
|
5
|
+
|
|
6
|
+
describe("flow function", () => {
|
|
7
|
+
it("should create a flow with basic properties", () => {
|
|
8
|
+
const result = flow({
|
|
9
|
+
id: "test-flow",
|
|
10
|
+
topic: "test-flow",
|
|
11
|
+
views: [text({ value: "Hello World" })],
|
|
12
|
+
data: {
|
|
13
|
+
greeting: "Hello",
|
|
14
|
+
},
|
|
15
|
+
navigation: {
|
|
16
|
+
BEGIN: "FLOW_1",
|
|
17
|
+
FLOW_1: {
|
|
18
|
+
startState: "VIEW_1",
|
|
19
|
+
VIEW_1: {
|
|
20
|
+
state_type: "VIEW",
|
|
21
|
+
ref: "view-1",
|
|
22
|
+
transitions: {},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const expected: Flow = {
|
|
29
|
+
data: {
|
|
30
|
+
greeting: "Hello",
|
|
31
|
+
},
|
|
32
|
+
id: "test-flow",
|
|
33
|
+
topic: "test-flow",
|
|
34
|
+
navigation: {
|
|
35
|
+
BEGIN: "FLOW_1",
|
|
36
|
+
FLOW_1: {
|
|
37
|
+
VIEW_1: {
|
|
38
|
+
ref: "view-1",
|
|
39
|
+
state_type: "VIEW",
|
|
40
|
+
transitions: {},
|
|
41
|
+
},
|
|
42
|
+
startState: "VIEW_1",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
views: [
|
|
46
|
+
{
|
|
47
|
+
id: "test-flow-views-0-text",
|
|
48
|
+
type: "text",
|
|
49
|
+
value: "Hello World",
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
expect(result).toEqual(expected);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should use "root" as default flow ID', () => {
|
|
58
|
+
const result = flow({
|
|
59
|
+
views: [text({ value: "Hello World" })],
|
|
60
|
+
navigation: {
|
|
61
|
+
BEGIN: "FLOW_1",
|
|
62
|
+
FLOW_1: {
|
|
63
|
+
startState: "VIEW_1",
|
|
64
|
+
VIEW_1: {
|
|
65
|
+
state_type: "VIEW",
|
|
66
|
+
ref: "view-1",
|
|
67
|
+
transitions: {},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
expect(result.id).toEqual("root");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("should generate hierarchical IDs for views", () => {
|
|
77
|
+
const result = flow({
|
|
78
|
+
id: "my-flow",
|
|
79
|
+
views: [text().withValue("First View"), text().withValue("Second View")],
|
|
80
|
+
navigation: {
|
|
81
|
+
BEGIN: "FLOW_1",
|
|
82
|
+
FLOW_1: {
|
|
83
|
+
startState: "VIEW_1",
|
|
84
|
+
VIEW_1: {
|
|
85
|
+
state_type: "VIEW",
|
|
86
|
+
ref: "view-1",
|
|
87
|
+
transitions: {},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const expected: Flow["views"] = [
|
|
94
|
+
{
|
|
95
|
+
id: "my-flow-views-0-text",
|
|
96
|
+
type: "text",
|
|
97
|
+
value: "First View",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: "my-flow-views-1-text",
|
|
101
|
+
type: "text",
|
|
102
|
+
value: "Second View",
|
|
103
|
+
},
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
expect(result.views).toEqual(expected);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("should preserve custom IDs in views", () => {
|
|
110
|
+
const result = flow({
|
|
111
|
+
id: "custom-flow",
|
|
112
|
+
views: [
|
|
113
|
+
text().withId("custom-view-id").withValue("Custom ID View"),
|
|
114
|
+
text().withValue("Auto ID View"),
|
|
115
|
+
],
|
|
116
|
+
navigation: {
|
|
117
|
+
BEGIN: "FLOW_1",
|
|
118
|
+
FLOW_1: {
|
|
119
|
+
startState: "VIEW_1",
|
|
120
|
+
VIEW_1: {
|
|
121
|
+
state_type: "VIEW",
|
|
122
|
+
ref: "custom-view-id",
|
|
123
|
+
transitions: {},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const expected: Flow["views"] = [
|
|
130
|
+
{
|
|
131
|
+
id: "custom-view-id",
|
|
132
|
+
type: "text",
|
|
133
|
+
value: "Custom ID View",
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: "custom-flow-views-1-text",
|
|
137
|
+
type: "text",
|
|
138
|
+
value: "Auto ID View",
|
|
139
|
+
},
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
expect(result.views).toEqual(expected);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("should handle function-based view generators", () => {
|
|
146
|
+
const result = flow({
|
|
147
|
+
id: "functional-flow",
|
|
148
|
+
views: [
|
|
149
|
+
(ctx) => ({
|
|
150
|
+
id: ctx.parentId ?? "default-id",
|
|
151
|
+
type: "text" as const,
|
|
152
|
+
value: "Function Generated View",
|
|
153
|
+
}),
|
|
154
|
+
],
|
|
155
|
+
navigation: {
|
|
156
|
+
BEGIN: "FLOW_1",
|
|
157
|
+
FLOW_1: {
|
|
158
|
+
startState: "VIEW_1",
|
|
159
|
+
VIEW_1: {
|
|
160
|
+
state_type: "VIEW",
|
|
161
|
+
ref: "view-func",
|
|
162
|
+
transitions: {},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const expected: Flow["views"] = [
|
|
169
|
+
{
|
|
170
|
+
id: "functional-flow-views",
|
|
171
|
+
type: "text",
|
|
172
|
+
value: "Function Generated View",
|
|
173
|
+
},
|
|
174
|
+
];
|
|
175
|
+
|
|
176
|
+
expect(result.views).toEqual(expected);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("should handle a complex flow with multiple properties", () => {
|
|
180
|
+
const result = flow({
|
|
181
|
+
id: "complex-flow",
|
|
182
|
+
views: [
|
|
183
|
+
text().withId("view-1").withValue("First View"),
|
|
184
|
+
text().withId("view-2").withValue("Second View"),
|
|
185
|
+
],
|
|
186
|
+
data: {
|
|
187
|
+
user: {
|
|
188
|
+
name: "John Doe",
|
|
189
|
+
email: "john@example.com",
|
|
190
|
+
},
|
|
191
|
+
settings: {
|
|
192
|
+
theme: "dark",
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
schema: {
|
|
196
|
+
ROOT: {
|
|
197
|
+
user: {
|
|
198
|
+
type: "object",
|
|
199
|
+
},
|
|
200
|
+
settings: {
|
|
201
|
+
type: "object",
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
navigation: {
|
|
206
|
+
BEGIN: "MAIN_FLOW",
|
|
207
|
+
MAIN_FLOW: {
|
|
208
|
+
startState: "FIRST_VIEW",
|
|
209
|
+
FIRST_VIEW: {
|
|
210
|
+
state_type: "VIEW",
|
|
211
|
+
ref: "view-1",
|
|
212
|
+
transitions: {
|
|
213
|
+
NEXT: "SECOND_VIEW",
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
SECOND_VIEW: {
|
|
217
|
+
state_type: "VIEW",
|
|
218
|
+
ref: "view-2",
|
|
219
|
+
transitions: {
|
|
220
|
+
DONE: "END_STATE",
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
END_STATE: {
|
|
224
|
+
state_type: "END",
|
|
225
|
+
outcome: "completed",
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const expected: Flow = {
|
|
232
|
+
data: {
|
|
233
|
+
settings: {
|
|
234
|
+
theme: "dark",
|
|
235
|
+
},
|
|
236
|
+
user: {
|
|
237
|
+
email: "john@example.com",
|
|
238
|
+
name: "John Doe",
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
id: "complex-flow",
|
|
242
|
+
navigation: {
|
|
243
|
+
BEGIN: "MAIN_FLOW",
|
|
244
|
+
MAIN_FLOW: {
|
|
245
|
+
END_STATE: {
|
|
246
|
+
outcome: "completed",
|
|
247
|
+
state_type: "END",
|
|
248
|
+
},
|
|
249
|
+
FIRST_VIEW: {
|
|
250
|
+
ref: "view-1",
|
|
251
|
+
state_type: "VIEW",
|
|
252
|
+
transitions: {
|
|
253
|
+
NEXT: "SECOND_VIEW",
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
SECOND_VIEW: {
|
|
257
|
+
ref: "view-2",
|
|
258
|
+
state_type: "VIEW",
|
|
259
|
+
transitions: {
|
|
260
|
+
DONE: "END_STATE",
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
startState: "FIRST_VIEW",
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
schema: {
|
|
267
|
+
ROOT: {
|
|
268
|
+
settings: {
|
|
269
|
+
type: "object",
|
|
270
|
+
},
|
|
271
|
+
user: {
|
|
272
|
+
type: "object",
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
views: [
|
|
277
|
+
{
|
|
278
|
+
id: "view-1",
|
|
279
|
+
type: "text",
|
|
280
|
+
value: "First View",
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
id: "view-2",
|
|
284
|
+
type: "text",
|
|
285
|
+
value: "Second View",
|
|
286
|
+
},
|
|
287
|
+
],
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
expect(result).toEqual(expected);
|
|
291
|
+
});
|
|
292
|
+
});
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Asset, Flow, DataModel, Navigation, Schema } from "@player-ui/types";
|
|
2
|
+
import { BaseBuildContext, BranchTypes } from "../base-builder";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Core options for creating a Player-UI Flow
|
|
6
|
+
*/
|
|
7
|
+
interface CoreFlowOptions<
|
|
8
|
+
T extends Asset = Asset,
|
|
9
|
+
C extends BaseBuildContext = BaseBuildContext,
|
|
10
|
+
> {
|
|
11
|
+
id?: string;
|
|
12
|
+
views: Array<T | { build(context?: C): T } | ((ctx: C) => T)>;
|
|
13
|
+
data?: DataModel;
|
|
14
|
+
schema?: Schema.Schema;
|
|
15
|
+
navigation: Navigation;
|
|
16
|
+
context?: C;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Options for creating a Player-UI Flow
|
|
21
|
+
* Allows additional properties to be passed through to the final Flow
|
|
22
|
+
*/
|
|
23
|
+
export type FlowOptions<
|
|
24
|
+
T extends Asset = Asset,
|
|
25
|
+
C extends BaseBuildContext = BaseBuildContext,
|
|
26
|
+
> = CoreFlowOptions<T, C> &
|
|
27
|
+
Omit<Flow<T>, keyof CoreFlowOptions<T, C> | "views">;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Creates a Player-UI Flow from the given options
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { flow } from './flow';
|
|
35
|
+
* import { text } from './assets';
|
|
36
|
+
*
|
|
37
|
+
* const myFlow = flow({
|
|
38
|
+
* id: 'example-flow',
|
|
39
|
+
* views: [text().withValue('Some Text').withId('view-1')],
|
|
40
|
+
* navigation: {
|
|
41
|
+
* BEGIN: 'FLOW_1',
|
|
42
|
+
* FLOW_1: {
|
|
43
|
+
* startState: 'VIEW_1',
|
|
44
|
+
* VIEW_1: { state_type: 'VIEW', ref: 'view-1', transitions: { '*': 'END_Done' } },
|
|
45
|
+
* END_Done: { state_type: 'END', outcome: 'done' }
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
function isBuilder<T>(
|
|
52
|
+
value: T | { build(context?: BaseBuildContext): T },
|
|
53
|
+
): value is { build(context?: BaseBuildContext): T } {
|
|
54
|
+
return (
|
|
55
|
+
typeof value === "object" &&
|
|
56
|
+
value !== null &&
|
|
57
|
+
"build" in value &&
|
|
58
|
+
typeof value.build === "function"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function isBuilderFunction<T>(
|
|
63
|
+
value: T | ((ctx: BaseBuildContext) => T),
|
|
64
|
+
): value is (ctx: BaseBuildContext) => T {
|
|
65
|
+
return typeof value === "function";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function flow<T extends Asset = Asset>(
|
|
69
|
+
options: FlowOptions<T>,
|
|
70
|
+
): Flow<T> {
|
|
71
|
+
const flowId = options.id || "root";
|
|
72
|
+
|
|
73
|
+
const viewsNamespace = `${flowId}-views`;
|
|
74
|
+
|
|
75
|
+
const processedViews = (() => {
|
|
76
|
+
const processViews = (): T[] => {
|
|
77
|
+
const results: T[] = [];
|
|
78
|
+
|
|
79
|
+
for (let index = 0; index < options.views.length; index++) {
|
|
80
|
+
const viewOrFn = options.views[index];
|
|
81
|
+
const ctx: BaseBuildContext = {
|
|
82
|
+
parentId: viewsNamespace,
|
|
83
|
+
branch: {
|
|
84
|
+
type: BranchTypes.ARRAY_ITEM,
|
|
85
|
+
index,
|
|
86
|
+
},
|
|
87
|
+
...(options.context ?? {}),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
if (isBuilder(viewOrFn)) {
|
|
91
|
+
results.push(viewOrFn.build(ctx));
|
|
92
|
+
} else if (isBuilderFunction(viewOrFn)) {
|
|
93
|
+
results.push(viewOrFn(ctx));
|
|
94
|
+
} else {
|
|
95
|
+
results.push(viewOrFn);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return results;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
return processViews();
|
|
103
|
+
})();
|
|
104
|
+
|
|
105
|
+
// Extract core properties that need special handling (views and context are handled separately)
|
|
106
|
+
const { views: _views, context: _context, ...restOptions } = options;
|
|
107
|
+
void _views; // Handled via processedViews
|
|
108
|
+
void _context; // Used to construct view build context
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
...restOptions,
|
|
112
|
+
id: flowId,
|
|
113
|
+
views: processedViews,
|
|
114
|
+
...(options.data && { data: options.data }),
|
|
115
|
+
...(options.schema && { schema: options.schema }),
|
|
116
|
+
navigation: options.navigation,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { ActionAsset, ActionMetaData } from "../types/action.js";
|
|
2
|
+
import type { Asset } from "@player-ui/types";
|
|
3
|
+
import { type FluentBuilder, type BaseBuildContext, type FluentPartial, FluentBuilderBase, createInspectMethod, type TaggedTemplateValue } from "../../../gen/common.js";
|
|
4
|
+
|
|
5
|
+
export interface ActionAssetBuilderMethods<AnyAsset extends Asset = Asset> {
|
|
6
|
+
/** A unique identifier for this asset */
|
|
7
|
+
withId(value: string | TaggedTemplateValue<string>): ActionAssetBuilder<AnyAsset>;
|
|
8
|
+
/** The transition value of the action in the state machine */
|
|
9
|
+
withValue(value: string | TaggedTemplateValue<string>): ActionAssetBuilder<AnyAsset>;
|
|
10
|
+
/** A text-like asset for the action's label */
|
|
11
|
+
withLabel(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ActionAssetBuilder<AnyAsset>;
|
|
12
|
+
/** An optional expression to execute before transitioning */
|
|
13
|
+
withExp(value: string | TaggedTemplateValue<string>): ActionAssetBuilder<AnyAsset>;
|
|
14
|
+
/** An optional string that describes the action for screen-readers */
|
|
15
|
+
withAccessibility(value: string | TaggedTemplateValue<string>): ActionAssetBuilder<AnyAsset>;
|
|
16
|
+
/** An optional confirmation dialog to show before executing the action */
|
|
17
|
+
withConfirmation(value: { message: string | TaggedTemplateValue<string>; affirmativeLabel: string | TaggedTemplateValue<string>; negativeLabel?: string | TaggedTemplateValue<string> } | FluentBuilder<{ message: string | TaggedTemplateValue<string>; affirmativeLabel: string | TaggedTemplateValue<string>; negativeLabel?: string | TaggedTemplateValue<string> }, BaseBuildContext> | FluentPartial<{ message: string | TaggedTemplateValue<string>; affirmativeLabel: string | TaggedTemplateValue<string>; negativeLabel?: string | TaggedTemplateValue<string> }, BaseBuildContext>): ActionAssetBuilder<AnyAsset>;
|
|
18
|
+
/** Additional optional data to assist with the action interactions on the page */
|
|
19
|
+
withMetaData(value: ActionMetaData | FluentBuilder<ActionMetaData, BaseBuildContext> | FluentPartial<ActionMetaData, BaseBuildContext>): ActionAssetBuilder<AnyAsset>;
|
|
20
|
+
/** Triggers the listed bindings to be validated */
|
|
21
|
+
withValidate(value: Array<string | TaggedTemplateValue<string>> | string | TaggedTemplateValue<string>): ActionAssetBuilder<AnyAsset>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A builder for ActionAsset
|
|
26
|
+
*/
|
|
27
|
+
export class ActionAssetBuilder<AnyAsset extends Asset = Asset> extends FluentBuilderBase<ActionAsset<AnyAsset>> implements ActionAssetBuilderMethods<AnyAsset>, FluentBuilder<ActionAsset<AnyAsset>, BaseBuildContext> {
|
|
28
|
+
private static readonly defaults: Record<string, unknown> = {"type":"action","id":""};
|
|
29
|
+
private static readonly __arrayProperties__: ReadonlySet<string> = new Set(["validate"]);
|
|
30
|
+
private static readonly __assetWrapperPaths__: ReadonlyArray<ReadonlyArray<string>> = [["label"]];
|
|
31
|
+
|
|
32
|
+
/** A unique identifier for this asset */
|
|
33
|
+
withId(value: string | TaggedTemplateValue<string>): ActionAssetBuilder<AnyAsset> {
|
|
34
|
+
return this.set("id", value);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** The transition value of the action in the state machine */
|
|
38
|
+
withValue(value: string | TaggedTemplateValue<string>): ActionAssetBuilder<AnyAsset> {
|
|
39
|
+
return this.set("value", value);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** A text-like asset for the action's label */
|
|
43
|
+
withLabel(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ActionAssetBuilder<AnyAsset> {
|
|
44
|
+
return this.set("label", value);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** An optional expression to execute before transitioning */
|
|
48
|
+
withExp(value: string | TaggedTemplateValue<string>): ActionAssetBuilder<AnyAsset> {
|
|
49
|
+
return this.set("exp", value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** An optional string that describes the action for screen-readers */
|
|
53
|
+
withAccessibility(value: string | TaggedTemplateValue<string>): ActionAssetBuilder<AnyAsset> {
|
|
54
|
+
return this.set("accessibility", value);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** An optional confirmation dialog to show before executing the action */
|
|
58
|
+
withConfirmation(value: { message: string | TaggedTemplateValue<string>; affirmativeLabel: string | TaggedTemplateValue<string>; negativeLabel?: string | TaggedTemplateValue<string> } | FluentBuilder<{ message: string | TaggedTemplateValue<string>; affirmativeLabel: string | TaggedTemplateValue<string>; negativeLabel?: string | TaggedTemplateValue<string> }, BaseBuildContext> | FluentPartial<{ message: string | TaggedTemplateValue<string>; affirmativeLabel: string | TaggedTemplateValue<string>; negativeLabel?: string | TaggedTemplateValue<string> }, BaseBuildContext>): ActionAssetBuilder<AnyAsset> {
|
|
59
|
+
return this.set("confirmation", value);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Additional optional data to assist with the action interactions on the page */
|
|
63
|
+
withMetaData(value: ActionMetaData | FluentBuilder<ActionMetaData, BaseBuildContext> | FluentPartial<ActionMetaData, BaseBuildContext>): ActionAssetBuilder<AnyAsset> {
|
|
64
|
+
return this.set("metaData", value);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Triggers the listed bindings to be validated */
|
|
68
|
+
withValidate(value: Array<string | TaggedTemplateValue<string>> | string | TaggedTemplateValue<string>): ActionAssetBuilder<AnyAsset> {
|
|
69
|
+
return this.set("validate", value);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Builds the final ActionAsset object
|
|
74
|
+
* @param context - Optional build context for nested builders
|
|
75
|
+
*/
|
|
76
|
+
build(context?: BaseBuildContext): ActionAsset<AnyAsset> {
|
|
77
|
+
return this.buildWithDefaults(ActionAssetBuilder.defaults, context);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
[Symbol.for("nodejs.util.inspect.custom")](): string {
|
|
81
|
+
return createInspectMethod("ActionAssetBuilder", this.values);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Creates a new ActionAsset builder
|
|
87
|
+
* @param initial Optional initial values
|
|
88
|
+
* @returns A fluent builder for ActionAsset
|
|
89
|
+
*/
|
|
90
|
+
export function action<AnyAsset extends Asset = Asset>(initial?: FluentPartial<ActionAsset<AnyAsset>>): ActionAssetBuilder<AnyAsset> {
|
|
91
|
+
return new ActionAssetBuilder<AnyAsset>(initial);
|
|
92
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { ChoiceItem, ChoiceInputModifier, ChoiceItemMetadata } from "../types/choice.js";
|
|
2
|
+
import type { Asset } from "@player-ui/types";
|
|
3
|
+
import { type FluentBuilder, type BaseBuildContext, type FluentPartial, FluentBuilderBase, createInspectMethod, type TaggedTemplateValue } from "../../../gen/common.js";
|
|
4
|
+
|
|
5
|
+
export interface ChoiceItemBuilderMethods<AnyAsset extends Asset = Asset> {
|
|
6
|
+
/** The id associated with the choice item */
|
|
7
|
+
withId(value: string | TaggedTemplateValue<string>): ChoiceItemBuilder<AnyAsset>;
|
|
8
|
+
/** The id used for replay tests. */
|
|
9
|
+
withAutomationId(value: string | TaggedTemplateValue<string>): ChoiceItemBuilder<AnyAsset>;
|
|
10
|
+
/** The label describing the choice. */
|
|
11
|
+
withLabel(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset>;
|
|
12
|
+
/** The icon describing the choice. */
|
|
13
|
+
withIcon(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset>;
|
|
14
|
+
/** The help for the choice. */
|
|
15
|
+
withHelp(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset>;
|
|
16
|
+
/** Support the legacy choiceHelp prop. No storybook docs for this; deprecated in favour of the "help" field. */
|
|
17
|
+
withChoiceHelp(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset>;
|
|
18
|
+
/** The description of the choice. */
|
|
19
|
+
withDescription(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset>;
|
|
20
|
+
/** The footer of the choice. */
|
|
21
|
+
withFooter(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset>;
|
|
22
|
+
/** The value to set when this choice is selected */
|
|
23
|
+
withValue(value: string | TaggedTemplateValue<string> | number | TaggedTemplateValue<number> | boolean | TaggedTemplateValue<boolean> | null): ChoiceItemBuilder<AnyAsset>;
|
|
24
|
+
/** The details shown when a user selects the choice item */
|
|
25
|
+
withChoiceDetail(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset>;
|
|
26
|
+
/** Any modifiers for the current item. No storybook docs for this as "readonly" (the only modifier) shouldn't be used anymore. */
|
|
27
|
+
withModifiers(value: Array<ChoiceInputModifier | FluentBuilder<ChoiceInputModifier, BaseBuildContext> | FluentPartial<ChoiceInputModifier, BaseBuildContext>>): ChoiceItemBuilder<AnyAsset>;
|
|
28
|
+
/** MetaData for the choiceItem */
|
|
29
|
+
withMetaData(value: ChoiceItemMetadata | FluentBuilder<ChoiceItemMetadata, BaseBuildContext> | FluentPartial<ChoiceItemMetadata, BaseBuildContext>): ChoiceItemBuilder<AnyAsset>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* A builder for ChoiceItem
|
|
34
|
+
*/
|
|
35
|
+
export class ChoiceItemBuilder<AnyAsset extends Asset = Asset> extends FluentBuilderBase<ChoiceItem<AnyAsset>> implements ChoiceItemBuilderMethods<AnyAsset>, FluentBuilder<ChoiceItem<AnyAsset>, BaseBuildContext> {
|
|
36
|
+
private static readonly defaults: Record<string, unknown> = {"id":""};
|
|
37
|
+
private static readonly __arrayProperties__: ReadonlySet<string> = new Set(["modifiers"]);
|
|
38
|
+
private static readonly __assetWrapperPaths__: ReadonlyArray<ReadonlyArray<string>> = [["label"],["icon"],["help"],["choiceHelp"],["description"],["footer"],["choiceDetail"]];
|
|
39
|
+
|
|
40
|
+
/** The id associated with the choice item */
|
|
41
|
+
withId(value: string | TaggedTemplateValue<string>): ChoiceItemBuilder<AnyAsset> {
|
|
42
|
+
return this.set("id", value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The id used for replay tests. */
|
|
46
|
+
withAutomationId(value: string | TaggedTemplateValue<string>): ChoiceItemBuilder<AnyAsset> {
|
|
47
|
+
return this.set("automationId", value);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** The label describing the choice. */
|
|
51
|
+
withLabel(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset> {
|
|
52
|
+
return this.set("label", value);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** The icon describing the choice. */
|
|
56
|
+
withIcon(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset> {
|
|
57
|
+
return this.set("icon", value);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** The help for the choice. */
|
|
61
|
+
withHelp(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset> {
|
|
62
|
+
return this.set("help", value);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Support the legacy choiceHelp prop. No storybook docs for this; deprecated in favour of the "help" field. */
|
|
66
|
+
withChoiceHelp(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset> {
|
|
67
|
+
return this.set("choiceHelp", value);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The description of the choice. */
|
|
71
|
+
withDescription(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset> {
|
|
72
|
+
return this.set("description", value);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** The footer of the choice. */
|
|
76
|
+
withFooter(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset> {
|
|
77
|
+
return this.set("footer", value);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** The value to set when this choice is selected */
|
|
81
|
+
withValue(value: string | TaggedTemplateValue<string> | number | TaggedTemplateValue<number> | boolean | TaggedTemplateValue<boolean> | null): ChoiceItemBuilder<AnyAsset> {
|
|
82
|
+
return this.set("value", value);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The details shown when a user selects the choice item */
|
|
86
|
+
withChoiceDetail(value: Asset | FluentBuilder<Asset, BaseBuildContext>): ChoiceItemBuilder<AnyAsset> {
|
|
87
|
+
return this.set("choiceDetail", value);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Any modifiers for the current item. No storybook docs for this as "readonly" (the only modifier) shouldn't be used anymore. */
|
|
91
|
+
withModifiers(value: Array<ChoiceInputModifier | FluentBuilder<ChoiceInputModifier, BaseBuildContext> | FluentPartial<ChoiceInputModifier, BaseBuildContext>>): ChoiceItemBuilder<AnyAsset> {
|
|
92
|
+
return this.set("modifiers", value);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** MetaData for the choiceItem */
|
|
96
|
+
withMetaData(value: ChoiceItemMetadata | FluentBuilder<ChoiceItemMetadata, BaseBuildContext> | FluentPartial<ChoiceItemMetadata, BaseBuildContext>): ChoiceItemBuilder<AnyAsset> {
|
|
97
|
+
return this.set("metaData", value);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Builds the final ChoiceItem object
|
|
102
|
+
* @param context - Optional build context for nested builders
|
|
103
|
+
*/
|
|
104
|
+
build(context?: BaseBuildContext): ChoiceItem<AnyAsset> {
|
|
105
|
+
return this.buildWithDefaults(ChoiceItemBuilder.defaults, context);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
[Symbol.for("nodejs.util.inspect.custom")](): string {
|
|
109
|
+
return createInspectMethod("ChoiceItemBuilder", this.values);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Creates a new ChoiceItem builder
|
|
115
|
+
* @param initial Optional initial values
|
|
116
|
+
* @returns A fluent builder for ChoiceItem
|
|
117
|
+
*/
|
|
118
|
+
export function choiceItem<AnyAsset extends Asset = Asset>(initial?: FluentPartial<ChoiceItem<AnyAsset>>): ChoiceItemBuilder<AnyAsset> {
|
|
119
|
+
return new ChoiceItemBuilder<AnyAsset>(initial);
|
|
120
|
+
}
|