diff --git a/package.json b/package.json index d3a81d77..c7cbea82 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@celonis/content-cli", - "version": "0.13.4", + "version": "0.13.5", "description": "CLI Tool to help manage content in Celonis EMS", "main": "content-cli.js", "bin": { diff --git a/src/api/batch-import-export-api.ts b/src/api/batch-import-export-api.ts index c14d3840..ce23e145 100644 --- a/src/api/batch-import-export-api.ts +++ b/src/api/batch-import-export-api.ts @@ -21,6 +21,20 @@ class BatchImportExportApi { }); } + public findActivePackagesByVariableValue(flavors: string[], variableValue: string, variableType: string): Promise { + const queryParams = new URLSearchParams(); + + queryParams.set("variableValue", variableValue); + if (variableType) { + queryParams.set("variableType", variableType); + } + flavors.forEach(flavor => queryParams.append("flavors", flavor)) + + return httpClientV2.get(`/package-manager/api/core/packages/export/list-by-variable-value?${queryParams.toString()}`).catch(e => { + throw new FatalError(`Problem getting active packages by variable value: ${e}`); + }); + } + public findActivePackagesByKeys(packageKeys: string[], withDependencies: boolean = false): Promise { const queryParams = new URLSearchParams(); diff --git a/src/commands/config.command.ts b/src/commands/config.command.ts index f2ad14ed..b77071e2 100644 --- a/src/commands/config.command.ts +++ b/src/commands/config.command.ts @@ -4,7 +4,12 @@ import {diffService} from "../services/package-manager/diff-service"; export class ConfigCommand { - public async listActivePackages(jsonResponse: boolean, flavors: string[], withDependencies: boolean, packageKeys:string[]): Promise { + public async listActivePackages(jsonResponse: boolean, flavors: string[], withDependencies: boolean, packageKeys: string[], variableValue: string, variableType: string): Promise { + if (variableValue) { + await this.listPackagesByVariableValue(jsonResponse, flavors, variableValue, variableType); + return; + } + if (jsonResponse) { await batchImportExportService.findAndExportListOfActivePackages(flavors ?? [], packageKeys ?? [], withDependencies) } else { @@ -31,4 +36,12 @@ export class ConfigCommand { public diffPackages(file: string, hasChanges: boolean, jsonResponse: boolean): Promise { return diffService.diffPackages(file, hasChanges, jsonResponse); } + + private async listPackagesByVariableValue(jsonResponse: boolean, flavors: string[], variableValue: string, variableType: string): Promise { + if (jsonResponse) { + await batchImportExportService.findAndExportListOfActivePackagesByVariableValue(flavors ?? [], variableValue, variableType ) + } else { + await batchImportExportService.listActivePackagesByVariableValue(flavors ?? [], variableValue, variableType); + } + } } \ No newline at end of file diff --git a/src/content-cli-config.ts b/src/content-cli-config.ts index 060972b7..6908ed8c 100644 --- a/src/content-cli-config.ts +++ b/src/content-cli-config.ts @@ -14,8 +14,10 @@ export class Config { .option("--flavors ", "Lists only active packages of the given flavors") .option("--withDependencies", "Include dependencies", "") .option("--packageKeys ", "Lists only given package keys") + .option("--variableValue ", "Variable value for filtering packages by.") + .option("--variableType ", "Variable type for filtering packages by.") .action(async cmd => { - await new ConfigCommand().listActivePackages(cmd.json, cmd.flavors, cmd.withDependencies, cmd.packageKeys); + await new ConfigCommand().listActivePackages(cmd.json, cmd.flavors, cmd.withDependencies, cmd.packageKeys, cmd.variableValue, cmd.variableType); process.exit(); }); diff --git a/src/services/package-manager/batch-import-export-service.ts b/src/services/package-manager/batch-import-export-service.ts index b304d8d2..b52a4fff 100644 --- a/src/services/package-manager/batch-import-export-service.ts +++ b/src/services/package-manager/batch-import-export-service.ts @@ -95,6 +95,21 @@ class BatchImportExportService { logger.info("Config import report file: " + reportFileName); } + public async findAndExportListOfActivePackagesByVariableValue(flavors: string[], variableValue: string, variableType: string): Promise { + let packagesToExport = await batchImportExportApi.findActivePackagesByVariableValue(flavors, variableValue, variableType); + + packagesToExport = await studioService.getExportPackagesWithStudioData(packagesToExport, false); + + this.exportListOfPackages(packagesToExport); + } + + public async listActivePackagesByVariableValue(flavors: string[], variableValue: string, variableType: string) : Promise { + const packagesByVariableValue = await batchImportExportApi.findActivePackagesByVariableValue(flavors, variableValue, variableType); + packagesByVariableValue.forEach(pkg => { + logger.info(`${pkg.name} - Key: "${pkg.key}"`) + }); + } + private exportListOfPackages(packages: PackageExportTransport[]): void { const filename = uuidv4() + ".json"; fileService.writeToFileWithGivenName(JSON.stringify(packages), filename); diff --git a/tests/config/config-list.spec.ts b/tests/config/config-list.spec.ts index d3657f8e..53433907 100644 --- a/tests/config/config-list.spec.ts +++ b/tests/config/config-list.spec.ts @@ -30,7 +30,7 @@ describe("Config list", () => { mockAxiosGet("https://myTeam.celonis.cloud/package-manager/api/core/packages/export/list?" + urlParams.toString(), [firstPackage, secondPackage]); - await new ConfigCommand().listActivePackages(false, flavorsArray, false, []); + await new ConfigCommand().listActivePackages(false, flavorsArray, false, [], null, null); expect(testTransport.logMessages.length).toBe(2); expect(testTransport.logMessages[0].message).toContain(`${firstPackage.name} - Key: "${firstPackage.key}"`); @@ -47,7 +47,7 @@ describe("Config list", () => { mockAxiosGet("https://myTeam.celonis.cloud/package-manager/api/core/packages/export/list?withDependencies=false", [{...firstPackage}, {...secondPackage}]); mockAxiosGet("https://myTeam.celonis.cloud/package-manager/api/packages/with-variable-assignments?type=DATA_MODEL", [studioPackage]); - await new ConfigCommand().listActivePackages(true, [], false, []); + await new ConfigCommand().listActivePackages(true, [], false, [], null, null); const expectedFileName = testTransport.logMessages[0].message.split(FileService.fileDownloadedMessage)[1]; @@ -93,7 +93,7 @@ describe("Config list", () => { }; mockAxiosGet("https://myTeam.celonis.cloud/package-manager/api/compute-pools/data-models/details", [dataModelDetailResponse]); - await new ConfigCommand().listActivePackages(true, [], true, []); + await new ConfigCommand().listActivePackages(true, [], true, [], null, null); const expectedFileName = testTransport.logMessages[0].message.split(FileService.fileDownloadedMessage)[1]; @@ -118,7 +118,7 @@ describe("Config list", () => { mockAxiosGet("https://myTeam.celonis.cloud/package-manager/api/core/packages/export/list-by-keys?packageKeys=key-1&packageKeys=key-2&withDependencies=false", [{...firstPackage}, {...secondPackage}]); mockAxiosGet("https://myTeam.celonis.cloud/package-manager/api/packages/with-variable-assignments?type=DATA_MODEL", [studioPackage]); - await new ConfigCommand().listActivePackages(true, [], false, [firstPackage.key, secondPackage.key]); + await new ConfigCommand().listActivePackages(true, [], false, [firstPackage.key, secondPackage.key], null, null); const expectedFileName = testTransport.logMessages[0].message.split(FileService.fileDownloadedMessage)[1]; @@ -164,7 +164,7 @@ describe("Config list", () => { }; mockAxiosGet("https://myTeam.celonis.cloud/package-manager/api/compute-pools/data-models/details", [dataModelDetailResponse]); - await new ConfigCommand().listActivePackages(true, [], true, [firstPackage.key, secondPackage.key]); + await new ConfigCommand().listActivePackages(true, [], true, [firstPackage.key, secondPackage.key], null, null); const expectedFileName = testTransport.logMessages[0].message.split(FileService.fileDownloadedMessage)[1]; @@ -179,4 +179,37 @@ describe("Config list", () => { expect(exportedSecondPackage).toEqual(secondPackage); expect(exportedFirstPackage).toEqual({...firstPackage, datamodels: [{...dataModelDetailResponse}]}); }) + + it("Should list all packages filtered by variable value", async () => { + const firstPackage = PackageManagerApiUtils.buildPackageExportTransport("key-1", "name-1"); + const secondPackage = PackageManagerApiUtils.buildPackageExportTransport("key-2", "name-2"); + + + mockAxiosGet("https://myTeam.celonis.cloud/package-manager/api/core/packages/export/list-by-variable-value?variableValue=1", [{...firstPackage}, {...secondPackage}]); + mockAxiosGet("https://myTeam.celonis.cloud/package-manager/api/packages/with-variable-assignments?type=DATA_MODEL", []); + + await new ConfigCommand().listActivePackages(false, [], false, [], "1", null); + + expect(testTransport.logMessages.length).toBe(2); + expect(testTransport.logMessages[0].message).toContain(`${firstPackage.name} - Key: "${firstPackage.key}"`); + expect(testTransport.logMessages[1].message).toContain(`${secondPackage.name} - Key: "${secondPackage.key}"`); + }) + + it("Should export all packages for json response filtered by variable value", async () => { + const firstPackage = PackageManagerApiUtils.buildPackageExportTransport("key-1", "name-1"); + const secondPackage = PackageManagerApiUtils.buildPackageExportTransport("key-2", "name-2"); + + mockAxiosGet("https://myTeam.celonis.cloud/package-manager/api/core/packages/export/list-by-variable-value?variableValue=1", [{...firstPackage}, {...secondPackage}]); + mockAxiosGet("https://myTeam.celonis.cloud/package-manager/api/packages/with-variable-assignments?type=DATA_MODEL", []); + + await new ConfigCommand().listActivePackages(true, [], false, [], "1", null); + + const expectedFileName = testTransport.logMessages[0].message.split(FileService.fileDownloadedMessage)[1]; + + expect(mockWriteFileSync).toHaveBeenCalledWith(path.resolve(process.cwd(), expectedFileName), expect.any(String), {encoding: "utf-8"}); + + const exportedTransports = JSON.parse(mockWriteFileSync.mock.calls[0][1]) as PackageExportTransport[]; + expect(exportedTransports.length).toBe(2); + }) + }) \ No newline at end of file