@celonis/content-cli 1.4.1 → 1.6.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,6 +57,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
57
57
  });
58
58
  });
59
59
  }
60
+ findPackagesByKeysAndVersion(packageKeysWithVersion, withDependencies = false) {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ const queryParams = new URLSearchParams();
63
+ packageKeysWithVersion.forEach(keyWithVersion => queryParams.append("packageKeysWithVersion", keyWithVersion));
64
+ queryParams.set("withDependencies", withDependencies.toString());
65
+ return this.httpClient().get(`/package-manager/api/core/packages/versions/export/list?${queryParams.toString()}`).catch(e => {
66
+ throw new logger_1.FatalError(`Problem getting packages by keys and versions: ${e}`);
67
+ });
68
+ });
69
+ }
60
70
  exportPackages(packageKeys, withDependencies) {
61
71
  return __awaiter(this, void 0, void 0, function* () {
62
72
  const queryParams = new URLSearchParams();
@@ -47,10 +47,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
47
47
  });
48
48
  });
49
49
  }
50
- findAndExportListOfActivePackages(flavors, packageKeys, withDependencies) {
50
+ findAndExportListOfPackages(flavors, packageKeys, keysByVersion, withDependencies) {
51
51
  return __awaiter(this, void 0, void 0, function* () {
52
52
  let packagesToExport;
53
- if (packageKeys.length) {
53
+ if (keysByVersion.length) {
54
+ packagesToExport = yield this.batchImportExportApi.findPackagesByKeysAndVersion(keysByVersion, withDependencies);
55
+ }
56
+ else if (packageKeys.length) {
54
57
  packagesToExport = yield this.batchImportExportApi.findActivePackagesByKeys(packageKeys, withDependencies);
55
58
  }
56
59
  else {
@@ -60,6 +63,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
60
63
  this.exportListOfPackages(packagesToExport);
61
64
  });
62
65
  }
66
+ listPackagesByKeysWithVersion(keysByVersion, withDependencies) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ const exportedPackages = yield this.batchImportExportApi.findPackagesByKeysAndVersion(keysByVersion, withDependencies);
69
+ exportedPackages.forEach(pkg => {
70
+ logger_1.logger.info(`${pkg.name} - Key: "${pkg.key}"`);
71
+ });
72
+ });
73
+ }
63
74
  batchExportPackages(packageKeys, packageKeysByVersion, withDependencies, gitBranch, unzip) {
64
75
  return __awaiter(this, void 0, void 0, function* () {
65
76
  let exportedPackagesData;
@@ -29,14 +29,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
29
29
  this.variableService = new variable_service_1.VariableService(context);
30
30
  this.diffService = new diff_service_1.DiffService(context);
31
31
  }
32
- listActivePackages(jsonResponse, flavors, withDependencies, packageKeys, variableValue, variableType) {
32
+ listPackages(jsonResponse, flavors, withDependencies, packageKeys, keysByVersion, variableValue, variableType) {
33
33
  return __awaiter(this, void 0, void 0, function* () {
34
34
  if (variableValue) {
35
35
  yield this.listPackagesByVariableValue(jsonResponse, flavors, variableValue, variableType);
36
36
  return;
37
37
  }
38
38
  if (jsonResponse) {
39
- yield this.batchImportExportService.findAndExportListOfActivePackages(flavors !== null && flavors !== void 0 ? flavors : [], packageKeys !== null && packageKeys !== void 0 ? packageKeys : [], withDependencies);
39
+ yield this.batchImportExportService.findAndExportListOfPackages(flavors !== null && flavors !== void 0 ? flavors : [], packageKeys !== null && packageKeys !== void 0 ? packageKeys : [], keysByVersion !== null && keysByVersion !== void 0 ? keysByVersion : [], withDependencies);
40
+ }
41
+ else if (keysByVersion) {
42
+ yield this.batchImportExportService.listPackagesByKeysWithVersion(keysByVersion, withDependencies);
40
43
  }
41
44
  else {
42
45
  yield this.batchImportExportService.listActivePackages(flavors !== null && flavors !== void 0 ? flavors : []);
@@ -31,14 +31,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
31
31
  register(context, configurator) {
32
32
  const configCommand = configurator.command("config");
33
33
  configCommand.command("list")
34
- .description("Command to list active packages that can be exported")
34
+ .description("Command to list packages")
35
35
  .option("--json", "Return response as json type", "")
36
36
  .option("--flavors <flavors...>", "Lists only active packages of the given flavors")
37
37
  .option("--withDependencies", "Include dependencies", "")
38
- .option("--packageKeys <packageKeys...>", "Lists only given package keys")
38
+ .option("--packageKeys <packageKeys...>", "Lists only active versions of given package keys")
39
+ .option("--keysByVersion <keysByVersion...>", "Lists packages by given key and version [packageKey.version]")
39
40
  .option("--variableValue <variableValue>", "Variable value for filtering packages by.")
40
41
  .option("--variableType <variableType>", "Variable type for filtering packages by.")
41
- .action(this.listActivePackages);
42
+ .action(this.listPackages);
42
43
  configCommand.command("export")
43
44
  .description("Command to export package configs")
44
45
  .option("--packageKeys <packageKeys...>", "Keys of packages to export. Exports the latest deployed version only")
@@ -130,9 +131,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
130
131
  .option("--params <params>", "Variable query params")
131
132
  .action(this.listAssignments);
132
133
  }
133
- listActivePackages(context, command, options) {
134
+ listPackages(context, command, options) {
134
135
  return __awaiter(this, void 0, void 0, function* () {
135
- yield new config_command_service_1.ConfigCommandService(context).listActivePackages(options.json, options.flavors, options.withDependencies, options.packageKeys, options.variableValue, options.variableType);
136
+ if (options.packageKeys && options.keysByVersion) {
137
+ throw new Error("Please provide either --packageKeys or --keysByVersion, but not both.");
138
+ }
139
+ yield new config_command_service_1.ConfigCommandService(context).listPackages(options.json, options.flavors, options.withDependencies, options.packageKeys, options.keysByVersion, options.variableValue, options.variableType);
136
140
  });
137
141
  }
138
142
  batchExportPackages(context, command, options) {
@@ -54,16 +54,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
54
54
  }
55
55
  });
56
56
  }
57
- batchExportPackages(packageKeys, includeDependencies, excludeActionFlows) {
58
- return __awaiter(this, void 0, void 0, function* () {
59
- yield this.packageService.batchExportPackages(packageKeys, includeDependencies, excludeActionFlows);
60
- });
61
- }
62
- batchImportPackages(spaceMappings, dataModelMappingsFilePath, exportedPackagesFile, overwrite, excludeActionFlows) {
63
- return __awaiter(this, void 0, void 0, function* () {
64
- yield this.packageService.batchImportPackages(spaceMappings !== null && spaceMappings !== void 0 ? spaceMappings : [], dataModelMappingsFilePath, exportedPackagesFile, overwrite, excludeActionFlows);
65
- });
66
- }
67
57
  }
68
58
  exports.PackageCommandService = PackageCommandService;
69
59
  });
@@ -27,26 +27,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
27
27
  const space_command_service_1 = require("./command-service/space-command.service");
28
28
  class Module extends module_handler_1.IModule {
29
29
  register(context, configurator) {
30
- const exportCommand = configurator.command("export");
31
- exportCommand.command("packages")
32
- .description("Command to export all given packages")
33
- .requiredOption("--packageKeys <packageKeys...>", "Exports only given package keys")
34
- .option("--includeDependencies", "Include variables and dependencies", "")
35
- .option("--excludeActionFlows", "Don't export action flows")
36
- .deprecationNotice("`content-cli export packages` is deprecated and is expected to be removed in subsequent updates around: 01-09-2025.\n" +
37
- "Please use `content-cli config export` instead.\n")
38
- .action(this.batchExportPackages);
39
- const importCommand = configurator.command("import");
40
- importCommand.command("packages")
41
- .description("Command to import all given packages")
42
- .option("--spaceMappings <spaceMappings...>", "List of mappings for importing packages to different target spaces. Mappings should follow format 'packageKey:targetSpaceKey'")
43
- .option("--overwrite", "Flag to allow overwriting of packages")
44
- .option("--excludeActionFlows", "Skip overwrite of action flows of package")
45
- .option("--dataModelMappingsFile <dataModelMappingsFile>", "DataModel variable mappings file path. If missing, variables will be mapped from manifest file.")
46
- .requiredOption("-f, --file <file>", "Exported packages file (relative path)")
47
- .deprecationNotice("`content-cli import packages` is deprecated and is expected to be removed in subsequent updates around: 01-09-2025.\n" +
48
- "Please use `content-cli config import` instead.\n")
49
- .action(this.batchImportPackages);
50
30
  const listCommand = configurator.command("list");
51
31
  listCommand.command("packages")
52
32
  .description("Command to list all packages")
@@ -103,17 +83,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
103
83
  .option("--packageManager", "Upload widget to package manager (deprecated)") // Deprecated
104
84
  .action(this.pushWidget);
105
85
  }
106
- batchExportPackages(context, command, options) {
107
- var _a;
108
- return __awaiter(this, void 0, void 0, function* () {
109
- yield new package_command_service_1.PackageCommandService(context).batchExportPackages(options.packageKeys, options.includeDependencies, (_a = options.excludeActionFlows) !== null && _a !== void 0 ? _a : false);
110
- });
111
- }
112
- batchImportPackages(context, command, options) {
113
- return __awaiter(this, void 0, void 0, function* () {
114
- yield new package_command_service_1.PackageCommandService(context).batchImportPackages(options.spaceMappings, options.dataModelMappingsFile, options.file, options.overwrite, options.excludeActionFlows);
115
- });
116
- }
117
86
  listPackages(context, command, options) {
118
87
  return __awaiter(this, void 0, void 0, function* () {
119
88
  yield new package_command_service_1.PackageCommandService(context).listPackages(options.json, options.includeDependencies, options.packageKeys);
@@ -13,39 +13,27 @@ 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", "fs", "adm-zip", "path", "os", "form-data", "../api/package-api", "../../../core/utils/logger", "../interfaces/package-manager.interfaces", "../../../core/utils/file-service", "../../../core/utils/yaml", "yaml", "../utils/semantic-versioning", "../api/node-api", "../api/package-dependencies-api", "./data-model.service", "./studio-variable.service", "./space.service"], factory);
16
+ define(["require", "exports", "uuid", "../api/package-api", "../../../core/utils/logger", "../interfaces/package-manager.interfaces", "../../../core/utils/file-service", "../api/package-dependencies-api", "./data-model.service", "./studio-variable.service"], factory);
17
17
  }
18
18
  })(function (require, exports) {
19
19
  "use strict";
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
21
  exports.PackageService = void 0;
22
22
  const uuid_1 = require("uuid");
23
- const fs = require("fs");
24
- const AdmZip = require("adm-zip");
25
- const path = require("path");
26
- const os_1 = require("os");
27
- const FormData = require("form-data");
28
23
  const package_api_1 = require("../api/package-api");
29
24
  const logger_1 = require("../../../core/utils/logger");
30
25
  const package_manager_interfaces_1 = require("../interfaces/package-manager.interfaces");
31
26
  const file_service_1 = require("../../../core/utils/file-service");
32
- const yaml_1 = require("../../../core/utils/yaml");
33
- const yaml_2 = require("yaml");
34
- const semantic_versioning_1 = require("../utils/semantic-versioning");
35
- const node_api_1 = require("../api/node-api");
36
27
  const package_dependencies_api_1 = require("../api/package-dependencies-api");
37
28
  const data_model_service_1 = require("./data-model.service");
38
29
  const studio_variable_service_1 = require("./studio-variable.service");
39
- const space_service_1 = require("./space.service");
40
30
  class PackageService {
41
31
  constructor(context) {
42
32
  this.fileDownloadedMessage = "File downloaded successfully. New filename: ";
43
33
  this.packageApi = new package_api_1.PackageApi(context);
44
- this.nodeApi = new node_api_1.NodeApi(context);
45
34
  this.packageDependenciesApi = new package_dependencies_api_1.PackageDependenciesApi(context);
46
35
  this.dataModelService = new data_model_service_1.DataModelService(context);
47
36
  this.variableService = new studio_variable_service_1.StudioVariableService(context);
48
- this.spaceService = new space_service_1.SpaceService(context);
49
37
  }
50
38
  listPackages() {
51
39
  return __awaiter(this, void 0, void 0, function* () {
@@ -85,247 +73,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
85
73
  this.exportListOfPackages(nodesListToExport, fieldsToInclude);
86
74
  });
87
75
  }
88
- batchImportPackages(spaceMappings, dataModelMappingsFilePath, exportedPackagesFile, overwrite, excludeActionFlows) {
89
- return __awaiter(this, void 0, void 0, function* () {
90
- exportedPackagesFile = exportedPackagesFile + (exportedPackagesFile.includes(".zip") ? "" : ".zip");
91
- const zip = new AdmZip(exportedPackagesFile);
92
- const importedFilePath = path.resolve((0, os_1.tmpdir)(), "export_" + (0, uuid_1.v4)());
93
- yield fs.mkdirSync(importedFilePath);
94
- yield zip.extractAllTo(importedFilePath);
95
- const manifestNodes = yield this.readManifestFile(importedFilePath);
96
- if (!overwrite) {
97
- const allTargetPackages = yield this.packageApi.findAllPackages();
98
- const manifestNodeKeys = manifestNodes.map(node => node.packageKey);
99
- const packagesWithDraftChanges = allTargetPackages
100
- .filter(node => manifestNodeKeys.includes(node.key) && node.workingDraftId !== node.activatedDraftId)
101
- .map(node => node.key)
102
- .join(", ");
103
- if (!!packagesWithDraftChanges) {
104
- throw new logger_1.FatalError(`Failed to import. Cannot overwrite packages with key(s) ${packagesWithDraftChanges}`);
105
- }
106
- }
107
- let dmTargetIdsBySourceIds = new Map();
108
- if (dataModelMappingsFilePath) {
109
- const dataModelMappings = yield file_service_1.fileService.readFileToJson(dataModelMappingsFilePath);
110
- dmTargetIdsBySourceIds = new Map(Object.entries(dataModelMappings.dataModelIdMappings));
111
- }
112
- manifestNodes.map(node => node.dependenciesByVersion = new Map(Object.entries(node.dependenciesByVersion)));
113
- const importedVersionsByNodeKey = new Map();
114
- const sourceToTargetVersionsByNodeKey = new Map();
115
- for (const node of manifestNodes) {
116
- for (const version of node.dependenciesByVersion.keys()) {
117
- yield this.checkNodeForCircularDependency(node, version, manifestNodes, []);
118
- }
119
- }
120
- const customSpacesMap = new Map();
121
- spaceMappings.forEach(spaceMap => {
122
- const packageAndSpaceid = spaceMap.split(":");
123
- customSpacesMap.set(packageAndSpaceid[0], packageAndSpaceid[1]);
124
- });
125
- const draftIdsByPackageKeyAndVersion = new Map();
126
- for (const node of manifestNodes) {
127
- yield this.importPackage(node, manifestNodes, sourceToTargetVersionsByNodeKey, customSpacesMap, dmTargetIdsBySourceIds, importedVersionsByNodeKey, draftIdsByPackageKeyAndVersion, importedFilePath, excludeActionFlows);
128
- }
129
- });
130
- }
131
- checkNodeForCircularDependency(node, version, manifestNodes, iteratedNodeAndVersions) {
132
- return __awaiter(this, void 0, void 0, function* () {
133
- const dependencies = node.dependenciesByVersion.get(version);
134
- if (iteratedNodeAndVersions.includes(`${node.packageKey}_${version}`)) {
135
- throw new Error("Circular dependency detected!");
136
- }
137
- iteratedNodeAndVersions.push(`${node.packageKey}_${version}`);
138
- for (const dependency of dependencies) {
139
- const manifestNodeOfDependency = manifestNodes.find(manifestNode => manifestNode.packageKey === dependency.key);
140
- yield this.checkNodeForCircularDependency(manifestNodeOfDependency, dependency.version, manifestNodes, iteratedNodeAndVersions);
141
- }
142
- });
143
- }
144
- importPackage(packageToImport, manifestNodes, sourceToTargetVersionsByNodeKey, spaceMappings, dmTargetIdsBySourceIds, importedVersionsByNodeKey, draftIdsByPackageKeyAndVersion, importedFilePath, excludeActionFlows) {
145
- var _a;
146
- return __awaiter(this, void 0, void 0, function* () {
147
- const importedPackageVersion = (_a = importedVersionsByNodeKey.get(packageToImport.packageKey)) !== null && _a !== void 0 ? _a : [];
148
- const versionsOfPackage = [...packageToImport.dependenciesByVersion.keys()].sort((k1, k2) => {
149
- const version1 = new semantic_versioning_1.SemanticVersioning(k1);
150
- const version2 = new semantic_versioning_1.SemanticVersioning(k1);
151
- return version1.isGreaterThan(version2) ? 1 : -1;
152
- }).filter(version => !importedPackageVersion.includes(version));
153
- for (const version of versionsOfPackage) {
154
- try {
155
- yield this.importPackageVersion(packageToImport, manifestNodes, sourceToTargetVersionsByNodeKey, spaceMappings, dmTargetIdsBySourceIds, importedVersionsByNodeKey, draftIdsByPackageKeyAndVersion, importedFilePath, version, excludeActionFlows);
156
- }
157
- catch (e) {
158
- logger_1.logger.error(`Problem import package with key: ${packageToImport.packageKey} ${version} ${e}`);
159
- }
160
- }
161
- });
162
- }
163
- importPackageVersion(packageToImport, manifestNodes, sourceToTargetVersionsByNodeKey, spaceMappings, dmTargetIdsBySourceIds, importedVersionsByNodeKey, draftIdsByPackageKeyAndVersion, importedFilePath, versionOfPackageBeingImported, excludeActionFlows) {
164
- var _a, _b;
165
- return __awaiter(this, void 0, void 0, function* () {
166
- if (packageToImport.dependenciesByVersion.get(versionOfPackageBeingImported).length) {
167
- const dependenciesOfPackageVersion = packageToImport.dependenciesByVersion.get(versionOfPackageBeingImported);
168
- yield this.importDependencyPackages(dependenciesOfPackageVersion, manifestNodes, sourceToTargetVersionsByNodeKey, spaceMappings, dmTargetIdsBySourceIds, importedVersionsByNodeKey, draftIdsByPackageKeyAndVersion, importedFilePath, excludeActionFlows);
169
- }
170
- if (this.checkIfPackageVersionHasBeenImported(packageToImport.packageKey, versionOfPackageBeingImported, importedVersionsByNodeKey)) {
171
- return;
172
- }
173
- const targetSpace = yield this.getTargetSpaceForExportedPackage(packageToImport, spaceMappings);
174
- let nodeInTargetTeam = yield this.nodeApi.findOneByKeyAndRootNodeKey(packageToImport.packageKey, packageToImport.packageKey);
175
- const pathToZipFile = path.resolve(importedFilePath, packageToImport.packageKey + "_" + versionOfPackageBeingImported + ".zip");
176
- const packageZip = this.createBodyForImport(pathToZipFile);
177
- yield this.packageApi.importPackage(packageZip, targetSpace.id, !!nodeInTargetTeam, excludeActionFlows);
178
- if (nodeInTargetTeam) {
179
- yield this.packageApi.movePackageToSpace(nodeInTargetTeam.id, targetSpace.id);
180
- }
181
- nodeInTargetTeam = yield this.nodeApi.findOneByKeyAndRootNodeKey(packageToImport.packageKey, packageToImport.packageKey);
182
- if (this.isLatestVersion(versionOfPackageBeingImported, [...packageToImport.dependenciesByVersion.keys()])) {
183
- if (dmTargetIdsBySourceIds.size > 0) {
184
- const variableAssignments = packageToImport.variables
185
- .filter(variable => variable.type === package_manager_interfaces_1.PackageManagerVariableType.DATA_MODEL).map(variable => {
186
- var _a;
187
- variable.value = dmTargetIdsBySourceIds.get((_a = variable.value) === null || _a === void 0 ? void 0 : _a.toString());
188
- return variable;
189
- });
190
- yield this.variableService.assignVariableValues(nodeInTargetTeam.key, variableAssignments);
191
- }
192
- else {
193
- yield this.variableService.assignVariableValues(nodeInTargetTeam.key, packageToImport.variables);
194
- }
195
- }
196
- draftIdsByPackageKeyAndVersion.set(`${nodeInTargetTeam.key}_${versionOfPackageBeingImported}`, nodeInTargetTeam.workingDraftId);
197
- yield this.updateDependencyVersions(packageToImport, versionOfPackageBeingImported, sourceToTargetVersionsByNodeKey, draftIdsByPackageKeyAndVersion);
198
- yield this.publishPackage(packageToImport);
199
- const packageVersionInTargetTeam = yield this.packageApi.findActiveVersionById(nodeInTargetTeam.id);
200
- const mappedVersions = (_a = sourceToTargetVersionsByNodeKey.get(packageToImport.packageKey)) !== null && _a !== void 0 ? _a : new Map();
201
- mappedVersions.set(versionOfPackageBeingImported, packageVersionInTargetTeam.version);
202
- sourceToTargetVersionsByNodeKey.set(packageToImport.packageKey, mappedVersions);
203
- const importedVersionsOfPackage = (_b = importedVersionsByNodeKey.get(packageToImport.packageKey)) !== null && _b !== void 0 ? _b : [];
204
- importedVersionsOfPackage.push(versionOfPackageBeingImported);
205
- importedVersionsByNodeKey.set(packageToImport.packageKey, importedVersionsOfPackage);
206
- const mappedVersion = sourceToTargetVersionsByNodeKey.get(packageToImport.packageKey).get(versionOfPackageBeingImported);
207
- logger_1.logger.info(`Imported package with key: ${packageToImport.packageKey} ${versionOfPackageBeingImported} successfully. New version: ${mappedVersion}`);
208
- });
209
- }
210
- isLatestVersion(packageVersion, allPackageVersions) {
211
- let isLatestVersion = true;
212
- for (const version of allPackageVersions) {
213
- const version1 = new semantic_versioning_1.SemanticVersioning(packageVersion);
214
- const version2 = new semantic_versioning_1.SemanticVersioning(version);
215
- if (version2.isGreaterThan(version1)) {
216
- isLatestVersion = false;
217
- break;
218
- }
219
- }
220
- return isLatestVersion;
221
- }
222
- importDependencyPackages(dependenciesToImport, manifestNodes, sourceToTargetVersionsByNodeKey, spaceMappings, dmTargetIdsBySourceIds, importedVersionsByNodeKey, draftIdsByPackageKeyAndVersion, importedFilePath, excludeActionFlows) {
223
- return __awaiter(this, void 0, void 0, function* () {
224
- for (const dependency of dependenciesToImport) {
225
- if (this.checkIfPackageVersionHasBeenImported(dependency.key, dependency.version, importedVersionsByNodeKey)) {
226
- continue;
227
- }
228
- const dependentPackage = manifestNodes.find(node => node.packageKey === dependency.key);
229
- yield this.importPackage(dependentPackage, manifestNodes, sourceToTargetVersionsByNodeKey, spaceMappings, dmTargetIdsBySourceIds, importedVersionsByNodeKey, draftIdsByPackageKeyAndVersion, importedFilePath, excludeActionFlows);
230
- }
231
- });
232
- }
233
- checkIfPackageVersionHasBeenImported(packageKey, version, importedVersions) {
234
- var _a;
235
- const importedPackages = (_a = importedVersions.get(packageKey)) !== null && _a !== void 0 ? _a : [];
236
- return importedPackages.includes(version);
237
- }
238
- createBodyForImport(filename) {
239
- const formData = new FormData();
240
- formData.append("package", fs.createReadStream(filename, { encoding: null }));
241
- return formData;
242
- }
243
- getTargetSpaceForExportedPackage(packageToImport, spaceMappings) {
244
- return __awaiter(this, void 0, void 0, function* () {
245
- let targetSpace;
246
- const allSpaces = yield this.spaceService.refreshAndGetAllSpaces();
247
- if (spaceMappings.has(packageToImport.packageKey)) {
248
- const customSpaceId = spaceMappings.get(packageToImport.packageKey);
249
- const customSpace = allSpaces.find(space => space.id === customSpaceId);
250
- if (!customSpace) {
251
- throw Error("Provided space id does not exist");
252
- }
253
- targetSpace = customSpace;
254
- }
255
- else {
256
- targetSpace = allSpaces.find(space => space.name === packageToImport.space.spaceName);
257
- if (!targetSpace) {
258
- targetSpace = yield this.spaceService.createSpace(packageToImport.space.spaceName, packageToImport.space.spaceIcon);
259
- }
260
- }
261
- return targetSpace;
262
- });
263
- }
264
- updateDependencyVersions(node, versionOfPackage, sourceToTargetVersionsByNodeKey, draftIdsByPackageKeyAndVersion) {
265
- return __awaiter(this, void 0, void 0, function* () {
266
- const createdNode = yield this.nodeApi.findOneByKeyAndRootNodeKey(node.packageKey, node.packageKey);
267
- const newDependencies = [];
268
- for (const dependency of [...node.dependenciesByVersion.get(versionOfPackage)]) {
269
- const nodeInTargetTeam = yield this.nodeApi.findOneByKeyAndRootNodeKey(dependency.key, dependency.key);
270
- const draftIdOfVersionedDependency = draftIdsByPackageKeyAndVersion.get(`${dependency.key}_${dependency.version}`);
271
- dependency.version = sourceToTargetVersionsByNodeKey.get(dependency.key).get(dependency.version);
272
- dependency.updateAvailable = dependency.updateAvailable;
273
- dependency.id = nodeInTargetTeam.rootNodeId;
274
- dependency.rootNodeId = createdNode.rootNodeId;
275
- dependency.draftId = draftIdOfVersionedDependency;
276
- newDependencies.push(dependency);
277
- yield this.packageDependenciesApi.deleteDependency(createdNode.id, dependency.key);
278
- }
279
- if (newDependencies.length) {
280
- yield this.packageDependenciesApi.createDependencies(createdNode.id, newDependencies);
281
- }
282
- });
283
- }
284
- publishPackage(packageToImport) {
285
- return __awaiter(this, void 0, void 0, function* () {
286
- const nodeInTargetTeam = yield this.nodeApi.findOneByKeyAndRootNodeKey(packageToImport.packageKey, packageToImport.packageKey);
287
- const nextVersion = yield this.packageApi.findNextVersion(nodeInTargetTeam.id);
288
- yield this.packageApi.publishPackage({
289
- packageKey: packageToImport.packageKey,
290
- version: nextVersion.version,
291
- publishMessage: "Published package after import",
292
- nodeIdsToExclude: []
293
- });
294
- });
295
- }
296
- batchExportPackages(packageKeys, includeDependencies, excludeActionFlows) {
297
- return __awaiter(this, void 0, void 0, function* () {
298
- const allPackages = yield this.packageApi.findAllPackages();
299
- let nodesListToExport = allPackages.filter(node => packageKeys.includes(node.key));
300
- const versionsByNodeKey = new Map();
301
- const allPackageKeys = allPackages.map(p => p.key);
302
- for (const packageKey of packageKeys) {
303
- if (!allPackageKeys.includes(packageKey)) {
304
- throw new Error(`Package ${packageKey} does not exist.`);
305
- }
306
- }
307
- nodesListToExport = yield this.getNodesWithActiveVersion(nodesListToExport);
308
- if (includeDependencies) {
309
- const dependencyPackages = yield this.getDependencyPackages(nodesListToExport, [], allPackages, [], versionsByNodeKey);
310
- nodesListToExport.push(...dependencyPackages);
311
- }
312
- const packagesWithVariableAssignments = yield this.variableService.getVariableAssignmentsForNodes();
313
- nodesListToExport.forEach(node => {
314
- var _a;
315
- node.variables = (_a = packagesWithVariableAssignments.find(nodeWithVariablesAssignment => nodeWithVariablesAssignment.key === node.key)) === null || _a === void 0 ? void 0 : _a.variableAssignments;
316
- });
317
- const packagesWithDataModelVariables = packagesWithVariableAssignments.map(packageWithVariablesAssignments => {
318
- packageWithVariablesAssignments.variableAssignments = packageWithVariablesAssignments.variableAssignments.filter(variable => variable.value && variable.type === package_manager_interfaces_1.PackageManagerVariableType.DATA_MODEL);
319
- return packageWithVariablesAssignments;
320
- });
321
- const dataModelDetailsByNode = yield this.dataModelService.getDataModelDetailsForPackages(packagesWithDataModelVariables);
322
- nodesListToExport.forEach(node => {
323
- node.datamodels = dataModelDetailsByNode.get(node.key);
324
- });
325
- nodesListToExport = yield this.spaceService.getParentSpaces(nodesListToExport);
326
- yield this.exportToZip(nodesListToExport, versionsByNodeKey, excludeActionFlows);
327
- });
328
- }
329
76
  getNodesWithActiveVersion(nodes) {
330
77
  return __awaiter(this, void 0, void 0, function* () {
331
78
  const activeVersionsOfPackage = yield this.packageApi.findActiveVersionByIds(nodes.map(node => node.id));
@@ -340,114 +87,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
340
87
  return yield this.packageDependenciesApi.findPackageDependenciesByIds(draftIdByNodeId);
341
88
  });
342
89
  }
343
- getDependencyPackages(nodesToResolve, dependencyPackages, allPackages, resolvedDependencies, versionsByNodeKey) {
344
- return __awaiter(this, void 0, void 0, function* () {
345
- const draftIdByNodeId = new Map();
346
- nodesToResolve.forEach(node => draftIdByNodeId.set(node.activatedDraftId, node.id));
347
- const dependenciesByPackageDraftIds = yield this.getPackagesWithDependencies(draftIdByNodeId);
348
- const nodesWithDependencies = nodesToResolve.map(nodeToExport => {
349
- var _a;
350
- nodeToExport.dependencies = (_a = dependenciesByPackageDraftIds[nodeToExport.activatedDraftId]) !== null && _a !== void 0 ? _a : [];
351
- return nodeToExport;
352
- });
353
- for (const node of nodesWithDependencies) {
354
- node.dependencies = node.dependencies.filter(dependency => !(dependency.external || dependency.deleted));
355
- node.dependencies.forEach(dependency => {
356
- var _a;
357
- const dependencyVersions = (_a = versionsByNodeKey.get(dependency.key)) !== null && _a !== void 0 ? _a : [];
358
- if (!dependencyVersions.includes(dependency.version)) {
359
- dependencyVersions.push(dependency.version);
360
- versionsByNodeKey.set(dependency.key, dependencyVersions);
361
- }
362
- });
363
- const nodesToGetKeys = node.dependencies.filter(dependency => {
364
- return !this.nodeHasBeenResolvedBefore(resolvedDependencies, dependency.key, dependency.version);
365
- }).map(iteratedNode => iteratedNode.key);
366
- if (nodesToGetKeys.length > 0) {
367
- const dependencyPackagesOfNode = allPackages.filter(packageNode => nodesToGetKeys.includes(packageNode.key)).map(dependency => {
368
- const versionedDep = node.dependencies.find(dep => dependency.key === dep.key);
369
- return Object.assign(Object.assign({}, dependency), { version: {
370
- version: versionedDep.version
371
- }, activatedDraftId: versionedDep.draftId });
372
- });
373
- dependencyPackages.push(...dependencyPackagesOfNode);
374
- yield this.getDependencyPackages(dependencyPackagesOfNode, dependencyPackages, allPackages, resolvedDependencies, versionsByNodeKey);
375
- }
376
- }
377
- return dependencyPackages;
378
- });
379
- }
380
- nodeHasBeenResolvedBefore(nodePath, nodeKey, version) {
381
- return nodePath.includes(nodeKey + ":" + version);
382
- }
383
90
  exportListOfPackages(nodes, fieldsToInclude) {
384
91
  const filename = (0, uuid_1.v4)() + ".json";
385
92
  file_service_1.fileService.writeToFileWithGivenName(JSON.stringify(nodes, fieldsToInclude), filename);
386
93
  logger_1.logger.info(file_service_1.FileService.fileDownloadedMessage + filename);
387
94
  }
388
- exportPackagesAndAssets(nodes, excludeActionFlows) {
389
- return __awaiter(this, void 0, void 0, function* () {
390
- const zips = [];
391
- for (const rootPackage of nodes) {
392
- const exportedPackage = yield this.packageApi.exportPackage(rootPackage.key, rootPackage.version.version, excludeActionFlows);
393
- zips.push({
394
- data: exportedPackage,
395
- packageKey: rootPackage.key,
396
- version: rootPackage.version.version
397
- });
398
- }
399
- return zips;
400
- });
401
- }
402
- exportToZip(nodes, versionsByNodeKey, excludeActionFlows) {
403
- return __awaiter(this, void 0, void 0, function* () {
404
- const manifestNodes = this.exportManifestOfPackages(nodes, versionsByNodeKey);
405
- const packageZips = yield this.exportPackagesAndAssets(nodes, excludeActionFlows);
406
- const zip = new AdmZip();
407
- zip.addFile("manifest.yml", Buffer.from((0, yaml_2.stringify)(manifestNodes), "utf8"));
408
- for (const packageZip of packageZips) {
409
- zip.addFile(`${packageZip.packageKey}_${packageZip.version}.zip`, packageZip.data);
410
- }
411
- const fileName = "export_" + (0, uuid_1.v4)() + ".zip";
412
- zip.writeZip(fileName);
413
- logger_1.logger.info(this.fileDownloadedMessage + fileName);
414
- });
415
- }
416
- exportManifestOfPackages(nodes, dependencyVersionsByNodeKey) {
417
- const manifestNodesByPackageKey = new Map();
418
- nodes.forEach(node => {
419
- var _a, _b, _c, _d;
420
- const manifestNode = (_a = manifestNodesByPackageKey.get(node.key)) !== null && _a !== void 0 ? _a : {};
421
- manifestNode.packageKey = node.key;
422
- manifestNode.packageId = node.id;
423
- manifestNode.space = {
424
- spaceName: node.space.name,
425
- spaceIcon: node.space.iconReference
426
- };
427
- manifestNode.variables = (_b = node.variables) === null || _b === void 0 ? void 0 : _b.map(variable => {
428
- var _a;
429
- if (variable.type === package_manager_interfaces_1.PackageManagerVariableType.DATA_MODEL) {
430
- // @ts-ignore
431
- const dataModel = (_a = node.datamodels) === null || _a === void 0 ? void 0 : _a.find(dataModel => dataModel.dataModelId === variable.value);
432
- return {
433
- key: variable.key,
434
- type: variable.type,
435
- value: variable.value,
436
- dataModelName: dataModel === null || dataModel === void 0 ? void 0 : dataModel.name,
437
- };
438
- }
439
- return variable;
440
- });
441
- manifestNode.dependenciesByVersion = (_c = manifestNode.dependenciesByVersion) !== null && _c !== void 0 ? _c : new Map();
442
- manifestNode.dependenciesByVersion.set(node.version.version, (_d = node.dependencies) !== null && _d !== void 0 ? _d : []);
443
- manifestNodesByPackageKey.set(node.key, manifestNode);
444
- });
445
- return [...manifestNodesByPackageKey.values()];
446
- }
447
- readManifestFile(importedFileName) {
448
- const manifest = (0, yaml_1.parse)(fs.readFileSync(path.resolve(importedFileName + "/manifest.yml"), { encoding: "utf-8" }));
449
- return Promise.all(manifest);
450
- }
451
95
  }
452
96
  exports.PackageService = PackageService;
453
97
  });
@@ -30,8 +30,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
30
30
  const homedir = os.homedir();
31
31
  // use 5 seconds buffer to avoid rare cases when accessToken is just about to expire before the command is sent
32
32
  const expiryBuffer = 5000;
33
- const deviceCodeScopes = ["studio", "package-manager", "integration.data-pools", "action-engine.projects"];
34
- const clientCredentialsScopes = ["studio", "integration.data-pools", "action-engine.projects", "package-manager"];
33
+ /** All OAuth scopes; used for both device code and client credentials. */
34
+ const OAUTH_SCOPES = ["studio", "package-manager", "integration.data-pools", "action-engine.projects"];
35
+ /** Device code fallback: try without action-engine.projects if all 4 scopes fail. */
36
+ const DEVICE_CODE_SCOPES_WITHOUT_ACTION_ENGINE = ["studio", "package-manager", "integration.data-pools"];
35
37
  class ProfileService {
36
38
  constructor() {
37
39
  this.profileContainerPath = path.resolve(homedir, ".celonis-content-cli-profiles");
@@ -40,18 +42,23 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
40
42
  findProfile(profileName) {
41
43
  return __awaiter(this, void 0, void 0, function* () {
42
44
  return new Promise((resolve, reject) => {
43
- this.mapCelonisEnvProfile();
44
- this.checkIfMissingProfile(profileName, reject);
45
45
  try {
46
- if (process.env.TEAM_URL && process.env.API_TOKEN) {
47
- resolve(this.buildProfileFromEnvVariables());
48
- }
49
- else {
46
+ if (!this.checkIfMissingProfile(profileName)) {
50
47
  const file = fs.readFileSync(path.resolve(this.profileContainerPath, this.constructProfileFileName(profileName)), { encoding: "utf-8" });
51
48
  const profile = JSON.parse(file);
52
49
  this.refreshProfile(profile)
53
50
  .then(() => resolve(profile));
54
51
  }
52
+ else if (process.env.TEAM_URL && process.env.API_TOKEN) {
53
+ resolve(this.buildProfileFromEnvVariables());
54
+ }
55
+ else if (process.env.CELONIS_URL && process.env.CELONIS_API_TOKEN) {
56
+ this.mapCelonisEnvProfile();
57
+ resolve(this.buildProfileFromEnvVariables());
58
+ }
59
+ else {
60
+ reject(`The profile ${profileName} couldn't be resolved due to missing environment variables.`);
61
+ }
55
62
  }
56
63
  catch (e) {
57
64
  reject(`The profile ${profileName} couldn't be resolved.`);
@@ -160,65 +167,56 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
160
167
  }
161
168
  break;
162
169
  case profile_interface_1.ProfileType.DEVICE_CODE:
163
- try {
164
- const deviceCodeIssuer = yield openid_client_1.Issuer.discover(profile.team);
165
- const deviceCodeOAuthClient = new deviceCodeIssuer.Client({
166
- client_id: "content-cli",
167
- token_endpoint_auth_method: "none",
168
- });
169
- const deviceCodeHandle = yield deviceCodeOAuthClient.deviceAuthorization({
170
- scope: deviceCodeScopes.join(" ")
171
- });
172
- logger_1.logger.info(`Continue authorization here: ${deviceCodeHandle.verification_uri_complete}`);
173
- const deviceCodeTokenSet = yield deviceCodeHandle.poll();
174
- profile.apiToken = deviceCodeTokenSet.access_token;
175
- profile.refreshToken = deviceCodeTokenSet.refresh_token;
176
- profile.expiresAt = deviceCodeTokenSet.expires_at;
170
+ const deviceCodeIssuer = yield openid_client_1.Issuer.discover(profile.team);
171
+ const deviceCodeOAuthClient = new deviceCodeIssuer.Client({
172
+ client_id: "content-cli",
173
+ token_endpoint_auth_method: "none",
174
+ });
175
+ const deviceCodeScopeAttempts = [OAUTH_SCOPES, DEVICE_CODE_SCOPES_WITHOUT_ACTION_ENGINE];
176
+ let deviceCodeSuccess = false;
177
+ for (const scopeList of deviceCodeScopeAttempts) {
178
+ try {
179
+ const deviceCodeHandle = yield deviceCodeOAuthClient.deviceAuthorization({
180
+ scope: scopeList.join(" "),
181
+ });
182
+ logger_1.logger.info(`Continue authorization here: ${deviceCodeHandle.verification_uri_complete}`);
183
+ const deviceCodeTokenSet = yield deviceCodeHandle.poll();
184
+ profile.apiToken = deviceCodeTokenSet.access_token;
185
+ profile.refreshToken = deviceCodeTokenSet.refresh_token;
186
+ profile.expiresAt = deviceCodeTokenSet.expires_at;
187
+ deviceCodeSuccess = true;
188
+ break;
189
+ }
190
+ catch (err) {
191
+ // This scope set failed; try next or fail below
192
+ }
177
193
  }
178
- catch (err) {
179
- logger_1.logger.error(new logger_1.FatalError("The provided team is wrong."));
180
- logger_1.logger.error(err);
194
+ if (!deviceCodeSuccess) {
195
+ throw new logger_1.FatalError("Device code authorization failed. The provided team or requested scopes may be invalid.");
181
196
  }
182
197
  break;
183
198
  case profile_interface_1.ProfileType.CLIENT_CREDENTIALS:
184
199
  const clientCredentialsIssuer = yield openid_client_1.Issuer.discover(profile.team);
185
- try {
186
- // try with client secret basic
187
- const clientCredentialsOAuthClient = new clientCredentialsIssuer.Client({
188
- client_id: profile.clientId,
189
- client_secret: profile.clientSecret,
190
- token_endpoint_auth_method: profile_interface_1.ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
191
- });
192
- const clientCredentialsTokenSet = yield clientCredentialsOAuthClient.grant({
193
- grant_type: "client_credentials",
194
- scope: clientCredentialsScopes.join(" ")
195
- });
200
+ const basicResult = yield this.tryClientCredentialsGrant(clientCredentialsIssuer, profile, profile_interface_1.ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
201
+ if (basicResult) {
196
202
  profile.clientAuthenticationMethod = profile_interface_1.ClientAuthenticationMethod.CLIENT_SECRET_BASIC;
197
- profile.apiToken = clientCredentialsTokenSet.access_token;
198
- profile.expiresAt = clientCredentialsTokenSet.expires_at;
203
+ profile.apiToken = basicResult.tokenSet.access_token;
204
+ profile.expiresAt = basicResult.tokenSet.expires_at;
205
+ profile.scopes = basicResult.scopes;
199
206
  }
200
- catch (e) {
201
- try {
202
- // try with client secret post
203
- const clientCredentialsOAuthClient = new clientCredentialsIssuer.Client({
204
- client_id: profile.clientId,
205
- client_secret: profile.clientSecret,
206
- token_endpoint_auth_method: profile_interface_1.ClientAuthenticationMethod.CLIENT_SECRET_POST,
207
- });
208
- const clientCredentialsTokenSet = yield clientCredentialsOAuthClient.grant({
209
- grant_type: "client_credentials",
210
- scope: clientCredentialsScopes.join(" ")
211
- });
207
+ else {
208
+ const postResult = yield this.tryClientCredentialsGrant(clientCredentialsIssuer, profile, profile_interface_1.ClientAuthenticationMethod.CLIENT_SECRET_POST);
209
+ if (postResult) {
212
210
  profile.clientAuthenticationMethod = profile_interface_1.ClientAuthenticationMethod.CLIENT_SECRET_POST;
213
- profile.apiToken = clientCredentialsTokenSet.access_token;
214
- profile.expiresAt = clientCredentialsTokenSet.expires_at;
211
+ profile.apiToken = postResult.tokenSet.access_token;
212
+ profile.expiresAt = postResult.tokenSet.expires_at;
213
+ profile.scopes = postResult.scopes;
215
214
  }
216
- catch (err) {
217
- logger_1.logger.error(new logger_1.FatalError("The OAuth client configuration is incorrect. " +
218
- "Check the id, secret and scopes for correctness."));
215
+ else {
216
+ throw new logger_1.FatalError("The OAuth client configuration is incorrect. " +
217
+ "Check the id, secret and allowed scopes for this client.");
219
218
  }
220
219
  }
221
- profile.scopes = [...clientCredentialsScopes];
222
220
  break;
223
221
  default:
224
222
  logger_1.logger.error(new logger_1.FatalError("Unsupported profile type"));
@@ -307,16 +305,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
307
305
  });
308
306
  });
309
307
  }
310
- checkIfMissingProfile(profileName, reject) {
311
- if (!profileName && (!process.env.TEAM_URL || !process.env.API_TOKEN)) {
312
- reject("Profile not found");
308
+ checkIfMissingProfile(profileName) {
309
+ if (!profileName) {
310
+ return true;
313
311
  }
314
312
  }
315
313
  mapCelonisEnvProfile() {
316
- if (!process.env.CELONIS_URL) {
317
- return;
314
+ let celonisUrl = process.env.CELONIS_URL;
315
+ if (!celonisUrl.startsWith("http://") && !celonisUrl.startsWith("https://")) {
316
+ celonisUrl = `https://${celonisUrl}`;
318
317
  }
319
- process.env.TEAM_URL = process.env.CELONIS_URL;
318
+ process.env.TEAM_URL = celonisUrl;
320
319
  if (process.env.CELONIS_API_TOKEN) {
321
320
  process.env.API_TOKEN = process.env.CELONIS_API_TOKEN;
322
321
  }
@@ -324,6 +323,75 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
324
323
  delete process.env.API_TOKEN;
325
324
  }
326
325
  }
326
+ /**
327
+ * Returns all non-empty combinations of scopes, ordered by size descending (4, then 3, 2, 1).
328
+ * Order within a combination does not matter; each set is tried once.
329
+ */
330
+ getScopeCombinationsOrderedBySize(scopes) {
331
+ function combinations(arr, k) {
332
+ if (k === 0)
333
+ return [[]];
334
+ if (k > arr.length)
335
+ return [];
336
+ const result = [];
337
+ for (let i = 0; i <= arr.length - k; i++) {
338
+ const rest = combinations(arr.slice(i + 1), k - 1);
339
+ rest.forEach(r => result.push([arr[i], ...r]));
340
+ }
341
+ return result;
342
+ }
343
+ return [
344
+ ...combinations(scopes, 4),
345
+ ...combinations(scopes, 3),
346
+ ...combinations(scopes, 2),
347
+ ...combinations(scopes, 1),
348
+ ];
349
+ }
350
+ /**
351
+ * Tries to obtain a client_credentials token. First tries with all scopes (including
352
+ * action-engine.projects); if no token is returned, tries again without action-engine.projects.
353
+ * Returns { tokenSet, scopes } or null if no grant succeeded.
354
+ */
355
+ tryClientCredentialsGrant(issuer, profile, tokenEndpointAuthMethod) {
356
+ return __awaiter(this, void 0, void 0, function* () {
357
+ const Client = issuer.Client;
358
+ const client = new Client({
359
+ client_id: profile.clientId,
360
+ client_secret: profile.clientSecret,
361
+ token_endpoint_auth_method: tokenEndpointAuthMethod,
362
+ });
363
+ const scopeAttempts = this.getScopeCombinationsOrderedBySize(OAUTH_SCOPES);
364
+ for (const scopeList of scopeAttempts) {
365
+ try {
366
+ const tokenSet = yield client.grant({
367
+ grant_type: "client_credentials",
368
+ scope: scopeList.join(" "),
369
+ });
370
+ if (tokenSet && tokenSet.access_token) {
371
+ const scopes = this.extractScopesFromTokenSet(tokenSet, scopeList);
372
+ return { tokenSet, scopes };
373
+ }
374
+ }
375
+ catch (_e) {
376
+ // This scope set failed (e.g. invalid_scope); try next
377
+ }
378
+ }
379
+ return null;
380
+ });
381
+ }
382
+ /**
383
+ * Extracts granted scopes from the token response (OAuth 2.0 scope parameter).
384
+ * Used at profile creation so we store the scopes the server actually granted for this client.
385
+ */
386
+ extractScopesFromTokenSet(tokenSet, fallbackScopes) {
387
+ if (tokenSet.scope && typeof tokenSet.scope === "string") {
388
+ const scopes = tokenSet.scope.trim().split(/\s+/).filter(Boolean);
389
+ if (scopes.length > 0) {
390
+ return scopes;
391
+ }
392
+ }
393
+ return [...fallbackScopes];
394
+ }
327
395
  }
328
396
  exports.ProfileService = ProfileService;
329
397
  exports.profileService = new ProfileService();
@@ -8,6 +8,7 @@ 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
+ findPackagesByKeysAndVersion(packageKeysWithVersion: string[], withDependencies?: boolean): Promise<PackageExportTransport[]>;
11
12
  exportPackages(packageKeys: string[], withDependencies: boolean): Promise<Buffer>;
12
13
  exportPackagesByVersions(packageKeysWithVersion: string[], withDependencies: boolean): Promise<Buffer>;
13
14
  batchExportPackagesMetadata(packageKeys: string[]): Promise<PackageMetadataExportTransport[]>;
@@ -6,7 +6,8 @@ export declare class BatchImportExportService {
6
6
  private gitService;
7
7
  constructor(context: Context);
8
8
  listActivePackages(flavors: string[]): Promise<void>;
9
- findAndExportListOfActivePackages(flavors: string[], packageKeys: string[], withDependencies: boolean): Promise<void>;
9
+ findAndExportListOfPackages(flavors: string[], packageKeys: string[], keysByVersion: string[], withDependencies: boolean): Promise<void>;
10
+ listPackagesByKeysWithVersion(keysByVersion: string[], withDependencies: boolean): Promise<void>;
10
11
  batchExportPackages(packageKeys: string[], packageKeysByVersion: string[], withDependencies: boolean, gitBranch: string, unzip: boolean): Promise<void>;
11
12
  batchExportPackagesMetadata(packageKeys: string[], jsonResponse: boolean): Promise<void>;
12
13
  batchImportPackages(sourcePath: string, overwrite: boolean, gitBranch: string): Promise<void>;
@@ -4,7 +4,7 @@ export declare class ConfigCommandService {
4
4
  private variableService;
5
5
  private diffService;
6
6
  constructor(context: Context);
7
- listActivePackages(jsonResponse: boolean, flavors: string[], withDependencies: boolean, packageKeys: string[], variableValue: string, variableType: string): Promise<void>;
7
+ listPackages(jsonResponse: boolean, flavors: string[], withDependencies: boolean, packageKeys: string[], keysByVersion: string[], variableValue: string, variableType: string): Promise<void>;
8
8
  listVariables(jsonResponse: boolean, keysByVersion: string[], keysByVersionFile: string): Promise<void>;
9
9
  batchExportPackages(packageKeys: string[], packageKeysByVersion: string[], withDependencies: boolean, gitBranch: string, unzip: boolean): Promise<void>;
10
10
  batchExportPackagesMetadata(packageKeys: string[], jsonResponse: boolean): Promise<void>;
@@ -5,7 +5,7 @@ import { Configurator, IModule } from "../../core/command/module-handler";
5
5
  import { Context } from "../../core/command/cli-context";
6
6
  declare class Module extends IModule {
7
7
  register(context: Context, configurator: Configurator): void;
8
- private listActivePackages;
8
+ private listPackages;
9
9
  private batchExportPackages;
10
10
  private batchExportPackagesMetadata;
11
11
  private getPackageVersion;
@@ -8,6 +8,4 @@ export declare class PackageCommandService {
8
8
  pushPackage(spaceKey: string, fileName: string, newKey: string, overwrite: boolean): Promise<void>;
9
9
  pushPackages(spaceKey: string): Promise<void>;
10
10
  listPackages(jsonResponse: boolean, includeDependencies: boolean, packageKeys: string[]): Promise<void>;
11
- batchExportPackages(packageKeys: string[], includeDependencies: boolean, excludeActionFlows?: boolean): Promise<void>;
12
- batchImportPackages(spaceMappings: string[], dataModelMappingsFilePath: string, exportedPackagesFile: string, overwrite: boolean, excludeActionFlows?: boolean): Promise<void>;
13
11
  }
@@ -5,8 +5,6 @@ import { Configurator, IModule } from "../../core/command/module-handler";
5
5
  import { Context } from "../../core/command/cli-context";
6
6
  declare class Module extends IModule {
7
7
  register(context: Context, configurator: Configurator): void;
8
- private batchExportPackages;
9
- private batchImportPackages;
10
8
  private listPackages;
11
9
  private listSpaces;
12
10
  private listAssets;
@@ -1,37 +1,16 @@
1
1
  import { Context } from "../../../core/command/cli-context";
2
2
  import { PackageDependencyTransport } from "../interfaces/package-manager.interfaces";
3
3
  import { BatchExportNodeTransport } from "../interfaces/batch-export-node.interfaces";
4
- import { ManifestNodeTransport } from "../interfaces/manifest.interface";
5
4
  export declare class PackageService {
6
5
  protected readonly fileDownloadedMessage = "File downloaded successfully. New filename: ";
7
6
  private packageApi;
8
- private nodeApi;
9
7
  private packageDependenciesApi;
10
8
  private dataModelService;
11
9
  private variableService;
12
- private spaceService;
13
10
  constructor(context: Context);
14
11
  listPackages(): Promise<void>;
15
12
  findAndExportListOfAllPackages(includeDependencies: boolean, packageKeys: string[]): Promise<void>;
16
- batchImportPackages(spaceMappings: string[], dataModelMappingsFilePath: string, exportedPackagesFile: string, overwrite: boolean, excludeActionFlows: boolean): Promise<void>;
17
- private checkNodeForCircularDependency;
18
- private importPackage;
19
- private importPackageVersion;
20
- private isLatestVersion;
21
- private importDependencyPackages;
22
- private checkIfPackageVersionHasBeenImported;
23
- private createBodyForImport;
24
- private getTargetSpaceForExportedPackage;
25
- private updateDependencyVersions;
26
- publishPackage(packageToImport: ManifestNodeTransport): Promise<void>;
27
- batchExportPackages(packageKeys: string[], includeDependencies: boolean, excludeActionFlows?: boolean): Promise<void>;
28
13
  getNodesWithActiveVersion(nodes: BatchExportNodeTransport[]): Promise<BatchExportNodeTransport[]>;
29
14
  getPackagesWithDependencies(draftIdByNodeId: Map<string, string>): Promise<Map<string, PackageDependencyTransport[]>>;
30
- private getDependencyPackages;
31
- private nodeHasBeenResolvedBefore;
32
15
  private exportListOfPackages;
33
- private exportPackagesAndAssets;
34
- private exportToZip;
35
- private exportManifestOfPackages;
36
- private readManifestFile;
37
16
  }
@@ -23,5 +23,21 @@ export declare class ProfileService {
23
23
  private tryKeyAuthentication;
24
24
  private checkIfMissingProfile;
25
25
  private mapCelonisEnvProfile;
26
+ /**
27
+ * Returns all non-empty combinations of scopes, ordered by size descending (4, then 3, 2, 1).
28
+ * Order within a combination does not matter; each set is tried once.
29
+ */
30
+ private getScopeCombinationsOrderedBySize;
31
+ /**
32
+ * Tries to obtain a client_credentials token. First tries with all scopes (including
33
+ * action-engine.projects); if no token is returned, tries again without action-engine.projects.
34
+ * Returns { tokenSet, scopes } or null if no grant succeeded.
35
+ */
36
+ private tryClientCredentialsGrant;
37
+ /**
38
+ * Extracts granted scopes from the token response (OAuth 2.0 scope parameter).
39
+ * Used at profile creation so we store the scopes the server actually granted for this client.
40
+ */
41
+ private extractScopesFromTokenSet;
26
42
  }
27
43
  export declare const profileService: ProfileService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celonis/content-cli",
3
- "version": "1.4.1",
3
+ "version": "1.6.0",
4
4
  "description": "CLI Tool to help manage content in Celonis Platform",
5
5
  "main": "content-cli.js",
6
6
  "bin": {
@@ -18,9 +18,9 @@
18
18
  "node": ">=18.20.5"
19
19
  },
20
20
  "dependencies": {
21
- "@datadog/datadog-ci": "2.48.0",
22
21
  "adm-zip": "0.5.14",
23
- "axios": "1.8.4",
22
+ "uuid": "9.0.1",
23
+ "axios": "1.13.5",
24
24
  "commander": "13.1.0",
25
25
  "form-data": "4.0.4",
26
26
  "openid-client": "5.6.1",