neonctl 1.3.0 → 1.4.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/README.md +126 -0
- package/commands/auth.js +4 -0
- package/commands/branches.js +40 -41
- package/commands/branches.test.js +85 -0
- package/commands/databases.js +54 -0
- package/commands/databases.test.js +52 -0
- package/commands/endpoints.js +86 -0
- package/commands/endpoints.test.js +85 -0
- package/commands/index.js +3 -1
- package/commands/projects.js +26 -18
- package/commands/projects.test.js +46 -0
- package/commands/users.js +3 -2
- package/config.js +2 -1
- package/env.js +3 -0
- package/index.js +12 -1
- package/package.json +10 -3
- package/parameters.gen.js +123 -0
- package/test_utils.js +75 -0
- package/utils.js +9 -0
- package/writer.js +59 -50
- package/writer.test.js +86 -0
package/README.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
Neon offers several methods for working with your projects. Utilizing the Neon Command Line Interface (CLI), you can operate Neon directly from a terminal or via automation. The Neon CLI facilitates numerous functions, such as Neon authentication, project creation and management, and more.
|
|
2
|
+
|
|
3
|
+
## Synopsis
|
|
4
|
+
|
|
5
|
+
The `neonctl` command can be called from command line. Without any arguments, it displays command usage and help:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
usage: neonctl <cmd> [args]
|
|
9
|
+
|
|
10
|
+
Commands:
|
|
11
|
+
neonctl auth Authenticate
|
|
12
|
+
neonctl projects [command] Manage projects
|
|
13
|
+
neonctl me Show current user
|
|
14
|
+
neonctl branches Manage branches
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
--version Show version number [boolean]
|
|
18
|
+
--help Show help [boolean]
|
|
19
|
+
-o, --output Set output format
|
|
20
|
+
[string] [choices: "json", "yaml", "table"] [default: "table"]
|
|
21
|
+
--api-host The API host [default: "https://console.neon.tech/api/v2"]
|
|
22
|
+
--config-dir Path to config directory
|
|
23
|
+
[string] [default: "/home/eduard/.config/neonctl"]
|
|
24
|
+
--oauth-host URL to Neon OAUTH host [default: "https://oauth2.neon.tech"]
|
|
25
|
+
--client-id OAuth client id [string] [default: "neonctl"]
|
|
26
|
+
--api-key API key [string] [default: ""]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Install the Neon CLI
|
|
30
|
+
|
|
31
|
+
This topic describes how to install the `neonctl` command-line interface tool and connect to Neon.
|
|
32
|
+
|
|
33
|
+
### Prerequisites
|
|
34
|
+
|
|
35
|
+
- Node.js 16.0 or higher. To check if you already have Node.js, run the following command:
|
|
36
|
+
|
|
37
|
+
```shell
|
|
38
|
+
node -v
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- The `npm` package manager. To check if you already have `npm`, run the following command:
|
|
42
|
+
|
|
43
|
+
```shell
|
|
44
|
+
npm -v
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
If you need to install either `Node.js` or `npm`, refer to instructions on [official nodejs page](https://nodejs.org) or you can use [Node version manager](https://github.com/nvm-sh/nvm).
|
|
48
|
+
|
|
49
|
+
### Install
|
|
50
|
+
|
|
51
|
+
To download and install Neon CLI, run the following command:
|
|
52
|
+
|
|
53
|
+
```shell
|
|
54
|
+
npm i -g neonctl
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Connect
|
|
58
|
+
|
|
59
|
+
To authenticate to Neon, run the following command:
|
|
60
|
+
|
|
61
|
+
```shell
|
|
62
|
+
neonctl auth
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The command launches a browser window where you can authorize the Neon CLI to access your Neon account. After granting permission, your credentials are saved locally to a credentials file.
|
|
66
|
+
|
|
67
|
+
## Commands
|
|
68
|
+
|
|
69
|
+
### neonctl auth
|
|
70
|
+
|
|
71
|
+
Authenticates the user or caller to Neon. See [Connect](#connect).
|
|
72
|
+
|
|
73
|
+
### neonctl me
|
|
74
|
+
|
|
75
|
+
Returns information about the authenticated user.
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
$> neonctl me
|
|
79
|
+
┌────────────────┬──────────────────────────┬────────────┬────────────────┐
|
|
80
|
+
│ Login │ Email │ Name │ Projects Limit │
|
|
81
|
+
├────────────────┼──────────────────────────┼────────────┼────────────────┤
|
|
82
|
+
│ user1 │ user1@example.com │ User1 │ 1 │
|
|
83
|
+
└────────────────┴──────────────────────────┴────────────┴────────────────┘
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
### neonctl projects
|
|
88
|
+
|
|
89
|
+
For creating and managing Neon projects.
|
|
90
|
+
|
|
91
|
+
## neonctl branches
|
|
92
|
+
For creating and managing Neon branches.
|
|
93
|
+
|
|
94
|
+
## Options
|
|
95
|
+
|
|
96
|
+
### version
|
|
97
|
+
|
|
98
|
+
Shows the neonctl version number
|
|
99
|
+
|
|
100
|
+
### help
|
|
101
|
+
|
|
102
|
+
Shows the neonctl command-line help
|
|
103
|
+
|
|
104
|
+
### output, o
|
|
105
|
+
|
|
106
|
+
Sets the output format.
|
|
107
|
+
|
|
108
|
+
### api-host
|
|
109
|
+
|
|
110
|
+
Shows the API host
|
|
111
|
+
|
|
112
|
+
### config-dir
|
|
113
|
+
|
|
114
|
+
Sets the path to the `neonctl` configuration directory
|
|
115
|
+
|
|
116
|
+
### oauth-host
|
|
117
|
+
|
|
118
|
+
Sets the URL of Neon OAuth host
|
|
119
|
+
|
|
120
|
+
### client-id
|
|
121
|
+
|
|
122
|
+
Sets the OAuth client id
|
|
123
|
+
|
|
124
|
+
### api-key
|
|
125
|
+
|
|
126
|
+
Sets the API key
|
package/commands/auth.js
CHANGED
|
@@ -4,6 +4,7 @@ import { TokenSet } from 'openid-client';
|
|
|
4
4
|
import { auth, refreshToken } from '../auth.js';
|
|
5
5
|
import { log } from '../log.js';
|
|
6
6
|
import { getApiClient } from '../api.js';
|
|
7
|
+
import { isCi } from '../env.js';
|
|
7
8
|
const CREDENTIALS_FILE = 'credentials.json';
|
|
8
9
|
export const command = 'auth';
|
|
9
10
|
export const describe = 'Authenticate';
|
|
@@ -12,6 +13,9 @@ export const handler = async (args) => {
|
|
|
12
13
|
await authFlow(args);
|
|
13
14
|
};
|
|
14
15
|
export const authFlow = async ({ configDir, oauthHost, clientId, }) => {
|
|
16
|
+
if (isCi()) {
|
|
17
|
+
throw new Error('Cannot run interactive auth in CI');
|
|
18
|
+
}
|
|
15
19
|
if (!clientId) {
|
|
16
20
|
throw new Error('Missing client id');
|
|
17
21
|
}
|
package/commands/branches.js
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { hideBin } from 'yargs/helpers';
|
|
3
|
-
import { writeOut } from '../writer.js';
|
|
1
|
+
import { writer } from '../writer.js';
|
|
4
2
|
import { branchCreateRequest, branchCreateRequestEndpointOptions, branchUpdateRequest, } from '../parameters.gen.js';
|
|
3
|
+
import { commandFailHandler } from '../utils.js';
|
|
4
|
+
const BRANCH_FIELDS = ['id', 'name', 'created_at'];
|
|
5
5
|
export const command = 'branches';
|
|
6
6
|
export const describe = 'Manage branches';
|
|
7
7
|
export const builder = (argv) => argv
|
|
8
8
|
.demandCommand(1, '')
|
|
9
|
-
.fail(
|
|
10
|
-
const y = yargs(hideBin(process.argv));
|
|
11
|
-
if (y.argv._.length === 1) {
|
|
12
|
-
argv.showHelp();
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
|
-
})
|
|
9
|
+
.fail(commandFailHandler)
|
|
16
10
|
.usage('usage: $0 branches <cmd> [args]')
|
|
17
11
|
.options({
|
|
18
12
|
'project.id': {
|
|
@@ -24,7 +18,7 @@ export const builder = (argv) => argv
|
|
|
24
18
|
.command('list', 'List branches', (yargs) => yargs, async (args) => await list(args))
|
|
25
19
|
.command('create', 'Create a branch', (yargs) => yargs.options({
|
|
26
20
|
...branchCreateRequest,
|
|
27
|
-
...Object.fromEntries(Object.entries(branchCreateRequestEndpointOptions).map(([key, value]) => [`endpoint.${key}`, value])),
|
|
21
|
+
...Object.fromEntries(Object.entries(branchCreateRequestEndpointOptions).map(([key, value]) => [`endpoint.${key}`, { ...value, demandOption: false }])),
|
|
28
22
|
}), async (args) => await create(args))
|
|
29
23
|
.command('update', 'Update a branch', (yargs) => yargs.options(branchUpdateRequest).option('branch.id', {
|
|
30
24
|
describe: 'Branch ID',
|
|
@@ -35,14 +29,19 @@ export const builder = (argv) => argv
|
|
|
35
29
|
describe: 'Branch ID',
|
|
36
30
|
type: 'string',
|
|
37
31
|
demandOption: true,
|
|
38
|
-
}), async (args) => await deleteBranch(args))
|
|
32
|
+
}), async (args) => await deleteBranch(args))
|
|
33
|
+
.command('get', 'Get a branch', (yargs) => yargs.option('branch.id', {
|
|
34
|
+
describe: 'Branch ID',
|
|
35
|
+
type: 'string',
|
|
36
|
+
demandOption: true,
|
|
37
|
+
}), async (args) => await get(args));
|
|
39
38
|
export const handler = (args) => {
|
|
40
39
|
return args;
|
|
41
40
|
};
|
|
42
41
|
const list = async (props) => {
|
|
43
42
|
const { data } = await props.apiClient.listProjectBranches(props.project.id);
|
|
44
|
-
|
|
45
|
-
fields:
|
|
43
|
+
writer(props).end(data.branches, {
|
|
44
|
+
fields: BRANCH_FIELDS,
|
|
46
45
|
});
|
|
47
46
|
};
|
|
48
47
|
const create = async (props) => {
|
|
@@ -50,42 +49,42 @@ const create = async (props) => {
|
|
|
50
49
|
branch: props.branch,
|
|
51
50
|
endpoints: props.endpoint ? [props.endpoint] : undefined,
|
|
52
51
|
});
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
},
|
|
58
|
-
...(data.endpoints?.length > 0
|
|
59
|
-
? {
|
|
60
|
-
endpoints: {
|
|
61
|
-
data: data.endpoints,
|
|
62
|
-
config: { fields: ['id', 'created_at'] },
|
|
63
|
-
},
|
|
64
|
-
}
|
|
65
|
-
: {}),
|
|
66
|
-
...(data.connection_uris
|
|
67
|
-
? {
|
|
68
|
-
connection_uri: {
|
|
69
|
-
data: data.connection_uris[0],
|
|
70
|
-
config: {
|
|
71
|
-
fields: ['connection_uri'],
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
}
|
|
75
|
-
: {}),
|
|
52
|
+
const out = writer(props);
|
|
53
|
+
out.write(data.branch, {
|
|
54
|
+
fields: BRANCH_FIELDS,
|
|
55
|
+
title: 'branch',
|
|
76
56
|
});
|
|
57
|
+
if (data.endpoints?.length > 0) {
|
|
58
|
+
out.write(data.endpoints, {
|
|
59
|
+
fields: ['id', 'created_at'],
|
|
60
|
+
title: 'endpoints',
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
if (data.connection_uris && data.connection_uris?.length > 0) {
|
|
64
|
+
out.write(data.connection_uris, {
|
|
65
|
+
fields: ['connection_uri'],
|
|
66
|
+
title: 'connection_uris',
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
out.end();
|
|
77
70
|
};
|
|
78
71
|
const update = async (props) => {
|
|
79
72
|
const { data } = await props.apiClient.updateProjectBranch(props.project.id, props.branch.id, {
|
|
80
73
|
branch: props.branch,
|
|
81
74
|
});
|
|
82
|
-
|
|
83
|
-
fields:
|
|
75
|
+
writer(props).end(data.branch, {
|
|
76
|
+
fields: BRANCH_FIELDS,
|
|
84
77
|
});
|
|
85
78
|
};
|
|
86
79
|
const deleteBranch = async (props) => {
|
|
87
80
|
const { data } = await props.apiClient.deleteProjectBranch(props.project.id, props.branch.id);
|
|
88
|
-
|
|
89
|
-
fields:
|
|
81
|
+
writer(props).end(data.branch, {
|
|
82
|
+
fields: BRANCH_FIELDS,
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
const get = async (props) => {
|
|
86
|
+
const { data } = await props.apiClient.getProjectBranch(props.project.id, props.branch.id);
|
|
87
|
+
writer(props).end(data.branch, {
|
|
88
|
+
fields: BRANCH_FIELDS,
|
|
90
89
|
});
|
|
91
90
|
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { describe } from '@jest/globals';
|
|
2
|
+
import { testCliCommand } from '../test_utils.js';
|
|
3
|
+
describe('branches', () => {
|
|
4
|
+
testCliCommand({
|
|
5
|
+
name: 'list',
|
|
6
|
+
args: ['branches', 'list', '--project.id', 'test'],
|
|
7
|
+
expected: {
|
|
8
|
+
snapshot: true,
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
testCliCommand({
|
|
12
|
+
name: 'create with endpoint',
|
|
13
|
+
args: [
|
|
14
|
+
'branches',
|
|
15
|
+
'create',
|
|
16
|
+
'--project.id',
|
|
17
|
+
'test',
|
|
18
|
+
'--branch.name',
|
|
19
|
+
'test_branch',
|
|
20
|
+
'--endpoint.type',
|
|
21
|
+
'read_only',
|
|
22
|
+
],
|
|
23
|
+
expected: {
|
|
24
|
+
snapshot: true,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
testCliCommand({
|
|
28
|
+
name: 'create without endpoint',
|
|
29
|
+
args: [
|
|
30
|
+
'branches',
|
|
31
|
+
'create',
|
|
32
|
+
'--project.id',
|
|
33
|
+
'test',
|
|
34
|
+
'--branch.name',
|
|
35
|
+
'test_branch',
|
|
36
|
+
],
|
|
37
|
+
expected: {
|
|
38
|
+
snapshot: true,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
testCliCommand({
|
|
42
|
+
name: 'delete',
|
|
43
|
+
args: [
|
|
44
|
+
'branches',
|
|
45
|
+
'delete',
|
|
46
|
+
'--project.id',
|
|
47
|
+
'test',
|
|
48
|
+
'--branch.id',
|
|
49
|
+
'test_branch_id',
|
|
50
|
+
],
|
|
51
|
+
expected: {
|
|
52
|
+
snapshot: true,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
testCliCommand({
|
|
56
|
+
name: 'update',
|
|
57
|
+
args: [
|
|
58
|
+
'branches',
|
|
59
|
+
'update',
|
|
60
|
+
'--project.id',
|
|
61
|
+
'test',
|
|
62
|
+
'--branch.id',
|
|
63
|
+
'test_branch_id',
|
|
64
|
+
'--branch.name',
|
|
65
|
+
'new_test_branch',
|
|
66
|
+
],
|
|
67
|
+
expected: {
|
|
68
|
+
snapshot: true,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
testCliCommand({
|
|
72
|
+
name: 'get',
|
|
73
|
+
args: [
|
|
74
|
+
'branches',
|
|
75
|
+
'get',
|
|
76
|
+
'--project.id',
|
|
77
|
+
'test',
|
|
78
|
+
'--branch.id',
|
|
79
|
+
'test_branch_id',
|
|
80
|
+
],
|
|
81
|
+
expected: {
|
|
82
|
+
snapshot: true,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { databaseCreateRequest } from '../parameters.gen.js';
|
|
2
|
+
import { commandFailHandler } from '../utils.js';
|
|
3
|
+
import { writer } from '../writer.js';
|
|
4
|
+
const DATABASE_FIELDS = ['name', 'owner_name'];
|
|
5
|
+
export const command = 'databases';
|
|
6
|
+
export const describe = 'Manage databases';
|
|
7
|
+
export const builder = (argv) => argv
|
|
8
|
+
.demandCommand(1, '')
|
|
9
|
+
.fail(commandFailHandler)
|
|
10
|
+
.usage('usage: $0 databases <cmd> [args]')
|
|
11
|
+
.options({
|
|
12
|
+
'project.id': {
|
|
13
|
+
describe: 'Project ID',
|
|
14
|
+
type: 'string',
|
|
15
|
+
demandOption: true,
|
|
16
|
+
},
|
|
17
|
+
'branch.id': {
|
|
18
|
+
describe: 'Branch ID',
|
|
19
|
+
type: 'string',
|
|
20
|
+
demandOption: true,
|
|
21
|
+
},
|
|
22
|
+
})
|
|
23
|
+
.command('list', 'List databases', (yargs) => yargs, async (args) => await list(args))
|
|
24
|
+
.command('create', 'Create a database', (yargs) => yargs.options(databaseCreateRequest), async (args) => await create(args))
|
|
25
|
+
.command('delete', 'Delete a database', (yargs) => yargs.options({
|
|
26
|
+
'database.name': {
|
|
27
|
+
describe: 'Database name',
|
|
28
|
+
type: 'string',
|
|
29
|
+
demandOption: true,
|
|
30
|
+
},
|
|
31
|
+
}), async (args) => await deleteDb(args));
|
|
32
|
+
export const handler = (args) => {
|
|
33
|
+
return args;
|
|
34
|
+
};
|
|
35
|
+
export const list = async (props) => {
|
|
36
|
+
const { data } = await props.apiClient.listProjectBranchDatabases(props.project.id, props.branch.id);
|
|
37
|
+
writer(props).end(data.databases, {
|
|
38
|
+
fields: DATABASE_FIELDS,
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
export const create = async (props) => {
|
|
42
|
+
const { data } = await props.apiClient.createProjectBranchDatabase(props.project.id, props.branch.id, {
|
|
43
|
+
database: props.database,
|
|
44
|
+
});
|
|
45
|
+
writer(props).end(data.database, {
|
|
46
|
+
fields: DATABASE_FIELDS,
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
export const deleteDb = async (props) => {
|
|
50
|
+
const { data } = await props.apiClient.deleteProjectBranchDatabase(props.project.id, props.branch.id, props.database.name);
|
|
51
|
+
writer(props).end(data.database, {
|
|
52
|
+
fields: DATABASE_FIELDS,
|
|
53
|
+
});
|
|
54
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { describe } from '@jest/globals';
|
|
2
|
+
import { testCliCommand } from '../test_utils.js';
|
|
3
|
+
describe('databases', () => {
|
|
4
|
+
testCliCommand({
|
|
5
|
+
name: 'list',
|
|
6
|
+
args: [
|
|
7
|
+
'databases',
|
|
8
|
+
'list',
|
|
9
|
+
'--project.id',
|
|
10
|
+
'test',
|
|
11
|
+
'--branch.id',
|
|
12
|
+
'test_branch_id',
|
|
13
|
+
],
|
|
14
|
+
expected: {
|
|
15
|
+
snapshot: true,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
testCliCommand({
|
|
19
|
+
name: 'create',
|
|
20
|
+
args: [
|
|
21
|
+
'databases',
|
|
22
|
+
'create',
|
|
23
|
+
'--project.id',
|
|
24
|
+
'test',
|
|
25
|
+
'--branch.id',
|
|
26
|
+
'test_branch_id',
|
|
27
|
+
'--database.name',
|
|
28
|
+
'test_db',
|
|
29
|
+
'--database.owner_name',
|
|
30
|
+
'test_owner',
|
|
31
|
+
],
|
|
32
|
+
expected: {
|
|
33
|
+
snapshot: true,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
testCliCommand({
|
|
37
|
+
name: 'delete',
|
|
38
|
+
args: [
|
|
39
|
+
'databases',
|
|
40
|
+
'delete',
|
|
41
|
+
'--project.id',
|
|
42
|
+
'test',
|
|
43
|
+
'--branch.id',
|
|
44
|
+
'test_branch_id',
|
|
45
|
+
'--database.name',
|
|
46
|
+
'test_db',
|
|
47
|
+
],
|
|
48
|
+
expected: {
|
|
49
|
+
snapshot: true,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { endpointCreateRequest, endpointUpdateRequest, } from '../parameters.gen.js';
|
|
2
|
+
import { commandFailHandler } from '../utils.js';
|
|
3
|
+
import { writer } from '../writer.js';
|
|
4
|
+
const ENDPOINT_FIELDS = [
|
|
5
|
+
'id',
|
|
6
|
+
'created_at',
|
|
7
|
+
'branch_id',
|
|
8
|
+
'type',
|
|
9
|
+
'current_state',
|
|
10
|
+
];
|
|
11
|
+
export const command = 'endpoints';
|
|
12
|
+
export const describe = 'Manage endpoints';
|
|
13
|
+
export const builder = (argv) => argv
|
|
14
|
+
.demandCommand(1, '')
|
|
15
|
+
.fail(commandFailHandler)
|
|
16
|
+
.usage('usage: $0 endpoints <cmd> [args]')
|
|
17
|
+
.options({
|
|
18
|
+
'project.id': {
|
|
19
|
+
describe: 'Project ID',
|
|
20
|
+
type: 'string',
|
|
21
|
+
demandOption: true,
|
|
22
|
+
},
|
|
23
|
+
})
|
|
24
|
+
.command('list', 'List endpoints', (yargs) => yargs.options({
|
|
25
|
+
'branch.id': {
|
|
26
|
+
describe: 'Branch ID',
|
|
27
|
+
type: 'string',
|
|
28
|
+
demandOption: false,
|
|
29
|
+
},
|
|
30
|
+
}), async (args) => await list(args))
|
|
31
|
+
.command('create', 'Create an endpoint', (yargs) => yargs.options(endpointCreateRequest), async (args) => await create(args))
|
|
32
|
+
.command('update', 'Update an endpoint', (yargs) => yargs.options({
|
|
33
|
+
'endpoint.id': {
|
|
34
|
+
describe: 'Endpoint ID',
|
|
35
|
+
type: 'string',
|
|
36
|
+
demandOption: true,
|
|
37
|
+
},
|
|
38
|
+
...endpointUpdateRequest,
|
|
39
|
+
}), async (args) => await update(args))
|
|
40
|
+
.command('delete', 'Delete an endpoint', (yargs) => yargs.options({
|
|
41
|
+
'endpoint.id': {
|
|
42
|
+
describe: 'Endpoint ID',
|
|
43
|
+
type: 'string',
|
|
44
|
+
demandOption: true,
|
|
45
|
+
},
|
|
46
|
+
}), async (args) => await deleteEndpoint(args))
|
|
47
|
+
.command('get', 'Get an endpoint', (yargs) => yargs.options({
|
|
48
|
+
'endpoint.id': {
|
|
49
|
+
describe: 'Endpoint ID',
|
|
50
|
+
type: 'string',
|
|
51
|
+
demandOption: true,
|
|
52
|
+
},
|
|
53
|
+
}), async (args) => await getEndpoint(args));
|
|
54
|
+
export const handler = async (args) => args;
|
|
55
|
+
const list = async (props) => {
|
|
56
|
+
const { data } = props.branch?.id
|
|
57
|
+
? await props.apiClient.listProjectBranchEndpoints(props.project.id, props.branch.id)
|
|
58
|
+
: await props.apiClient.listProjectEndpoints(props.project.id);
|
|
59
|
+
writer(props).end(data.endpoints, {
|
|
60
|
+
fields: ENDPOINT_FIELDS,
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
const create = async (props) => {
|
|
64
|
+
const { data } = await props.apiClient.createProjectEndpoint(props.project.id, { endpoint: props.endpoint });
|
|
65
|
+
writer(props).end(data.endpoint, {
|
|
66
|
+
fields: ENDPOINT_FIELDS,
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
const update = async (props) => {
|
|
70
|
+
const { data } = await props.apiClient.updateProjectEndpoint(props.project.id, props.endpoint.id, { endpoint: props.endpoint });
|
|
71
|
+
writer(props).end(data.endpoint, {
|
|
72
|
+
fields: ENDPOINT_FIELDS,
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
const deleteEndpoint = async (props) => {
|
|
76
|
+
const { data } = await props.apiClient.deleteProjectEndpoint(props.project.id, props.endpoint.id);
|
|
77
|
+
writer(props).end(data.endpoint, {
|
|
78
|
+
fields: ENDPOINT_FIELDS,
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
const getEndpoint = async (props) => {
|
|
82
|
+
const { data } = await props.apiClient.getProjectEndpoint(props.project.id, props.endpoint.id);
|
|
83
|
+
writer(props).end(data.endpoint, {
|
|
84
|
+
fields: ENDPOINT_FIELDS,
|
|
85
|
+
});
|
|
86
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { describe } from '@jest/globals';
|
|
2
|
+
import { testCliCommand } from '../test_utils.js';
|
|
3
|
+
describe('endpoints', () => {
|
|
4
|
+
testCliCommand({
|
|
5
|
+
name: 'list',
|
|
6
|
+
args: ['endpoints', 'list', '--project.id', 'test'],
|
|
7
|
+
expected: {
|
|
8
|
+
snapshot: true,
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
testCliCommand({
|
|
12
|
+
name: 'list with branch filter',
|
|
13
|
+
args: [
|
|
14
|
+
'endpoints',
|
|
15
|
+
'list',
|
|
16
|
+
'--project.id',
|
|
17
|
+
'test',
|
|
18
|
+
'--branch.id',
|
|
19
|
+
'test_branch_id',
|
|
20
|
+
],
|
|
21
|
+
expected: {
|
|
22
|
+
snapshot: true,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
testCliCommand({
|
|
26
|
+
name: 'create',
|
|
27
|
+
args: [
|
|
28
|
+
'endpoints',
|
|
29
|
+
'create',
|
|
30
|
+
'--project.id',
|
|
31
|
+
'test',
|
|
32
|
+
'--endpoint.branch_id',
|
|
33
|
+
'test_branch_id',
|
|
34
|
+
'--endpoint.type',
|
|
35
|
+
'read_only',
|
|
36
|
+
],
|
|
37
|
+
expected: {
|
|
38
|
+
snapshot: true,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
testCliCommand({
|
|
42
|
+
name: 'delete',
|
|
43
|
+
args: [
|
|
44
|
+
'endpoints',
|
|
45
|
+
'delete',
|
|
46
|
+
'--project.id',
|
|
47
|
+
'test',
|
|
48
|
+
'--endpoint.id',
|
|
49
|
+
'test_endpoint_id',
|
|
50
|
+
],
|
|
51
|
+
expected: {
|
|
52
|
+
snapshot: true,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
testCliCommand({
|
|
56
|
+
name: 'update',
|
|
57
|
+
args: [
|
|
58
|
+
'endpoints',
|
|
59
|
+
'update',
|
|
60
|
+
'--project.id',
|
|
61
|
+
'test',
|
|
62
|
+
'--endpoint.id',
|
|
63
|
+
'test_endpoint_id',
|
|
64
|
+
'--endpoint.branch_id',
|
|
65
|
+
'test_branch_id',
|
|
66
|
+
],
|
|
67
|
+
expected: {
|
|
68
|
+
snapshot: true,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
testCliCommand({
|
|
72
|
+
name: 'get',
|
|
73
|
+
args: [
|
|
74
|
+
'endpoints',
|
|
75
|
+
'get',
|
|
76
|
+
'--project.id',
|
|
77
|
+
'test',
|
|
78
|
+
'--endpoint.id',
|
|
79
|
+
'test_endpoint_id',
|
|
80
|
+
],
|
|
81
|
+
expected: {
|
|
82
|
+
snapshot: true,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
});
|
package/commands/index.js
CHANGED
|
@@ -2,4 +2,6 @@ import * as auth from './auth.js';
|
|
|
2
2
|
import * as projects from './projects.js';
|
|
3
3
|
import * as users from './users.js';
|
|
4
4
|
import * as branches from './branches.js';
|
|
5
|
-
|
|
5
|
+
import * as endpoints from './endpoints.js';
|
|
6
|
+
import * as databases from './databases.js';
|
|
7
|
+
export default [auth, projects, users, branches, endpoints, databases];
|