@uniformdev/transformer 1.1.21 → 1.1.23

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/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Transformer
2
+
3
+ It's a nodejs rewritten version of decomissioned Siphon.Transform.exe that takes in Uniform serialization and changes. See [001-basics.md](001-basics.md).
package/dist/cli/index.js CHANGED
@@ -592,7 +592,8 @@ var CompositionConverterService = class {
592
592
  contentTypesDir,
593
593
  entriesDir,
594
594
  compositionTypes,
595
- flattenComponentIds,
595
+ componentsToReferences,
596
+ componentsToBlocks,
596
597
  whatIf,
597
598
  strict
598
599
  } = options;
@@ -602,13 +603,17 @@ var CompositionConverterService = class {
602
603
  const entriesDirFull = this.fileSystem.resolvePath(rootDir, entriesDir);
603
604
  let contentTypesWritten = 0;
604
605
  let entriesFromCompositions = 0;
605
- let entriesFromFlattened = 0;
606
+ let entriesFromReferences = 0;
606
607
  let entriesReused = 0;
608
+ let blocksEmbedded = 0;
607
609
  this.logger.info(`Composition types: ${compositionTypes.join(", ")}`);
608
- if (flattenComponentIds.length > 0) {
609
- this.logger.info(`Flatten component types: ${flattenComponentIds.join(", ")}`);
610
+ if (componentsToReferences.length > 0) {
611
+ this.logger.info(`Components to references: ${componentsToReferences.join(", ")}`);
610
612
  }
611
- const sourceItemMap = flattenComponentIds.length > 0 ? await this.buildSourceItemMap(entriesDirFull) : /* @__PURE__ */ new Map();
613
+ if (componentsToBlocks.length > 0) {
614
+ this.logger.info(`Components to blocks: ${componentsToBlocks.join(", ")}`);
615
+ }
616
+ const sourceItemMap = componentsToReferences.length > 0 ? await this.buildSourceItemMap(entriesDirFull) : /* @__PURE__ */ new Map();
612
617
  if (sourceItemMap.size > 0) {
613
618
  this.logger.info(`Found ${sourceItemMap.size} existing entry(ies) with sourceItem values`);
614
619
  }
@@ -619,7 +624,7 @@ var CompositionConverterService = class {
619
624
  );
620
625
  if (compositionResults.length === 0) {
621
626
  this.logger.warn("No compositions found matching the specified types");
622
- return { contentTypesWritten: 0, entriesFromCompositions: 0, entriesFromFlattened: 0, entriesReused: 0 };
627
+ return { contentTypesWritten: 0, entriesFromCompositions: 0, entriesFromReferences: 0, entriesReused: 0, blocksEmbedded: 0 };
623
628
  }
624
629
  this.logger.info(`Found ${compositionResults.length} composition(s)`);
625
630
  const rootComponentTypes = /* @__PURE__ */ new Set();
@@ -636,28 +641,76 @@ var CompositionConverterService = class {
636
641
  const contentType = this.generateContentType(component);
637
642
  contentTypeMap.set(rootType, contentType);
638
643
  }
639
- const flattenContentTypeMap = /* @__PURE__ */ new Map();
640
- const missingFlattenTypes = [];
641
- const foundMissingFlattenTypes = /* @__PURE__ */ new Set();
642
- for (const flattenType of flattenComponentIds) {
644
+ const allTargetTypes = [.../* @__PURE__ */ new Set([...componentsToReferences, ...componentsToBlocks])];
645
+ const targetContentTypeMap = /* @__PURE__ */ new Map();
646
+ const missingTargetTypes = [];
647
+ const foundMissingTargetTypes = /* @__PURE__ */ new Set();
648
+ const blockTypeIdMap = /* @__PURE__ */ new Map();
649
+ for (const targetType of allTargetTypes) {
643
650
  const isRootType = [...rootComponentTypes].some(
644
- (rt) => this.compareTypes(rt, flattenType, strict)
651
+ (rt) => this.compareTypes(rt, targetType, strict)
645
652
  );
646
653
  if (isRootType) {
647
654
  continue;
648
655
  }
656
+ const isBlockType = componentsToBlocks.some(
657
+ (bt) => this.compareTypes(bt, targetType, strict)
658
+ );
659
+ const isRefType = componentsToReferences.some(
660
+ (rt) => this.compareTypes(rt, targetType, strict)
661
+ );
649
662
  try {
650
663
  const { component } = await this.componentService.loadComponent(
651
664
  componentsDirFull,
652
- flattenType,
665
+ targetType,
653
666
  { strict }
654
667
  );
655
- const contentType = this.generateContentType(component);
656
- flattenContentTypeMap.set(flattenType, contentType);
668
+ if (isRefType) {
669
+ const contentType = this.generateContentType(component);
670
+ targetContentTypeMap.set(targetType, contentType);
671
+ }
672
+ if (isBlockType) {
673
+ let blockId = targetType;
674
+ let needsRename = false;
675
+ if (isRefType) {
676
+ needsRename = true;
677
+ }
678
+ if (!needsRename) {
679
+ const existingPath = this.fileSystem.joinPath(contentTypesDirFull, `${targetType}.json`);
680
+ if (await this.fileSystem.fileExists(existingPath)) {
681
+ try {
682
+ const existing = await this.fileSystem.readFile(existingPath);
683
+ if (existing?.type !== "block") {
684
+ needsRename = true;
685
+ }
686
+ } catch {
687
+ }
688
+ }
689
+ }
690
+ if (needsRename) {
691
+ blockId = `${targetType}Block`;
692
+ this.logger.info(`Content type "${targetType}" already exists as non-block, using "${blockId}" for block`);
693
+ }
694
+ blockTypeIdMap.set(targetType, blockId);
695
+ const blockContentType = this.generateContentType(component);
696
+ blockContentType.type = "block";
697
+ blockContentType.id = blockId;
698
+ blockContentType.name = needsRename ? `${blockContentType.name} Block` : blockContentType.name;
699
+ targetContentTypeMap.set(blockId, blockContentType);
700
+ }
701
+ if (!isBlockType) {
702
+ if (!isRefType) {
703
+ const contentType = this.generateContentType(component);
704
+ targetContentTypeMap.set(targetType, contentType);
705
+ }
706
+ }
657
707
  } catch (error) {
658
708
  if (error instanceof ComponentNotFoundError) {
659
- this.logger.info(`Flatten component type not found: ${flattenType}`);
660
- missingFlattenTypes.push(flattenType);
709
+ this.logger.info(`Component type not found: ${targetType}`);
710
+ missingTargetTypes.push(targetType);
711
+ if (isBlockType) {
712
+ blockTypeIdMap.set(targetType, targetType);
713
+ }
661
714
  continue;
662
715
  }
663
716
  throw error;
@@ -669,48 +722,84 @@ var CompositionConverterService = class {
669
722
  const compositionName = comp._name ?? compositionId;
670
723
  const compositionType = comp.type;
671
724
  const entry = this.generateEntryFromComposition(composition);
672
- const flattenedByType = /* @__PURE__ */ new Map();
673
- if (flattenComponentIds.length > 0 && comp.slots) {
674
- for (const flattenType of flattenComponentIds) {
675
- if (this.compareTypes(flattenType, compositionType, strict)) {
725
+ const refsByType = /* @__PURE__ */ new Map();
726
+ if (componentsToReferences.length > 0 && comp.slots) {
727
+ for (const refType of componentsToReferences) {
728
+ if (this.compareTypes(refType, compositionType, strict)) {
676
729
  this.logger.warn(
677
- `Skipping flatten of "${flattenType}" \u2014 same as root component type`
730
+ `Skipping reference of "${refType}" \u2014 same as root component type`
678
731
  );
679
732
  continue;
680
733
  }
681
734
  const instances = this.findFlattenTargets(
682
735
  comp.slots,
683
- flattenType,
736
+ refType,
684
737
  compositionId,
685
738
  compositionName,
686
739
  strict
687
740
  );
688
741
  if (instances.length > 0) {
689
- flattenedByType.set(flattenType, instances);
690
- if (missingFlattenTypes.includes(flattenType)) {
691
- foundMissingFlattenTypes.add(flattenType);
742
+ refsByType.set(refType, instances);
743
+ if (missingTargetTypes.includes(refType)) {
744
+ foundMissingTargetTypes.add(refType);
692
745
  }
693
746
  }
694
747
  }
695
748
  }
696
749
  const resolvedRefIds = /* @__PURE__ */ new Map();
697
- for (const [flattenType, instances] of flattenedByType) {
750
+ for (const [refType, instances] of refsByType) {
698
751
  const refIds = [];
699
752
  for (const inst of instances) {
700
753
  const existingId = this.findExistingEntryBySourceItem(inst, sourceItemMap);
701
754
  refIds.push(existingId ?? inst.determinisiticId);
702
755
  }
703
- resolvedRefIds.set(flattenType, refIds);
756
+ resolvedRefIds.set(refType, refIds);
704
757
  }
705
- for (const [flattenType] of flattenedByType) {
706
- entry.entry.fields[flattenType] = {
758
+ for (const [refType] of refsByType) {
759
+ entry.entry.fields[refType] = {
707
760
  type: "contentReference",
708
- value: resolvedRefIds.get(flattenType)
761
+ value: resolvedRefIds.get(refType)
709
762
  };
710
763
  }
711
- if (flattenComponentIds.length > 0) {
764
+ if (componentsToReferences.length > 0) {
712
765
  this.transformContentReferences(entry);
713
766
  }
767
+ const blocksByType = /* @__PURE__ */ new Map();
768
+ if (componentsToBlocks.length > 0 && comp.slots) {
769
+ for (const blockType of componentsToBlocks) {
770
+ if (this.compareTypes(blockType, compositionType, strict)) {
771
+ this.logger.warn(
772
+ `Skipping block of "${blockType}" \u2014 same as root component type`
773
+ );
774
+ continue;
775
+ }
776
+ const instances = this.findFlattenTargets(
777
+ comp.slots,
778
+ blockType,
779
+ compositionId,
780
+ compositionName,
781
+ strict
782
+ );
783
+ if (instances.length > 0) {
784
+ blocksByType.set(blockType, instances);
785
+ if (missingTargetTypes.includes(blockType)) {
786
+ foundMissingTargetTypes.add(blockType);
787
+ }
788
+ }
789
+ }
790
+ }
791
+ for (const [blockType, instances] of blocksByType) {
792
+ const resolvedBlockId = blockTypeIdMap.get(blockType) ?? blockType;
793
+ const blockValues = instances.map((inst) => ({
794
+ type: resolvedBlockId,
795
+ fields: { ...inst.instance.parameters ?? {} }
796
+ }));
797
+ entry.entry.fields[resolvedBlockId] = {
798
+ type: "$block",
799
+ value: blockValues
800
+ };
801
+ blocksEmbedded += instances.length;
802
+ }
714
803
  const entryId = entry.entry._id;
715
804
  const entryFilePath = this.fileSystem.joinPath(entriesDirFull, `${entryId}.json`);
716
805
  this.logger.action(
@@ -722,7 +811,7 @@ var CompositionConverterService = class {
722
811
  await this.fileSystem.writeFile(entryFilePath, entry);
723
812
  }
724
813
  entriesFromCompositions++;
725
- for (const [flattenType, instances] of flattenedByType) {
814
+ for (const [refType, instances] of refsByType) {
726
815
  for (const inst of instances) {
727
816
  const existingId = this.findExistingEntryBySourceItem(inst, sourceItemMap);
728
817
  if (existingId) {
@@ -733,7 +822,7 @@ var CompositionConverterService = class {
733
822
  this.logger.action(
734
823
  whatIf,
735
824
  "UPDATE",
736
- `${entriesDir}/${existingId}.json (${flattenType}, merged fields from "${this.truncate(compositionName, 50)}")`
825
+ `${entriesDir}/${existingId}.json (${refType}, merged fields from "${this.truncate(compositionName, 50)}")`
737
826
  );
738
827
  if (!whatIf) {
739
828
  const existingEntry = await this.fileSystem.readFile(existingEntryPath);
@@ -757,31 +846,53 @@ var CompositionConverterService = class {
757
846
  this.logger.action(
758
847
  whatIf,
759
848
  "WRITE",
760
- `${entriesDir}/${inst.determinisiticId}.json (${flattenType} from "${this.truncate(compositionName, 50)}")`
849
+ `${entriesDir}/${inst.determinisiticId}.json (${refType} from "${this.truncate(compositionName, 50)}")`
761
850
  );
762
851
  if (!whatIf) {
763
852
  await this.fileSystem.writeFile(flatEntryPath, flatEntry);
764
853
  }
765
- entriesFromFlattened++;
854
+ entriesFromReferences++;
766
855
  }
767
856
  }
768
857
  }
769
- if (flattenComponentIds.length > 0) {
858
+ if (componentsToReferences.length > 0) {
770
859
  for (const contentType of contentTypeMap.values()) {
771
- for (const flattenType of flattenComponentIds) {
772
- if (this.compareTypes(flattenType, contentType.id, strict)) {
860
+ for (const refType of componentsToReferences) {
861
+ if (this.compareTypes(refType, contentType.id, strict)) {
773
862
  continue;
774
863
  }
775
- if (missingFlattenTypes.includes(flattenType) && !foundMissingFlattenTypes.has(flattenType)) {
864
+ if (missingTargetTypes.includes(refType) && !foundMissingTargetTypes.has(refType)) {
776
865
  continue;
777
866
  }
778
867
  contentType.fields.push({
779
- id: flattenType,
780
- name: flattenType,
868
+ id: refType,
869
+ name: refType,
781
870
  type: "contentReference",
782
871
  typeConfig: {
783
872
  isMulti: true,
784
- allowedContentTypes: [flattenType]
873
+ allowedContentTypes: [refType]
874
+ },
875
+ localizable: false
876
+ });
877
+ }
878
+ }
879
+ }
880
+ if (componentsToBlocks.length > 0) {
881
+ for (const contentType of contentTypeMap.values()) {
882
+ for (const blockType of componentsToBlocks) {
883
+ if (this.compareTypes(blockType, contentType.id, strict)) {
884
+ continue;
885
+ }
886
+ if (missingTargetTypes.includes(blockType) && !foundMissingTargetTypes.has(blockType)) {
887
+ continue;
888
+ }
889
+ const resolvedBlockId = blockTypeIdMap.get(blockType) ?? blockType;
890
+ contentType.fields.push({
891
+ id: resolvedBlockId,
892
+ name: resolvedBlockId,
893
+ type: "$block",
894
+ typeConfig: {
895
+ allowedContentTypes: [resolvedBlockId]
785
896
  },
786
897
  localizable: false
787
898
  });
@@ -791,25 +902,30 @@ var CompositionConverterService = class {
791
902
  for (const contentType of contentTypeMap.values()) {
792
903
  contentType.fields = this.componentService.sortParametersByGroup(contentType.fields);
793
904
  }
794
- for (const contentType of flattenContentTypeMap.values()) {
905
+ for (const contentType of targetContentTypeMap.values()) {
795
906
  contentType.fields = this.componentService.sortParametersByGroup(contentType.fields);
796
907
  }
797
908
  for (const [typeName, contentType] of contentTypeMap) {
798
909
  const filePath = this.fileSystem.joinPath(contentTypesDirFull, `${typeName}.json`);
799
- const fieldCount = contentType.fields.filter((f) => f.type !== "contentReference").length;
910
+ const baseFieldCount = contentType.fields.filter((f) => f.type !== "contentReference" && f.type !== "$block").length;
800
911
  const refCount = contentType.fields.filter((f) => f.type === "contentReference").length;
801
- const refInfo = refCount > 0 ? ` + ${refCount} reference(s)` : "";
912
+ const blockCount = contentType.fields.filter((f) => f.type === "$block").length;
913
+ const extras = [
914
+ refCount > 0 ? `${refCount} reference(s)` : "",
915
+ blockCount > 0 ? `${blockCount} block(s)` : ""
916
+ ].filter(Boolean).join(", ");
917
+ const extrasInfo = extras ? ` + ${extras}` : "";
802
918
  this.logger.action(
803
919
  whatIf,
804
920
  "WRITE",
805
- `${contentTypesDir}/${typeName}.json (${fieldCount} fields${refInfo})`
921
+ `${contentTypesDir}/${typeName}.json (${baseFieldCount} fields${extrasInfo})`
806
922
  );
807
923
  if (!whatIf) {
808
924
  await this.fileSystem.writeFile(filePath, contentType);
809
925
  }
810
926
  contentTypesWritten++;
811
927
  }
812
- for (const [typeName, contentType] of flattenContentTypeMap) {
928
+ for (const [typeName, contentType] of targetContentTypeMap) {
813
929
  const filePath = this.fileSystem.joinPath(contentTypesDirFull, `${typeName}.json`);
814
930
  this.logger.action(
815
931
  whatIf,
@@ -821,15 +937,15 @@ var CompositionConverterService = class {
821
937
  }
822
938
  contentTypesWritten++;
823
939
  }
824
- const neverFoundMissingTypes = missingFlattenTypes.filter(
825
- (type) => !foundMissingFlattenTypes.has(type)
940
+ const neverFoundMissingTypes = missingTargetTypes.filter(
941
+ (type) => !foundMissingTargetTypes.has(type)
826
942
  );
827
943
  if (neverFoundMissingTypes.length > 0) {
828
944
  this.logger.warn(
829
- `Flatten component type(s) not found in any composition: ${neverFoundMissingTypes.join(", ")}`
945
+ `Component type(s) not found in any composition: ${neverFoundMissingTypes.join(", ")}`
830
946
  );
831
947
  }
832
- return { contentTypesWritten, entriesFromCompositions, entriesFromFlattened, entriesReused };
948
+ return { contentTypesWritten, entriesFromCompositions, entriesFromReferences, entriesReused, blocksEmbedded };
833
949
  }
834
950
  // --- Content Type Generation ---
835
951
  generateContentType(component) {
@@ -4174,13 +4290,16 @@ import { Command as Command10 } from "commander";
4174
4290
  function createConvertCompositionsToEntriesCommand() {
4175
4291
  const command = new Command10("convert-compositions-to-entries");
4176
4292
  command.description(
4177
- "Converts compositions into content entries, optionally flattening nested components into separate referenced entries."
4293
+ "Converts compositions into content entries, optionally converting nested components into references or blocks."
4178
4294
  ).option(
4179
4295
  "--compositionTypes <types>",
4180
4296
  "Pipe-separated list of composition types to convert (e.g., ProductDetailPage|ArticlePage)"
4181
4297
  ).option(
4182
- "--flattenComponentIds <types>",
4183
- "Pipe-separated list of component types to flatten into separate entries (e.g., DetailHero|ArticleDetail)"
4298
+ "--componentsToReferences <types>",
4299
+ "Pipe-separated list of component types to convert into separate referenced entries (e.g., DetailHero|ArticleDetail)"
4300
+ ).option(
4301
+ "--componentsToBlocks <types>",
4302
+ "Pipe-separated list of component types to convert into inline blocks (e.g., DetailHero|ArticleDetail)"
4184
4303
  ).hook("preAction", (thisCommand) => {
4185
4304
  const opts = thisCommand.opts();
4186
4305
  const requiredOptions = [
@@ -4196,7 +4315,8 @@ function createConvertCompositionsToEntriesCommand() {
4196
4315
  const options = {
4197
4316
  ...globalOpts,
4198
4317
  compositionTypes: opts.compositionTypes,
4199
- flattenComponentIds: opts.flattenComponentIds
4318
+ componentsToReferences: opts.componentsToReferences,
4319
+ componentsToBlocks: opts.componentsToBlocks
4200
4320
  };
4201
4321
  const logger = new Logger();
4202
4322
  const fileSystem = new FileSystemService();
@@ -4210,7 +4330,9 @@ function createConvertCompositionsToEntriesCommand() {
4210
4330
  );
4211
4331
  try {
4212
4332
  const compositionTypes = options.compositionTypes.split("|").map((t) => t.trim()).filter((t) => t.length > 0);
4213
- const flattenComponentIds = options.flattenComponentIds ? options.flattenComponentIds.split("|").map((t) => t.trim()).filter((t) => t.length > 0) : [];
4333
+ const parsePipeSeparated = (value) => value ? value.split("|").map((t) => t.trim()).filter((t) => t.length > 0) : [];
4334
+ const componentsToReferences = parsePipeSeparated(options.componentsToReferences);
4335
+ const componentsToBlocks = parsePipeSeparated(options.componentsToBlocks);
4214
4336
  const result = await converter.convert({
4215
4337
  rootDir: options.rootDir,
4216
4338
  compositionsDir: options.compositionsDir,
@@ -4218,14 +4340,16 @@ function createConvertCompositionsToEntriesCommand() {
4218
4340
  contentTypesDir: options.contentTypesDir,
4219
4341
  entriesDir: options.entriesDir,
4220
4342
  compositionTypes,
4221
- flattenComponentIds,
4343
+ componentsToReferences,
4344
+ componentsToBlocks,
4222
4345
  whatIf: options.whatIf ?? false,
4223
4346
  strict: options.strict ?? false
4224
4347
  });
4225
- const flatInfo = result.entriesFromFlattened > 0 ? `, ${result.entriesFromFlattened} from flattened components` : "";
4348
+ const refInfo = result.entriesFromReferences > 0 ? `, ${result.entriesFromReferences} from references` : "";
4226
4349
  const reusedInfo = result.entriesReused > 0 ? `, ${result.entriesReused} reused existing` : "";
4350
+ const blocksInfo = result.blocksEmbedded > 0 ? `, ${result.blocksEmbedded} block(s) embedded` : "";
4227
4351
  logger.success(
4228
- `${result.contentTypesWritten} content type(s), ${result.entriesFromCompositions} entry(ies) from compositions${flatInfo}${reusedInfo}`
4352
+ `${result.contentTypesWritten} content type(s), ${result.entriesFromCompositions} entry(ies) from compositions${refInfo}${reusedInfo}${blocksInfo}`
4229
4353
  );
4230
4354
  } catch (error) {
4231
4355
  if (error instanceof TransformError) {
@@ -4779,7 +4903,7 @@ function createRemoveFieldCommand() {
4779
4903
  // package.json
4780
4904
  var package_default = {
4781
4905
  name: "@uniformdev/transformer",
4782
- version: "1.1.21",
4906
+ version: "1.1.23",
4783
4907
  description: "CLI tool for transforming Uniform.dev serialization files offline",
4784
4908
  type: "module",
4785
4909
  bin: {