dp-command
v1.2.1
Published
CLI for interacting with APIs
Readme
dp
Use your terminal to interact with APIs. Any API.
Index
Motivation
The problem
Interacting with an API as an admin can be sometimes hard or not user-friendly. You might have a web app for users, but no UI for amdin features.
Building a UI only for few admin features is not worth it.
So, how do you end up interacting with the admin API? Using Postman, curl, browser...
The solution
dp is a tool to interact with any API. Ideally, these API endpoints can be configured to work with dp,
keeping in mind it is a CLI tool.
💡 You can design API endpoints to work with dp
With dp, you can have access to different APIs, configure the command you will use and the token.
Installation
You can install the dp command using the following command:
npm i -g dp-command@latestUsage
Add an instance
To add an API, use the following command:
dp addYou will be prompted to add the name and endpoint of the API.
The name will be used to access that instance. For example, you will be able to use:
dp <your-app-name> healthThis will make a GET request to <your-endpoint>/health.
Edit an instance
You can edit an instance using:
dp update <your-app-name> [--name=NAME] [--endpoint=ENDPOINT] [--token=TOKEN] [--remote-code-execution={0|1}]Delete an instance
You can delete an instance using:
dp rm <your-app-name>List all instances
You can list all instances using the following command. It will be printed as a table.
dp lsDelete all instances
If you need to do a factory reset you can use the following command to delete the dp configuration:
dp delete-configurationAPI design
Base path
Since the API design for using dp is specific for this goal, you might want to separate these endpoints
from your main API. You can create your dp endpoints inside a path, such as https://api.example.com/dp
Configure your instance endpoint (Edit an instance)
Tokens
dp can send tokens on the requests made to APIs. It will use the header Authorization and will use a Bearer token.
Configure your instance token (Edit an instance)
Requests
All requests will use the GET or POST methods. The POST method will be used when the API returns a prompt.
The API endpoints will be built based on the command given.
dp <your-app-name> users john-doe shadowban --hours=5
turns into:
GET <your-endpoint>/users/john-doe/shadowban?hours=5With this in mind, you can reorder your API organization to make the command feel more natural:
dp <your-app-name> shadowban john-doe --hours=5
turns into:
GET <your-endpoint>/shadowban/john-doe?hours=5POST method
The POST method will be used when dp submits a prompt to the API. The endpoint path will be same, with the same query parameters, but it will include a body too.
User Agent
The requests made through dp will include a User-Agent header with the value dp-command / <VERSION>.
<VERSION> is the npm package version. So, for version 1.0.2, the User-Agent would be dp-command / 1.1.0.
Format
Ideally, the API should return the responses in JSON. This way, dp can parse and execute logic based on the returned data.
If dp can't parse the JSON, it will return the response as text.
Errors
When the API wants to return an error, it can return a JSON with the following formats:
{ "error": { "message": "ERROR_MESSAGE" } }{ "success": false }The first example will throw an error and print "ERROR_MESSAGE" on the terminal
Interaction with terminal
The API can interact with the terminal by returning these kind of elements. You can combine all the elements in the same API response.
Message
Make a message appear in the terminal:
{ "message": "Hello world" }This will print "Hello world" in the terminal.
Table
Make a table appear in the terminal:
{ "table": {
"content": [
{ "Header": "content", "Header 2": "content" },
{ "Header": "content", "Header 2": "content" }
]
}}You can make the table vertical using:
{ "table": {
"vertical": true,
"content": [
{ "Name": "John"},
{ "Surname": "Doe"}
]
}}Prompt
The API can send a form/prompt to be submitted from the terminal. These are the different options for creating prompts:
{ "prompt": [
{
"type": "text",
"name": "name",
"title": "Name",
"placeholder": "Please write a name"
},
{
"type": "password",
"name": "code",
"title": "Secret code"
},
{
"type": "confirm",
"name": "public",
"title": "Make user public"
},
{
"type": "select",
"name": "user_type",
"title": "User type",
"options": [
{ "value": "admin", "label": "Admin" },
{ "value": "user", "label": "User" },
]
},
{
"type": "hidden",
"name": "process",
"value": "create_user"
}
]}After all the prompts are completed, dp will send back the answers to the same endpoint, but using the POST method and attaching the answers as the body of the request.
Prompt flow example
1. The user executes a command
dp <your-app-name> register-user2. A request is made to the API
GET <your-endpoint>/register-user3. The API responds
{ "prompt": [
{
"type": "text",
"name": "username",
"title": "Username",
"placeholder": "A good username"
}
]}4. dp prompts a question to the user
Username:
> john-doe5. The user submits the question
6. dp sends the result to the API
POST <your-endpoint>/register-user
{ "username": "john-doe" }7. The API responds
{ "message": "User created" }8. dp shows the user the message sent by the API
User createdCommand
The API can send a command to be executed in the user's terminal. For doing so, the user needs to have the instance configured to execute commands.
dp update <your-app-name> --remote-code-execution=1The API has to respond the following to execute a command:
{ "command": "ls -l" }If the user hasn't configured the instance to execute the command, it will print the command in the terminal.
Token
The API can set user's instance token. Useful for when creating a login flow using dp or to log out.
{ "token": "95687afb5d9a2a9fa39038f991640b0c" }You will be able to use:
dp <your-app-name> login
// API can return a prompt for username and password and then, if correct, return a tokenand
dp <your-app-name> logout
// API can return an empty token to remove user's local tokenExample
For this example, we will be using npoint.io to host our server response.
Our endpoint is https://api.npoint.io/383cab3939da2e10034e.
To make it work, you need to follow the next steps:
1. Create an instance
dp addFor the name, use example, for the endpoint use https://api.npoint.io
2. (Optional) Make the code executable
dp update example --remote-code-execution=13. Execute the "command"
dp example 383cab3939da2e10034eThis will return a message, a table, a prompt, and execute a command (ls).
Content of https://api.npoint.io/383cab3939da2e10034e:
{
"message": "Hey! This is a test",
"table": {
"content": [
{
"Name": "John",
"Surname": "Doe",
"Email": "[email protected]"
},
{
"Name": "Jane",
"Surname": "Doe",
"Email": "[email protected]"
}
]
},
"prompt": [
{
"type": "text",
"name": "name",
"title": "Name",
"placeholder": "Please write a name"
},
{
"type": "password",
"name": "code",
"title": "Secret code"
},
{
"type": "confirm",
"name": "public",
"title": "Make user public"
},
{
"type": "select",
"name": "user_type",
"title": "User type",
"options": [
{
"value": "admin",
"label": "Admin"
},
{
"value": "user",
"label": "User"
}
]
}
],
"command": "ls"
}Aliases
For faster typing, you can create an alias to your dp instance.
For example, instead of using
dp <your-app-name> orders lsyou can use:
<your-app-name> orders lsThis can be done creating an alias. Edit your ~/.bashrc file and add the following line:
alias <your-app-name>="dp <your-app-name>"People
The original author of dp is itaibo
You can contribute too!
