@komaci/esm-generator 244.2.0 → 244.2.1

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.
@@ -35,6 +35,7 @@ const common_shared_1 = require("@komaci/common-shared");
35
35
  const generator_1 = __importDefault(require("@babel/generator"));
36
36
  const complexDoc = JSON.parse(fs.readFileSync((0, path_1.join)(__dirname, './general-komaci-docs/complexTemplateDoc/template.json'), 'utf-8'));
37
37
  describe('imageToExpression', () => {
38
+ const moduleMetadata = (0, common_shared_1.initModuleMetadataObject)();
38
39
  it('should return an expression for a KomaciDocument Image node', () => {
39
40
  const komaciDocImagePrimitive = {
40
41
  type: 'Image',
@@ -43,13 +44,13 @@ describe('imageToExpression', () => {
43
44
  value: 'testPrimitive.jpg', // this is string literal of a relative URL
44
45
  },
45
46
  };
46
- let expression = (0, compositionAstGeneration_1.imageToExpression)(komaciDocImagePrimitive);
47
+ let expression = (0, compositionAstGeneration_1.imageToExpression)(moduleMetadata, komaciDocImagePrimitive);
47
48
  expect(expression.type).toBe('CallExpression');
48
49
  let callExpression = expression;
49
50
  expect(callExpression).not.toBeUndefined();
50
51
  expect(callExpression.callee).toBe(types_2.ID.IMG_FUNC);
51
52
  expect(callExpression.arguments).not.toBeUndefined();
52
- expect(callExpression.arguments).toHaveLength(1);
53
+ expect(callExpression.arguments).toHaveLength(2);
53
54
  expect(callExpression.arguments[0]).not.toBeUndefined();
54
55
  expect(callExpression.arguments[0].type).toBe('ObjectExpression');
55
56
  let objExpression = callExpression
@@ -59,7 +60,8 @@ describe('imageToExpression', () => {
59
60
  expect(objExpression.properties[0].type).toBe('ObjectProperty');
60
61
  let objProperty = objExpression.properties[0];
61
62
  expect(objProperty.key).toBe(types_2.ID.IMG_SRC);
62
- expect(objProperty.value).toEqual((0, types_1.stringLiteral)('testPrimitive.jpg')); // img({src: "testPrimitive.jpg"})
63
+ expect(objProperty.value.properties[1]
64
+ .value).toEqual((0, types_1.stringLiteral)('testPrimitive.jpg')); // img({src: "testPrimitive.jpg"})
63
65
  const komaciDocImageBinding = {
64
66
  type: 'Image',
65
67
  src: {
@@ -67,13 +69,13 @@ describe('imageToExpression', () => {
67
69
  value: 'testBinding', // this is a string literal, but represents a variable name
68
70
  },
69
71
  };
70
- expression = (0, compositionAstGeneration_1.imageToExpression)(komaciDocImageBinding);
72
+ expression = (0, compositionAstGeneration_1.imageToExpression)(moduleMetadata, komaciDocImageBinding);
71
73
  expect(expression.type).toBe('CallExpression');
72
74
  callExpression = expression;
73
75
  expect(callExpression).not.toBeUndefined();
74
76
  expect(callExpression.callee).toBe(types_2.ID.IMG_FUNC);
75
77
  expect(callExpression.arguments).not.toBeUndefined();
76
- expect(callExpression.arguments).toHaveLength(1);
78
+ expect(callExpression.arguments).toHaveLength(2);
77
79
  expect(callExpression.arguments[0]).not.toBeUndefined();
78
80
  expect(callExpression.arguments[0].type).toBe('ObjectExpression');
79
81
  objExpression = callExpression.arguments[0];
@@ -83,12 +85,13 @@ describe('imageToExpression', () => {
83
85
  expect(objExpression.properties[0].type).toBe('ObjectProperty');
84
86
  objProperty = objExpression.properties[0];
85
87
  expect(objProperty.key).toBe(types_2.ID.IMG_SRC);
86
- let segments = ['ctx', 'props', 'testBinding'];
88
+ const segments = ['ctx', 'props', 'testBinding'];
87
89
  let expr = (0, types_1.identifier)(segments[0]);
88
90
  for (let i = 1; i < segments.length; i++) {
89
91
  expr = (0, types_1.optionalMemberExpression)(expr, (0, types_1.identifier)(segments[i]), false, false);
90
92
  }
91
- expect(objProperty.value).toEqual(expr); // img({src: ctx.props.testBinding})
93
+ expect(objProperty.value.properties[1]
94
+ .value).toEqual((0, types_1.stringLiteral)('testBinding')); // img({src: ctx.props.testBinding})
92
95
  const komaciDocImageNestedBinding = {
93
96
  type: 'Image',
94
97
  src: {
@@ -96,13 +99,13 @@ describe('imageToExpression', () => {
96
99
  value: 'imageObject/nested/imageName', // this is a string literal, represents nested-scoped variable names
97
100
  },
98
101
  };
99
- expression = (0, compositionAstGeneration_1.imageToExpression)(komaciDocImageNestedBinding);
102
+ expression = (0, compositionAstGeneration_1.imageToExpression)(moduleMetadata, komaciDocImageNestedBinding);
100
103
  expect(expression.type).toBe('CallExpression');
101
104
  callExpression = expression;
102
105
  expect(callExpression).not.toBeUndefined();
103
106
  expect(callExpression.callee).toBe(types_2.ID.IMG_FUNC);
104
107
  expect(callExpression.arguments).not.toBeUndefined();
105
- expect(callExpression.arguments).toHaveLength(1);
108
+ expect(callExpression.arguments).toHaveLength(2);
106
109
  expect(callExpression.arguments[0]).not.toBeUndefined();
107
110
  expect(callExpression.arguments[0].type).toBe('ObjectExpression');
108
111
  objExpression = callExpression.arguments[0];
@@ -112,13 +115,8 @@ describe('imageToExpression', () => {
112
115
  expect(objExpression.properties[0].type).toBe('ObjectProperty');
113
116
  objProperty = objExpression.properties[0];
114
117
  expect(objProperty.key).toBe(types_2.ID.IMG_SRC);
115
- segments = ['ctx', 'props', 'imageObject', 'nested', 'imageName'];
116
- expr = (0, types_1.identifier)(segments[0]);
117
- const chainingStartIdx = 2;
118
- for (let i = 1; i < segments.length; i++) {
119
- expr = (0, types_1.optionalMemberExpression)(expr, (0, types_1.identifier)(segments[i]), false, i > chainingStartIdx);
120
- }
121
- expect(objProperty.value).toEqual(expr); // img({src: ctx.props.imageObject?.nested?.imageName})
118
+ expect(objProperty.value.properties[1]
119
+ .value).toEqual((0, types_1.stringLiteral)('imageObject.nested.imageName'));
122
120
  });
123
121
  it('should not return an expression for invalid KomaciDocument Image nodes due to invalid src.value type (boolean)', () => {
124
122
  const komaciDocImagePrimitive = {
@@ -128,14 +126,14 @@ describe('imageToExpression', () => {
128
126
  value: false, // not a supported type (boolean)
129
127
  },
130
128
  };
131
- const expression = (0, compositionAstGeneration_1.imageToExpression)(komaciDocImagePrimitive);
129
+ const expression = (0, compositionAstGeneration_1.imageToExpression)(moduleMetadata, komaciDocImagePrimitive);
132
130
  expect(expression.type).toBe('CallExpression');
133
131
  const callExpression = expression;
134
132
  expect(callExpression).not.toBeUndefined();
135
133
  expect(callExpression.callee).not.toBeUndefined();
136
134
  expect(callExpression.callee).toBe(types_2.ID.IMG_FUNC);
137
135
  expect(callExpression.arguments).not.toBeUndefined();
138
- expect(callExpression.arguments).toHaveLength(1);
136
+ expect(callExpression.arguments).toHaveLength(2);
139
137
  expect(callExpression.arguments[0].type).toBe('ObjectExpression');
140
138
  const objExpression = callExpression
141
139
  .arguments[0];
@@ -150,15 +148,15 @@ describe('imageToExpression', () => {
150
148
  value: '', // blanks not supported
151
149
  },
152
150
  };
153
- let expression = (0, compositionAstGeneration_1.imageToExpression)(komaciDocImagePrimitiveBlank);
154
- expression = (0, compositionAstGeneration_1.imageToExpression)(komaciDocImagePrimitiveBlank);
151
+ let expression = (0, compositionAstGeneration_1.imageToExpression)(moduleMetadata, komaciDocImagePrimitiveBlank);
152
+ expression = (0, compositionAstGeneration_1.imageToExpression)(moduleMetadata, komaciDocImagePrimitiveBlank);
155
153
  expect(expression.type).toBe('CallExpression');
156
154
  const callExpression = expression;
157
155
  expect(callExpression).not.toBeUndefined();
158
156
  expect(callExpression.callee).not.toBeUndefined();
159
157
  expect(callExpression.callee).toBe(types_2.ID.IMG_FUNC);
160
158
  expect(callExpression.arguments).not.toBeUndefined();
161
- expect(callExpression.arguments).toHaveLength(1);
159
+ expect(callExpression.arguments).toHaveLength(2);
162
160
  expect(callExpression.arguments[0].type).toBe('ObjectExpression');
163
161
  const objExpression = callExpression
164
162
  .arguments[0];
@@ -175,15 +173,15 @@ describe('imageToExpression', () => {
175
173
  };
176
174
  // change the src.value type to something invalid, a number
177
175
  komaciDocImageInvalidSrcValType.src.value = 12345;
178
- let expression = (0, compositionAstGeneration_1.imageToExpression)(komaciDocImageInvalidSrcValType);
179
- expression = (0, compositionAstGeneration_1.imageToExpression)(komaciDocImageInvalidSrcValType);
176
+ let expression = (0, compositionAstGeneration_1.imageToExpression)(moduleMetadata, komaciDocImageInvalidSrcValType);
177
+ expression = (0, compositionAstGeneration_1.imageToExpression)(moduleMetadata, komaciDocImageInvalidSrcValType);
180
178
  expect(expression.type).toBe('CallExpression');
181
179
  const callExpression = expression;
182
180
  expect(callExpression).not.toBeUndefined();
183
181
  expect(callExpression.callee).not.toBeUndefined();
184
182
  expect(callExpression.callee).toBe(types_2.ID.IMG_FUNC);
185
183
  expect(callExpression.arguments).not.toBeUndefined();
186
- expect(callExpression.arguments).toHaveLength(1);
184
+ expect(callExpression.arguments).toHaveLength(2);
187
185
  expect(callExpression.arguments[0].type).toBe('ObjectExpression');
188
186
  const objExpression = callExpression
189
187
  .arguments[0];
@@ -218,23 +216,66 @@ describe('compositionToExpression', () => {
218
216
  (0, common_shared_1.initializeImportMetdataFromKomaciDocument)(complexDoc, moduleMetadata, 0);
219
217
  moduleMetadata.adgs.set(0, (0, common_shared_1.initAdgMetadataObject)('adg0'));
220
218
  (0, common_shared_1.addTemplateUsageForAdg)(complexDoc, 0, moduleMetadata);
221
- it('effectiely builds a conditional expression for a component with isActive', () => {
219
+ it('effectively builds a conditional expression for a component with isActive', () => {
222
220
  const res = (0, compositionAstGeneration_1.compositionToExpression)(moduleMetadata, complexDoc.compositions[0].compositions[2].compositions[1]);
223
- expect(res.type).toBe('ConditionalExpression');
221
+ expect(res.type).toBe('CallExpression');
222
+ expect(res.callee).toBe(types_2.ID.CONDITION_FUNC);
224
223
  const code = (0, generator_1.default)(res).code;
225
- expect(code).toBe('u(ctx.props.apexResult) || ctx.props.apexResult ? [i(ctx.props.apexResult?.data?.names, ctx, user_var_test => {\n return [e({}, ctx, []), cg(i4, {\n componentId: "c-name-detail",\n props: {\n name: user_var_test.value?.name\n }\n }, ctx)];\n}), u(ctx.props.apexResult) || ctx.props.apexResult?.data ? i(ctx.props.apexResult?.data, ctx, user_var_contactName => {\n return [e({}, ctx, [])];\n}) : undefined, u(ctx.props.apexResult) || ctx.props.apexResult?.error ? [] : undefined] : undefined');
224
+ expect(code).toBe(`c(ctx, {
225
+ c: {
226
+ t: "b",
227
+ v: "apexResult"
228
+ },
229
+ slot: ""
230
+ }, ctx => [i({
231
+ c: {
232
+ t: "b",
233
+ v: "apexResult.data.names"
234
+ }
235
+ }, ctx, user_var_test => {
236
+ return [e({}, ctx, []), cg(i4, {
237
+ componentId: "c-name-detail",
238
+ props: ctx => ({
239
+ name: user_var_test.value?.name
240
+ })
241
+ }, ctx, [], [])];
242
+ }), c(ctx, {
243
+ c: {
244
+ t: "b",
245
+ v: "apexResult.data"
246
+ }
247
+ }, ctx => i({
248
+ c: {
249
+ t: "b",
250
+ v: "apexResult.data"
251
+ }
252
+ }, ctx, user_var_contactName => {
253
+ return [e({}, ctx, [])];
254
+ }), false), c(ctx, {
255
+ c: {
256
+ t: "b",
257
+ v: "apexResult.error"
258
+ }
259
+ }, ctx => [], false)], false)`);
226
260
  });
227
261
  it('effectiely builds a conditional expression for a component with negated isActive', () => {
228
262
  const res = (0, compositionAstGeneration_1.compositionToExpression)(moduleMetadata, complexDoc.compositions[0].compositions[2].compositions[2]);
229
- expect(res.type).toBe('ConditionalExpression');
263
+ expect(res.type).toBe('CallExpression');
264
+ expect(res.callee).toBe(types_2.ID.CONDITION_FUNC);
230
265
  const code = (0, generator_1.default)(res).code;
231
- expect(code).toBe('u(ctx.props.apexResult) || !ctx.props.apexResult ? [] : undefined');
266
+ expect(code).toBe(`c(ctx, {
267
+ c: {
268
+ t: "b",
269
+ v: "apexResult"
270
+ },
271
+ slot: ""
272
+ }, ctx => [], true)`);
232
273
  });
233
274
  it('returns a basic reference when isActive is not set', () => {
234
275
  const res = (0, compositionAstGeneration_1.compositionToExpression)(moduleMetadata, complexDoc.compositions[0].compositions[2].compositions[0]);
235
276
  expect(res.type).toBe('CallExpression');
236
277
  const code = (0, generator_1.default)(res).code;
237
- expect(code).toBe('cg(i1, {\n slot: "title",\n componentId: "c-title",\n props: {\n icon: "standard:apex",\n size: "medium"\n }\n}, ctx)');
278
+ expect(code).toBe('cg(i1, {\n slot: "title",\n componentId: "c-title",\n props: ctx => ({\n icon: "standard:apex",\n size: "medium"\n })\n}, ctx, [], [])');
238
279
  });
239
280
  });
240
281
  describe('containerToExpression', () => {
@@ -273,14 +314,109 @@ describe('composedAdgToExpression', () => {
273
314
  expect(res.type).toBe('CallExpression');
274
315
  expect(res.callee.name).toBe('cg');
275
316
  const code = (0, generator_1.default)(res).code;
276
- expect(code).toBe('cg(i3, {\n componentId: "c-lookup-field-row",\n props: {\n label: "CreatedBy User Info",\n objectApiName: "User",\n recordId: ctx.props.record?.data?.fields?.CreatedById?.value\n }\n}, ctx)');
317
+ expect(code).toBe('cg(i3, {\n componentId: "c-lookup-field-row",\n props: ctx => ({\n label: "CreatedBy User Info",\n objectApiName: "User",\n recordId: ctx.props.record?.data?.fields?.CreatedById?.value\n })\n}, ctx, [], ["record"])');
277
318
  });
278
319
  it('properly composed composedAdg with children', () => {
279
320
  const res = (0, compositionAstGeneration_1.composedAdgToExpression)(moduleMetadata, complexDoc.compositions[0].compositions[0]);
280
321
  expect(res.type).toBe('CallExpression');
281
322
  expect(res.callee.name).toBe('cg');
282
323
  const code = (0, generator_1.default)(res).code;
283
- expect(code).toBe('cg(i0, {\n componentId: "lightning-card",\n props: {}\n}, ctx, [cg(i1, {\n slot: "title",\n componentId: "c-title",\n props: {\n icon: "standard:account",\n size: "large"\n }\n}, ctx), u(ctx.props.record) || ctx.props.record?.data ? [cg(i2, {\n componentId: "c-fieldrow",\n props: {\n label: "Object Type",\n value: ctx.props.objectApiName\n }\n}, ctx), cg(i2, {\n componentId: "c-fieldrow",\n props: {\n label: "Account Id",\n value: ctx.props.record?.data?.fields?.Id?.value\n }\n}, ctx), cg(i2, {\n componentId: "c-fieldrow",\n props: {\n label: "Account Name",\n value: ctx.props.record?.data?.fields?.Name?.value\n }\n}, ctx), u(ctx.props.ownerRecord) || ctx.props.ownerRecord?.data ? cg(i2, {\n componentId: "c-fieldrow",\n props: {\n label: "Account Owner",\n value: ctx.props.ownerRecord?.data?.fields?.Name?.value\n }\n}, ctx) : undefined, u(ctx.props.createdByRecord) || ctx.props.createdByRecord?.data ? cg(i2, {\n componentId: "c-fieldrow",\n props: {\n label: "Created By",\n value: ctx.props.createdByRecord?.data?.fields?.Name?.value\n }\n}, ctx) : undefined] : undefined])');
324
+ expect(code).toBe(`cg(i0, {
325
+ componentId: "lightning-card",
326
+ props: ctx => ({})
327
+ }, ctx, [cg(i1, {
328
+ slot: "title",
329
+ componentId: "c-title",
330
+ props: ctx => ({
331
+ icon: "standard:account",
332
+ size: "large"
333
+ })
334
+ }, ctx, [], []), c(ctx, {
335
+ c: {
336
+ t: "b",
337
+ v: "record.data"
338
+ },
339
+ slot: ""
340
+ }, ctx => [cg(i2, {
341
+ componentId: "c-fieldrow",
342
+ props: ctx => ({
343
+ label: "Object Type",
344
+ value: ctx.props.objectApiName
345
+ })
346
+ }, ctx, [], ["objectApiName"]), cg(i2, {
347
+ componentId: "c-fieldrow",
348
+ props: ctx => ({
349
+ label: "Account Id",
350
+ value: ctx.props.record?.data?.fields?.Id?.value
351
+ })
352
+ }, ctx, [], ["record"]), cg(i2, {
353
+ componentId: "c-fieldrow",
354
+ props: ctx => ({
355
+ label: "Account Name",
356
+ value: ctx.props.record?.data?.fields?.Name?.value
357
+ })
358
+ }, ctx, [], ["record"]), c(ctx, {
359
+ c: {
360
+ t: "b",
361
+ v: "ownerRecord.data"
362
+ }
363
+ }, ctx => cg(i2, {
364
+ componentId: "c-fieldrow",
365
+ props: ctx => ({
366
+ label: "Account Owner",
367
+ value: ctx.props.ownerRecord?.data?.fields?.Name?.value
368
+ })
369
+ }, ctx, [], ["ownerRecord"]), false), c(ctx, {
370
+ c: {
371
+ t: "b",
372
+ v: "createdByRecord.data"
373
+ }
374
+ }, ctx => cg(i2, {
375
+ componentId: "c-fieldrow",
376
+ props: ctx => ({
377
+ label: "Created By",
378
+ value: ctx.props.createdByRecord?.data?.fields?.Name?.value
379
+ })
380
+ }, ctx, [], ["createdByRecord"]), false)], false)], [])`);
381
+ });
382
+ it('properly generated dependentProps', () => {
383
+ const res = (0, compositionAstGeneration_1.composedAdgToExpression)(moduleMetadata, {
384
+ type: 'ComposedAdg',
385
+ input: {
386
+ type: 'ImportReference',
387
+ value: 't0-0/names/0',
388
+ },
389
+ properties: {
390
+ attr1: {
391
+ type: 'Binding',
392
+ value: 'recordId',
393
+ },
394
+ attr2: {
395
+ type: 'Binding',
396
+ value: 'recordId',
397
+ },
398
+ attr3: {
399
+ type: 'Binding',
400
+ value: 'record',
401
+ },
402
+ attr4: {
403
+ type: 'Binding',
404
+ value: 'record/data/Name',
405
+ },
406
+ },
407
+ });
408
+ expect(res.type).toBe('CallExpression');
409
+ expect(res.callee.name).toBe('cg');
410
+ const code = (0, generator_1.default)(res).code;
411
+ expect(code).toBe(`cg(i0, {
412
+ componentId: "lightning-card",
413
+ props: ctx => ({
414
+ attr1: ctx.props.recordId,
415
+ attr2: ctx.props.recordId,
416
+ attr3: ctx.props.record,
417
+ attr4: ctx.props.record?.data?.Name
418
+ })
419
+ }, ctx, [], ["recordId", "record"])`);
284
420
  });
285
421
  });
286
422
  describe('iterationToExpression', () => {
@@ -321,7 +457,92 @@ describe('iterationToExpression', () => {
321
457
  expect(res.type).toBe('CallExpression');
322
458
  expect(res.callee.name).toBe('i');
323
459
  const code = (0, generator_1.default)(res).code;
324
- expect(code).toBe('i(ctx.props.contacts, ctx, user_var_contact => {\n return [cg(i0, {\n componentId: "lightning-card",\n props: {\n label: user_var_contact.value?.Name,\n myIndex: user_var_contact.index\n }\n }, ctx)];\n})');
460
+ expect(code).toBe(`i({
461
+ c: {
462
+ t: "b",
463
+ v: "contacts"
464
+ }
465
+ }, ctx, user_var_contact => {
466
+ return [cg(i0, {
467
+ componentId: "lightning-card",
468
+ props: ctx => ({
469
+ label: user_var_contact.value?.Name,
470
+ myIndex: user_var_contact.index
471
+ })
472
+ }, ctx, [], [])];
473
+ })`);
474
+ });
475
+ it('can compose an iteration factory call from a two nested iterator composition', () => {
476
+ const res = (0, compositionAstGeneration_1.iterationToExpression)(moduleMetadata, {
477
+ type: 'Iteration',
478
+ input: {
479
+ type: 'Binding',
480
+ value: 'contacts',
481
+ },
482
+ iterator: 'contact',
483
+ compositions: [
484
+ {
485
+ type: 'Iteration',
486
+ input: {
487
+ type: 'Binding',
488
+ value: 'actions',
489
+ },
490
+ iterator: 'action',
491
+ compositions: [
492
+ {
493
+ type: 'ComposedAdg',
494
+ input: {
495
+ type: 'ImportReference',
496
+ value: 't0-0/names/0',
497
+ },
498
+ properties: {
499
+ label: {
500
+ type: 'Binding',
501
+ value: 'contact/value/Name',
502
+ },
503
+ myIndex: {
504
+ type: 'Binding',
505
+ value: 'contact/index',
506
+ },
507
+ actionName: {
508
+ type: 'Binding',
509
+ value: 'action/name',
510
+ },
511
+ },
512
+ key: {
513
+ type: 'Binding',
514
+ value: 'contact/value/Id',
515
+ },
516
+ },
517
+ ],
518
+ },
519
+ ],
520
+ });
521
+ expect(res.type).toBe('CallExpression');
522
+ expect(res.callee.name).toBe('i');
523
+ const code = (0, generator_1.default)(res).code;
524
+ expect(code).toBe(`i({
525
+ c: {
526
+ t: "b",
527
+ v: "contacts"
528
+ }
529
+ }, ctx, user_var_contact => {
530
+ return [i({
531
+ c: {
532
+ t: "b",
533
+ v: "actions"
534
+ }
535
+ }, ctx, user_var_action => {
536
+ return [cg(i0, {
537
+ componentId: "lightning-card",
538
+ props: ctx => ({
539
+ actionName: user_var_action.name,
540
+ label: user_var_contact.value?.Name,
541
+ myIndex: user_var_contact.index
542
+ })
543
+ }, ctx, [], [])];
544
+ })];
545
+ })`);
325
546
  });
326
547
  });
327
548
  describe('slotToExpression', () => {
@@ -372,7 +593,7 @@ describe('getCompositionConfig', () => {
372
593
  it('collects composition config for a composedAdg', () => {
373
594
  const res = (0, compositionAstGeneration_1.getCompositionConfig)(complexDoc.compositions[0].compositions[2].compositions[0]);
374
595
  const code = (0, generator_1.default)(res).code;
375
- expect(code).toBe('{\n slot: "title",\n props: {\n icon: "standard:apex",\n size: "medium"\n }\n}');
596
+ expect(code).toBe('{\n slot: "title",\n props: ctx => ({\n icon: "standard:apex",\n size: "medium"\n })\n}');
376
597
  });
377
598
  it('generates duplicate composition configs for similar composedAdgs', () => {
378
599
  const res = (0, compositionAstGeneration_1.getCompositionConfig)(complexDoc.compositions[0].compositions[2].compositions[0]);
@@ -397,7 +618,7 @@ describe('getCompositionConfig', () => {
397
618
  });
398
619
  const swappedCode = (0, generator_1.default)(swapRes).code;
399
620
  const code = (0, generator_1.default)(res).code;
400
- const expected = '{\n slot: "title",\n props: {\n icon: "standard:apex",\n size: "medium"\n }\n}';
621
+ const expected = '{\n slot: "title",\n props: ctx => ({\n icon: "standard:apex",\n size: "medium"\n })\n}';
401
622
  expect(code).toBe(expected);
402
623
  expect(swappedCode).toBe(expected);
403
624
  });
@@ -445,14 +666,11 @@ describe('getCompositionConfig', () => {
445
666
  },
446
667
  },
447
668
  });
448
- expect(res.properties[0].value
449
- .properties[0].key.type).toBe('Identifier');
450
- expect(res.properties[0].value
451
- .properties[1].key.type).toBe('StringLiteral');
452
- expect(res.properties[0].value
453
- .properties[2].key.type).toBe('Identifier');
454
- expect(res.properties[0].value
455
- .properties[3].key.type).toBe('StringLiteral');
669
+ const functionBody = res.properties[0].value.body;
670
+ expect(functionBody.properties[0].key.type).toBe('Identifier');
671
+ expect(functionBody.properties[1].key.type).toBe('StringLiteral');
672
+ expect(functionBody.properties[2].key.type).toBe('Identifier');
673
+ expect(functionBody.properties[3].key.type).toBe('StringLiteral');
456
674
  });
457
675
  });
458
676
  //# sourceMappingURL=compositionAstGeneration.spec.js.map
@@ -571,4 +571,15 @@ describe('composeStaticMetadataAssignmentExpression', () => {
571
571
  expect(right.name).toBe('Adg0Meta');
572
572
  });
573
573
  });
574
+ describe('composeSelfServiceAssignmentExpression', () => {
575
+ it('returns proper expression statement', () => {
576
+ const expr = (0, functionAstGeneration_1.composeSelfServiceAssignmentExpression)('adg0')
577
+ .expression;
578
+ const left = expr.left;
579
+ expect(left.object.name).toBe('adg0');
580
+ expect(left.property.name).toBe('self');
581
+ const right = expr.right;
582
+ expect(right.value).toBeTruthy();
583
+ });
584
+ });
574
585
  //# sourceMappingURL=functionAstGeneration.spec.js.map
@@ -922,4 +922,48 @@ describe('collectMetadataForImportedTemplates', () => {
922
922
  expect(moduleMetadata.adgs.get(1)?.properties.size).toBe(2);
923
923
  });
924
924
  });
925
+ describe('valueReferenceToExpression', () => {
926
+ it('properly references the property that we want to refernce as a string', () => {
927
+ const obj = (0, genericAstGeneration_1.valueReferenceToExpression)((0, common_shared_1.initModuleMetadataObject)(), {
928
+ type: 'Binding',
929
+ value: 'record/sub/path',
930
+ });
931
+ expect(obj.properties[0].key.name).toBe('t');
932
+ expect(obj.properties[0].value.value).toBe('b');
933
+ expect(obj.properties[1].key.name).toBe('v');
934
+ expect(obj.properties[1].value.value).toBe('record.sub.path');
935
+ });
936
+ it('properly references a binding in an iteration context by value', () => {
937
+ const obj = (0, genericAstGeneration_1.valueReferenceToExpression)((0, common_shared_1.initModuleMetadataObject)(), {
938
+ type: 'Binding',
939
+ value: 'item/val',
940
+ }, ['item']);
941
+ expect(obj.properties[0].key.name).toBe('t');
942
+ expect(obj.properties[0].value.value).toBe('s');
943
+ expect(obj.properties[1].key.name).toBe('v');
944
+ expect(obj.properties[1]
945
+ .value.object.name).toBe('user_var_item');
946
+ expect(obj.properties[1]
947
+ .value.property.name).toBe('val');
948
+ });
949
+ it('handles whatever this weird typing edge case is where value is undefined', () => {
950
+ const obj = (0, genericAstGeneration_1.valueReferenceToExpression)((0, common_shared_1.initModuleMetadataObject)(), {
951
+ type: 'PrimitiveValue',
952
+ });
953
+ expect(obj.properties[0].key.name).toBe('t');
954
+ expect(obj.properties[0].value.value).toBe('s');
955
+ expect(obj.properties[1].key.name).toBe('v');
956
+ expect(obj.properties[1].value.name).toBe('undefined');
957
+ });
958
+ it('properly references a static value', () => {
959
+ const obj = (0, genericAstGeneration_1.valueReferenceToExpression)((0, common_shared_1.initModuleMetadataObject)(), {
960
+ type: 'PrimitiveValue',
961
+ value: 'reference',
962
+ });
963
+ expect(obj.properties[0].key.name).toBe('t');
964
+ expect(obj.properties[0].value.value).toBe('s');
965
+ expect(obj.properties[1].key.name).toBe('v');
966
+ expect(obj.properties[1].value.value).toBe('reference');
967
+ });
968
+ });
925
969
  //# sourceMappingURL=genericAstGeneration.spec.js.map
@@ -38,7 +38,7 @@ function generateModuleSource(komaciHTMLDoc, komaciJSDoc, srcFileMap) {
38
38
  // eslint-disable-next-line jest/no-disabled-tests
39
39
  describe('fixtures', () => {
40
40
  // find all folder paths containing a file whose name ends in ".src"
41
- const fixtures = glob_1.default.sync(path_1.default.resolve(FIXTURES_DIR, '**/*.src'));
41
+ const fixtures = glob_1.default.sync(path_1.default.resolve(FIXTURES_DIR, '**/*.json'));
42
42
  for (const caseEntry of fixtures) {
43
43
  const caseFolder = path_1.default.dirname(caseEntry);
44
44
  const caseName = path_1.default.relative(FIXTURES_DIR, caseFolder);
@@ -63,14 +63,15 @@ export declare function slotToExpression(moduleMetadata: ModuleMetadata, slot: S
63
63
  * @param {string[]} iterationContext if this is being called from inside an iteration we need that prepend context for bindingToExpression
64
64
  * @returns {Expression} the babel Expression representing the Image prompt into the Resolver API
65
65
  */
66
- export declare function imageToExpression(image: Image, iterationContext?: string[]): t.Expression;
66
+ export declare function imageToExpression(moduleMetadata: ModuleMetadata, image: Image, iterationContext?: string[]): t.Expression;
67
67
  /**
68
68
  * Creates a babel configuration ObjectExpression for provided composition. This is the `CompositionConfig`
69
69
  * from Resolver API in its babel ObjectExpression form.
70
70
  * @param {ComposedAdg | Container | Slot} composition the Composition from which to create a configuration (as a ComposedAdg, Container, or Slot)
71
71
  * @param {string} componentId the component indentifier, as a string
72
72
  * @param {string[]} iterationContext if this is being called from inside an iteration we need that prepend context for bindingToExpression
73
+ * @param {t.Expression[]} dependentProps list of properties which are dependencies of this composition
73
74
  * @returns {ObjectExpression} the babel ObjectExpression representing the Resolver API CompositionConfig
74
75
  */
75
- export declare function getCompositionConfig(composition: ComposedAdg | Container | Slot, componentId?: string, iterationContext?: string[]): t.ObjectExpression;
76
+ export declare function getCompositionConfig(composition: ComposedAdg | Container | Slot | Iteration, componentId?: string, iterationContext?: string[], dependentProps?: Set<string>): t.ObjectExpression;
76
77
  //# sourceMappingURL=compositionAstGeneration.d.ts.map
@@ -91,20 +91,26 @@ function compositionToExpression(moduleMetadata, composition, iterationContext)
91
91
  expression = slotToExpression(moduleMetadata, composition, iterationContext);
92
92
  break;
93
93
  case 'Image':
94
- expression = imageToExpression(composition, iterationContext);
94
+ expression = imageToExpression(moduleMetadata, composition, iterationContext);
95
95
  break;
96
96
  }
97
97
  // If the composition has an isActive condition, then
98
98
  // expression needs to be proceded by a conditional check.
99
99
  if (composition.isActive) {
100
- let conditionalTest = (0, genericAstGeneration_1.bindingToExpression)(composition.isActive.input, iterationContext);
101
- if (composition.isActive.negate) {
102
- conditionalTest = t.unaryExpression('!', conditionalTest);
100
+ const props = [
101
+ t.objectProperty(t.identifier('c'), (0, genericAstGeneration_1.valueReferenceToExpression)(moduleMetadata, composition.isActive.input, iterationContext)),
102
+ ];
103
+ const container = composition;
104
+ if (container.slot !== undefined) {
105
+ props.push(t.objectProperty(t.identifier('slot'), t.stringLiteral(container.slot)));
103
106
  }
104
- const prop = (0, genericAstGeneration_1.bindingToExpression)(composition.isActive.input, iterationContext, true);
105
- const unresolvedTest = t.callExpression(types_1.ID.UNRESOLVED_FUNC, [prop]);
106
- const test = t.logicalExpression('||', unresolvedTest, conditionalTest);
107
- expression = t.conditionalExpression(test, expression, types_1.ID.UNDEFINED);
107
+ const compositionFunc = t.arrowFunctionExpression([types_1.ID.CONTEXT], expression);
108
+ expression = t.callExpression(types_1.ID.CONDITION_FUNC, [
109
+ types_1.ID.CONTEXT,
110
+ t.objectExpression(props),
111
+ compositionFunc,
112
+ t.booleanLiteral(composition.isActive.negate || false),
113
+ ]);
108
114
  }
109
115
  return expression;
110
116
  }
@@ -121,7 +127,7 @@ function containerToExpression(moduleMetadata, container, iterationContext) {
121
127
  const children = compositionsToArrayExpression(moduleMetadata, container.compositions, iterationContext) || t.arrayExpression([]);
122
128
  // If key or slot is specified, then the container will need to be
123
129
  // accounted for in the module via the element function.
124
- if (container.key || container.slot) {
130
+ if (container.key || (container.slot && !container.isActive)) {
125
131
  const params = [];
126
132
  // arg1: Composition configuration.
127
133
  params.push(getCompositionConfig(container, undefined, iterationContext));
@@ -167,7 +173,9 @@ function composedAdgToExpression(moduleMetadata, composedAdg, iterationContext)
167
173
  throw new Error(common_shared_1.ERROR_PREFIX + 'binding not yet supported for ComposedAdg input');
168
174
  }
169
175
  // arg2: Composition configuration.
170
- params.push(getCompositionConfig(composedAdg, componentId, iterationContext));
176
+ const dependentProps = new Set();
177
+ const config = getCompositionConfig(composedAdg, componentId, iterationContext, dependentProps);
178
+ params.push(config);
171
179
  // arg3: Context.
172
180
  params.push(types_1.ID.CONTEXT);
173
181
  // arg4: Array of expressions for each child.
@@ -175,6 +183,12 @@ function composedAdgToExpression(moduleMetadata, composedAdg, iterationContext)
175
183
  if (children && children.elements.length) {
176
184
  params.push(children);
177
185
  }
186
+ else {
187
+ params.push(t.arrayExpression());
188
+ }
189
+ // arg5: Array of dependent properties
190
+ const expArray = [...dependentProps].map((ele) => t.stringLiteral(ele));
191
+ params.push(t.arrayExpression(expArray));
178
192
  return t.callExpression(types_1.ID.COMPOSED_GRAPH_FUNC, params);
179
193
  }
180
194
  exports.composedAdgToExpression = composedAdgToExpression;
@@ -188,7 +202,13 @@ exports.composedAdgToExpression = composedAdgToExpression;
188
202
  function iterationToExpression(moduleMetadata, iteration, iterationContext = []) {
189
203
  const params = [];
190
204
  // arg1: Expression for the collection being iterated.
191
- params.push((0, genericAstGeneration_1.bindingToExpression)(iteration.input, iterationContext));
205
+ const props = [
206
+ t.objectProperty(t.identifier('c'), (0, genericAstGeneration_1.valueReferenceToExpression)(moduleMetadata, iteration.input, iterationContext)),
207
+ ];
208
+ if (iteration.slot !== undefined) {
209
+ props.push(t.objectProperty(t.identifier('slot'), t.stringLiteral(iteration.slot)));
210
+ }
211
+ params.push(t.objectExpression(props));
192
212
  // arg2: Context.
193
213
  params.push(types_1.ID.CONTEXT);
194
214
  // arg3: Function to return compositions inside the the iteration.
@@ -233,33 +253,15 @@ exports.slotToExpression = slotToExpression;
233
253
  * @param {string[]} iterationContext if this is being called from inside an iteration we need that prepend context for bindingToExpression
234
254
  * @returns {Expression} the babel Expression representing the Image prompt into the Resolver API
235
255
  */
236
- function imageToExpression(image, iterationContext) {
256
+ function imageToExpression(moduleMetadata, image, iterationContext) {
237
257
  const params = [];
238
- const funcObjProps = [];
239
- if ((0, common_shared_1.isCompositionAnImage)(image)) {
240
- if ((0, common_shared_1.isSrcPrimitiveValue)(image.src)) {
241
- // type guard ensures `image.src` is a PrimitiveValue
242
- // lwc-platform will NOT produce an Image KomaciNode with a blank or missing src attribute.
243
- // However, just in case we do encounter this, we handle it here by simply NOT producing the
244
- // function ObjectProperty for such a node.
245
- if (image.src.value &&
246
- typeof image.src.value === 'string' &&
247
- image.src.value !== '') {
248
- funcObjProps.push(t.objectProperty(types_1.ID.IMG_SRC, t.stringLiteral(image.src.value)));
249
- }
250
- }
251
- else if ((0, common_shared_1.isSrcABinding)(image.src)) {
252
- // type guard ensures `image.src` is a Binding
253
- // lwc-platform will NOT produce an Image KomaciNode with a blank or missing src attribute.
254
- // However, just in case we do encounter this, we handle it here by simply NOT producing the
255
- // function ObjectProperty for such a node.
256
- if (image.src.value !== '') {
257
- funcObjProps.push(t.objectProperty(types_1.ID.IMG_SRC, (0, genericAstGeneration_1.bindingToExpression)(image.src, iterationContext)));
258
- }
259
- }
258
+ if ((0, common_shared_1.isCompositionAnImage)(image) &&
259
+ image.src.value &&
260
+ typeof image.src.value === 'string' &&
261
+ image.src.value !== '') {
262
+ params.push(t.objectProperty(types_1.ID.IMG_SRC, (0, genericAstGeneration_1.valueReferenceToExpression)(moduleMetadata, image.src, iterationContext)));
260
263
  }
261
- params.push(t.objectExpression(funcObjProps));
262
- return t.callExpression(types_1.ID.IMG_FUNC, params);
264
+ return t.callExpression(types_1.ID.IMG_FUNC, [t.objectExpression(params), types_1.ID.CONTEXT]);
263
265
  }
264
266
  exports.imageToExpression = imageToExpression;
265
267
  /**
@@ -268,11 +270,12 @@ exports.imageToExpression = imageToExpression;
268
270
  * @param {ComposedAdg | Container | Slot} composition the Composition from which to create a configuration (as a ComposedAdg, Container, or Slot)
269
271
  * @param {string} componentId the component indentifier, as a string
270
272
  * @param {string[]} iterationContext if this is being called from inside an iteration we need that prepend context for bindingToExpression
273
+ * @param {t.Expression[]} dependentProps list of properties which are dependencies of this composition
271
274
  * @returns {ObjectExpression} the babel ObjectExpression representing the Resolver API CompositionConfig
272
275
  */
273
- function getCompositionConfig(composition, componentId, iterationContext) {
276
+ function getCompositionConfig(composition, componentId, iterationContext, dependentProps) {
274
277
  const config = [];
275
- if (composition.slot) {
278
+ if (composition.slot !== undefined) {
276
279
  config.push(t.objectProperty(types_1.ID.SLOT, t.stringLiteral(composition.slot)));
277
280
  }
278
281
  // ComposedAdg config contains additional information.
@@ -289,6 +292,11 @@ function getCompositionConfig(composition, componentId, iterationContext) {
289
292
  props.push(t.objectProperty(hasSpecialCharacters.test(propName)
290
293
  ? t.stringLiteral(propName)
291
294
  : t.identifier(propName), (0, genericAstGeneration_1.bindingToExpression)(prop, iterationContext)));
295
+ const propValue = prop.value.split('/')[0];
296
+ // exclude iteration bindings from dependent prop list
297
+ if (!iterationContext?.includes(propValue)) {
298
+ dependentProps?.add(propValue);
299
+ }
292
300
  }
293
301
  else if (prop.type === 'PrimitiveValue') {
294
302
  props.push(t.objectProperty(hasSpecialCharacters.test(propName)
@@ -296,7 +304,7 @@ function getCompositionConfig(composition, componentId, iterationContext) {
296
304
  : t.identifier(propName), (0, genericAstGeneration_1.primitiveToExpression)(prop)));
297
305
  }
298
306
  }
299
- config.push(t.objectProperty(types_1.ID.PROPS, t.objectExpression(props)));
307
+ config.push(t.objectProperty(types_1.ID.PROPS, t.arrowFunctionExpression([types_1.ID.CONTEXT], t.objectExpression(props))));
300
308
  }
301
309
  }
302
310
  return t.objectExpression(config);
@@ -92,4 +92,11 @@ export declare function produceErrorAdgFunction(moduleMetadata: ModuleMetadata,
92
92
  * @returns an expression statement, eg: adg0.meta = adg0meta
93
93
  */
94
94
  export declare function composeStaticMetadataAssignmentExpression(adgName: string, staticMetadataObject: t.VariableDeclaration): t.ExpressionStatement;
95
+ /**
96
+ * Helper function to set self service as true. This way we can indicate at the resolver level what resolution
97
+ * flow to use
98
+ * @param adgName the name of the adg function to associate the adgMeta object with.
99
+ * @returns an expression statement, eg: adg0.self = true
100
+ */
101
+ export declare function composeSelfServiceAssignmentExpression(adgName: string): t.ExpressionStatement;
95
102
  //# sourceMappingURL=functionAstGeneration.d.ts.map
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.composeStaticMetadataAssignmentExpression = exports.produceErrorAdgFunction = exports.getInlineFunctionFromTemplateCompositions = exports.getAdgFunctionBody = exports.addExportStatement = exports.composeAdgStaticMetadata = exports.composeAdgFunction = exports.getFactoryFuncDeclaration = exports.adgToExpression = exports.sanitizeFunction = exports.hoistLocalFunction = void 0;
26
+ exports.composeSelfServiceAssignmentExpression = exports.composeStaticMetadataAssignmentExpression = exports.produceErrorAdgFunction = exports.getInlineFunctionFromTemplateCompositions = exports.getAdgFunctionBody = exports.addExportStatement = exports.composeAdgStaticMetadata = exports.composeAdgFunction = exports.getFactoryFuncDeclaration = exports.adgToExpression = exports.sanitizeFunction = exports.hoistLocalFunction = void 0;
27
27
  const t = __importStar(require("@babel/types"));
28
28
  const common_shared_1 = require("@komaci/common-shared");
29
29
  const compositionAstGeneration_1 = require("./compositionAstGeneration");
@@ -307,15 +307,17 @@ function collectChildrenStaticMetadata(rootComposition, moduleMetadata) {
307
307
  const childrenArray = [];
308
308
  let imgFound = false;
309
309
  if (rootComposition) {
310
- (0, common_shared_1.traverseComposition)(rootComposition, (comp) => {
311
- if (comp.type == 'ComposedAdg' || comp.type == 'Image') {
312
- if (comp.type == 'Image') {
313
- imgFound = true;
310
+ (0, common_shared_1.traverseComposition)(rootComposition, {
311
+ pretraversal: (comp) => {
312
+ if (comp.type == 'ComposedAdg' || comp.type == 'Image') {
313
+ if (comp.type == 'Image') {
314
+ imgFound = true;
315
+ }
316
+ const childProp = generateComposisitonMetadata(comp, moduleMetadata);
317
+ childrenArray.push(childProp);
314
318
  }
315
- const childProp = generateComposisitonMetadata(comp, moduleMetadata);
316
- childrenArray.push(childProp);
317
- }
318
- return false;
319
+ return false;
320
+ },
319
321
  });
320
322
  }
321
323
  return { childrenArray, imgFound };
@@ -434,13 +436,17 @@ function getInlineFunctionFromTemplateCompositions(moduleMetadata, requiredFacto
434
436
  const statements = [];
435
437
  const body = t.blockStatement(statements);
436
438
  const emptyCompositionsArray = compositions.length < 1;
437
- if (moduleMetadata.hasRenderFunction && adgMetadata.exportName == 'default') {
439
+ if (moduleMetadata.renderFunction && adgMetadata.exportName == 'default') {
438
440
  // function body destructured factory object. e.g. `const { cg } = fct;`
439
441
  const fctFuncs = getFactoryFuncDeclaration(requiredFactoryFunctions); // passing in false because we are not processing the script file in this method
440
442
  if (fctFuncs) {
441
443
  statements.push(fctFuncs);
442
444
  }
443
- const rtFuncParams = [types_1.ID.HOISTED_RENDER_FUNC_ID, types_1.ID.CONTEXT];
445
+ const rtFuncParams = [
446
+ types_1.ID.HOISTED_RENDER_FUNC_ID,
447
+ types_1.ID.CONTEXT,
448
+ t.arrayExpression(moduleMetadata.renderFunction.requiredProperties.map((prop) => t.stringLiteral(prop))),
449
+ ];
444
450
  // rf(hoistedRenderFunction, CTX)
445
451
  const rtFunc = t.callExpression(types_1.ID.RENDER_FUNC, rtFuncParams);
446
452
  //creating the return statement
@@ -527,4 +533,14 @@ function composeStaticMetadataAssignmentExpression(adgName, staticMetadataObject
527
533
  .id.name)));
528
534
  }
529
535
  exports.composeStaticMetadataAssignmentExpression = composeStaticMetadataAssignmentExpression;
536
+ /**
537
+ * Helper function to set self service as true. This way we can indicate at the resolver level what resolution
538
+ * flow to use
539
+ * @param adgName the name of the adg function to associate the adgMeta object with.
540
+ * @returns an expression statement, eg: adg0.self = true
541
+ */
542
+ function composeSelfServiceAssignmentExpression(adgName) {
543
+ return t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier(adgName), t.identifier('self')), t.booleanLiteral(true)));
544
+ }
545
+ exports.composeSelfServiceAssignmentExpression = composeSelfServiceAssignmentExpression;
530
546
  //# sourceMappingURL=functionAstGeneration.js.map
@@ -72,6 +72,22 @@ export declare function primitiveToExpression(primitive: PrimitiveValue): t.Expr
72
72
  * @returns A composed member expression
73
73
  */
74
74
  export declare function bindingToExpression(binding: Binding | PropertyReference, iterationContext?: string[], parseRootOnly?: boolean): t.Identifier | t.OptionalMemberExpression;
75
+ /**
76
+ * compose a object that references a value for use in iteration and conditional factory functions.
77
+ * for times when we are operating inside of an iteration context, we want to leverage bindings so we can
78
+ * straight up hoist the iteration value. in every other use case we will be either a property reference or static value
79
+ *
80
+ * - t represent "type"
81
+ * - t could be either `b` (binding) or `s` (static value)
82
+ * - v represents "value"
83
+ * - maps to the value whatever that may be.
84
+ *
85
+ * @param moduleMetadata metadata about the module we are composing
86
+ * @param ref the value that needs to be referenced by this prop
87
+ * @param iterationContext if this value is based on some iteration
88
+ * @returns an object of the form { t: 'b' | 's', v: 'some value or prop ref' }
89
+ */
90
+ export declare function valueReferenceToExpression(moduleMetadata: ModuleMetadata, ref: Binding | Value, iterationContext?: string[]): t.ObjectExpression;
75
91
  /**
76
92
  * Convert a single Komaci function to an object expression in the shape of a
77
93
  * FunctionDefinition as defined in Resolver API.
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.collectMetadataForImportedTemplates = exports.exportNamedDeclarationForDynamicImport = exports.addUndefinedDefaultExport = exports.propertyToExpression = exports.functionToExpression = exports.bindingToExpression = exports.primitiveToExpression = exports.valueToExpression = exports.processWireFunctionType = exports.processErrorFunction = exports.addImportStatements = exports.generateResolvableModule = void 0;
26
+ exports.collectMetadataForImportedTemplates = exports.exportNamedDeclarationForDynamicImport = exports.addUndefinedDefaultExport = exports.propertyToExpression = exports.functionToExpression = exports.valueReferenceToExpression = exports.bindingToExpression = exports.primitiveToExpression = exports.valueToExpression = exports.processWireFunctionType = exports.processErrorFunction = exports.addImportStatements = exports.generateResolvableModule = void 0;
27
27
  const common_shared_1 = require("@komaci/common-shared");
28
28
  const static_analyzer_1 = require("@komaci/static-analyzer");
29
29
  const t = __importStar(require("@babel/types"));
@@ -95,7 +95,7 @@ function generateResolvableModule(input, scriptKomaciDoc, templateKomaciDocMap,
95
95
  if (renderFunction) {
96
96
  renderFunctionMetadata = (0, componentAstProcessing_1.processRenderFunction)(componentDefaultAdgIndex, moduleContext, moduleMetadata, renderFunction);
97
97
  if (renderFunctionMetadata) {
98
- moduleMetadata.hasRenderFunction = true;
98
+ moduleMetadata.renderFunction = renderFunctionMetadata;
99
99
  moduleMetadata.adgs
100
100
  .get(componentDefaultAdgIndex)
101
101
  ?.requiredCompositionFactoryFunctions.add(common_shared_1.IdKeys.RENDER_FUNC);
@@ -104,7 +104,7 @@ function generateResolvableModule(input, scriptKomaciDoc, templateKomaciDocMap,
104
104
  }
105
105
  }
106
106
  //has a default html file but no render funciton ***
107
- if (hasTemplateKomaciDoc && !moduleMetadata.hasRenderFunction) {
107
+ if (hasTemplateKomaciDoc && !moduleMetadata.renderFunction) {
108
108
  componentDefaultAdgIndex = (0, common_shared_1.reconcileDefaultAdg)(componentDefaultAdgIndex, moduleMetadata);
109
109
  if (componentDefaultAdgIndex !== undefined) {
110
110
  (0, common_shared_1.initializeImportMetdataFromKomaciDocument)(defaultTemplateKomaciDoc, moduleMetadata, componentDefaultAdgIndex);
@@ -125,7 +125,7 @@ function generateResolvableModule(input, scriptKomaciDoc, templateKomaciDocMap,
125
125
  }
126
126
  //as long as we have at least one template and theres a valid render function, check to see if its imported. In the case the default html doc is imported, the assocated adg refernce will be set.
127
127
  if (Object.keys(moduleMetadata.templateKomaciDocMap).length > 0 &&
128
- moduleMetadata.hasRenderFunction) {
128
+ moduleMetadata.renderFunction) {
129
129
  collectMetadataForImportedTemplates(moduleMetadata);
130
130
  }
131
131
  // all metadata collected at this point, time to start building ast
@@ -192,6 +192,9 @@ function generateResolvableModule(input, scriptKomaciDoc, templateKomaciDocMap,
192
192
  statements.push(staticMetadataObject);
193
193
  statements.push(adgFunctionDefinition);
194
194
  statements.push(staticMetadataAssignmentExpression);
195
+ // the default export is the only adg that we care to hook the self service thing to since default adgs are always what is passed to the resolver
196
+ const selfServiceAssignmentExpression = (0, functionAstGeneration_1.composeSelfServiceAssignmentExpression)(adg.defaultGeneratedName);
197
+ statements.push(selfServiceAssignmentExpression);
195
198
  }
196
199
  for (const [exportName, adg] of Object.entries(moduleMetadata.exports)) {
197
200
  statements.push((0, functionAstGeneration_1.addExportStatement)(adg.defaultGeneratedName, exportName));
@@ -543,6 +546,52 @@ function bindingToExpression(binding, iterationContext, parseRootOnly = false) {
543
546
  return expr;
544
547
  }
545
548
  exports.bindingToExpression = bindingToExpression;
549
+ /**
550
+ * compose a object that references a value for use in iteration and conditional factory functions.
551
+ * for times when we are operating inside of an iteration context, we want to leverage bindings so we can
552
+ * straight up hoist the iteration value. in every other use case we will be either a property reference or static value
553
+ *
554
+ * - t represent "type"
555
+ * - t could be either `b` (binding) or `s` (static value)
556
+ * - v represents "value"
557
+ * - maps to the value whatever that may be.
558
+ *
559
+ * @param moduleMetadata metadata about the module we are composing
560
+ * @param ref the value that needs to be referenced by this prop
561
+ * @param iterationContext if this value is based on some iteration
562
+ * @returns an object of the form { t: 'b' | 's', v: 'some value or prop ref' }
563
+ */
564
+ function valueReferenceToExpression(moduleMetadata, ref, iterationContext) {
565
+ let objectRef;
566
+ if (ref.type !== 'Binding' ||
567
+ (ref.type === 'Binding' &&
568
+ iterationContext &&
569
+ iterationContext.length !== 0 &&
570
+ iterationContext.includes(ref.value.split('/')[0]))) {
571
+ let objectValue;
572
+ if (ref.type === 'Binding') {
573
+ objectValue = bindingToExpression(ref, iterationContext);
574
+ }
575
+ else if (ref.value) {
576
+ objectValue = valueToExpression(ref, moduleMetadata);
577
+ }
578
+ else {
579
+ objectValue = t.identifier('undefined');
580
+ }
581
+ objectRef = t.objectExpression([
582
+ t.objectProperty(t.identifier('t'), t.stringLiteral('s')),
583
+ t.objectProperty(t.identifier('v'), objectValue),
584
+ ]);
585
+ }
586
+ else {
587
+ objectRef = t.objectExpression([
588
+ t.objectProperty(t.identifier('t'), t.stringLiteral('b')),
589
+ t.objectProperty(t.identifier('v'), t.stringLiteral(ref.value.replace(/\//g, '.'))),
590
+ ]);
591
+ }
592
+ return objectRef;
593
+ }
594
+ exports.valueReferenceToExpression = valueReferenceToExpression;
546
595
  /**
547
596
  * Convert a single Komaci function to an object expression in the shape of a
548
597
  * FunctionDefinition as defined in Resolver API.
package/build/types.js CHANGED
@@ -70,6 +70,7 @@ exports.ID = {
70
70
  IMG_SRC: t.identifier('src'),
71
71
  IMG_FUNC: t.identifier('img'),
72
72
  HOISTED_RENDER_FUNC_ID: t.identifier('hoistedRender'),
73
+ CONDITION_FUNC: t.identifier('c'),
73
74
  };
74
75
  // enum representing the different states of the way an Import is used
75
76
  var ImportUsageState;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@komaci/esm-generator",
3
- "version": "244.2.0",
3
+ "version": "244.2.1",
4
4
  "description": "Komaci generator for ADG ES modules",
5
5
  "homepage": "https://komaci.dev/",
6
6
  "repository": {
@@ -29,11 +29,11 @@
29
29
  "@babel/core": "^7.9.0",
30
30
  "@babel/generator": "^7.9.0",
31
31
  "@babel/types": "^7.9.0",
32
- "@komaci/common-shared": "244.2.0",
33
- "@komaci/static-analyzer": "244.2.0"
32
+ "@komaci/common-shared": "244.2.1",
33
+ "@komaci/static-analyzer": "244.2.1"
34
34
  },
35
35
  "devDependencies": {
36
- "@komaci/types": "244.2.0",
36
+ "@komaci/types": "244.2.1",
37
37
  "@lwc-platform/sfdc-lwc-compiler": "242.15.1-2.28.0",
38
38
  "@lwc/metadata": "^2.28.0-0"
39
39
  }