@contentstack/apps-cli 1.0.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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +200 -0
  3. package/bin/dev +17 -0
  4. package/bin/dev.cmd +3 -0
  5. package/bin/run +5 -0
  6. package/bin/run.cmd +3 -0
  7. package/lib/commands/app/base-command.d.ts +51 -0
  8. package/lib/commands/app/base-command.js +123 -0
  9. package/lib/commands/app/create.d.ts +68 -0
  10. package/lib/commands/app/create.js +288 -0
  11. package/lib/commands/app/delete.d.ts +10 -0
  12. package/lib/commands/app/delete.js +72 -0
  13. package/lib/commands/app/get.d.ts +12 -0
  14. package/lib/commands/app/get.js +57 -0
  15. package/lib/commands/app/index.d.ts +7 -0
  16. package/lib/commands/app/index.js +35 -0
  17. package/lib/commands/app/install.d.ts +11 -0
  18. package/lib/commands/app/install.js +77 -0
  19. package/lib/commands/app/uninstall.d.ts +11 -0
  20. package/lib/commands/app/uninstall.js +51 -0
  21. package/lib/commands/app/update.d.ts +34 -0
  22. package/lib/commands/app/update.js +190 -0
  23. package/lib/config/index.d.ts +16 -0
  24. package/lib/config/index.js +20 -0
  25. package/lib/config/manifest.json +69 -0
  26. package/lib/index.d.ts +2 -0
  27. package/lib/index.js +3 -0
  28. package/lib/messages/index.d.ts +83 -0
  29. package/lib/messages/index.js +101 -0
  30. package/lib/types/app.d.ts +101 -0
  31. package/lib/types/app.js +29 -0
  32. package/lib/types/index.d.ts +2 -0
  33. package/lib/types/index.js +5 -0
  34. package/lib/types/utils.d.ts +18 -0
  35. package/lib/types/utils.js +2 -0
  36. package/lib/util/common-utils.d.ts +18 -0
  37. package/lib/util/common-utils.js +148 -0
  38. package/lib/util/fs.d.ts +2 -0
  39. package/lib/util/fs.js +36 -0
  40. package/lib/util/index.d.ts +4 -0
  41. package/lib/util/index.js +9 -0
  42. package/lib/util/inquirer.d.ts +34 -0
  43. package/lib/util/inquirer.js +198 -0
  44. package/lib/util/log.d.ts +41 -0
  45. package/lib/util/log.js +150 -0
  46. package/package.json +99 -0
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const tmp = tslib_1.__importStar(require("tmp"));
5
+ const adm_zip_1 = tslib_1.__importDefault(require("adm-zip"));
6
+ const pick_1 = tslib_1.__importDefault(require("lodash/pick"));
7
+ const shell = tslib_1.__importStar(require("shelljs"));
8
+ const merge_1 = tslib_1.__importDefault(require("lodash/merge"));
9
+ const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
10
+ const path_1 = require("path");
11
+ const fs_1 = require("fs");
12
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
13
+ const base_command_1 = require("./base-command");
14
+ const types_1 = require("../../types");
15
+ const messages_1 = require("../../messages");
16
+ const util_1 = require("../../util");
17
+ class Create extends base_command_1.BaseCommand {
18
+ async run() {
19
+ this.sharedConfig.org = this.flags.org;
20
+ this.sharedConfig.appName = this.flags.name;
21
+ this.appData = require(this.sharedConfig.manifestPath);
22
+ await this.flagsPromptQueue();
23
+ this.appData.name = this.sharedConfig.appName;
24
+ this.appData.target_type = this.flags["app-type"];
25
+ if (this.flags["app-type"] === types_1.AppType.ORGANIZATION) {
26
+ this.appData.ui_location.locations = (0, util_1.getOrgAppUiLocation)();
27
+ }
28
+ try {
29
+ if (this.flags.yes ||
30
+ (await cli_utilities_1.cliux.inquire({
31
+ type: "confirm",
32
+ name: "cloneBoilerplate",
33
+ message: this.messages.CONFIRM_CLONE_BOILERPLATE,
34
+ }))) {
35
+ await this.boilerplateFlow();
36
+ }
37
+ else {
38
+ await this.registerTheAppOnDeveloperHub(false);
39
+ }
40
+ }
41
+ catch (error) {
42
+ if ((error === null || error === void 0 ? void 0 : error.errorMessage) || (error === null || error === void 0 ? void 0 : error.message) || !(0, isEmpty_1.default)(error)) {
43
+ this.log((error === null || error === void 0 ? void 0 : error.errorMessage) || (error === null || error === void 0 ? void 0 : error.message) || error, "error");
44
+ }
45
+ this.exit(1);
46
+ }
47
+ }
48
+ /**
49
+ * @method boilerplateFlow
50
+ *
51
+ * @memberof Create
52
+ */
53
+ async boilerplateFlow() {
54
+ // NOTE Step 1: download the boilerplate app from GitHub
55
+ await this.unZipBoilerplate(await this.cloneBoilerplate());
56
+ tmp.setGracefulCleanup(); // NOTE If graceful cleanup is set, tmp will remove all controlled temporary objects on process exit
57
+ // NOTE Step 2: Registering the app
58
+ await this.registerTheAppOnDeveloperHub();
59
+ // NOTE Step 3: Install dependencies
60
+ cli_utilities_1.ux.action.start(this.messages.INSTALL_DEPENDENCIES);
61
+ await this.installDependencies();
62
+ cli_utilities_1.ux.action.stop();
63
+ this.log(this.$t(this.messages.START_APP_COMMAND, {
64
+ command: `cd ${this.sharedConfig.folderPath} && npm run start`,
65
+ }), "info");
66
+ }
67
+ /**
68
+ * @method promptQueue
69
+ *
70
+ * @memberof Create
71
+ */
72
+ async flagsPromptQueue() {
73
+ if ((0, isEmpty_1.default)(this.sharedConfig.appName)) {
74
+ this.sharedConfig.appName = await (0, util_1.getAppName)(this.sharedConfig.defaultAppName);
75
+ }
76
+ this.sharedConfig.org = await (0, util_1.getOrg)(this.flags, {
77
+ log: this.log,
78
+ managementSdk: this.managementSdk,
79
+ });
80
+ }
81
+ /**
82
+ * @method cloneBoilerplate
83
+ *
84
+ * @return {*} {Promise<string>}
85
+ * @memberof Create
86
+ */
87
+ async cloneBoilerplate() {
88
+ cli_utilities_1.ux.action.start(this.messages.CLONE_BOILERPLATE);
89
+ const tmpObj = tmp.fileSync();
90
+ const filePath = tmpObj.name;
91
+ const writer = (0, fs_1.createWriteStream)(filePath);
92
+ const response = await new cli_utilities_1.HttpClient({ responseType: "stream" }).get(this.sharedConfig.appBoilerplateGithubUrl);
93
+ response === null || response === void 0 ? void 0 : response.data.pipe(writer);
94
+ return new Promise((resolve, reject) => {
95
+ writer
96
+ .on("finish", function () {
97
+ resolve(filePath);
98
+ cli_utilities_1.ux.action.stop();
99
+ })
100
+ .on("error", () => {
101
+ reject(this.messages.FILE_GENERATION_FAILURE);
102
+ });
103
+ });
104
+ }
105
+ /**
106
+ * @method unZipBoilerplate
107
+ *
108
+ * @param {string} filepath
109
+ * @memberof Create
110
+ */
111
+ async unZipBoilerplate(filepath) {
112
+ var _a;
113
+ const zip = new adm_zip_1.default(filepath);
114
+ const dataDir = (_a = this.flags["data-dir"]) !== null && _a !== void 0 ? _a : process.cwd();
115
+ let targetPath = (0, path_1.resolve)(dataDir, this.sharedConfig.appName);
116
+ const sourcePath = (0, path_1.resolve)(dataDir, this.sharedConfig.boilerplateName);
117
+ if (this.flags["data-dir"] && !(0, fs_1.existsSync)(this.flags["data-dir"])) {
118
+ (0, fs_1.mkdirSync)(this.flags["data-dir"], { recursive: true });
119
+ }
120
+ if ((0, fs_1.existsSync)(targetPath)) {
121
+ this.log(this.messages.DIR_EXIST, "warn");
122
+ targetPath = await (0, util_1.getDirName)(targetPath);
123
+ }
124
+ this.sharedConfig.folderPath = targetPath;
125
+ await new Promise((resolve, reject) => {
126
+ cli_utilities_1.ux.action.start(this.messages.UNZIP);
127
+ zip.extractAllToAsync(dataDir, true, false, (error) => {
128
+ cli_utilities_1.ux.action.stop();
129
+ if (!error) {
130
+ (0, fs_1.renameSync)(sourcePath, targetPath);
131
+ // NOTE write manifest into Boilerplate location
132
+ return resolve();
133
+ }
134
+ reject(error);
135
+ });
136
+ });
137
+ }
138
+ /**
139
+ * @method registerTheAppOnDeveloperHub
140
+ *
141
+ * @param {boolean} [saveManifest=true]
142
+ * @memberof Create
143
+ */
144
+ async registerTheAppOnDeveloperHub(saveManifest = true, retry = 0) {
145
+ cli_utilities_1.ux.action.start(this.$t(this.messages.REGISTER_THE_APP_ON_DEVELOPER_HUB, {
146
+ appName: this.sharedConfig.appName,
147
+ }));
148
+ await this.managementAppSdk
149
+ .organization(this.sharedConfig.org)
150
+ .app()
151
+ .create(this.appData)
152
+ .then((response) => {
153
+ cli_utilities_1.ux.action.stop();
154
+ if (this.sharedConfig.nameChanged) {
155
+ (0, fs_1.renameSync)(this.sharedConfig.oldFolderPath, this.sharedConfig.folderPath);
156
+ }
157
+ const validKeys = [
158
+ "uid",
159
+ "name",
160
+ "icon",
161
+ "oauth",
162
+ "version",
163
+ "visibility",
164
+ "created_by",
165
+ "created_at",
166
+ "updated_by",
167
+ "updated_at",
168
+ "target_type",
169
+ "description",
170
+ "ui_location",
171
+ "organization_uid",
172
+ "framework_version",
173
+ ];
174
+ this.appData = (0, merge_1.default)(this.appData, (0, pick_1.default)(response, validKeys));
175
+ if (saveManifest) {
176
+ (0, fs_1.writeFileSync)((0, path_1.resolve)(this.sharedConfig.folderPath, "manifest.json"), JSON.stringify(this.appData), {
177
+ encoding: "utf8",
178
+ flag: "w",
179
+ });
180
+ }
181
+ this.log(this.messages.APP_CREATION_SUCCESS, "info");
182
+ })
183
+ .catch(async (error) => {
184
+ cli_utilities_1.ux.action.stop("Failed");
185
+ switch (error.status) {
186
+ case 400:
187
+ this.log(this.messages.APP_CREATION_CONSTRAINT_FAILURE, "error");
188
+ break;
189
+ case 403:
190
+ this.log(this.messages.APP_INVALID_ORG, "error");
191
+ break;
192
+ case 409:
193
+ this.log(this.$t(this.messages.DUPLICATE_APP_NAME, {
194
+ appName: this.appData.name,
195
+ }), "warn");
196
+ return await this.manageNameConflict(saveManifest, retry);
197
+ default:
198
+ this.log(this.$t(this.messages.APP_CREATION_FAILURE, {
199
+ appName: this.appData.name,
200
+ }), "error");
201
+ break;
202
+ }
203
+ this.rollbackBoilerplate();
204
+ if (error.errorMessage) {
205
+ this.log(error.errorMessage, "error");
206
+ }
207
+ throw error;
208
+ });
209
+ }
210
+ /**
211
+ * @method rollbackBoilerplate
212
+ *
213
+ * @memberof Create
214
+ */
215
+ rollbackBoilerplate() {
216
+ if ((0, fs_1.existsSync)(this.sharedConfig.folderPath)) {
217
+ cli_utilities_1.ux.action.start(this.messages.ROLLBACK_BOILERPLATE);
218
+ (0, fs_1.rmSync)(this.sharedConfig.folderPath, {
219
+ force: true,
220
+ recursive: true,
221
+ maxRetries: 3,
222
+ });
223
+ cli_utilities_1.ux.action.stop();
224
+ }
225
+ }
226
+ /**
227
+ * @method manageNameConflict
228
+ *
229
+ * @param {boolean} saveManifest
230
+ * @param {number} retry
231
+ * @return {*} {Promise<void>}
232
+ * @memberof Create
233
+ */
234
+ async manageNameConflict(saveManifest, retry) {
235
+ this.sharedConfig.appName = await (0, util_1.getAppName)(`${this.sharedConfig.appName}+${retry + 1}`);
236
+ this.appData.name = this.sharedConfig.appName;
237
+ if (!this.sharedConfig.oldFolderPath) {
238
+ this.sharedConfig.oldFolderPath = this.sharedConfig.folderPath;
239
+ }
240
+ this.sharedConfig.folderPath = (0, path_1.resolve)((0, path_1.dirname)(this.sharedConfig.folderPath), this.appData.name);
241
+ this.sharedConfig.nameChanged = true;
242
+ return await this.registerTheAppOnDeveloperHub(saveManifest, retry);
243
+ }
244
+ /**
245
+ * @method installDependencies
246
+ *
247
+ * @memberof Create
248
+ */
249
+ async installDependencies() {
250
+ shell.cd(this.sharedConfig.folderPath);
251
+ await new Promise((resolve, reject) => {
252
+ shell.exec("npm install", { silent: true }, (error) => {
253
+ if (error !== 0) {
254
+ return reject(error);
255
+ }
256
+ resolve();
257
+ });
258
+ });
259
+ }
260
+ }
261
+ Create.hidden = false;
262
+ Create.description = "Create a new app in Developer Hub and optionally clone a boilerplate locally.";
263
+ Create.examples = [
264
+ "$ <%= config.bin %> <%= command.id %>",
265
+ "$ <%= config.bin %> <%= command.id %> --name App-1 --app-type stack",
266
+ "$ <%= config.bin %> <%= command.id %> --name App-2 --app-type stack -d ./boilerplate",
267
+ "$ <%= config.bin %> <%= command.id %> --name App-3 --app-type organization --org <UID> -d ./boilerplate -c ./external-config.json",
268
+ ];
269
+ Create.flags = {
270
+ name: cli_utilities_1.flags.string({
271
+ char: "n",
272
+ description: messages_1.appCreate.NAME_DESCRIPTION,
273
+ }),
274
+ "app-type": cli_utilities_1.flags.string({
275
+ default: "stack",
276
+ options: ["stack", "organization"],
277
+ description: messages_1.appCreate.APP_TYPE_DESCRIPTION,
278
+ }),
279
+ config: cli_utilities_1.flags.string({
280
+ char: "c",
281
+ description: messages_1.commonMsg.CONFIG,
282
+ }),
283
+ "data-dir": cli_utilities_1.flags.string({
284
+ char: "d",
285
+ description: messages_1.commonMsg.CURRENT_WORKING_DIR,
286
+ }),
287
+ };
288
+ exports.default = Create;
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from "./base-command";
2
+ export default class Delete extends BaseCommand<typeof Delete> {
3
+ static hidden: boolean;
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ "app-uid": import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_command_1 = require("./base-command");
4
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
5
+ const messages_1 = require("../../messages");
6
+ const util_1 = require("../../util");
7
+ class Delete extends base_command_1.BaseCommand {
8
+ async run() {
9
+ try {
10
+ let app;
11
+ this.sharedConfig.org = await (0, util_1.getOrg)(this.flags, {
12
+ managementSdk: this.managementSdk,
13
+ log: this.log,
14
+ });
15
+ if (!this.flags["app-uid"]) {
16
+ app = await (0, util_1.getApp)(this.flags, this.sharedConfig.org, {
17
+ managementSdk: this.managementAppSdk,
18
+ log: this.log,
19
+ });
20
+ this.flags["app-uid"] = app === null || app === void 0 ? void 0 : app.uid;
21
+ }
22
+ const { items: appInstallations } = await (0, util_1.fetchAppInstallations)(this.flags, this.sharedConfig.org, { managementSdk: this.managementAppSdk, log: this.log });
23
+ if (appInstallations.length === 0) {
24
+ const userConfirmation = this.flags['yes'] || await cli_utilities_1.cliux.inquire({
25
+ type: "confirm",
26
+ message: messages_1.deleteAppMsg.DELETE_CONFIRMATION,
27
+ name: "confirmation"
28
+ });
29
+ if (userConfirmation) {
30
+ await (0, util_1.deleteApp)(this.flags, this.sharedConfig.org, {
31
+ managementSdk: this.managementAppSdk,
32
+ log: this.log,
33
+ });
34
+ this.log((0, messages_1.$t)(messages_1.deleteAppMsg.APP_DELETED_SUCCESSFULLY, {
35
+ app: (app === null || app === void 0 ? void 0 : app.name) || this.flags["app-uid"],
36
+ }), "info");
37
+ }
38
+ else {
39
+ this.log(messages_1.commonMsg.USER_TERMINATION, "error");
40
+ }
41
+ }
42
+ else {
43
+ this.log(messages_1.deleteAppMsg.APP_IS_INSTALLED, "error");
44
+ }
45
+ }
46
+ catch (error) {
47
+ this.log((error === null || error === void 0 ? void 0 : error.errorMessage) || (error === null || error === void 0 ? void 0 : error.message) || error, "error");
48
+ if (error.status === 400) {
49
+ // check for invalid app-uid
50
+ this.log(messages_1.deleteAppMsg.PLEASE_SELECT_APP_FROM_LIST);
51
+ delete this.flags["app-uid"];
52
+ await this.run();
53
+ }
54
+ if (error.status === 409 && error.statusText === "Conflict") {
55
+ this.log(messages_1.commonMsg.CONTACT_SUPPORT, "error");
56
+ }
57
+ }
58
+ }
59
+ }
60
+ Delete.hidden = false;
61
+ Delete.description = "Delete app from marketplace";
62
+ Delete.examples = [
63
+ "$ <%= config.bin %> <%= command.id %>",
64
+ "$ <%= config.bin %> <%= command.id %> --app-uid <value>",
65
+ "$ <%= config.bin %> <%= command.id %> --app-uid <value> --org <value> -d ./boilerplate",
66
+ ];
67
+ Delete.flags = {
68
+ "app-uid": cli_utilities_1.flags.string({
69
+ description: messages_1.commonMsg.APP_UID,
70
+ }),
71
+ };
72
+ exports.default = Delete;
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from "./base-command";
2
+ export default class Get extends BaseCommand<typeof Get> {
3
+ static hidden: boolean;
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ "app-uid": import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
+ "app-type": import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
+ "data-dir": import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_command_1 = require("./base-command");
4
+ const util_1 = require("../../util");
5
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
6
+ const messages_1 = require("../../messages");
7
+ class Get extends base_command_1.BaseCommand {
8
+ async run() {
9
+ try {
10
+ let appData;
11
+ this.sharedConfig.org = await (0, util_1.getOrg)(this.flags, {
12
+ managementSdk: this.managementSdk,
13
+ log: this.log,
14
+ });
15
+ if (!this.flags["app-uid"]) {
16
+ appData = await (0, util_1.getApp)(this.flags, this.sharedConfig.org, {
17
+ managementSdk: this.managementAppSdk,
18
+ log: this.log,
19
+ });
20
+ }
21
+ else {
22
+ appData = await (0, util_1.fetchApp)(this.flags, this.sharedConfig.org, {
23
+ managementSdk: this.managementAppSdk,
24
+ log: this.log,
25
+ });
26
+ }
27
+ await (0, util_1.writeFile)(this.flags["data-dir"], this.flags["yes"], appData, this.log);
28
+ }
29
+ catch (error) {
30
+ this.log((error === null || error === void 0 ? void 0 : error.errorMessage) || (error === null || error === void 0 ? void 0 : error.message) || error, "error");
31
+ this.exit(1);
32
+ }
33
+ }
34
+ }
35
+ Get.hidden = false;
36
+ Get.description = "Get details of an app in developer hub";
37
+ Get.examples = [
38
+ "$ <%= config.bin %> <%= command.id %>",
39
+ "$ <%= config.bin %> <%= command.id %> --org <value> --app-uid <value>",
40
+ "$ <%= config.bin %> <%= command.id %> --org <value> --app-uid <value> --app-type stack",
41
+ "$ <%= config.bin %> <%= command.id %> --org <value> --app-uid <value> --app-type organization",
42
+ ];
43
+ Get.flags = {
44
+ "app-uid": cli_utilities_1.flags.string({
45
+ description: messages_1.commonMsg.APP_UID,
46
+ }),
47
+ "app-type": cli_utilities_1.flags.string({
48
+ default: "stack",
49
+ options: ["stack", "organization"],
50
+ description: messages_1.commonMsg.APP_TYPE_DESCRIPTION,
51
+ }),
52
+ "data-dir": cli_utilities_1.flags.string({
53
+ char: "d",
54
+ description: messages_1.commonMsg.CURRENT_WORKING_DIR,
55
+ }),
56
+ };
57
+ exports.default = Get;
@@ -0,0 +1,7 @@
1
+ import { Command } from "@contentstack/cli-utilities";
2
+ export default class App extends Command {
3
+ static description: string;
4
+ static hidden: boolean;
5
+ static examples: string[];
6
+ run(): Promise<void>;
7
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path_1 = require("path");
4
+ const child_process_1 = require("child_process");
5
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
6
+ const log_1 = require("../../util/log");
7
+ class App extends cli_utilities_1.Command {
8
+ async run() {
9
+ (0, child_process_1.exec)(`${(0, path_1.resolve)(process.cwd(), "bin", "run")} app --help`, (_er, stdout, _stderr) => {
10
+ if (stdout) {
11
+ this.log(`\n${stdout}`);
12
+ }
13
+ else {
14
+ (0, log_1.print)([
15
+ {
16
+ bold: true,
17
+ color: "yellow",
18
+ message: `\nUse '${this.config.bin} app --help' command to see more info\n`,
19
+ },
20
+ ]);
21
+ }
22
+ });
23
+ }
24
+ }
25
+ App.description = "Apps CLI plugin";
26
+ App.hidden = true;
27
+ App.examples = [
28
+ "$ <%= config.bin %> <%= command.id %>:create",
29
+ "$ <%= config.bin %> <%= command.id %>:get",
30
+ "$ <%= config.bin %> <%= command.id %>:update",
31
+ "$ <%= config.bin %> <%= command.id %>:delete",
32
+ "$ <%= config.bin %> <%= command.id %>:install",
33
+ "$ <%= config.bin %> <%= command.id %>:uninstall",
34
+ ];
35
+ exports.default = App;
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from "./base-command";
2
+ export default class Install extends BaseCommand<typeof Install> {
3
+ static description: string | undefined;
4
+ static hidden: boolean;
5
+ static examples: string[];
6
+ static flags: {
7
+ 'app-uid': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
+ 'stack-api-key': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_command_1 = require("./base-command");
4
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
5
+ const messages_1 = require("../../messages");
6
+ const util_1 = require("../../util");
7
+ class Install extends base_command_1.BaseCommand {
8
+ async run() {
9
+ try {
10
+ let app, stack, appType;
11
+ // validating user given stack, as installation API doesn't return appropriate errors if stack-api-key is invalid
12
+ // validating this first, as orgUid is not required for fetching stack
13
+ if (this.flags['stack-api-key']) {
14
+ stack = await (0, util_1.fetchStack)(this.flags, { managementSdk: this.managementSdk, log: this.log });
15
+ }
16
+ // get organization to be used
17
+ this.sharedConfig.org = await (0, util_1.getOrg)(this.flags, { managementSdk: this.managementSdk, log: this.log });
18
+ // fetch app details
19
+ if (!this.flags['app-uid']) {
20
+ app = await (0, util_1.getApp)(this.flags, this.sharedConfig.org, { managementSdk: this.managementAppSdk, log: this.log });
21
+ }
22
+ else {
23
+ app = await (0, util_1.fetchApp)(this.flags, this.sharedConfig.org, { managementSdk: this.managementAppSdk, log: this.log });
24
+ }
25
+ appType = app === null || app === void 0 ? void 0 : app['target_type']; // get app-type from the fetched app
26
+ this.flags['app-uid'] = app === null || app === void 0 ? void 0 : app.uid;
27
+ // in case stack-api-key is provided and the selected app is an organization app
28
+ if (appType === 'organization' && this.flags['stack-api-key']) {
29
+ const confirmation = this.flags['yes'] || await cli_utilities_1.cliux.inquire({
30
+ type: "confirm",
31
+ message: (0, messages_1.$t)(messages_1.installAppMsg.INSTALL_ORG_APP_TO_STACK, { app: (app === null || app === void 0 ? void 0 : app.name) || (app === null || app === void 0 ? void 0 : app.uid) }),
32
+ name: "confirmation"
33
+ });
34
+ if (!confirmation) {
35
+ throw new Error(messages_1.commonMsg.USER_TERMINATION);
36
+ }
37
+ }
38
+ // in case a stack app is selected and no stack-api-key is provided
39
+ if (appType === 'stack' && !this.flags['stack-api-key']) {
40
+ this.log((0, messages_1.$t)(messages_1.installAppMsg.MISSING_STACK_API_KEY, { app: (app === null || app === void 0 ? void 0 : app.name) || (app === null || app === void 0 ? void 0 : app.uid) }), "warn");
41
+ stack = await (0, util_1.getStack)(this.sharedConfig.org, { managementSdk: this.managementSdk, log: this.log });
42
+ this.flags['stack-api-key'] = stack === null || stack === void 0 ? void 0 : stack['api_key'];
43
+ }
44
+ // install app
45
+ this.log((0, messages_1.$t)(messages_1.installAppMsg.INSTALLING_APP_NOTICE, {
46
+ app: (app === null || app === void 0 ? void 0 : app.name) || (app === null || app === void 0 ? void 0 : app.uid),
47
+ type: appType,
48
+ target: this.flags['stack-api-key'] || this.sharedConfig.org
49
+ }), "info");
50
+ await (0, util_1.installApp)(this.flags, this.sharedConfig.org, appType, { managementSdk: this.managementAppSdk, log: this.log });
51
+ this.log((0, messages_1.$t)(messages_1.installAppMsg.APP_INSTALLED_SUCCESSFULLY, {
52
+ app: (app === null || app === void 0 ? void 0 : app.name) || this.flags['app-uid'],
53
+ target: (stack === null || stack === void 0 ? void 0 : stack.name) || this.sharedConfig.org
54
+ }), "info");
55
+ }
56
+ catch (error) {
57
+ this.log((error === null || error === void 0 ? void 0 : error.errorMessage) || (error === null || error === void 0 ? void 0 : error.message) || error, "error");
58
+ this.exit(1);
59
+ }
60
+ }
61
+ }
62
+ Install.description = "Install an app from the marketplace";
63
+ Install.hidden = false;
64
+ Install.examples = [
65
+ "$ <%= config.bin %> <%= command.id %>",
66
+ "$ <%= config.bin %> <%= command.id %> --org <UID> --app-uid <APP-UID-1>",
67
+ "$ <%= config.bin %> <%= command.id %> --org <UID> --app-uid <APP-UID-1> --stack-api-key <STACK-API-KEY-1>",
68
+ ];
69
+ Install.flags = {
70
+ 'app-uid': cli_utilities_1.flags.string({
71
+ description: messages_1.commonMsg.APP_UID,
72
+ }),
73
+ 'stack-api-key': cli_utilities_1.flags.string({
74
+ description: messages_1.commonMsg.STACK_API_KEY
75
+ })
76
+ };
77
+ exports.default = Install;
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from "./base-command";
2
+ export default class Uninstall extends BaseCommand<typeof Uninstall> {
3
+ static description: string;
4
+ static hidden: boolean;
5
+ static examples: string[];
6
+ static flags: {
7
+ 'app-uid': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
+ 'installation-uid': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_command_1 = require("./base-command");
4
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
5
+ const util_1 = require("../../util");
6
+ const messages_1 = require("../../messages");
7
+ class Uninstall extends base_command_1.BaseCommand {
8
+ async run() {
9
+ try {
10
+ let app, appType;
11
+ // get organization to be used
12
+ this.sharedConfig.org = await (0, util_1.getOrg)(this.flags, { managementSdk: this.managementSdk, log: this.log });
13
+ // fetch app details
14
+ if (!this.flags['app-uid']) {
15
+ app = await (0, util_1.getApp)(this.flags, this.sharedConfig.org, { managementSdk: this.managementAppSdk, log: this.log });
16
+ }
17
+ else {
18
+ app = await (0, util_1.fetchApp)(this.flags, this.sharedConfig.org, { managementSdk: this.managementAppSdk, log: this.log });
19
+ }
20
+ this.flags['app-uid'] = app === null || app === void 0 ? void 0 : app.uid;
21
+ appType = app === null || app === void 0 ? void 0 : app['target_type'];
22
+ // select installation uid to uninstall
23
+ if (!this.flags['installation-uid']) {
24
+ this.flags['installation-uid'] = await (0, util_1.getInstallation)(this.flags, this.sharedConfig.org, this.managementSdk, appType, { managementSdk: this.managementAppSdk, log: this.log });
25
+ }
26
+ // uninstall app
27
+ await (0, util_1.uninstallApp)(this.flags, this.sharedConfig.org, { managementSdk: this.managementAppSdk, log: this.log });
28
+ this.log(this.$t(messages_1.uninstallAppMsg.APP_UNINSTALLED, { app: (app === null || app === void 0 ? void 0 : app.name) || this.flags["app-uid"] }), "info");
29
+ }
30
+ catch (error) {
31
+ this.log((error === null || error === void 0 ? void 0 : error.errorMessage) || (error === null || error === void 0 ? void 0 : error.message) || error, "error");
32
+ this.exit(1);
33
+ }
34
+ }
35
+ }
36
+ Uninstall.description = "Uninstall an app";
37
+ Uninstall.hidden = false;
38
+ Uninstall.examples = [
39
+ "$ <%= config.bin %> <%= command.id %>",
40
+ "$ <%= config.bin %> <%= command.id %> --org <UID> --app-uid <APP-UID-1>",
41
+ "$ <%= config.bin %> <%= command.id %> --org <UID> --app-uid <APP-UID-1> --installation-uid <INSTALLATION-UID-1>",
42
+ ];
43
+ Uninstall.flags = {
44
+ 'app-uid': cli_utilities_1.flags.string({
45
+ description: messages_1.commonMsg.APP_UID,
46
+ }),
47
+ 'installation-uid': cli_utilities_1.flags.string({
48
+ description: messages_1.uninstallAppMsg.INSTALLATION_UID
49
+ })
50
+ };
51
+ exports.default = Uninstall;