@uniformdev/transformer 1.1.35 → 1.1.37

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 CHANGED
@@ -607,11 +607,15 @@ var CompositionConverterService = class {
607
607
  compositionTypes,
608
608
  componentsToReferences: rawComponentsToReferences,
609
609
  componentsToBlocks: rawComponentsToBlocks,
610
+ slotsToReferences: rawSlotsToReferences,
611
+ slotsToBlocks: rawSlotsToBlocks,
610
612
  whatIf,
611
613
  strict
612
614
  } = options;
613
615
  const initialComponentsToReferences = [...new Set(rawComponentsToReferences)];
614
616
  const initialComponentsToBlocks = [...new Set(rawComponentsToBlocks)];
617
+ const initialSlotsToReferences = [...new Set(rawSlotsToReferences)];
618
+ const initialSlotsToBlocks = [...new Set(rawSlotsToBlocks)];
615
619
  const compositionsDirFull = this.fileSystem.resolvePath(rootDir, compositionsDir);
616
620
  const componentsDirFull = this.fileSystem.resolvePath(rootDir, componentsDir);
617
621
  const contentTypesDirFull = this.fileSystem.resolvePath(rootDir, contentTypesDir);
@@ -628,7 +632,13 @@ var CompositionConverterService = class {
628
632
  if (initialComponentsToBlocks.length > 0) {
629
633
  this.logger.info(`Components to blocks: ${initialComponentsToBlocks.join(", ")}`);
630
634
  }
631
- const sourceItemMap = initialComponentsToReferences.length > 0 ? await this.buildSourceItemMap(entriesDirFull) : /* @__PURE__ */ new Map();
635
+ if (initialSlotsToReferences.length > 0) {
636
+ this.logger.info(`Slots to references: ${initialSlotsToReferences.join(", ")}`);
637
+ }
638
+ if (initialSlotsToBlocks.length > 0) {
639
+ this.logger.info(`Slots to blocks: ${initialSlotsToBlocks.join(", ")}`);
640
+ }
641
+ const sourceItemMap = initialComponentsToReferences.length > 0 || initialSlotsToReferences.length > 0 ? await this.buildSourceItemMap(entriesDirFull) : /* @__PURE__ */ new Map();
632
642
  if (sourceItemMap.size > 0) {
633
643
  this.logger.info(`Found ${sourceItemMap.size} existing entry(ies) with sourceItem values`);
634
644
  }
@@ -645,6 +655,8 @@ var CompositionConverterService = class {
645
655
  this.logger.info(`Found ${compositionResults.length} composition(s)`);
646
656
  const componentsToReferences = this.expandWildcardTypes(compositionResults, initialComponentsToReferences, strict);
647
657
  const componentsToBlocks = this.expandWildcardTypes(compositionResults, initialComponentsToBlocks, strict);
658
+ const slotsToReferences = this.expandWildcardSlots(compositionResults, initialSlotsToReferences, strict);
659
+ const slotsToBlocks = this.expandWildcardSlots(compositionResults, initialSlotsToBlocks, strict);
648
660
  const rootComponentTypes = /* @__PURE__ */ new Set();
649
661
  for (const { composition } of compositionResults) {
650
662
  rootComponentTypes.add(composition.composition.type);
@@ -659,6 +671,7 @@ var CompositionConverterService = class {
659
671
  );
660
672
  const contentType = this.generateContentType(component);
661
673
  contentTypeMap.set(rootType, contentType);
674
+ this.logger.debug(`Generated content type "${rootType}" with ${contentType.fields.length} field(s): ${contentType.fields.map((f) => f.id).join(", ")}`);
662
675
  } catch (error) {
663
676
  if (error instanceof ComponentNotFoundError) {
664
677
  this.logger.warn(`Component not found: ${rootType} \u2014 skipping content type generation`);
@@ -694,6 +707,7 @@ var CompositionConverterService = class {
694
707
  if (isRefType) {
695
708
  const contentType = this.generateContentType(component);
696
709
  targetContentTypeMap.set(targetType, contentType);
710
+ this.logger.debug(`Generated reference content type "${targetType}" with ${contentType.fields.length} field(s): ${contentType.fields.map((f) => f.id).join(", ")}`);
697
711
  }
698
712
  if (isBlockType) {
699
713
  let blockId = targetType;
@@ -723,6 +737,7 @@ var CompositionConverterService = class {
723
737
  blockContentType.id = blockId;
724
738
  blockContentType.name = needsRename ? `${blockContentType.name} Block` : blockContentType.name;
725
739
  targetContentTypeMap.set(blockId, blockContentType);
740
+ this.logger.debug(`Generated block content type "${blockId}" with ${blockContentType.fields.length} field(s): ${blockContentType.fields.map((f) => f.id).join(", ")}`);
726
741
  }
727
742
  if (!isBlockType) {
728
743
  if (!isRefType) {
@@ -742,6 +757,83 @@ var CompositionConverterService = class {
742
757
  throw error;
743
758
  }
744
759
  }
760
+ const slotToRefTypes = /* @__PURE__ */ new Map();
761
+ const slotToBlockTypes = /* @__PURE__ */ new Map();
762
+ for (const slotName of slotsToReferences) slotToRefTypes.set(slotName, /* @__PURE__ */ new Set());
763
+ for (const slotName of slotsToBlocks) slotToBlockTypes.set(slotName, /* @__PURE__ */ new Set());
764
+ for (const { composition: discoverComp } of compositionResults) {
765
+ const dc = discoverComp.composition;
766
+ if (!dc.slots) continue;
767
+ const dcName = dc._name ?? dc._id;
768
+ for (const slotName of slotsToReferences) {
769
+ const instances = this.findInstancesInSlot(dc.slots, slotName, dc._id, dcName, strict);
770
+ for (const inst of instances) {
771
+ if (!this.compareTypes(inst.componentType, dc.type, strict)) {
772
+ slotToRefTypes.get(slotName).add(inst.componentType);
773
+ }
774
+ }
775
+ }
776
+ for (const slotName of slotsToBlocks) {
777
+ const instances = this.findInstancesInSlot(dc.slots, slotName, dc._id, dcName, strict);
778
+ for (const inst of instances) {
779
+ if (!this.compareTypes(inst.componentType, dc.type, strict)) {
780
+ slotToBlockTypes.get(slotName).add(inst.componentType);
781
+ }
782
+ }
783
+ }
784
+ }
785
+ const allSlotRefTypes = /* @__PURE__ */ new Set();
786
+ for (const types of slotToRefTypes.values()) for (const t of types) allSlotRefTypes.add(t);
787
+ const allSlotBlockTypes = /* @__PURE__ */ new Set();
788
+ for (const types of slotToBlockTypes.values()) for (const t of types) allSlotBlockTypes.add(t);
789
+ const allSlotTargetTypes = /* @__PURE__ */ new Set([...allSlotRefTypes, ...allSlotBlockTypes]);
790
+ for (const targetType of allSlotTargetTypes) {
791
+ if (targetContentTypeMap.has(targetType) || missingTargetTypes.includes(targetType)) continue;
792
+ const isRootType = [...rootComponentTypes].some((rt) => this.compareTypes(rt, targetType, strict));
793
+ if (isRootType) continue;
794
+ const isSlotBlockType = allSlotBlockTypes.has(targetType);
795
+ const isSlotRefType = allSlotRefTypes.has(targetType);
796
+ try {
797
+ const { component } = await this.componentService.loadComponent(componentsDirFull, targetType, { strict });
798
+ if (isSlotRefType) {
799
+ const contentType = this.generateContentType(component);
800
+ targetContentTypeMap.set(targetType, contentType);
801
+ this.logger.debug(`Generated slot reference content type "${targetType}" with ${contentType.fields.length} field(s)`);
802
+ }
803
+ if (isSlotBlockType && !blockTypeIdMap.has(targetType)) {
804
+ let blockId = targetType;
805
+ let needsRename = isSlotRefType;
806
+ if (!needsRename) {
807
+ const existingPath = this.fileSystem.joinPath(contentTypesDirFull, `${targetType}.json`);
808
+ if (await this.fileSystem.fileExists(existingPath)) {
809
+ try {
810
+ const existing = await this.fileSystem.readFile(existingPath);
811
+ if (existing?.type !== "block") needsRename = true;
812
+ } catch {
813
+ }
814
+ }
815
+ }
816
+ if (needsRename) {
817
+ blockId = `${targetType}Block`;
818
+ this.logger.info(`Content type "${targetType}" already exists as non-block, using "${blockId}" for block`);
819
+ }
820
+ blockTypeIdMap.set(targetType, blockId);
821
+ const blockContentType = this.generateContentType(component);
822
+ blockContentType.type = "block";
823
+ blockContentType.id = blockId;
824
+ blockContentType.name = needsRename ? `${blockContentType.name} Block` : blockContentType.name;
825
+ targetContentTypeMap.set(blockId, blockContentType);
826
+ this.logger.debug(`Generated slot block content type "${blockId}" with ${blockContentType.fields.length} field(s)`);
827
+ }
828
+ } catch (error) {
829
+ if (error instanceof ComponentNotFoundError) {
830
+ this.logger.info(`Component type not found: ${targetType}`);
831
+ if (isSlotBlockType && !blockTypeIdMap.has(targetType)) blockTypeIdMap.set(targetType, targetType);
832
+ continue;
833
+ }
834
+ throw error;
835
+ }
836
+ }
745
837
  for (const { composition } of compositionResults) {
746
838
  const comp = composition.composition;
747
839
  const compositionId = comp._id;
@@ -764,6 +856,7 @@ var CompositionConverterService = class {
764
856
  }
765
857
  } else {
766
858
  entry = this.generateEntryFromComposition(composition);
859
+ this.logger.debug(`Generated entry "${entry.entry._id}" from composition "${compositionName}" (${compositionType}) with fields: ${Object.keys(entry.entry.fields).join(", ") || "(none)"}`);
767
860
  }
768
861
  const refsByType = /* @__PURE__ */ new Map();
769
862
  if (componentsToReferences.length > 0 && comp.slots) {
@@ -781,6 +874,7 @@ var CompositionConverterService = class {
781
874
  compositionName,
782
875
  strict
783
876
  );
877
+ this.logger.debug(`Composition "${compositionName}": found ${instances.length} instance(s) of reference type "${refType}"`);
784
878
  if (instances.length > 0) {
785
879
  refsByType.set(refType, instances);
786
880
  if (missingTargetTypes.includes(refType)) {
@@ -794,6 +888,7 @@ var CompositionConverterService = class {
794
888
  const refIds = [];
795
889
  for (const inst of instances) {
796
890
  const existingId = this.findExistingEntryBySourceItem(inst, sourceItemMap);
891
+ this.logger.debug(`Reference instance "${inst.determinisiticId}" (${refType}): ${existingId ? `reusing existing entry "${existingId}"` : `assigned new ID "${inst.determinisiticId}"`}`);
797
892
  refIds.push(existingId ?? inst.determinisiticId);
798
893
  }
799
894
  resolvedRefIds.set(refType, refIds);
@@ -804,7 +899,43 @@ var CompositionConverterService = class {
804
899
  value: resolvedRefIds.get(refType)
805
900
  };
806
901
  }
807
- if (componentsToReferences.length > 0) {
902
+ const refsBySlot = /* @__PURE__ */ new Map();
903
+ if (slotsToReferences.length > 0 && comp.slots) {
904
+ for (const slotName of slotsToReferences) {
905
+ const instances = this.findInstancesInSlot(
906
+ comp.slots,
907
+ slotName,
908
+ compositionId,
909
+ compositionName,
910
+ strict
911
+ );
912
+ const filtered = instances.filter((inst) => {
913
+ if (this.compareTypes(inst.componentType, compositionType, strict)) {
914
+ this.logger.warn(`Skipping reference of "${inst.componentType}" in slot "${slotName}" \u2014 same as root component type`);
915
+ return false;
916
+ }
917
+ return true;
918
+ });
919
+ this.logger.debug(`Composition "${compositionName}": found ${filtered.length} instance(s) in reference slot "${slotName}"`);
920
+ if (filtered.length > 0) refsBySlot.set(slotName, filtered);
921
+ }
922
+ }
923
+ const resolvedSlotRefIds = /* @__PURE__ */ new Map();
924
+ for (const [slotName, instances] of refsBySlot) {
925
+ const refIds = [];
926
+ for (const inst of instances) {
927
+ const existingId = this.findExistingEntryBySourceItem(inst, sourceItemMap);
928
+ refIds.push(existingId ?? inst.determinisiticId);
929
+ }
930
+ resolvedSlotRefIds.set(slotName, refIds);
931
+ }
932
+ for (const [slotName] of refsBySlot) {
933
+ entry.entry.fields[slotName] = {
934
+ type: "contentReference",
935
+ value: resolvedSlotRefIds.get(slotName)
936
+ };
937
+ }
938
+ if (componentsToReferences.length > 0 || slotsToReferences.length > 0) {
808
939
  this.transformContentReferences(entry);
809
940
  }
810
941
  const blocksByType = /* @__PURE__ */ new Map();
@@ -823,6 +954,7 @@ var CompositionConverterService = class {
823
954
  compositionName,
824
955
  strict
825
956
  );
957
+ this.logger.debug(`Composition "${compositionName}": found ${instances.length} instance(s) of block type "${blockType}"`);
826
958
  if (instances.length > 0) {
827
959
  blocksByType.set(blockType, instances);
828
960
  if (missingTargetTypes.includes(blockType)) {
@@ -843,6 +975,35 @@ var CompositionConverterService = class {
843
975
  };
844
976
  blocksEmbedded += instances.length;
845
977
  }
978
+ const blocksBySlot = /* @__PURE__ */ new Map();
979
+ if (slotsToBlocks.length > 0 && comp.slots) {
980
+ for (const slotName of slotsToBlocks) {
981
+ const instances = this.findInstancesInSlot(
982
+ comp.slots,
983
+ slotName,
984
+ compositionId,
985
+ compositionName,
986
+ strict
987
+ );
988
+ const filtered = instances.filter((inst) => {
989
+ if (this.compareTypes(inst.componentType, compositionType, strict)) {
990
+ this.logger.warn(`Skipping block of "${inst.componentType}" in slot "${slotName}" \u2014 same as root component type`);
991
+ return false;
992
+ }
993
+ return true;
994
+ });
995
+ this.logger.debug(`Composition "${compositionName}": found ${filtered.length} instance(s) in block slot "${slotName}"`);
996
+ if (filtered.length > 0) blocksBySlot.set(slotName, filtered);
997
+ }
998
+ }
999
+ for (const [slotName, instances] of blocksBySlot) {
1000
+ const blockValues = instances.map((inst) => ({
1001
+ type: blockTypeIdMap.get(inst.componentType) ?? inst.componentType,
1002
+ fields: { ...inst.instance.parameters ?? {} }
1003
+ }));
1004
+ entry.entry.fields[slotName] = { type: "$block", value: blockValues };
1005
+ blocksEmbedded += instances.length;
1006
+ }
846
1007
  const entryId = entry.entry._id;
847
1008
  if (isExistingEntry) {
848
1009
  this.logger.action(
@@ -879,6 +1040,7 @@ var CompositionConverterService = class {
879
1040
  "UPDATE",
880
1041
  `${entriesDir}/${existingId}.json (${refType}, merged fields from "${this.truncate(compositionName, 50)}")`
881
1042
  );
1043
+ this.logger.debug(`Merging fields [${Object.keys(inst.instance.parameters ?? {}).join(", ") || "(none)"}] into existing reference entry "${existingId}"`);
882
1044
  if (!whatIf) {
883
1045
  const existingEntry = await this.fileSystem.readFile(existingEntryPath2);
884
1046
  if (existingEntry?.entry) {
@@ -903,6 +1065,43 @@ var CompositionConverterService = class {
903
1065
  "WRITE",
904
1066
  `${entriesDir}/${inst.determinisiticId}.json (${refType} from "${this.truncate(compositionName, 50)}")`
905
1067
  );
1068
+ this.logger.debug(`Writing reference entry "${inst.determinisiticId}" (${refType}) with fields: ${Object.keys(flatEntry.entry.fields).join(", ") || "(none)"}`);
1069
+ if (!whatIf) {
1070
+ await this.fileSystem.writeFile(flatEntryPath, flatEntry);
1071
+ }
1072
+ entriesFromReferences++;
1073
+ }
1074
+ }
1075
+ for (const [, instances] of refsBySlot) {
1076
+ for (const inst of instances) {
1077
+ const existingId = this.findExistingEntryBySourceItem(inst, sourceItemMap);
1078
+ if (existingId) {
1079
+ const existingSlotEntryPath = this.fileSystem.joinPath(entriesDirFull, `${existingId}.json`);
1080
+ this.logger.action(
1081
+ whatIf,
1082
+ "UPDATE",
1083
+ `${entriesDir}/${existingId}.json (${inst.componentType}, merged fields from "${this.truncate(compositionName, 50)}")`
1084
+ );
1085
+ if (!whatIf) {
1086
+ const existingEntry = await this.fileSystem.readFile(existingSlotEntryPath);
1087
+ if (existingEntry?.entry) {
1088
+ existingEntry.entry.fields = {
1089
+ ...existingEntry.entry.fields,
1090
+ ...inst.instance.parameters ?? {}
1091
+ };
1092
+ await this.fileSystem.writeFile(existingSlotEntryPath, existingEntry);
1093
+ }
1094
+ }
1095
+ entriesReused++;
1096
+ continue;
1097
+ }
1098
+ const flatEntry = this.generateEntryFromFlattenedInstance(inst);
1099
+ const flatEntryPath = this.fileSystem.joinPath(entriesDirFull, `${inst.determinisiticId}.json`);
1100
+ this.logger.action(
1101
+ whatIf,
1102
+ "WRITE",
1103
+ `${entriesDir}/${inst.determinisiticId}.json (${inst.componentType} from "${this.truncate(compositionName, 50)}")`
1104
+ );
906
1105
  if (!whatIf) {
907
1106
  await this.fileSystem.writeFile(flatEntryPath, flatEntry);
908
1107
  }
@@ -929,6 +1128,7 @@ var CompositionConverterService = class {
929
1128
  },
930
1129
  localizable: false
931
1130
  });
1131
+ this.logger.debug(`Field "${refType}" (contentReference) added to content type "${contentType.id}"`);
932
1132
  }
933
1133
  }
934
1134
  }
@@ -951,6 +1151,43 @@ var CompositionConverterService = class {
951
1151
  },
952
1152
  localizable: false
953
1153
  });
1154
+ this.logger.debug(`Field "${resolvedBlockId}" ($block) added to content type "${contentType.id}"`);
1155
+ }
1156
+ }
1157
+ }
1158
+ if (slotsToReferences.length > 0) {
1159
+ for (const contentType of contentTypeMap.values()) {
1160
+ for (const slotName of slotsToReferences) {
1161
+ const typesInSlot = slotToRefTypes.get(slotName) ?? /* @__PURE__ */ new Set();
1162
+ const allowedTypes = [...typesInSlot].filter(
1163
+ (t) => !this.compareTypes(t, contentType.id, strict)
1164
+ );
1165
+ if (allowedTypes.length === 0) continue;
1166
+ contentType.fields.push({
1167
+ id: slotName,
1168
+ name: slotName,
1169
+ type: "contentReference",
1170
+ typeConfig: { isMulti: true, allowedTypes },
1171
+ localizable: false
1172
+ });
1173
+ this.logger.debug(`Field "${slotName}" (contentReference, allowedTypes: ${allowedTypes.join(", ")}) added to content type "${contentType.id}"`);
1174
+ }
1175
+ }
1176
+ }
1177
+ if (slotsToBlocks.length > 0) {
1178
+ for (const contentType of contentTypeMap.values()) {
1179
+ for (const slotName of slotsToBlocks) {
1180
+ const typesInSlot = slotToBlockTypes.get(slotName) ?? /* @__PURE__ */ new Set();
1181
+ const resolvedBlockIds = [...typesInSlot].filter((t) => !this.compareTypes(t, contentType.id, strict)).map((t) => blockTypeIdMap.get(t) ?? t);
1182
+ if (resolvedBlockIds.length === 0) continue;
1183
+ contentType.fields.push({
1184
+ id: slotName,
1185
+ name: slotName,
1186
+ type: "$block",
1187
+ typeConfig: { allowedTypes: resolvedBlockIds },
1188
+ localizable: false
1189
+ });
1190
+ this.logger.debug(`Field "${slotName}" ($block, allowedTypes: ${resolvedBlockIds.join(", ")}) added to content type "${contentType.id}"`);
954
1191
  }
955
1192
  }
956
1193
  }
@@ -975,6 +1212,7 @@ var CompositionConverterService = class {
975
1212
  "WRITE",
976
1213
  `${contentTypesDir}/${typeName}.json (${baseFieldCount} fields${extrasInfo})`
977
1214
  );
1215
+ this.logger.debug(`Content type "${typeName}" fields: ${contentType.fields.map((f) => `${f.id}:${f.type}`).join(", ")}`);
978
1216
  if (!whatIf) {
979
1217
  await this.fileSystem.writeFile(filePath, contentType);
980
1218
  }
@@ -987,6 +1225,7 @@ var CompositionConverterService = class {
987
1225
  "WRITE",
988
1226
  `${contentTypesDir}/${typeName}.json (${contentType.fields.length} fields)`
989
1227
  );
1228
+ this.logger.debug(`Content type "${typeName}" fields: ${contentType.fields.map((f) => `${f.id}:${f.type}`).join(", ")}`);
990
1229
  if (!whatIf) {
991
1230
  await this.fileSystem.writeFile(filePath, contentType);
992
1231
  }
@@ -1118,6 +1357,29 @@ var CompositionConverterService = class {
1118
1357
  }
1119
1358
  }
1120
1359
  }
1360
+ // --- Slot-Based Instance Finding ---
1361
+ findInstancesInSlot(slots, slotName, compositionId, compositionName, strict) {
1362
+ const results = [];
1363
+ for (const [name, instances] of Object.entries(slots)) {
1364
+ const matches = strict ? name === slotName : name.toLowerCase() === slotName.toLowerCase();
1365
+ if (!matches) continue;
1366
+ if (!Array.isArray(instances)) continue;
1367
+ for (let i = 0; i < instances.length; i++) {
1368
+ const instance = instances[i];
1369
+ if (instance._pattern) continue;
1370
+ const path2 = `${compositionId}-${name}-[${i}]-${instance.type}`;
1371
+ results.push({
1372
+ instance,
1373
+ path: path2,
1374
+ determinisiticId: computeGuidHash(path2),
1375
+ componentType: instance.type,
1376
+ compositionId,
1377
+ compositionName
1378
+ });
1379
+ }
1380
+ }
1381
+ return results;
1382
+ }
1121
1383
  // --- Content Reference Transformation ---
1122
1384
  transformContentReferences(entry) {
1123
1385
  const dataResources = {};
@@ -1220,6 +1482,34 @@ var CompositionConverterService = class {
1220
1482
  }
1221
1483
  return [...new Set(expanded)];
1222
1484
  }
1485
+ expandWildcardSlots(compositionResults, patterns, strict) {
1486
+ const expanded = [];
1487
+ for (const pattern of patterns) {
1488
+ if (!pattern.includes("*")) {
1489
+ expanded.push(pattern);
1490
+ continue;
1491
+ }
1492
+ const matched = /* @__PURE__ */ new Set();
1493
+ for (const { composition } of compositionResults) {
1494
+ if (composition.composition.slots) {
1495
+ for (const slotName of Object.keys(composition.composition.slots)) {
1496
+ if (this.matchesType(slotName, pattern, strict)) {
1497
+ matched.add(slotName);
1498
+ }
1499
+ }
1500
+ }
1501
+ }
1502
+ if (matched.size === 0) {
1503
+ this.logger.warn(`Wildcard pattern "${pattern}" did not match any slot names`);
1504
+ } else {
1505
+ this.logger.info(`Wildcard "${pattern}" expanded to: ${[...matched].join(", ")}`);
1506
+ }
1507
+ for (const name of matched) {
1508
+ expanded.push(name);
1509
+ }
1510
+ }
1511
+ return [...new Set(expanded)];
1512
+ }
1223
1513
  collectMatchingTypes(slots, pattern, strict, matched) {
1224
1514
  for (const instances of Object.values(slots)) {
1225
1515
  if (!Array.isArray(instances)) continue;
@@ -1352,6 +1642,7 @@ var PropertyPropagatorService = class {
1352
1642
  try {
1353
1643
  const { component: sourceComponent, filePath: sourceFilePath } = await this.componentService.loadComponent(fullComponentsDir, sourceType, findOptions);
1354
1644
  sourceComponents.push({ sourceType, sourceFilePath, sourceComponent });
1645
+ this.logger.debug(`Loaded source component "${sourceType}" from ${sourceFilePath}`);
1355
1646
  } catch (error) {
1356
1647
  if (error instanceof ComponentNotFoundError) {
1357
1648
  this.logger.warn(`Component not found: ${sourceType} (searched: ${fullComponentsDir})`);
@@ -1362,6 +1653,7 @@ var PropertyPropagatorService = class {
1362
1653
  }
1363
1654
  this.logger.info(`Loading component: ${targetComponentType}`);
1364
1655
  const { component: targetComponent, filePath: targetFilePath } = await this.componentService.loadComponent(fullComponentsDir, targetComponentType, findOptions);
1656
+ this.logger.debug(`Loaded target component "${targetComponentType}" from ${targetFilePath}`);
1365
1657
  const propertyNames = property.split("|").map((p) => p.trim()).filter((p) => p.length > 0);
1366
1658
  const resolvedParams = [];
1367
1659
  const resolvedNames = [];
@@ -1382,6 +1674,8 @@ var PropertyPropagatorService = class {
1382
1674
  if (!exists) {
1383
1675
  resolvedParams.push(param);
1384
1676
  resolvedNames.push(param.id);
1677
+ } else {
1678
+ this.logger.debug(`Parameter "${param.id}" already collected from another source \u2014 skipping duplicate`);
1385
1679
  }
1386
1680
  }
1387
1681
  }
@@ -1420,7 +1714,10 @@ var PropertyPropagatorService = class {
1420
1714
  targetGroup,
1421
1715
  findOptions
1422
1716
  );
1717
+ this.logger.debug(`Group "${targetGroup}" (id: ${groupId}) created on component ${targetComponentType}`);
1423
1718
  componentModified = true;
1719
+ } else {
1720
+ this.logger.debug(`Group "${targetGroup}" (id: ${groupId}) already exists on ${targetComponentType}`);
1424
1721
  }
1425
1722
  for (const param of resolvedParams) {
1426
1723
  const existingParam = this.componentService.findParameter(
@@ -1445,6 +1742,7 @@ var PropertyPropagatorService = class {
1445
1742
  param.id,
1446
1743
  findOptions
1447
1744
  );
1745
+ this.logger.debug(`Parameter "${param.id}" (type: ${param.type}) added to component ${targetComponentType} in group "${targetGroup}"`);
1448
1746
  componentModified = true;
1449
1747
  } else {
1450
1748
  this.logger.info(`Parameter "${param.id}" already exists on ${targetComponentType}`);
@@ -1464,7 +1762,10 @@ var PropertyPropagatorService = class {
1464
1762
  param.id,
1465
1763
  findOptions
1466
1764
  );
1765
+ this.logger.debug(`Parameter "${param.id}" added to group "${targetGroup}" on ${targetComponentType} (was missing from group)`);
1467
1766
  componentModified = true;
1767
+ } else {
1768
+ this.logger.debug(`Parameter "${param.id}" already in group "${targetGroup}" on ${targetComponentType} \u2014 no change`);
1468
1769
  }
1469
1770
  }
1470
1771
  }
@@ -1477,6 +1778,7 @@ var PropertyPropagatorService = class {
1477
1778
  compositionTypes,
1478
1779
  findOptions
1479
1780
  );
1781
+ this.logger.debug(`Found ${compositions.length} composition(s) matching types [${compositionTypes.join(", ")}]`);
1480
1782
  let modifiedCompositions = 0;
1481
1783
  let propagatedInstances = 0;
1482
1784
  for (const { composition, filePath } of compositions) {
@@ -1487,6 +1789,7 @@ var PropertyPropagatorService = class {
1487
1789
  findOptions
1488
1790
  );
1489
1791
  if (instances.length === 0) {
1792
+ this.logger.debug(`Skipping "${filePath}": no instances of ${targetComponentType} found`);
1490
1793
  continue;
1491
1794
  }
1492
1795
  const valuesToPropagate = {};
@@ -1496,6 +1799,7 @@ var PropertyPropagatorService = class {
1496
1799
  }
1497
1800
  }
1498
1801
  if (Object.keys(valuesToPropagate).length === 0) {
1802
+ this.logger.debug(`Skipping "${filePath}": ${instances.length} instance(s) of ${targetComponentType} found but none of [${resolvedNames.join(", ")}] present in root overrides`);
1499
1803
  continue;
1500
1804
  }
1501
1805
  let compositionModified = false;
@@ -1507,9 +1811,11 @@ var PropertyPropagatorService = class {
1507
1811
  this.compositionService.setInstanceParameters(instance, clonedValues);
1508
1812
  compositionModified = true;
1509
1813
  propagatedInstances++;
1814
+ const updatedParamNames = Object.keys(valuesToPropagate).join(", ");
1510
1815
  instanceUpdates.push(
1511
- `${targetComponentType} "${instanceName}": ${Object.keys(valuesToPropagate).join(", ")}`
1816
+ `${targetComponentType} "${instanceName}": ${updatedParamNames}`
1512
1817
  );
1818
+ this.logger.debug(`Component ${targetComponentType} "${instanceName}": parameters ${updatedParamNames} updated`);
1513
1819
  }
1514
1820
  if (compositionModified) {
1515
1821
  this.logger.action(whatIf, "UPDATE", `composition/${relativePath}`);
@@ -1532,7 +1838,10 @@ var PropertyPropagatorService = class {
1532
1838
  if (exists) {
1533
1839
  this.logger.action(whatIf, "DELETE", `Parameter "${param.id}" from ${sourceType}`);
1534
1840
  modifiedSource = this.componentService.removeParameter(modifiedSource, param.id, findOptions);
1841
+ this.logger.debug(`Parameter "${param.id}" removed from component ${sourceType}`);
1535
1842
  sourceComponentModified = true;
1843
+ } else {
1844
+ this.logger.debug(`Parameter "${param.id}" not found on source component "${sourceType}" \u2014 nothing to delete`);
1536
1845
  }
1537
1846
  }
1538
1847
  const beforeGroupCount = modifiedSource.parameters?.filter(
@@ -1571,6 +1880,8 @@ var PropertyPropagatorService = class {
1571
1880
  if (!whatIf) {
1572
1881
  await this.compositionService.saveComposition(filePath, composition);
1573
1882
  }
1883
+ } else {
1884
+ this.logger.debug(`No root overrides matching [${resolvedNames.join(", ")}] in composition/${relativePath}`);
1574
1885
  }
1575
1886
  }
1576
1887
  }
@@ -1598,9 +1909,16 @@ var PropertyPropagatorService = class {
1598
1909
  // src/cli/logger.ts
1599
1910
  import chalk from "chalk";
1600
1911
  var Logger = class {
1912
+ constructor(verbose = false) {
1913
+ this.verbose = verbose;
1914
+ }
1601
1915
  info(message) {
1602
1916
  console.log(`${chalk.blue("[INFO]")} ${message}`);
1603
1917
  }
1918
+ debug(message) {
1919
+ if (!this.verbose) return;
1920
+ console.log(`${chalk.magenta("[DEBUG]")} ${message}`);
1921
+ }
1604
1922
  success(message) {
1605
1923
  console.log(`${chalk.green("[DONE]")} ${message}`);
1606
1924
  }
@@ -1636,7 +1954,7 @@ function createPropagateRootComponentPropertyCommand() {
1636
1954
  ).option(
1637
1955
  "--deleteSourceParameter",
1638
1956
  "Delete the original parameters from the source component after propagation"
1639
- ).hook("preAction", (thisCommand) => {
1957
+ ).option("--verbose", "Enable verbose output with detailed progress information").hook("preAction", (thisCommand) => {
1640
1958
  const opts = thisCommand.opts();
1641
1959
  const requiredOptions = [
1642
1960
  { name: "compositionType", flag: "--compositionType" },
@@ -1659,7 +1977,7 @@ function createPropagateRootComponentPropertyCommand() {
1659
1977
  targetGroup: opts.targetGroup,
1660
1978
  deleteSourceParameter: opts.deleteSourceParameter
1661
1979
  };
1662
- const logger = new Logger();
1980
+ const logger = new Logger(opts.verbose ?? false);
1663
1981
  const fileSystem = new FileSystemService();
1664
1982
  const componentService = new ComponentService(fileSystem);
1665
1983
  const compositionService = new CompositionService(fileSystem);
@@ -4447,7 +4765,13 @@ function createConvertCompositionsToEntriesCommand() {
4447
4765
  ).option(
4448
4766
  "--componentsToBlocks <types>",
4449
4767
  "Pipe-separated list of component types to convert into inline blocks (e.g., DetailHero|ArticleDetail)"
4450
- ).hook("preAction", (thisCommand) => {
4768
+ ).option(
4769
+ "--slotsToReferences <slots>",
4770
+ "Pipe-separated list of slot names whose instances should be converted into separate referenced entries (e.g., main|sidebar)"
4771
+ ).option(
4772
+ "--slotsToBlocks <slots>",
4773
+ "Pipe-separated list of slot names whose instances should be converted into inline blocks (e.g., main|sidebar)"
4774
+ ).option("--verbose", "Enable verbose output with detailed progress information").hook("preAction", (thisCommand) => {
4451
4775
  const opts = thisCommand.opts();
4452
4776
  const requiredOptions = [
4453
4777
  { name: "compositionTypes", flag: "--compositionTypes" }
@@ -4463,9 +4787,11 @@ function createConvertCompositionsToEntriesCommand() {
4463
4787
  ...globalOpts,
4464
4788
  compositionTypes: opts.compositionTypes,
4465
4789
  componentsToReferences: opts.componentsToReferences,
4466
- componentsToBlocks: opts.componentsToBlocks
4790
+ componentsToBlocks: opts.componentsToBlocks,
4791
+ slotsToReferences: opts.slotsToReferences,
4792
+ slotsToBlocks: opts.slotsToBlocks
4467
4793
  };
4468
- const logger = new Logger();
4794
+ const logger = new Logger(opts.verbose ?? false);
4469
4795
  const fileSystem = new FileSystemService();
4470
4796
  const componentService = new ComponentService(fileSystem);
4471
4797
  const compositionService = new CompositionService(fileSystem);
@@ -4480,6 +4806,8 @@ function createConvertCompositionsToEntriesCommand() {
4480
4806
  const parsePipeSeparated = (value) => value ? [...new Set(value.split("|").map((t) => t.trim()).filter((t) => t.length > 0))] : [];
4481
4807
  const componentsToReferences = parsePipeSeparated(options.componentsToReferences);
4482
4808
  const componentsToBlocks = parsePipeSeparated(options.componentsToBlocks);
4809
+ const slotsToReferences = parsePipeSeparated(options.slotsToReferences);
4810
+ const slotsToBlocks = parsePipeSeparated(options.slotsToBlocks);
4483
4811
  const result = await converter.convert({
4484
4812
  rootDir: options.rootDir,
4485
4813
  compositionsDir: options.compositionsDir,
@@ -4489,6 +4817,8 @@ function createConvertCompositionsToEntriesCommand() {
4489
4817
  compositionTypes,
4490
4818
  componentsToReferences,
4491
4819
  componentsToBlocks,
4820
+ slotsToReferences,
4821
+ slotsToBlocks,
4492
4822
  whatIf: options.whatIf ?? false,
4493
4823
  strict: options.strict ?? false
4494
4824
  });
@@ -6033,7 +6363,7 @@ function createRemoveOrphanEntriesCommand() {
6033
6363
  // package.json
6034
6364
  var package_default = {
6035
6365
  name: "@uniformdev/transformer",
6036
- version: "1.1.35",
6366
+ version: "1.1.37",
6037
6367
  description: "CLI tool for transforming Uniform.dev serialization files offline",
6038
6368
  type: "module",
6039
6369
  bin: {