@uniformdev/transformer 1.1.54 → 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;
@@ -2430,7 +2482,7 @@ var ComponentAdderService = class {
2430
2482
  const newInstance = this.createComponentInstance(newComponentType, parsedParams);
2431
2483
  const compositionsResult = await this.addComponentToDirectory(
2432
2484
  fullCompositionsDir,
2433
- parentTypes,
2485
+ resolvedParentTypes,
2434
2486
  slot,
2435
2487
  newInstance,
2436
2488
  whatIf,
@@ -2439,7 +2491,7 @@ var ComponentAdderService = class {
2439
2491
  );
2440
2492
  const compositionPatternsResult = await this.addComponentToDirectory(
2441
2493
  fullCompositionPatternsDir,
2442
- parentTypes,
2494
+ resolvedParentTypes,
2443
2495
  slot,
2444
2496
  newInstance,
2445
2497
  whatIf,
@@ -2448,7 +2500,7 @@ var ComponentAdderService = class {
2448
2500
  );
2449
2501
  const componentPatternsResult = await this.addComponentToDirectory(
2450
2502
  fullComponentPatternsDir,
2451
- parentTypes,
2503
+ resolvedParentTypes,
2452
2504
  slot,
2453
2505
  newInstance,
2454
2506
  whatIf,
@@ -2566,7 +2618,7 @@ var ComponentAdderService = class {
2566
2618
  };
2567
2619
  const compositionsResult = await this.addComponentToDirectory(
2568
2620
  fullCompositionsDir,
2569
- parentTypes,
2621
+ resolvedParentTypes,
2570
2622
  slot,
2571
2623
  newInstance,
2572
2624
  whatIf,
@@ -2576,7 +2628,7 @@ var ComponentAdderService = class {
2576
2628
  );
2577
2629
  const compositionPatternsResult = await this.addComponentToDirectory(
2578
2630
  fullCompositionPatternsDir,
2579
- parentTypes,
2631
+ resolvedParentTypes,
2580
2632
  slot,
2581
2633
  newInstance,
2582
2634
  whatIf,
@@ -2586,7 +2638,7 @@ var ComponentAdderService = class {
2586
2638
  );
2587
2639
  const componentPatternsResult = await this.addComponentToDirectory(
2588
2640
  fullComponentPatternsDir,
2589
- parentTypes,
2641
+ resolvedParentTypes,
2590
2642
  slot,
2591
2643
  newInstance,
2592
2644
  whatIf,
@@ -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,