@celonis/content-cli 1.0.8 → 1.1.0

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.
@@ -57,7 +57,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
57
57
  });
58
58
  });
59
59
  }
60
- exportPackages(packageKeys, withDependencies = false) {
60
+ exportPackages(packageKeys, withDependencies) {
61
61
  return __awaiter(this, void 0, void 0, function* () {
62
62
  const queryParams = new URLSearchParams();
63
63
  packageKeys.forEach(packageKey => queryParams.append("packageKeys", packageKey));
@@ -67,7 +67,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
67
67
  });
68
68
  });
69
69
  }
70
- exportPackagesByVersions(packageKeysWithVersion, withDependencies = false) {
70
+ exportPackagesByVersions(packageKeysWithVersion, withDependencies) {
71
71
  return __awaiter(this, void 0, void 0, function* () {
72
72
  const queryParams = new URLSearchParams();
73
73
  packageKeysWithVersion.forEach(packageKeyByVersion => queryParams.append("packageKeysWithVersion", packageKeyByVersion));
@@ -13,7 +13,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
13
13
  if (v !== undefined) module.exports = v;
14
14
  }
15
15
  else if (typeof define === "function" && define.amd) {
16
- define(["require", "exports", "uuid", "form-data", "stream", "adm-zip", "./interfaces/batch-export-import.constants", "../../core/utils/file-service", "../../core/utils/logger", "../../core/utils/json", "../studio/api/package-api", "./api/batch-import-export-api", "./studio.service"], factory);
16
+ define(["require", "exports", "uuid", "form-data", "stream", "adm-zip", "./interfaces/batch-export-import.constants", "../../core/utils/file-service", "../../core/utils/logger", "../../core/utils/json", "../studio/api/package-api", "./api/batch-import-export-api", "./studio.service", "../../core/git-profile/git/git.service", "node:fs"], factory);
17
17
  }
18
18
  })(function (require, exports) {
19
19
  "use strict";
@@ -30,11 +30,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
30
30
  const package_api_1 = require("../studio/api/package-api");
31
31
  const batch_import_export_api_1 = require("./api/batch-import-export-api");
32
32
  const studio_service_1 = require("./studio.service");
33
+ const git_service_1 = require("../../core/git-profile/git/git.service");
34
+ const fs = require("node:fs");
33
35
  class BatchImportExportService {
34
36
  constructor(context) {
35
37
  this.batchImportExportApi = new batch_import_export_api_1.BatchImportExportApi(context);
36
38
  this.studioPackageApi = new package_api_1.PackageApi(context);
37
39
  this.studioService = new studio_service_1.StudioService(context);
40
+ this.gitService = new git_service_1.GitService(context);
38
41
  }
39
42
  listActivePackages(flavors) {
40
43
  return __awaiter(this, void 0, void 0, function* () {
@@ -57,7 +60,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
57
60
  this.exportListOfPackages(packagesToExport);
58
61
  });
59
62
  }
60
- batchExportPackages(packageKeys, packageKeysByVersion, withDependencies = false) {
63
+ batchExportPackages(packageKeys, packageKeysByVersion, withDependencies, gitBranch) {
61
64
  return __awaiter(this, void 0, void 0, function* () {
62
65
  let exportedPackagesData;
63
66
  if (packageKeys) {
@@ -86,10 +89,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
86
89
  }
87
90
  }
88
91
  });
89
- const fileDownloadedMessage = "File downloaded successfully. New filename: ";
90
- const filename = `export_${(0, uuid_1.v4)()}.zip`;
91
- exportedPackagesZip.writeZip(filename);
92
- logger_1.logger.info(fileDownloadedMessage + filename);
92
+ if (gitBranch) {
93
+ const extractedDirectory = file_service_1.fileService.extractExportedZipWithNestedZips(exportedPackagesZip);
94
+ yield this.gitService.pushToBranch(extractedDirectory, gitBranch);
95
+ logger_1.logger.info("Successfully exported packages to branch: " + gitBranch);
96
+ }
97
+ else {
98
+ const fileDownloadedMessage = "File downloaded successfully. New filename: ";
99
+ const filename = `export_${(0, uuid_1.v4)()}.zip`;
100
+ exportedPackagesZip.writeZip(filename);
101
+ logger_1.logger.info(fileDownloadedMessage + filename);
102
+ }
93
103
  });
94
104
  }
95
105
  batchExportPackagesMetadata(packageKeys, jsonResponse) {
@@ -105,9 +115,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
105
115
  }
106
116
  });
107
117
  }
108
- batchImportPackages(file, overwrite) {
118
+ batchImportPackages(file, overwrite, gitBranch) {
109
119
  return __awaiter(this, void 0, void 0, function* () {
110
- let configs = new AdmZip(file);
120
+ let fileToBeImported;
121
+ if (gitBranch) {
122
+ fileToBeImported = yield this.gitService.pullFromBranch(gitBranch);
123
+ fileToBeImported = file_service_1.fileService.zipDirectoryInBatchExportFormat(fileToBeImported);
124
+ }
125
+ else {
126
+ fileToBeImported = file;
127
+ }
128
+ let configs = new AdmZip(fileToBeImported);
111
129
  const studioManifests = this.parseEntryData(configs, batch_export_import_constants_1.BatchExportImportConstants.STUDIO_FILE_NAME);
112
130
  const variablesManifests = this.parseEntryData(configs, batch_export_import_constants_1.BatchExportImportConstants.VARIABLES_FILE_NAME);
113
131
  configs = yield this.studioService.mapSpaces(configs, studioManifests);
@@ -115,6 +133,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
115
133
  const formData = this.buildBodyForImport(configs, variablesManifests);
116
134
  const postPackageImportData = yield this.batchImportExportApi.importPackages(formData, overwrite);
117
135
  yield this.studioService.processImportedPackages(configs, existingStudioPackages, studioManifests);
136
+ if (gitBranch) {
137
+ fs.rmSync(fileToBeImported);
138
+ }
118
139
  const reportFileName = "config_import_report_" + (0, uuid_1.v4)() + ".json";
119
140
  file_service_1.fileService.writeToFileWithGivenName(JSON.stringify(postPackageImportData), reportFileName);
120
141
  logger_1.logger.info("Config import report file: " + reportFileName);
@@ -52,14 +52,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
52
52
  }
53
53
  });
54
54
  }
55
- batchExportPackages(packageKeys, packageKeysByVersion, withDependencies = false) {
56
- return this.batchImportExportService.batchExportPackages(packageKeys, packageKeysByVersion, withDependencies);
55
+ batchExportPackages(packageKeys, packageKeysByVersion, withDependencies, gitBranch) {
56
+ return this.batchImportExportService.batchExportPackages(packageKeys, packageKeysByVersion, withDependencies, gitBranch);
57
57
  }
58
58
  batchExportPackagesMetadata(packageKeys, jsonResponse) {
59
59
  return this.batchImportExportService.batchExportPackagesMetadata(packageKeys, jsonResponse);
60
60
  }
61
- batchImportPackages(file, overwrite) {
62
- return this.batchImportExportService.batchImportPackages(file, overwrite);
61
+ batchImportPackages(file, overwrite, gitBranch) {
62
+ if (file && gitBranch) {
63
+ throw new Error("You cannot use both file and gitBranch options at the same time. Only one import source can be defined.");
64
+ }
65
+ if (!file && !gitBranch) {
66
+ throw new Error("You must provide either a file or a gitBranch option to import packages.");
67
+ }
68
+ return this.batchImportExportService.batchImportPackages(file, overwrite, gitBranch);
63
69
  }
64
70
  diffPackages(file, hasChanges, jsonResponse) {
65
71
  return this.diffService.diffPackages(file, hasChanges, jsonResponse);
@@ -40,6 +40,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
40
40
  .option("--packageKeys <packageKeys...>", "Keys of packages to export. Exports the latest deployed version only")
41
41
  .option("--keysByVersion <keysByVersion...>", "Keys of packages to export by version")
42
42
  .option("--withDependencies", "Include variables and dependencies", "")
43
+ .betaOption("--gitProfile <gitProfile>", "Git profile which you want to use for the Git operations")
44
+ .betaOption("--gitBranch <gitBranch>", "Git branch in which you want to push the exported file")
43
45
  .action(this.batchExportPackages);
44
46
  const metadataCommand = configCommand.command("metadata")
45
47
  .description("Commands related to package metadata");
@@ -52,7 +54,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
52
54
  configCommand.command("import")
53
55
  .description("Command to import package configs")
54
56
  .option("--overwrite", "Flag to allow overwriting of packages")
55
- .requiredOption("-f, --file <file>", "Exported packages file (relative path)")
57
+ .betaOption("--gitProfile <gitProfile>", "Git profile which you want to use for the Git operations")
58
+ .betaOption("--gitBranch <gitBranch>", "Git branch from which you want to pull the exported file and import")
59
+ .option("-f, --file <file>", "Exported packages file (relative path)")
56
60
  .action(this.batchImportPackages);
57
61
  configCommand.command("diff")
58
62
  .description("Command to diff configs of packages")
@@ -82,11 +86,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
82
86
  });
83
87
  }
84
88
  batchExportPackages(context, command, options) {
89
+ var _a;
85
90
  return __awaiter(this, void 0, void 0, function* () {
86
91
  if ((options.packageKeys && options.keysByVersion) || (!options.packageKeys && !options.keysByVersion)) {
87
92
  throw new Error("Please provide either --packageKeys or --keysByVersion, but not both.");
88
93
  }
89
- yield new config_command_service_1.ConfigCommandService(context).batchExportPackages(options.packageKeys, options.keysByVersion, options.withDependencies);
94
+ options.withDependencies = (_a = options.withDependencies) !== null && _a !== void 0 ? _a : false;
95
+ yield new config_command_service_1.ConfigCommandService(context).batchExportPackages(options.packageKeys, options.keysByVersion, options.withDependencies, options.gitBranch);
90
96
  });
91
97
  }
92
98
  batchExportPackagesMetadata(context, command, options) {
@@ -96,7 +102,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
96
102
  }
97
103
  batchImportPackages(context, command, options) {
98
104
  return __awaiter(this, void 0, void 0, function* () {
99
- yield new config_command_service_1.ConfigCommandService(context).batchImportPackages(options.file, options.overwrite);
105
+ yield new config_command_service_1.ConfigCommandService(context).batchImportPackages(options.file, options.overwrite, options.gitBranch);
100
106
  });
101
107
  }
102
108
  diffPackages(context, command, options) {
@@ -0,0 +1,87 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ (function (factory) {
11
+ if (typeof module === "object" && typeof module.exports === "object") {
12
+ var v = factory(require, exports);
13
+ if (v !== undefined) module.exports = v;
14
+ }
15
+ else if (typeof define === "function" && define.amd) {
16
+ define(["require", "exports", "../../core/utils/question.service", "../../core/utils/logger", "../../core/git-profile/git-profile.service", "../../core/git-profile/git-profile.interface"], factory);
17
+ }
18
+ })(function (require, exports) {
19
+ "use strict";
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.GitProfileCommandService = void 0;
22
+ const question_service_1 = require("../../core/utils/question.service");
23
+ const logger_1 = require("../../core/utils/logger");
24
+ const git_profile_service_1 = require("../../core/git-profile/git-profile.service");
25
+ const git_profile_interface_1 = require("../../core/git-profile/git-profile.interface");
26
+ class GitProfileCommandService {
27
+ constructor() {
28
+ this.gitProfileService = new git_profile_service_1.GitProfileService();
29
+ }
30
+ createProfile(setAsDefault) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ const profile = {};
33
+ const questions = new question_service_1.QuestionService();
34
+ try {
35
+ profile.name = yield questions.ask("Name of the Git profile to create: ");
36
+ profile.username = yield questions.ask("Your Git username: ");
37
+ profile.repository = yield questions.ask("Your repository (format: repoOwner/repoName): ");
38
+ const type = yield questions.ask("Authentication type: PAT (1), SSH token (2): ");
39
+ switch (type) {
40
+ case "1":
41
+ profile.authenticationType = git_profile_interface_1.AuthenticationType.PAT;
42
+ profile.token = yield questions.ask("Your Personal Access Token (PAT): ");
43
+ break;
44
+ case "2":
45
+ profile.authenticationType = git_profile_interface_1.AuthenticationType.SSH;
46
+ break;
47
+ default:
48
+ logger_1.logger.error(new logger_1.FatalError("Invalid type"));
49
+ break;
50
+ }
51
+ // possibly check if the user has sent a valid token that has access in the repository
52
+ this.gitProfileService.storeProfile(profile);
53
+ if (setAsDefault) {
54
+ yield this.makeDefaultProfile(profile.name);
55
+ }
56
+ }
57
+ finally {
58
+ yield questions.close();
59
+ }
60
+ logger_1.logger.info("Git Profile created successfully!");
61
+ });
62
+ }
63
+ listProfiles() {
64
+ return __awaiter(this, void 0, void 0, function* () {
65
+ const profiles = this.gitProfileService.readAllProfiles();
66
+ const defaultProfile = this.gitProfileService.getDefaultProfile();
67
+ if (profiles) {
68
+ profiles.forEach(profile => {
69
+ if (defaultProfile && defaultProfile === profile) {
70
+ logger_1.logger.info(profile + " (default)");
71
+ }
72
+ else {
73
+ logger_1.logger.info(profile);
74
+ }
75
+ });
76
+ }
77
+ });
78
+ }
79
+ makeDefaultProfile(profile) {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ yield this.gitProfileService.makeDefaultProfile(profile);
82
+ logger_1.logger.info("Default Git profile: " + profile);
83
+ });
84
+ }
85
+ }
86
+ exports.GitProfileCommandService = GitProfileCommandService;
87
+ });
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Commands to create and list access profiles.
3
+ */
4
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6
+ return new (P || (P = Promise))(function (resolve, reject) {
7
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
9
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
11
+ });
12
+ };
13
+ (function (factory) {
14
+ if (typeof module === "object" && typeof module.exports === "object") {
15
+ var v = factory(require, exports);
16
+ if (v !== undefined) module.exports = v;
17
+ }
18
+ else if (typeof define === "function" && define.amd) {
19
+ define(["require", "exports", "../../core/command/module-handler", "./git-profile-command.service"], factory);
20
+ }
21
+ })(function (require, exports) {
22
+ "use strict";
23
+ const module_handler_1 = require("../../core/command/module-handler");
24
+ const git_profile_command_service_1 = require("./git-profile-command.service");
25
+ class Module extends module_handler_1.IModule {
26
+ register(context, configurator) {
27
+ const gitCommand = configurator.command("git")
28
+ .beta()
29
+ .description("Commands related to Git settings");
30
+ const gitProfileCommand = gitCommand.command("profile")
31
+ .beta()
32
+ .description("Manage Git profiles required to use git-related operations.");
33
+ gitProfileCommand.command("list")
34
+ .description("Command to list all stored Git profiles")
35
+ .beta()
36
+ .action(this.listProfiles);
37
+ gitProfileCommand.command("create")
38
+ .description("Command to create a new Git profile")
39
+ .option("--setAsDefault", "Set this Git profile as default")
40
+ .beta()
41
+ .action(this.createProfile);
42
+ gitProfileCommand.command("default <profile>")
43
+ .description("Command to set a Git profile as default")
44
+ .beta()
45
+ .action(this.defaultProfile);
46
+ }
47
+ defaultProfile(context, command) {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ const profile = command.args[0];
50
+ yield new git_profile_command_service_1.GitProfileCommandService().makeDefaultProfile(profile);
51
+ });
52
+ }
53
+ createProfile(context, command, options) {
54
+ return __awaiter(this, void 0, void 0, function* () {
55
+ yield new git_profile_command_service_1.GitProfileCommandService().createProfile(options.setAsDefault);
56
+ });
57
+ }
58
+ listProfiles(context, command) {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ yield new git_profile_command_service_1.GitProfileCommandService().listProfiles();
61
+ });
62
+ }
63
+ }
64
+ return Module;
65
+ });
@@ -13,7 +13,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
13
13
  if (v !== undefined) module.exports = v;
14
14
  }
15
15
  else if (typeof define === "function" && define.amd) {
16
- define(["require", "exports", "../http/http-client", "../profile/profile.service", "../utils/logger"], factory);
16
+ define(["require", "exports", "../http/http-client", "../profile/profile.service", "../utils/logger", "../git-profile/git-profile.service"], factory);
17
17
  }
18
18
  })(function (require, exports) {
19
19
  "use strict";
@@ -22,6 +22,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
22
22
  const http_client_1 = require("../http/http-client");
23
23
  const profile_service_1 = require("../profile/profile.service");
24
24
  const logger_1 = require("../utils/logger");
25
+ const git_profile_service_1 = require("../git-profile/git-profile.service");
25
26
  /**
26
27
  * The execution context object is passed to the modules to access
27
28
  * foundational services such as APIs, profiles, logging etc. It is
@@ -31,7 +32,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
31
32
  constructor(options) {
32
33
  this.log = logger_1.logger;
33
34
  this.profileService = new profile_service_1.ProfileService();
35
+ this.gitProfileService = new git_profile_service_1.GitProfileService();
34
36
  this.profileName = options.profile;
37
+ this.gitProfileName = options.gitProfile;
35
38
  }
36
39
  get httpClient() {
37
40
  if (!this._httpClient) {
@@ -42,6 +45,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
42
45
  init() {
43
46
  return __awaiter(this, void 0, void 0, function* () {
44
47
  yield this.loadProfile(this.profileName);
48
+ yield this.loadGitProfile(this.gitProfileName);
45
49
  if (this.profile) {
46
50
  // only if a profile is available, it makes sense to provide an initialized
47
51
  // HttpClient API.
@@ -70,6 +74,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
70
74
  }
71
75
  });
72
76
  }
77
+ loadGitProfile(gitProfileName) {
78
+ return __awaiter(this, void 0, void 0, function* () {
79
+ if (!gitProfileName) {
80
+ this.log.debug("Git Profile name not specified, using default profile");
81
+ gitProfileName = this.gitProfileService.getDefaultProfile();
82
+ if (!gitProfileName) {
83
+ this.log.debug("A default Git profile is not configured.");
84
+ }
85
+ }
86
+ try {
87
+ this.gitProfile = yield this.gitProfileService.findProfile(gitProfileName);
88
+ this.gitProfileName = gitProfileName;
89
+ this.log.debug(`Using Git profile ${gitProfileName}`);
90
+ }
91
+ catch (err) {
92
+ this.gitProfile = undefined;
93
+ this.gitProfileName = undefined;
94
+ }
95
+ });
96
+ }
73
97
  }
74
98
  exports.Context = Context;
75
99
  });
@@ -0,0 +1,125 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ (function (factory) {
11
+ if (typeof module === "object" && typeof module.exports === "object") {
12
+ var v = factory(require, exports);
13
+ if (v !== undefined) module.exports = v;
14
+ }
15
+ else if (typeof define === "function" && define.amd) {
16
+ define(["require", "exports", "simple-git", "../../utils/logger", "fs", "path", "node:os", "uuid"], factory);
17
+ }
18
+ })(function (require, exports) {
19
+ "use strict";
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.GitService = void 0;
22
+ const simple_git_1 = require("simple-git");
23
+ const logger_1 = require("../../utils/logger");
24
+ const fs = require("fs");
25
+ const path = require("path");
26
+ const os = require("node:os");
27
+ const uuid_1 = require("uuid");
28
+ class GitService {
29
+ constructor(context) {
30
+ this.gitProfile = context.gitProfile;
31
+ }
32
+ pullFromBranch(branch) {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ this.validateGitProfileExistence();
35
+ const repoUrl = this.getRepoUrl();
36
+ const targetDir = path.join(os.tmpdir(), `content-cli-${(0, uuid_1.v4)()}`);
37
+ fs.mkdirSync(targetDir, { recursive: true });
38
+ const git = (0, simple_git_1.default)();
39
+ try {
40
+ yield git.clone(repoUrl, targetDir, ["--branch", branch, "--single-branch"]);
41
+ }
42
+ catch (err) {
43
+ throw new Error(`Failed to pull from ${branch}: ${err}`);
44
+ }
45
+ this.cleanupGitDirectory(targetDir);
46
+ return targetDir;
47
+ });
48
+ }
49
+ pushToBranch(sourceDir, branch) {
50
+ var _a, _b;
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ this.validateGitProfileExistence();
53
+ const workingDir = path.join(os.tmpdir(), `content-cli-${(0, uuid_1.v4)()}`);
54
+ fs.mkdirSync(workingDir, { recursive: true });
55
+ const repoUrl = this.getRepoUrl();
56
+ const git = (0, simple_git_1.default)();
57
+ try {
58
+ yield git.clone(repoUrl, workingDir, ["--branch", "main"]);
59
+ const repoGit = (0, simple_git_1.default)({ baseDir: workingDir });
60
+ yield repoGit.addConfig("user.name", (_a = this.gitProfile.username) !== null && _a !== void 0 ? _a : "content-cli");
61
+ yield repoGit.addConfig("user.email", `${(_b = this.gitProfile.username) !== null && _b !== void 0 ? _b : "cli"}@users.noreply.github.com`);
62
+ yield this.cleanupNonGitFiles(workingDir);
63
+ yield this.checkoutOrCreateLocalBranch(repoGit, branch);
64
+ fs.cpSync(sourceDir, workingDir, { recursive: true });
65
+ yield repoGit.add("./*");
66
+ const status = yield repoGit.status();
67
+ if (status.files.length === 0) {
68
+ logger_1.logger.debug("No changes to commit.");
69
+ return;
70
+ }
71
+ const commitMessage = "Update from content-cli";
72
+ yield repoGit.commit(commitMessage);
73
+ yield repoGit.push(["--set-upstream", "origin", branch]);
74
+ }
75
+ catch (err) {
76
+ throw new Error(`Failed to push to ${branch}: ${err}`);
77
+ }
78
+ finally {
79
+ fs.rmSync(workingDir, { recursive: true, force: true });
80
+ }
81
+ });
82
+ }
83
+ cleanupNonGitFiles(workingDir) {
84
+ return __awaiter(this, void 0, void 0, function* () {
85
+ for (const entry of fs.readdirSync(workingDir)) {
86
+ if (entry !== ".git") {
87
+ fs.rmSync(path.join(workingDir, entry), { recursive: true, force: true });
88
+ }
89
+ }
90
+ });
91
+ }
92
+ checkoutOrCreateLocalBranch(git, branch) {
93
+ return __awaiter(this, void 0, void 0, function* () {
94
+ const branches = yield git.branch();
95
+ if (!branches.all.includes(`remotes/origin/${branch}`)) {
96
+ yield git.checkoutLocalBranch(branch);
97
+ }
98
+ else {
99
+ yield git.checkout(["-b", branch, "--track", `origin/${branch}`]);
100
+ }
101
+ });
102
+ }
103
+ getRepoUrl() {
104
+ const { authenticationType, repository, token, username } = this.gitProfile;
105
+ if (authenticationType === "SSH") {
106
+ return `git@github.com:${repository}.git`;
107
+ }
108
+ const safeUsername = encodeURIComponent(username !== null && username !== void 0 ? username : "git");
109
+ const safeToken = encodeURIComponent(token);
110
+ return `https://${safeUsername}:${safeToken}@github.com/${repository}.git`;
111
+ }
112
+ cleanupGitDirectory(repoDirectory) {
113
+ const gitPath = path.join(repoDirectory, ".git");
114
+ if (fs.existsSync(gitPath)) {
115
+ fs.rmSync(gitPath, { recursive: true, force: true });
116
+ }
117
+ }
118
+ validateGitProfileExistence() {
119
+ if (!this.gitProfile) {
120
+ throw new Error("No configured Git profile.");
121
+ }
122
+ }
123
+ }
124
+ exports.GitService = GitService;
125
+ });
@@ -0,0 +1,18 @@
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.AuthenticationType = void 0;
13
+ // tslint:disable-next-line:variable-name
14
+ exports.AuthenticationType = {
15
+ SSH: "SSH",
16
+ PAT: "Personal Access Token",
17
+ };
18
+ });
@@ -0,0 +1,133 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ (function (factory) {
11
+ if (typeof module === "object" && typeof module.exports === "object") {
12
+ var v = factory(require, exports);
13
+ if (v !== undefined) module.exports = v;
14
+ }
15
+ else if (typeof define === "function" && define.amd) {
16
+ define(["require", "exports", "path", "fs", "../utils/logger", "os", "./git-profile.interface", "./git-profile.validator"], factory);
17
+ }
18
+ })(function (require, exports) {
19
+ "use strict";
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.GitProfileService = void 0;
22
+ const path = require("path");
23
+ const fs = require("fs");
24
+ const logger_1 = require("../utils/logger");
25
+ const os = require("os");
26
+ const git_profile_interface_1 = require("./git-profile.interface");
27
+ const git_profile_validator_1 = require("./git-profile.validator");
28
+ class GitProfileService {
29
+ constructor() {
30
+ this.homedir = os.homedir();
31
+ this.gitProfileContainerPath = path.resolve(this.homedir, ".celonis-content-cli-git-profiles");
32
+ this.configContainer = path.resolve(this.gitProfileContainerPath, "config.json");
33
+ }
34
+ findProfile(profileName) {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ return new Promise((resolve, reject) => {
37
+ if (process.env.USERNAME && process.env.GIT_TOKEN && process.env.REPOSITORY) {
38
+ resolve(this.buildProfileFromEnvVariables());
39
+ }
40
+ else {
41
+ if (!profileName) {
42
+ reject(new Error("No profile was found"));
43
+ }
44
+ this.createProfileContainerIfNotExists();
45
+ const file = fs.readFileSync(path.resolve(this.gitProfileContainerPath, this.constructProfileFileName(profileName)), { encoding: "utf-8" });
46
+ const profile = JSON.parse(file);
47
+ resolve(profile);
48
+ }
49
+ });
50
+ });
51
+ }
52
+ makeDefaultProfile(profileName) {
53
+ return __awaiter(this, void 0, void 0, function* () {
54
+ return new Promise((resolve, reject) => {
55
+ this.findProfile(profileName)
56
+ .then((profile) => {
57
+ this.createProfileContainerIfNotExists();
58
+ this.storeConfig({ defaultProfile: profileName });
59
+ resolve(profile);
60
+ })
61
+ .catch(err => {
62
+ logger_1.logger.error(new logger_1.FatalError("Git Profile does not exit."));
63
+ reject(err);
64
+ });
65
+ });
66
+ });
67
+ }
68
+ getDefaultProfile() {
69
+ if (fs.existsSync(this.configContainer)) {
70
+ const config = JSON.parse(fs.readFileSync(this.configContainer, { encoding: "utf-8" }));
71
+ return config.defaultProfile;
72
+ }
73
+ else {
74
+ return null;
75
+ }
76
+ }
77
+ storeProfile(profile) {
78
+ this.createProfileContainerIfNotExists();
79
+ const newProfileFileName = this.constructProfileFileName(profile.name);
80
+ fs.writeFileSync(path.resolve(this.gitProfileContainerPath, newProfileFileName), JSON.stringify(profile), {
81
+ encoding: "utf-8",
82
+ });
83
+ }
84
+ buildProfileFromEnvVariables() {
85
+ return __awaiter(this, void 0, void 0, function* () {
86
+ const profileVariables = this.getProfileEnvVariables();
87
+ const profile = {
88
+ name: profileVariables.repository,
89
+ repository: profileVariables.repository,
90
+ token: profileVariables.apiToken,
91
+ authenticationType: git_profile_interface_1.AuthenticationType.SSH,
92
+ };
93
+ profile.authenticationType = yield git_profile_validator_1.GitProfileValidator.validateProfile(profile);
94
+ return profile;
95
+ });
96
+ }
97
+ storeConfig(config) {
98
+ fs.writeFileSync(this.configContainer, JSON.stringify(config), { encoding: "utf-8" });
99
+ }
100
+ createProfileContainerIfNotExists() {
101
+ if (!fs.existsSync(this.gitProfileContainerPath)) {
102
+ fs.mkdirSync(this.gitProfileContainerPath);
103
+ }
104
+ }
105
+ constructProfileFileName(profileName) {
106
+ return profileName + ".json";
107
+ }
108
+ readAllProfiles() {
109
+ let fileNames = [];
110
+ try {
111
+ if (fs.existsSync(this.gitProfileContainerPath)) {
112
+ fileNames = fs
113
+ // @ts-ignore
114
+ .readdirSync(this.gitProfileContainerPath, { withFileTypes: true })
115
+ .filter(dirent => !dirent.isDirectory() && dirent.name.endsWith(".json") && dirent.name !== "config.json")
116
+ .map(dirent => dirent.name.replace(".json", ""));
117
+ }
118
+ }
119
+ catch (err) {
120
+ logger_1.logger.error(new logger_1.FatalError(err));
121
+ }
122
+ return fileNames;
123
+ }
124
+ getProfileEnvVariables() {
125
+ return {
126
+ username: process.env.USERNAME,
127
+ token: process.env.GIT_TOKEN,
128
+ repository: process.env.REPOSITORY,
129
+ };
130
+ }
131
+ }
132
+ exports.GitProfileService = GitProfileService;
133
+ });
@@ -0,0 +1,46 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ (function (factory) {
11
+ if (typeof module === "object" && typeof module.exports === "object") {
12
+ var v = factory(require, exports);
13
+ if (v !== undefined) module.exports = v;
14
+ }
15
+ else if (typeof define === "function" && define.amd) {
16
+ define(["require", "exports", "../utils/logger", "./git-profile.interface"], factory);
17
+ }
18
+ })(function (require, exports) {
19
+ "use strict";
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.GitProfileValidator = void 0;
22
+ const logger_1 = require("../utils/logger");
23
+ const git_profile_interface_1 = require("./git-profile.interface");
24
+ class GitProfileValidator {
25
+ static validateProfile(gitProfile) {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ if (gitProfile.name == null) {
28
+ logger_1.logger.error(new logger_1.FatalError("The name can not be empty"));
29
+ }
30
+ if (gitProfile.username == null) {
31
+ logger_1.logger.error(new logger_1.FatalError("The username can not be empty"));
32
+ }
33
+ if (gitProfile.repository == null) {
34
+ logger_1.logger.error(new logger_1.FatalError("The repository can not be empty"));
35
+ }
36
+ if (gitProfile.authenticationType == null) {
37
+ logger_1.logger.error(new logger_1.FatalError("The authentication type can not be empty"));
38
+ }
39
+ if (gitProfile.authenticationType === git_profile_interface_1.AuthenticationType.PAT && gitProfile.token == null) {
40
+ logger_1.logger.error(new logger_1.FatalError("The token can not be empty for authentication with PAT"));
41
+ }
42
+ });
43
+ }
44
+ }
45
+ exports.GitProfileValidator = GitProfileValidator;
46
+ });
@@ -13,7 +13,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
13
13
  if (v !== undefined) module.exports = v;
14
14
  }
15
15
  else if (typeof define === "function" && define.amd) {
16
- define(["require", "exports", "fs", "path", "./logger"], factory);
16
+ define(["require", "exports", "fs", "path", "./logger", "adm-zip", "uuid", "node:os"], factory);
17
17
  }
18
18
  })(function (require, exports) {
19
19
  "use strict";
@@ -22,6 +22,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
22
22
  const fs = require("fs");
23
23
  const path = require("path");
24
24
  const logger_1 = require("./logger");
25
+ const AdmZip = require("adm-zip");
26
+ const uuid_1 = require("uuid");
27
+ const os = require("node:os");
25
28
  class FileService {
26
29
  writeToFileWithGivenName(data, filename) {
27
30
  fs.writeFileSync(path.resolve(process.cwd(), filename), this.getSerializedFileContent(data), {
@@ -43,6 +46,45 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
43
46
  }
44
47
  return fs.readFileSync(path.resolve(process.cwd(), filename), { encoding: "utf-8" });
45
48
  }
49
+ extractExportedZipWithNestedZips(zipFile) {
50
+ const tempDir = path.join(os.tmpdir(), `${(0, uuid_1.v4)()}`);
51
+ fs.mkdirSync(tempDir, { recursive: true });
52
+ zipFile.extractAllTo(tempDir, true);
53
+ const files = fs.readdirSync(tempDir);
54
+ for (const file of files) {
55
+ const innerZipPath = path.join(tempDir, file);
56
+ if (file.endsWith(".zip")) {
57
+ const nestedZip = new AdmZip(innerZipPath);
58
+ const nestedDir = innerZipPath.replace(/\.zip$/, "");
59
+ fs.mkdirSync(nestedDir, { recursive: true });
60
+ nestedZip.extractAllTo(nestedDir, true);
61
+ fs.rmSync(innerZipPath); // Optionally remove the inner zip
62
+ }
63
+ }
64
+ return tempDir;
65
+ }
66
+ zipDirectoryInBatchExportFormat(sourceDir) {
67
+ const files = fs.readdirSync(sourceDir);
68
+ const finalZip = new AdmZip();
69
+ files.forEach(file => {
70
+ const fullPath = path.join(sourceDir, file);
71
+ const stat = fs.statSync(fullPath);
72
+ if (stat.isDirectory()) {
73
+ const zip = new AdmZip();
74
+ zip.addLocalFolder(fullPath);
75
+ const zippedBuffer = zip.toBuffer();
76
+ finalZip.addFile(`${file}.zip`, zippedBuffer);
77
+ }
78
+ else if (stat.isFile()) {
79
+ finalZip.addLocalFile(fullPath);
80
+ }
81
+ });
82
+ const tempDir = path.join(os.tmpdir(), "content-cli-exports");
83
+ fs.mkdirSync(tempDir, { recursive: true });
84
+ const zipFilePath = path.join(tempDir, `export_${(0, uuid_1.v4)()}.zip`);
85
+ finalZip.writeZip(zipFilePath);
86
+ return zipFilePath;
87
+ }
46
88
  getSerializedFileContent(data) {
47
89
  return data;
48
90
  }
@@ -8,8 +8,8 @@ export declare class BatchImportExportApi {
8
8
  findAllActivePackages(flavors: string[], withDependencies?: boolean): Promise<PackageExportTransport[]>;
9
9
  findActivePackagesByVariableValue(flavors: string[], variableValue: string, variableType: string): Promise<PackageExportTransport[]>;
10
10
  findActivePackagesByKeys(packageKeys: string[], withDependencies?: boolean): Promise<PackageExportTransport[]>;
11
- exportPackages(packageKeys: string[], withDependencies?: boolean): Promise<Buffer>;
12
- exportPackagesByVersions(packageKeysWithVersion: string[], withDependencies?: boolean): Promise<Buffer>;
11
+ exportPackages(packageKeys: string[], withDependencies: boolean): Promise<Buffer>;
12
+ exportPackagesByVersions(packageKeysWithVersion: string[], withDependencies: boolean): Promise<Buffer>;
13
13
  batchExportPackagesMetadata(packageKeys: string[]): Promise<PackageMetadataExportTransport[]>;
14
14
  importPackages(data: FormData, overwrite: boolean): Promise<PostPackageImportData[]>;
15
15
  findVariablesWithValuesByPackageKeysAndVersion(packagesByKeyAndVersion: PackageKeyAndVersionPair[]): Promise<VariableManifestTransport[]>;
@@ -3,12 +3,13 @@ export declare class BatchImportExportService {
3
3
  private batchImportExportApi;
4
4
  private studioPackageApi;
5
5
  private studioService;
6
+ private gitService;
6
7
  constructor(context: Context);
7
8
  listActivePackages(flavors: string[]): Promise<void>;
8
9
  findAndExportListOfActivePackages(flavors: string[], packageKeys: string[], withDependencies: boolean): Promise<void>;
9
- batchExportPackages(packageKeys: string[], packageKeysByVersion: string[], withDependencies?: boolean): Promise<void>;
10
+ batchExportPackages(packageKeys: string[], packageKeysByVersion: string[], withDependencies: boolean, gitBranch: string): Promise<void>;
10
11
  batchExportPackagesMetadata(packageKeys: string[], jsonResponse: boolean): Promise<void>;
11
- batchImportPackages(file: string, overwrite: boolean): Promise<void>;
12
+ batchImportPackages(file: string, overwrite: boolean, gitBranch: string): Promise<void>;
12
13
  findAndExportListOfActivePackagesByVariableValue(flavors: string[], variableValue: string, variableType: string): Promise<void>;
13
14
  listActivePackagesByVariableValue(flavors: string[], variableValue: string, variableType: string): Promise<void>;
14
15
  private exportListOfPackages;
@@ -6,9 +6,9 @@ export declare class ConfigCommandService {
6
6
  constructor(context: Context);
7
7
  listActivePackages(jsonResponse: boolean, flavors: string[], withDependencies: boolean, packageKeys: string[], variableValue: string, variableType: string): Promise<void>;
8
8
  listVariables(jsonResponse: boolean, keysByVersion: string[], keysByVersionFile: string): Promise<void>;
9
- batchExportPackages(packageKeys: string[], packageKeysByVersion: string[], withDependencies?: boolean): Promise<void>;
9
+ batchExportPackages(packageKeys: string[], packageKeysByVersion: string[], withDependencies: boolean, gitBranch: string): Promise<void>;
10
10
  batchExportPackagesMetadata(packageKeys: string[], jsonResponse: boolean): Promise<void>;
11
- batchImportPackages(file: string, overwrite: boolean): Promise<void>;
11
+ batchImportPackages(file: string, overwrite: boolean, gitBranch: string): Promise<void>;
12
12
  diffPackages(file: string, hasChanges: boolean, jsonResponse: boolean): Promise<void>;
13
13
  private listPackagesByVariableValue;
14
14
  }
@@ -0,0 +1,6 @@
1
+ export declare class GitProfileCommandService {
2
+ private gitProfileService;
3
+ createProfile(setAsDefault: boolean): Promise<void>;
4
+ listProfiles(): Promise<void>;
5
+ makeDefaultProfile(profile: string): Promise<void>;
6
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Commands to create and list access profiles.
3
+ */
4
+ import { Configurator, IModule } from "../../core/command/module-handler";
5
+ import { Context } from "../../core/command/cli-context";
6
+ declare class Module extends IModule {
7
+ register(context: Context, configurator: Configurator): void;
8
+ private defaultProfile;
9
+ private createProfile;
10
+ private listProfiles;
11
+ }
12
+ export = Module;
@@ -1,5 +1,6 @@
1
1
  import { HttpClient } from "../http/http-client";
2
2
  import { Profile } from "../profile/profile.interface";
3
+ import { GitProfile } from "../git-profile/git-profile.interface";
3
4
  /**
4
5
  * The execution context object is passed to the modules to access
5
6
  * foundational services such as APIs, profiles, logging etc. It is
@@ -8,11 +9,15 @@ import { Profile } from "../profile/profile.interface";
8
9
  export declare class Context {
9
10
  _httpClient: HttpClient;
10
11
  profile: Profile;
12
+ gitProfile: GitProfile;
11
13
  private log;
12
14
  private profileName;
15
+ private gitProfileName;
13
16
  private profileService;
17
+ private gitProfileService;
14
18
  constructor(options: any);
15
19
  get httpClient(): HttpClient;
16
20
  init(): Promise<void>;
17
21
  private loadProfile;
22
+ private loadGitProfile;
18
23
  }
@@ -0,0 +1,12 @@
1
+ import { Context } from "../../command/cli-context";
2
+ export declare class GitService {
3
+ private readonly gitProfile;
4
+ constructor(context: Context);
5
+ pullFromBranch(branch: string): Promise<string>;
6
+ pushToBranch(sourceDir: string, branch: string): Promise<void>;
7
+ private cleanupNonGitFiles;
8
+ private checkoutOrCreateLocalBranch;
9
+ private getRepoUrl;
10
+ private cleanupGitDirectory;
11
+ private validateGitProfileExistence;
12
+ }
@@ -0,0 +1,11 @@
1
+ export interface GitProfile {
2
+ name: string;
3
+ username?: string;
4
+ repository: string;
5
+ token?: string;
6
+ authenticationType: AuthenticationType;
7
+ }
8
+ export type AuthenticationType = "SSH" | "Personal Access Token";
9
+ export declare const AuthenticationType: {
10
+ [key: string]: AuthenticationType;
11
+ };
@@ -0,0 +1,19 @@
1
+ import { GitProfile } from "./git-profile.interface";
2
+ export interface GitConfig {
3
+ defaultProfile: string;
4
+ }
5
+ export declare class GitProfileService {
6
+ private readonly homedir;
7
+ private readonly gitProfileContainerPath;
8
+ private readonly configContainer;
9
+ findProfile(profileName: string): Promise<GitProfile>;
10
+ makeDefaultProfile(profileName: string): Promise<GitProfile>;
11
+ getDefaultProfile(): string;
12
+ storeProfile(profile: GitProfile): void;
13
+ private buildProfileFromEnvVariables;
14
+ private storeConfig;
15
+ private createProfileContainerIfNotExists;
16
+ private constructProfileFileName;
17
+ readAllProfiles(): string[];
18
+ private getProfileEnvVariables;
19
+ }
@@ -0,0 +1,4 @@
1
+ import { GitProfile } from "./git-profile.interface";
2
+ export declare class GitProfileValidator {
3
+ static validateProfile(gitProfile: GitProfile): Promise<any>;
4
+ }
@@ -1,9 +1,12 @@
1
+ import AdmZip = require("adm-zip");
1
2
  export declare class FileService {
2
3
  static readonly fileDownloadedMessage = "File downloaded successfully. New filename: ";
3
4
  writeToFileWithGivenName(data: any, filename: string): void;
4
5
  createDirectoryWithGivenName(dirName: string): void;
5
6
  readFileToJson<T>(fileName: string): Promise<T>;
6
7
  readFile(filename: string): string;
8
+ extractExportedZipWithNestedZips(zipFile: AdmZip): string;
9
+ zipDirectoryInBatchExportFormat(sourceDir: string): string;
7
10
  private getSerializedFileContent;
8
11
  }
9
12
  export declare const fileService: FileService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celonis/content-cli",
3
- "version": "1.0.8",
3
+ "version": "1.1.0",
4
4
  "description": "CLI Tool to help manage content in Celonis Platform",
5
5
  "main": "content-cli.js",
6
6
  "bin": {
@@ -26,6 +26,7 @@
26
26
  "openid-client": "5.6.1",
27
27
  "hpagent": "1.2.0",
28
28
  "semver": "7.6.3",
29
+ "simple-git": "3.28.0",
29
30
  "valid-url": "1.0.9",
30
31
  "winston": "3.17.0",
31
32
  "yaml": "2.7.0"