superuser.app 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +296 -0
- package/commands/domains/add.js +102 -0
- package/commands/domains/list.js +71 -0
- package/commands/domains/remove.js +97 -0
- package/commands/domains/verify.js +130 -0
- package/commands/g/endpoint.js +32 -0
- package/commands/g/test.js +42 -0
- package/commands/init.js +220 -0
- package/commands/login.js +123 -0
- package/commands/me.js +54 -0
- package/commands/organizations/create.js +68 -0
- package/commands/profile.js +58 -0
- package/commands/register.js +127 -0
- package/commands/run.js +194 -0
- package/commands/serve.js +35 -0
- package/commands/test.js +68 -0
- package/commands/up.js +257 -0
- package/commands/update.js +84 -0
- package/commands/version.js +31 -0
- package/helpers/constants.js +3 -0
- package/helpers/draw_box.js +38 -0
- package/helpers/draw_table.js +144 -0
- package/helpers/file_writer.js +101 -0
- package/helpers/generate/endpoint/_index.js +44 -0
- package/helpers/generate/test/_index.js +112 -0
- package/helpers/load_package.js +62 -0
- package/helpers/local_server.js +72 -0
- package/helpers/settings_manager.js +108 -0
- package/helpers/verify_packages.js +85 -0
- package/index.js +7 -0
- package/package.json +31 -0
- package/src/endpoint/functions/index.js +35 -0
- package/src/init/__.env +1 -0
- package/src/init/__.env.production +1 -0
- package/src/init/__.env.staging +1 -0
- package/src/init/__.gitignore +6 -0
- package/src/init/functions/index.js +15 -0
- package/src/init/instant.package.json +3 -0
- package/src/init/package.json +16 -0
- package/src/init/serve.instant.js +52 -0
- package/src/init/test/run.js +45 -0
- package/src/init/test/tests/_index.js +53 -0
- package/src/test/blank.mjs +16 -0
- package/src/test/endpoint.mjs +20 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Keith William Horwood
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# Superuser Package Manager
|
|
2
|
+
## Extend AI agents with tools, instantly
|
|
3
|
+
|
|
4
|
+
`ibot` is the official CLI for publishing [Superuser](https://instant.chat) packages.
|
|
5
|
+
You can use this utility to publish new packages to the Superuser package registry,
|
|
6
|
+
available at [instant.chat/packages](https://instant.chat/packages).
|
|
7
|
+
|
|
8
|
+
[Superuser](https://instant.chat) enables you to rapidly build custom
|
|
9
|
+
chatbots and AI agents that can be extended with custom tools. It provides four
|
|
10
|
+
major features;
|
|
11
|
+
|
|
12
|
+
1. Chat with and develop your agent in real time from the web
|
|
13
|
+
2. Extend your agent with [hosted tool packages](https://instant.chat/packages)
|
|
14
|
+
3. Write your own private tool packages for your agents
|
|
15
|
+
4. Deploy your agent to third-party services like Discord and Slack
|
|
16
|
+
|
|
17
|
+
## What is the Superuser Package Registry?
|
|
18
|
+
|
|
19
|
+
The Superuser Package Registry is a **serverless hosting platform and registry** for
|
|
20
|
+
building tools that extend AI chatbots and agents.
|
|
21
|
+
|
|
22
|
+
**Superuser packages are just REST API servers.**
|
|
23
|
+
Every package is an [Instant API](https://github.com/instant-dev/api) project,
|
|
24
|
+
which is a simple way to export and auto-document JavaScript functions as REST endpoints
|
|
25
|
+
that can be called via any HTTP client.
|
|
26
|
+
|
|
27
|
+
Authentication to your published packages are handled via **API keychains** which
|
|
28
|
+
are delegated via [Superuser](https://instant.chat).
|
|
29
|
+
|
|
30
|
+
**NOTE:** While in beta, only Superuser agents can use your published tools.
|
|
31
|
+
We'll be opening up the gateway to programmatic access in the coming months.
|
|
32
|
+
|
|
33
|
+
## Superuser Package vs. MCP
|
|
34
|
+
|
|
35
|
+
Reminder, **Superuser packages are just REST API servers.**
|
|
36
|
+
|
|
37
|
+
MCP, or Model Context Protocol, is a standard for passing tool and prompt context
|
|
38
|
+
between AI models and service providers. Superuser packages are **not**
|
|
39
|
+
MCP compatible out of the box, as they are simply REST APIs. However, it is our goal to add
|
|
40
|
+
MCP bindings to the [Instant API](https://github.com/instant-dev/api) framework which
|
|
41
|
+
powers all Superuser packages. When formalized, this will allow you to use
|
|
42
|
+
Superuser packages with any MCP-compatible client or service provider.
|
|
43
|
+
Contributors welcome!
|
|
44
|
+
|
|
45
|
+
## Quickstart
|
|
46
|
+
|
|
47
|
+
Visit [instant.chat/signup](https://instant.chat/signup) to register.
|
|
48
|
+
Creating a new bot is easy, you can then use this CLI to develop
|
|
49
|
+
and publish custom packages to extend your bots.
|
|
50
|
+
|
|
51
|
+
```shell
|
|
52
|
+
$ npm i ibot -g
|
|
53
|
+
$ mkdir new-project
|
|
54
|
+
$ cd new-project
|
|
55
|
+
$ ibot init # initialize project in this directory
|
|
56
|
+
$ ibot login # log in to Superuser Package Registry with your Superuser account
|
|
57
|
+
$ ibot serve # run your tool package on a local server to test
|
|
58
|
+
$ ibot run / # test a single endpoint (like curl)
|
|
59
|
+
$ ibot up # publish to development environment
|
|
60
|
+
$ ibot up --env staging # publish to staging environment
|
|
61
|
+
$ ibot up --env production # publish to production environment
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
You can run `ibot help` at any time to see available commands.
|
|
65
|
+
|
|
66
|
+
# Table of contents
|
|
67
|
+
|
|
68
|
+
1. [How does Superuser work?](#how-does-instant-bot-work)
|
|
69
|
+
1. [How is hosting billed?](#how-is-hosting-billed)
|
|
70
|
+
1. [Building custom packages for your bots](#building-custom-packages-for-your-bots)
|
|
71
|
+
1. [Initialize a project](#initialize-a-project)
|
|
72
|
+
1. [Defining tools aka endpoints](#defining-tools-aka-endpoints)
|
|
73
|
+
1. [Endpoint name, description, types](#endpoint-name-description-types)
|
|
74
|
+
1. [Deploy an Superuser Package](#deploy-an-instant-tool-package)
|
|
75
|
+
1. [Public packages](#public-packages)
|
|
76
|
+
1. [Private packages](#private-packages)
|
|
77
|
+
1. [Additional utilities](#additional-utilities)
|
|
78
|
+
1. [Generate endpoints](#generate-endpoints)
|
|
79
|
+
1. [Generate tests](#generate-tests)
|
|
80
|
+
1. [Run tests](#run-tests)
|
|
81
|
+
1. [Environment variables](#environment-variables)
|
|
82
|
+
1. [Roadmap](#roadmap)
|
|
83
|
+
1. [Contact](#contact)
|
|
84
|
+
|
|
85
|
+
# How does Superuser work?
|
|
86
|
+
|
|
87
|
+
Superuser provides hosting for both (1) your agent and (2) your tool packages.
|
|
88
|
+
Your agent is a chatbot that you can chat with directly via the Superuser web interface.
|
|
89
|
+
Tool packages are REST APIs that can be used by your agent. You can publish tool packages
|
|
90
|
+
for use by your agent and others or keep them private.
|
|
91
|
+
|
|
92
|
+
When you ask your agent a question that requires a tool call, Superuser will
|
|
93
|
+
automatically route the request to the appropriate tool from the Superuser Package Registry
|
|
94
|
+
and call the tool on your behalf.
|
|
95
|
+
|
|
96
|
+
## How is hosting billed?
|
|
97
|
+
|
|
98
|
+
Model usage (generating responses) is a subscription-based service. However,
|
|
99
|
+
for development purposes, you can use our lowest-tier model indefinitely in rate-limited mode
|
|
100
|
+
on the free tier **but only while on the web interface**.
|
|
101
|
+
|
|
102
|
+
Tools cost money to run, and are billed as serverless functions
|
|
103
|
+
at a rate of [$0.50 of credits per 1,000 GB-s](https://instant.chat/pricing) of usage.
|
|
104
|
+
Credits are prepaid, and during our beta period all users get a one-time bonus of $1.00
|
|
105
|
+
in free usage credits.
|
|
106
|
+
|
|
107
|
+
GB-s represents a "gigabyte-second" and is calculated by the function RAM × execution time.
|
|
108
|
+
For example, a function with 512 MB (0.5 GB) of RAM running for 200ms would use:
|
|
109
|
+
|
|
110
|
+
- Used GB-s = 0.5GB × 0.2s = 0.1 GB-s
|
|
111
|
+
- Used credits = $0.50 / 1,000 GB-s × 0.1 GB-s = $0.00005
|
|
112
|
+
|
|
113
|
+
# Building custom packages for your bots
|
|
114
|
+
|
|
115
|
+
Building bots on [Superuser](https://instant.chat) is straightforward. Extending
|
|
116
|
+
with custom tool packages can be done online via the web interface, or if you prefer
|
|
117
|
+
working with your own editor, you can use this CLI.
|
|
118
|
+
|
|
119
|
+
## Initialize a project
|
|
120
|
+
|
|
121
|
+
To initialize a new Superuser package:
|
|
122
|
+
|
|
123
|
+
```shell
|
|
124
|
+
$ npm i ibot -g
|
|
125
|
+
$ mkdir new-project
|
|
126
|
+
$ cd new-project
|
|
127
|
+
$ ibot init
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
You'll be walked through the process. The `ibot` CLI will automatically check for
|
|
131
|
+
updates to core packages, so make sure you update when available. To play around with your
|
|
132
|
+
Superuser package locally;
|
|
133
|
+
|
|
134
|
+
```shell
|
|
135
|
+
$ ibot serve
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Will start an HTTP server. To execute a standalone endpoint / tool:
|
|
139
|
+
|
|
140
|
+
```shell
|
|
141
|
+
$ ibot run /
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Defining tools aka endpoints
|
|
145
|
+
|
|
146
|
+
Defining custom tools is easy. You'll find the terms **tool** and
|
|
147
|
+
**endpoint** used interchangeably as they all refer
|
|
148
|
+
to the same thing: your bot executing custom code in the cloud.
|
|
149
|
+
|
|
150
|
+
A **tool** is just an **endpoint** hosted by the Superuser Package Registry.
|
|
151
|
+
|
|
152
|
+
All endpoints for Superuser packages live in the `functions/` directory.
|
|
153
|
+
Each file name maps to the endpoint route e.g. `functions/hello.js`
|
|
154
|
+
routes to `localhost:8000/hello`. You can export custom `GET`, `POST`, `PUT`
|
|
155
|
+
and `DELETE` functions from every file. Here's an example "hello world" endpoint:
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
// functions/hello.js
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* A basic hello world function
|
|
162
|
+
* @param {string} name Your name
|
|
163
|
+
* @returns {string} message The return message
|
|
164
|
+
*/
|
|
165
|
+
export async function GET (name = 'world') {
|
|
166
|
+
return `hello ${name}`!
|
|
167
|
+
};
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
You can write any code you want and install any NPM packages you'd like to
|
|
171
|
+
your tool package.
|
|
172
|
+
|
|
173
|
+
### Endpoint name, description, types
|
|
174
|
+
|
|
175
|
+
Using the comment block above every exported method (e.g. GET) you can
|
|
176
|
+
define your endpoint. Superuser packages use an open source specification called
|
|
177
|
+
[Instant API](https://github.com/instant-dev/api) to export JavaScript
|
|
178
|
+
functions as type safe web APIs. You can learn more about how to properly
|
|
179
|
+
define and document the shape (parameters) of your API there.
|
|
180
|
+
|
|
181
|
+
## Deploy an Superuser Package
|
|
182
|
+
|
|
183
|
+
### Public packages
|
|
184
|
+
|
|
185
|
+
**NOTE:** You **will not** be charged for other people using your public actions.
|
|
186
|
+
They are billed directly from their account.
|
|
187
|
+
|
|
188
|
+
By default all packages are created as public projects. Public
|
|
189
|
+
projects are namespaced to your username, e.g. `@my-username/project`.
|
|
190
|
+
This can be found in the `"name"` field of `superuser.json`.
|
|
191
|
+
|
|
192
|
+
Note that the code for public projects will be shared publicly for anybody
|
|
193
|
+
to see, and the expectation is that others can use this code in their bots
|
|
194
|
+
as well.
|
|
195
|
+
they will be billed from their balance.
|
|
196
|
+
|
|
197
|
+
To deploy a public project to a `development` environment, you can use:
|
|
198
|
+
|
|
199
|
+
```shell
|
|
200
|
+
$ ibot up
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
You can also publish to `staging` and `production` using:
|
|
204
|
+
|
|
205
|
+
```shell
|
|
206
|
+
$ ibot up --env staging
|
|
207
|
+
$ ibot up --env production
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Private packages
|
|
211
|
+
|
|
212
|
+
**NOTE:** You **_WILL_** be charged by anybody accessing your private
|
|
213
|
+
packages. However, all code and endpoints will not be publicly available;
|
|
214
|
+
you must share the URL with somebody in order for them to use it.
|
|
215
|
+
|
|
216
|
+
You can publish private project by prepending `private/` on the
|
|
217
|
+
`"name"` field in `superuser.json`, e.g.
|
|
218
|
+
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"name": "private/@my-username/private-package"
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
You then deploy as normal. These packages will be visible by you in the
|
|
226
|
+
registry but nobody else.
|
|
227
|
+
|
|
228
|
+
# Additional utilities
|
|
229
|
+
|
|
230
|
+
There are a few additional utilities you may find useful with this package;
|
|
231
|
+
|
|
232
|
+
## Generate endpoints
|
|
233
|
+
|
|
234
|
+
```shell
|
|
235
|
+
# generates functions/my-endpoint/example.js
|
|
236
|
+
$ ibot g:endpoint my-endpoint/example
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Generate tests
|
|
240
|
+
|
|
241
|
+
```shell
|
|
242
|
+
# Generate blank tests or ones for an endpoint
|
|
243
|
+
$ ibot g:test my_test # OR ...
|
|
244
|
+
$ ibot g:test --endpoint my-endpoint/example
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Run tests
|
|
248
|
+
|
|
249
|
+
You can write tests for your tools to verify they work. Simply run;
|
|
250
|
+
|
|
251
|
+
```shell
|
|
252
|
+
$ ibot test
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
And voila!
|
|
256
|
+
|
|
257
|
+
## Environment variables
|
|
258
|
+
|
|
259
|
+
You can store environment variables with your packages in;
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
.env
|
|
263
|
+
.env.production
|
|
264
|
+
.env.staging
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
These files **will not** be published for everybody to see, so
|
|
268
|
+
you can use them to hide secrets within your code. However, be
|
|
269
|
+
careful when using environment variables with public packages:
|
|
270
|
+
if you ever return them in an endpoint response, or connect to
|
|
271
|
+
sensitive data, there's a chance you may expose that information
|
|
272
|
+
to another user of the platform.
|
|
273
|
+
|
|
274
|
+
# Roadmap
|
|
275
|
+
|
|
276
|
+
There's a lot to build! [Superuser](https://instant.chat) is still in early beta. Coming soon;
|
|
277
|
+
|
|
278
|
+
- Deploy to Slack
|
|
279
|
+
- Uploading image support
|
|
280
|
+
- Knowledge bases
|
|
281
|
+
- Much more!
|
|
282
|
+
|
|
283
|
+
Submit requests via Discord at [discord.gg/instant](https://discord.gg/instant)!
|
|
284
|
+
|
|
285
|
+
# Contact
|
|
286
|
+
|
|
287
|
+
The best place for help and support is Discord at [discord.gg/instant](https://discord.gg/instant),
|
|
288
|
+
but feel free to bookmark all of these links.
|
|
289
|
+
|
|
290
|
+
| Destination | Link |
|
|
291
|
+
| ----------- | ---- |
|
|
292
|
+
| Superuser | [instant.chat](https://instant.chat) |
|
|
293
|
+
| GitHub | [github.com/instantbots](https://github.com/instantbots) |
|
|
294
|
+
| Discord | [discord.gg/instant](https://discord.gg/instant) |
|
|
295
|
+
| X / instantbots | [x.com/instantbots](https://x.com/instantbots) |
|
|
296
|
+
| X / Keith Horwood | [x.com/keithwhor](https://x.com/keithwhor) |
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const { Command } = require('cmnd');
|
|
2
|
+
const io = require('io');
|
|
3
|
+
const colors = require('colors/safe');
|
|
4
|
+
const inquirer = require('inquirer');
|
|
5
|
+
|
|
6
|
+
const constants = require('../../helpers/constants.js');
|
|
7
|
+
const SettingsManager = require('../../helpers/settings_manager.js');
|
|
8
|
+
|
|
9
|
+
class DomainsAddCommand extends Command {
|
|
10
|
+
|
|
11
|
+
constructor() {
|
|
12
|
+
super('domains', 'add');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
help () {
|
|
16
|
+
return {
|
|
17
|
+
description: 'Add a custom domain to a package',
|
|
18
|
+
args: [],
|
|
19
|
+
flags: {},
|
|
20
|
+
vflags: {}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async run (params) {
|
|
25
|
+
|
|
26
|
+
const settings = SettingsManager.read(true);
|
|
27
|
+
const host = settings.activeProfile.host || constants.BASE_URL;
|
|
28
|
+
|
|
29
|
+
let addResult = await inquirer.prompt([
|
|
30
|
+
{
|
|
31
|
+
name: 'hostname',
|
|
32
|
+
type: 'input',
|
|
33
|
+
message: `Hostname`,
|
|
34
|
+
validate: e => {
|
|
35
|
+
if (!e.match(/^([a-z0-9\-]+.)+[a-z0-9\-]+$/gi)) {
|
|
36
|
+
return 'Must be a valid hostname'
|
|
37
|
+
} else {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'name',
|
|
44
|
+
type: 'input',
|
|
45
|
+
message: `Package name`,
|
|
46
|
+
validate: v => {
|
|
47
|
+
if (
|
|
48
|
+
v.match(/@[a-z][a-z0-9\-]*[a-z0-9]\/[a-z][a-z0-9\-]*[a-z0-9]/i) &&
|
|
49
|
+
v.indexOf('--') === -1
|
|
50
|
+
) {
|
|
51
|
+
return true;
|
|
52
|
+
} else {
|
|
53
|
+
return 'must be a valid package name in format "@org/package"';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'environment',
|
|
59
|
+
type: 'list',
|
|
60
|
+
message: 'Environment',
|
|
61
|
+
choices: [
|
|
62
|
+
'development',
|
|
63
|
+
'staging',
|
|
64
|
+
'production'
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
const postParams = {...addResult};
|
|
70
|
+
|
|
71
|
+
const result = await io.post(
|
|
72
|
+
`${host}/v1/custom_domains`,
|
|
73
|
+
settings.activeProfile.key,
|
|
74
|
+
null,
|
|
75
|
+
postParams
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
if (result.statusCode !== 200) {
|
|
79
|
+
const message = result.data?.error?.message || `Invalid statusCode: ${result.statusCode}`;
|
|
80
|
+
throw new Error(message);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const customDomain = result.data;
|
|
84
|
+
const packageName = `@${customDomain.package.organization.name}/${customDomain.package.name}`;
|
|
85
|
+
const environment = customDomain.environment;
|
|
86
|
+
|
|
87
|
+
console.log();
|
|
88
|
+
console.log(`${colors.bold.green('Success!')} Custom domain created.`);
|
|
89
|
+
console.log(`${colors.bold(`hostname`)}: ${customDomain.hostname}`);
|
|
90
|
+
console.log(`${colors.bold(`package`)}: ${packageName}`);
|
|
91
|
+
console.log(`${colors.bold(`environment`)}: ${environment}`);
|
|
92
|
+
console.log(`${colors.bold(`verified at`)}: ${customDomain.verified_at || '(unverified)'}`);
|
|
93
|
+
console.log(`${colors.bold(`created`)}: ${customDomain.created_at}`);
|
|
94
|
+
console.log();
|
|
95
|
+
|
|
96
|
+
return void 0;
|
|
97
|
+
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = DomainsAddCommand;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const { Command } = require('cmnd');
|
|
2
|
+
const io = require('io');
|
|
3
|
+
const colors = require('colors/safe');
|
|
4
|
+
|
|
5
|
+
const constants = require('../../helpers/constants.js');
|
|
6
|
+
const SettingsManager = require('../../helpers/settings_manager.js');
|
|
7
|
+
const DrawTable = require('../../helpers/draw_table.js');
|
|
8
|
+
|
|
9
|
+
class DomainsListCommand extends Command {
|
|
10
|
+
|
|
11
|
+
constructor() {
|
|
12
|
+
super('domains', 'list');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
help () {
|
|
16
|
+
return {
|
|
17
|
+
description: 'List all custom domains',
|
|
18
|
+
args: [],
|
|
19
|
+
flags: {},
|
|
20
|
+
vflags: {}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async run (params) {
|
|
25
|
+
|
|
26
|
+
const settings = SettingsManager.read(true);
|
|
27
|
+
const host = settings.activeProfile.host || constants.BASE_URL;
|
|
28
|
+
|
|
29
|
+
const result = await io.get(
|
|
30
|
+
`${host}/v1/custom_domains`,
|
|
31
|
+
settings.activeProfile.key,
|
|
32
|
+
null,
|
|
33
|
+
{invalidated: false},
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
if (result.statusCode !== 200) {
|
|
37
|
+
const message = result.data?.error?.message || `Invalid statusCode: ${result.statusCode}`;
|
|
38
|
+
throw new Error(message);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const customDomains = result.data.data;
|
|
42
|
+
|
|
43
|
+
const columns = [
|
|
44
|
+
'hostname',
|
|
45
|
+
'package',
|
|
46
|
+
'environment',
|
|
47
|
+
'verified_at'
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
const rows = customDomains.map(customDomain => {
|
|
51
|
+
const packageName = `${customDomain.package.is_private ? `private/` : ``}@${customDomain.package.organization.name}/${customDomain.package.name}`;
|
|
52
|
+
const environment = customDomain.environment;
|
|
53
|
+
return {
|
|
54
|
+
hostname: customDomain.hostname,
|
|
55
|
+
package: packageName,
|
|
56
|
+
environment: environment,
|
|
57
|
+
verified_at: customDomain.verified_at
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
console.log();
|
|
62
|
+
DrawTable.render(columns, rows);
|
|
63
|
+
console.log();
|
|
64
|
+
|
|
65
|
+
return void 0;
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = DomainsListCommand;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const { Command } = require('cmnd');
|
|
2
|
+
const io = require('io');
|
|
3
|
+
const colors = require('colors/safe');
|
|
4
|
+
const inquirer = require('inquirer');
|
|
5
|
+
|
|
6
|
+
const constants = require('../../helpers/constants.js');
|
|
7
|
+
const SettingsManager = require('../../helpers/settings_manager.js');
|
|
8
|
+
const DrawTable = require('../../helpers/draw_table.js');
|
|
9
|
+
|
|
10
|
+
class DomainsRemoveCommand extends Command {
|
|
11
|
+
|
|
12
|
+
constructor() {
|
|
13
|
+
super('domains', 'remove');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
help () {
|
|
17
|
+
return {
|
|
18
|
+
description: 'Remove domains from your packages',
|
|
19
|
+
args: [],
|
|
20
|
+
flags: {},
|
|
21
|
+
vflags: {}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async run (params) {
|
|
26
|
+
|
|
27
|
+
const settings = SettingsManager.read(true);
|
|
28
|
+
const host = settings.activeProfile.host || constants.BASE_URL;
|
|
29
|
+
|
|
30
|
+
const result = await io.get(
|
|
31
|
+
`${host}/v1/custom_domains`,
|
|
32
|
+
settings.activeProfile.key,
|
|
33
|
+
null,
|
|
34
|
+
{invalidated: false}
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
if (result.statusCode !== 200) {
|
|
38
|
+
const message = result.data?.error?.message || `Invalid statusCode: ${result.statusCode}`;
|
|
39
|
+
throw new Error(message);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const customDomains = result.data.data;
|
|
43
|
+
|
|
44
|
+
const columns = [
|
|
45
|
+
'hostname',
|
|
46
|
+
'package',
|
|
47
|
+
'environment',
|
|
48
|
+
'verified_at'
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const rows = customDomains.map(customDomain => {
|
|
52
|
+
const packageName = `@${customDomain.package.organization.name}/${customDomain.package.name}`;
|
|
53
|
+
const environment = customDomain.environment;
|
|
54
|
+
return {
|
|
55
|
+
hostname: customDomain.hostname,
|
|
56
|
+
package: packageName,
|
|
57
|
+
environment: environment,
|
|
58
|
+
verified_at: customDomain.verified_at
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
console.log();
|
|
63
|
+
const index = await DrawTable.selectIndexFromTable('Choose a domain to remove', columns, rows);
|
|
64
|
+
|
|
65
|
+
if (index === -1) {
|
|
66
|
+
console.log();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const removeParams = {};
|
|
71
|
+
removeParams.hostname = rows[index].hostname;
|
|
72
|
+
removeParams.name = rows[index].package;
|
|
73
|
+
removeParams.environment = rows[index].environment;
|
|
74
|
+
|
|
75
|
+
const removeResult = await io.del(
|
|
76
|
+
`${host}/v1/custom_domains`,
|
|
77
|
+
settings.activeProfile.key,
|
|
78
|
+
null,
|
|
79
|
+
removeParams
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
if (removeResult.statusCode !== 200) {
|
|
83
|
+
const message = removeResult.data?.error?.message || `Invalid statusCode: ${removeResult.statusCode}`;
|
|
84
|
+
throw new Error(message);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.log();
|
|
88
|
+
console.log(`${colors.bold.green('Success!')} Domain ${colors.bold(removeParams.hostname)} removed.`);
|
|
89
|
+
console.log();
|
|
90
|
+
|
|
91
|
+
return void 0;
|
|
92
|
+
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = DomainsRemoveCommand;
|