Skip to content

Commit abd9a0d

Browse files
authored
Merge pull request #280 from contentstack/staging
DX | 31-07-2024 | Release
2 parents 0b4ab90 + f72cb75 commit abd9a0d

File tree

9 files changed

+132
-33
lines changed

9 files changed

+132
-33
lines changed

README.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ $ npm install -g @contentstack/apps-cli
2020
$ csdx COMMAND
2121
running command...
2222
$ csdx (--version|-v)
23-
@contentstack/apps-cli/1.2.1 darwin-arm64 node-v18.12.1
23+
@contentstack/apps-cli/1.3.0 darwin-arm64 node-v18.16.0
2424
$ csdx --help [COMMAND]
2525
USAGE
2626
$ csdx COMMAND
@@ -67,22 +67,24 @@ EXAMPLES
6767
$ csdx app:reinstall
6868
```
6969

70-
_See code: [src/commands/app/index.ts](https://github.com/contentstack/apps-cli/blob/v1.2.1/src/commands/app/index.ts)_
70+
_See code: [src/commands/app/index.ts](https://github.com/contentstack/apps-cli/blob/v1.3.0/src/commands/app/index.ts)_
7171

7272
## `csdx app:create`
7373

7474
Create a new app in Developer Hub and optionally clone a boilerplate locally.
7575

7676
```
7777
USAGE
78-
$ csdx app:create [-n <value>] [--app-type stack|organization] [-c <value>] [-d <value>]
78+
$ csdx app:create [-n <value>] [--app-type stack|organization] [-c <value>] [-d <value>] [--boilerplate
79+
<value>]
7980
8081
FLAGS
8182
-c, --config=<value> Path of the external config
8283
-d, --data-dir=<value> Current working directory.
83-
-n, --name=<value> [default: app-boilerplate] Name of the app to be created
84+
-n, --name=<value> Name of the app to be created
8485
--app-type=<option> [default: stack] Type of app
8586
<options: stack|organization>
87+
--boilerplate=<value> Provide a boilerplate. <options: App Boilerplate|DAM App Boilerplate|Ecommerce App Boilerplate>
8688
8789
DESCRIPTION
8890
Create a new app in Developer Hub and optionally clone a boilerplate locally.
@@ -95,9 +97,15 @@ EXAMPLES
9597
$ csdx app:create --name App-2 --app-type stack -d ./boilerplate
9698
9799
$ csdx app:create --name App-3 --app-type organization --org <UID> -d ./boilerplate -c ./external-config.json
100+
101+
$ csdx app:create --name App-4 --app-type organization --org <UID> --boilerplate <App Boilerplate>
102+
103+
$ csdx app:create --name App-4 --app-type organization --org <UID> --boilerplate <DAM App Boilerplate>
104+
105+
$ csdx app:create --name App-4 --app-type organization --org <UID> --boilerplate <Ecommerce App Boilerplate>
98106
```
99107

100-
_See code: [src/commands/app/create.ts](https://github.com/contentstack/apps-cli/blob/v1.2.1/src/commands/app/create.ts)_
108+
_See code: [src/commands/app/create.ts](https://github.com/contentstack/apps-cli/blob/v1.3.0/src/commands/app/create.ts)_
101109

102110
## `csdx app:delete`
103111

@@ -121,7 +129,7 @@ EXAMPLES
121129
$ csdx app:delete --app-uid <value> --org <value> -d ./boilerplate
122130
```
123131

124-
_See code: [src/commands/app/delete.ts](https://github.com/contentstack/apps-cli/blob/v1.2.1/src/commands/app/delete.ts)_
132+
_See code: [src/commands/app/delete.ts](https://github.com/contentstack/apps-cli/blob/v1.3.0/src/commands/app/delete.ts)_
125133

126134
## `csdx app:deploy`
127135

@@ -158,7 +166,7 @@ EXAMPLES
158166
$ csdx app:deploy --org <UID> --app-uid <APP-UID-1> --hosting-type <Hosting with Launch> --launch-project <new> --config <config-path>
159167
```
160168

161-
_See code: [src/commands/app/deploy.ts](https://github.com/contentstack/apps-cli/blob/v1.2.1/src/commands/app/deploy.ts)_
169+
_See code: [src/commands/app/deploy.ts](https://github.com/contentstack/apps-cli/blob/v1.3.0/src/commands/app/deploy.ts)_
162170

163171
## `csdx app:get`
164172

@@ -187,7 +195,7 @@ EXAMPLES
187195
$ csdx app:get --org <value> --app-uid <value> --app-type organization
188196
```
189197

190-
_See code: [src/commands/app/get.ts](https://github.com/contentstack/apps-cli/blob/v1.2.1/src/commands/app/get.ts)_
198+
_See code: [src/commands/app/get.ts](https://github.com/contentstack/apps-cli/blob/v1.3.0/src/commands/app/get.ts)_
191199

192200
## `csdx app:install`
193201

@@ -212,7 +220,7 @@ EXAMPLES
212220
$ csdx app:install --org <UID> --app-uid <APP-UID-1> --stack-api-key <STACK-API-KEY-1>
213221
```
214222

215-
_See code: [src/commands/app/install.ts](https://github.com/contentstack/apps-cli/blob/v1.2.1/src/commands/app/install.ts)_
223+
_See code: [src/commands/app/install.ts](https://github.com/contentstack/apps-cli/blob/v1.3.0/src/commands/app/install.ts)_
216224

217225
## `csdx app:reinstall`
218226

@@ -237,7 +245,7 @@ EXAMPLES
237245
$ csdx app:reinstall --org <UID> --app-uid <APP-UID-1> --stack-api-key <STACK-API-KEY-1>
238246
```
239247

240-
_See code: [src/commands/app/reinstall.ts](https://github.com/contentstack/apps-cli/blob/v1.2.1/src/commands/app/reinstall.ts)_
248+
_See code: [src/commands/app/reinstall.ts](https://github.com/contentstack/apps-cli/blob/v1.3.0/src/commands/app/reinstall.ts)_
241249

242250
## `csdx app:uninstall`
243251

@@ -263,7 +271,7 @@ EXAMPLES
263271
$ csdx app:uninstall --org <UID> --app-uid <APP-UID-1> --installation-uid <INSTALLATION-UID-1>
264272
```
265273

266-
_See code: [src/commands/app/uninstall.ts](https://github.com/contentstack/apps-cli/blob/v1.2.1/src/commands/app/uninstall.ts)_
274+
_See code: [src/commands/app/uninstall.ts](https://github.com/contentstack/apps-cli/blob/v1.3.0/src/commands/app/uninstall.ts)_
267275

268276
## `csdx app:update`
269277

@@ -285,5 +293,5 @@ EXAMPLES
285293
$ csdx app:update --app-manifest ./boilerplate/manifest.json
286294
```
287295

288-
_See code: [src/commands/app/update.ts](https://github.com/contentstack/apps-cli/blob/v1.2.1/src/commands/app/update.ts)_
296+
_See code: [src/commands/app/update.ts](https://github.com/contentstack/apps-cli/blob/v1.3.0/src/commands/app/update.ts)_
289297
<!-- commandsstop -->

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/apps-cli",
3-
"version": "1.2.1",
3+
"version": "1.3.0",
44
"description": "App ClI",
55
"author": "Contentstack CLI",
66
"homepage": "https://github.com/contentstack/contentstack-apps-cli",

src/commands/app/create.ts

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,21 @@ import {
2121
flags,
2222
HttpClient,
2323
configHandler,
24-
FlagInput
24+
FlagInput,
2525
} from "@contentstack/cli-utilities";
2626

2727
import { BaseCommand } from "../../base-command";
28-
import { AppManifest, AppType } from "../../types";
28+
import { AppManifest, AppType, BoilerplateAppType } from "../../types";
2929
import { appCreate, commonMsg } from "../../messages";
3030
import {
3131
getOrg,
3232
getAppName,
3333
getDirName,
3434
getOrgAppUiLocation,
35-
sanitizePath
35+
sanitizePath,
36+
selectedBoilerplate,
37+
validateBoilerplate,
38+
validateAppName,
3639
} from "../../util";
3740

3841
export default class Create extends BaseCommand<typeof Create> {
@@ -51,12 +54,14 @@ export default class Create extends BaseCommand<typeof Create> {
5154
"$ <%= config.bin %> <%= command.id %> --name App-1 --app-type stack",
5255
"$ <%= config.bin %> <%= command.id %> --name App-2 --app-type stack -d ./boilerplate",
5356
"$ <%= config.bin %> <%= command.id %> --name App-3 --app-type organization --org <UID> -d ./boilerplate -c ./external-config.json",
57+
"$ <%= config.bin %> <%= command.id %> --name App-4 --app-type organization --org <UID> --boilerplate <App Boilerplate>",
58+
"$ <%= config.bin %> <%= command.id %> --name App-4 --app-type organization --org <UID> --boilerplate <DAM App Boilerplate>",
59+
"$ <%= config.bin %> <%= command.id %> --name App-4 --app-type organization --org <UID> --boilerplate <Ecommerce App Boilerplate>",
5460
];
5561

5662
static flags: FlagInput = {
5763
name: flags.string({
5864
char: "n",
59-
default: "app-boilerplate",
6065
description: appCreate.NAME_DESCRIPTION,
6166
}),
6267
"app-type": flags.string({
@@ -72,11 +77,15 @@ export default class Create extends BaseCommand<typeof Create> {
7277
char: "d",
7378
description: commonMsg.CURRENT_WORKING_DIR,
7479
}),
80+
boilerplate: flags.string({
81+
description: appCreate.BOILERPLATE_TEMPLATES,
82+
}),
7583
};
7684

7785
async run(): Promise<void> {
7886
this.sharedConfig.org = this.flags.org;
7987
this.sharedConfig.appName = this.flags.name;
88+
this.sharedConfig.boilerplateName = this.flags.boilerplate;
8089

8190
await this.flagsPromptQueue();
8291

@@ -143,10 +152,31 @@ export default class Create extends BaseCommand<typeof Create> {
143152
* @memberof Create
144153
*/
145154
async flagsPromptQueue() {
146-
if (isEmpty(this.sharedConfig.appName)) {
147-
this.sharedConfig.appName = await getAppName(
148-
this.sharedConfig.defaultAppName
149-
);
155+
if (this.sharedConfig.appName) {
156+
validateAppName(this.sharedConfig.appName);
157+
}
158+
159+
let boilerplate: BoilerplateAppType | null = null;
160+
if (isEmpty(this.sharedConfig.boilerplateName)) {
161+
boilerplate = await selectedBoilerplate();
162+
} else {
163+
boilerplate = (await validateBoilerplate(
164+
this.sharedConfig.boilerplateName
165+
)) as BoilerplateAppType;
166+
}
167+
168+
if (boilerplate) {
169+
let boilerplateName = this.sharedConfig.appName || boilerplate.name;
170+
if (isEmpty(this.sharedConfig.appName)) {
171+
boilerplateName = boilerplateName
172+
.toLowerCase()
173+
.replace(/ /g, "-")
174+
.substring(0, 20);
175+
}
176+
177+
this.sharedConfig.boilerplateName = boilerplateName;
178+
this.sharedConfig.appBoilerplateGithubUrl = boilerplate.link;
179+
this.sharedConfig.appName = boilerplateName;
150180
}
151181

152182
//Auto select org in case of oauth
@@ -198,7 +228,11 @@ export default class Create extends BaseCommand<typeof Create> {
198228
const zip = new AdmZip(filepath);
199229
const dataDir = this.flags["data-dir"] ?? process.cwd();
200230
let targetPath = resolve(dataDir, this.sharedConfig.appName);
201-
const sourcePath = resolve(dataDir, this.sharedConfig.boilerplateName);
231+
232+
// Get the directory inside the zip file
233+
const zipEntries = zip.getEntries();
234+
const firstEntry = zipEntries[0];
235+
const sourcePath = resolve(sanitizePath(dataDir), sanitizePath(firstEntry.entryName.split("/")[0]));
202236

203237
if (this.flags["data-dir"] && !existsSync(this.flags["data-dir"])) {
204238
mkdirSync(this.flags["data-dir"], { recursive: true });
@@ -235,10 +269,7 @@ export default class Create extends BaseCommand<typeof Create> {
235269
*/
236270
manageManifestToggeling() {
237271
// NOTE Use boilerplate manifest if exist
238-
const manifestPath = resolve(
239-
this.sharedConfig.folderPath || "",
240-
"manifest.json"
241-
);
272+
const manifestPath = resolve(this.sharedConfig.folderPath, "manifest.json");
242273

243274
if (existsSync(manifestPath)) {
244275
this.sharedConfig.manifestPath = manifestPath;

src/config/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import { resolve } from "path";
33
const config = {
44
defaultAppName: "app-boilerplate",
55
manifestPath: resolve(__dirname, "manifest.json"),
6-
boilerplateName: "marketplace-app-boilerplate-main",
76
developerHubBaseUrl: "",
87
appBoilerplateGithubUrl:
98
"https://codeload.github.com/contentstack/marketplace-app-boilerplate/zip/refs/heads/main",
109
defaultAppFileName: "manifest",
10+
boilerplatesUrl: 'https://marketplace-artifacts.contentstack.com/cli/starter-template.json'
1111
};
1212

1313
export default config;

src/messages/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ const appCreate = {
5858
REGISTER_THE_APP_ON_DEVELOPER_HUB:
5959
"Registering the app with the name {appName} on the Developer Hub...",
6060
START_APP_COMMAND: "Start the app using the following command: {command}",
61+
BOILERPLATE_TEMPLATES: "Provide a boilerplate. <options: App Boilerplate|DAM App Boilerplate|Ecommerce App Boilerplate>",
62+
SELECT_BOILERPLATE: "Select one from the following boilerplates:"
6163
};
6264

6365
const getAppMsg = {

src/types/app.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,12 @@ export interface LaunchProjectRes {
140140
environmentUid: any;
141141
developerHubAppUid: any;
142142
}
143+
144+
export interface BoilerplateAppType {
145+
name: string;
146+
description?: string;
147+
link: string;
148+
tags?: string[];
149+
created_at?: string;
150+
updated_at?: string;
151+
}

src/util/common-utils.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
cliux,
88
Stack,
99
FsUtility,
10+
HttpClient,
1011
} from "@contentstack/cli-utilities";
1112
import { projectsQuery } from "../graphql/queries";
1213
import { apiRequestHandler } from "./api-request-handler";
@@ -19,6 +20,8 @@ import {
1920
} from "../types";
2021
import { askProjectName } from "./inquirer";
2122
import { deployAppMsg } from "../messages";
23+
import config from "../config";
24+
import find from "lodash/find";
2225

2326
export type CommonOptions = {
2427
log: LogFn;
@@ -396,6 +399,28 @@ const handleProjectNameConflict = async (
396399
}
397400
return projectName;
398401
};
402+
async function fetchBoilerplateDetails(): Promise<Record<string, any>[]> {
403+
try {
404+
const content = await new HttpClient().get(config.boilerplatesUrl);
405+
return content?.data?.templates ?? [];
406+
} catch (error) {
407+
throw error;
408+
}
409+
}
410+
411+
async function validateBoilerplate(boilerplateName: string) {
412+
const boilerplates = await fetchBoilerplateDetails();
413+
const boilerplate = find(
414+
boilerplates,
415+
(boilerplate) => boilerplate.name === boilerplateName
416+
);
417+
if (!boilerplate) {
418+
throw new Error(
419+
"Invalid boilerplate! Please select a boilerplate from the following options: App Boilerplate, DAM App Boilerplate or Ecommerce App Boilerplate"
420+
);
421+
}
422+
return boilerplate;
423+
}
399424

400425
export {
401426
getOrganizations,
@@ -418,4 +443,6 @@ export {
418443
disconnectApp,
419444
formatUrl,
420445
handleProjectNameConflict,
446+
fetchBoilerplateDetails,
447+
validateBoilerplate,
421448
};

0 commit comments

Comments
 (0)