@uniformdev/transformer 1.1.37 → 1.1.39

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 Command17 } from "commander";
4
+ import { Command as Command18 } from "commander";
5
5
 
6
6
  // src/cli/commands/propagate-root-component-property.ts
7
7
  import { Command } from "commander";
@@ -5910,6 +5910,7 @@ var BlockFieldFlattenerService = class {
5910
5910
  parameterId,
5911
5911
  whatIf,
5912
5912
  strict,
5913
+ excludeSet,
5913
5914
  "composition"
5914
5915
  );
5915
5916
  const compositionPatternsResult = await this.flattenInDirectory(
@@ -5918,6 +5919,7 @@ var BlockFieldFlattenerService = class {
5918
5919
  parameterId,
5919
5920
  whatIf,
5920
5921
  strict,
5922
+ excludeSet,
5921
5923
  "compositionPattern"
5922
5924
  );
5923
5925
  const componentPatternsResult = await this.flattenInDirectory(
@@ -5926,6 +5928,7 @@ var BlockFieldFlattenerService = class {
5926
5928
  parameterId,
5927
5929
  whatIf,
5928
5930
  strict,
5931
+ excludeSet,
5929
5932
  "componentPattern"
5930
5933
  );
5931
5934
  const totalFiles = compositionsResult.filesModified + compositionPatternsResult.filesModified + componentPatternsResult.filesModified;
@@ -6002,7 +6005,7 @@ var BlockFieldFlattenerService = class {
6002
6005
  }
6003
6006
  }
6004
6007
  }
6005
- async flattenInDirectory(directory, componentId, parameterId, whatIf, strict, label) {
6008
+ async flattenInDirectory(directory, componentId, parameterId, whatIf, strict, excludeSet, label) {
6006
6009
  let files;
6007
6010
  try {
6008
6011
  files = await this.fileSystem.findFiles(directory, "**/*.{json,yaml,yml}");
@@ -6020,8 +6023,8 @@ var BlockFieldFlattenerService = class {
6020
6023
  continue;
6021
6024
  }
6022
6025
  if (!composition?.composition) continue;
6023
- const treeCount = this.flattenBlocksInTree(composition.composition, componentId, parameterId, strict);
6024
- const overridesCount = this.flattenBlocksInOverrides(composition, componentId, parameterId, strict);
6026
+ const treeCount = this.flattenBlocksInTree(composition.composition, componentId, parameterId, strict, excludeSet);
6027
+ const overridesCount = this.flattenBlocksInOverrides(composition, componentId, parameterId, strict, excludeSet);
6025
6028
  const totalCount = treeCount + overridesCount;
6026
6029
  if (totalCount > 0) {
6027
6030
  const relativePath = filePath.replace(directory, "").replace(/^[/\\]/, "");
@@ -6039,7 +6042,7 @@ var BlockFieldFlattenerService = class {
6039
6042
  }
6040
6043
  return { filesModified, instancesUpdated };
6041
6044
  }
6042
- flattenBlocksInTree(node, componentId, parameterId, strict) {
6045
+ flattenBlocksInTree(node, componentId, parameterId, strict, excludeSet) {
6043
6046
  let count = 0;
6044
6047
  if (this.compareIds(node.type, componentId, strict) && node.parameters) {
6045
6048
  const matchingKey = this.findKeyName(node.parameters, parameterId, strict);
@@ -6049,7 +6052,9 @@ var BlockFieldFlattenerService = class {
6049
6052
  if (Array.isArray(items) && items.length === 1) {
6050
6053
  const blockItem = items[0];
6051
6054
  for (const [fieldId, fieldValue] of Object.entries(blockItem.fields ?? {})) {
6052
- node.parameters[fieldId] = fieldValue;
6055
+ if (!excludeSet.has(fieldId.toLowerCase())) {
6056
+ node.parameters[fieldId] = fieldValue;
6057
+ }
6053
6058
  }
6054
6059
  }
6055
6060
  delete node.parameters[matchingKey];
@@ -6060,28 +6065,29 @@ var BlockFieldFlattenerService = class {
6060
6065
  for (const slotInstances of Object.values(node.slots)) {
6061
6066
  if (!Array.isArray(slotInstances)) continue;
6062
6067
  for (const instance of slotInstances) {
6063
- count += this.flattenBlocksInTree(instance, componentId, parameterId, strict);
6068
+ count += this.flattenBlocksInTree(instance, componentId, parameterId, strict, excludeSet);
6064
6069
  }
6065
6070
  }
6066
6071
  }
6067
6072
  return count;
6068
6073
  }
6069
- flattenBlocksInOverrides(composition, componentId, parameterId, strict) {
6074
+ flattenBlocksInOverrides(composition, componentId, parameterId, strict, excludeSet) {
6070
6075
  if (!composition.composition._overrides) return 0;
6071
6076
  let count = 0;
6072
6077
  if (this.compareIds(composition.composition.type, componentId, strict)) {
6073
- count += this.flattenOverrideMap(composition.composition._overrides, parameterId, strict);
6078
+ count += this.flattenOverrideMap(composition.composition._overrides, parameterId, strict, excludeSet);
6074
6079
  }
6075
6080
  count += this.flattenOverridesForMatchingInstances(
6076
6081
  composition.composition,
6077
6082
  composition.composition._overrides,
6078
6083
  componentId,
6079
6084
  parameterId,
6080
- strict
6085
+ strict,
6086
+ excludeSet
6081
6087
  );
6082
6088
  return count;
6083
6089
  }
6084
- flattenOverrideMap(overrides, parameterId, strict) {
6090
+ flattenOverrideMap(overrides, parameterId, strict, excludeSet) {
6085
6091
  let count = 0;
6086
6092
  for (const override of Object.values(overrides)) {
6087
6093
  if (!override.parameters) continue;
@@ -6092,7 +6098,9 @@ var BlockFieldFlattenerService = class {
6092
6098
  if (Array.isArray(items) && items.length === 1) {
6093
6099
  const blockItem = items[0];
6094
6100
  for (const [fieldId, fieldValue] of Object.entries(blockItem.fields ?? {})) {
6095
- override.parameters[fieldId] = fieldValue;
6101
+ if (!excludeSet.has(fieldId.toLowerCase())) {
6102
+ override.parameters[fieldId] = fieldValue;
6103
+ }
6096
6104
  }
6097
6105
  }
6098
6106
  delete override.parameters[matchingKey];
@@ -6100,7 +6108,7 @@ var BlockFieldFlattenerService = class {
6100
6108
  }
6101
6109
  return count;
6102
6110
  }
6103
- flattenOverridesForMatchingInstances(node, overrides, componentId, parameterId, strict) {
6111
+ flattenOverridesForMatchingInstances(node, overrides, componentId, parameterId, strict, excludeSet) {
6104
6112
  let count = 0;
6105
6113
  if (node.slots) {
6106
6114
  for (const slotInstances of Object.values(node.slots)) {
@@ -6116,7 +6124,9 @@ var BlockFieldFlattenerService = class {
6116
6124
  if (Array.isArray(items) && items.length === 1) {
6117
6125
  const blockItem = items[0];
6118
6126
  for (const [fieldId, fieldValue] of Object.entries(blockItem.fields ?? {})) {
6119
- override.parameters[fieldId] = fieldValue;
6127
+ if (!excludeSet.has(fieldId.toLowerCase())) {
6128
+ override.parameters[fieldId] = fieldValue;
6129
+ }
6120
6130
  }
6121
6131
  }
6122
6132
  delete override.parameters[matchingKey];
@@ -6124,7 +6134,7 @@ var BlockFieldFlattenerService = class {
6124
6134
  }
6125
6135
  }
6126
6136
  }
6127
- count += this.flattenOverridesForMatchingInstances(instance, overrides, componentId, parameterId, strict);
6137
+ count += this.flattenOverridesForMatchingInstances(instance, overrides, componentId, parameterId, strict, excludeSet);
6128
6138
  }
6129
6139
  }
6130
6140
  }
@@ -6360,10 +6370,134 @@ function createRemoveOrphanEntriesCommand() {
6360
6370
  return command;
6361
6371
  }
6362
6372
 
6373
+ // src/cli/commands/remove-unused-content-types.ts
6374
+ import { Command as Command17 } from "commander";
6375
+
6376
+ // src/core/services/unused-content-type-remover.service.ts
6377
+ var UnusedContentTypeRemoverService = class {
6378
+ constructor(fileSystem, logger) {
6379
+ this.fileSystem = fileSystem;
6380
+ this.logger = logger;
6381
+ }
6382
+ async remove(options) {
6383
+ const { rootDir, contentTypesDir, entriesDir, whatIf, strict } = options;
6384
+ const contentTypesDirFull = this.fileSystem.resolvePath(rootDir, contentTypesDir);
6385
+ const entriesDirFull = this.fileSystem.resolvePath(rootDir, entriesDir);
6386
+ const ctDirExists = await this.fileSystem.fileExists(contentTypesDirFull);
6387
+ if (!ctDirExists) {
6388
+ this.logger.warn(`Content types directory not found: ${contentTypesDir} \u2014 nothing to do`);
6389
+ return { totalContentTypes: 0, removedContentTypes: 0, retainedContentTypes: 0 };
6390
+ }
6391
+ const ctFiles = await this.fileSystem.findFiles(contentTypesDirFull, "**/*.{json,yaml,yml}");
6392
+ if (ctFiles.length === 0) {
6393
+ this.logger.warn("No content type files found \u2014 nothing to do");
6394
+ return { totalContentTypes: 0, removedContentTypes: 0, retainedContentTypes: 0 };
6395
+ }
6396
+ this.logger.info(`Loaded ${ctFiles.length} content type file(s)`);
6397
+ const contentTypeMap = /* @__PURE__ */ new Map();
6398
+ for (const filePath of ctFiles) {
6399
+ let ct;
6400
+ try {
6401
+ ct = await this.fileSystem.readFile(filePath);
6402
+ } catch {
6403
+ this.logger.warn(`Could not read content type file: ${filePath} \u2014 skipping`);
6404
+ continue;
6405
+ }
6406
+ if (!ct?.id) {
6407
+ this.logger.warn(`Content type file missing id: ${filePath} \u2014 skipping`);
6408
+ continue;
6409
+ }
6410
+ contentTypeMap.set(filePath, { filePath, id: ct.id });
6411
+ }
6412
+ const usedTypeIds = /* @__PURE__ */ new Set();
6413
+ const entriesDirExists = await this.fileSystem.fileExists(entriesDirFull);
6414
+ if (!entriesDirExists) {
6415
+ this.logger.warn(`Entries directory not found: ${entriesDir} \u2014 treating all content types as unused`);
6416
+ } else {
6417
+ const entryFiles = await this.fileSystem.findFiles(entriesDirFull, "**/*.{json,yaml,yml}");
6418
+ this.logger.info(`Loaded ${entryFiles.length} entry file(s)`);
6419
+ for (const filePath of entryFiles) {
6420
+ let entryData;
6421
+ try {
6422
+ entryData = await this.fileSystem.readFile(filePath);
6423
+ } catch {
6424
+ this.logger.warn(`Could not read entry file: ${filePath} \u2014 skipping`);
6425
+ continue;
6426
+ }
6427
+ if (!entryData?.entry?.type) {
6428
+ continue;
6429
+ }
6430
+ usedTypeIds.add(entryData.entry.type);
6431
+ }
6432
+ }
6433
+ let removedContentTypes = 0;
6434
+ let retainedContentTypes = 0;
6435
+ for (const { filePath, id } of contentTypeMap.values()) {
6436
+ const isUsed = this.isUsed(id, usedTypeIds, strict);
6437
+ if (isUsed) {
6438
+ retainedContentTypes++;
6439
+ } else {
6440
+ const relPath = this.fileSystem.joinPath(
6441
+ contentTypesDir,
6442
+ this.fileSystem.getBasename(filePath)
6443
+ );
6444
+ this.logger.action(whatIf, "DELETE", relPath);
6445
+ if (!whatIf) {
6446
+ this.fileSystem.deleteFile(filePath);
6447
+ }
6448
+ removedContentTypes++;
6449
+ }
6450
+ }
6451
+ return {
6452
+ totalContentTypes: contentTypeMap.size,
6453
+ removedContentTypes,
6454
+ retainedContentTypes
6455
+ };
6456
+ }
6457
+ isUsed(contentTypeId, usedTypeIds, strict) {
6458
+ if (strict) {
6459
+ return usedTypeIds.has(contentTypeId);
6460
+ }
6461
+ const lower = contentTypeId.toLowerCase();
6462
+ for (const used of usedTypeIds) {
6463
+ if (used.toLowerCase() === lower) return true;
6464
+ }
6465
+ return false;
6466
+ }
6467
+ };
6468
+
6469
+ // src/cli/commands/remove-unused-content-types.ts
6470
+ function createRemoveUnusedContentTypesCommand() {
6471
+ const command = new Command17("remove-unused-content-types");
6472
+ command.description("Removes content type definition files that have zero entries referencing them.").action(async (_opts, cmd) => {
6473
+ const globalOpts = cmd.optsWithGlobals();
6474
+ const options = {
6475
+ ...globalOpts
6476
+ };
6477
+ const logger = new Logger();
6478
+ logger.info(`rootDir: ${options.rootDir}`);
6479
+ logger.info(`contentTypesDir: ${options.contentTypesDir}`);
6480
+ logger.info(`entriesDir: ${options.entriesDir}`);
6481
+ const fileSystem = new FileSystemService();
6482
+ const service = new UnusedContentTypeRemoverService(fileSystem, logger);
6483
+ const result = await service.remove({
6484
+ rootDir: options.rootDir,
6485
+ contentTypesDir: options.contentTypesDir,
6486
+ entriesDir: options.entriesDir,
6487
+ whatIf: options.whatIf ?? false,
6488
+ strict: options.strict ?? false
6489
+ });
6490
+ logger.success(
6491
+ `Removed ${result.removedContentTypes} unused content type(s). ${result.retainedContentTypes} content type(s) retained.`
6492
+ );
6493
+ });
6494
+ return command;
6495
+ }
6496
+
6363
6497
  // package.json
6364
6498
  var package_default = {
6365
6499
  name: "@uniformdev/transformer",
6366
- version: "1.1.37",
6500
+ version: "1.1.39",
6367
6501
  description: "CLI tool for transforming Uniform.dev serialization files offline",
6368
6502
  type: "module",
6369
6503
  bin: {
@@ -6432,7 +6566,7 @@ var package_default = {
6432
6566
  };
6433
6567
 
6434
6568
  // src/cli/index.ts
6435
- var program = new Command17();
6569
+ var program = new Command18();
6436
6570
  var appVersion = package_default.version;
6437
6571
  console.error(`uniform-transform v${appVersion}`);
6438
6572
  program.name("uniform-transform").description("CLI tool for transforming Uniform.dev serialization files offline").version(appVersion);
@@ -6461,5 +6595,6 @@ program.addCommand(createAddComponentParameterCommand());
6461
6595
  program.addCommand(createAddContentTypeFieldCommand());
6462
6596
  program.addCommand(createFlattenBlockFieldCommand());
6463
6597
  program.addCommand(createRemoveOrphanEntriesCommand());
6598
+ program.addCommand(createRemoveUnusedContentTypesCommand());
6464
6599
  program.parse();
6465
6600
  //# sourceMappingURL=index.js.map