@uniformdev/transformer 1.1.34 → 1.1.36
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 +249 -19
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +43 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command17 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/cli/commands/propagate-root-component-property.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -659,6 +659,7 @@ var CompositionConverterService = class {
|
|
|
659
659
|
);
|
|
660
660
|
const contentType = this.generateContentType(component);
|
|
661
661
|
contentTypeMap.set(rootType, contentType);
|
|
662
|
+
this.logger.debug(`Generated content type "${rootType}" with ${contentType.fields.length} field(s): ${contentType.fields.map((f) => f.id).join(", ")}`);
|
|
662
663
|
} catch (error) {
|
|
663
664
|
if (error instanceof ComponentNotFoundError) {
|
|
664
665
|
this.logger.warn(`Component not found: ${rootType} \u2014 skipping content type generation`);
|
|
@@ -694,6 +695,7 @@ var CompositionConverterService = class {
|
|
|
694
695
|
if (isRefType) {
|
|
695
696
|
const contentType = this.generateContentType(component);
|
|
696
697
|
targetContentTypeMap.set(targetType, contentType);
|
|
698
|
+
this.logger.debug(`Generated reference content type "${targetType}" with ${contentType.fields.length} field(s): ${contentType.fields.map((f) => f.id).join(", ")}`);
|
|
697
699
|
}
|
|
698
700
|
if (isBlockType) {
|
|
699
701
|
let blockId = targetType;
|
|
@@ -723,6 +725,7 @@ var CompositionConverterService = class {
|
|
|
723
725
|
blockContentType.id = blockId;
|
|
724
726
|
blockContentType.name = needsRename ? `${blockContentType.name} Block` : blockContentType.name;
|
|
725
727
|
targetContentTypeMap.set(blockId, blockContentType);
|
|
728
|
+
this.logger.debug(`Generated block content type "${blockId}" with ${blockContentType.fields.length} field(s): ${blockContentType.fields.map((f) => f.id).join(", ")}`);
|
|
726
729
|
}
|
|
727
730
|
if (!isBlockType) {
|
|
728
731
|
if (!isRefType) {
|
|
@@ -764,6 +767,7 @@ var CompositionConverterService = class {
|
|
|
764
767
|
}
|
|
765
768
|
} else {
|
|
766
769
|
entry = this.generateEntryFromComposition(composition);
|
|
770
|
+
this.logger.debug(`Generated entry "${entry.entry._id}" from composition "${compositionName}" (${compositionType}) with fields: ${Object.keys(entry.entry.fields).join(", ") || "(none)"}`);
|
|
767
771
|
}
|
|
768
772
|
const refsByType = /* @__PURE__ */ new Map();
|
|
769
773
|
if (componentsToReferences.length > 0 && comp.slots) {
|
|
@@ -781,6 +785,7 @@ var CompositionConverterService = class {
|
|
|
781
785
|
compositionName,
|
|
782
786
|
strict
|
|
783
787
|
);
|
|
788
|
+
this.logger.debug(`Composition "${compositionName}": found ${instances.length} instance(s) of reference type "${refType}"`);
|
|
784
789
|
if (instances.length > 0) {
|
|
785
790
|
refsByType.set(refType, instances);
|
|
786
791
|
if (missingTargetTypes.includes(refType)) {
|
|
@@ -794,6 +799,7 @@ var CompositionConverterService = class {
|
|
|
794
799
|
const refIds = [];
|
|
795
800
|
for (const inst of instances) {
|
|
796
801
|
const existingId = this.findExistingEntryBySourceItem(inst, sourceItemMap);
|
|
802
|
+
this.logger.debug(`Reference instance "${inst.determinisiticId}" (${refType}): ${existingId ? `reusing existing entry "${existingId}"` : `assigned new ID "${inst.determinisiticId}"`}`);
|
|
797
803
|
refIds.push(existingId ?? inst.determinisiticId);
|
|
798
804
|
}
|
|
799
805
|
resolvedRefIds.set(refType, refIds);
|
|
@@ -823,6 +829,7 @@ var CompositionConverterService = class {
|
|
|
823
829
|
compositionName,
|
|
824
830
|
strict
|
|
825
831
|
);
|
|
832
|
+
this.logger.debug(`Composition "${compositionName}": found ${instances.length} instance(s) of block type "${blockType}"`);
|
|
826
833
|
if (instances.length > 0) {
|
|
827
834
|
blocksByType.set(blockType, instances);
|
|
828
835
|
if (missingTargetTypes.includes(blockType)) {
|
|
@@ -879,6 +886,7 @@ var CompositionConverterService = class {
|
|
|
879
886
|
"UPDATE",
|
|
880
887
|
`${entriesDir}/${existingId}.json (${refType}, merged fields from "${this.truncate(compositionName, 50)}")`
|
|
881
888
|
);
|
|
889
|
+
this.logger.debug(`Merging fields [${Object.keys(inst.instance.parameters ?? {}).join(", ") || "(none)"}] into existing reference entry "${existingId}"`);
|
|
882
890
|
if (!whatIf) {
|
|
883
891
|
const existingEntry = await this.fileSystem.readFile(existingEntryPath2);
|
|
884
892
|
if (existingEntry?.entry) {
|
|
@@ -903,6 +911,7 @@ var CompositionConverterService = class {
|
|
|
903
911
|
"WRITE",
|
|
904
912
|
`${entriesDir}/${inst.determinisiticId}.json (${refType} from "${this.truncate(compositionName, 50)}")`
|
|
905
913
|
);
|
|
914
|
+
this.logger.debug(`Writing reference entry "${inst.determinisiticId}" (${refType}) with fields: ${Object.keys(flatEntry.entry.fields).join(", ") || "(none)"}`);
|
|
906
915
|
if (!whatIf) {
|
|
907
916
|
await this.fileSystem.writeFile(flatEntryPath, flatEntry);
|
|
908
917
|
}
|
|
@@ -929,6 +938,7 @@ var CompositionConverterService = class {
|
|
|
929
938
|
},
|
|
930
939
|
localizable: false
|
|
931
940
|
});
|
|
941
|
+
this.logger.debug(`Field "${refType}" (contentReference) added to content type "${contentType.id}"`);
|
|
932
942
|
}
|
|
933
943
|
}
|
|
934
944
|
}
|
|
@@ -951,6 +961,7 @@ var CompositionConverterService = class {
|
|
|
951
961
|
},
|
|
952
962
|
localizable: false
|
|
953
963
|
});
|
|
964
|
+
this.logger.debug(`Field "${resolvedBlockId}" ($block) added to content type "${contentType.id}"`);
|
|
954
965
|
}
|
|
955
966
|
}
|
|
956
967
|
}
|
|
@@ -975,6 +986,7 @@ var CompositionConverterService = class {
|
|
|
975
986
|
"WRITE",
|
|
976
987
|
`${contentTypesDir}/${typeName}.json (${baseFieldCount} fields${extrasInfo})`
|
|
977
988
|
);
|
|
989
|
+
this.logger.debug(`Content type "${typeName}" fields: ${contentType.fields.map((f) => `${f.id}:${f.type}`).join(", ")}`);
|
|
978
990
|
if (!whatIf) {
|
|
979
991
|
await this.fileSystem.writeFile(filePath, contentType);
|
|
980
992
|
}
|
|
@@ -987,6 +999,7 @@ var CompositionConverterService = class {
|
|
|
987
999
|
"WRITE",
|
|
988
1000
|
`${contentTypesDir}/${typeName}.json (${contentType.fields.length} fields)`
|
|
989
1001
|
);
|
|
1002
|
+
this.logger.debug(`Content type "${typeName}" fields: ${contentType.fields.map((f) => `${f.id}:${f.type}`).join(", ")}`);
|
|
990
1003
|
if (!whatIf) {
|
|
991
1004
|
await this.fileSystem.writeFile(filePath, contentType);
|
|
992
1005
|
}
|
|
@@ -1352,6 +1365,7 @@ var PropertyPropagatorService = class {
|
|
|
1352
1365
|
try {
|
|
1353
1366
|
const { component: sourceComponent, filePath: sourceFilePath } = await this.componentService.loadComponent(fullComponentsDir, sourceType, findOptions);
|
|
1354
1367
|
sourceComponents.push({ sourceType, sourceFilePath, sourceComponent });
|
|
1368
|
+
this.logger.debug(`Loaded source component "${sourceType}" from ${sourceFilePath}`);
|
|
1355
1369
|
} catch (error) {
|
|
1356
1370
|
if (error instanceof ComponentNotFoundError) {
|
|
1357
1371
|
this.logger.warn(`Component not found: ${sourceType} (searched: ${fullComponentsDir})`);
|
|
@@ -1362,6 +1376,7 @@ var PropertyPropagatorService = class {
|
|
|
1362
1376
|
}
|
|
1363
1377
|
this.logger.info(`Loading component: ${targetComponentType}`);
|
|
1364
1378
|
const { component: targetComponent, filePath: targetFilePath } = await this.componentService.loadComponent(fullComponentsDir, targetComponentType, findOptions);
|
|
1379
|
+
this.logger.debug(`Loaded target component "${targetComponentType}" from ${targetFilePath}`);
|
|
1365
1380
|
const propertyNames = property.split("|").map((p) => p.trim()).filter((p) => p.length > 0);
|
|
1366
1381
|
const resolvedParams = [];
|
|
1367
1382
|
const resolvedNames = [];
|
|
@@ -1382,6 +1397,8 @@ var PropertyPropagatorService = class {
|
|
|
1382
1397
|
if (!exists) {
|
|
1383
1398
|
resolvedParams.push(param);
|
|
1384
1399
|
resolvedNames.push(param.id);
|
|
1400
|
+
} else {
|
|
1401
|
+
this.logger.debug(`Parameter "${param.id}" already collected from another source \u2014 skipping duplicate`);
|
|
1385
1402
|
}
|
|
1386
1403
|
}
|
|
1387
1404
|
}
|
|
@@ -1420,7 +1437,10 @@ var PropertyPropagatorService = class {
|
|
|
1420
1437
|
targetGroup,
|
|
1421
1438
|
findOptions
|
|
1422
1439
|
);
|
|
1440
|
+
this.logger.debug(`Group "${targetGroup}" (id: ${groupId}) created on component ${targetComponentType}`);
|
|
1423
1441
|
componentModified = true;
|
|
1442
|
+
} else {
|
|
1443
|
+
this.logger.debug(`Group "${targetGroup}" (id: ${groupId}) already exists on ${targetComponentType}`);
|
|
1424
1444
|
}
|
|
1425
1445
|
for (const param of resolvedParams) {
|
|
1426
1446
|
const existingParam = this.componentService.findParameter(
|
|
@@ -1445,6 +1465,7 @@ var PropertyPropagatorService = class {
|
|
|
1445
1465
|
param.id,
|
|
1446
1466
|
findOptions
|
|
1447
1467
|
);
|
|
1468
|
+
this.logger.debug(`Parameter "${param.id}" (type: ${param.type}) added to component ${targetComponentType} in group "${targetGroup}"`);
|
|
1448
1469
|
componentModified = true;
|
|
1449
1470
|
} else {
|
|
1450
1471
|
this.logger.info(`Parameter "${param.id}" already exists on ${targetComponentType}`);
|
|
@@ -1464,7 +1485,10 @@ var PropertyPropagatorService = class {
|
|
|
1464
1485
|
param.id,
|
|
1465
1486
|
findOptions
|
|
1466
1487
|
);
|
|
1488
|
+
this.logger.debug(`Parameter "${param.id}" added to group "${targetGroup}" on ${targetComponentType} (was missing from group)`);
|
|
1467
1489
|
componentModified = true;
|
|
1490
|
+
} else {
|
|
1491
|
+
this.logger.debug(`Parameter "${param.id}" already in group "${targetGroup}" on ${targetComponentType} \u2014 no change`);
|
|
1468
1492
|
}
|
|
1469
1493
|
}
|
|
1470
1494
|
}
|
|
@@ -1477,6 +1501,7 @@ var PropertyPropagatorService = class {
|
|
|
1477
1501
|
compositionTypes,
|
|
1478
1502
|
findOptions
|
|
1479
1503
|
);
|
|
1504
|
+
this.logger.debug(`Found ${compositions.length} composition(s) matching types [${compositionTypes.join(", ")}]`);
|
|
1480
1505
|
let modifiedCompositions = 0;
|
|
1481
1506
|
let propagatedInstances = 0;
|
|
1482
1507
|
for (const { composition, filePath } of compositions) {
|
|
@@ -1487,6 +1512,7 @@ var PropertyPropagatorService = class {
|
|
|
1487
1512
|
findOptions
|
|
1488
1513
|
);
|
|
1489
1514
|
if (instances.length === 0) {
|
|
1515
|
+
this.logger.debug(`Skipping "${filePath}": no instances of ${targetComponentType} found`);
|
|
1490
1516
|
continue;
|
|
1491
1517
|
}
|
|
1492
1518
|
const valuesToPropagate = {};
|
|
@@ -1496,6 +1522,7 @@ var PropertyPropagatorService = class {
|
|
|
1496
1522
|
}
|
|
1497
1523
|
}
|
|
1498
1524
|
if (Object.keys(valuesToPropagate).length === 0) {
|
|
1525
|
+
this.logger.debug(`Skipping "${filePath}": ${instances.length} instance(s) of ${targetComponentType} found but none of [${resolvedNames.join(", ")}] present in root overrides`);
|
|
1499
1526
|
continue;
|
|
1500
1527
|
}
|
|
1501
1528
|
let compositionModified = false;
|
|
@@ -1507,9 +1534,11 @@ var PropertyPropagatorService = class {
|
|
|
1507
1534
|
this.compositionService.setInstanceParameters(instance, clonedValues);
|
|
1508
1535
|
compositionModified = true;
|
|
1509
1536
|
propagatedInstances++;
|
|
1537
|
+
const updatedParamNames = Object.keys(valuesToPropagate).join(", ");
|
|
1510
1538
|
instanceUpdates.push(
|
|
1511
|
-
`${targetComponentType} "${instanceName}": ${
|
|
1539
|
+
`${targetComponentType} "${instanceName}": ${updatedParamNames}`
|
|
1512
1540
|
);
|
|
1541
|
+
this.logger.debug(`Component ${targetComponentType} "${instanceName}": parameters ${updatedParamNames} updated`);
|
|
1513
1542
|
}
|
|
1514
1543
|
if (compositionModified) {
|
|
1515
1544
|
this.logger.action(whatIf, "UPDATE", `composition/${relativePath}`);
|
|
@@ -1532,7 +1561,10 @@ var PropertyPropagatorService = class {
|
|
|
1532
1561
|
if (exists) {
|
|
1533
1562
|
this.logger.action(whatIf, "DELETE", `Parameter "${param.id}" from ${sourceType}`);
|
|
1534
1563
|
modifiedSource = this.componentService.removeParameter(modifiedSource, param.id, findOptions);
|
|
1564
|
+
this.logger.debug(`Parameter "${param.id}" removed from component ${sourceType}`);
|
|
1535
1565
|
sourceComponentModified = true;
|
|
1566
|
+
} else {
|
|
1567
|
+
this.logger.debug(`Parameter "${param.id}" not found on source component "${sourceType}" \u2014 nothing to delete`);
|
|
1536
1568
|
}
|
|
1537
1569
|
}
|
|
1538
1570
|
const beforeGroupCount = modifiedSource.parameters?.filter(
|
|
@@ -1571,6 +1603,8 @@ var PropertyPropagatorService = class {
|
|
|
1571
1603
|
if (!whatIf) {
|
|
1572
1604
|
await this.compositionService.saveComposition(filePath, composition);
|
|
1573
1605
|
}
|
|
1606
|
+
} else {
|
|
1607
|
+
this.logger.debug(`No root overrides matching [${resolvedNames.join(", ")}] in composition/${relativePath}`);
|
|
1574
1608
|
}
|
|
1575
1609
|
}
|
|
1576
1610
|
}
|
|
@@ -1598,9 +1632,16 @@ var PropertyPropagatorService = class {
|
|
|
1598
1632
|
// src/cli/logger.ts
|
|
1599
1633
|
import chalk from "chalk";
|
|
1600
1634
|
var Logger = class {
|
|
1635
|
+
constructor(verbose = false) {
|
|
1636
|
+
this.verbose = verbose;
|
|
1637
|
+
}
|
|
1601
1638
|
info(message) {
|
|
1602
1639
|
console.log(`${chalk.blue("[INFO]")} ${message}`);
|
|
1603
1640
|
}
|
|
1641
|
+
debug(message) {
|
|
1642
|
+
if (!this.verbose) return;
|
|
1643
|
+
console.log(`${chalk.magenta("[DEBUG]")} ${message}`);
|
|
1644
|
+
}
|
|
1604
1645
|
success(message) {
|
|
1605
1646
|
console.log(`${chalk.green("[DONE]")} ${message}`);
|
|
1606
1647
|
}
|
|
@@ -1636,7 +1677,7 @@ function createPropagateRootComponentPropertyCommand() {
|
|
|
1636
1677
|
).option(
|
|
1637
1678
|
"--deleteSourceParameter",
|
|
1638
1679
|
"Delete the original parameters from the source component after propagation"
|
|
1639
|
-
).hook("preAction", (thisCommand) => {
|
|
1680
|
+
).option("--verbose", "Enable verbose output with detailed progress information").hook("preAction", (thisCommand) => {
|
|
1640
1681
|
const opts = thisCommand.opts();
|
|
1641
1682
|
const requiredOptions = [
|
|
1642
1683
|
{ name: "compositionType", flag: "--compositionType" },
|
|
@@ -1659,7 +1700,7 @@ function createPropagateRootComponentPropertyCommand() {
|
|
|
1659
1700
|
targetGroup: opts.targetGroup,
|
|
1660
1701
|
deleteSourceParameter: opts.deleteSourceParameter
|
|
1661
1702
|
};
|
|
1662
|
-
const logger = new Logger();
|
|
1703
|
+
const logger = new Logger(opts.verbose ?? false);
|
|
1663
1704
|
const fileSystem = new FileSystemService();
|
|
1664
1705
|
const componentService = new ComponentService(fileSystem);
|
|
1665
1706
|
const compositionService = new CompositionService(fileSystem);
|
|
@@ -1686,6 +1727,10 @@ function createPropagateRootComponentPropertyCommand() {
|
|
|
1686
1727
|
`Modified ${result.modifiedComponents} component, ${result.modifiedCompositions} compositions`
|
|
1687
1728
|
);
|
|
1688
1729
|
} catch (error) {
|
|
1730
|
+
if (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError) {
|
|
1731
|
+
logger.warn(error.message);
|
|
1732
|
+
return;
|
|
1733
|
+
}
|
|
1689
1734
|
if (error instanceof TransformError) {
|
|
1690
1735
|
logger.error(error.message);
|
|
1691
1736
|
process.exit(1);
|
|
@@ -3215,6 +3260,10 @@ function createRenameSlotCommand() {
|
|
|
3215
3260
|
`Renamed slot: ${result.compositionsModified} composition(s), ${result.compositionPatternsModified} composition pattern(s), ${result.componentPatternsModified} component pattern(s) updated`
|
|
3216
3261
|
);
|
|
3217
3262
|
} catch (error) {
|
|
3263
|
+
if (error instanceof ComponentNotFoundError) {
|
|
3264
|
+
logger.warn(error.message);
|
|
3265
|
+
return;
|
|
3266
|
+
}
|
|
3218
3267
|
if (error instanceof TransformError) {
|
|
3219
3268
|
logger.error(error.message);
|
|
3220
3269
|
process.exit(1);
|
|
@@ -3492,6 +3541,10 @@ function createRenameComponentCommand() {
|
|
|
3492
3541
|
`Renamed component: ${result.allowedComponentsUpdated} allowedComponents ref(s), ${result.compositionsModified} composition(s), ${result.compositionPatternsModified} composition pattern(s), ${result.componentPatternsModified} component pattern(s) updated`
|
|
3493
3542
|
);
|
|
3494
3543
|
} catch (error) {
|
|
3544
|
+
if (error instanceof ComponentNotFoundError) {
|
|
3545
|
+
logger.warn(error.message);
|
|
3546
|
+
return;
|
|
3547
|
+
}
|
|
3495
3548
|
if (error instanceof TransformError) {
|
|
3496
3549
|
logger.error(error.message);
|
|
3497
3550
|
process.exit(1);
|
|
@@ -3603,16 +3656,7 @@ var ComponentAdderService = class {
|
|
|
3603
3656
|
throw new TransformError("parentComponentType cannot be empty");
|
|
3604
3657
|
}
|
|
3605
3658
|
this.logger.info(`Validating new component: ${newComponentType}`);
|
|
3606
|
-
|
|
3607
|
-
await this.componentService.loadComponent(fullComponentsDir, newComponentType, findOptions);
|
|
3608
|
-
} catch (error) {
|
|
3609
|
-
if (error instanceof ComponentNotFoundError) {
|
|
3610
|
-
throw new TransformError(
|
|
3611
|
-
`Component type "${newComponentType}" not found in ${fullComponentsDir}`
|
|
3612
|
-
);
|
|
3613
|
-
}
|
|
3614
|
-
throw error;
|
|
3615
|
-
}
|
|
3659
|
+
await this.componentService.loadComponent(fullComponentsDir, newComponentType, findOptions);
|
|
3616
3660
|
let allowedComponentsUpdated = false;
|
|
3617
3661
|
const resolvedParentTypes = [];
|
|
3618
3662
|
for (const parentType of parentTypes) {
|
|
@@ -4042,6 +4086,10 @@ function createAddComponentCommand() {
|
|
|
4042
4086
|
`Added component: ${result.allowedComponentsUpdated ? "1 component definition updated, " : ""}${result.instancesAdded} instance(s) added across ${result.compositionsModified} composition(s), ${result.compositionPatternsModified} composition pattern(s), ${result.componentPatternsModified} component pattern(s)`
|
|
4043
4087
|
);
|
|
4044
4088
|
} catch (error) {
|
|
4089
|
+
if (error instanceof ComponentNotFoundError) {
|
|
4090
|
+
logger.warn(error.message);
|
|
4091
|
+
return;
|
|
4092
|
+
}
|
|
4045
4093
|
if (error instanceof TransformError) {
|
|
4046
4094
|
logger.error(error.message);
|
|
4047
4095
|
process.exit(1);
|
|
@@ -4097,6 +4145,10 @@ function createAddComponentPatternCommand() {
|
|
|
4097
4145
|
`Added component pattern: ${result.allowedComponentsUpdated ? "1 component definition updated, " : ""}${result.instancesAdded} instance(s) added across ${result.compositionsModified} composition(s), ${result.compositionPatternsModified} composition pattern(s), ${result.componentPatternsModified} component pattern(s)`
|
|
4098
4146
|
);
|
|
4099
4147
|
} catch (error) {
|
|
4148
|
+
if (error instanceof ComponentNotFoundError) {
|
|
4149
|
+
logger.warn(error.message);
|
|
4150
|
+
return;
|
|
4151
|
+
}
|
|
4100
4152
|
if (error instanceof TransformError) {
|
|
4101
4153
|
logger.error(error.message);
|
|
4102
4154
|
process.exit(1);
|
|
@@ -4407,6 +4459,10 @@ function createPropagateRootComponentSlotCommand() {
|
|
|
4407
4459
|
`Modified ${result.modifiedComponents} component(s), ${result.modifiedCompositions} composition(s)`
|
|
4408
4460
|
);
|
|
4409
4461
|
} catch (error) {
|
|
4462
|
+
if (error instanceof ComponentNotFoundError) {
|
|
4463
|
+
logger.warn(error.message);
|
|
4464
|
+
return;
|
|
4465
|
+
}
|
|
4410
4466
|
if (error instanceof TransformError) {
|
|
4411
4467
|
logger.error(error.message);
|
|
4412
4468
|
process.exit(1);
|
|
@@ -4432,7 +4488,7 @@ function createConvertCompositionsToEntriesCommand() {
|
|
|
4432
4488
|
).option(
|
|
4433
4489
|
"--componentsToBlocks <types>",
|
|
4434
4490
|
"Pipe-separated list of component types to convert into inline blocks (e.g., DetailHero|ArticleDetail)"
|
|
4435
|
-
).hook("preAction", (thisCommand) => {
|
|
4491
|
+
).option("--verbose", "Enable verbose output with detailed progress information").hook("preAction", (thisCommand) => {
|
|
4436
4492
|
const opts = thisCommand.opts();
|
|
4437
4493
|
const requiredOptions = [
|
|
4438
4494
|
{ name: "compositionTypes", flag: "--compositionTypes" }
|
|
@@ -4450,7 +4506,7 @@ function createConvertCompositionsToEntriesCommand() {
|
|
|
4450
4506
|
componentsToReferences: opts.componentsToReferences,
|
|
4451
4507
|
componentsToBlocks: opts.componentsToBlocks
|
|
4452
4508
|
};
|
|
4453
|
-
const logger = new Logger();
|
|
4509
|
+
const logger = new Logger(opts.verbose ?? false);
|
|
4454
4510
|
const fileSystem = new FileSystemService();
|
|
4455
4511
|
const componentService = new ComponentService(fileSystem);
|
|
4456
4512
|
const compositionService = new CompositionService(fileSystem);
|
|
@@ -4484,6 +4540,10 @@ function createConvertCompositionsToEntriesCommand() {
|
|
|
4484
4540
|
`${result.contentTypesWritten} content type(s), ${result.entriesFromCompositions} entry(ies) from compositions${refInfo}${reusedInfo}${blocksInfo}`
|
|
4485
4541
|
);
|
|
4486
4542
|
} catch (error) {
|
|
4543
|
+
if (error instanceof ComponentNotFoundError) {
|
|
4544
|
+
logger.warn(error.message);
|
|
4545
|
+
return;
|
|
4546
|
+
}
|
|
4487
4547
|
if (error instanceof TransformError) {
|
|
4488
4548
|
logger.error(error.message);
|
|
4489
4549
|
process.exit(1);
|
|
@@ -4811,7 +4871,7 @@ function createRemoveParameterCommand() {
|
|
|
4811
4871
|
aggregate.compositionPatternsModified += result.compositionPatternsModified;
|
|
4812
4872
|
aggregate.componentPatternsModified += result.componentPatternsModified;
|
|
4813
4873
|
} catch (error) {
|
|
4814
|
-
if (
|
|
4874
|
+
if (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError) {
|
|
4815
4875
|
logger.warn(error.message);
|
|
4816
4876
|
continue;
|
|
4817
4877
|
}
|
|
@@ -5254,6 +5314,10 @@ function createAddComponentParameterCommand() {
|
|
|
5254
5314
|
`${result.parameterReplaced ? "Replaced" : "Added"} parameter "${options.parameterId}" on component "${options.componentId}"`
|
|
5255
5315
|
);
|
|
5256
5316
|
} catch (error) {
|
|
5317
|
+
if (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError) {
|
|
5318
|
+
logger.warn(error.message);
|
|
5319
|
+
return;
|
|
5320
|
+
}
|
|
5257
5321
|
if (error instanceof TransformError) {
|
|
5258
5322
|
logger.error(error.message);
|
|
5259
5323
|
process.exit(1);
|
|
@@ -5832,6 +5896,10 @@ function createFlattenBlockFieldCommand() {
|
|
|
5832
5896
|
`Flattened parameter "${options.parameterId}" on component "${options.componentId}": ${result.compositionsModified} composition(s), ${result.compositionPatternsModified} composition pattern(s), ${result.componentPatternsModified} component pattern(s) updated`
|
|
5833
5897
|
);
|
|
5834
5898
|
} catch (error) {
|
|
5899
|
+
if (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError) {
|
|
5900
|
+
logger.warn(error.message);
|
|
5901
|
+
return;
|
|
5902
|
+
}
|
|
5835
5903
|
if (error instanceof TransformError) {
|
|
5836
5904
|
logger.error(error.message);
|
|
5837
5905
|
process.exit(1);
|
|
@@ -5842,10 +5910,171 @@ function createFlattenBlockFieldCommand() {
|
|
|
5842
5910
|
return command;
|
|
5843
5911
|
}
|
|
5844
5912
|
|
|
5913
|
+
// src/cli/commands/remove-orphan-entries.ts
|
|
5914
|
+
import { Command as Command16 } from "commander";
|
|
5915
|
+
|
|
5916
|
+
// src/core/services/orphan-entry-remover.service.ts
|
|
5917
|
+
var OrphanEntryRemoverService = class {
|
|
5918
|
+
constructor(fileSystem, logger) {
|
|
5919
|
+
this.fileSystem = fileSystem;
|
|
5920
|
+
this.logger = logger;
|
|
5921
|
+
}
|
|
5922
|
+
async remove(options) {
|
|
5923
|
+
const { rootDir, entriesDir, rootContentTypes, whatIf, strict } = options;
|
|
5924
|
+
const entriesDirFull = this.fileSystem.resolvePath(rootDir, entriesDir);
|
|
5925
|
+
const dirExists = await this.fileSystem.fileExists(entriesDirFull);
|
|
5926
|
+
if (!dirExists) {
|
|
5927
|
+
this.logger.warn(`Entries directory not found: ${entriesDir} \u2014 nothing to do`);
|
|
5928
|
+
return { totalEntries: 0, whitelistedEntries: 0, removedEntries: 0 };
|
|
5929
|
+
}
|
|
5930
|
+
const entryFiles = await this.fileSystem.findFiles(entriesDirFull, "**/*.{json,yaml,yml}");
|
|
5931
|
+
if (entryFiles.length === 0) {
|
|
5932
|
+
this.logger.warn("No entry files found \u2014 nothing to do");
|
|
5933
|
+
return { totalEntries: 0, whitelistedEntries: 0, removedEntries: 0 };
|
|
5934
|
+
}
|
|
5935
|
+
this.logger.info(`Loaded ${entryFiles.length} entry file(s)`);
|
|
5936
|
+
const entryMap = /* @__PURE__ */ new Map();
|
|
5937
|
+
for (const filePath of entryFiles) {
|
|
5938
|
+
let entryData;
|
|
5939
|
+
try {
|
|
5940
|
+
entryData = await this.fileSystem.readFile(filePath);
|
|
5941
|
+
} catch {
|
|
5942
|
+
this.logger.warn(`Could not read entry file: ${filePath} \u2014 skipping`);
|
|
5943
|
+
continue;
|
|
5944
|
+
}
|
|
5945
|
+
if (!entryData?.entry?._id) {
|
|
5946
|
+
this.logger.warn(`Entry file missing entry._id: ${filePath} \u2014 skipping`);
|
|
5947
|
+
continue;
|
|
5948
|
+
}
|
|
5949
|
+
entryMap.set(entryData.entry._id, { filePath, entryData });
|
|
5950
|
+
}
|
|
5951
|
+
this.logger.info(`Root content types: ${rootContentTypes.join(", ")}`);
|
|
5952
|
+
const whitelist = /* @__PURE__ */ new Set();
|
|
5953
|
+
for (const [entryId, { entryData }] of entryMap) {
|
|
5954
|
+
if (this.matchesContentType(entryData.entry.type, rootContentTypes, strict)) {
|
|
5955
|
+
whitelist.add(entryId);
|
|
5956
|
+
}
|
|
5957
|
+
}
|
|
5958
|
+
this.logger.info(`Whitelisted ${whitelist.size} entry(ies) from root content types`);
|
|
5959
|
+
let round = 0;
|
|
5960
|
+
let frontier = [...whitelist];
|
|
5961
|
+
while (frontier.length > 0) {
|
|
5962
|
+
round++;
|
|
5963
|
+
const nextFrontier = [];
|
|
5964
|
+
for (const entryId of frontier) {
|
|
5965
|
+
const entry = entryMap.get(entryId);
|
|
5966
|
+
if (!entry) continue;
|
|
5967
|
+
const referencedIds = this.extractReferencedEntryIds(entry.entryData);
|
|
5968
|
+
for (const refId of referencedIds) {
|
|
5969
|
+
if (!whitelist.has(refId) && entryMap.has(refId)) {
|
|
5970
|
+
whitelist.add(refId);
|
|
5971
|
+
nextFrontier.push(refId);
|
|
5972
|
+
}
|
|
5973
|
+
}
|
|
5974
|
+
}
|
|
5975
|
+
if (nextFrontier.length > 0) {
|
|
5976
|
+
this.logger.info(`BFS round ${round}: added ${nextFrontier.length} entry(ies) via references`);
|
|
5977
|
+
}
|
|
5978
|
+
frontier = nextFrontier;
|
|
5979
|
+
}
|
|
5980
|
+
this.logger.info(`BFS stable after ${round} round(s)`);
|
|
5981
|
+
let removedEntries = 0;
|
|
5982
|
+
for (const [entryId, { filePath, entryData }] of entryMap) {
|
|
5983
|
+
if (!whitelist.has(entryId)) {
|
|
5984
|
+
const relPath = this.fileSystem.joinPath(entriesDir, this.fileSystem.getBasename(filePath));
|
|
5985
|
+
this.logger.action(whatIf, "DELETE", `${relPath} (${entryData.entry.type})`);
|
|
5986
|
+
if (!whatIf) {
|
|
5987
|
+
this.fileSystem.deleteFile(filePath);
|
|
5988
|
+
}
|
|
5989
|
+
removedEntries++;
|
|
5990
|
+
}
|
|
5991
|
+
}
|
|
5992
|
+
return {
|
|
5993
|
+
totalEntries: entryMap.size,
|
|
5994
|
+
whitelistedEntries: whitelist.size,
|
|
5995
|
+
removedEntries
|
|
5996
|
+
};
|
|
5997
|
+
}
|
|
5998
|
+
extractReferencedEntryIds(entryData) {
|
|
5999
|
+
const ids = [];
|
|
6000
|
+
if (entryData.entry._dataResources) {
|
|
6001
|
+
for (const resource of Object.values(entryData.entry._dataResources)) {
|
|
6002
|
+
if (resource.type === "uniformContentInternalReference" && resource.variables?.entryIds) {
|
|
6003
|
+
const entryIds = resource.variables.entryIds.split(",").map((s) => s.trim()).filter(Boolean);
|
|
6004
|
+
ids.push(...entryIds);
|
|
6005
|
+
}
|
|
6006
|
+
}
|
|
6007
|
+
}
|
|
6008
|
+
if (entryData.entry.fields) {
|
|
6009
|
+
for (const field of Object.values(entryData.entry.fields)) {
|
|
6010
|
+
if (field.type === "contentReference" && Array.isArray(field.value)) {
|
|
6011
|
+
for (const id of field.value) {
|
|
6012
|
+
if (typeof id === "string") {
|
|
6013
|
+
ids.push(id);
|
|
6014
|
+
}
|
|
6015
|
+
}
|
|
6016
|
+
}
|
|
6017
|
+
}
|
|
6018
|
+
}
|
|
6019
|
+
return ids;
|
|
6020
|
+
}
|
|
6021
|
+
matchesContentType(entryType, rootContentTypes, strict) {
|
|
6022
|
+
for (const rootType of rootContentTypes) {
|
|
6023
|
+
if (strict) {
|
|
6024
|
+
if (entryType === rootType) return true;
|
|
6025
|
+
} else {
|
|
6026
|
+
if (entryType.toLowerCase() === rootType.toLowerCase()) return true;
|
|
6027
|
+
}
|
|
6028
|
+
}
|
|
6029
|
+
return false;
|
|
6030
|
+
}
|
|
6031
|
+
};
|
|
6032
|
+
|
|
6033
|
+
// src/cli/commands/remove-orphan-entries.ts
|
|
6034
|
+
function createRemoveOrphanEntriesCommand() {
|
|
6035
|
+
const command = new Command16("remove-orphan-entries");
|
|
6036
|
+
command.description(
|
|
6037
|
+
"Removes entry files that are not reachable from root content-type entries by following contentReference links transitively."
|
|
6038
|
+
).option(
|
|
6039
|
+
"--rootContentTypes <types>",
|
|
6040
|
+
'Pipe-separated list of content-type IDs whose entries are treated as roots and never deleted (e.g. "HomePage|BlogPost")'
|
|
6041
|
+
).hook("preAction", (thisCommand) => {
|
|
6042
|
+
const opts = thisCommand.opts();
|
|
6043
|
+
const requiredOptions = [{ name: "rootContentTypes", flag: "--rootContentTypes" }];
|
|
6044
|
+
const missing = requiredOptions.filter((opt) => !opts[opt.name]).map((opt) => opt.flag);
|
|
6045
|
+
if (missing.length > 0) {
|
|
6046
|
+
console.error(`error: missing required options: ${missing.join(", ")}`);
|
|
6047
|
+
process.exit(1);
|
|
6048
|
+
}
|
|
6049
|
+
}).action(async (opts, cmd) => {
|
|
6050
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
6051
|
+
const options = {
|
|
6052
|
+
...globalOpts,
|
|
6053
|
+
rootContentTypes: opts.rootContentTypes
|
|
6054
|
+
};
|
|
6055
|
+
const logger = new Logger();
|
|
6056
|
+
logger.info(`rootContentTypes: ${options.rootContentTypes}`);
|
|
6057
|
+
const rootContentTypes = options.rootContentTypes.split("|").map((t) => t.trim()).filter(Boolean);
|
|
6058
|
+
const fileSystem = new FileSystemService();
|
|
6059
|
+
const service = new OrphanEntryRemoverService(fileSystem, logger);
|
|
6060
|
+
const result = await service.remove({
|
|
6061
|
+
rootDir: options.rootDir,
|
|
6062
|
+
entriesDir: options.entriesDir,
|
|
6063
|
+
rootContentTypes,
|
|
6064
|
+
whatIf: options.whatIf ?? false,
|
|
6065
|
+
strict: options.strict ?? false
|
|
6066
|
+
});
|
|
6067
|
+
logger.success(
|
|
6068
|
+
`Removed ${result.removedEntries} orphan entry(ies). ${result.whitelistedEntries} entry(ies) retained.`
|
|
6069
|
+
);
|
|
6070
|
+
});
|
|
6071
|
+
return command;
|
|
6072
|
+
}
|
|
6073
|
+
|
|
5845
6074
|
// package.json
|
|
5846
6075
|
var package_default = {
|
|
5847
6076
|
name: "@uniformdev/transformer",
|
|
5848
|
-
version: "1.1.
|
|
6077
|
+
version: "1.1.36",
|
|
5849
6078
|
description: "CLI tool for transforming Uniform.dev serialization files offline",
|
|
5850
6079
|
type: "module",
|
|
5851
6080
|
bin: {
|
|
@@ -5914,7 +6143,7 @@ var package_default = {
|
|
|
5914
6143
|
};
|
|
5915
6144
|
|
|
5916
6145
|
// src/cli/index.ts
|
|
5917
|
-
var program = new
|
|
6146
|
+
var program = new Command17();
|
|
5918
6147
|
var appVersion = package_default.version;
|
|
5919
6148
|
console.error(`uniform-transform v${appVersion}`);
|
|
5920
6149
|
program.name("uniform-transform").description("CLI tool for transforming Uniform.dev serialization files offline").version(appVersion);
|
|
@@ -5942,5 +6171,6 @@ program.addCommand(createRemoveFieldCommand());
|
|
|
5942
6171
|
program.addCommand(createAddComponentParameterCommand());
|
|
5943
6172
|
program.addCommand(createAddContentTypeFieldCommand());
|
|
5944
6173
|
program.addCommand(createFlattenBlockFieldCommand());
|
|
6174
|
+
program.addCommand(createRemoveOrphanEntriesCommand());
|
|
5945
6175
|
program.parse();
|
|
5946
6176
|
//# sourceMappingURL=index.js.map
|