|
1 | 1 | --- |
2 | 2 | name: contentstack-cli |
3 | | -description: Contentstack CLI development patterns, OCLIF commands, API integration, and authentication/configuration workflows. Use when working with Contentstack CLI plugins, OCLIF commands, CLI commands, or Contentstack API integration. |
| 3 | +description: >- |
| 4 | + Contentstack CLI development patterns, OCLIF commands, API integration, and auth/config |
| 5 | + workflows. Use for CLI plugins, OCLIF commands, or API integration—including Developer |
| 6 | + Hub apps (packages/contentstack-apps-cli, app:* commands). |
4 | 7 | --- |
5 | 8 |
|
6 | 9 | # Contentstack CLI Development |
@@ -477,3 +480,103 @@ cliux.print('🔄 Processing...', { color: 'blue' }); |
477 | 480 | // ... operation ... |
478 | 481 | cliux.success('✅ Completed successfully'); |
479 | 482 | ``` |
| 483 | + |
| 484 | +## Apps CLI commands (`app:*`) |
| 485 | + |
| 486 | +Package: **`packages/contentstack-apps-cli`** (`@contentstack/apps-cli`). SDK, config, HTTP, manifests, GraphQL: [framework](../framework/SKILL.md#apps-cli-plugin-contentstackapps-cli). |
| 487 | + |
| 488 | +### Command layout |
| 489 | + |
| 490 | +| Path | Command id | Purpose | |
| 491 | +| --- | --- | --- | |
| 492 | +| `src/commands/app/index.ts` | `app` | Topic help | |
| 493 | +| `src/commands/app/create.ts` | `app:create` | Create app + optional boilerplate | |
| 494 | +| `src/commands/app/get.ts` | `app:get` | Fetch app details | |
| 495 | +| `src/commands/app/update.ts` | `app:update` | Update from manifest | |
| 496 | +| `src/commands/app/delete.ts` | `app:delete` | Delete from marketplace | |
| 497 | +| `src/commands/app/install.ts` | `app:install` | Install on stack | |
| 498 | +| `src/commands/app/reinstall.ts` | `app:reinstall` | Reinstall on stack | |
| 499 | +| `src/commands/app/uninstall.ts` | `app:uninstall` | Uninstall (factory + strategy) | |
| 500 | +| `src/commands/app/deploy.ts` | `app:deploy` | Deploy (Launch / custom hosting) | |
| 501 | + |
| 502 | +OCLIF topic: `app` (`oclif.topics.app` in `package.json`). Short names in `csdxConfig.shortCommandName` (e.g. `app:create` → `APCRT`). |
| 503 | + |
| 504 | +### Base command hierarchy |
| 505 | + |
| 506 | +```typescript |
| 507 | +import { BaseCommand } from "../../base-command"; |
| 508 | +import { AppCLIBaseCommand } from "../../app-cli-base-command"; |
| 509 | + |
| 510 | +// Org-level or SDK-only commands |
| 511 | +export default class AppInstall extends BaseCommand<typeof AppInstall> { |
| 512 | + static flags = { /* ... */, ...BaseCommand.baseFlags }; |
| 513 | + async run() { /* this.flags, this.managementSdk, this.marketplaceAppSdk ready after init */ } |
| 514 | +} |
| 515 | + |
| 516 | +// Commands that read manifest.json from cwd |
| 517 | +export default class AppUpdate extends AppCLIBaseCommand { |
| 518 | + async run() { |
| 519 | + // this.manifestData, this.manifestPath set in AppCLIBaseCommand.init |
| 520 | + } |
| 521 | +} |
| 522 | +``` |
| 523 | + |
| 524 | +- **`BaseCommand`** (`src/base-command.ts`) — `init()` parses flags/args, `registerConfig`, logger, `validateRegionAndAuth`, SDK init. **`baseFlags`**: `org`, `yes`. Also: `getValPrompt`, `messages` / `$t`, `catch` / `finally` (nonexistent flag → exit 2). |
| 525 | +- **`AppCLIBaseCommand`** — After `super.init()`, `getManifestData()` from `{cwd}/manifest.json`. |
| 526 | + |
| 527 | +Always call `await super.init()` first in `init()` overrides. |
| 528 | + |
| 529 | +### Command responsibilities |
| 530 | + |
| 531 | +- **CLI layer** — static `flags` / `examples`, prompts (`cliux`, `getValPrompt`, `src/util/inquirer.ts`), `this.log`, `this.error` / exit. |
| 532 | +- **Business logic** — `src/util/`, `src/factories/`, `src/strategies/`; keep `run()` small. |
| 533 | + |
| 534 | +### Parse and flags |
| 535 | + |
| 536 | +Parse runs inside **`BaseCommand.init`** only; do not re-parse in `run()`. After `init`, use `this.flags` and `this.args`. Inherit `BaseCommand.baseFlags` when `org` / `--yes` apply. |
| 537 | + |
| 538 | +OCLIF hook: `src/hooks/init/load-chalk.ts` (registered in `package.json` `oclif.hooks.init`). |
| 539 | + |
| 540 | +### Apps command example |
| 541 | + |
| 542 | +```typescript |
| 543 | +export default class AppGet extends BaseCommand<typeof AppGet> { |
| 544 | + static description = "Get details of an app in developer hub"; |
| 545 | + |
| 546 | + static flags = { |
| 547 | + "app-uid": Flags.string({ description: "App UID" }), |
| 548 | + "app-type": Flags.string({ |
| 549 | + options: ["stack", "organization"], |
| 550 | + default: "stack", |
| 551 | + }), |
| 552 | + ...BaseCommand.baseFlags, |
| 553 | + }; |
| 554 | + |
| 555 | + async run(): Promise<void> { |
| 556 | + const { org, "app-uid": appUid } = this.flags; |
| 557 | + // Use this.marketplaceAppSdk / GraphQL / apiRequestHandler — see framework Apps CLI section |
| 558 | + this.log(this.$t(this.messages.APP_FETCH_SUCCESS), "info"); |
| 559 | + } |
| 560 | +} |
| 561 | +``` |
| 562 | + |
| 563 | +### External config and deploy |
| 564 | + |
| 565 | +- **`--config`** — JSON merged into `sharedConfig` (see `registerConfig` in `base-command.ts`). Used by create/deploy for Launch project settings. |
| 566 | +- **`--data-dir`** — Working directory for boilerplate clone and manifest paths. |
| 567 | + |
| 568 | +### Errors |
| 569 | + |
| 570 | +`BaseCommand.catch` handles `NonExistent flag` with exit code 2. Prefer actionable messages via `messages` / `$t` and existing util error helpers. |
| 571 | + |
| 572 | +### Build and test |
| 573 | + |
| 574 | +| Command | Purpose | |
| 575 | +| --- | --- | |
| 576 | +| `pnpm --filter @contentstack/apps-cli run build` | `tsc` → `lib/` | |
| 577 | +| `pnpm --filter @contentstack/apps-cli test` | Mocha + ESLint (`posttest`) | |
| 578 | +| `pnpm --filter @contentstack/apps-cli run test:unit:report` | Unit tests with nyc | |
| 579 | + |
| 580 | +### Testing apps commands |
| 581 | + |
| 582 | +Unit tests under `test/unit/commands/app/`. Use `stubAuthentication` from `test/unit/helpers/auth-stub-helper.ts` and nock Developer Hub hosts from `getDeveloperHubUrl()`. See [testing](../testing/SKILL.md) and [dev-workflow](../dev-workflow/SKILL.md). |
0 commit comments