@celonis/content-cli 1.7.0 → 1.8.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.
package/README.md CHANGED
@@ -72,8 +72,8 @@ Example, if you want to push a package from zipped file "interesting-package.zip
72
72
  content-cli push package -p my-dev-profile --spaceKey my-cool-space -f interesting-package.zip
73
73
  ```
74
74
 
75
- A more comprehensive list of Content CLI capabilities can be found on the following
76
- [documentation](https://github.com/celonis/content-cli/blob/master/DOCUMENTATION.md).
75
+ A comprehensive list of Content CLI capabilities can be found in the
76
+ [documentation](https://github.com/celonis/content-cli/tree/main/docs).
77
77
 
78
78
  You can still explore the full capabilities of Content CLI and the list of options for the different commands
79
79
  by using the `-h` option in your command.
@@ -159,14 +159,14 @@ npm i -g @celonis/content-cli
159
159
  ## Contributing
160
160
 
161
161
  We encourage public contributions! Please check
162
- [CONTRIBUTING.md](https://github.com/celonis/content-cli/blob/master/CONTRIBUTING.md) for details on our
162
+ [CONTRIBUTING.md](https://github.com/celonis/content-cli/blob/main/CONTRIBUTING.md) for details on our
163
163
  code of conduct.
164
164
 
165
- For details on command development, refer to the [How to Add a Command](https://github.com/celonis/content-cli/blob/master/docs/how-to-add-command.md) guide.
165
+ For details on command development, refer to the [How to Add a Command](https://github.com/celonis/content-cli/blob/main/docs/how-to-add-command.md) guide.
166
166
 
167
167
  ## License
168
168
 
169
169
  Copyright (c) 2021 Celonis SE
170
170
 
171
171
  This project is licensed under the MIT License -
172
- see [LICENSE](https://github.com/celonis/content-cli/blob/master/LICENSE) file for details.
172
+ see [LICENSE](https://github.com/celonis/content-cli/blob/main/LICENSE) file for details.
@@ -33,6 +33,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
33
33
  });
34
34
  });
35
35
  }
36
+ createVersion(packageKey, request) {
37
+ return __awaiter(this, void 0, void 0, function* () {
38
+ return this.httpClient()
39
+ .post(`/pacman/api/core/packages/${packageKey}/versions`, request)
40
+ .catch(e => {
41
+ throw new logger_1.FatalError(`Problem creating version for package '${packageKey}': ${e}`);
42
+ });
43
+ });
44
+ }
36
45
  }
37
46
  exports.PackageVersionApi = PackageVersionApi;
38
47
  });
@@ -9,4 +9,10 @@
9
9
  })(function (require, exports) {
10
10
  "use strict";
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.VersionBumpOption = void 0;
13
+ var VersionBumpOption;
14
+ (function (VersionBumpOption) {
15
+ VersionBumpOption["NONE"] = "NONE";
16
+ VersionBumpOption["PATCH"] = "PATCH";
17
+ })(VersionBumpOption || (exports.VersionBumpOption = VersionBumpOption = {}));
12
18
  });
@@ -79,6 +79,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
79
79
  .requiredOption("--packageVersion <packageVersion>", "Version of the package. Can be a specific version or \"LATEST\" keyword, which will return the most recently created version.")
80
80
  .option("--json", "Return the response as a JSON file")
81
81
  .action(this.getPackageVersion);
82
+ configVersionCommand.command("create")
83
+ .description("Create a new version for a package")
84
+ .requiredOption("--packageKey <packageKey>", "Identifier of the package")
85
+ .option("--packageVersion <packageVersion>", "Version string (required if versionBumpOption is NONE)")
86
+ .option("--versionBumpOption <versionBumpOption>", "Version bump option: NONE or PATCH", "NONE")
87
+ .option("--summaryOfChanges <summaryOfChanges>", "Summary of changes for this version")
88
+ .option("--nodeFilterKeys <nodeFilterKeys...>", "Node keys to include in the version. If omitted, all nodes of the package are included.")
89
+ .option("--json", "Return the response as a JSON file")
90
+ .action(this.createPackageVersion);
82
91
  const variablesCommand = configCommand.command("variables")
83
92
  .description("Commands related to variable configs");
84
93
  variablesCommand.command("list")
@@ -162,6 +171,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
162
171
  yield new package_version_command_service_1.PackageVersionCommandService(context).getPackageVersion(options.packageKey, options.packageVersion, options.json);
163
172
  });
164
173
  }
174
+ createPackageVersion(context, command, options) {
175
+ return __awaiter(this, void 0, void 0, function* () {
176
+ const hasExplicitVersion = !!options.packageVersion;
177
+ const hasVersionBump = options.versionBumpOption && options.versionBumpOption !== "NONE";
178
+ if (hasExplicitVersion && hasVersionBump) {
179
+ throw new Error("Please provide either --packageVersion or --versionBumpOption, but not both.");
180
+ }
181
+ if (!hasExplicitVersion && !hasVersionBump) {
182
+ throw new Error("Please provide either --packageVersion or --versionBumpOption PATCH.");
183
+ }
184
+ yield new package_version_command_service_1.PackageVersionCommandService(context).createPackageVersion(options.packageKey, options.packageVersion, options.versionBumpOption, options.summaryOfChanges, options.nodeFilterKeys, options.json);
185
+ });
186
+ }
165
187
  batchImportPackages(context, command, options) {
166
188
  return __awaiter(this, void 0, void 0, function* () {
167
189
  if (options.gitProfile && !options.gitBranch) {
@@ -29,6 +29,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
29
29
  yield this.packageVersionService.findPackageVersion(packageKey, version, jsonResponse);
30
30
  });
31
31
  }
32
+ createPackageVersion(packageKey, version, versionBumpOption, summaryOfChanges, nodeFilterKeys, jsonResponse) {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ yield this.packageVersionService.createPackageVersion(packageKey, version, versionBumpOption, summaryOfChanges, nodeFilterKeys, jsonResponse);
35
+ });
36
+ }
32
37
  }
33
38
  exports.PackageVersionCommandService = PackageVersionCommandService;
34
39
  });
@@ -40,6 +40,30 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
40
40
  }
41
41
  });
42
42
  }
43
+ createPackageVersion(packageKey, version, versionBumpOption, summaryOfChanges, nodeFilterKeys, jsonResponse) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ const request = {
46
+ version: version,
47
+ versionBumpOption: versionBumpOption,
48
+ summaryOfChanges: summaryOfChanges,
49
+ };
50
+ if (nodeFilterKeys && nodeFilterKeys.length > 0) {
51
+ request.nodeFilter = {
52
+ filterType: "INCLUDE",
53
+ keys: nodeFilterKeys,
54
+ };
55
+ }
56
+ const created = yield this.packageVersionApi.createVersion(packageKey, request);
57
+ if (jsonResponse) {
58
+ const filename = (0, uuid_1.v4)() + ".json";
59
+ file_service_1.fileService.writeToFileWithGivenName(JSON.stringify(created, null, 2), filename);
60
+ logger_1.logger.info(file_service_1.FileService.fileDownloadedMessage + filename);
61
+ }
62
+ else {
63
+ this.printPackageVersionCreatedTransport(created);
64
+ }
65
+ });
66
+ }
43
67
  printPackageVersionTransport(packageVersionTransport) {
44
68
  logger_1.logger.info(`Package Key: ${packageVersionTransport.packageKey}`);
45
69
  logger_1.logger.info(`Version: ${packageVersionTransport.version}`);
@@ -50,6 +74,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
50
74
  logger_1.logger.info(`Deployed: ${packageVersionTransport.deployed}`);
51
75
  logger_1.logger.info(`Published By: ${packageVersionTransport.publishedBy}`);
52
76
  }
77
+ printPackageVersionCreatedTransport(transport) {
78
+ logger_1.logger.info(`Successfully created version ${transport.version} for package ${transport.packageKey}`);
79
+ logger_1.logger.info(`Version: ${transport.version}`);
80
+ logger_1.logger.info(`Package Key: ${transport.packageKey}`);
81
+ logger_1.logger.info(`Summary of Changes: ${transport.summaryOfChanges}`);
82
+ logger_1.logger.info(`Creation Date: ${new Date(transport.creationDate).toISOString()}`);
83
+ logger_1.logger.info(`Created By: ${transport.createdBy}`);
84
+ }
53
85
  }
54
86
  exports.PackageVersionService = PackageVersionService;
55
87
  });
@@ -37,6 +37,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
37
37
  command.command("default <profile>")
38
38
  .description("Command to set a profile as default")
39
39
  .action(this.defaultProfile);
40
+ command.command("secure <profile>")
41
+ .description("Migrate a profile's secrets to secure system keychain storage")
42
+ .action(this.secureProfile);
40
43
  }
41
44
  defaultProfile(context, command) {
42
45
  return __awaiter(this, void 0, void 0, function* () {
@@ -55,6 +58,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
55
58
  yield new profile_command_service_1.ProfileCommandService().listProfiles();
56
59
  });
57
60
  }
61
+ secureProfile(context, command) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ const profile = command.args[0];
64
+ yield new profile_command_service_1.ProfileCommandService().secureProfile(profile);
65
+ });
66
+ }
58
67
  }
59
68
  return Module;
60
69
  });
@@ -55,7 +55,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
55
55
  }
56
56
  profile.authenticationType = yield profile_validator_1.ProfileValidator.validateProfile(profile);
57
57
  yield this.profileService.authorizeProfile(profile);
58
- this.profileService.storeProfile(profile);
58
+ yield this.profileService.storeProfile(profile);
59
59
  if (setAsDefault) {
60
60
  yield this.makeDefaultProfile(profile.name);
61
61
  }
@@ -89,6 +89,23 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
89
89
  logger_1.logger.info("Default profile: " + profile);
90
90
  });
91
91
  }
92
+ secureProfile(profileName) {
93
+ return __awaiter(this, void 0, void 0, function* () {
94
+ const profile = yield this.profileService.findProfile(profileName);
95
+ if (profile.secretsStoredSecurely) {
96
+ logger_1.logger.info(`Profile "${profileName}" is already using secure storage.`);
97
+ return;
98
+ }
99
+ yield this.profileService.storeProfile(profile);
100
+ const updatedProfile = yield this.profileService.findProfile(profileName);
101
+ if (updatedProfile.secretsStoredSecurely) {
102
+ logger_1.logger.info(`Profile "${profileName}" secrets have been migrated to secure storage.`);
103
+ }
104
+ else {
105
+ logger_1.logger.warn(`Failed to migrate profile "${profileName}" to secure storage. Secrets remain in plaintext.`);
106
+ }
107
+ });
108
+ }
92
109
  }
93
110
  exports.ProfileCommandService = ProfileCommandService;
94
111
  });
@@ -13,12 +13,12 @@ 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", "./profile.interface", "./profile.validator", "path", "fs", "../utils/logger", "openid-client", "axios", "os"], factory);
16
+ define(["require", "exports", "./profile.interface", "./profile.validator", "path", "fs", "../utils/logger", "openid-client", "axios", "os", "./secret-storage.service"], factory);
17
17
  }
18
18
  })(function (require, exports) {
19
19
  "use strict";
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.profileService = exports.ProfileService = void 0;
21
+ exports.ProfileService = void 0;
22
22
  const profile_interface_1 = require("./profile.interface");
23
23
  const profile_validator_1 = require("./profile.validator");
24
24
  const path = require("path");
@@ -27,6 +27,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
27
27
  const openid_client_1 = require("openid-client");
28
28
  const axios_1 = require("axios");
29
29
  const os = require("os");
30
+ const secret_storage_service_1 = require("./secret-storage.service");
30
31
  const homedir = os.homedir();
31
32
  // use 5 seconds buffer to avoid rare cases when accessToken is just about to expire before the command is sent
32
33
  const expiryBuffer = 5000;
@@ -38,6 +39,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
38
39
  constructor() {
39
40
  this.profileContainerPath = path.resolve(homedir, ".celonis-content-cli-profiles");
40
41
  this.configContainer = path.resolve(this.profileContainerPath, "config.json");
42
+ this.secureSecretStorageService = new secret_storage_service_1.SecureSecretStorageService();
41
43
  }
42
44
  findProfile(profileName) {
43
45
  return __awaiter(this, void 0, void 0, function* () {
@@ -46,8 +48,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
46
48
  if (!this.checkIfMissingProfile(profileName)) {
47
49
  const file = fs.readFileSync(path.resolve(this.profileContainerPath, this.constructProfileFileName(profileName)), { encoding: "utf-8" });
48
50
  const profile = JSON.parse(file);
49
- this.refreshProfile(profile)
50
- .then(() => resolve(profile));
51
+ if (profile.secretsStoredSecurely) {
52
+ this.secureSecretStorageService.getSecrets(profileName)
53
+ .then(profileSecureSecrets => {
54
+ if (profileSecureSecrets) {
55
+ profile.apiToken = profileSecureSecrets.apiToken;
56
+ profile.refreshToken = profileSecureSecrets.refreshToken;
57
+ profile.clientSecret = profileSecureSecrets.clientSecret;
58
+ this.refreshProfile(profile)
59
+ .then(() => resolve(profile))
60
+ .catch(() => reject(`The profile ${profileName} couldn't be resolved.`));
61
+ }
62
+ else {
63
+ reject("Failed to read secrets from system keychain.");
64
+ }
65
+ })
66
+ .catch(() => reject(`The profile ${profileName} couldn't be resolved.`));
67
+ }
68
+ else {
69
+ this.refreshProfile(profile)
70
+ .then(() => resolve(profile))
71
+ .catch(() => reject(`The profile ${profileName} couldn't be resolved.`));
72
+ }
51
73
  }
52
74
  else if (process.env.TEAM_URL && process.env.API_TOKEN) {
53
75
  resolve(this.buildProfileFromEnvVariables());
@@ -92,11 +114,24 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
92
114
  }
93
115
  }
94
116
  storeProfile(profile) {
95
- this.createProfileContainerIfNotExists();
96
- const newProfileFileName = this.constructProfileFileName(profile.name);
97
- profile.team = this.getBaseTeamUrl(profile.team);
98
- fs.writeFileSync(path.resolve(this.profileContainerPath, newProfileFileName), JSON.stringify(profile), {
99
- encoding: "utf-8",
117
+ return __awaiter(this, void 0, void 0, function* () {
118
+ this.createProfileContainerIfNotExists();
119
+ const newProfileFileName = this.constructProfileFileName(profile.name);
120
+ profile.team = this.getBaseTeamUrl(profile.team);
121
+ const secretsStoredInKeychain = yield this.secureSecretStorageService.storeSecrets(profile);
122
+ const profileToStore = Object.assign({}, profile);
123
+ if (secretsStoredInKeychain) {
124
+ profileToStore.secretsStoredSecurely = true;
125
+ delete profileToStore.apiToken;
126
+ delete profileToStore.refreshToken;
127
+ delete profileToStore.clientSecret;
128
+ }
129
+ else {
130
+ profileToStore.secretsStoredSecurely = false;
131
+ }
132
+ fs.writeFileSync(path.resolve(this.profileContainerPath, newProfileFileName), JSON.stringify(profileToStore), {
133
+ encoding: "utf-8",
134
+ });
100
135
  });
101
136
  }
102
137
  buildProfileFromEnvVariables() {
@@ -263,7 +298,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
263
298
  logger_1.logger.error(new logger_1.FatalError("The profile cannot be refreshed. Please retry or recreate profile."));
264
299
  }
265
300
  }
266
- this.storeProfile(profile);
301
+ yield this.storeProfile(profile);
267
302
  });
268
303
  }
269
304
  getProfileEnvVariables() {
@@ -394,5 +429,4 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
394
429
  }
395
430
  }
396
431
  exports.ProfileService = ProfileService;
397
- exports.profileService = new ProfileService();
398
432
  });
@@ -0,0 +1,115 @@
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"], factory);
17
+ }
18
+ })(function (require, exports) {
19
+ "use strict";
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.SecureSecretStorageService = void 0;
22
+ const logger_1 = require("../utils/logger");
23
+ var PROFILE_SECRET_TYPE;
24
+ (function (PROFILE_SECRET_TYPE) {
25
+ PROFILE_SECRET_TYPE["API_TOKEN"] = "apiToken";
26
+ PROFILE_SECRET_TYPE["CLIENT_SECRET"] = "clientSecret";
27
+ PROFILE_SECRET_TYPE["REFRESH_TOKEN"] = "refreshToken";
28
+ })(PROFILE_SECRET_TYPE || (PROFILE_SECRET_TYPE = {}));
29
+ const CONTENT_CLI_SERVICE_NAME = "celonis-content-cli";
30
+ // Lazy load keytar to handle cases where native dependencies are not available
31
+ let keytar = null;
32
+ let keytarLoadError = null;
33
+ function getKeytar() {
34
+ if (keytar !== null) {
35
+ return keytar;
36
+ }
37
+ if (keytarLoadError !== null) {
38
+ return null;
39
+ }
40
+ try {
41
+ keytar = require("@github/keytar");
42
+ return keytar;
43
+ }
44
+ catch (error) {
45
+ keytarLoadError = error;
46
+ return null;
47
+ }
48
+ }
49
+ class SecureSecretStorageService {
50
+ storeSecrets(profile) {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ let secretsStoredInKeychain = true;
53
+ const secretEntries = [
54
+ { type: PROFILE_SECRET_TYPE.API_TOKEN, value: profile.apiToken },
55
+ { type: PROFILE_SECRET_TYPE.CLIENT_SECRET, value: profile.clientSecret },
56
+ { type: PROFILE_SECRET_TYPE.REFRESH_TOKEN, value: profile.refreshToken },
57
+ ];
58
+ for (const secretEntry of secretEntries) {
59
+ if (secretEntry.value) {
60
+ const stored = yield this.storeSecret(this.getSecretServiceName(profile.name), secretEntry.type, secretEntry.value);
61
+ if (!stored) {
62
+ secretsStoredInKeychain = false;
63
+ }
64
+ }
65
+ }
66
+ if (!secretsStoredInKeychain) {
67
+ logger_1.logger.warn("⚠️ Failed to store secrets securely. They will be stored in plain text file.");
68
+ return false;
69
+ }
70
+ return true;
71
+ });
72
+ }
73
+ getSecrets(profileName) {
74
+ return __awaiter(this, void 0, void 0, function* () {
75
+ const keytarModule = getKeytar();
76
+ if (!keytarModule) {
77
+ return undefined;
78
+ }
79
+ try {
80
+ const secrets = yield keytarModule.findCredentials(this.getSecretServiceName(profileName));
81
+ if (!secrets.length) {
82
+ return undefined;
83
+ }
84
+ const profileSecrets = {};
85
+ for (const secret of secrets) {
86
+ profileSecrets[secret.account] = secret.password;
87
+ }
88
+ return profileSecrets;
89
+ }
90
+ catch (err) {
91
+ return undefined;
92
+ }
93
+ });
94
+ }
95
+ getSecretServiceName(profileName) {
96
+ return `${CONTENT_CLI_SERVICE_NAME}:${profileName}`;
97
+ }
98
+ storeSecret(service, account, secret) {
99
+ return __awaiter(this, void 0, void 0, function* () {
100
+ const keytarModule = getKeytar();
101
+ if (!keytarModule) {
102
+ return false;
103
+ }
104
+ try {
105
+ yield keytarModule.setPassword(service, account, secret);
106
+ return true;
107
+ }
108
+ catch (err) {
109
+ return false;
110
+ }
111
+ });
112
+ }
113
+ }
114
+ exports.SecureSecretStorageService = SecureSecretStorageService;
115
+ });
@@ -1,7 +1,8 @@
1
1
  import { Context } from "../../../core/command/cli-context";
2
- import { PackageVersionTransport } from "../interfaces/package-version.interfaces";
2
+ import { PackageVersionCreatedTransport, PackageVersionTransport, SavePackageVersionTransport } from "../interfaces/package-version.interfaces";
3
3
  export declare class PackageVersionApi {
4
4
  private httpClient;
5
5
  constructor(context: Context);
6
6
  findOne(packageKey: string, version: string): Promise<PackageVersionTransport>;
7
+ createVersion(packageKey: string, request: SavePackageVersionTransport): Promise<PackageVersionCreatedTransport>;
7
8
  }
@@ -8,3 +8,24 @@ export interface PackageVersionTransport {
8
8
  deployed: boolean;
9
9
  publishedBy: string;
10
10
  }
11
+ export interface SavePackageVersionTransport {
12
+ version?: string;
13
+ versionBumpOption?: VersionBumpOption;
14
+ summaryOfChanges?: string;
15
+ nodeFilter?: NodeFilterTransport;
16
+ }
17
+ export declare enum VersionBumpOption {
18
+ NONE = "NONE",
19
+ PATCH = "PATCH"
20
+ }
21
+ export interface NodeFilterTransport {
22
+ filterType: "INCLUDE";
23
+ keys: string[];
24
+ }
25
+ export interface PackageVersionCreatedTransport {
26
+ packageKey: string;
27
+ version: string;
28
+ summaryOfChanges: string;
29
+ creationDate: string;
30
+ createdBy: string;
31
+ }
@@ -9,6 +9,7 @@ declare class Module extends IModule {
9
9
  private batchExportPackages;
10
10
  private batchExportPackagesMetadata;
11
11
  private getPackageVersion;
12
+ private createPackageVersion;
12
13
  private batchImportPackages;
13
14
  private diffPackages;
14
15
  private listVariables;
@@ -3,4 +3,5 @@ export declare class PackageVersionCommandService {
3
3
  private packageVersionService;
4
4
  constructor(context: Context);
5
5
  getPackageVersion(packageKey: string, version: string, jsonResponse: boolean): Promise<void>;
6
+ createPackageVersion(packageKey: string, version: string | undefined, versionBumpOption: string, summaryOfChanges: string | undefined, nodeFilterKeys: string[] | undefined, jsonResponse: boolean): Promise<void>;
6
7
  }
@@ -3,5 +3,7 @@ export declare class PackageVersionService {
3
3
  private packageVersionApi;
4
4
  constructor(context: Context);
5
5
  findPackageVersion(packageKey: string, version: string, jsonResponse: boolean): Promise<void>;
6
+ createPackageVersion(packageKey: string, version: string | undefined, versionBumpOption: string, summaryOfChanges: string | undefined, nodeFilterKeys: string[] | undefined, jsonResponse: boolean): Promise<void>;
6
7
  private printPackageVersionTransport;
8
+ private printPackageVersionCreatedTransport;
7
9
  }
@@ -8,5 +8,6 @@ declare class Module extends IModule {
8
8
  private defaultProfile;
9
9
  private createProfile;
10
10
  private listProfiles;
11
+ private secureProfile;
11
12
  }
12
13
  export = Module;
@@ -3,4 +3,5 @@ export declare class ProfileCommandService {
3
3
  createProfile(setAsDefault: boolean): Promise<void>;
4
4
  listProfiles(): Promise<void>;
5
5
  makeDefaultProfile(profile: string): Promise<void>;
6
+ secureProfile(profileName: string): Promise<void>;
6
7
  }
@@ -1,14 +1,17 @@
1
- export interface Profile {
1
+ export interface ProfileSecrets {
2
+ apiToken: string;
3
+ clientSecret?: string;
4
+ refreshToken?: string;
5
+ secretsStoredSecurely?: boolean;
6
+ }
7
+ export interface Profile extends ProfileSecrets {
2
8
  name: string;
3
9
  team: string;
4
10
  type: ProfileType;
5
- apiToken: string;
6
11
  authenticationType: AuthenticationType;
7
12
  clientId?: string;
8
- clientSecret?: string;
9
13
  scopes?: string[];
10
14
  clientAuthenticationMethod?: ClientAuthenticationMethod;
11
- refreshToken?: string;
12
15
  expiresAt?: number;
13
16
  }
14
17
  export type AuthenticationType = "Bearer" | "AppKey";
@@ -5,10 +5,11 @@ export interface Config {
5
5
  export declare class ProfileService {
6
6
  private profileContainerPath;
7
7
  private configContainer;
8
+ private secureSecretStorageService;
8
9
  findProfile(profileName: string): Promise<Profile>;
9
10
  makeDefaultProfile(profileName: string): Promise<Profile>;
10
11
  getDefaultProfile(): string;
11
- storeProfile(profile: Profile): void;
12
+ storeProfile(profile: Profile): Promise<void>;
12
13
  private buildProfileFromEnvVariables;
13
14
  private storeConfig;
14
15
  private createProfileContainerIfNotExists;
@@ -40,4 +41,3 @@ export declare class ProfileService {
40
41
  */
41
42
  private extractScopesFromTokenSet;
42
43
  }
43
- export declare const profileService: ProfileService;
@@ -0,0 +1,7 @@
1
+ import { Profile, ProfileSecrets } from "./profile.interface";
2
+ export declare class SecureSecretStorageService {
3
+ storeSecrets(profile: Profile): Promise<boolean>;
4
+ getSecrets(profileName: string): Promise<ProfileSecrets | undefined>;
5
+ private getSecretServiceName;
6
+ private storeSecret;
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celonis/content-cli",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "CLI Tool to help manage content in Celonis Platform",
5
5
  "main": "content-cli.js",
6
6
  "bin": {
@@ -26,8 +26,9 @@
26
26
  "form-data": "4.0.4",
27
27
  "openid-client": "5.6.1",
28
28
  "hpagent": "1.2.0",
29
+ "@github/keytar": "7.10.6",
29
30
  "semver": "7.6.3",
30
- "simple-git": "3.28.0",
31
+ "simple-git": "3.32.3",
31
32
  "valid-url": "1.0.9",
32
33
  "winston": "3.17.0",
33
34
  "yaml": "2.7.0"