@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.
Files changed (134) hide show
  1. package/dist/cjs/index.cjs +2396 -0
  2. package/dist/cjs/index.cjs.map +1 -0
  3. package/dist/index.legacy-esm.js +2276 -0
  4. package/dist/index.mjs +2276 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/package.json +38 -0
  7. package/src/core/base-builder/__tests__/fluent-builder-base.test.ts +2423 -0
  8. package/src/core/base-builder/__tests__/fluent-partial.test.ts +179 -0
  9. package/src/core/base-builder/__tests__/id-generator.test.ts +658 -0
  10. package/src/core/base-builder/__tests__/registry.test.ts +534 -0
  11. package/src/core/base-builder/__tests__/resolution-mixed-arrays.test.ts +319 -0
  12. package/src/core/base-builder/__tests__/resolution-pipeline.test.ts +416 -0
  13. package/src/core/base-builder/__tests__/resolution-switches.test.ts +468 -0
  14. package/src/core/base-builder/__tests__/resolution-templates.test.ts +255 -0
  15. package/src/core/base-builder/__tests__/switch.test.ts +815 -0
  16. package/src/core/base-builder/__tests__/template.test.ts +596 -0
  17. package/src/core/base-builder/__tests__/value-extraction.test.ts +200 -0
  18. package/src/core/base-builder/__tests__/value-storage.test.ts +459 -0
  19. package/src/core/base-builder/conditional/index.ts +64 -0
  20. package/src/core/base-builder/context.ts +152 -0
  21. package/src/core/base-builder/errors.ts +69 -0
  22. package/src/core/base-builder/fluent-builder-base.ts +308 -0
  23. package/src/core/base-builder/guards.ts +137 -0
  24. package/src/core/base-builder/id/generator.ts +290 -0
  25. package/src/core/base-builder/id/registry.ts +152 -0
  26. package/src/core/base-builder/index.ts +72 -0
  27. package/src/core/base-builder/resolution/path-resolver.ts +116 -0
  28. package/src/core/base-builder/resolution/pipeline.ts +103 -0
  29. package/src/core/base-builder/resolution/steps/__tests__/nested-asset-wrappers.test.ts +206 -0
  30. package/src/core/base-builder/resolution/steps/asset-id.ts +77 -0
  31. package/src/core/base-builder/resolution/steps/asset-wrappers.ts +64 -0
  32. package/src/core/base-builder/resolution/steps/builders.ts +84 -0
  33. package/src/core/base-builder/resolution/steps/mixed-arrays.ts +95 -0
  34. package/src/core/base-builder/resolution/steps/nested-asset-wrappers.ts +124 -0
  35. package/src/core/base-builder/resolution/steps/static-values.ts +35 -0
  36. package/src/core/base-builder/resolution/steps/switches.ts +71 -0
  37. package/src/core/base-builder/resolution/steps/templates.ts +40 -0
  38. package/src/core/base-builder/resolution/value-resolver.ts +333 -0
  39. package/src/core/base-builder/storage/auxiliary-storage.ts +82 -0
  40. package/src/core/base-builder/storage/value-storage.ts +282 -0
  41. package/src/core/base-builder/types.ts +266 -0
  42. package/src/core/base-builder/utils.ts +10 -0
  43. package/src/core/flow/__tests__/index.test.ts +292 -0
  44. package/src/core/flow/index.ts +118 -0
  45. package/src/core/index.ts +8 -0
  46. package/src/core/mocks/generated/action.builder.ts +92 -0
  47. package/src/core/mocks/generated/choice-item.builder.ts +120 -0
  48. package/src/core/mocks/generated/choice.builder.ts +134 -0
  49. package/src/core/mocks/generated/collection.builder.ts +93 -0
  50. package/src/core/mocks/generated/field-collection.builder.ts +86 -0
  51. package/src/core/mocks/generated/index.ts +10 -0
  52. package/src/core/mocks/generated/info.builder.ts +64 -0
  53. package/src/core/mocks/generated/input.builder.ts +63 -0
  54. package/src/core/mocks/generated/overview-collection.builder.ts +65 -0
  55. package/src/core/mocks/generated/splash-collection.builder.ts +93 -0
  56. package/src/core/mocks/generated/text.builder.ts +47 -0
  57. package/src/core/mocks/index.ts +1 -0
  58. package/src/core/mocks/types/action.ts +92 -0
  59. package/src/core/mocks/types/choice.ts +129 -0
  60. package/src/core/mocks/types/collection.ts +140 -0
  61. package/src/core/mocks/types/info.ts +7 -0
  62. package/src/core/mocks/types/input.ts +7 -0
  63. package/src/core/mocks/types/text.ts +5 -0
  64. package/src/core/schema/__tests__/index.test.ts +127 -0
  65. package/src/core/schema/index.ts +195 -0
  66. package/src/core/schema/types.ts +7 -0
  67. package/src/core/switch/__tests__/index.test.ts +156 -0
  68. package/src/core/switch/index.ts +81 -0
  69. package/src/core/tagged-template/README.md +448 -0
  70. package/src/core/tagged-template/__tests__/extract-bindings-from-schema.test.ts +207 -0
  71. package/src/core/tagged-template/__tests__/index.test.ts +190 -0
  72. package/src/core/tagged-template/__tests__/schema-std-integration.test.ts +580 -0
  73. package/src/core/tagged-template/binding.ts +95 -0
  74. package/src/core/tagged-template/expression.ts +92 -0
  75. package/src/core/tagged-template/extract-bindings-from-schema.ts +120 -0
  76. package/src/core/tagged-template/index.ts +5 -0
  77. package/src/core/tagged-template/std.ts +472 -0
  78. package/src/core/tagged-template/types.ts +123 -0
  79. package/src/core/template/__tests__/index.test.ts +380 -0
  80. package/src/core/template/index.ts +196 -0
  81. package/src/core/utils/index.ts +160 -0
  82. package/src/fp/README.md +411 -0
  83. package/src/fp/__tests__/index.test.ts +1178 -0
  84. package/src/fp/index.ts +386 -0
  85. package/src/gen/common.ts +15 -0
  86. package/src/index.ts +5 -0
  87. package/src/types.ts +203 -0
  88. package/types/core/base-builder/conditional/index.d.ts +21 -0
  89. package/types/core/base-builder/context.d.ts +39 -0
  90. package/types/core/base-builder/errors.d.ts +45 -0
  91. package/types/core/base-builder/fluent-builder-base.d.ts +147 -0
  92. package/types/core/base-builder/guards.d.ts +58 -0
  93. package/types/core/base-builder/id/generator.d.ts +69 -0
  94. package/types/core/base-builder/id/registry.d.ts +93 -0
  95. package/types/core/base-builder/index.d.ts +9 -0
  96. package/types/core/base-builder/resolution/path-resolver.d.ts +15 -0
  97. package/types/core/base-builder/resolution/pipeline.d.ts +27 -0
  98. package/types/core/base-builder/resolution/steps/asset-id.d.ts +14 -0
  99. package/types/core/base-builder/resolution/steps/asset-wrappers.d.ts +14 -0
  100. package/types/core/base-builder/resolution/steps/builders.d.ts +14 -0
  101. package/types/core/base-builder/resolution/steps/mixed-arrays.d.ts +14 -0
  102. package/types/core/base-builder/resolution/steps/nested-asset-wrappers.d.ts +14 -0
  103. package/types/core/base-builder/resolution/steps/static-values.d.ts +14 -0
  104. package/types/core/base-builder/resolution/steps/switches.d.ts +15 -0
  105. package/types/core/base-builder/resolution/steps/templates.d.ts +14 -0
  106. package/types/core/base-builder/resolution/value-resolver.d.ts +62 -0
  107. package/types/core/base-builder/storage/auxiliary-storage.d.ts +50 -0
  108. package/types/core/base-builder/storage/value-storage.d.ts +82 -0
  109. package/types/core/base-builder/types.d.ts +183 -0
  110. package/types/core/base-builder/utils.d.ts +2 -0
  111. package/types/core/flow/index.d.ts +23 -0
  112. package/types/core/index.d.ts +8 -0
  113. package/types/core/mocks/index.d.ts +2 -0
  114. package/types/core/mocks/types/action.d.ts +58 -0
  115. package/types/core/mocks/types/choice.d.ts +95 -0
  116. package/types/core/mocks/types/collection.d.ts +102 -0
  117. package/types/core/mocks/types/info.d.ts +7 -0
  118. package/types/core/mocks/types/input.d.ts +7 -0
  119. package/types/core/mocks/types/text.d.ts +5 -0
  120. package/types/core/schema/index.d.ts +34 -0
  121. package/types/core/schema/types.d.ts +5 -0
  122. package/types/core/switch/index.d.ts +21 -0
  123. package/types/core/tagged-template/binding.d.ts +19 -0
  124. package/types/core/tagged-template/expression.d.ts +11 -0
  125. package/types/core/tagged-template/extract-bindings-from-schema.d.ts +7 -0
  126. package/types/core/tagged-template/index.d.ts +6 -0
  127. package/types/core/tagged-template/std.d.ts +174 -0
  128. package/types/core/tagged-template/types.d.ts +69 -0
  129. package/types/core/template/index.d.ts +97 -0
  130. package/types/core/utils/index.d.ts +47 -0
  131. package/types/fp/index.d.ts +149 -0
  132. package/types/gen/common.d.ts +6 -0
  133. package/types/index.d.ts +3 -0
  134. package/types/types.d.ts +163 -0
@@ -0,0 +1,416 @@
1
+ import { describe, test, expect, beforeEach, vi } from "vitest";
2
+ import type { BaseBuildContext } from "../types";
3
+ import { ValueStorage } from "../storage/value-storage";
4
+ import { AuxiliaryStorage } from "../storage/auxiliary-storage";
5
+ import { executeBuildPipeline } from "../resolution/pipeline";
6
+
7
+ // Mock the resolution steps
8
+ vi.mock("../resolution/steps/static-values", () => ({
9
+ resolveStaticValues: vi.fn(),
10
+ }));
11
+
12
+ vi.mock("../resolution/steps/asset-id", () => ({
13
+ generateAssetIdForBuilder: vi.fn(),
14
+ }));
15
+
16
+ vi.mock("../resolution/steps/asset-wrappers", () => ({
17
+ resolveAssetWrappers: vi.fn(),
18
+ }));
19
+
20
+ vi.mock("../resolution/steps/mixed-arrays", () => ({
21
+ resolveMixedArrays: vi.fn(),
22
+ }));
23
+
24
+ vi.mock("../resolution/steps/builders", () => ({
25
+ resolveBuilders: vi.fn(),
26
+ }));
27
+
28
+ vi.mock("../resolution/steps/switches", () => ({
29
+ resolveSwitches: vi.fn(),
30
+ }));
31
+
32
+ vi.mock("../resolution/steps/templates", () => ({
33
+ resolveTemplates: vi.fn(),
34
+ }));
35
+
36
+ import { resolveStaticValues } from "../resolution/steps/static-values";
37
+ import { generateAssetIdForBuilder } from "../resolution/steps/asset-id";
38
+ import { resolveAssetWrappers } from "../resolution/steps/asset-wrappers";
39
+ import { resolveMixedArrays } from "../resolution/steps/mixed-arrays";
40
+ import { resolveBuilders } from "../resolution/steps/builders";
41
+ import { resolveSwitches } from "../resolution/steps/switches";
42
+ import { resolveTemplates } from "../resolution/steps/templates";
43
+
44
+ interface TestType {
45
+ id?: string;
46
+ type?: string;
47
+ value?: string;
48
+ label?: string;
49
+ }
50
+
51
+ describe("executeBuildPipeline", () => {
52
+ let valueStorage: ValueStorage<TestType>;
53
+ let auxiliaryStorage: AuxiliaryStorage;
54
+ let arrayProperties: ReadonlySet<string>;
55
+
56
+ beforeEach(() => {
57
+ vi.clearAllMocks();
58
+ valueStorage = new ValueStorage<TestType>();
59
+ auxiliaryStorage = new AuxiliaryStorage();
60
+ arrayProperties = new Set(["values"]);
61
+ });
62
+
63
+ test("executes all 8 steps in correct order", () => {
64
+ const callOrder: string[] = [];
65
+
66
+ vi.mocked(resolveStaticValues).mockImplementation(() => {
67
+ callOrder.push("resolveStaticValues");
68
+ });
69
+ vi.mocked(generateAssetIdForBuilder).mockImplementation(() => {
70
+ callOrder.push("generateAssetIdForBuilder");
71
+ });
72
+ vi.mocked(resolveAssetWrappers).mockImplementation(() => {
73
+ callOrder.push("resolveAssetWrappers");
74
+ });
75
+ vi.mocked(resolveMixedArrays).mockImplementation(() => {
76
+ callOrder.push("resolveMixedArrays");
77
+ });
78
+ vi.mocked(resolveBuilders).mockImplementation(() => {
79
+ callOrder.push("resolveBuilders");
80
+ });
81
+ vi.mocked(resolveSwitches).mockImplementation(() => {
82
+ callOrder.push("resolveSwitches");
83
+ });
84
+ vi.mocked(resolveTemplates).mockImplementation(() => {
85
+ callOrder.push("resolveTemplates");
86
+ });
87
+
88
+ const context: BaseBuildContext = { parentId: "test" };
89
+ executeBuildPipeline(
90
+ valueStorage,
91
+ auxiliaryStorage,
92
+ undefined,
93
+ context,
94
+ arrayProperties,
95
+ );
96
+
97
+ expect(callOrder).toEqual([
98
+ "resolveStaticValues",
99
+ "generateAssetIdForBuilder",
100
+ "resolveAssetWrappers",
101
+ "resolveMixedArrays",
102
+ "resolveBuilders",
103
+ "resolveSwitches",
104
+ "resolveTemplates",
105
+ ]);
106
+ });
107
+
108
+ test("merges defaults into result", () => {
109
+ const defaults: Partial<TestType> = {
110
+ type: "test",
111
+ id: "default-id",
112
+ };
113
+
114
+ const result = executeBuildPipeline(
115
+ valueStorage,
116
+ auxiliaryStorage,
117
+ defaults,
118
+ undefined,
119
+ arrayProperties,
120
+ );
121
+
122
+ expect(result).toMatchObject({
123
+ type: "test",
124
+ id: "default-id",
125
+ });
126
+ });
127
+
128
+ test("handles empty storage gracefully", () => {
129
+ const emptyValueStorage = new ValueStorage<TestType>();
130
+ const emptyAuxiliaryStorage = new AuxiliaryStorage();
131
+
132
+ const result = executeBuildPipeline(
133
+ emptyValueStorage,
134
+ emptyAuxiliaryStorage,
135
+ undefined,
136
+ undefined,
137
+ new Set(),
138
+ );
139
+
140
+ expect(result).toEqual({});
141
+ expect(resolveStaticValues).toHaveBeenCalled();
142
+ });
143
+
144
+ test("passes correct context to nested steps", () => {
145
+ const context: BaseBuildContext = { parentId: "parent-1" };
146
+
147
+ // Mock generateAssetIdForBuilder to set the id in result
148
+ vi.mocked(generateAssetIdForBuilder).mockImplementation(
149
+ (_storage, result) => {
150
+ (result as Record<string, unknown>).id = "parent-1-test";
151
+ },
152
+ );
153
+
154
+ executeBuildPipeline(
155
+ valueStorage,
156
+ auxiliaryStorage,
157
+ undefined,
158
+ context,
159
+ arrayProperties,
160
+ );
161
+
162
+ // Verify resolveAssetWrappers receives nested context with parentId
163
+ expect(resolveAssetWrappers).toHaveBeenCalledWith(
164
+ valueStorage,
165
+ expect.objectContaining({ id: "parent-1-test" }),
166
+ expect.objectContaining({ parentId: "parent-1-test", branch: undefined }),
167
+ );
168
+ });
169
+
170
+ test("passes arrayProperties to resolveSwitches", () => {
171
+ const context: BaseBuildContext = { parentId: "test" };
172
+ const customArrayProps = new Set(["values", "actions", "items"]);
173
+
174
+ executeBuildPipeline(
175
+ valueStorage,
176
+ auxiliaryStorage,
177
+ undefined,
178
+ context,
179
+ customArrayProps,
180
+ );
181
+
182
+ expect(resolveSwitches).toHaveBeenCalledWith(
183
+ auxiliaryStorage,
184
+ expect.any(Object),
185
+ expect.any(Object),
186
+ customArrayProps,
187
+ );
188
+ });
189
+ });
190
+
191
+ describe("createNestedParentContext", () => {
192
+ // Test the context creation logic directly through executeBuildPipeline behavior
193
+
194
+ beforeEach(() => {
195
+ vi.clearAllMocks();
196
+ });
197
+
198
+ test("creates context with parentId from generated asset ID", () => {
199
+ const valueStorage = new ValueStorage<TestType>();
200
+ const auxiliaryStorage = new AuxiliaryStorage();
201
+ const context: BaseBuildContext = { parentId: "root" };
202
+
203
+ // Simulate generating an ID
204
+ vi.mocked(generateAssetIdForBuilder).mockImplementation(
205
+ (_storage, result) => {
206
+ (result as Record<string, unknown>).id = "root-test";
207
+ },
208
+ );
209
+
210
+ let capturedNestedContext: BaseBuildContext | undefined;
211
+ vi.mocked(resolveAssetWrappers).mockImplementation(
212
+ (_storage, _result, nestedCtx) => {
213
+ capturedNestedContext = nestedCtx;
214
+ },
215
+ );
216
+
217
+ executeBuildPipeline(
218
+ valueStorage,
219
+ auxiliaryStorage,
220
+ undefined,
221
+ context,
222
+ new Set(),
223
+ );
224
+
225
+ expect(capturedNestedContext).toBeDefined();
226
+ expect(capturedNestedContext?.parentId).toBe("root-test");
227
+ });
228
+
229
+ test("clears branch from nested context", () => {
230
+ const valueStorage = new ValueStorage<TestType>();
231
+ const auxiliaryStorage = new AuxiliaryStorage();
232
+ const context: BaseBuildContext = {
233
+ parentId: "root",
234
+ branch: { type: "slot", name: "label" },
235
+ };
236
+
237
+ vi.mocked(generateAssetIdForBuilder).mockImplementation(
238
+ (_storage, result) => {
239
+ (result as Record<string, unknown>).id = "root-label-test";
240
+ },
241
+ );
242
+
243
+ let capturedNestedContext: BaseBuildContext | undefined;
244
+ vi.mocked(resolveAssetWrappers).mockImplementation(
245
+ (_storage, _result, nestedCtx) => {
246
+ capturedNestedContext = nestedCtx;
247
+ },
248
+ );
249
+
250
+ executeBuildPipeline(
251
+ valueStorage,
252
+ auxiliaryStorage,
253
+ undefined,
254
+ context,
255
+ new Set(),
256
+ );
257
+
258
+ expect(capturedNestedContext).toBeDefined();
259
+ expect(capturedNestedContext?.branch).toBeUndefined();
260
+ });
261
+
262
+ test("returns undefined when no parent context", () => {
263
+ const valueStorage = new ValueStorage<TestType>();
264
+ const auxiliaryStorage = new AuxiliaryStorage();
265
+
266
+ let capturedNestedContext: BaseBuildContext | undefined = {
267
+ parentId: "should-be-cleared",
268
+ };
269
+ vi.mocked(resolveAssetWrappers).mockImplementation(
270
+ (_storage, _result, nestedCtx) => {
271
+ capturedNestedContext = nestedCtx;
272
+ },
273
+ );
274
+
275
+ executeBuildPipeline(
276
+ valueStorage,
277
+ auxiliaryStorage,
278
+ undefined,
279
+ undefined, // No context
280
+ new Set(),
281
+ );
282
+
283
+ expect(capturedNestedContext).toBeUndefined();
284
+ });
285
+
286
+ test("preserves other context properties in nested context", () => {
287
+ const valueStorage = new ValueStorage<TestType>();
288
+ const auxiliaryStorage = new AuxiliaryStorage();
289
+
290
+ interface ExtendedContext extends BaseBuildContext {
291
+ customProperty: string;
292
+ }
293
+
294
+ const context: ExtendedContext = {
295
+ parentId: "root",
296
+ customProperty: "custom-value",
297
+ branch: { type: "slot", name: "test" },
298
+ };
299
+
300
+ vi.mocked(generateAssetIdForBuilder).mockImplementation(
301
+ (_storage, result) => {
302
+ (result as Record<string, unknown>).id = "root-test-asset";
303
+ },
304
+ );
305
+
306
+ let capturedNestedContext: ExtendedContext | undefined;
307
+ vi.mocked(resolveAssetWrappers).mockImplementation(
308
+ (_storage, _result, nestedCtx) => {
309
+ capturedNestedContext = nestedCtx as ExtendedContext;
310
+ },
311
+ );
312
+
313
+ executeBuildPipeline(
314
+ valueStorage,
315
+ auxiliaryStorage,
316
+ undefined,
317
+ context,
318
+ new Set(),
319
+ );
320
+
321
+ expect(capturedNestedContext).toBeDefined();
322
+ expect(capturedNestedContext?.customProperty).toBe("custom-value");
323
+ expect(capturedNestedContext?.parentId).toBe("root-test-asset");
324
+ expect(capturedNestedContext?.branch).toBeUndefined();
325
+ });
326
+ });
327
+
328
+ describe("Pipeline Step Order Verification", () => {
329
+ beforeEach(() => {
330
+ vi.clearAllMocks();
331
+ });
332
+
333
+ test("static values are resolved before asset ID generation", () => {
334
+ const callOrder: number[] = [];
335
+
336
+ vi.mocked(resolveStaticValues).mockImplementation(() => {
337
+ callOrder.push(1);
338
+ });
339
+ vi.mocked(generateAssetIdForBuilder).mockImplementation(() => {
340
+ callOrder.push(2);
341
+ });
342
+
343
+ executeBuildPipeline(
344
+ new ValueStorage<TestType>(),
345
+ new AuxiliaryStorage(),
346
+ undefined,
347
+ { parentId: "test" },
348
+ new Set(),
349
+ );
350
+
351
+ expect(callOrder.indexOf(1)).toBeLessThan(callOrder.indexOf(2));
352
+ });
353
+
354
+ test("asset ID is generated before nested context is created", () => {
355
+ let idWhenAssetWrappersCall: string | undefined;
356
+
357
+ vi.mocked(generateAssetIdForBuilder).mockImplementation(
358
+ (_storage, result) => {
359
+ (result as Record<string, unknown>).id = "generated-id";
360
+ },
361
+ );
362
+
363
+ vi.mocked(resolveAssetWrappers).mockImplementation(
364
+ (_storage, result, _ctx) => {
365
+ idWhenAssetWrappersCall = (result as Record<string, unknown>)
366
+ .id as string;
367
+ },
368
+ );
369
+
370
+ executeBuildPipeline(
371
+ new ValueStorage<TestType>(),
372
+ new AuxiliaryStorage(),
373
+ undefined,
374
+ { parentId: "test" },
375
+ new Set(),
376
+ );
377
+
378
+ expect(idWhenAssetWrappersCall).toBe("generated-id");
379
+ });
380
+
381
+ test("templates are resolved last", () => {
382
+ const callOrder: string[] = [];
383
+
384
+ vi.mocked(resolveStaticValues).mockImplementation(() => {
385
+ callOrder.push("static");
386
+ });
387
+ vi.mocked(generateAssetIdForBuilder).mockImplementation(() => {
388
+ callOrder.push("id");
389
+ });
390
+ vi.mocked(resolveAssetWrappers).mockImplementation(() => {
391
+ callOrder.push("wrappers");
392
+ });
393
+ vi.mocked(resolveMixedArrays).mockImplementation(() => {
394
+ callOrder.push("mixedArrays");
395
+ });
396
+ vi.mocked(resolveBuilders).mockImplementation(() => {
397
+ callOrder.push("builders");
398
+ });
399
+ vi.mocked(resolveSwitches).mockImplementation(() => {
400
+ callOrder.push("switches");
401
+ });
402
+ vi.mocked(resolveTemplates).mockImplementation(() => {
403
+ callOrder.push("templates");
404
+ });
405
+
406
+ executeBuildPipeline(
407
+ new ValueStorage<TestType>(),
408
+ new AuxiliaryStorage(),
409
+ undefined,
410
+ { parentId: "test" },
411
+ new Set(),
412
+ );
413
+
414
+ expect(callOrder[callOrder.length - 1]).toBe("templates");
415
+ });
416
+ });