@uniformdev/transformer 1.1.42 → 1.1.44

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 Command20 } from "commander";
4
+ import { Command as Command21 } from "commander";
5
5
 
6
6
  // src/cli/commands/propagate-root-component-property.ts
7
7
  import { Command } from "commander";
@@ -6908,12 +6908,12 @@ var GenerateMissingProjectMapNodesService = class {
6908
6908
  }
6909
6909
  pathToNodeId(nodePath) {
6910
6910
  if (nodePath === "/") return "pmn-group-root";
6911
- const slug = nodePath.split("/").filter((s) => s.length > 0).join("-");
6911
+ const slug = nodePath.split("/").filter((s) => s.length > 0).join("-").replace(/[\\:*?"<>|]/g, "_");
6912
6912
  return `pmn-group-${slug}`;
6913
6913
  }
6914
6914
  pathToFileName(nodePath) {
6915
6915
  if (nodePath === "/") return "root-node.yaml";
6916
- const slug = nodePath.split("/").filter((s) => s.length > 0).join("-");
6916
+ const slug = nodePath.split("/").filter((s) => s.length > 0).join("-").replace(/[\\:*?"<>|]/g, "_");
6917
6917
  return `${slug}-node.yaml`;
6918
6918
  }
6919
6919
  };
@@ -6943,10 +6943,208 @@ function createGenerateMissingProjectMapNodesCommand() {
6943
6943
  return command;
6944
6944
  }
6945
6945
 
6946
+ // src/cli/commands/split-content-type.ts
6947
+ import { Command as Command20 } from "commander";
6948
+
6949
+ // src/core/services/content-type-splitter.service.ts
6950
+ var ContentTypeSplitterService = class {
6951
+ constructor(fileSystem, logger) {
6952
+ this.fileSystem = fileSystem;
6953
+ this.logger = logger;
6954
+ }
6955
+ async split(options) {
6956
+ const {
6957
+ rootDir,
6958
+ contentTypesDir,
6959
+ entriesDir,
6960
+ contentType,
6961
+ newContentType,
6962
+ fieldId,
6963
+ fieldContains,
6964
+ whatIf,
6965
+ strict
6966
+ } = options;
6967
+ const ctDirFull = this.fileSystem.resolvePath(rootDir, contentTypesDir);
6968
+ const ctDirExists = await this.fileSystem.fileExists(ctDirFull);
6969
+ if (!ctDirExists) {
6970
+ this.logger.warn(`Content types directory not found: ${contentTypesDir}`);
6971
+ return { contentTypeCreated: false, entriesScanned: 0, entriesUpdated: 0 };
6972
+ }
6973
+ const ctFiles = await this.fileSystem.findFiles(ctDirFull, "**/*.{json,yaml,yml}");
6974
+ let sourceCtFilePath;
6975
+ let sourceCt;
6976
+ let newCtExists = false;
6977
+ for (const filePath of ctFiles) {
6978
+ let ct;
6979
+ try {
6980
+ ct = await this.fileSystem.readFile(filePath);
6981
+ } catch {
6982
+ this.logger.warn(`Could not read content type file: ${filePath} \u2014 skipping`);
6983
+ continue;
6984
+ }
6985
+ if (!ct?.id) continue;
6986
+ if (this.matchesId(ct.id, contentType, strict)) {
6987
+ sourceCtFilePath = filePath;
6988
+ sourceCt = ct;
6989
+ }
6990
+ if (this.matchesId(ct.id, newContentType, strict)) {
6991
+ newCtExists = true;
6992
+ }
6993
+ }
6994
+ if (!sourceCtFilePath || !sourceCt) {
6995
+ this.logger.warn(`Content type "${contentType}" not found in ${contentTypesDir}`);
6996
+ return { contentTypeCreated: false, entriesScanned: 0, entriesUpdated: 0 };
6997
+ }
6998
+ let contentTypeCreated = false;
6999
+ if (newCtExists) {
7000
+ this.logger.info(`Content type "${newContentType}" already exists \u2014 skipping creation`);
7001
+ } else {
7002
+ const newCt = {
7003
+ ...sourceCt,
7004
+ id: newContentType,
7005
+ name: newContentType
7006
+ };
7007
+ const ext = this.fileSystem.getExtension(sourceCtFilePath) || ".yaml";
7008
+ const newCtFilePath = this.fileSystem.resolvePath(ctDirFull, `${newContentType}${ext}`);
7009
+ const relPath = `${contentTypesDir}/${newContentType}${ext}`;
7010
+ this.logger.action(whatIf, "CREATE", relPath);
7011
+ if (!whatIf) {
7012
+ await this.fileSystem.writeFile(newCtFilePath, newCt);
7013
+ }
7014
+ contentTypeCreated = true;
7015
+ }
7016
+ const entriesDirFull = this.fileSystem.resolvePath(rootDir, entriesDir);
7017
+ const entriesDirExists = await this.fileSystem.fileExists(entriesDirFull);
7018
+ if (!entriesDirExists) {
7019
+ this.logger.warn(`Entries directory not found: ${entriesDir}`);
7020
+ return { contentTypeCreated, entriesScanned: 0, entriesUpdated: 0 };
7021
+ }
7022
+ const entryFiles = await this.fileSystem.findFiles(entriesDirFull, "**/*.{json,yaml,yml}");
7023
+ this.logger.info(`Scanning ${entryFiles.length} entry file(s)`);
7024
+ let entriesScanned = 0;
7025
+ let entriesUpdated = 0;
7026
+ for (const filePath of entryFiles) {
7027
+ let entryData;
7028
+ try {
7029
+ entryData = await this.fileSystem.readFile(filePath);
7030
+ } catch {
7031
+ this.logger.warn(`Could not read entry file: ${filePath} \u2014 skipping`);
7032
+ continue;
7033
+ }
7034
+ if (!entryData?.entry?.type) continue;
7035
+ if (!this.matchesId(entryData.entry.type, contentType, strict)) continue;
7036
+ entriesScanned++;
7037
+ const fields = entryData.entry.fields;
7038
+ if (!fields || typeof fields !== "object") {
7039
+ this.logger.warn(`Entry "${entryData.entry._id}" has no fields \u2014 skipping`);
7040
+ continue;
7041
+ }
7042
+ if (!(fieldId in fields)) {
7043
+ this.logger.warn(
7044
+ `Entry "${entryData.entry._id}" does not have field "${fieldId}" \u2014 skipping`
7045
+ );
7046
+ continue;
7047
+ }
7048
+ const field = fields[fieldId];
7049
+ const fieldValueStr = this.getFieldValueString(field);
7050
+ if (!this.containsValue(fieldValueStr, fieldContains, strict)) continue;
7051
+ const relPath = this.fileSystem.joinPath(
7052
+ entriesDir,
7053
+ this.fileSystem.getBasename(filePath)
7054
+ );
7055
+ this.logger.action(
7056
+ whatIf,
7057
+ "UPDATE",
7058
+ `${relPath}: type ${entryData.entry.type} \u2192 ${newContentType}`
7059
+ );
7060
+ if (!whatIf) {
7061
+ const updatedEntry = {
7062
+ ...entryData,
7063
+ entry: { ...entryData.entry, type: newContentType }
7064
+ };
7065
+ await this.fileSystem.writeFile(filePath, updatedEntry);
7066
+ }
7067
+ entriesUpdated++;
7068
+ }
7069
+ return { contentTypeCreated, entriesScanned, entriesUpdated };
7070
+ }
7071
+ matchesId(value, target, strict) {
7072
+ if (strict) return value === target;
7073
+ return value.toLowerCase() === target.toLowerCase();
7074
+ }
7075
+ containsValue(haystack, needle, strict) {
7076
+ if (strict) return haystack.includes(needle);
7077
+ return haystack.toLowerCase().includes(needle.toLowerCase());
7078
+ }
7079
+ getFieldValueString(field) {
7080
+ if (field === null || field === void 0) return "";
7081
+ if (typeof field === "string") return field;
7082
+ if (typeof field === "number" || typeof field === "boolean") return String(field);
7083
+ if (typeof field === "object") {
7084
+ const f = field;
7085
+ if (f.value !== void 0) return String(f.value);
7086
+ return JSON.stringify(f);
7087
+ }
7088
+ return String(field);
7089
+ }
7090
+ };
7091
+
7092
+ // src/cli/commands/split-content-type.ts
7093
+ function createSplitContentTypeCommand() {
7094
+ const command = new Command20("split-content-type");
7095
+ command.description(
7096
+ "Creates a new content type as a copy of an existing one, then reassigns matching entries to it."
7097
+ ).option("--contentType <type>", "Source content type ID to split").option("--newContentType <type>", "New content type ID to create").option("--fieldId <id>", "Field ID in entry.fields whose value is checked").option("--fieldContains <value>", "Substring to search for in the field value").hook("preAction", (thisCommand) => {
7098
+ const opts = thisCommand.opts();
7099
+ const requiredOptions = [
7100
+ { name: "contentType", flag: "--contentType" },
7101
+ { name: "newContentType", flag: "--newContentType" },
7102
+ { name: "fieldId", flag: "--fieldId" },
7103
+ { name: "fieldContains", flag: "--fieldContains" }
7104
+ ];
7105
+ const missing = requiredOptions.filter((opt) => !opts[opt.name]).map((opt) => opt.flag);
7106
+ if (missing.length > 0) {
7107
+ console.error(`error: missing required options: ${missing.join(", ")}`);
7108
+ process.exit(1);
7109
+ }
7110
+ }).action(async (opts, cmd) => {
7111
+ const globalOpts = cmd.optsWithGlobals();
7112
+ const options = {
7113
+ ...globalOpts,
7114
+ contentType: opts.contentType,
7115
+ newContentType: opts.newContentType,
7116
+ fieldId: opts.fieldId,
7117
+ fieldContains: opts.fieldContains
7118
+ };
7119
+ const logger = new Logger();
7120
+ logger.info(`contentType: ${options.contentType}`);
7121
+ logger.info(`newContentType: ${options.newContentType}`);
7122
+ logger.info(`fieldId: ${options.fieldId}`);
7123
+ logger.info(`fieldContains: ${options.fieldContains}`);
7124
+ const fileSystem = new FileSystemService();
7125
+ const service = new ContentTypeSplitterService(fileSystem, logger);
7126
+ const result = await service.split({
7127
+ rootDir: options.rootDir,
7128
+ contentTypesDir: options.contentTypesDir,
7129
+ entriesDir: options.entriesDir,
7130
+ contentType: options.contentType,
7131
+ newContentType: options.newContentType,
7132
+ fieldId: options.fieldId,
7133
+ fieldContains: options.fieldContains,
7134
+ whatIf: options.whatIf ?? false,
7135
+ strict: options.strict ?? false
7136
+ });
7137
+ logger.success(
7138
+ `Content type created: ${result.contentTypeCreated}. Entries scanned: ${result.entriesScanned}, updated: ${result.entriesUpdated}.`
7139
+ );
7140
+ });
7141
+ return command;
7142
+ }
7143
+
6946
7144
  // package.json
6947
7145
  var package_default = {
6948
7146
  name: "@uniformdev/transformer",
6949
- version: "1.1.42",
7147
+ version: "1.1.44",
6950
7148
  description: "CLI tool for transforming Uniform.dev serialization files offline",
6951
7149
  type: "module",
6952
7150
  bin: {
@@ -7015,7 +7213,7 @@ var package_default = {
7015
7213
  };
7016
7214
 
7017
7215
  // src/cli/index.ts
7018
- var program = new Command20();
7216
+ var program = new Command21();
7019
7217
  var appVersion = package_default.version;
7020
7218
  console.error(`uniform-transform v${appVersion}`);
7021
7219
  program.name("uniform-transform").description("CLI tool for transforming Uniform.dev serialization files offline").version(appVersion);
@@ -7050,5 +7248,6 @@ program.addCommand(createRemoveOrphanEntriesCommand());
7050
7248
  program.addCommand(createRemoveUnusedContentTypesCommand());
7051
7249
  program.addCommand(createRemoveUnusedComponentTypesCommand());
7052
7250
  program.addCommand(createGenerateMissingProjectMapNodesCommand());
7251
+ program.addCommand(createSplitContentTypeCommand());
7053
7252
  program.parse();
7054
7253
  //# sourceMappingURL=index.js.map