@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 +339 -9
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.js +321 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
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}": ${
|
|
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
|
-
).
|
|
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.
|
|
6366
|
+
version: "1.1.37",
|
|
6037
6367
|
description: "CLI tool for transforming Uniform.dev serialization files offline",
|
|
6038
6368
|
type: "module",
|
|
6039
6369
|
bin: {
|