Extending a plug-in
Extending a plug-in
Before you begin, be sure to complete the Installing the sample plug-in tutorial.
Overview
This tutorial demonstrates how to extend the plug-in that is bundled with this sample by:
- Creating a Typescript interface for the Typicode response data
- Creating a programmatic API
- Creating a command definition
- Creating a command handler
We'll do this by using @zowe/imperative
infrastructure to surface REST API data on our Zowe™ CLI plug-in.
Specifically, we're going to show data from this URI by Typicode. Typicode serves sample REST JSON data for testing purposes.
At the end of this tutorial, you will be able to use a new command from the Zowe CLI interface: zowe zowe-cli-sample list typicode-todos
Completed source for this tutorial can be found on the typicode-todos
branch of the zowe-cli-sample-plugin repository.
Creating a Typescript interface for the Typicode response data
First, we'll create a Typescript interface to map the response data from a server.
Within zowe-cli-sample-plugin/src/api
, create a folder named doc
to contain our interface (sometimes referred to as a "document" or "doc"). Within the doc folder, create a file named ITodo.ts
.
The ITodo.ts
file will contain the following:
export interface ITodo {
userId: number;
id: number;
title: string;
completed: boolean;
}
Creating a programmatic API
Next, we'll create a Node.js API that our command handler uses. This API can also be used in any Node.js application, because these Node.js APIs make use of REST APIs, Node.js APIs, other NPM packages, or custom logic to provide higher level functions than are served by any single API.
Adjacent to the existing file named zowe-cli-sample-plugin/src/api/Files.ts
, create a file Typicode.ts
.
Typicode.ts
should contain the following:
import { ITodo } from "./doc/ITodo";
import { RestClient, AbstractSession, ImperativeExpect, Logger } from "@zowe/imperative";
export class Typicode {
public static readonly TODO_URI = "/todos";
public static getTodos(session: AbstractSession): Promise<ITodo[]> {
Logger.getAppLogger().trace("Typicode.getTodos() called");
return RestClient.getExpectJSON<ITodo[]>(session, Typicode.TODO_URI);
}
public static getTodo(session: AbstractSession, id: number): Promise<ITodo> {
Logger.getAppLogger().trace("Typicode.getTodos() called with id " + id);
ImperativeExpect.toNotBeNullOrUndefined(id, "id must be provided");
const resource = Typicode.TODO_URI + "/" + id;
return RestClient.getExpectJSON<ITodo>(session, resource);
}
}
The Typicode
class provides two programmatic APIs, getTodos
and getTodo
, to get an array of ITodo
objects or a specific
ITodo
respectively. The Node.js APIs use @zowe/imperative
infrastructure to provide logging, parameter validation,
and to call a REST API. See the Imperative CLI Framework documentation for more information.
Exporting interface and programmatic API for other Node.js applications
Update zowe-cli-sample-plugin/src/index.ts to contain the following:
export * from "./api/doc/ITodo";
export * from "./api/Typicode";
A sample invocation of your API might look similar to the following, if it were used by a separate, standalone Node.js application:
import { Typicode } from "@zowe/zowe-cli-sample-plugin";
import { Session, Imperative } from "@zowe/imperative";
import { inspect } from "util";
const session = new Session({ hostname: "jsonplaceholder.typicode.com"});
(async () => {
const firstTodo = await Typicode.getTodo(session, 1);
Imperative.console.debug("First todo was: " + inspect(firstTodo));
})();
Checkpoint one
Issue npm run build
to verify a clean compilation and confirm that no lint errors are present. At this point in this tutorial, you have a programmatic API
that will be used by your handler or another Node.js application. Next you'll define the command syntax for the command that will use your programmatic Node.js APIs.