@komaci/common-shared 242.0.0 → 242.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,28 +1,285 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.addTemplateUsageForDefaultAdg = exports.mapExportNamesToAdgs = exports.initalizeAdgMetadata = exports.initializeImportMetdataFromKomaciDocument = exports.initModuleMetadataObject = void 0;
3
+ exports.upliftFakePropsFromTemplate = exports.reconcileDefaultAdg = exports.isImportInvalid = exports.reconcilePrimingAdapater = exports.reconcileWireReference = exports.composeWireFunctionMetadata = exports.addTemplateUsageForDefaultAdg = exports.mapExportNamesToAdgs = exports.initalizeAdgMetadata = exports.collectImportMetadataFromAst = exports.updateAliasForImport = exports.addNewImportFromAst = exports.reconcileImport = exports.reconcileNamespace = exports.traverseAstImports = exports.composeImportMetadata = exports.initializeImportMetdataFromKomaciDocument = exports.initAdgMetadataObject = exports.initModuleMetadataObject = exports.NO_KOMACI_DOC_REF = void 0;
4
+ const allowlistNamespaces_1 = require("./allowlistNamespaces");
5
+ const komaciDocumentIntrospection_1 = require("./komaciDocumentIntrospection");
6
+ const types_1 = require("./types");
7
+ const wires_1 = require("./wires");
8
+ const utils_1 = require("./utils");
9
+ /** not all imports are consumed in a statically analyzable way. when we add their metadata, we use this to ack that the komaciDocImportRef for this import is nil */
10
+ exports.NO_KOMACI_DOC_REF = 'nil';
4
11
  /**
5
12
  * establish a base object for module metadata
6
13
  * @returns A structured object for module metadata
7
14
  */
8
15
  const initModuleMetadataObject = () => ({
16
+ importGeneratorIndex: 0,
17
+ adgGeneratorIndex: 0,
9
18
  importsByNamespace: new Map(),
10
19
  importsByName: new Map(),
11
20
  importIndexReference: new Map(),
12
- adgs: [],
21
+ adgs: new Map(),
13
22
  exports: {},
14
23
  });
15
24
  exports.initModuleMetadataObject = initModuleMetadataObject;
16
25
  /**
17
- *
26
+ * establish an empty object for adg metadata
27
+ * @param defaultGeneratedName a generated name for this object
28
+ * @returns an empty metadata object
29
+ */
30
+ const initAdgMetadataObject = (defaultGeneratedName) => ({
31
+ defaultGeneratedName,
32
+ properties: new Map(),
33
+ functions: [],
34
+ propertiesUsedInTemplate: new Set(),
35
+ requiredAdgFactoryFunctions: new Set(),
36
+ requiredCompositionFactoryFunctions: new Set(),
37
+ hasSourceFile: false,
38
+ });
39
+ exports.initAdgMetadataObject = initAdgMetadataObject;
40
+ /**
41
+ * Process import references from komaci document
18
42
  * @param doc the KomaciDocument itself
19
43
  * @param moduleMetadata data structure representing metadata about the module we are working on
20
44
  */
21
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
22
- const initializeImportMetdataFromKomaciDocument = (doc, moduleMetadata) => {
23
- // to be implemented
45
+ const initializeImportMetdataFromKomaciDocument = (doc, moduleMetadata, fromTemplate = false) => {
46
+ const namespaces = doc.imports || [];
47
+ for (let i = 0; i < namespaces.length; i++) {
48
+ const importNamespace = namespaces[i];
49
+ const names = new Set(importNamespace.names);
50
+ const isSupported = (0, allowlistNamespaces_1.isSupportedNamespace)(importNamespace.resourceName);
51
+ const namespace = {
52
+ names,
53
+ isSupported,
54
+ resourceName: importNamespace.resourceName,
55
+ isDefaultSpecifier: names.has('default'),
56
+ isNamespaceSpecifier: names.has('*'),
57
+ };
58
+ moduleMetadata.importsByNamespace.set(importNamespace.resourceName, namespace);
59
+ for (let j = 0; j < importNamespace.names.length; j++) {
60
+ const name = importNamespace.names[j];
61
+ const komaciDocImportRef = `${i}/names/${j}`;
62
+ const importAlias = moduleMetadata.importsByName.has(name)
63
+ ? `${name}-${importNamespace.resourceName}`
64
+ : undefined;
65
+ (0, exports.composeImportMetadata)(name, importNamespace.resourceName, isSupported, fromTemplate ? 't-' + komaciDocImportRef : komaciDocImportRef, // to prevent collision in references
66
+ moduleMetadata, importAlias);
67
+ }
68
+ /*
69
+ * For imports from other resolvable modules we know that they will always be only a default import.
70
+ * as such if we see one of these special imports we should snag the component id for this resolvable module
71
+ */
72
+ const firstItem = fromTemplate ? `t-${i}/names/0` : `${i}/names/0`;
73
+ const adgImportName = moduleMetadata.importIndexReference.get(firstItem);
74
+ if (namespace.resourceName.startsWith('@salesforce/komaci') && adgImportName) {
75
+ // name reference and the object map are built along side eachother so if one exists so does the ohter
76
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
77
+ const adgImport = moduleMetadata.importsByName.get(adgImportName);
78
+ adgImport.componentId = (0, komaciDocumentIntrospection_1.importToComponentId)(namespace.resourceName);
79
+ }
80
+ }
24
81
  };
25
82
  exports.initializeImportMetdataFromKomaciDocument = initializeImportMetdataFromKomaciDocument;
83
+ /**
84
+ * Update module metadata with information about the given import.
85
+ * @param name import name
86
+ * @param resourceName import path
87
+ * @param isSupported if it's from a valid namespace
88
+ * @param komaciDocImportRef reference index in komaci document
89
+ * @param moduleMetadata the metadata object
90
+ *
91
+ * @return the import metadata object in case anything needs to be modified
92
+ */
93
+ const composeImportMetadata = (name, resourceName, isSupported, komaciDocImportRef, moduleMetadata, importAlias) => {
94
+ const generatorIndex = isSupported
95
+ ? moduleMetadata.importGeneratorIndex++
96
+ : moduleMetadata.importGeneratorIndex;
97
+ let importKey = name;
98
+ if (importAlias) {
99
+ importKey = importAlias;
100
+ }
101
+ else if (name === 'default') {
102
+ importKey = `default-${resourceName}`;
103
+ importAlias = importKey;
104
+ }
105
+ else if (name === '*') {
106
+ importKey = `namespace-${resourceName}`;
107
+ importAlias = importKey;
108
+ }
109
+ const currentImport = {
110
+ name,
111
+ komaciDocImportRef,
112
+ importAlias,
113
+ generatorAlias: `i${generatorIndex}`,
114
+ resourceName: resourceName,
115
+ isFromInternalNamespace: isSupported,
116
+ isFromSupportedLibrary: (0, allowlistNamespaces_1.isLibraryValid)(resourceName),
117
+ usedInPriming: false,
118
+ staticallyAnalyzable: true,
119
+ };
120
+ moduleMetadata.importsByName.set(importKey, currentImport);
121
+ // no komaci doc ref means import is not referenced in the komaci document but was from the ast
122
+ if (komaciDocImportRef !== exports.NO_KOMACI_DOC_REF) {
123
+ moduleMetadata.importIndexReference.set(komaciDocImportRef, importKey);
124
+ }
125
+ return currentImport;
126
+ };
127
+ exports.composeImportMetadata = composeImportMetadata;
128
+ /**
129
+ * collect all the imports for a given ast and then execute a callback with information about the import
130
+ * @param ast The babel ast
131
+ * @param cb function to call for acting on import information
132
+ */
133
+ const traverseAstImports = (ast, cb) => {
134
+ const program = ast.program;
135
+ const body = program.body;
136
+ const importDeclarations = body.filter((currentDec) => currentDec.type === 'ImportDeclaration');
137
+ importDeclarations.forEach((currentDec) => {
138
+ const specifiers = currentDec.specifiers;
139
+ const resourceName = currentDec.source.value;
140
+ specifiers.forEach((specifier) => {
141
+ let referencedName;
142
+ let originalImportName;
143
+ let lookupName;
144
+ if ((specifier.type === 'ImportSpecifier' &&
145
+ (0, utils_1.getFromIdentifierOrStringLiteral)(specifier.local) !==
146
+ (0, utils_1.getFromIdentifierOrStringLiteral)(specifier.imported)) ||
147
+ specifier.type !== 'ImportSpecifier') {
148
+ referencedName = (0, utils_1.getFromIdentifierOrStringLiteral)(specifier.local);
149
+ lookupName = referencedName;
150
+ if (specifier.type === 'ImportSpecifier') {
151
+ originalImportName = (0, utils_1.getFromIdentifierOrStringLiteral)(specifier.imported);
152
+ lookupName = originalImportName;
153
+ }
154
+ else if (specifier.type === 'ImportDefaultSpecifier') {
155
+ lookupName = `default-${resourceName}`;
156
+ originalImportName = 'default';
157
+ }
158
+ else if (specifier.type === 'ImportNamespaceSpecifier') {
159
+ lookupName = `namespace-${resourceName}`;
160
+ originalImportName = '*';
161
+ }
162
+ }
163
+ else {
164
+ referencedName = (0, utils_1.getFromIdentifierOrStringLiteral)(specifier.imported);
165
+ lookupName = referencedName;
166
+ }
167
+ cb(lookupName, referencedName, resourceName, originalImportName);
168
+ });
169
+ });
170
+ };
171
+ exports.traverseAstImports = traverseAstImports;
172
+ /**
173
+ * given the name of a resource see if we have information about it. if we don't compose the base object for later reference.
174
+ * @param resourceName The import path
175
+ * @param moduleMetadata Metadata about this module
176
+ * @returns The namespace metadata object
177
+ */
178
+ const reconcileNamespace = (resourceName, moduleMetadata) => {
179
+ let namespace = moduleMetadata.importsByNamespace.get(resourceName);
180
+ if (!namespace) {
181
+ namespace = {
182
+ names: new Set(),
183
+ isSupported: (0, allowlistNamespaces_1.isNamespaceInternal)((0, allowlistNamespaces_1.getNamespaceFromImport)(resourceName)),
184
+ resourceName: resourceName,
185
+ isDefaultSpecifier: false,
186
+ isNamespaceSpecifier: false,
187
+ };
188
+ moduleMetadata.importsByNamespace.set(resourceName, namespace);
189
+ }
190
+ return namespace;
191
+ };
192
+ exports.reconcileNamespace = reconcileNamespace;
193
+ /**
194
+ * When looking for an import if it it doesn't exist and we'd have
195
+ * to just make it anyway this function will do that for you
196
+ *
197
+ * @param name identifier of import you're looking for
198
+ * @param importPath resource path for the import
199
+ * @param moduleMetadata module metadata instance
200
+ * @returns The import metadata for this import (as much as we know)
201
+ */
202
+ const reconcileImport = (name, importPath, moduleMetadata) => {
203
+ const existingImport = moduleMetadata.importsByName.get(name);
204
+ if (existingImport) {
205
+ return existingImport;
206
+ }
207
+ else {
208
+ const newImport = (0, exports.composeImportMetadata)(name, importPath, (0, allowlistNamespaces_1.isNamespaceInternal)((0, allowlistNamespaces_1.getNamespaceFromImport)(importPath)), exports.NO_KOMACI_DOC_REF, moduleMetadata);
209
+ const namespace = (0, exports.reconcileNamespace)(importPath, moduleMetadata);
210
+ namespace.names.add(newImport.name);
211
+ return newImport;
212
+ }
213
+ };
214
+ exports.reconcileImport = reconcileImport;
215
+ /**
216
+ * add a new import that is only found in the ast. sometimes imports are not statically analyzable but we still want to collect info on them so we do this.
217
+ * @param referencedName the name used to reference this import in code
218
+ * @param namespace the metadata about the import namespace
219
+ * @param moduleMetadata the metadata about the module
220
+ * @param originalImportName (optional) the original name of the import that has been aliases. undefined if no alias.
221
+ */
222
+ const addNewImportFromAst = (referencedName, namespace, moduleMetadata, originalImportName) => {
223
+ const importAlias = originalImportName && referencedName !== originalImportName
224
+ ? referencedName
225
+ : undefined;
226
+ const importMetadata = (0, exports.composeImportMetadata)(originalImportName || referencedName, namespace.resourceName, namespace.isSupported, exports.NO_KOMACI_DOC_REF, moduleMetadata, importAlias);
227
+ importMetadata.staticallyAnalyzable = false;
228
+ if (originalImportName && referencedName !== originalImportName) {
229
+ importMetadata.importAlias = referencedName;
230
+ }
231
+ moduleMetadata.importsByName.set(referencedName, importMetadata);
232
+ namespace.names.add(referencedName);
233
+ };
234
+ exports.addNewImportFromAst = addNewImportFromAst;
235
+ /**
236
+ * Komaci Documents don't keep track of import aliases but sometimes they're referenced in code so we want to makes sure we have them.
237
+ * @param lookupName the name used as the holdover key tor eference this import
238
+ * @param referencedName the name used to reference this import in code
239
+ * @param namespace the import namespace metadata
240
+ * @param moduleMetadata metadata about this module
241
+ * @param originalImportName (optional) the original name of the import that has been aliases. undefined if no alias.
242
+ */
243
+ const updateAliasForImport = (lookupName, referencedName, namespace, moduleMetadata, originalImportName) => {
244
+ const importMetadata = moduleMetadata.importsByName.get(lookupName);
245
+ if (originalImportName && referencedName !== originalImportName && importMetadata) {
246
+ const isDefaultOrNamespace = originalImportName === '*' || originalImportName === 'default';
247
+ importMetadata.importAlias = referencedName;
248
+ moduleMetadata.importsByName.set(referencedName, importMetadata);
249
+ moduleMetadata.importsByName.delete(lookupName);
250
+ namespace.names.delete(isDefaultOrNamespace ? originalImportName : lookupName);
251
+ namespace.names.add(referencedName);
252
+ if (importMetadata.komaciDocImportRef !== exports.NO_KOMACI_DOC_REF) {
253
+ moduleMetadata.importIndexReference.set(importMetadata.komaciDocImportRef, referencedName);
254
+ }
255
+ }
256
+ };
257
+ exports.updateAliasForImport = updateAliasForImport;
258
+ /**
259
+ * pull all needful import metadata we can from the ast
260
+ * for the most part, we can grab data from the komaci document for imports but sometimes
261
+ * imports are consumed in non statically analyzable ways like inside of a getter or template string
262
+ * so we need to collect that info seperately
263
+ *
264
+ * also, the Komaci Document doesn't maintain the local alias for default or namespaced imports. so if we
265
+ * have previously collected information about one of these imports from the Komaci Document then we want
266
+ * to make sure the alias is consumed and the maps properly represent the way the import is consumed.
267
+ *
268
+ * @param moduleMetadata metadata data structure to modify
269
+ * @param ast ast for the given component
270
+ */
271
+ const collectImportMetadataFromAst = (ast, moduleMetadata) => {
272
+ (0, exports.traverseAstImports)(ast, (lookupName, referencedName, resourceName, originalImportName) => {
273
+ const namespace = (0, exports.reconcileNamespace)(resourceName, moduleMetadata);
274
+ if (!moduleMetadata.importsByName.has(lookupName)) {
275
+ (0, exports.addNewImportFromAst)(referencedName, namespace, moduleMetadata, originalImportName);
276
+ }
277
+ else {
278
+ (0, exports.updateAliasForImport)(lookupName, referencedName, namespace, moduleMetadata, originalImportName);
279
+ }
280
+ });
281
+ };
282
+ exports.collectImportMetadataFromAst = collectImportMetadataFromAst;
26
283
  /**
27
284
  * From a given adg, collect as much metadata as possible ONLY from the komaci document
28
285
  *
@@ -34,11 +291,82 @@ exports.initializeImportMetdataFromKomaciDocument = initializeImportMetdataFromK
34
291
  * @param doc the KomaciDocument itself
35
292
  * @param moduleMetadata data structure representing metadata about the module we are working on
36
293
  */
37
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
38
- const initalizeAdgMetadata = (docAdgIndex, doc, moduleMetadata) => {
39
- // if the moduleMetadata already has info about this adg we can assume we've shaken up this path of the tree already.
40
- // pull in processing that is currently in komaciDocIntrospection
41
- // we should walk the tree from this adg, processing properties, functions, parent ADGs
294
+ const initalizeAdgMetadata = (docAdgIndex, doc, moduleMetadata, hasSourceFile, isBundle = true) => {
295
+ (0, komaciDocumentIntrospection_1.traverseParentAdgs)(doc.adgs?.[docAdgIndex], docAdgIndex, doc, moduleMetadata, (adg, index) => {
296
+ // if we have data for an adg already then we can assume that it's already been processed
297
+ if (!moduleMetadata.adgs.has(index)) {
298
+ const functions = adg.functions;
299
+ const adgMetadata = {
300
+ hasSourceFile,
301
+ defaultGeneratedName: `adg${moduleMetadata.adgGeneratorIndex++}`,
302
+ requiredAdgFactoryFunctions: new Set(),
303
+ requiredCompositionFactoryFunctions: new Set(),
304
+ propertiesUsedInTemplate: new Set(),
305
+ properties: new Map(),
306
+ functions: [],
307
+ parentReference: adg.parentClass,
308
+ };
309
+ if (isBundle) {
310
+ adgMetadata.compositions = [];
311
+ }
312
+ if (adgMetadata.parentReference?.type === 'ImportReference') {
313
+ const importName = moduleMetadata.importIndexReference.get(adgMetadata.parentReference.value);
314
+ const importMetadata = importName
315
+ ? moduleMetadata.importsByName.get(importName)
316
+ : undefined;
317
+ if (!importMetadata ||
318
+ !importMetadata.isFromInternalNamespace ||
319
+ !importMetadata.isFromSupportedLibrary) {
320
+ adgMetadata.parentReference = {
321
+ type: 'Unresolved',
322
+ value: '',
323
+ };
324
+ }
325
+ if (importMetadata) {
326
+ importMetadata.usedInPriming = true;
327
+ }
328
+ }
329
+ if (adgMetadata.parentReference?.type === 'Unresolved') {
330
+ adgMetadata.requiredAdgFactoryFunctions.add(types_1.IdKeys.UNRESOLVED_VALUE);
331
+ }
332
+ adgMetadata.requiredAdgFactoryFunctions.add(types_1.IdKeys.ADG_FUNC);
333
+ moduleMetadata.adgs.set(index, adgMetadata);
334
+ adgMetadata.properties = (0, komaciDocumentIntrospection_1.initializePropertiesMap)(adg.properties, functions, index, doc, moduleMetadata, adgMetadata.properties);
335
+ (0, komaciDocumentIntrospection_1.processFreestandingFunctions)(functions, adgMetadata, moduleMetadata);
336
+ adg.functions
337
+ ?.filter((func) => func.type === types_1.FunctionTypes.WIRE_FUNCTION && func.input)
338
+ // we've filtered out functions where the input isn't defined already
339
+ .forEach((func) =>
340
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
341
+ (0, komaciDocumentIntrospection_1.traverseInput)(func.input, (value) => {
342
+ if (value.type === 'PropertyReference' &&
343
+ adgMetadata.properties.has(value.value)) {
344
+ const property = adgMetadata.properties.get(value.value);
345
+ if (property) {
346
+ property.usedInPriming = true;
347
+ }
348
+ }
349
+ else if (value.type === 'Unresolved') {
350
+ adgMetadata.requiredAdgFactoryFunctions.add(types_1.IdKeys.UNRESOLVED_VALUE);
351
+ }
352
+ else if (value.type === 'ImportReference' &&
353
+ moduleMetadata.importIndexReference.has(value.value)) {
354
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
355
+ const importMetadata = moduleMetadata.importsByName.get(
356
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
357
+ moduleMetadata.importIndexReference.get(value.value));
358
+ importMetadata.usedInPriming = true;
359
+ if (!importMetadata.isFromInternalNamespace) {
360
+ adgMetadata.requiredAdgFactoryFunctions.add(types_1.IdKeys.UNRESOLVED_VALUE);
361
+ const undefinedValue = value;
362
+ undefinedValue.type = 'Unresolved';
363
+ undefinedValue.value = types_1.IdKeys.UNRESOLVED_VALUE;
364
+ }
365
+ }
366
+ return false;
367
+ }));
368
+ }
369
+ });
42
370
  };
43
371
  exports.initalizeAdgMetadata = initalizeAdgMetadata;
44
372
  /**
@@ -47,18 +375,217 @@ exports.initalizeAdgMetadata = initalizeAdgMetadata;
47
375
  * @param moduleMetadata data structure representing metadata about the module we are working on
48
376
  */
49
377
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
50
- const mapExportNamesToAdgs = (doc, moduleMetadata) => {
51
- // to implement
378
+ const mapExportNamesToAdgs = (exports, moduleMetadata) => {
379
+ if (exports) {
380
+ Object.entries(exports).forEach(([exportName, exportReference]) => {
381
+ if (exportReference?.type === 'AdgReference') {
382
+ const adg = moduleMetadata.adgs.get(exportReference.value);
383
+ if (adg) {
384
+ adg.exportName = exportName;
385
+ moduleMetadata.exports[exportName] = adg;
386
+ }
387
+ }
388
+ });
389
+ }
52
390
  };
53
391
  exports.mapExportNamesToAdgs = mapExportNamesToAdgs;
54
392
  /**
55
393
  * Walk the compositions to see what props are being used, add this information to the adg metadata
56
- * @param doc the KomaciDocument itself
394
+ * @param doc the template KomaciDocument
395
+ * @param adgIndex the index of the default adg
57
396
  * @param moduleMetadata data structure representing metadata about the module we are working on
58
397
  */
59
398
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
60
- const addTemplateUsageForDefaultAdg = (doc, moduleMetadata) => {
61
- // to implement
399
+ const addTemplateUsageForDefaultAdg = (doc, adgIndex, moduleMetadata) => {
400
+ if (moduleMetadata.adgs.has(adgIndex)) {
401
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
402
+ const adg = moduleMetadata.adgs.get(adgIndex);
403
+ if (doc?.exports?.default?.type === 'CompositionReference' &&
404
+ doc.compositions?.[doc.exports.default.value]) {
405
+ const composition = doc.compositions[doc.exports.default.value];
406
+ adg.compositions = [composition];
407
+ (0, komaciDocumentIntrospection_1.traverseComposition)(composition, (comp, iterationContext) => {
408
+ (0, komaciDocumentIntrospection_1.updatePropertiesForComposition)(comp, adg.properties, adg.propertiesUsedInTemplate, iterationContext);
409
+ if (comp && comp.isActive) {
410
+ adg.requiredCompositionFactoryFunctions.add(types_1.IdKeys.UNRESOLVED_FUNC);
411
+ }
412
+ if ((0, komaciDocumentIntrospection_1.isCompositionAComposedAdg)(comp)) {
413
+ adg.requiredCompositionFactoryFunctions.add(types_1.IdKeys.COMPOSED_GRAPH_FUNC);
414
+ if (comp.input.type === 'ImportReference') {
415
+ const importName = moduleMetadata.importIndexReference.get(`t-${comp.input.value}`);
416
+ const importInfo = importName
417
+ ? moduleMetadata.importsByName.get(importName)
418
+ : undefined;
419
+ if (importInfo) {
420
+ importInfo.usedInPriming = true;
421
+ }
422
+ }
423
+ }
424
+ else if ((0, komaciDocumentIntrospection_1.isCompositionASlot)(comp)) {
425
+ adg.requiredCompositionFactoryFunctions.add(types_1.IdKeys.SLOT_FUNC);
426
+ }
427
+ else if ((0, komaciDocumentIntrospection_1.isCompositionAnIteration)(comp)) {
428
+ adg.requiredCompositionFactoryFunctions.add(types_1.IdKeys.ITERATION_FUNC);
429
+ }
430
+ else if ((0, komaciDocumentIntrospection_1.isCompositionAnImage)(comp)) {
431
+ adg.requiredCompositionFactoryFunctions.add(types_1.IdKeys.IMG_FUNC);
432
+ }
433
+ else if ((0, komaciDocumentIntrospection_1.isCompositionAContainer)(comp) && (comp.key || comp.slot)) {
434
+ adg.requiredCompositionFactoryFunctions.add(types_1.IdKeys.ELEMENT_FUNC);
435
+ }
436
+ return false;
437
+ });
438
+ }
439
+ }
62
440
  };
63
441
  exports.addTemplateUsageForDefaultAdg = addTemplateUsageForDefaultAdg;
442
+ /**
443
+ * Collect functional metadata for a wire this includes
444
+ * - wire function details (name, batch / reducer if priming function)
445
+ * - input
446
+ * - required properties
447
+ *
448
+ * all bundled up into one readily available package for later composition
449
+ *
450
+ * @param functionDetails
451
+ * @param wireImport
452
+ * @param moduleMetadata
453
+ * @returns
454
+ */
455
+ const composeWireFunctionMetadata = (functionDetails, wireImport, moduleMetadata) => {
456
+ const isSupported = (0, wires_1.isSupportedWireAdapter)(wireImport.resourceName, wireImport.name);
457
+ const functionMetadata = {
458
+ input: functionDetails.input,
459
+ type: types_1.FunctionTypes.WIRE_FUNCTION,
460
+ requiredProperties: [],
461
+ importReference: {
462
+ functionName: isSupported
463
+ ? wireImport.importAlias || wireImport.name
464
+ : types_1.IdKeys.UNRESOLVED_VALUE,
465
+ },
466
+ };
467
+ // compose required properties
468
+ if (functionDetails.input && functionDetails.input.length > 0) {
469
+ if (functionDetails.input.length !== 1 ||
470
+ functionDetails.input[0].type !== 'ObjectValue') {
471
+ // Only valid input according to Wire Adapter Protocol.
472
+ throw new Error(types_1.ERROR_PREFIX + 'WireFunction has invalid input');
473
+ }
474
+ const inputObject = functionDetails.input[0];
475
+ functionMetadata.requiredProperties = Object.values(inputObject.value)
476
+ .filter(komaciDocumentIntrospection_1.isValueProperty)
477
+ .map((input) => (0, komaciDocumentIntrospection_1.stripChildReferenceFromValue)(input.value));
478
+ }
479
+ const primingAdapterDef = (0, wires_1.getPrimingAdapter)(wireImport.resourceName, wireImport.name);
480
+ if (primingAdapterDef) {
481
+ (0, exports.reconcilePrimingAdapater)(functionMetadata, primingAdapterDef, moduleMetadata);
482
+ functionMetadata.type = types_1.FunctionTypes.PRIMING_FUNCTION;
483
+ wireImport.usedInPriming = false;
484
+ }
485
+ else {
486
+ wireImport.usedInPriming = isSupported;
487
+ }
488
+ return functionMetadata;
489
+ };
490
+ exports.composeWireFunctionMetadata = composeWireFunctionMetadata;
491
+ /**
492
+ * A Wire Function can only have one valid type of reference, an import. if we see an import we should collect the info for that
493
+ * otherwise, we should mark the reference as unresolved and make sure we are accounting for it in factory functions
494
+ * @param func The details about a function from the komaci doc
495
+ * @param adg metadata about the adg this function is in
496
+ * @param moduleMetadata general module metadata (imports mostly)
497
+ * @returns import metadata if this wire references a valid one, undefined otherwise
498
+ */
499
+ const reconcileWireReference = (func, adg, moduleMetadata) => {
500
+ let importMetadata;
501
+ if (func.reference.type === 'ImportReference' &&
502
+ moduleMetadata.importIndexReference.has(func?.reference.value) &&
503
+ moduleMetadata.importsByName.has(
504
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
505
+ moduleMetadata.importIndexReference.get(func?.reference.value))) {
506
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
507
+ importMetadata = moduleMetadata.importsByName.get(
508
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
509
+ moduleMetadata.importIndexReference.get(func?.reference.value));
510
+ }
511
+ else {
512
+ func.reference = {
513
+ type: 'Unresolved',
514
+ value: '',
515
+ };
516
+ adg.requiredAdgFactoryFunctions.add(types_1.IdKeys.UNRESOLVED_VALUE);
517
+ }
518
+ return importMetadata;
519
+ };
520
+ exports.reconcileWireReference = reconcileWireReference;
521
+ /**
522
+ * Some wires have associated priming adapters. if we do have one of those then we want to use it instead of the
523
+ * original wire adapter referenced in the komaci document. as part of this we have to make sure the new imports
524
+ * are made and appropriately referenced inside module metadata
525
+ *
526
+ * @param functionMetadata Details about a wire function
527
+ * @param primingAdapterDef Details about the priming adapter associated for this wire
528
+ * @param moduleMetadata Instance of module metadata data structure
529
+ */
530
+ const reconcilePrimingAdapater = (functionMetadata, primingAdapterDef, moduleMetadata) => {
531
+ const importMetadata = (0, exports.reconcileImport)(primingAdapterDef.prime.identifier, primingAdapterDef.prime.importPath, moduleMetadata);
532
+ importMetadata.usedInPriming = true;
533
+ functionMetadata.importReference.functionName = importMetadata.name;
534
+ if (primingAdapterDef.batch) {
535
+ if (primingAdapterDef.batch.prime.importPath ===
536
+ primingAdapterDef.prime.importPath &&
537
+ primingAdapterDef.batch.prime.identifier ===
538
+ primingAdapterDef.prime.identifier) {
539
+ functionMetadata.importReference.batchingName = importMetadata.name;
540
+ }
541
+ else {
542
+ const batchImport = (0, exports.reconcileImport)(primingAdapterDef.batch.prime.identifier, primingAdapterDef.batch.prime.importPath, moduleMetadata);
543
+ batchImport.usedInPriming = true;
544
+ functionMetadata.importReference.batchingName = batchImport.name;
545
+ }
546
+ const reducerImport = (0, exports.reconcileImport)(primingAdapterDef.batch.reducer.identifier, primingAdapterDef.batch.reducer.importPath, moduleMetadata);
547
+ reducerImport.usedInPriming = true;
548
+ functionMetadata.importReference.reducer = reducerImport.name;
549
+ }
550
+ };
551
+ exports.reconcilePrimingAdapater = reconcilePrimingAdapater;
552
+ function isImportInvalid(importMetadata) {
553
+ return (!importMetadata.isFromInternalNamespace || !importMetadata.isFromSupportedLibrary);
554
+ }
555
+ exports.isImportInvalid = isImportInvalid;
556
+ /**
557
+ * in specific cases, mainly template only compositions, we may not have a default adg already but need one to compose the resolvable module.
558
+ * @param currentDefaultAdgIndex The current index of the default adg if it exists
559
+ * @param moduleMetadata metadata about the module
560
+ * @returns the index of the default adg
561
+ */
562
+ function reconcileDefaultAdg(currentDefaultAdgIndex, moduleMetadata) {
563
+ let componentDefaultAdgIndex = currentDefaultAdgIndex;
564
+ if (componentDefaultAdgIndex === undefined) {
565
+ const fakeDefaultAdg = (0, exports.initAdgMetadataObject)(`adg${moduleMetadata.adgGeneratorIndex++}`);
566
+ fakeDefaultAdg.requiredAdgFactoryFunctions.add(types_1.IdKeys.ADG_FUNC);
567
+ componentDefaultAdgIndex = 0;
568
+ moduleMetadata.adgs.set(componentDefaultAdgIndex, fakeDefaultAdg);
569
+ moduleMetadata.exports.default = fakeDefaultAdg;
570
+ }
571
+ return componentDefaultAdgIndex;
572
+ }
573
+ exports.reconcileDefaultAdg = reconcileDefaultAdg;
574
+ /**
575
+ * If we process a template and see it has some props we don't know about we can uplift them to the adgs props using this.
576
+ * this is only currently used for template only bundles
577
+ * @param adg The metadata object for a given adg
578
+ */
579
+ function upliftFakePropsFromTemplate(adg) {
580
+ for (const prop of adg?.propertiesUsedInTemplate.values()) {
581
+ if (!adg.properties.has(prop)) {
582
+ adg.properties.set(prop, {
583
+ type: types_1.PropertyTypes.BASE,
584
+ isPublic: true,
585
+ usedInPriming: true,
586
+ });
587
+ }
588
+ }
589
+ }
590
+ exports.upliftFakePropsFromTemplate = upliftFakePropsFromTemplate;
64
591
  //# sourceMappingURL=moduleMetadata.js.map