@uniformdev/transformer 1.1.34 → 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);
@@ -4811,7 +4830,7 @@ function createRemoveParameterCommand() {
4811
4830
  aggregate.compositionPatternsModified += result.compositionPatternsModified;
4812
4831
  aggregate.componentPatternsModified += result.componentPatternsModified;
4813
4832
  } catch (error) {
4814
- if (hasWildcard && (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError)) {
4833
+ if (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError) {
4815
4834
  logger.warn(error.message);
4816
4835
  continue;
4817
4836
  }
@@ -5254,6 +5273,10 @@ function createAddComponentParameterCommand() {
5254
5273
  `${result.parameterReplaced ? "Replaced" : "Added"} parameter "${options.parameterId}" on component "${options.componentId}"`
5255
5274
  );
5256
5275
  } catch (error) {
5276
+ if (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError) {
5277
+ logger.warn(error.message);
5278
+ return;
5279
+ }
5257
5280
  if (error instanceof TransformError) {
5258
5281
  logger.error(error.message);
5259
5282
  process.exit(1);
@@ -5832,6 +5855,10 @@ function createFlattenBlockFieldCommand() {
5832
5855
  `Flattened parameter "${options.parameterId}" on component "${options.componentId}": ${result.compositionsModified} composition(s), ${result.compositionPatternsModified} composition pattern(s), ${result.componentPatternsModified} component pattern(s) updated`
5833
5856
  );
5834
5857
  } catch (error) {
5858
+ if (error instanceof ComponentNotFoundError || error instanceof PropertyNotFoundError) {
5859
+ logger.warn(error.message);
5860
+ return;
5861
+ }
5835
5862
  if (error instanceof TransformError) {
5836
5863
  logger.error(error.message);
5837
5864
  process.exit(1);
@@ -5842,10 +5869,171 @@ function createFlattenBlockFieldCommand() {
5842
5869
  return command;
5843
5870
  }
5844
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
+
5845
6033
  // package.json
5846
6034
  var package_default = {
5847
6035
  name: "@uniformdev/transformer",
5848
- version: "1.1.34",
6036
+ version: "1.1.35",
5849
6037
  description: "CLI tool for transforming Uniform.dev serialization files offline",
5850
6038
  type: "module",
5851
6039
  bin: {
@@ -5914,7 +6102,7 @@ var package_default = {
5914
6102
  };
5915
6103
 
5916
6104
  // src/cli/index.ts
5917
- var program = new Command16();
6105
+ var program = new Command17();
5918
6106
  var appVersion = package_default.version;
5919
6107
  console.error(`uniform-transform v${appVersion}`);
5920
6108
  program.name("uniform-transform").description("CLI tool for transforming Uniform.dev serialization files offline").version(appVersion);
@@ -5942,5 +6130,6 @@ program.addCommand(createRemoveFieldCommand());
5942
6130
  program.addCommand(createAddComponentParameterCommand());
5943
6131
  program.addCommand(createAddContentTypeFieldCommand());
5944
6132
  program.addCommand(createFlattenBlockFieldCommand());
6133
+ program.addCommand(createRemoveOrphanEntriesCommand());
5945
6134
  program.parse();
5946
6135
  //# sourceMappingURL=index.js.map