@uniformdev/transformer 1.1.33 → 1.1.35

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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli/index.ts
4
- import { Command as Command16 } from "commander";
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";
@@ -1686,6 +1686,10 @@ function createPropagateRootComponentPropertyCommand() {
1686
1686
  `Modified ${result.modifiedComponents} component, ${result.modifiedCompositions} compositions`
1687
1687
  );
1688
1688
  } catch (error) {
1689
+ if (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError) {
1690
+ logger.warn(error.message);
1691
+ return;
1692
+ }
1689
1693
  if (error instanceof TransformError) {
1690
1694
  logger.error(error.message);
1691
1695
  process.exit(1);
@@ -3215,6 +3219,10 @@ function createRenameSlotCommand() {
3215
3219
  `Renamed slot: ${result.compositionsModified} composition(s), ${result.compositionPatternsModified} composition pattern(s), ${result.componentPatternsModified} component pattern(s) updated`
3216
3220
  );
3217
3221
  } catch (error) {
3222
+ if (error instanceof ComponentNotFoundError) {
3223
+ logger.warn(error.message);
3224
+ return;
3225
+ }
3218
3226
  if (error instanceof TransformError) {
3219
3227
  logger.error(error.message);
3220
3228
  process.exit(1);
@@ -3492,6 +3500,10 @@ function createRenameComponentCommand() {
3492
3500
  `Renamed component: ${result.allowedComponentsUpdated} allowedComponents ref(s), ${result.compositionsModified} composition(s), ${result.compositionPatternsModified} composition pattern(s), ${result.componentPatternsModified} component pattern(s) updated`
3493
3501
  );
3494
3502
  } catch (error) {
3503
+ if (error instanceof ComponentNotFoundError) {
3504
+ logger.warn(error.message);
3505
+ return;
3506
+ }
3495
3507
  if (error instanceof TransformError) {
3496
3508
  logger.error(error.message);
3497
3509
  process.exit(1);
@@ -3603,16 +3615,7 @@ var ComponentAdderService = class {
3603
3615
  throw new TransformError("parentComponentType cannot be empty");
3604
3616
  }
3605
3617
  this.logger.info(`Validating new component: ${newComponentType}`);
3606
- try {
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
- }
3618
+ await this.componentService.loadComponent(fullComponentsDir, newComponentType, findOptions);
3616
3619
  let allowedComponentsUpdated = false;
3617
3620
  const resolvedParentTypes = [];
3618
3621
  for (const parentType of parentTypes) {
@@ -4042,6 +4045,10 @@ function createAddComponentCommand() {
4042
4045
  `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
4046
  );
4044
4047
  } catch (error) {
4048
+ if (error instanceof ComponentNotFoundError) {
4049
+ logger.warn(error.message);
4050
+ return;
4051
+ }
4045
4052
  if (error instanceof TransformError) {
4046
4053
  logger.error(error.message);
4047
4054
  process.exit(1);
@@ -4097,6 +4104,10 @@ function createAddComponentPatternCommand() {
4097
4104
  `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
4105
  );
4099
4106
  } catch (error) {
4107
+ if (error instanceof ComponentNotFoundError) {
4108
+ logger.warn(error.message);
4109
+ return;
4110
+ }
4100
4111
  if (error instanceof TransformError) {
4101
4112
  logger.error(error.message);
4102
4113
  process.exit(1);
@@ -4407,6 +4418,10 @@ function createPropagateRootComponentSlotCommand() {
4407
4418
  `Modified ${result.modifiedComponents} component(s), ${result.modifiedCompositions} composition(s)`
4408
4419
  );
4409
4420
  } catch (error) {
4421
+ if (error instanceof ComponentNotFoundError) {
4422
+ logger.warn(error.message);
4423
+ return;
4424
+ }
4410
4425
  if (error instanceof TransformError) {
4411
4426
  logger.error(error.message);
4412
4427
  process.exit(1);
@@ -4484,6 +4499,10 @@ function createConvertCompositionsToEntriesCommand() {
4484
4499
  `${result.contentTypesWritten} content type(s), ${result.entriesFromCompositions} entry(ies) from compositions${refInfo}${reusedInfo}${blocksInfo}`
4485
4500
  );
4486
4501
  } catch (error) {
4502
+ if (error instanceof ComponentNotFoundError) {
4503
+ logger.warn(error.message);
4504
+ return;
4505
+ }
4487
4506
  if (error instanceof TransformError) {
4488
4507
  logger.error(error.message);
4489
4508
  process.exit(1);
@@ -4766,7 +4785,28 @@ function createRemoveParameterCommand() {
4766
4785
  const fileSystem = new FileSystemService();
4767
4786
  const componentService = new ComponentService(fileSystem);
4768
4787
  const remover = new ParameterRemoverService(fileSystem, componentService, logger);
4769
- const componentTypes = options.componentType.split("|").map((t) => t.trim()).filter(Boolean);
4788
+ const rawTypes = options.componentType.split("|").map((t) => t.trim()).filter(Boolean);
4789
+ const hasWildcard = rawTypes.includes("*");
4790
+ let componentTypes;
4791
+ if (hasWildcard) {
4792
+ const fullComponentsDir = fileSystem.resolvePath(options.rootDir, options.componentsDir);
4793
+ let allFiles = [];
4794
+ try {
4795
+ allFiles = await fileSystem.findFiles(fullComponentsDir, "*.{json,yaml,yml}");
4796
+ } catch {
4797
+ }
4798
+ const allTypeNames = allFiles.map(
4799
+ (f) => fileSystem.getBasename(f).replace(/\.(json|yaml|yml)$/i, "")
4800
+ );
4801
+ const explicit = rawTypes.filter((t) => t !== "*");
4802
+ const seen = new Set(explicit.map((t) => t.toLowerCase()));
4803
+ componentTypes = [
4804
+ ...explicit,
4805
+ ...allTypeNames.filter((t) => !seen.has(t.toLowerCase()))
4806
+ ];
4807
+ } else {
4808
+ componentTypes = rawTypes;
4809
+ }
4770
4810
  const aggregate = {
4771
4811
  compositionsModified: 0,
4772
4812
  compositionPatternsModified: 0,
@@ -4774,20 +4814,28 @@ function createRemoveParameterCommand() {
4774
4814
  };
4775
4815
  try {
4776
4816
  for (const componentType of componentTypes) {
4777
- const result = await remover.remove({
4778
- rootDir: options.rootDir,
4779
- componentsDir: options.componentsDir,
4780
- compositionsDir: options.compositionsDir,
4781
- compositionPatternsDir: options.compositionPatternsDir,
4782
- componentPatternsDir: options.componentPatternsDir,
4783
- componentType,
4784
- parameterId: options.parameterId,
4785
- whatIf: options.whatIf ?? false,
4786
- strict: options.strict ?? false
4787
- });
4788
- aggregate.compositionsModified += result.compositionsModified;
4789
- aggregate.compositionPatternsModified += result.compositionPatternsModified;
4790
- aggregate.componentPatternsModified += result.componentPatternsModified;
4817
+ try {
4818
+ const result = await remover.remove({
4819
+ rootDir: options.rootDir,
4820
+ componentsDir: options.componentsDir,
4821
+ compositionsDir: options.compositionsDir,
4822
+ compositionPatternsDir: options.compositionPatternsDir,
4823
+ componentPatternsDir: options.componentPatternsDir,
4824
+ componentType,
4825
+ parameterId: options.parameterId,
4826
+ whatIf: options.whatIf ?? false,
4827
+ strict: options.strict ?? false
4828
+ });
4829
+ aggregate.compositionsModified += result.compositionsModified;
4830
+ aggregate.compositionPatternsModified += result.compositionPatternsModified;
4831
+ aggregate.componentPatternsModified += result.componentPatternsModified;
4832
+ } catch (error) {
4833
+ if (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError) {
4834
+ logger.warn(error.message);
4835
+ continue;
4836
+ }
4837
+ throw error;
4838
+ }
4791
4839
  }
4792
4840
  logger.success(
4793
4841
  `Removed parameter: ${aggregate.compositionsModified} composition(s), ${aggregate.compositionPatternsModified} composition pattern(s), ${aggregate.componentPatternsModified} component pattern(s) updated`
@@ -4814,6 +4862,7 @@ var FieldRemoverService = class {
4814
4862
  this.logger = logger;
4815
4863
  }
4816
4864
  compareIds(id1, id2, strict) {
4865
+ if (id2 === "*") return true;
4817
4866
  if (strict) {
4818
4867
  return id1 === id2;
4819
4868
  }
@@ -5047,7 +5096,8 @@ function createRemoveFieldCommand() {
5047
5096
  const fileSystem = new FileSystemService();
5048
5097
  const componentService = new ComponentService(fileSystem);
5049
5098
  const remover = new FieldRemoverService(fileSystem, componentService, logger);
5050
- const componentTypes = options.componentType.split("|").map((t) => t.trim()).filter(Boolean);
5099
+ const rawTypes = options.componentType.split("|").map((t) => t.trim()).filter(Boolean);
5100
+ const componentTypes = rawTypes.includes("*") ? ["*"] : rawTypes;
5051
5101
  const aggregate = {
5052
5102
  compositionsModified: 0,
5053
5103
  compositionPatternsModified: 0,
@@ -5223,6 +5273,10 @@ function createAddComponentParameterCommand() {
5223
5273
  `${result.parameterReplaced ? "Replaced" : "Added"} parameter "${options.parameterId}" on component "${options.componentId}"`
5224
5274
  );
5225
5275
  } catch (error) {
5276
+ if (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError) {
5277
+ logger.warn(error.message);
5278
+ return;
5279
+ }
5226
5280
  if (error instanceof TransformError) {
5227
5281
  logger.error(error.message);
5228
5282
  process.exit(1);
@@ -5801,6 +5855,10 @@ function createFlattenBlockFieldCommand() {
5801
5855
  `Flattened parameter "${options.parameterId}" on component "${options.componentId}": ${result.compositionsModified} composition(s), ${result.compositionPatternsModified} composition pattern(s), ${result.componentPatternsModified} component pattern(s) updated`
5802
5856
  );
5803
5857
  } catch (error) {
5858
+ if (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError) {
5859
+ logger.warn(error.message);
5860
+ return;
5861
+ }
5804
5862
  if (error instanceof TransformError) {
5805
5863
  logger.error(error.message);
5806
5864
  process.exit(1);
@@ -5811,10 +5869,171 @@ function createFlattenBlockFieldCommand() {
5811
5869
  return command;
5812
5870
  }
5813
5871
 
5872
+ // src/cli/commands/remove-orphan-entries.ts
5873
+ import { Command as Command16 } from "commander";
5874
+
5875
+ // src/core/services/orphan-entry-remover.service.ts
5876
+ var OrphanEntryRemoverService = class {
5877
+ constructor(fileSystem, logger) {
5878
+ this.fileSystem = fileSystem;
5879
+ this.logger = logger;
5880
+ }
5881
+ async remove(options) {
5882
+ const { rootDir, entriesDir, rootContentTypes, whatIf, strict } = options;
5883
+ const entriesDirFull = this.fileSystem.resolvePath(rootDir, entriesDir);
5884
+ const dirExists = await this.fileSystem.fileExists(entriesDirFull);
5885
+ if (!dirExists) {
5886
+ this.logger.warn(`Entries directory not found: ${entriesDir} \u2014 nothing to do`);
5887
+ return { totalEntries: 0, whitelistedEntries: 0, removedEntries: 0 };
5888
+ }
5889
+ const entryFiles = await this.fileSystem.findFiles(entriesDirFull, "**/*.{json,yaml,yml}");
5890
+ if (entryFiles.length === 0) {
5891
+ this.logger.warn("No entry files found \u2014 nothing to do");
5892
+ return { totalEntries: 0, whitelistedEntries: 0, removedEntries: 0 };
5893
+ }
5894
+ this.logger.info(`Loaded ${entryFiles.length} entry file(s)`);
5895
+ const entryMap = /* @__PURE__ */ new Map();
5896
+ for (const filePath of entryFiles) {
5897
+ let entryData;
5898
+ try {
5899
+ entryData = await this.fileSystem.readFile(filePath);
5900
+ } catch {
5901
+ this.logger.warn(`Could not read entry file: ${filePath} \u2014 skipping`);
5902
+ continue;
5903
+ }
5904
+ if (!entryData?.entry?._id) {
5905
+ this.logger.warn(`Entry file missing entry._id: ${filePath} \u2014 skipping`);
5906
+ continue;
5907
+ }
5908
+ entryMap.set(entryData.entry._id, { filePath, entryData });
5909
+ }
5910
+ this.logger.info(`Root content types: ${rootContentTypes.join(", ")}`);
5911
+ const whitelist = /* @__PURE__ */ new Set();
5912
+ for (const [entryId, { entryData }] of entryMap) {
5913
+ if (this.matchesContentType(entryData.entry.type, rootContentTypes, strict)) {
5914
+ whitelist.add(entryId);
5915
+ }
5916
+ }
5917
+ this.logger.info(`Whitelisted ${whitelist.size} entry(ies) from root content types`);
5918
+ let round = 0;
5919
+ let frontier = [...whitelist];
5920
+ while (frontier.length > 0) {
5921
+ round++;
5922
+ const nextFrontier = [];
5923
+ for (const entryId of frontier) {
5924
+ const entry = entryMap.get(entryId);
5925
+ if (!entry) continue;
5926
+ const referencedIds = this.extractReferencedEntryIds(entry.entryData);
5927
+ for (const refId of referencedIds) {
5928
+ if (!whitelist.has(refId) && entryMap.has(refId)) {
5929
+ whitelist.add(refId);
5930
+ nextFrontier.push(refId);
5931
+ }
5932
+ }
5933
+ }
5934
+ if (nextFrontier.length > 0) {
5935
+ this.logger.info(`BFS round ${round}: added ${nextFrontier.length} entry(ies) via references`);
5936
+ }
5937
+ frontier = nextFrontier;
5938
+ }
5939
+ this.logger.info(`BFS stable after ${round} round(s)`);
5940
+ let removedEntries = 0;
5941
+ for (const [entryId, { filePath, entryData }] of entryMap) {
5942
+ if (!whitelist.has(entryId)) {
5943
+ const relPath = this.fileSystem.joinPath(entriesDir, this.fileSystem.getBasename(filePath));
5944
+ this.logger.action(whatIf, "DELETE", `${relPath} (${entryData.entry.type})`);
5945
+ if (!whatIf) {
5946
+ this.fileSystem.deleteFile(filePath);
5947
+ }
5948
+ removedEntries++;
5949
+ }
5950
+ }
5951
+ return {
5952
+ totalEntries: entryMap.size,
5953
+ whitelistedEntries: whitelist.size,
5954
+ removedEntries
5955
+ };
5956
+ }
5957
+ extractReferencedEntryIds(entryData) {
5958
+ const ids = [];
5959
+ if (entryData.entry._dataResources) {
5960
+ for (const resource of Object.values(entryData.entry._dataResources)) {
5961
+ if (resource.type === "uniformContentInternalReference" && resource.variables?.entryIds) {
5962
+ const entryIds = resource.variables.entryIds.split(",").map((s) => s.trim()).filter(Boolean);
5963
+ ids.push(...entryIds);
5964
+ }
5965
+ }
5966
+ }
5967
+ if (entryData.entry.fields) {
5968
+ for (const field of Object.values(entryData.entry.fields)) {
5969
+ if (field.type === "contentReference" && Array.isArray(field.value)) {
5970
+ for (const id of field.value) {
5971
+ if (typeof id === "string") {
5972
+ ids.push(id);
5973
+ }
5974
+ }
5975
+ }
5976
+ }
5977
+ }
5978
+ return ids;
5979
+ }
5980
+ matchesContentType(entryType, rootContentTypes, strict) {
5981
+ for (const rootType of rootContentTypes) {
5982
+ if (strict) {
5983
+ if (entryType === rootType) return true;
5984
+ } else {
5985
+ if (entryType.toLowerCase() === rootType.toLowerCase()) return true;
5986
+ }
5987
+ }
5988
+ return false;
5989
+ }
5990
+ };
5991
+
5992
+ // src/cli/commands/remove-orphan-entries.ts
5993
+ function createRemoveOrphanEntriesCommand() {
5994
+ const command = new Command16("remove-orphan-entries");
5995
+ command.description(
5996
+ "Removes entry files that are not reachable from root content-type entries by following contentReference links transitively."
5997
+ ).option(
5998
+ "--rootContentTypes <types>",
5999
+ 'Pipe-separated list of content-type IDs whose entries are treated as roots and never deleted (e.g. "HomePage|BlogPost")'
6000
+ ).hook("preAction", (thisCommand) => {
6001
+ const opts = thisCommand.opts();
6002
+ const requiredOptions = [{ name: "rootContentTypes", flag: "--rootContentTypes" }];
6003
+ const missing = requiredOptions.filter((opt) => !opts[opt.name]).map((opt) => opt.flag);
6004
+ if (missing.length > 0) {
6005
+ console.error(`error: missing required options: ${missing.join(", ")}`);
6006
+ process.exit(1);
6007
+ }
6008
+ }).action(async (opts, cmd) => {
6009
+ const globalOpts = cmd.optsWithGlobals();
6010
+ const options = {
6011
+ ...globalOpts,
6012
+ rootContentTypes: opts.rootContentTypes
6013
+ };
6014
+ const logger = new Logger();
6015
+ logger.info(`rootContentTypes: ${options.rootContentTypes}`);
6016
+ const rootContentTypes = options.rootContentTypes.split("|").map((t) => t.trim()).filter(Boolean);
6017
+ const fileSystem = new FileSystemService();
6018
+ const service = new OrphanEntryRemoverService(fileSystem, logger);
6019
+ const result = await service.remove({
6020
+ rootDir: options.rootDir,
6021
+ entriesDir: options.entriesDir,
6022
+ rootContentTypes,
6023
+ whatIf: options.whatIf ?? false,
6024
+ strict: options.strict ?? false
6025
+ });
6026
+ logger.success(
6027
+ `Removed ${result.removedEntries} orphan entry(ies). ${result.whitelistedEntries} entry(ies) retained.`
6028
+ );
6029
+ });
6030
+ return command;
6031
+ }
6032
+
5814
6033
  // package.json
5815
6034
  var package_default = {
5816
6035
  name: "@uniformdev/transformer",
5817
- version: "1.1.33",
6036
+ version: "1.1.35",
5818
6037
  description: "CLI tool for transforming Uniform.dev serialization files offline",
5819
6038
  type: "module",
5820
6039
  bin: {
@@ -5883,7 +6102,7 @@ var package_default = {
5883
6102
  };
5884
6103
 
5885
6104
  // src/cli/index.ts
5886
- var program = new Command16();
6105
+ var program = new Command17();
5887
6106
  var appVersion = package_default.version;
5888
6107
  console.error(`uniform-transform v${appVersion}`);
5889
6108
  program.name("uniform-transform").description("CLI tool for transforming Uniform.dev serialization files offline").version(appVersion);
@@ -5911,5 +6130,6 @@ program.addCommand(createRemoveFieldCommand());
5911
6130
  program.addCommand(createAddComponentParameterCommand());
5912
6131
  program.addCommand(createAddContentTypeFieldCommand());
5913
6132
  program.addCommand(createFlattenBlockFieldCommand());
6133
+ program.addCommand(createRemoveOrphanEntriesCommand());
5914
6134
  program.parse();
5915
6135
  //# sourceMappingURL=index.js.map