In this tutorial, you learn how to use oclif to create a CLI that lists the articles in your DEV account.
The goal is to show how to create a CLI that interacts with an authenticated API. We will only add one single command, (list), however extending the CLI should be pretty straightforward.
This tutorial documents the first steps I took when I built dev-to-sync, take a look at that repo to see how I added some more commands.
Requirements
Node.js and NPM, visit the homepage for installation instructions.
- Run
node -v
to verify you have version 12 or higher. - Run
npm -v
to verify you have version 6 or higher.
- Run
A DEV API key
- Generate one here https://dev.to/settings/account.
Install the oclif cli
npm install -g oclif
Setup a new project
oclif multi dev-to-sync
cd dev-to-sync
Initialize git repo
Even though it's not essential for the working of the CLI, you probably want to initialize a git repo and do an initial commit.
git init
git commit -m "Initial commit"
Link local project
In order to make our new CLI available for running it locally while we're developing it, it needs to be linked:
npm link
Run it
Now that that's done, we can give it a run to see if it all works.
If all went well, running the command
dev-to-sync
should output something like this:
$ dev-to-sync
Sync your DEV account with a local folder
VERSION
dev-to-sync/0.0.0 darwin-x64 node-v12.18.1
USAGE
$ dev-to-sync [COMMAND]
COMMANDS
hello describe the command here
help display help for dev-to-sync
This shows us there is a hello command, which we can execute like this:
$ dev-to-sync hello
hello world from ./src/commands/hello.ts
Creating alias
In this step we give our CLI a shortcut
dts
so we can invoke it with less keystrokes.
Open
package.json
and add a key
dts
with value
./bin/run
to the
bin
object.
"bin": {
"dev-to-sync": "./bin/run",
"dts": "./bin/run"
}
After this you need to run
npm link
again to make sure your operating system is aware of the new command.
Create a wrapper for the DEV api
To access the DEV api we create a wrapper class called
DevtoClient
. We initialize the class with the API key and use that to set up the header, adding the
api-key
property to each request.
We implement a
get
method to execute authenticated requests to the DEV api and a
getArticles
method that retreives the articles.
Install the dependencies
Install
node-fetch
and it's types:
npm install node-fetch
npm install -D @types/node-fetch
Create the client
Create
src/lib/devto-client.ts
and add the following snippet:
import fetch from "node-fetch";
export class DevtoClient {
private readonly baseUrl = "https://dev.to/api";
private readonly headers: { "api-key": string; "content-type": string };
constructor(private readonly apiKey: string) {
this.headers = {
"api-key": this.apiKey,
"content-type": "application/json",
};
}
get(url: string) {
return fetch(this.baseUrl + url, { headers: this.headers }).then((res) =>
res.json()
);
}
async getArticles(): Promise<any[]> {
const result = await this.get("/articles/me/all");
if (!result) {
throw new Error("Error retrieving articles");
}
return result;
}
}
Create
src/lib/utils.ts
and add the following snippet:
import { DevtoClient } from "./devto-client";
if (!process.env.DEV_TO_TOKEN) {
throw new Error(`
Environment variable DEV_TO_TOKEN not found
`);
}
export const client = new DevtoClient(process.env.DEV_TO_TOKEN);
We now can import the
client
at any of the commands and use it.
Implementing the list command
Create the command
Run the following command to create a new command to the CLI:
oclif command list
Implement the command
Open
src/commands/list.ts
and replace the content with the following snippet:
import { Command } from "@oclif/command";
import { client } from "../lib/utils";
export default class List extends Command {
static description = "List articles in a DEV account";
async run() {
const articles = await client.getArticles();
for (const article of articles) {
console.log(article.title);
}
}
}
Test the command
$ dts list
Tutorial: Styling Angular CLI Apps with Bootstrap
Automate your DEV Posts using GitHub Actions
Using yarn with Angular CLI
Where to go from here?
This should be a steady basis to quickly build more functionality. You can, for example:
- Use
oclif command
to add more commands, check the DEV api documentation for the available API methods. - Add colors to the output using chalk.
- Make the CLI interactive using inquirer.
- Use oclif plugins if you want to add additional functionality to your CLI like autoupdate, autocomplete or update warnings.
- Download beeman/dev-to-sync for a more complete implementation.
Conclusion
In this tutorial, we created a CLI from scratch by using oclif. After setting up the project, we implemented an API client that communicates with the DEV api, and a small method that wraps the API client and takes the API key from the environment. The last step was implementing the list command to retrieve the articles from the list, and show them in the console.
Thanks!
Thanks for reading my article. Feel free to reach out if you have any questions! Follow me on Twitter or leave a comment on DEV! 🐝