@uniformdev/transformer 1.1.36 → 1.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +317 -18
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +279 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -148,6 +148,8 @@ interface ConvertCompositionsToEntriesOptions extends GlobalOptions {
|
|
|
148
148
|
compositionTypes: string;
|
|
149
149
|
componentsToReferences?: string;
|
|
150
150
|
componentsToBlocks?: string;
|
|
151
|
+
slotsToReferences?: string;
|
|
152
|
+
slotsToBlocks?: string;
|
|
151
153
|
}
|
|
152
154
|
interface RemoveParameterOptions extends GlobalOptions {
|
|
153
155
|
componentType: string;
|
|
@@ -461,6 +463,8 @@ interface ConvertCompositionsToEntriesInternalOptions {
|
|
|
461
463
|
compositionTypes: string[];
|
|
462
464
|
componentsToReferences: string[];
|
|
463
465
|
componentsToBlocks: string[];
|
|
466
|
+
slotsToReferences: string[];
|
|
467
|
+
slotsToBlocks: string[];
|
|
464
468
|
whatIf: boolean;
|
|
465
469
|
strict: boolean;
|
|
466
470
|
}
|
|
@@ -521,6 +525,7 @@ declare class CompositionConverterService {
|
|
|
521
525
|
generateEntryFromFlattenedInstance(inst: FlattenedInstance): EntryDefinition;
|
|
522
526
|
findFlattenTargets(slots: Record<string, ComponentInstance[]>, targetType: string, compositionId: string, compositionName: string, strict: boolean): FlattenedInstance[];
|
|
523
527
|
private walkSlots;
|
|
528
|
+
findInstancesInSlot(slots: Record<string, ComponentInstance[]>, slotName: string, compositionId: string, compositionName: string, strict: boolean): FlattenedInstance[];
|
|
524
529
|
private transformContentReferences;
|
|
525
530
|
buildEntryIdMap(entriesDirFull: string): Promise<Map<string, string>>;
|
|
526
531
|
buildSourceItemMap(entriesDirFull: string): Promise<Map<string, string>>;
|
|
@@ -528,6 +533,7 @@ declare class CompositionConverterService {
|
|
|
528
533
|
private matchesType;
|
|
529
534
|
private compareTypes;
|
|
530
535
|
private expandWildcardTypes;
|
|
536
|
+
private expandWildcardSlots;
|
|
531
537
|
private collectMatchingTypes;
|
|
532
538
|
private truncate;
|
|
533
539
|
private truncateName;
|
package/dist/index.js
CHANGED
|
@@ -597,11 +597,15 @@ var CompositionConverterService = class {
|
|
|
597
597
|
compositionTypes,
|
|
598
598
|
componentsToReferences: rawComponentsToReferences,
|
|
599
599
|
componentsToBlocks: rawComponentsToBlocks,
|
|
600
|
+
slotsToReferences: rawSlotsToReferences,
|
|
601
|
+
slotsToBlocks: rawSlotsToBlocks,
|
|
600
602
|
whatIf,
|
|
601
603
|
strict
|
|
602
604
|
} = options;
|
|
603
605
|
const initialComponentsToReferences = [...new Set(rawComponentsToReferences)];
|
|
604
606
|
const initialComponentsToBlocks = [...new Set(rawComponentsToBlocks)];
|
|
607
|
+
const initialSlotsToReferences = [...new Set(rawSlotsToReferences)];
|
|
608
|
+
const initialSlotsToBlocks = [...new Set(rawSlotsToBlocks)];
|
|
605
609
|
const compositionsDirFull = this.fileSystem.resolvePath(rootDir, compositionsDir);
|
|
606
610
|
const componentsDirFull = this.fileSystem.resolvePath(rootDir, componentsDir);
|
|
607
611
|
const contentTypesDirFull = this.fileSystem.resolvePath(rootDir, contentTypesDir);
|
|
@@ -618,7 +622,13 @@ var CompositionConverterService = class {
|
|
|
618
622
|
if (initialComponentsToBlocks.length > 0) {
|
|
619
623
|
this.logger.info(`Components to blocks: ${initialComponentsToBlocks.join(", ")}`);
|
|
620
624
|
}
|
|
621
|
-
|
|
625
|
+
if (initialSlotsToReferences.length > 0) {
|
|
626
|
+
this.logger.info(`Slots to references: ${initialSlotsToReferences.join(", ")}`);
|
|
627
|
+
}
|
|
628
|
+
if (initialSlotsToBlocks.length > 0) {
|
|
629
|
+
this.logger.info(`Slots to blocks: ${initialSlotsToBlocks.join(", ")}`);
|
|
630
|
+
}
|
|
631
|
+
const sourceItemMap = initialComponentsToReferences.length > 0 || initialSlotsToReferences.length > 0 ? await this.buildSourceItemMap(entriesDirFull) : /* @__PURE__ */ new Map();
|
|
622
632
|
if (sourceItemMap.size > 0) {
|
|
623
633
|
this.logger.info(`Found ${sourceItemMap.size} existing entry(ies) with sourceItem values`);
|
|
624
634
|
}
|
|
@@ -635,6 +645,8 @@ var CompositionConverterService = class {
|
|
|
635
645
|
this.logger.info(`Found ${compositionResults.length} composition(s)`);
|
|
636
646
|
const componentsToReferences = this.expandWildcardTypes(compositionResults, initialComponentsToReferences, strict);
|
|
637
647
|
const componentsToBlocks = this.expandWildcardTypes(compositionResults, initialComponentsToBlocks, strict);
|
|
648
|
+
const slotsToReferences = this.expandWildcardSlots(compositionResults, initialSlotsToReferences, strict);
|
|
649
|
+
const slotsToBlocks = this.expandWildcardSlots(compositionResults, initialSlotsToBlocks, strict);
|
|
638
650
|
const rootComponentTypes = /* @__PURE__ */ new Set();
|
|
639
651
|
for (const { composition } of compositionResults) {
|
|
640
652
|
rootComponentTypes.add(composition.composition.type);
|
|
@@ -735,6 +747,83 @@ var CompositionConverterService = class {
|
|
|
735
747
|
throw error;
|
|
736
748
|
}
|
|
737
749
|
}
|
|
750
|
+
const slotToRefTypes = /* @__PURE__ */ new Map();
|
|
751
|
+
const slotToBlockTypes = /* @__PURE__ */ new Map();
|
|
752
|
+
for (const slotName of slotsToReferences) slotToRefTypes.set(slotName, /* @__PURE__ */ new Set());
|
|
753
|
+
for (const slotName of slotsToBlocks) slotToBlockTypes.set(slotName, /* @__PURE__ */ new Set());
|
|
754
|
+
for (const { composition: discoverComp } of compositionResults) {
|
|
755
|
+
const dc = discoverComp.composition;
|
|
756
|
+
if (!dc.slots) continue;
|
|
757
|
+
const dcName = dc._name ?? dc._id;
|
|
758
|
+
for (const slotName of slotsToReferences) {
|
|
759
|
+
const instances = this.findInstancesInSlot(dc.slots, slotName, dc._id, dcName, strict);
|
|
760
|
+
for (const inst of instances) {
|
|
761
|
+
if (!this.compareTypes(inst.componentType, dc.type, strict)) {
|
|
762
|
+
slotToRefTypes.get(slotName).add(inst.componentType);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
for (const slotName of slotsToBlocks) {
|
|
767
|
+
const instances = this.findInstancesInSlot(dc.slots, slotName, dc._id, dcName, strict);
|
|
768
|
+
for (const inst of instances) {
|
|
769
|
+
if (!this.compareTypes(inst.componentType, dc.type, strict)) {
|
|
770
|
+
slotToBlockTypes.get(slotName).add(inst.componentType);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
const allSlotRefTypes = /* @__PURE__ */ new Set();
|
|
776
|
+
for (const types of slotToRefTypes.values()) for (const t of types) allSlotRefTypes.add(t);
|
|
777
|
+
const allSlotBlockTypes = /* @__PURE__ */ new Set();
|
|
778
|
+
for (const types of slotToBlockTypes.values()) for (const t of types) allSlotBlockTypes.add(t);
|
|
779
|
+
const allSlotTargetTypes = /* @__PURE__ */ new Set([...allSlotRefTypes, ...allSlotBlockTypes]);
|
|
780
|
+
for (const targetType of allSlotTargetTypes) {
|
|
781
|
+
if (targetContentTypeMap.has(targetType) || missingTargetTypes.includes(targetType)) continue;
|
|
782
|
+
const isRootType = [...rootComponentTypes].some((rt) => this.compareTypes(rt, targetType, strict));
|
|
783
|
+
if (isRootType) continue;
|
|
784
|
+
const isSlotBlockType = allSlotBlockTypes.has(targetType);
|
|
785
|
+
const isSlotRefType = allSlotRefTypes.has(targetType);
|
|
786
|
+
try {
|
|
787
|
+
const { component } = await this.componentService.loadComponent(componentsDirFull, targetType, { strict });
|
|
788
|
+
if (isSlotRefType) {
|
|
789
|
+
const contentType = this.generateContentType(component);
|
|
790
|
+
targetContentTypeMap.set(targetType, contentType);
|
|
791
|
+
this.logger.debug(`Generated slot reference content type "${targetType}" with ${contentType.fields.length} field(s)`);
|
|
792
|
+
}
|
|
793
|
+
if (isSlotBlockType && !blockTypeIdMap.has(targetType)) {
|
|
794
|
+
let blockId = targetType;
|
|
795
|
+
let needsRename = isSlotRefType;
|
|
796
|
+
if (!needsRename) {
|
|
797
|
+
const existingPath = this.fileSystem.joinPath(contentTypesDirFull, `${targetType}.json`);
|
|
798
|
+
if (await this.fileSystem.fileExists(existingPath)) {
|
|
799
|
+
try {
|
|
800
|
+
const existing = await this.fileSystem.readFile(existingPath);
|
|
801
|
+
if (existing?.type !== "block") needsRename = true;
|
|
802
|
+
} catch {
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
if (needsRename) {
|
|
807
|
+
blockId = `${targetType}Block`;
|
|
808
|
+
this.logger.info(`Content type "${targetType}" already exists as non-block, using "${blockId}" for block`);
|
|
809
|
+
}
|
|
810
|
+
blockTypeIdMap.set(targetType, blockId);
|
|
811
|
+
const blockContentType = this.generateContentType(component);
|
|
812
|
+
blockContentType.type = "block";
|
|
813
|
+
blockContentType.id = blockId;
|
|
814
|
+
blockContentType.name = needsRename ? `${blockContentType.name} Block` : blockContentType.name;
|
|
815
|
+
targetContentTypeMap.set(blockId, blockContentType);
|
|
816
|
+
this.logger.debug(`Generated slot block content type "${blockId}" with ${blockContentType.fields.length} field(s)`);
|
|
817
|
+
}
|
|
818
|
+
} catch (error) {
|
|
819
|
+
if (error instanceof ComponentNotFoundError) {
|
|
820
|
+
this.logger.info(`Component type not found: ${targetType}`);
|
|
821
|
+
if (isSlotBlockType && !blockTypeIdMap.has(targetType)) blockTypeIdMap.set(targetType, targetType);
|
|
822
|
+
continue;
|
|
823
|
+
}
|
|
824
|
+
throw error;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
738
827
|
for (const { composition } of compositionResults) {
|
|
739
828
|
const comp = composition.composition;
|
|
740
829
|
const compositionId = comp._id;
|
|
@@ -800,7 +889,43 @@ var CompositionConverterService = class {
|
|
|
800
889
|
value: resolvedRefIds.get(refType)
|
|
801
890
|
};
|
|
802
891
|
}
|
|
803
|
-
|
|
892
|
+
const refsBySlot = /* @__PURE__ */ new Map();
|
|
893
|
+
if (slotsToReferences.length > 0 && comp.slots) {
|
|
894
|
+
for (const slotName of slotsToReferences) {
|
|
895
|
+
const instances = this.findInstancesInSlot(
|
|
896
|
+
comp.slots,
|
|
897
|
+
slotName,
|
|
898
|
+
compositionId,
|
|
899
|
+
compositionName,
|
|
900
|
+
strict
|
|
901
|
+
);
|
|
902
|
+
const filtered = instances.filter((inst) => {
|
|
903
|
+
if (this.compareTypes(inst.componentType, compositionType, strict)) {
|
|
904
|
+
this.logger.warn(`Skipping reference of "${inst.componentType}" in slot "${slotName}" \u2014 same as root component type`);
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
return true;
|
|
908
|
+
});
|
|
909
|
+
this.logger.debug(`Composition "${compositionName}": found ${filtered.length} instance(s) in reference slot "${slotName}"`);
|
|
910
|
+
if (filtered.length > 0) refsBySlot.set(slotName, filtered);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
const resolvedSlotRefIds = /* @__PURE__ */ new Map();
|
|
914
|
+
for (const [slotName, instances] of refsBySlot) {
|
|
915
|
+
const refIds = [];
|
|
916
|
+
for (const inst of instances) {
|
|
917
|
+
const existingId = this.findExistingEntryBySourceItem(inst, sourceItemMap);
|
|
918
|
+
refIds.push(existingId ?? inst.determinisiticId);
|
|
919
|
+
}
|
|
920
|
+
resolvedSlotRefIds.set(slotName, refIds);
|
|
921
|
+
}
|
|
922
|
+
for (const [slotName] of refsBySlot) {
|
|
923
|
+
entry.entry.fields[slotName] = {
|
|
924
|
+
type: "contentReference",
|
|
925
|
+
value: resolvedSlotRefIds.get(slotName)
|
|
926
|
+
};
|
|
927
|
+
}
|
|
928
|
+
if (componentsToReferences.length > 0 || slotsToReferences.length > 0) {
|
|
804
929
|
this.transformContentReferences(entry);
|
|
805
930
|
}
|
|
806
931
|
const blocksByType = /* @__PURE__ */ new Map();
|
|
@@ -840,6 +965,35 @@ var CompositionConverterService = class {
|
|
|
840
965
|
};
|
|
841
966
|
blocksEmbedded += instances.length;
|
|
842
967
|
}
|
|
968
|
+
const blocksBySlot = /* @__PURE__ */ new Map();
|
|
969
|
+
if (slotsToBlocks.length > 0 && comp.slots) {
|
|
970
|
+
for (const slotName of slotsToBlocks) {
|
|
971
|
+
const instances = this.findInstancesInSlot(
|
|
972
|
+
comp.slots,
|
|
973
|
+
slotName,
|
|
974
|
+
compositionId,
|
|
975
|
+
compositionName,
|
|
976
|
+
strict
|
|
977
|
+
);
|
|
978
|
+
const filtered = instances.filter((inst) => {
|
|
979
|
+
if (this.compareTypes(inst.componentType, compositionType, strict)) {
|
|
980
|
+
this.logger.warn(`Skipping block of "${inst.componentType}" in slot "${slotName}" \u2014 same as root component type`);
|
|
981
|
+
return false;
|
|
982
|
+
}
|
|
983
|
+
return true;
|
|
984
|
+
});
|
|
985
|
+
this.logger.debug(`Composition "${compositionName}": found ${filtered.length} instance(s) in block slot "${slotName}"`);
|
|
986
|
+
if (filtered.length > 0) blocksBySlot.set(slotName, filtered);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
for (const [slotName, instances] of blocksBySlot) {
|
|
990
|
+
const blockValues = instances.map((inst) => ({
|
|
991
|
+
type: blockTypeIdMap.get(inst.componentType) ?? inst.componentType,
|
|
992
|
+
fields: { ...inst.instance.parameters ?? {} }
|
|
993
|
+
}));
|
|
994
|
+
entry.entry.fields[slotName] = { type: "$block", value: blockValues };
|
|
995
|
+
blocksEmbedded += instances.length;
|
|
996
|
+
}
|
|
843
997
|
const entryId = entry.entry._id;
|
|
844
998
|
if (isExistingEntry) {
|
|
845
999
|
this.logger.action(
|
|
@@ -908,6 +1062,42 @@ var CompositionConverterService = class {
|
|
|
908
1062
|
entriesFromReferences++;
|
|
909
1063
|
}
|
|
910
1064
|
}
|
|
1065
|
+
for (const [, instances] of refsBySlot) {
|
|
1066
|
+
for (const inst of instances) {
|
|
1067
|
+
const existingId = this.findExistingEntryBySourceItem(inst, sourceItemMap);
|
|
1068
|
+
if (existingId) {
|
|
1069
|
+
const existingSlotEntryPath = this.fileSystem.joinPath(entriesDirFull, `${existingId}.json`);
|
|
1070
|
+
this.logger.action(
|
|
1071
|
+
whatIf,
|
|
1072
|
+
"UPDATE",
|
|
1073
|
+
`${entriesDir}/${existingId}.json (${inst.componentType}, merged fields from "${this.truncate(compositionName, 50)}")`
|
|
1074
|
+
);
|
|
1075
|
+
if (!whatIf) {
|
|
1076
|
+
const existingEntry = await this.fileSystem.readFile(existingSlotEntryPath);
|
|
1077
|
+
if (existingEntry?.entry) {
|
|
1078
|
+
existingEntry.entry.fields = {
|
|
1079
|
+
...existingEntry.entry.fields,
|
|
1080
|
+
...inst.instance.parameters ?? {}
|
|
1081
|
+
};
|
|
1082
|
+
await this.fileSystem.writeFile(existingSlotEntryPath, existingEntry);
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
entriesReused++;
|
|
1086
|
+
continue;
|
|
1087
|
+
}
|
|
1088
|
+
const flatEntry = this.generateEntryFromFlattenedInstance(inst);
|
|
1089
|
+
const flatEntryPath = this.fileSystem.joinPath(entriesDirFull, `${inst.determinisiticId}.json`);
|
|
1090
|
+
this.logger.action(
|
|
1091
|
+
whatIf,
|
|
1092
|
+
"WRITE",
|
|
1093
|
+
`${entriesDir}/${inst.determinisiticId}.json (${inst.componentType} from "${this.truncate(compositionName, 50)}")`
|
|
1094
|
+
);
|
|
1095
|
+
if (!whatIf) {
|
|
1096
|
+
await this.fileSystem.writeFile(flatEntryPath, flatEntry);
|
|
1097
|
+
}
|
|
1098
|
+
entriesFromReferences++;
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
911
1101
|
}
|
|
912
1102
|
if (componentsToReferences.length > 0) {
|
|
913
1103
|
for (const contentType of contentTypeMap.values()) {
|
|
@@ -955,6 +1145,42 @@ var CompositionConverterService = class {
|
|
|
955
1145
|
}
|
|
956
1146
|
}
|
|
957
1147
|
}
|
|
1148
|
+
if (slotsToReferences.length > 0) {
|
|
1149
|
+
for (const contentType of contentTypeMap.values()) {
|
|
1150
|
+
for (const slotName of slotsToReferences) {
|
|
1151
|
+
const typesInSlot = slotToRefTypes.get(slotName) ?? /* @__PURE__ */ new Set();
|
|
1152
|
+
const allowedTypes = [...typesInSlot].filter(
|
|
1153
|
+
(t) => !this.compareTypes(t, contentType.id, strict)
|
|
1154
|
+
);
|
|
1155
|
+
if (allowedTypes.length === 0) continue;
|
|
1156
|
+
contentType.fields.push({
|
|
1157
|
+
id: slotName,
|
|
1158
|
+
name: slotName,
|
|
1159
|
+
type: "contentReference",
|
|
1160
|
+
typeConfig: { isMulti: true, allowedTypes },
|
|
1161
|
+
localizable: false
|
|
1162
|
+
});
|
|
1163
|
+
this.logger.debug(`Field "${slotName}" (contentReference, allowedTypes: ${allowedTypes.join(", ")}) added to content type "${contentType.id}"`);
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
if (slotsToBlocks.length > 0) {
|
|
1168
|
+
for (const contentType of contentTypeMap.values()) {
|
|
1169
|
+
for (const slotName of slotsToBlocks) {
|
|
1170
|
+
const typesInSlot = slotToBlockTypes.get(slotName) ?? /* @__PURE__ */ new Set();
|
|
1171
|
+
const resolvedBlockIds = [...typesInSlot].filter((t) => !this.compareTypes(t, contentType.id, strict)).map((t) => blockTypeIdMap.get(t) ?? t);
|
|
1172
|
+
if (resolvedBlockIds.length === 0) continue;
|
|
1173
|
+
contentType.fields.push({
|
|
1174
|
+
id: slotName,
|
|
1175
|
+
name: slotName,
|
|
1176
|
+
type: "$block",
|
|
1177
|
+
typeConfig: { allowedTypes: resolvedBlockIds },
|
|
1178
|
+
localizable: false
|
|
1179
|
+
});
|
|
1180
|
+
this.logger.debug(`Field "${slotName}" ($block, allowedTypes: ${resolvedBlockIds.join(", ")}) added to content type "${contentType.id}"`);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
958
1184
|
for (const contentType of contentTypeMap.values()) {
|
|
959
1185
|
contentType.fields = this.componentService.sortParametersByGroup(contentType.fields);
|
|
960
1186
|
}
|
|
@@ -1121,6 +1347,29 @@ var CompositionConverterService = class {
|
|
|
1121
1347
|
}
|
|
1122
1348
|
}
|
|
1123
1349
|
}
|
|
1350
|
+
// --- Slot-Based Instance Finding ---
|
|
1351
|
+
findInstancesInSlot(slots, slotName, compositionId, compositionName, strict) {
|
|
1352
|
+
const results = [];
|
|
1353
|
+
for (const [name, instances] of Object.entries(slots)) {
|
|
1354
|
+
const matches = strict ? name === slotName : name.toLowerCase() === slotName.toLowerCase();
|
|
1355
|
+
if (!matches) continue;
|
|
1356
|
+
if (!Array.isArray(instances)) continue;
|
|
1357
|
+
for (let i = 0; i < instances.length; i++) {
|
|
1358
|
+
const instance = instances[i];
|
|
1359
|
+
if (instance._pattern) continue;
|
|
1360
|
+
const path2 = `${compositionId}-${name}-[${i}]-${instance.type}`;
|
|
1361
|
+
results.push({
|
|
1362
|
+
instance,
|
|
1363
|
+
path: path2,
|
|
1364
|
+
determinisiticId: computeGuidHash(path2),
|
|
1365
|
+
componentType: instance.type,
|
|
1366
|
+
compositionId,
|
|
1367
|
+
compositionName
|
|
1368
|
+
});
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
return results;
|
|
1372
|
+
}
|
|
1124
1373
|
// --- Content Reference Transformation ---
|
|
1125
1374
|
transformContentReferences(entry) {
|
|
1126
1375
|
const dataResources = {};
|
|
@@ -1223,6 +1472,34 @@ var CompositionConverterService = class {
|
|
|
1223
1472
|
}
|
|
1224
1473
|
return [...new Set(expanded)];
|
|
1225
1474
|
}
|
|
1475
|
+
expandWildcardSlots(compositionResults, patterns, strict) {
|
|
1476
|
+
const expanded = [];
|
|
1477
|
+
for (const pattern of patterns) {
|
|
1478
|
+
if (!pattern.includes("*")) {
|
|
1479
|
+
expanded.push(pattern);
|
|
1480
|
+
continue;
|
|
1481
|
+
}
|
|
1482
|
+
const matched = /* @__PURE__ */ new Set();
|
|
1483
|
+
for (const { composition } of compositionResults) {
|
|
1484
|
+
if (composition.composition.slots) {
|
|
1485
|
+
for (const slotName of Object.keys(composition.composition.slots)) {
|
|
1486
|
+
if (this.matchesType(slotName, pattern, strict)) {
|
|
1487
|
+
matched.add(slotName);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
if (matched.size === 0) {
|
|
1493
|
+
this.logger.warn(`Wildcard pattern "${pattern}" did not match any slot names`);
|
|
1494
|
+
} else {
|
|
1495
|
+
this.logger.info(`Wildcard "${pattern}" expanded to: ${[...matched].join(", ")}`);
|
|
1496
|
+
}
|
|
1497
|
+
for (const name of matched) {
|
|
1498
|
+
expanded.push(name);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
return [...new Set(expanded)];
|
|
1502
|
+
}
|
|
1226
1503
|
collectMatchingTypes(slots, pattern, strict, matched) {
|
|
1227
1504
|
for (const instances of Object.values(slots)) {
|
|
1228
1505
|
if (!Array.isArray(instances)) continue;
|