@uniformdev/transformer 1.1.55 → 1.1.56

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/index.d.ts CHANGED
@@ -234,6 +234,9 @@ declare class SlotNotFoundError extends TransformError {
234
234
  declare class SlotAlreadyExistsError extends TransformError {
235
235
  constructor(slotId: string, componentType: string);
236
236
  }
237
+ declare class ContentTypeFieldConflictError extends TransformError {
238
+ constructor(contentTypeId: string, fieldId: string, existingType: string, newType: string);
239
+ }
237
240
 
238
241
  declare class FileSystemService {
239
242
  private isJsonFile;
@@ -534,6 +537,7 @@ interface FlattenedInstance {
534
537
  }
535
538
  interface ConvertResult {
536
539
  contentTypesWritten: number;
540
+ contentTypesMerged: number;
537
541
  entriesFromCompositions: number;
538
542
  entriesFromReferences: number;
539
543
  entriesReused: number;
@@ -548,6 +552,7 @@ declare class CompositionConverterService {
548
552
  convert(options: ConvertCompositionsToEntriesInternalOptions): Promise<ConvertResult>;
549
553
  generateContentType(component: ComponentDefinition): ContentTypeDefinition;
550
554
  private parameterToField;
555
+ private mergeWithExistingContentType;
551
556
  generateEntryFromComposition(composition: Composition): EntryDefinition;
552
557
  generateEntryFromFlattenedInstance(inst: FlattenedInstance): EntryDefinition;
553
558
  findFlattenTargets(slots: Record<string, ComponentInstance[]>, targetType: string, compositionId: string, compositionName: string, strict: boolean): FlattenedInstance[];
@@ -660,4 +665,4 @@ declare class FieldRemoverService {
660
665
  private removeKeysFromMap;
661
666
  }
662
667
 
663
- export { type AddComponentOptions, type AddComponentParameterOptions, type AddComponentPatternOptions, type AddContentTypeFieldOptions, type ClearSlotOptions, ComponentAdderService, ComponentAlreadyExistsError, type ComponentDefinition, type ComponentInstance, ComponentNotFoundError, ComponentRenamerService, ComponentService, type Composition, CompositionConverterService, type CompositionOverrides, type CompositionPatternCandidatesOptions, type CompositionRoot, CompositionService, type ContentTypeDefinition$1 as ContentTypeDefinition, type ContentTypeField$1 as ContentTypeField, type ConvertCompositionsToEntriesOptions, DuplicateIdError, FieldRemoverService, FileNotFoundError, FileSystemService, type FlattenBlockFieldOptions, type GenerateMissingProjectMapNodesOptions, type GlobalOptions, InvalidYamlError, Logger, type PackSerializationOptions, type Parameter, ParameterRemoverService, type ParameterValue, type PropagateRootComponentPropertyOptions, type PropagateRootComponentSlotOptions, type PropagateRootSlotOptions, PropertyNotFoundError, PropertyPropagatorService, type RemoveFieldOptions, type RemoveOrphanEntriesOptions, type RemoveParameterOptions, type RemoveUnusedComponentTypesOptions, type RemoveUnusedContentTypesOptions, type RenameComponentOptions, type RenameSlotOptions, SlotAlreadyExistsError, type SlotDefinition, SlotNotFoundError, SlotRenamerService, type SplitContentTypeOptions, TransformError, type UnpackSerializationOptions, computeGuidHash, regenerateIds };
668
+ export { type AddComponentOptions, type AddComponentParameterOptions, type AddComponentPatternOptions, type AddContentTypeFieldOptions, type ClearSlotOptions, ComponentAdderService, ComponentAlreadyExistsError, type ComponentDefinition, type ComponentInstance, ComponentNotFoundError, ComponentRenamerService, ComponentService, type Composition, CompositionConverterService, type CompositionOverrides, type CompositionPatternCandidatesOptions, type CompositionRoot, CompositionService, type ContentTypeDefinition$1 as ContentTypeDefinition, type ContentTypeField$1 as ContentTypeField, ContentTypeFieldConflictError, type ConvertCompositionsToEntriesOptions, DuplicateIdError, FieldRemoverService, FileNotFoundError, FileSystemService, type FlattenBlockFieldOptions, type GenerateMissingProjectMapNodesOptions, type GlobalOptions, InvalidYamlError, Logger, type PackSerializationOptions, type Parameter, ParameterRemoverService, type ParameterValue, type PropagateRootComponentPropertyOptions, type PropagateRootComponentSlotOptions, type PropagateRootSlotOptions, PropertyNotFoundError, PropertyPropagatorService, type RemoveFieldOptions, type RemoveOrphanEntriesOptions, type RemoveParameterOptions, type RemoveUnusedComponentTypesOptions, type RemoveUnusedContentTypesOptions, type RenameComponentOptions, type RenameSlotOptions, SlotAlreadyExistsError, type SlotDefinition, SlotNotFoundError, SlotRenamerService, type SplitContentTypeOptions, TransformError, type UnpackSerializationOptions, computeGuidHash, regenerateIds };
package/dist/index.js CHANGED
@@ -56,6 +56,14 @@ var SlotAlreadyExistsError = class extends TransformError {
56
56
  this.name = "SlotAlreadyExistsError";
57
57
  }
58
58
  };
59
+ var ContentTypeFieldConflictError = class extends TransformError {
60
+ constructor(contentTypeId, fieldId, existingType, newType) {
61
+ super(
62
+ `Content type "${contentTypeId}" field "${fieldId}" type conflict: existing type "${existingType}" differs from generated type "${newType}"`
63
+ );
64
+ this.name = "ContentTypeFieldConflictError";
65
+ }
66
+ };
59
67
 
60
68
  // src/core/services/file-system.service.ts
61
69
  import * as fs from "fs";
@@ -611,6 +619,7 @@ var CompositionConverterService = class {
611
619
  const contentTypesDirFull = this.fileSystem.resolvePath(rootDir, contentTypesDir);
612
620
  const entriesDirFull = this.fileSystem.resolvePath(rootDir, entriesDir);
613
621
  let contentTypesWritten = 0;
622
+ let contentTypesMerged = 0;
614
623
  let entriesFromCompositions = 0;
615
624
  let entriesFromReferences = 0;
616
625
  let entriesReused = 0;
@@ -640,7 +649,7 @@ var CompositionConverterService = class {
640
649
  );
641
650
  if (compositionResults.length === 0) {
642
651
  this.logger.warn("No compositions found matching the specified types");
643
- return { contentTypesWritten: 0, entriesFromCompositions: 0, entriesFromReferences: 0, entriesReused: 0, blocksEmbedded: 0 };
652
+ return { contentTypesWritten: 0, contentTypesMerged: 0, entriesFromCompositions: 0, entriesFromReferences: 0, entriesReused: 0, blocksEmbedded: 0 };
644
653
  }
645
654
  this.logger.info(`Found ${compositionResults.length} composition(s)`);
646
655
  const componentsToReferences = this.expandWildcardTypes(compositionResults, initialComponentsToReferences, strict);
@@ -1154,37 +1163,49 @@ var CompositionConverterService = class {
1154
1163
  }
1155
1164
  for (const [typeName, contentType] of contentTypeMap) {
1156
1165
  const filePath = this.fileSystem.joinPath(contentTypesDirFull, `${typeName}.json`);
1157
- const baseFieldCount = contentType.fields.filter((f) => f.type !== "contentReference" && f.type !== "$block").length;
1158
- const refCount = contentType.fields.filter((f) => f.type === "contentReference").length;
1159
- const blockCount = contentType.fields.filter((f) => f.type === "$block").length;
1166
+ const merged = await this.mergeWithExistingContentType(filePath, contentType);
1167
+ const baseFieldCount = merged.fields.filter((f) => f.type !== "contentReference" && f.type !== "$block").length;
1168
+ const refCount = merged.fields.filter((f) => f.type === "contentReference").length;
1169
+ const blockCount = merged.fields.filter((f) => f.type === "$block").length;
1160
1170
  const extras = [
1161
1171
  refCount > 0 ? `${refCount} reference(s)` : "",
1162
1172
  blockCount > 0 ? `${blockCount} block(s)` : ""
1163
1173
  ].filter(Boolean).join(", ");
1164
1174
  const extrasInfo = extras ? ` + ${extras}` : "";
1175
+ const isMerged = merged !== contentType;
1165
1176
  this.logger.action(
1166
1177
  whatIf,
1167
- "WRITE",
1178
+ isMerged ? "MERGE" : "WRITE",
1168
1179
  `${contentTypesDir}/${typeName}.json (${baseFieldCount} fields${extrasInfo})`
1169
1180
  );
1170
- this.logger.debug(`Content type "${typeName}" fields: ${contentType.fields.map((f) => `${f.id}:${f.type}`).join(", ")}`);
1181
+ this.logger.debug(`Content type "${typeName}" fields: ${merged.fields.map((f) => `${f.id}:${f.type}`).join(", ")}`);
1171
1182
  if (!whatIf) {
1172
- await this.fileSystem.writeFile(filePath, contentType);
1183
+ await this.fileSystem.writeFile(filePath, merged);
1184
+ }
1185
+ if (isMerged) {
1186
+ contentTypesMerged++;
1187
+ } else {
1188
+ contentTypesWritten++;
1173
1189
  }
1174
- contentTypesWritten++;
1175
1190
  }
1176
1191
  for (const [typeName, contentType] of targetContentTypeMap) {
1177
1192
  const filePath = this.fileSystem.joinPath(contentTypesDirFull, `${typeName}.json`);
1193
+ const merged = await this.mergeWithExistingContentType(filePath, contentType);
1194
+ const isMerged = merged !== contentType;
1178
1195
  this.logger.action(
1179
1196
  whatIf,
1180
- "WRITE",
1181
- `${contentTypesDir}/${typeName}.json (${contentType.fields.length} fields)`
1197
+ isMerged ? "MERGE" : "WRITE",
1198
+ `${contentTypesDir}/${typeName}.json (${merged.fields.length} fields)`
1182
1199
  );
1183
- this.logger.debug(`Content type "${typeName}" fields: ${contentType.fields.map((f) => `${f.id}:${f.type}`).join(", ")}`);
1200
+ this.logger.debug(`Content type "${typeName}" fields: ${merged.fields.map((f) => `${f.id}:${f.type}`).join(", ")}`);
1184
1201
  if (!whatIf) {
1185
- await this.fileSystem.writeFile(filePath, contentType);
1202
+ await this.fileSystem.writeFile(filePath, merged);
1203
+ }
1204
+ if (isMerged) {
1205
+ contentTypesMerged++;
1206
+ } else {
1207
+ contentTypesWritten++;
1186
1208
  }
1187
- contentTypesWritten++;
1188
1209
  }
1189
1210
  const neverFoundMissingTypes = missingTargetTypes.filter(
1190
1211
  (type) => !foundMissingTargetTypes.has(type)
@@ -1194,7 +1215,7 @@ var CompositionConverterService = class {
1194
1215
  `Component type(s) not found in any composition: ${neverFoundMissingTypes.join(", ")}`
1195
1216
  );
1196
1217
  }
1197
- return { contentTypesWritten, entriesFromCompositions, entriesFromReferences, entriesReused, blocksEmbedded };
1218
+ return { contentTypesWritten, contentTypesMerged, entriesFromCompositions, entriesFromReferences, entriesReused, blocksEmbedded };
1198
1219
  }
1199
1220
  // --- Content Type Generation ---
1200
1221
  generateContentType(component) {
@@ -1227,6 +1248,37 @@ var CompositionConverterService = class {
1227
1248
  }
1228
1249
  return field;
1229
1250
  }
1251
+ async mergeWithExistingContentType(filePath, generated) {
1252
+ const exists = await this.fileSystem.fileExists(filePath);
1253
+ if (!exists) {
1254
+ return generated;
1255
+ }
1256
+ const existing = await this.fileSystem.readFile(filePath);
1257
+ const existingFieldMap = /* @__PURE__ */ new Map();
1258
+ for (const field of existing.fields) {
1259
+ existingFieldMap.set(field.id, field);
1260
+ }
1261
+ for (const newField of generated.fields) {
1262
+ const existingField = existingFieldMap.get(newField.id);
1263
+ if (existingField && existingField.type !== newField.type) {
1264
+ throw new ContentTypeFieldConflictError(
1265
+ generated.id,
1266
+ newField.id,
1267
+ existingField.type,
1268
+ newField.type
1269
+ );
1270
+ }
1271
+ }
1272
+ const generatedFieldIds = new Set(generated.fields.map((f) => f.id));
1273
+ const extraFields = existing.fields.filter((f) => !generatedFieldIds.has(f.id));
1274
+ if (extraFields.length === 0) {
1275
+ return generated;
1276
+ }
1277
+ return {
1278
+ ...generated,
1279
+ fields: [...generated.fields, ...extraFields]
1280
+ };
1281
+ }
1230
1282
  // --- Entry Generation ---
1231
1283
  generateEntryFromComposition(composition) {
1232
1284
  const comp = composition.composition;
@@ -3451,6 +3503,7 @@ export {
3451
3503
  ComponentService,
3452
3504
  CompositionConverterService,
3453
3505
  CompositionService,
3506
+ ContentTypeFieldConflictError,
3454
3507
  DuplicateIdError,
3455
3508
  FieldRemoverService,
3456
3509
  FileNotFoundError,