npm package: @ibm-wch-sdk/cli
Description: Command line interface for the generation of WCH SDK related artifacts.
Author: Dr. Carsten Leue
Latest version: 6.0.524

# Watson Content Hub Command Line Interface

Some simple command line utilities to simplify life.

- [Stories](#stories)

### Usage

Local install for use from an [NPM script](https://docs.npmjs.com/misc/scripts):

```bash
npm install --save-dev @ibm-wch-sdk/cli
```

Global install for use from the command line:

```bash
npm install -g @ibm-wch-sdk/cli
```

The command installs the CLI and registers as an executable in the path, so you can use it as `ibm-wch-sdk-cli`.

## Simplified Layout Generation

Generates a single angular layout, layout mapping and components for a given type.

### Usage

```bash
ibm-wch-sdk-cli create layout --data <DATA> --src <SRC> --type <TYPE> [--name <NAME>] [--verbose] [--flat] [--scss] [--editable]
```

With

- `DATA`: wchtools data folder
- `SRC`: target folder of the application that will receive the generated typescript files. Typically this is the `src/app` folder of the application.
- `TYPE`: name of the type to construct the layout for. This needs to be the full type name, not a regular expression. The name is case sensitive.
- `NAME`: name of the generated layout. If missing, will be derived from the type name

Refer to [Code Generation](#code-generation) for a description of the remaining parameters.

## Layout Generation

Generates angular layouts and layout mappings based on type information.

### Usage

```bash
ibm-wch-sdk-cli create layouts --data <DATA> [--include <INCLUDE>] [--exclude <EXCLUDE>] [--count COUNT]
```

With

- `DATA`: wchtools data folder
- `INCLUDE`: regular expression pattern for the type includes
- `EXCLUDE`: regular expression pattern for the type excludes
- `COUNT`: number of layouts to create per type, defaults to `1`.

The layout generator will generate the following artifacts:

- a layout per type. The name of the layout will be derived from the layout name. If the layout already exists, nothing happens.
- a layout mapping per type, if the mapping already exists, nothing happens
- the generated layout will be added to the layout mapping. If there is no default mapping defined, this layout will also become the default layout.

The resulting data structure can be used to produce Angular code components and templates using the `create components` command.

### Naming Scheme

The layout name is derived from the type name as follows:

- convert the type name to camel case
- if the result ends with `Type` remove that suffix
- add a `Layout` suffix

The layout selector is derived from the layout name as follows:

- convert the layout name to kebab case

The layout mapping name is derived from the layout name as follows:

- add `Mapping` to the layout name

## Data Aggregation

When reusing component libraries via [npm](https://www.npmjs.com/) these libraries can contain WCH data artifacts in the form of [wchtools](https://www.npmjs.com/package/wchtools-cli) data files. In order to setup the server, it is necessary to copy all artifacts from all references components across the dependency chain.

Use the `copy data` command to aggregate all dependencies into a temporary directory. This directory can then be pushed.

```bash
ibm-wch-sdk-cli copy data --aggregated [--package <PACKAGE_DIR>]
```

The command will inspect the specified `package.json` for data dependencies and then copies the dependencies in topological order.

### Declaring data dependencies

- Add the desired node module to the `dependencies` section of your `package.json`. This ensures that the binaries get installed from [npm](https://www.npmjs.com/).
- Introduce the `wchtools-dependencies` key in your `package.json` file. The value is an array of pointers to [wchtools](https://www.npmjs.com/package/wchtools-cli) data files. Use a `./` prefix for data directories local to your project. All other identifiers are considered external modules names and point to the `wchtools-dependencies` exposed by those modules.

If different modules expose the same data artifacts, then the artifacts will be overridden during the aggregation process in topological order.

## Code Generation

Generates Angular layouts and components based on a wchtools folder. Uses information from the content types, layout and layout mappings.

### Usage

```bash
ibm-wch-sdk-cli create components --data <DATA> --src <SRC> [--include <INCLUDE>] [--exclude <EXCLUDE>] [--module <MODULE>] [--verbose] [--scss] [--flat] [--skipRegistration] [--layoutHtmlTemplate <LAYOUT_TEMPLATE>] [--editable]
```

With

- `DATA`: wchtools data folder
- `SRC`: target folder of the application that will receive the generated typescript files. Typically this is the `src/app` folder of the application.
- `INCLUDE`: regular expression pattern for the type includes
- `EXCLUDE`: regular expression pattern for the type excludes
- `MODULE`: optional path to the typescript file that contains the module for the newly created components. This defaults to `app.module.ts` in the source directory.
- `LAYOUT_TEMPLATE`: path to a handlebars template

Parameters

- `data`: wch data folder
- `src`: folder for the generated source files
- `module`: filename of the module file
- `include`: regular expression pattern for the type includes
- `exclude`: regular expression pattern for the type excludes
- `verbose`: enable verbose logging
- `scss`: generate `scss` instead of `css` style templates
- `flat`: do not use tags on the type to create a folder hierarchy
- `skipRegistration`: do not register the newly created components with the (application) module
- `layoutHtmlTemplate`: use this [Handlebars](http://handlebarsjs.com/) template to produce the layout HTML preview. The context is the content type object and the template has access to these [helpers](https://www.npmjs.com/package/handlebars-helpers).
- `editable`: generate inline edit enabled markup for the HTML templates

The code generator will generate the following artifacts:

- an abstract base class generated from the type definition. This class defines strongly typed fields for all elements described in the content type, both as observables and as updated fields. Do not edit this class, a next run of the generator will update it with a potentially updated type definition.
- an intermediate class based on the abstract base class. This is a class by type that can be edited, e.g. to add derived fields that would be common across all layouts based on that type.
- a class that represents the final layout. This has the required @LayoutComponent and @Component annotations and contains layout mapping information. This class is accompanied by a template file and a CSS file.
- a descriptor file that lists all available layouts in an array. This file can be used to add the layouts to the application module (via spread operator syntax).

**Note**: the code generator uses tags on the type to build a directory structure for components and layouts. The tags will be sorted and converted to kebab case. You can disable this feature by passing the `--flat` parameter.

**Note**: the code generator will override the generated files except for the layout files and the the type specific base classes, since these are meant to be modified by the customer. Instead of overriding these readonly files, the generator produces a file with a `.$gen` extension. Customers can use this to manually merge in potential modifications.

## Code Registration

Registers layout components with the application module. The command will scan all components for those that have the `@LayoutComponent` annotation. All such components will be added to an array in the `layouts.ts` file, this file will alway be regenerated to contain the full list of layouts.
In addition the command will update the main application module (typically `app.module.ts`) to reference this generated list.

### Usage

```bash
ibm-wch-sdk-cli register layoutcomponents --src <SRC> [--module <MODULE>] [--verbose] [--skipRegistration]
```

With

- `SRC`: target folder of the application that will receive the generated typescript files. Typically this is the `src/app` folder of the application.
- `MODULE`: optional path to the typescript file that contains the module for the newly created components. This defaults to `app.module.ts` in the source directory.

Parameters

- `src`: folder for the generated source files
- `module`: filename of the module file
- `verbose`: enable verbose logging
- `skipRegistration`: do not register the newly created components with the (application) module

## Prefetch

Injects prefetching URLs into the `index.html` file. These URLs will be loaded in parallel to the application script, so the data is available as soon as the application is ready.

These files will be prefetched:

- `site`: the site
- `content`: the content items referenced by the site. The items are ordered by levels as first sort criteria, and position as second criteria.

### Usage

```bash
ibm-wch-sdk-cli add prefetch --data <DATA> --src <SRC> [--url <URL>] [--relative]
```

With

- `DATA`: wchtools data folder
- `SRC`: target folder of the application that contains the `index.html` file. Typically this is the `src` folder of the application.
- `URL`: the API URL of WCH. If this parameter is omitted, will use the value from `%USERPROFILE%/.wchtoolsoptions` as a fallback.

Optional parameters:

- `relative`: creates server relative prefetch URLs, i.e. without the protocol or the hostname
- `verbose`: prints some information during processing

## Project Bootstrap

Generates a new single page application based on a set of content types and a WCH non-base tenant.

**Note**: you need to use the latest [WchTools](https://github.ibm.com/DX/prod-tools/releases/tag/v2.0.1-8) version to successfully run the project bootstrap. Since this version is not part of a registry, please download and install the package.Then copy the installed `wchtools-cli` folder from the global `node_modules` folder into the local `node_modules` folder.

### Usage

```bash
ibm-wch-sdk-cli create project --src <SRC> --name <NAME> --url <API_URL> [--override] [--verbose] [--include <INCLUDE>] [--exclude <EXCLUDE>] [--user <USER>] [--password <PASSWORD>]
```

With

- `SRC`: target folder of the application. The new project will use a subfolder of the specified folder.
- `NAME`: your application name, this will also be the name of the sub folder
- `API_URL`: the `API URL` as provided by the WCH Hub Information panel.
- `INCLUDE`: regular expression pattern for the type includes
- `EXCLUDE`: regular expression pattern for the type excludes
- `USER`: the username, consider to use proper credential management as outlined below instead of passing the username explicitly
- `PASSWORD`: the password, consider to use proper credential management as outlined below instead of passing the username explicitly

Optional parameters:

- `override`: overrides a potentially existing project. Use with care.
- `verbose`: prints some information during processing

## Credential Management

The credentials used to access a tenant can be stored securely on your development machine. Depending on the operating system, use one of the following options.

### Credential Management (Windows)

Under Windows use the [Credential Manager](<https://msdn.microsoft.com/en-us/library/windows/desktop/aa380517(v=vs.85).aspx#generic_credentials>) to store your credentials for WCH. You can start the credential manager by navigating to `Control Panel\User Accounts and Family Safety\Credential Manager`. Create a new `Generic Credential`. As `Internet or network address` choose the API URL from WCH, make sure end the URL with a trailing slash. Enter your WCH username and password and hit `OK`.

### Credential Management (Linux)

Under Linux the credentials are read from the `${home}/.ibm-wch-sdk-cli/.credentials` file. Use the `store credentials` command to securely persist the credentials in this file.

## Credential Storage

Stores a user name and password WCH in the file `${home}/.ibm-wch-sdk-cli/.credentials`. The password is encrypted using the private SSH key found in `${home}/.ssh/id_rsa`. This command has been designed to work in a `Unix` environment, but it will also for for `Windows` provided an SSH key exists at the specified location.

### Usage

```bash
ibm-wch-sdk-cli store credentials --password <PASSWORD> [--data <DATA>] [--user <USER>] [--url <API_URL>]
```

With

- `URL`: the API URL of WCH. If this parameter is omitted, will use the value from `%USERPROFILE%/.wchtoolsoptions` as a fallback.
- `USER`: the username. If this parameter is omitted, will use the value from `%USERPROFILE%/.wchtoolsoptions` as a fallback.
- `PASSWORD`: the password
- `DATA`: the WCH tools data folder. If there is a `.wchtoolsoptions` file in this folder, username and URL will be read from that file.

### Note

If the file `${home}/.ssh/id_rsa` does not exist, you can create one using the following shell command:

```bash
ssh-keygen -t rsa -q -f ~/.ssh/id_rsa -P ""
```

## Page Type Generation

Generates a content type for pages, a layout and a layout mapping. After pushing the generated artifacts to WCH, the admin UI can be used to create pages based on this page type.

### Usage

```bash
ibm-wch-sdk-cli create pagetype --data <DATA> --src <SRC> --type <NAME> [--verbose] [--flat] [--scss]
```

With

- `DATA`: wchtools data folder
- `SRC`: target folder of the application that will receive the generated typescript files. Typically this is the `src/app` folder of the application.
- `TYPE`: name of the type to create. This needs to be the full type name, not a regular expression. The name is case sensitive.

## Asset Generation

Generates a managed web asset based on a local file.

### Usage

```bash
ibm-wch-sdk-cli create asset --data <DATA> --src <ASSET_FILE> [--name <NAME>] [--verbose]
```

With

- `DATA`: wchtools data folder
- `SRC`: filename of the asset
- `NAME`: optionally the name of the uploaded asset. If this is missing, the command uses the local filename

## Compilation

The `build production` command performs a production build and make sure to use the configured base URL for the application.

### Usage

```bash
ibm-wch-sdk-cli build production [--data <DATA>] [--src <SRC>] [--name <NAME>]
```

With

- `DATA`: wchtools data folder
- `SRC`: folder with the package JSON
- `NAME`: the application name

## Normalization

The `normalize json` command scans the given directory for JSON files and canonicalizes (normalizes) these files. This is very helpful to compare directories, since the canonicalized files can be compared via standard tools. The normalization process does not modify the semantic of the JSON records.

### Usage

```bash
ibm-wch-sdk-cli normalize json [--data <DATA>] [--verbose]
```

With

- `DATA`: folder containing the JSON records, typically the wchtools data folder

## Libraries

The CLI supports adding component libraries to your application. The command adds the component to the `package.json` as a dependency and will also add the necessary configuration to the application module. Call

```bash
ibm-wch-sdk-cli add library --name <NAME>
```

with

- `NAME`: identification of the module to be added, follows the same format as [npm install](https://docs.npmjs.com/cli/install), e.g. `@myscope/mycomponent` or `@myscope/mycomponent^1.0.0`

### Library Requirements

The library must be a standard NPM library following the [Angular Package Format](https://goo.gl/jB3GVv) specification. The module may optionally declare how it is to be registered in its `package.json`, e.g. like this

```json
{
  "wchConfig": {
    "install": {
      "ngModules": {
        "TextAndImageModule": "@dx-samples/text-and-image-component"
      }
    }
  }
}
```

The `ngModules` entry defined which modules are to be imorted into the application module and where these modules originate from. If the section is missing, then the command will only add the dependency to the `package.json` but will not register the module.

# Getting Started

## Usecase: First time setup

This section describes how to get started with your new WCH tenant.

### Register for a tenant

Get your [WCH tenant](https://www.ibm.com/bs-en/marketplace/cloud-cms-solution) by subscribing for a registration. You will need the following information:

- `username`: the username for your tenant
- `password`: the password for your tenant
- `API_URL`: copy this URL from the **Watson Content Hub Information** section from the WCH UI, the URL e.g. looks like this `https://dch-dxcloud.rtp.raleigh.ibm.com/api/bd24d106-f6a1-46e4-b50f-1f80b15bc0b2`.

### Install Node-JS

Install [Node-JS](https://nodejs.org/en/) `>= 6` for your environment.

### Store your credentials

Securely store your credentials in a [Credential Store](#credential-management).

For `Linux` call

```bash
ibm-wch-sdk-cli store credentials --password <PASSWORD> --user <USER> --url <API_URL>
```

For `Windows` follow the instructions in [credential management](#credential-management).

### Initialize your project

Bootstrap the initial version of your application by calling:

```bash
ibm-wch-sdk-cli create project --name <NAME> --src <PROJECT_FOLDER> --url <API_URL>
```

Note that the project name cannot be `test`. New project names must start with a letter, and must contain only alphanumeric characters or dashes. When adding a dash the segment after the dash must also start with a letter.

After the initialization of the project (at least) the following folders exists in your project folder:

- `src`: folder that contains the application, ready to be built
- `data`: folder that contains the related WCH artifacts such as layouts, layout mappings and sites

### Build you application

Change into the project folder and initialize the environment (this step might take a little while):

```bash
npm install
npm dedupe
```

Run your application in development mode

```bash
npm run start
```

You can now access the application on `http://localhost:4200`.

### Publish your application

After local development you will want to publish the application. Call

```bash
npm run deploy
```

This will build the application in production mode and will also publish it to your tenant.

## Usecase: Add Pages

In order to create a meaningful application you will need to create pages and associate content and layouts with these pages.

### Create a Page Content Type

Pages can only be created in the WCH admin UI if there exists a content type for the desired page. Create such a content type by calling

```bash
npm run gen:pagetype <NAME>
```

Where `NAME` is the desired name of the type. This creates the required type, layout, layout mappings and also registers Angular components for the layouts. Note that the page type will per default not contain any elements. These can be added later via the WCH UI of by editing the type document.

You can run the command multiple times in a row to create many pages types.

### Push the new Page Content Type to the server

In order to create a page via the UI, push your changes to wch. Call

```bash
npm run deploy:push
```

Note that this command relies on the username and password to be stored in the [Credential Store](#credential-management).

### Create new Pages

Login to the WCH admin UI and create the desired page and content hierarchy.

## Stories

- (Continuous Delivery using GitHub and Travis)(#continuous_delivery_using_github_and_travis)

### Continuous Delivery using GitHub and Travis

This section describes how to set up a continuous delivery process to automatically deploy your application to [WCH](https://www.ibm.com/products/watson-content-hub).

- Setup a [github repository](https://github.com/). Use this repository to host your code.
- Setup a [travis account](https://travis-ci.org) and link it to your repository.
- Make sure that your project can be built and deployed using an npm command, if you used the [create project](#initialize_your_project) command to setup your project, then the command is `npm run deploy`.
  - the deploy command reads the API URL from the `.wchtoolsoptions.json` file from your data folder. Validate that this URL is correct.
- Add a `.travis.yml` file to your application. Per default this file will already be available.
- Configure your travis build step
  - add the `ibm_wch_sdk_cli_username` environment variable and set it to your username
  - add the `ibm_wch_sdk_cli_password` environment variable and set it to your password. Make sure to mark this as secured.
  - check the `build only if .travis.yml is present` checkbox

Done, when doing a commit to github this will automatically trigger the build and deployment pipeline and update your [WCH tenant](https://www.ibm.com/products/watson-content-hub).

### Sample .travis.yml file

```yaml
language: node_js
sudo: false
node_js:
  - '8'
cache:
  directories:
    - 'node_modules'
script:
  - npm run deploy
```