diff --git a/package-lock.json b/package-lock.json index 6638c98..0593cba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,23 +1,23 @@ { "name": "@contentstack/apps-cli", - "version": "1.0.1", + "version": "1.0.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@contentstack/apps-cli", - "version": "1.0.1", + "version": "1.0.3", "license": "MIT", "dependencies": { - "@contentstack/cli-command": "^1.2.9", - "@contentstack/cli-utilities": "^1.4.5", + "@contentstack/cli-command": "^1.2.12", + "@contentstack/cli-utilities": "^1.5.1", "adm-zip": "^0.5.10", "chalk": "^4.1.2", "lodash": "^4.17.21", "open": "^9.1.0", "shelljs": "^0.8.5", "tmp": "^0.2.1", - "winston": "^3.9.0" + "winston": "^3.10.0" }, "bin": { "app": "bin/run" @@ -515,11 +515,11 @@ } }, "node_modules/@contentstack/cli-command": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@contentstack/cli-command/-/cli-command-1.2.9.tgz", - "integrity": "sha512-kmAIWUtEib6VnME2A2RN/ltLrVzaijgvczbMFQoFJZBvHkyZQ8yn+406EY1sq/DB8vGuHYRz+4RMIZ8G8y034g==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@contentstack/cli-command/-/cli-command-1.2.12.tgz", + "integrity": "sha512-CKyZzjXCFdnUomt5bLv497ZNgr9i2KMoXUluFpiyRTQpdB5naE3qWz1P6KHemeDahjmPiHE/IQzJcrng1vH4og==", "dependencies": { - "@contentstack/cli-utilities": "^1.4.5", + "@contentstack/cli-utilities": "~1.5.2", "contentstack": "^3.10.1" }, "engines": { @@ -527,12 +527,12 @@ } }, "node_modules/@contentstack/cli-utilities": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@contentstack/cli-utilities/-/cli-utilities-1.4.5.tgz", - "integrity": "sha512-rAOHX6ZKfBfdRA0VtIrs3a2QOZIq3yIlNSLY0cqksRDvqvnsUa0wwyKjew2pvDkP4tVXOrVm5S5rjwW7a74MIw==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@contentstack/cli-utilities/-/cli-utilities-1.5.2.tgz", + "integrity": "sha512-WwH3PRH/xdmb1QBvlWJ0fwnkNtEhkFY87GJkMNI1z/xz+wrw50I/YJBV0aVB2ZqRFJ9GI1bvieG5aib8v0srcw==", "dependencies": { - "@contentstack/management": "^1.8.0", - "@oclif/core": "^2.8.2", + "@contentstack/management": "~1.10.0", + "@oclif/core": "^2.9.3", "axios": "1.3.4", "chalk": "^4.0.0", "cli-cursor": "^3.1.0", @@ -544,6 +544,7 @@ "inquirer-search-checkbox": "^1.0.0", "inquirer-search-list": "^1.2.6", "lodash": "^4.17.15", + "mkdirp": "^1.0.4", "open": "^8.4.2", "ora": "^5.4.0", "rxjs": "^6.6.7", @@ -601,41 +602,19 @@ } }, "node_modules/@contentstack/management": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@contentstack/management/-/management-1.8.0.tgz", - "integrity": "sha512-rKI9CEwwmh8L0f5OaicjBlty0O77BT3KiHkPj23rJ2lLWlas7RlWaVhbavXJASSpS0w1FWx8+BmGwkaAoRVyRg==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@contentstack/management/-/management-1.10.2.tgz", + "integrity": "sha512-jO24EqcCJhOjqdsqw8y3T0SPPAd0DG4BByjUcV0S28W2yoa8aBbcjcbZioRPzRLYKTmZWsAZissl18cIJm5djQ==", "dependencies": { - "axios": "^0.27.2", + "axios": "^1.4.0", "form-data": "^3.0.1", "lodash": "^4.17.21", - "qs": "^6.10.3" + "qs": "^6.11.2" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/@contentstack/management/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/@contentstack/management/node_modules/axios/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/@contentstack/utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@contentstack/utils/-/utils-1.3.0.tgz", @@ -2378,7 +2357,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", - "dev": true, "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -2389,7 +2367,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -7503,7 +7480,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -11689,9 +11665,9 @@ } }, "node_modules/winston": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.9.0.tgz", - "integrity": "sha512-jW51iW/X95BCW6MMtZWr2jKQBP4hV5bIDq9QrIjfDk6Q9QuxvTKEAlpUNAzP+HYHFFCeENhph16s0zEunu4uuQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.10.0.tgz", + "integrity": "sha512-nT6SIDaE9B7ZRO0u3UvdrimG0HkB7dSTAgInQnNR2SOPJ4bvq5q79+pXLftKmP52lJGW15+H5MCK0nM9D3KB/g==", "dependencies": { "@colors/colors": "1.5.0", "@dabh/diagnostics": "^2.0.2", @@ -13346,21 +13322,21 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" }, "@contentstack/cli-command": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@contentstack/cli-command/-/cli-command-1.2.9.tgz", - "integrity": "sha512-kmAIWUtEib6VnME2A2RN/ltLrVzaijgvczbMFQoFJZBvHkyZQ8yn+406EY1sq/DB8vGuHYRz+4RMIZ8G8y034g==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@contentstack/cli-command/-/cli-command-1.2.12.tgz", + "integrity": "sha512-CKyZzjXCFdnUomt5bLv497ZNgr9i2KMoXUluFpiyRTQpdB5naE3qWz1P6KHemeDahjmPiHE/IQzJcrng1vH4og==", "requires": { - "@contentstack/cli-utilities": "^1.4.5", + "@contentstack/cli-utilities": "~1.5.2", "contentstack": "^3.10.1" } }, "@contentstack/cli-utilities": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@contentstack/cli-utilities/-/cli-utilities-1.4.5.tgz", - "integrity": "sha512-rAOHX6ZKfBfdRA0VtIrs3a2QOZIq3yIlNSLY0cqksRDvqvnsUa0wwyKjew2pvDkP4tVXOrVm5S5rjwW7a74MIw==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@contentstack/cli-utilities/-/cli-utilities-1.5.2.tgz", + "integrity": "sha512-WwH3PRH/xdmb1QBvlWJ0fwnkNtEhkFY87GJkMNI1z/xz+wrw50I/YJBV0aVB2ZqRFJ9GI1bvieG5aib8v0srcw==", "requires": { - "@contentstack/management": "^1.8.0", - "@oclif/core": "^2.8.2", + "@contentstack/management": "~1.10.0", + "@oclif/core": "^2.9.3", "axios": "1.3.4", "chalk": "^4.0.0", "cli-cursor": "^3.1.0", @@ -13372,6 +13348,7 @@ "inquirer-search-checkbox": "^1.0.0", "inquirer-search-list": "^1.2.6", "lodash": "^4.17.15", + "mkdirp": "^1.0.4", "open": "^8.4.2", "ora": "^5.4.0", "rxjs": "^6.6.7", @@ -13419,37 +13396,14 @@ } }, "@contentstack/management": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@contentstack/management/-/management-1.8.0.tgz", - "integrity": "sha512-rKI9CEwwmh8L0f5OaicjBlty0O77BT3KiHkPj23rJ2lLWlas7RlWaVhbavXJASSpS0w1FWx8+BmGwkaAoRVyRg==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@contentstack/management/-/management-1.10.2.tgz", + "integrity": "sha512-jO24EqcCJhOjqdsqw8y3T0SPPAd0DG4BByjUcV0S28W2yoa8aBbcjcbZioRPzRLYKTmZWsAZissl18cIJm5djQ==", "requires": { - "axios": "^0.27.2", + "axios": "^1.4.0", "form-data": "^3.0.1", "lodash": "^4.17.21", - "qs": "^6.10.3" - }, - "dependencies": { - "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - }, - "dependencies": { - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - } - } - } + "qs": "^6.11.2" } }, "@contentstack/utils": { @@ -14852,7 +14806,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", - "dev": true, "requires": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -14863,7 +14816,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -18680,8 +18632,7 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "mkdirp-infer-owner": { "version": "2.0.0", @@ -21833,9 +21784,9 @@ } }, "winston": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.9.0.tgz", - "integrity": "sha512-jW51iW/X95BCW6MMtZWr2jKQBP4hV5bIDq9QrIjfDk6Q9QuxvTKEAlpUNAzP+HYHFFCeENhph16s0zEunu4uuQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.10.0.tgz", + "integrity": "sha512-nT6SIDaE9B7ZRO0u3UvdrimG0HkB7dSTAgInQnNR2SOPJ4bvq5q79+pXLftKmP52lJGW15+H5MCK0nM9D3KB/g==", "requires": { "@colors/colors": "1.5.0", "@dabh/diagnostics": "^2.0.2", diff --git a/package.json b/package.json index d1bd7cc..586117f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/apps-cli", - "version": "1.0.1", + "version": "1.0.3", "description": "App ClI", "author": "Contentstack CLI", "homepage": "https://github.com/contentstack/contentstack-apps-cli", @@ -17,15 +17,15 @@ "/oclif.manifest.json" ], "dependencies": { - "@contentstack/cli-command": "^1.2.9", - "@contentstack/cli-utilities": "^1.4.5", + "@contentstack/cli-command": "^1.2.12", + "@contentstack/cli-utilities": "^1.5.1", "adm-zip": "^0.5.10", "chalk": "^4.1.2", "lodash": "^4.17.21", "open": "^9.1.0", "shelljs": "^0.8.5", "tmp": "^0.2.1", - "winston": "^3.9.0" + "winston": "^3.10.0" }, "devDependencies": { "@oclif/test": "^2.0.3", diff --git a/src/commands/app/uninstall.ts b/src/commands/app/uninstall.ts index bc045db..679c33b 100644 --- a/src/commands/app/uninstall.ts +++ b/src/commands/app/uninstall.ts @@ -1,6 +1,6 @@ import { BaseCommand } from "./base-command"; import { flags } from "@contentstack/cli-utilities"; -import { getOrg, getApp, fetchApp } from "../../util"; +import { getOrg, fetchApp, getInstalledApps } from "../../util"; import { commonMsg, uninstallAppMsg } from "../../messages"; import { UninstallAppFactory } from "../../factories/uninstall-app-factory"; @@ -34,7 +34,7 @@ export default class Uninstall extends BaseCommand { // fetch app details if (!this.flags['app-uid']) { - app = await getApp(this.flags, this.sharedConfig.org, {managementSdk: this.managementAppSdk, log: this.log}) + app = await getInstalledApps(this.flags, this.sharedConfig.org, {managementSdk: this.managementAppSdk, log: this.log}) } else { app = await fetchApp(this.flags, this.sharedConfig.org, {managementSdk: this.managementAppSdk, log: this.log}) } diff --git a/src/util/common-utils.ts b/src/util/common-utils.ts index b45f566..39aef40 100644 --- a/src/util/common-utils.ts +++ b/src/util/common-utils.ts @@ -179,6 +179,45 @@ function uninstallApp(flags: FlagInput, orgUid: string, options: CommonOptions, .uninstall() } +async function fetchInstalledApps(flags: FlagInput, orgUid: string, options: CommonOptions) { + const { managementSdk, log } = options; + const apps = (await fetchApps(flags, orgUid, options)) || []; + let batchRequests = []; + // Make calls in batch. 10 requests per batch allowed. + while (apps.length) { + batchRequests.push(apps.splice(0, 10)); + } + const results = []; + for (const batch of batchRequests) { + const promises = batch.map(async (app) => { + try { + const installations = await managementSdk + .organization(orgUid) + .app(app.uid) + .installation() + .findAll(); + return installations.items.length ? installations.items : null; + } + catch (error) { + log("Unable to fetch installations.", "warn"); + log(error, "error"); + throw error; + } + }); + results.push(await Promise.all(promises)); + } + for (let i = batchRequests.length - 1; i >= 0; i--) { + const batchLength = batchRequests[i].length; + for (let j = batchLength - 1; j >= 0; j--) { + if (!results[i][j]) { + batchRequests[i].splice(j, 1); + results[i].splice(j, 1); + } + } + } + return batchRequests.flat(); +} + export { getOrganizations, getOrgAppUiLocation, @@ -189,5 +228,6 @@ export { installApp, getStacks, fetchStack, - uninstallApp + uninstallApp, + fetchInstalledApps, }; diff --git a/src/util/inquirer.ts b/src/util/inquirer.ts index a6cd0e4..df3eeab 100644 --- a/src/util/inquirer.ts +++ b/src/util/inquirer.ts @@ -16,9 +16,10 @@ import messages, { $t, commonMsg, errors, uninstallAppMsg } from "../messages"; import { CommonOptions, getOrganizations, - fetchApps, getStacks, - fetchAppInstallations + fetchAppInstallations, + fetchInstalledApps, + fetchApps } from "./common-utils"; /** @@ -103,7 +104,28 @@ async function getOrg(flags: FlagInput, options: CommonOptions) { async function getApp(flags: FlagInput, orgUid: string, options: CommonOptions) : Promise | undefined> { cliux.loader("Loading Apps"); - const apps = (await fetchApps(flags, orgUid, options)) || []; + const apps = (await fetchApps(flags, orgUid, options)); + cliux.loader("done"); + + if (apps.length === 0) { + throw new Error(messages.APPS_NOT_FOUND) + } + + flags.app = await cliux + .inquire({ + type: "search-list", + name: "App", + choices: apps, + message: messages.CHOOSE_APP + }) + .then((name) => apps.find(app => app.name === name)?.uid) + + return apps.find(app => app.uid === flags.app); +} + +async function getInstalledApps(flags: FlagInput, orgUid: string, options: CommonOptions) : Promise | undefined> { + cliux.loader("Loading Apps"); + const apps = (await fetchInstalledApps(flags, orgUid, options)); cliux.loader("done"); if (apps.length === 0) { @@ -201,7 +223,7 @@ async function getInstallation( // fetch stacks from where the app has to be uninstalled cliux.loader("done"); const stacks: Stack[] = await getStacks({managementSdk: managementSdkForStacks, log: options.log}, orgUid); - installations = populateMissingDataInInstallations(installations, stacks) + installations = populateMissingDataInInstallations(installations as [Installation], stacks) // To support uninstall all flag if (uninstallAll) { return installations.map(installation => installation.uid).join(',') @@ -249,6 +271,7 @@ export { getDirName, getDeveloperHubUrl, getApp, + getInstalledApps, getStack, - getInstallation + getInstallation, };