@uniformdev/transformer 1.1.40 → 1.1.42

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 CHANGED
@@ -1611,6 +1611,11 @@ function walkAndRegenerate(value, currentPath) {
1611
1611
  return value;
1612
1612
  }
1613
1613
 
1614
+ // src/core/utils.ts
1615
+ function splitList(value) {
1616
+ return value.split(/[,;|]/).map((s) => s.trim()).filter((s) => s.length > 0);
1617
+ }
1618
+
1614
1619
  // src/core/services/property-propagator.service.ts
1615
1620
  var PropertyPropagatorService = class {
1616
1621
  constructor(fileSystem, componentService, compositionService, logger) {
@@ -1654,7 +1659,7 @@ var PropertyPropagatorService = class {
1654
1659
  this.logger.info(`Loading component: ${targetComponentType}`);
1655
1660
  const { component: targetComponent, filePath: targetFilePath } = await this.componentService.loadComponent(fullComponentsDir, targetComponentType, findOptions);
1656
1661
  this.logger.debug(`Loaded target component "${targetComponentType}" from ${targetFilePath}`);
1657
- const propertyNames = property.split("|").map((p) => p.trim()).filter((p) => p.length > 0);
1662
+ const propertyNames = splitList(property);
1658
1663
  const resolvedParams = [];
1659
1664
  const resolvedNames = [];
1660
1665
  for (const { sourceType, sourceComponent } of sourceComponents) {
@@ -1892,7 +1897,7 @@ var PropertyPropagatorService = class {
1892
1897
  };
1893
1898
  }
1894
1899
  parsePipeSeparatedValues(value, strict) {
1895
- const entries = value.split("|").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
1900
+ const entries = splitList(value);
1896
1901
  const normalized = [];
1897
1902
  for (const entry of entries) {
1898
1903
  const exists = normalized.some(
@@ -3850,7 +3855,7 @@ var ComponentAdderService = class {
3850
3855
  return id1.toLowerCase() === id2.toLowerCase();
3851
3856
  }
3852
3857
  parseParentComponentTypes(parentComponentType) {
3853
- return parentComponentType.split("|").map((t) => t.trim()).filter((t) => t.length > 0);
3858
+ return splitList(parentComponentType);
3854
3859
  }
3855
3860
  matchesAnyParentType(instanceType, parentTypes, strict) {
3856
3861
  return parentTypes.some((pt) => this.compareIds(instanceType, pt, strict));
@@ -4494,7 +4499,7 @@ var SlotPropagatorService = class {
4494
4499
  }
4495
4500
  this.logger.info(`Loading component: ${targetComponentType}`);
4496
4501
  const { component: targetComponent, filePath: targetFilePath } = await this.componentService.loadComponent(fullComponentsDir, targetComponentType, findOptions);
4497
- const slotNames = slot.split("|").map((s) => s.trim()).filter((s) => s.length > 0);
4502
+ const slotNames = splitList(slot);
4498
4503
  const resolvedSlots = [];
4499
4504
  const resolvedSlotIds = [];
4500
4505
  for (const { sourceType, sourceComponent } of sourceComponents) {
@@ -4669,7 +4674,7 @@ var SlotPropagatorService = class {
4669
4674
  instance.slots[slotName].push(...components);
4670
4675
  }
4671
4676
  parsePipeSeparatedValues(value, strict) {
4672
- const entries = value.split("|").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
4677
+ const entries = splitList(value);
4673
4678
  const normalized = [];
4674
4679
  for (const entry of entries) {
4675
4680
  const exists = normalized.some(
@@ -4816,8 +4821,8 @@ function createConvertCompositionsToEntriesCommand() {
4816
4821
  logger
4817
4822
  );
4818
4823
  try {
4819
- const compositionTypes = options.compositionTypes.split("|").map((t) => t.trim()).filter((t) => t.length > 0);
4820
- const parsePipeSeparated = (value) => value ? [...new Set(value.split("|").map((t) => t.trim()).filter((t) => t.length > 0))] : [];
4824
+ const compositionTypes = splitList(options.compositionTypes);
4825
+ const parsePipeSeparated = (value) => value ? [...new Set(splitList(value))] : [];
4821
4826
  const componentsToReferences = parsePipeSeparated(options.componentsToReferences);
4822
4827
  const componentsToBlocks = parsePipeSeparated(options.componentsToBlocks);
4823
4828
  const slotsToReferences = parsePipeSeparated(options.slotsToReferences);
@@ -5129,7 +5134,7 @@ function createRemoveParameterCommand() {
5129
5134
  const fileSystem = new FileSystemService();
5130
5135
  const componentService = new ComponentService(fileSystem);
5131
5136
  const remover = new ParameterRemoverService(fileSystem, componentService, logger);
5132
- const rawTypes = options.componentType.split("|").map((t) => t.trim()).filter(Boolean);
5137
+ const rawTypes = splitList(options.componentType);
5133
5138
  const hasWildcard = rawTypes.includes("*");
5134
5139
  let componentTypes;
5135
5140
  if (hasWildcard) {
@@ -5440,7 +5445,7 @@ function createRemoveFieldCommand() {
5440
5445
  const fileSystem = new FileSystemService();
5441
5446
  const componentService = new ComponentService(fileSystem);
5442
5447
  const remover = new FieldRemoverService(fileSystem, componentService, logger);
5443
- const rawTypes = options.componentType.split("|").map((t) => t.trim()).filter(Boolean);
5448
+ const rawTypes = splitList(options.componentType);
5444
5449
  const componentTypes = rawTypes.includes("*") ? ["*"] : rawTypes;
5445
5450
  const aggregate = {
5446
5451
  compositionsModified: 0,
@@ -6367,7 +6372,7 @@ function createRemoveOrphanEntriesCommand() {
6367
6372
  };
6368
6373
  const logger = new Logger();
6369
6374
  logger.info(`rootContentTypes: ${options.rootContentTypes}`);
6370
- const rootContentTypes = options.rootContentTypes.split("|").map((t) => t.trim()).filter(Boolean);
6375
+ const rootContentTypes = splitList(options.rootContentTypes);
6371
6376
  const fileSystem = new FileSystemService();
6372
6377
  const service = new OrphanEntryRemoverService(fileSystem, logger);
6373
6378
  const result = await service.remove({
@@ -6625,7 +6630,8 @@ var UnusedComponentTypeRemoverService = class {
6625
6630
  compositionPatternsDir,
6626
6631
  componentPatternsDir,
6627
6632
  whatIf,
6628
- strict
6633
+ strict,
6634
+ excludeComponentTypes = []
6629
6635
  } = options;
6630
6636
  const componentsDirFull = this.fileSystem.resolvePath(rootDir, componentsDir);
6631
6637
  const ctDirExists = await this.fileSystem.fileExists(componentsDirFull);
@@ -6676,7 +6682,10 @@ var UnusedComponentTypeRemoverService = class {
6676
6682
  let retainedComponentTypes = 0;
6677
6683
  for (const { filePath, id } of componentMap.values()) {
6678
6684
  const isUsed = this.isUsed(id, usedTypeIds, strict);
6679
- if (isUsed) {
6685
+ const isExcluded = excludeComponentTypes.some(
6686
+ (ex) => strict ? ex === id : ex.toLowerCase() === id.toLowerCase()
6687
+ );
6688
+ if (isUsed || isExcluded) {
6680
6689
  retainedComponentTypes++;
6681
6690
  } else {
6682
6691
  const relPath = this.fileSystem.joinPath(
@@ -6775,6 +6784,9 @@ function createRemoveUnusedComponentTypesCommand() {
6775
6784
  const command = new Command18("remove-unused-component-types");
6776
6785
  command.description(
6777
6786
  "Removes component definition files that are not referenced in any composition, pattern, or allowedComponents list."
6787
+ ).option(
6788
+ "--excludeComponentTypes <types>",
6789
+ 'Pipe-separated list of component type IDs to keep even if unused (e.g. "Hero|Button")'
6778
6790
  ).action(async (_opts, cmd) => {
6779
6791
  const globalOpts = cmd.optsWithGlobals();
6780
6792
  const options = {
@@ -6786,6 +6798,8 @@ function createRemoveUnusedComponentTypesCommand() {
6786
6798
  logger.info(`compositionsDir: ${options.compositionsDir}`);
6787
6799
  logger.info(`compositionPatternsDir: ${options.compositionPatternsDir}`);
6788
6800
  logger.info(`componentPatternsDir: ${options.componentPatternsDir}`);
6801
+ logger.info(`excludeComponentTypes: ${options.excludeComponentTypes ?? ""}`);
6802
+ const excludeComponentTypes = options.excludeComponentTypes ? splitList(options.excludeComponentTypes) : [];
6789
6803
  const fileSystem = new FileSystemService();
6790
6804
  const service = new UnusedComponentTypeRemoverService(fileSystem, logger);
6791
6805
  const result = await service.remove({
@@ -6795,7 +6809,8 @@ function createRemoveUnusedComponentTypesCommand() {
6795
6809
  compositionPatternsDir: options.compositionPatternsDir,
6796
6810
  componentPatternsDir: options.componentPatternsDir,
6797
6811
  whatIf: options.whatIf ?? false,
6798
- strict: options.strict ?? false
6812
+ strict: options.strict ?? false,
6813
+ excludeComponentTypes
6799
6814
  });
6800
6815
  logger.success(
6801
6816
  `Removed ${result.removedComponentTypes} unused component type(s). ${result.retainedComponentTypes} component type(s) retained.`
@@ -6814,7 +6829,7 @@ var GenerateMissingProjectMapNodesService = class {
6814
6829
  this.logger = logger;
6815
6830
  }
6816
6831
  async generate(options) {
6817
- const { rootDir, projectMapNodesDir, compositionsDir, rootContentTypes, whatIf, strict } = options;
6832
+ const { rootDir, projectMapNodesDir, whatIf } = options;
6818
6833
  const nodesDirFull = this.fileSystem.resolvePath(rootDir, projectMapNodesDir);
6819
6834
  const nodesDirExists = await this.fileSystem.fileExists(nodesDirFull);
6820
6835
  if (!nodesDirExists) {
@@ -6843,41 +6858,8 @@ var GenerateMissingProjectMapNodesService = class {
6843
6858
  allNodes.push({ filePath, node });
6844
6859
  }
6845
6860
  const existingPaths = new Set(allNodes.map(({ node }) => node.path));
6846
- const compositionsDirFull = this.fileSystem.resolvePath(rootDir, compositionsDir);
6847
- const compositionIdToType = /* @__PURE__ */ new Map();
6848
- const compositionsDirExists = await this.fileSystem.fileExists(compositionsDirFull);
6849
- if (!compositionsDirExists) {
6850
- this.logger.warn(`Compositions directory not found: ${compositionsDir} \u2014 no source nodes will match`);
6851
- } else {
6852
- const compositionFiles = await this.fileSystem.findFiles(
6853
- compositionsDirFull,
6854
- "**/*.{json,yaml,yml}"
6855
- );
6856
- for (const filePath of compositionFiles) {
6857
- let comp;
6858
- try {
6859
- comp = await this.fileSystem.readFile(filePath);
6860
- } catch {
6861
- this.logger.warn(`Could not read composition file: ${filePath} \u2014 skipping`);
6862
- continue;
6863
- }
6864
- if (comp?.composition?._id && comp?.composition?.type) {
6865
- compositionIdToType.set(comp.composition._id, comp.composition.type);
6866
- }
6867
- }
6868
- }
6869
- const sourceNodes = allNodes.filter(({ node }) => {
6870
- if (!node.compositionId) return false;
6871
- const rootType = compositionIdToType.get(node.compositionId);
6872
- if (!rootType) {
6873
- this.logger.warn(
6874
- `No composition found for compositionId "${node.compositionId}" (node path: ${node.path}) \u2014 skipping`
6875
- );
6876
- return false;
6877
- }
6878
- return this.matchesContentType(rootType, rootContentTypes, strict);
6879
- });
6880
- this.logger.info(`${sourceNodes.length} node(s) match root content types`);
6861
+ const sourceNodes = allNodes.filter(({ node }) => !!node.compositionId);
6862
+ this.logger.info(`${sourceNodes.length} node(s) selected as sources`);
6881
6863
  const ancestorPaths = /* @__PURE__ */ new Set();
6882
6864
  for (const { node } of sourceNodes) {
6883
6865
  for (const ancestor of this.computeAncestorPaths(node.path)) {
@@ -6934,52 +6916,25 @@ var GenerateMissingProjectMapNodesService = class {
6934
6916
  const slug = nodePath.split("/").filter((s) => s.length > 0).join("-");
6935
6917
  return `${slug}-node.yaml`;
6936
6918
  }
6937
- matchesContentType(rootType, rootContentTypes, strict) {
6938
- for (const ct of rootContentTypes) {
6939
- if (strict) {
6940
- if (rootType === ct) return true;
6941
- } else {
6942
- if (rootType.toLowerCase() === ct.toLowerCase()) return true;
6943
- }
6944
- }
6945
- return false;
6946
- }
6947
6919
  };
6948
6920
 
6949
6921
  // src/cli/commands/generate-missing-project-map-nodes.ts
6950
6922
  function createGenerateMissingProjectMapNodesCommand() {
6951
6923
  const command = new Command19("generate-missing-project-map-nodes");
6952
6924
  command.description(
6953
- "Creates group project map nodes for ancestor path segments that are missing from the project map. Only paths reachable from compositions whose root type matches --rootContentTypes are considered."
6954
- ).option(
6955
- "--rootContentTypes <types>",
6956
- 'Pipe-separated list of root component types identifying the leaf-page compositions whose ancestor paths should be filled in (e.g. "BlogPost|NewsArticle")'
6957
- ).hook("preAction", (thisCommand) => {
6958
- const opts = thisCommand.opts();
6959
- const requiredOptions = [{ name: "rootContentTypes", flag: "--rootContentTypes" }];
6960
- const missing = requiredOptions.filter((opt) => !opts[opt.name]).map((opt) => opt.flag);
6961
- if (missing.length > 0) {
6962
- console.error(`error: missing required options: ${missing.join(", ")}`);
6963
- process.exit(1);
6964
- }
6965
- }).action(async (opts, cmd) => {
6925
+ "Creates group project map nodes for ancestor path segments that are missing from the project map. All project map nodes with a compositionId are used as sources."
6926
+ ).action(async (opts, cmd) => {
6966
6927
  const globalOpts = cmd.optsWithGlobals();
6967
6928
  const options = {
6968
- ...globalOpts,
6969
- rootContentTypes: opts.rootContentTypes
6929
+ ...globalOpts
6970
6930
  };
6971
6931
  const logger = new Logger();
6972
- logger.info(`rootContentTypes: ${options.rootContentTypes}`);
6973
- const rootContentTypes = options.rootContentTypes.split("|").map((t) => t.trim()).filter(Boolean);
6974
6932
  const fileSystem = new FileSystemService();
6975
6933
  const service = new GenerateMissingProjectMapNodesService(fileSystem, logger);
6976
6934
  const result = await service.generate({
6977
6935
  rootDir: options.rootDir,
6978
6936
  projectMapNodesDir: options.projectMapNodesDir,
6979
- compositionsDir: options.compositionsDir,
6980
- rootContentTypes,
6981
- whatIf: options.whatIf ?? false,
6982
- strict: options.strict ?? false
6937
+ whatIf: options.whatIf ?? false
6983
6938
  });
6984
6939
  logger.success(
6985
6940
  `Created ${result.generatedCount} missing project map node(s). ${result.alreadyCoveredCount} ancestor path(s) already existed.`
@@ -6991,7 +6946,7 @@ function createGenerateMissingProjectMapNodesCommand() {
6991
6946
  // package.json
6992
6947
  var package_default = {
6993
6948
  name: "@uniformdev/transformer",
6994
- version: "1.1.40",
6949
+ version: "1.1.42",
6995
6950
  description: "CLI tool for transforming Uniform.dev serialization files offline",
6996
6951
  type: "module",
6997
6952
  bin: {
@@ -7073,6 +7028,9 @@ program.requiredOption("--rootDir <path>", "Path to the serialization project ro
7073
7028
  "Project map definitions directory name",
7074
7029
  "projectMapDefinition"
7075
7030
  ).option("--projectMapNodesDir <dir>", "Project map nodes directory name", "projectMapNode").option("--quirksDir <dir>", "Quirks directory name", "quirk");
7031
+ program.hook("preAction", (_thisCommand, actionCommand) => {
7032
+ console.error(`[INFO] ${actionCommand.name()} args: ${JSON.stringify(actionCommand.optsWithGlobals())}`);
7033
+ });
7076
7034
  program.addCommand(createPropagateRootComponentPropertyCommand());
7077
7035
  program.addCommand(createFindCompositionPatternCandidatesCommand());
7078
7036
  program.addCommand(createUnpackSerializationCommand());