@bctrl/cli 0.1.4 → 0.1.6
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/dist/commands/ai/index.js +29 -21
- package/dist/commands/api-key/index.js +10 -10
- package/dist/commands/browser-extension/index.js +18 -19
- package/dist/commands/file/index.js +17 -18
- package/dist/commands/help/index.js +3 -3
- package/dist/commands/proxy/index.js +26 -20
- package/dist/commands/run/index.js +44 -27
- package/dist/commands/runtime/index.js +159 -130
- package/dist/commands/shared/help.d.ts +1 -0
- package/dist/commands/shared/help.js +9 -5
- package/dist/commands/shared/operation.d.ts +83 -0
- package/dist/commands/shared/{rest.js → operation.js} +87 -46
- package/dist/commands/space/index.js +61 -52
- package/dist/commands/space/list.js +14 -13
- package/dist/commands/subaccount/index.js +35 -53
- package/dist/commands/tool/index.js +18 -20
- package/dist/commands/tool-call/index.js +5 -5
- package/dist/commands/toolset/index.js +11 -13
- package/dist/commands/usage/index.js +3 -3
- package/dist/commands/vault/index.js +23 -21
- package/dist/generated/help.d.ts +5990 -128
- package/dist/generated/help.js +7905 -221
- package/dist/generated/openapi-routes.d.ts +391 -0
- package/dist/generated/openapi-routes.js +100 -0
- package/dist/generated/openapi-types.d.ts +13830 -0
- package/dist/generated/openapi-types.js +5 -0
- package/dist/openapi.d.ts +20 -0
- package/dist/openapi.js +1 -0
- package/package.json +1 -1
- package/dist/commands/shared/rest.d.ts +0 -55
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { readJsonFile } from '../shared/io.js';
|
|
3
3
|
import { addOutputFlags } from '../shared/output.js';
|
|
4
|
-
import {
|
|
4
|
+
import { createOperationDeleteCommand, createOperationJsonBodyCommand, createOperationListCommand, createOperationViewCommand, outputFlags, requestOperationAndPrint, } from '../shared/operation.js';
|
|
5
5
|
export function createAiCommand(factory) {
|
|
6
6
|
const command = new Command('ai').description('Manage AI models and credentials');
|
|
7
7
|
command.addCommand(createAiModelsCommand(factory));
|
|
@@ -10,9 +10,9 @@ export function createAiCommand(factory) {
|
|
|
10
10
|
}
|
|
11
11
|
function createAiModelsCommand(factory) {
|
|
12
12
|
const command = new Command('models').description('Discover AI models');
|
|
13
|
-
command.addCommand(
|
|
13
|
+
command.addCommand(createOperationListCommand(factory, {
|
|
14
|
+
operationId: 'ai.models.list',
|
|
14
15
|
description: 'List AI models',
|
|
15
|
-
path: '/ai/models',
|
|
16
16
|
configure: (cmd) => cmd
|
|
17
17
|
.option('--provider <provider>', 'Filter by provider')
|
|
18
18
|
.option('--status <status>', 'Filter by support status')
|
|
@@ -21,7 +21,7 @@ function createAiModelsCommand(factory) {
|
|
|
21
21
|
query: (options) => ({
|
|
22
22
|
provider: typeof options.provider === 'string' ? options.provider : undefined,
|
|
23
23
|
status: typeof options.status === 'string' ? options.status : undefined,
|
|
24
|
-
managed: typeof options.managed === 'string' ? options.managed : undefined,
|
|
24
|
+
managed: typeof options.managed === 'string' ? parseBooleanFlag(options.managed) : undefined,
|
|
25
25
|
engine: typeof options.engine === 'string' ? options.engine : undefined,
|
|
26
26
|
}),
|
|
27
27
|
}));
|
|
@@ -29,9 +29,9 @@ function createAiModelsCommand(factory) {
|
|
|
29
29
|
}
|
|
30
30
|
function createAiCredentialsCommand(factory) {
|
|
31
31
|
const command = new Command('credentials').description('Manage BYOK AI credentials');
|
|
32
|
-
command.addCommand(
|
|
32
|
+
command.addCommand(createOperationListCommand(factory, {
|
|
33
|
+
operationId: 'ai.credentials.list',
|
|
33
34
|
description: 'List AI credentials',
|
|
34
|
-
path: '/ai/credentials',
|
|
35
35
|
configure: (cmd) => cmd
|
|
36
36
|
.option('--provider <provider>', 'Filter by provider')
|
|
37
37
|
.option('--name <name>', 'Filter by name')
|
|
@@ -42,32 +42,32 @@ function createAiCredentialsCommand(factory) {
|
|
|
42
42
|
status: typeof options.status === 'string' ? options.status : undefined,
|
|
43
43
|
}),
|
|
44
44
|
}));
|
|
45
|
-
command.addCommand(
|
|
45
|
+
command.addCommand(createOperationViewCommand(factory, {
|
|
46
|
+
operationId: 'ai.credentials.get',
|
|
46
47
|
name: 'get',
|
|
47
48
|
description: 'Get an AI credential',
|
|
48
|
-
path: '/ai/credentials/{credentialId}',
|
|
49
49
|
argName: 'credentialId',
|
|
50
50
|
}));
|
|
51
|
-
command.addCommand(createAiCredentialWriteCommand(factory, 'create', '
|
|
52
|
-
command.addCommand(createAiCredentialWriteCommand(factory, 'patch', '
|
|
53
|
-
'credentialId',
|
|
54
|
-
]));
|
|
51
|
+
command.addCommand(createAiCredentialWriteCommand(factory, 'create', 'ai.credentials.create'));
|
|
52
|
+
command.addCommand(createAiCredentialWriteCommand(factory, 'patch', 'ai.credentials.update', ['credentialId']));
|
|
55
53
|
command.addCommand(addOutputFlags(new Command('test').description('Test an AI credential').argument('<credentialId>')).action(async (credentialId, options) => {
|
|
56
|
-
await
|
|
54
|
+
await requestOperationAndPrint(factory, 'ai.credentials.test', {
|
|
55
|
+
pathParams: { credentialId },
|
|
56
|
+
output: outputFlags(options),
|
|
57
|
+
});
|
|
57
58
|
}));
|
|
58
|
-
command.addCommand(
|
|
59
|
+
command.addCommand(createOperationDeleteCommand(factory, {
|
|
60
|
+
operationId: 'ai.credentials.delete',
|
|
59
61
|
description: 'Delete an AI credential',
|
|
60
|
-
path: '/ai/credentials/{credentialId}',
|
|
61
62
|
argNames: ['credentialId'],
|
|
62
63
|
}));
|
|
63
64
|
return command;
|
|
64
65
|
}
|
|
65
|
-
function createAiCredentialWriteCommand(factory, name,
|
|
66
|
-
return
|
|
66
|
+
function createAiCredentialWriteCommand(factory, name, operationId, argNames = []) {
|
|
67
|
+
return createOperationJsonBodyCommand(factory, {
|
|
68
|
+
operationId,
|
|
67
69
|
name,
|
|
68
70
|
description: name === 'create' ? 'Create an AI credential' : 'Update an AI credential',
|
|
69
|
-
method,
|
|
70
|
-
path,
|
|
71
71
|
argNames,
|
|
72
72
|
configure: (cmd) => cmd
|
|
73
73
|
.option('--name <name>', 'Credential name')
|
|
@@ -79,8 +79,9 @@ function createAiCredentialWriteCommand(factory, name, method, path, argNames =
|
|
|
79
79
|
.option('--subaccount-id <id>', 'Subaccount scope when using a parent/org key')
|
|
80
80
|
.option('--input <path>', 'Read full JSON request body from file, or - for stdin'),
|
|
81
81
|
body: async (_args, options) => {
|
|
82
|
-
if (typeof options.input === 'string')
|
|
83
|
-
return readJsonFile(options.input);
|
|
82
|
+
if (typeof options.input === 'string') {
|
|
83
|
+
return (await readJsonFile(options.input));
|
|
84
|
+
}
|
|
84
85
|
return {
|
|
85
86
|
name: options.name,
|
|
86
87
|
provider: options.provider,
|
|
@@ -93,3 +94,10 @@ function createAiCredentialWriteCommand(factory, name, method, path, argNames =
|
|
|
93
94
|
},
|
|
94
95
|
});
|
|
95
96
|
}
|
|
97
|
+
function parseBooleanFlag(value) {
|
|
98
|
+
if (value === 'true')
|
|
99
|
+
return true;
|
|
100
|
+
if (value === 'false')
|
|
101
|
+
return false;
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { readJsonFile } from '../shared/io.js';
|
|
3
|
-
import {
|
|
3
|
+
import { createOperationDeleteCommand, createOperationJsonBodyCommand, createOperationListCommand, } from '../shared/operation.js';
|
|
4
4
|
export function createApiKeyCommand(factory) {
|
|
5
5
|
const command = new Command('api-key').description('Manage API keys');
|
|
6
|
-
command.addCommand(
|
|
6
|
+
command.addCommand(createOperationListCommand(factory, {
|
|
7
|
+
operationId: 'api-keys.list',
|
|
7
8
|
description: 'List API keys',
|
|
8
|
-
path: '/api-keys',
|
|
9
9
|
configure: (cmd) => cmd
|
|
10
10
|
.option('--subaccount-id <id>', 'Filter by subaccount id')
|
|
11
11
|
.option('--kind <kind>', 'Filter by key kind: organization or subaccount')
|
|
@@ -18,19 +18,19 @@ export function createApiKeyCommand(factory) {
|
|
|
18
18
|
cursor: typeof options.cursor === 'string' ? options.cursor : undefined,
|
|
19
19
|
}),
|
|
20
20
|
}));
|
|
21
|
-
command.addCommand(
|
|
21
|
+
command.addCommand(createOperationJsonBodyCommand(factory, {
|
|
22
|
+
operationId: 'api-keys.create',
|
|
22
23
|
name: 'create',
|
|
23
24
|
description: 'Create an API key',
|
|
24
|
-
method: 'post',
|
|
25
|
-
path: '/api-keys',
|
|
26
25
|
configure: (cmd) => cmd
|
|
27
26
|
.option('--name <name>', 'API key name')
|
|
28
27
|
.option('--subaccount-id <id>', 'Create a subaccount-scoped key')
|
|
29
28
|
.option('--expires-at <iso>', 'Expiration timestamp')
|
|
30
29
|
.option('--input <path>', 'Read full JSON request body from file, or - for stdin'),
|
|
31
30
|
body: async (_args, options) => {
|
|
32
|
-
if (typeof options.input === 'string')
|
|
33
|
-
return readJsonFile(options.input);
|
|
31
|
+
if (typeof options.input === 'string') {
|
|
32
|
+
return (await readJsonFile(options.input));
|
|
33
|
+
}
|
|
34
34
|
return {
|
|
35
35
|
name: options.name,
|
|
36
36
|
subaccountId: options.subaccountId,
|
|
@@ -38,9 +38,9 @@ export function createApiKeyCommand(factory) {
|
|
|
38
38
|
};
|
|
39
39
|
},
|
|
40
40
|
}));
|
|
41
|
-
command.addCommand(
|
|
41
|
+
command.addCommand(createOperationDeleteCommand(factory, {
|
|
42
|
+
operationId: 'api-keys.delete',
|
|
42
43
|
description: 'Delete an API key',
|
|
43
|
-
path: '/api-keys/{keyId}',
|
|
44
44
|
argNames: ['keyId'],
|
|
45
45
|
}));
|
|
46
46
|
return command;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { readBlob, readJsonFile } from '../shared/io.js';
|
|
3
3
|
import { addOutputFlags, outputData } from '../shared/output.js';
|
|
4
|
-
import {
|
|
4
|
+
import { createOperationDeleteCommand, createOperationJsonBodyCommand, createOperationListCommand, createOperationViewCommand, uploadOperationFile, } from '../shared/operation.js';
|
|
5
5
|
export function createBrowserExtensionCommand(factory) {
|
|
6
6
|
const command = new Command('browser-extension').description('Manage browser extensions');
|
|
7
|
-
command.addCommand(
|
|
7
|
+
command.addCommand(createOperationListCommand(factory, {
|
|
8
|
+
operationId: 'browser-extensions.list',
|
|
8
9
|
description: 'List browser extensions',
|
|
9
|
-
path: '/browser-extensions',
|
|
10
10
|
configure: (cmd) => cmd
|
|
11
11
|
.option('--subaccount-id <id>', 'Filter by subaccount id')
|
|
12
12
|
.option('--q <text>', 'Search query')
|
|
@@ -19,10 +19,10 @@ export function createBrowserExtensionCommand(factory) {
|
|
|
19
19
|
source: typeof options.source === 'string' ? options.source : undefined,
|
|
20
20
|
}),
|
|
21
21
|
}));
|
|
22
|
-
command.addCommand(
|
|
22
|
+
command.addCommand(createOperationViewCommand(factory, {
|
|
23
|
+
operationId: 'browser-extensions.get',
|
|
23
24
|
name: 'get',
|
|
24
25
|
description: 'Get a browser extension',
|
|
25
|
-
path: '/browser-extensions/{extensionId}',
|
|
26
26
|
argName: 'extensionId',
|
|
27
27
|
}));
|
|
28
28
|
command.addCommand(addOutputFlags(new Command('upload')
|
|
@@ -30,9 +30,8 @@ export function createBrowserExtensionCommand(factory) {
|
|
|
30
30
|
.argument('<path>')
|
|
31
31
|
.option('--name <name>', 'Display name')
|
|
32
32
|
.option('--subaccount-id <id>', 'Create under a subaccount when using a parent/org key')).action(async (path, options) => {
|
|
33
|
-
const client = await factory.apiClient();
|
|
34
33
|
const file = await readBlob(path);
|
|
35
|
-
const result = await
|
|
34
|
+
const result = await uploadOperationFile(factory, 'browser-extensions.upload', {
|
|
36
35
|
file: file.blob,
|
|
37
36
|
fileName: file.fileName,
|
|
38
37
|
fields: {
|
|
@@ -42,19 +41,19 @@ export function createBrowserExtensionCommand(factory) {
|
|
|
42
41
|
});
|
|
43
42
|
await outputData(factory.io, result, options);
|
|
44
43
|
}));
|
|
45
|
-
command.addCommand(
|
|
44
|
+
command.addCommand(createOperationJsonBodyCommand(factory, {
|
|
45
|
+
operationId: 'browser-extensions.import',
|
|
46
46
|
name: 'import',
|
|
47
47
|
description: 'Import a browser extension from a URL',
|
|
48
|
-
method: 'post',
|
|
49
|
-
path: '/browser-extensions/import',
|
|
50
48
|
configure: (cmd) => cmd
|
|
51
49
|
.option('--url <url>', 'Extension URL')
|
|
52
50
|
.option('--name <name>', 'Display name')
|
|
53
51
|
.option('--subaccount-id <id>', 'Create under a subaccount when using a parent/org key')
|
|
54
52
|
.option('--input <path>', 'Read full JSON request body from file, or - for stdin'),
|
|
55
53
|
body: async (_args, options) => {
|
|
56
|
-
if (typeof options.input === 'string')
|
|
57
|
-
return readJsonFile(options.input);
|
|
54
|
+
if (typeof options.input === 'string') {
|
|
55
|
+
return (await readJsonFile(options.input));
|
|
56
|
+
}
|
|
58
57
|
return {
|
|
59
58
|
url: options.url,
|
|
60
59
|
name: options.name,
|
|
@@ -62,24 +61,24 @@ export function createBrowserExtensionCommand(factory) {
|
|
|
62
61
|
};
|
|
63
62
|
},
|
|
64
63
|
}));
|
|
65
|
-
command.addCommand(
|
|
64
|
+
command.addCommand(createOperationJsonBodyCommand(factory, {
|
|
65
|
+
operationId: 'browser-extensions.update',
|
|
66
66
|
name: 'patch',
|
|
67
67
|
description: 'Update a browser extension',
|
|
68
|
-
method: 'patch',
|
|
69
|
-
path: '/browser-extensions/{extensionId}',
|
|
70
68
|
argNames: ['extensionId'],
|
|
71
69
|
configure: (cmd) => cmd
|
|
72
70
|
.option('--name <name>', 'Display name')
|
|
73
71
|
.option('--input <path>', 'Read full JSON request body from file, or - for stdin'),
|
|
74
72
|
body: async (_args, options) => {
|
|
75
|
-
if (typeof options.input === 'string')
|
|
76
|
-
return readJsonFile(options.input);
|
|
73
|
+
if (typeof options.input === 'string') {
|
|
74
|
+
return (await readJsonFile(options.input));
|
|
75
|
+
}
|
|
77
76
|
return { name: options.name };
|
|
78
77
|
},
|
|
79
78
|
}));
|
|
80
|
-
command.addCommand(
|
|
79
|
+
command.addCommand(createOperationDeleteCommand(factory, {
|
|
80
|
+
operationId: 'browser-extensions.delete',
|
|
81
81
|
description: 'Delete a browser extension',
|
|
82
|
-
path: '/browser-extensions/{extensionId}',
|
|
83
82
|
argNames: ['extensionId'],
|
|
84
83
|
}));
|
|
85
84
|
return command;
|
|
@@ -2,12 +2,12 @@ import { Command } from 'commander';
|
|
|
2
2
|
import { readBlob, readJsonFile, writeBinary } from '../shared/io.js';
|
|
3
3
|
import { parsePositiveInteger } from '../shared/options.js';
|
|
4
4
|
import { addOutputFlags, outputData } from '../shared/output.js';
|
|
5
|
-
import {
|
|
5
|
+
import { createOperationDeleteCommand, createOperationJsonBodyCommand, createOperationListCommand, createOperationViewCommand, downloadOperation, uploadOperationFile, } from '../shared/operation.js';
|
|
6
6
|
export function createFileCommand(factory) {
|
|
7
7
|
const command = new Command('file').description('Upload, download, and manage BCTRL files');
|
|
8
|
-
command.addCommand(
|
|
8
|
+
command.addCommand(createOperationListCommand(factory, {
|
|
9
|
+
operationId: 'files.list',
|
|
9
10
|
description: 'List files',
|
|
10
|
-
path: '/files',
|
|
11
11
|
configure: (cmd) => cmd
|
|
12
12
|
.option('--space <id>', 'Filter by space id')
|
|
13
13
|
.option('--source <source>', 'Filter by file source')
|
|
@@ -29,10 +29,10 @@ export function createFileCommand(factory) {
|
|
|
29
29
|
cursor: typeof options.cursor === 'string' ? options.cursor : undefined,
|
|
30
30
|
}),
|
|
31
31
|
}));
|
|
32
|
-
command.addCommand(
|
|
32
|
+
command.addCommand(createOperationViewCommand(factory, {
|
|
33
|
+
operationId: 'files.get',
|
|
33
34
|
name: 'get',
|
|
34
35
|
description: 'View file metadata',
|
|
35
|
-
path: '/files/{fileId}',
|
|
36
36
|
argName: 'fileId',
|
|
37
37
|
}));
|
|
38
38
|
command.addCommand(addOutputFlags(new Command('upload')
|
|
@@ -40,11 +40,9 @@ export function createFileCommand(factory) {
|
|
|
40
40
|
.argument('<path>')
|
|
41
41
|
.option('--space <id>', 'Space id; omitted uses caller default space')
|
|
42
42
|
.option('--path <storagePath>', 'Storage path')
|
|
43
|
-
.option('--name <name>', 'Display name'))
|
|
44
|
-
.action(async (path, options) => {
|
|
45
|
-
const client = await factory.apiClient();
|
|
43
|
+
.option('--name <name>', 'Display name')).action(async (path, options) => {
|
|
46
44
|
const file = await readBlob(path);
|
|
47
|
-
const result = await
|
|
45
|
+
const result = await uploadOperationFile(factory, 'files.upload', {
|
|
48
46
|
file: file.blob,
|
|
49
47
|
fileName: options.name ?? file.fileName,
|
|
50
48
|
query: { spaceId: options.space },
|
|
@@ -60,23 +58,24 @@ export function createFileCommand(factory) {
|
|
|
60
58
|
.argument('<id>')
|
|
61
59
|
.requiredOption('--to <path>', 'Output path, or - for stdout')
|
|
62
60
|
.action(async (id, options) => {
|
|
63
|
-
const
|
|
64
|
-
|
|
61
|
+
const data = await downloadOperation(factory, 'files.content', {
|
|
62
|
+
pathParams: { fileId: id },
|
|
63
|
+
});
|
|
65
64
|
await writeBinary(options.to, data);
|
|
66
65
|
}));
|
|
67
|
-
command.addCommand(
|
|
66
|
+
command.addCommand(createOperationJsonBodyCommand(factory, {
|
|
67
|
+
operationId: 'files.update',
|
|
68
68
|
name: 'patch',
|
|
69
69
|
description: 'Edit file metadata',
|
|
70
|
-
method: 'patch',
|
|
71
|
-
path: '/files/{fileId}',
|
|
72
70
|
argNames: ['fileId'],
|
|
73
71
|
configure: (cmd) => cmd
|
|
74
72
|
.option('--name <name>', 'Display name')
|
|
75
73
|
.option('--metadata-file <path>', 'Metadata JSON file')
|
|
76
74
|
.option('--input <path>', 'Read full JSON request body from file, or - for stdin'),
|
|
77
75
|
body: async (_args, options) => {
|
|
78
|
-
if (typeof options.input === 'string')
|
|
79
|
-
return readJsonFile(options.input);
|
|
76
|
+
if (typeof options.input === 'string') {
|
|
77
|
+
return (await readJsonFile(options.input));
|
|
78
|
+
}
|
|
80
79
|
return {
|
|
81
80
|
name: options.name,
|
|
82
81
|
metadata: typeof options.metadataFile === 'string'
|
|
@@ -85,9 +84,9 @@ export function createFileCommand(factory) {
|
|
|
85
84
|
};
|
|
86
85
|
},
|
|
87
86
|
}));
|
|
88
|
-
command.addCommand(
|
|
87
|
+
command.addCommand(createOperationDeleteCommand(factory, {
|
|
88
|
+
operationId: 'files.delete',
|
|
89
89
|
description: 'Delete a file',
|
|
90
|
-
path: '/files/{fileId}',
|
|
91
90
|
argNames: ['fileId'],
|
|
92
91
|
}));
|
|
93
92
|
return command;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { addOutputFlags } from '../shared/output.js';
|
|
3
|
-
import {
|
|
3
|
+
import { outputFlags, requestOperationAndPrint } from '../shared/operation.js';
|
|
4
4
|
export function createHelpCommand(factory) {
|
|
5
5
|
return addOutputFlags(new Command('help')
|
|
6
6
|
.description('Get BCTRL API help')
|
|
7
7
|
.option('--topic <topic>', 'Help topic')
|
|
8
8
|
.option('--audience <audience>', 'Help audience')).action(async (options) => {
|
|
9
|
-
await
|
|
9
|
+
await requestOperationAndPrint(factory, 'help', {
|
|
10
10
|
query: {
|
|
11
11
|
topic: options.topic,
|
|
12
12
|
audience: options.audience,
|
|
13
13
|
},
|
|
14
|
-
output: options,
|
|
14
|
+
output: outputFlags(options),
|
|
15
15
|
});
|
|
16
16
|
});
|
|
17
17
|
}
|
|
@@ -1,39 +1,38 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { addOutputFlags } from '../shared/output.js';
|
|
3
|
-
import { addPaginationFlags,
|
|
3
|
+
import { addPaginationFlags, createOperationDeleteCommand, createOperationJsonBodyCommand, createOperationListCommand, createOperationViewCommand, outputFlags, requestOperationAndPrint, } from '../shared/operation.js';
|
|
4
4
|
export function createProxyCommand(factory) {
|
|
5
5
|
const command = new Command('proxy').description('Manage proxies');
|
|
6
|
-
command.addCommand(
|
|
6
|
+
command.addCommand(createOperationListCommand(factory, {
|
|
7
|
+
operationId: 'proxies.list',
|
|
7
8
|
description: 'List proxies',
|
|
8
|
-
path: '/proxies',
|
|
9
9
|
}));
|
|
10
|
-
command.addCommand(
|
|
10
|
+
command.addCommand(createOperationViewCommand(factory, {
|
|
11
|
+
operationId: 'proxies.get',
|
|
11
12
|
name: 'get',
|
|
12
13
|
description: 'Get a proxy',
|
|
13
|
-
path: '/proxies/{proxyId}',
|
|
14
14
|
argName: 'proxyId',
|
|
15
15
|
}));
|
|
16
|
-
command.addCommand(
|
|
16
|
+
command.addCommand(createOperationJsonBodyCommand(factory, {
|
|
17
|
+
operationId: 'proxies.create',
|
|
17
18
|
name: 'create',
|
|
18
19
|
description: 'Create a proxy',
|
|
19
|
-
method: 'post',
|
|
20
|
-
path: '/proxies',
|
|
21
20
|
}));
|
|
22
|
-
command.addCommand(
|
|
21
|
+
command.addCommand(createOperationJsonBodyCommand(factory, {
|
|
22
|
+
operationId: 'proxies.update',
|
|
23
23
|
name: 'patch',
|
|
24
24
|
description: 'Update a proxy',
|
|
25
|
-
method: 'patch',
|
|
26
|
-
path: '/proxies/{proxyId}',
|
|
27
25
|
argNames: ['proxyId'],
|
|
28
26
|
}));
|
|
29
27
|
command.addCommand(addOutputFlags(new Command('test').description('Test a proxy').argument('<proxyId>')).action(async (proxyId, options) => {
|
|
30
|
-
await
|
|
31
|
-
|
|
28
|
+
await requestOperationAndPrint(factory, 'proxies.test', {
|
|
29
|
+
pathParams: { proxyId },
|
|
30
|
+
output: outputFlags(options),
|
|
32
31
|
});
|
|
33
32
|
}));
|
|
34
|
-
command.addCommand(
|
|
33
|
+
command.addCommand(createOperationDeleteCommand(factory, {
|
|
34
|
+
operationId: 'proxies.delete',
|
|
35
35
|
description: 'Delete a proxy',
|
|
36
|
-
path: '/proxies/{proxyId}',
|
|
37
36
|
argNames: ['proxyId'],
|
|
38
37
|
}));
|
|
39
38
|
command.addCommand(createProxyPoolCommand(factory));
|
|
@@ -41,9 +40,9 @@ export function createProxyCommand(factory) {
|
|
|
41
40
|
}
|
|
42
41
|
function createProxyPoolCommand(factory) {
|
|
43
42
|
const command = new Command('pool').description('Inspect managed proxy pools');
|
|
44
|
-
command.addCommand(
|
|
43
|
+
command.addCommand(createOperationListCommand(factory, {
|
|
44
|
+
operationId: 'proxies.pools.list',
|
|
45
45
|
description: 'List proxy pools',
|
|
46
|
-
path: '/proxies/pools',
|
|
47
46
|
configure: (cmd) => addPaginationFlags(cmd)
|
|
48
47
|
.option('--country <country>', 'Filter by ISO country code')
|
|
49
48
|
.option('--category <category>', 'Filter by category')
|
|
@@ -51,16 +50,23 @@ function createProxyPoolCommand(factory) {
|
|
|
51
50
|
query: (options) => ({
|
|
52
51
|
country: typeof options.country === 'string' ? options.country : undefined,
|
|
53
52
|
category: typeof options.category === 'string' ? options.category : undefined,
|
|
54
|
-
available: typeof options.available === 'string' ? options.available : undefined,
|
|
53
|
+
available: typeof options.available === 'string' ? parseBooleanFlag(options.available) : undefined,
|
|
55
54
|
limit: typeof options.limit === 'number' ? options.limit : undefined,
|
|
56
55
|
cursor: typeof options.cursor === 'string' ? options.cursor : undefined,
|
|
57
56
|
}),
|
|
58
57
|
}));
|
|
59
|
-
command.addCommand(
|
|
58
|
+
command.addCommand(createOperationViewCommand(factory, {
|
|
59
|
+
operationId: 'proxies.pools.get',
|
|
60
60
|
name: 'get',
|
|
61
61
|
description: 'Get a proxy pool',
|
|
62
|
-
path: '/proxies/pools/{poolId}',
|
|
63
62
|
argName: 'poolId',
|
|
64
63
|
}));
|
|
65
64
|
return command;
|
|
66
65
|
}
|
|
66
|
+
function parseBooleanFlag(value) {
|
|
67
|
+
if (value === 'true')
|
|
68
|
+
return true;
|
|
69
|
+
if (value === 'false')
|
|
70
|
+
return false;
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
@@ -3,12 +3,12 @@ import { CliError } from '../../runtime/errors.js';
|
|
|
3
3
|
import { readJsonFile, writeBinary } from '../shared/io.js';
|
|
4
4
|
import { parsePositiveInteger } from '../shared/options.js';
|
|
5
5
|
import { addOutputFlags } from '../shared/output.js';
|
|
6
|
-
import { addPaginationFlags,
|
|
6
|
+
import { addPaginationFlags, createOperationJsonBodyCommand, createOperationListCommand, createOperationViewCommand, downloadOperation, outputFlags, requestOperation, requestOperationAndPrint, streamOperationText, } from '../shared/operation.js';
|
|
7
7
|
export function createRunCommand(factory) {
|
|
8
8
|
const command = new Command('run').description('Inspect and stream runs');
|
|
9
|
-
command.addCommand(
|
|
9
|
+
command.addCommand(createOperationListCommand(factory, {
|
|
10
|
+
operationId: 'runs.list',
|
|
10
11
|
description: 'List runs',
|
|
11
|
-
path: '/runs',
|
|
12
12
|
configure: (cmd) => addPaginationFlags(cmd)
|
|
13
13
|
.option('--space <id>', 'Filter by space id')
|
|
14
14
|
.option('--runtime <id>', 'Filter by runtime id')
|
|
@@ -23,10 +23,10 @@ export function createRunCommand(factory) {
|
|
|
23
23
|
cursor: typeof options.cursor === 'string' ? options.cursor : undefined,
|
|
24
24
|
}),
|
|
25
25
|
}));
|
|
26
|
-
command.addCommand(
|
|
26
|
+
command.addCommand(createOperationViewCommand(factory, {
|
|
27
|
+
operationId: 'runs.get',
|
|
27
28
|
name: 'get',
|
|
28
29
|
description: 'Get a run',
|
|
29
|
-
path: '/runs/{runId}',
|
|
30
30
|
argName: 'runId',
|
|
31
31
|
}));
|
|
32
32
|
command.addCommand(createRunActivityCommand(factory));
|
|
@@ -44,7 +44,7 @@ function createRunActivityCommand(factory) {
|
|
|
44
44
|
command.addCommand(createSseCommand(factory, {
|
|
45
45
|
name: 'stream',
|
|
46
46
|
description: 'Stream run activities',
|
|
47
|
-
|
|
47
|
+
operationId: 'runs.activity.stream',
|
|
48
48
|
configure: (cmd) => addPaginationFlags(cmd)
|
|
49
49
|
.option('--view <view>', 'Activity view')
|
|
50
50
|
.option('--type <type>', 'Filter by activity type')
|
|
@@ -73,7 +73,8 @@ function createRunActivityListCommand(factory) {
|
|
|
73
73
|
.option('--severity <severity>', 'Filter by severity')
|
|
74
74
|
.option('--invocation <id>', 'Filter by invocation id')
|
|
75
75
|
.option('--file <id>', 'Filter by file id')).action(async (runId, options) => {
|
|
76
|
-
await
|
|
76
|
+
await requestOperationAndPrint(factory, 'runs.activity.list', {
|
|
77
|
+
pathParams: { runId },
|
|
77
78
|
query: {
|
|
78
79
|
view: options.view,
|
|
79
80
|
type: options.type,
|
|
@@ -84,7 +85,7 @@ function createRunActivityListCommand(factory) {
|
|
|
84
85
|
limit: options.limit,
|
|
85
86
|
cursor: options.cursor,
|
|
86
87
|
},
|
|
87
|
-
output: options,
|
|
88
|
+
output: outputFlags(options),
|
|
88
89
|
});
|
|
89
90
|
});
|
|
90
91
|
}
|
|
@@ -94,7 +95,7 @@ function createRunEventsCommand(factory) {
|
|
|
94
95
|
command.addCommand(createSseCommand(factory, {
|
|
95
96
|
name: 'stream',
|
|
96
97
|
description: 'Stream run events',
|
|
97
|
-
|
|
98
|
+
operationId: 'runs.events.stream',
|
|
98
99
|
configure: (cmd) => addPaginationFlags(cmd)
|
|
99
100
|
.option('--type <type>', 'Filter by event type')
|
|
100
101
|
.option('--status <status>', 'Filter by event status')
|
|
@@ -117,7 +118,8 @@ function createRunEventsListCommand(factory) {
|
|
|
117
118
|
.option('--status <status>', 'Filter by event status')
|
|
118
119
|
.option('--page-id <id>', 'Filter by page id')
|
|
119
120
|
.option('--context-id <id>', 'Filter by browser context id')).action(async (runId, options) => {
|
|
120
|
-
await
|
|
121
|
+
await requestOperationAndPrint(factory, 'runs.events.list', {
|
|
122
|
+
pathParams: { runId },
|
|
121
123
|
query: {
|
|
122
124
|
type: options.type,
|
|
123
125
|
status: options.status,
|
|
@@ -126,7 +128,7 @@ function createRunEventsListCommand(factory) {
|
|
|
126
128
|
limit: options.limit,
|
|
127
129
|
cursor: options.cursor,
|
|
128
130
|
},
|
|
129
|
-
output: options,
|
|
131
|
+
output: outputFlags(options),
|
|
130
132
|
});
|
|
131
133
|
});
|
|
132
134
|
}
|
|
@@ -138,9 +140,14 @@ function createRunFilesCommand(factory) {
|
|
|
138
140
|
}
|
|
139
141
|
function createRunFilesListCommand(factory) {
|
|
140
142
|
return addOutputFlags(addPaginationFlags(new Command('list').description('List run files').argument('<runId>')).option('--type <type>', 'Filter by file type')).action(async (runId, options) => {
|
|
141
|
-
await
|
|
142
|
-
|
|
143
|
-
|
|
143
|
+
await requestOperationAndPrint(factory, 'runs.files.list', {
|
|
144
|
+
pathParams: { runId },
|
|
145
|
+
query: {
|
|
146
|
+
type: options.type,
|
|
147
|
+
limit: options.limit,
|
|
148
|
+
cursor: options.cursor,
|
|
149
|
+
},
|
|
150
|
+
output: outputFlags(options),
|
|
144
151
|
});
|
|
145
152
|
});
|
|
146
153
|
}
|
|
@@ -152,7 +159,6 @@ function createRunFilesExportCommand(factory) {
|
|
|
152
159
|
.option('--name <name>', 'Export file name', 'run-files.zip')
|
|
153
160
|
.option('--type <type...>', 'Filter exported file types')
|
|
154
161
|
.option('--input <path>', 'Read JSON request body from file, or - for stdin')).action(async (runId, options) => {
|
|
155
|
-
const client = await factory.apiClient();
|
|
156
162
|
const body = typeof options.input === 'string'
|
|
157
163
|
? await readJsonFile(options.input)
|
|
158
164
|
: {
|
|
@@ -160,12 +166,17 @@ function createRunFilesExportCommand(factory) {
|
|
|
160
166
|
name: options.name,
|
|
161
167
|
filter: options.type ? { type: options.type } : undefined,
|
|
162
168
|
};
|
|
163
|
-
const result = await
|
|
169
|
+
const result = (await requestOperation(factory, 'runs.files.export', {
|
|
170
|
+
pathParams: { runId },
|
|
171
|
+
body: body,
|
|
172
|
+
}));
|
|
164
173
|
const fileId = result.fileId ?? result.id;
|
|
165
174
|
if (!fileId) {
|
|
166
175
|
throw new CliError('Expected run export response to include fileId');
|
|
167
176
|
}
|
|
168
|
-
const data = await
|
|
177
|
+
const data = await downloadOperation(factory, 'files.content', {
|
|
178
|
+
pathParams: { fileId },
|
|
179
|
+
});
|
|
169
180
|
await writeBinary(options.to, data);
|
|
170
181
|
});
|
|
171
182
|
}
|
|
@@ -174,14 +185,15 @@ function createRunInvocationsCommand(factory) {
|
|
|
174
185
|
.option('--status <status>', 'Filter by invocation status')
|
|
175
186
|
.option('--action <action>', 'Filter by invocation action'));
|
|
176
187
|
command.action(async (runId, options) => {
|
|
177
|
-
await
|
|
188
|
+
await requestOperationAndPrint(factory, 'runs.invocations.list', {
|
|
189
|
+
pathParams: { runId },
|
|
178
190
|
query: {
|
|
179
191
|
status: options.status,
|
|
180
192
|
action: options.action,
|
|
181
193
|
limit: options.limit,
|
|
182
194
|
cursor: options.cursor,
|
|
183
195
|
},
|
|
184
|
-
output: options,
|
|
196
|
+
output: outputFlags(options),
|
|
185
197
|
});
|
|
186
198
|
});
|
|
187
199
|
return command;
|
|
@@ -192,24 +204,27 @@ function createRunInvocationCommand(factory) {
|
|
|
192
204
|
.description('Get a run invocation')
|
|
193
205
|
.argument('<runId>')
|
|
194
206
|
.argument('<invocationId>')).action(async (runId, invocationId, options) => {
|
|
195
|
-
await
|
|
207
|
+
await requestOperationAndPrint(factory, 'runs.invocations.get', {
|
|
208
|
+
pathParams: { runId, invocationId },
|
|
209
|
+
output: outputFlags(options),
|
|
210
|
+
});
|
|
196
211
|
}));
|
|
197
212
|
return command;
|
|
198
213
|
}
|
|
199
214
|
function createRunViewerCommand(factory, name, description) {
|
|
200
|
-
return
|
|
215
|
+
return createOperationJsonBodyCommand(factory, {
|
|
216
|
+
operationId: name === 'live' ? 'runs.live' : 'runs.recording',
|
|
201
217
|
name,
|
|
202
218
|
description,
|
|
203
|
-
method: 'post',
|
|
204
|
-
path: `/runs/{runId}/${name}`,
|
|
205
219
|
argNames: ['runId'],
|
|
206
220
|
configure: (cmd) => cmd
|
|
207
221
|
.option('--expires-in-seconds <seconds>', 'Viewer expiration in seconds', parsePositiveInteger)
|
|
208
222
|
.option('--control <none|input>', 'Live viewer control mode')
|
|
209
223
|
.option('--input <path>', 'Read JSON request body from file, or - for stdin'),
|
|
210
224
|
body: async (_args, options) => {
|
|
211
|
-
if (typeof options.input === 'string')
|
|
212
|
-
return readJsonFile(options.input);
|
|
225
|
+
if (typeof options.input === 'string') {
|
|
226
|
+
return (await readJsonFile(options.input));
|
|
227
|
+
}
|
|
213
228
|
return {
|
|
214
229
|
expiresInSeconds: typeof options.expiresInSeconds === 'number' ? options.expiresInSeconds : undefined,
|
|
215
230
|
control: name === 'live' ? options.control : undefined,
|
|
@@ -221,8 +236,10 @@ function createSseCommand(factory, config) {
|
|
|
221
236
|
let command = new Command(config.name).description(config.description).argument('<runId>');
|
|
222
237
|
command = config.configure(command);
|
|
223
238
|
return command.action(async (runId, options) => {
|
|
224
|
-
const
|
|
225
|
-
|
|
239
|
+
const stream = await streamOperationText(factory, config.operationId, {
|
|
240
|
+
pathParams: { runId },
|
|
241
|
+
query: config.query(options),
|
|
242
|
+
});
|
|
226
243
|
await renderSseStream(factory, stream);
|
|
227
244
|
});
|
|
228
245
|
}
|