From 515bb4a4652b7fe8e06c4897d31e0808784696df Mon Sep 17 00:00:00 2001 From: harshithad0703 Date: Fri, 26 Jul 2024 17:24:22 +0530 Subject: [PATCH 01/10] updated reinstall and deploy with marketplace calls --- src/commands/app/deploy.ts | 21 +++++++----- src/commands/app/reinstall.ts | 9 ++--- src/util/common-utils.ts | 63 ++++++++++++----------------------- 3 files changed, 37 insertions(+), 56 deletions(-) diff --git a/src/commands/app/deploy.ts b/src/commands/app/deploy.ts index 585ce80..1e2e5b1 100644 --- a/src/commands/app/deploy.ts +++ b/src/commands/app/deploy.ts @@ -70,7 +70,7 @@ export default class Deploy extends AppCLIBaseCommand { const apolloClient = await this.getApolloClient(); const projects = await getProjects(apolloClient); await this.handleAppDisconnect(projects); - + flags["hosting-type"] = flags["hosting-type"] || (await getHostingType()); const updateHostingPayload: UpdateHostingParams = { provider: "external", @@ -89,14 +89,18 @@ export default class Deploy extends AppCLIBaseCommand { config["name"] = config["name"] || app?.name; this.flags["launch-project"] = this.flags["launch-project"] || (await askProjectType()); - await this.handleHostingWithLaunch(config, updateHostingPayload, projects); + await this.handleHostingWithLaunch( + config, + updateHostingPayload, + projects + ); break; default: this.log("Please provide a valid Hosting Type.", "error"); return; } - if(this.flags["app-uid"]){ + if (this.flags["app-uid"]) { await updateApp( flags, this.sharedConfig.org, @@ -284,11 +288,10 @@ export default class Deploy extends AppCLIBaseCommand { if (!this.flags["yes"]) { throw new Error(deployAppMsg.APP_UPDATE_TERMINATION_MSG); } - await disconnectApp( - this.flags, - this.sharedConfig.org, - this.developerHubBaseUrl - ); + await disconnectApp(this.flags, this.sharedConfig.org, { + marketplaceSdk: this.marketplaceAppSdk, + log: this.log, + }); } } -} \ No newline at end of file +} diff --git a/src/commands/app/reinstall.ts b/src/commands/app/reinstall.ts index d1305b3..eee2c6a 100644 --- a/src/commands/app/reinstall.ts +++ b/src/commands/app/reinstall.ts @@ -102,12 +102,9 @@ export default class Reinstall extends AppCLIBaseCommand { }), "info" ); - await reinstallApp({ - flags: this.flags, - type: appType, - developerHubBaseUrl: this.developerHubBaseUrl, - orgUid: this.sharedConfig.org, - manifestUid: this.flags["app-uid"], + await reinstallApp(this.flags, this.sharedConfig.org, appType, { + marketplaceSdk: this.marketplaceAppSdk, + log: this.log, }); this.log( $t(reinstallAppMsg.APP_REINSTALLED_SUCCESSFULLY, { diff --git a/src/util/common-utils.ts b/src/util/common-utils.ts index 5aa3807..860c218 100644 --- a/src/util/common-utils.ts +++ b/src/util/common-utils.ts @@ -10,7 +10,6 @@ import { HttpClient, } from "@contentstack/cli-utilities"; import { projectsQuery } from "../graphql/queries"; -import { apiRequestHandler } from "./api-request-handler"; import { AppLocation, Extension, @@ -166,34 +165,23 @@ function installApp( }); } -async function reinstallApp(params: { - flags: FlagInput; - type: string; - developerHubBaseUrl: string; - orgUid: string; - manifestUid: string; -}): Promise { - const { type, developerHubBaseUrl, flags, orgUid, manifestUid } = params; - const payload = { - target_type: type, - target_uid: (flags["stack-api-key"] as any) || orgUid, - }; - - const url = `https://${developerHubBaseUrl}/manifests/${manifestUid}/reinstall`; - try { - const result = await apiRequestHandler({ - orgUid, - payload, - url, - method: "PUT", +function reinstallApp( + flags: FlagInput, + orgUid: string, + type: string, + options: MarketPlaceOptions +) { + const { marketplaceSdk } = options; + return marketplaceSdk + .marketplace(orgUid) + .app(flags["app-uid"] as any) + .reinstall({ + targetUid: (flags["stack-api-key"] as any) || orgUid, + targetType: type as any, }); - return result; - } catch (err) { - throw err; - } } -function fetchStack(flags: FlagInput, options: CommonOptions) { +function fetchStack(flags: FlagInput, options: CommonOptions): Promise { const { managementSdk } = options; return managementSdk .stack({ api_key: flags["stack-api-key"] as any }) @@ -363,21 +351,14 @@ function setupConfig(configPath: string) { async function disconnectApp( flags: FlagInput, orgUid: string, - developerHubBaseUrl: string -) { - const appUid: any = flags["app-uid"]; - const url = `https://${developerHubBaseUrl}/manifests/${appUid}/hosting/disconnect`; - try { - const result = await apiRequestHandler({ - orgUid, - payload: { provider: "launch" }, - url, - method: "PATCH", - }); - return result; - } catch (err) { - throw err; - } + options: MarketPlaceOptions +): Promise { + const { marketplaceSdk } = options; + return marketplaceSdk + .marketplace(orgUid) + .app(flags["app-uid"] as any) + .hosting() + .disconnect({ provider: "launch" }); } function formatUrl(url: string): string { From 263ceb2cf4eaa4196ce048d2a0133f6218ed47c9 Mon Sep 17 00:00:00 2001 From: harshithad0703 Date: Tue, 30 Jul 2024 15:03:51 +0530 Subject: [PATCH 02/10] updated create test cases --- test/unit/commands/app/create.test.ts | 79 ++++++++++++++++++++---- test/unit/commands/app/reinstall.test.ts | 4 +- test/unit/config/manifest.json | 29 +++++++-- 3 files changed, 93 insertions(+), 19 deletions(-) diff --git a/test/unit/commands/app/create.test.ts b/test/unit/commands/app/create.test.ts index cedd9ea..6d04c9a 100644 --- a/test/unit/commands/app/create.test.ts +++ b/test/unit/commands/app/create.test.ts @@ -12,6 +12,7 @@ import config from "../../../../src/config"; import messages from "../../../../src/messages"; import * as mock from "../../mock/common.mock.json"; import manifestData from "../../../../src/config/manifest.json"; +import manifestData2 from "../../../unit/config/manifest.json"; import { getDeveloperHubUrl } from "../../../../src/util/inquirer"; const { origin, pathname } = new URL(config.appBoilerplateGithubUrl); @@ -25,6 +26,7 @@ describe("app:create", () => { axios.defaults.adapter = "http"; }); + //working describe("Creating a stack app using a boilerplate flow", () => { test .stdout({ print: process.env.PRINT === "true" || false }) @@ -64,13 +66,20 @@ describe("app:create", () => { data: { ...manifestData, name: "test-app", version: 1 }, }) ) - .command(["app:create", "--data-dir", process.cwd()]) + .command([ + "app:create", + "--name", + "test-app", + "--data-dir", + process.cwd(), + ]) .do(({ stdout }) => expect(stdout).to.contain(messages.APP_CREATION_SUCCESS) ) .it("should create a stack level app"); }); + // //working describe("Creating a organization app using a boilerplate flow", () => { test .stdout({ print: process.env.PRINT === "true" || false }) @@ -106,16 +115,23 @@ describe("app:create", () => { .nock(`https://${developerHubBaseUrl}`, (api) => api .post("/manifests", { - ...manifestData, + ...manifestData2, name: "test-app", target_type: "organization", }) + .reply(200, { - data: { ...manifestData, name: "test-app", version: 1 }, + data: { + ...manifestData2, + name: "test-app", + version: 1, + }, }) ) .command([ "app:create", + "--name", + "test-app", "--data-dir", process.cwd(), "--app-type", @@ -209,6 +225,15 @@ describe("app:create", () => { .stdout({ print: process.env.PRINT === "true" || false }) .stub(ux.action, "stop", () => {}) .stub(ux.action, "start", () => {}) + .stub(shelljs, "cd", () => {}) + .stub(shelljs, "exec", (...args) => { + const [, , callback]: any = args; + callback(0); + }) + .stub(fs, "renameSync", () => new PassThrough()) + .stub(fs, "writeFileSync", () => new PassThrough()) + .stub(fs, "createWriteStream", () => new PassThrough()) + .stub(tmp, "fileSync", () => ({ name: zipPath })) .stub(cliux, "inquire", async (...args: any) => { const [prompt]: any = args; const cases = { @@ -219,16 +244,39 @@ describe("app:create", () => { return (cases as Record)[prompt.name]; }) + .nock(origin, (api) => + api.get(pathname).reply(200, { data: "test-data" }) + ) .nock(region.cma, (api) => api .get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0") .reply(200, { organizations: mock.organizations }) ) .nock(`https://${developerHubBaseUrl}`, (api) => - api.post("/manifests", { ...manifestData, name: "test-app" }).reply(400) + api + .post("/manifests", { + ...manifestData2, + name: "test-app", + target_type: "organization", + }) + + .reply(200, { + data: { + ...manifestData2, + name: "test-app", + version: 1, + }, + }) ) - .command(["app:create", "--data-dir", process.cwd()]) - .exit(1) + .command([ + "app:create", + "--name", + "test-app", + "--data-dir", + process.cwd(), + "--app-type", + "organization", + ]) .do(({ stdout }) => expect(stdout).to.contain(messages.APP_CREATION_CONSTRAINT_FAILURE) ) @@ -260,6 +308,8 @@ describe("app:create", () => { ) .command([ "app:create", + "--name", + "test-app", "--data-dir", process.cwd(), "--config", @@ -272,6 +322,7 @@ describe("app:create", () => { .it("App creation should fail!"); }); + //working describe("Dependency installation failure", () => { test .stdout({ print: process.env.PRINT === "true" || false }) @@ -305,13 +356,17 @@ describe("app:create", () => { .reply(200, { organizations: mock.organizations }) ) .nock(`https://${developerHubBaseUrl}`, (api) => - api - .post("/manifests", { ...manifestData, name: "test-app" }) - .reply(200, { - data: { ...manifestData, name: "test-app", version: 1 }, - }) + api.post("/manifests", { ...manifestData }).reply(200, { + data: { ...manifestData, name: "test-app", version: 1 }, + }) ) - .command(["app:create", "--data-dir", process.cwd()]) + .command([ + "app:create", + "--name", + "test-app", + "--data-dir", + process.cwd(), + ]) .exit(1) .do(({ stdout }) => expect(stdout).to.contain("Dependency installation failed.!") diff --git a/test/unit/commands/app/reinstall.test.ts b/test/unit/commands/app/reinstall.test.ts index d34b546..0c784ba 100644 --- a/test/unit/commands/app/reinstall.test.ts +++ b/test/unit/commands/app/reinstall.test.ts @@ -2,7 +2,7 @@ import { ux, cliux, configHandler } from "@contentstack/cli-utilities"; import { expect, test } from "@oclif/test"; import * as mock from "../../mock/common.mock.json"; import messages, { $t } from "../../../../src/messages"; -import { getDeveloperHubUrl } from "../../../../lib/util/inquirer"; +import { getDeveloperHubUrl } from "../../../../src/util/inquirer"; const region: { cma: string; cda: string; name: string } = configHandler.get("region"); @@ -227,7 +227,7 @@ describe("app:reinstall", () => { describe("App is already latest version", () => { test - .stdout({ print: process.env.PRINT === "true" || false }) + .stdout({ print: true }) .stub(ux.action, "stop", () => {}) .stub(ux.action, "start", () => {}) .stub(cliux, "inquire", async (...args: any) => { diff --git a/test/unit/config/manifest.json b/test/unit/config/manifest.json index 3fd1dc1..679e26c 100644 --- a/test/unit/config/manifest.json +++ b/test/unit/config/manifest.json @@ -1,9 +1,28 @@ { - "version": 1, + "description": "", + "icon": "", "name": "test-app", - "uid": "app-uid-1", - "target_type": "stack", + "organization_uid": "", + "target_type": "", "visibility": "private", - "description": "test app", - "organization_uid": "test-uid-1" + "uid": "", + "hosting": { + "provider": "external", + "deployment_url": "http://localhost:3000" + }, + "version": 1, + "ui_location": { + "locations": [ + { + "type": "cs.org.config", + "meta": [ + { + "path": "/app-configuration", + "signed": true, + "enabled": true + } + ] + } + ] + } } From 517fb7044f1dab7eb53b4a8d2bbcfdbb1db95010 Mon Sep 17 00:00:00 2001 From: Aman Kumar Date: Thu, 1 Aug 2024 17:57:45 +0530 Subject: [PATCH 03/10] fix: handle undefined issue & org flag missing in help command --- README.md | 57 ++++++---- package-lock.json | 208 ++++++++++++++++++++++++++++++++-- package.json | 4 +- src/base-command.ts | 15 ++- src/commands/app/create.ts | 1 + src/commands/app/delete.ts | 1 + src/commands/app/deploy.ts | 1 + src/commands/app/get.ts | 1 + src/commands/app/index.ts | 7 +- src/commands/app/install.ts | 1 + src/commands/app/reinstall.ts | 1 + src/commands/app/uninstall.ts | 1 + src/commands/app/update.ts | 1 + src/util/inquirer.ts | 4 + 14 files changed, 255 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 7cdbd94..39a2d9e 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ $ npm install -g @contentstack/apps-cli $ csdx COMMAND running command... $ csdx (--version|-v) -@contentstack/apps-cli/1.3.0 darwin-arm64 node-v18.16.0 +@contentstack/apps-cli/1.3.1 darwin-arm64 node-v18.20.2 $ csdx --help [COMMAND] USAGE $ csdx COMMAND @@ -54,20 +54,22 @@ DESCRIPTION EXAMPLES $ csdx app:create - $ csdx app:get + $ csdx app:delete - $ csdx app:update + $ csdx app:deploy - $ csdx app:delete + $ csdx app:get $ csdx app:install + $ csdx app:reinstall + $ csdx app:uninstall - $ csdx app:reinstall + $ csdx app:update ``` -_See code: [src/commands/app/index.ts](https://github.com/contentstack/apps-cli/blob/v1.3.0/src/commands/app/index.ts)_ +_See code: [src/commands/app/index.ts](https://github.com/contentstack/apps-cli/blob/v1.3.1/src/commands/app/index.ts)_ ## `csdx app:create` @@ -76,7 +78,7 @@ Create a new app in Developer Hub and optionally clone a boilerplate locally. ``` USAGE $ csdx app:create [-n ] [--app-type stack|organization] [-c ] [-d ] [--boilerplate - ] + ] [--org ] FLAGS -c, --config= Path of the external config @@ -84,7 +86,9 @@ FLAGS -n, --name= Name of the app to be created --app-type=