@bctrl/cli 0.1.4 → 0.1.5
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 +34 -52
- 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 +5963 -128
- package/dist/generated/help.js +7878 -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 +13755 -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,42 +1,55 @@
|
|
|
1
1
|
import { Command, Option } from 'commander';
|
|
2
2
|
import { readBlob, readJsonFile } from '../shared/io.js';
|
|
3
|
+
import { addPaginationFlags, createOperationJsonBodyCommand, outputFlags, requestOperationAndPrint, uploadOperationFile, } from '../shared/operation.js';
|
|
3
4
|
import { parsePositiveInteger } from '../shared/options.js';
|
|
4
5
|
import { addOutputFlags, outputData } from '../shared/output.js';
|
|
5
|
-
import {
|
|
6
|
+
import { CliError } from '../../runtime/errors.js';
|
|
6
7
|
export function createRuntimeCommand(factory) {
|
|
7
8
|
const command = new Command('runtime').description('Manage runtimes');
|
|
8
|
-
command.addCommand(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
command.addCommand(addOutputFlags(addPaginationFlags(new Command('list').description('List runtimes'))
|
|
10
|
+
.option('--space <id>', 'Filter by space id')
|
|
11
|
+
.addOption(new Option('--status <status>', 'Filter by runtime status').choices([
|
|
12
|
+
'active',
|
|
13
|
+
'failed',
|
|
14
|
+
'stopped',
|
|
15
|
+
]))).action(async (options) => {
|
|
16
|
+
await requestOperationAndPrint(factory, 'runtimes.list', {
|
|
17
|
+
query: {
|
|
18
|
+
spaceId: options.space,
|
|
19
|
+
status: options.status,
|
|
20
|
+
limit: options.limit,
|
|
21
|
+
cursor: options.cursor,
|
|
22
|
+
},
|
|
23
|
+
output: outputFlags(options),
|
|
24
|
+
});
|
|
20
25
|
}));
|
|
21
|
-
command.addCommand(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
command.addCommand(addOutputFlags(new Command('get').description('Get a runtime').argument('<runtimeId>')).action(async (runtimeId, options) => {
|
|
27
|
+
await requestOperationAndPrint(factory, 'runtimes.get', {
|
|
28
|
+
pathParams: { runtimeId },
|
|
29
|
+
output: outputFlags(options),
|
|
30
|
+
});
|
|
26
31
|
}));
|
|
27
32
|
command.addCommand(createRuntimeCreateCommand(factory));
|
|
28
33
|
command.addCommand(createRuntimePatchCommand(factory));
|
|
29
|
-
command.addCommand(
|
|
30
|
-
description
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
command.addCommand(addOutputFlags(new Command('delete')
|
|
35
|
+
.description('Delete a runtime and its browser state')
|
|
36
|
+
.argument('<runtimeId>')
|
|
37
|
+
.option('-y, --yes', 'Confirm deletion')
|
|
38
|
+
.option('--force', 'Stop the runtime first if it is still active')).action(async (runtimeId, options) => {
|
|
39
|
+
if (options.yes !== true) {
|
|
40
|
+
throw new CliError('Refusing to delete without --yes');
|
|
41
|
+
}
|
|
42
|
+
await requestOperationAndPrint(factory, 'runtimes.delete', {
|
|
43
|
+
pathParams: { runtimeId },
|
|
44
|
+
query: { force: options.force === true ? true : undefined },
|
|
45
|
+
output: outputFlags(options),
|
|
46
|
+
});
|
|
35
47
|
}));
|
|
36
48
|
command.addCommand(createRuntimeStartCommand(factory));
|
|
37
49
|
command.addCommand(addOutputFlags(new Command('stop').description('Stop a runtime').argument('<runtimeId>')).action(async (runtimeId, options) => {
|
|
38
|
-
await
|
|
39
|
-
|
|
50
|
+
await requestOperationAndPrint(factory, 'runtimes.stop', {
|
|
51
|
+
pathParams: { runtimeId },
|
|
52
|
+
output: outputFlags(options),
|
|
40
53
|
});
|
|
41
54
|
}));
|
|
42
55
|
command.addCommand(createRuntimeFileCommand(factory));
|
|
@@ -47,8 +60,9 @@ export function createRuntimeCommand(factory) {
|
|
|
47
60
|
function createRuntimeTargetCommand(factory) {
|
|
48
61
|
const command = new Command('target').description('Manage runtime targets (tabs)');
|
|
49
62
|
command.addCommand(addOutputFlags(new Command('list').description('List targets').argument('<runtimeId>')).action(async (runtimeId, options) => {
|
|
50
|
-
await
|
|
51
|
-
|
|
63
|
+
await requestOperationAndPrint(factory, 'runtimes.targets.list', {
|
|
64
|
+
pathParams: { runtimeId },
|
|
65
|
+
output: outputFlags(options),
|
|
52
66
|
});
|
|
53
67
|
}));
|
|
54
68
|
command.addCommand(addOutputFlags(new Command('create')
|
|
@@ -56,78 +70,82 @@ function createRuntimeTargetCommand(factory) {
|
|
|
56
70
|
.argument('<runtimeId>')
|
|
57
71
|
.option('--uri <uri>', 'Navigate the new target to this URI')
|
|
58
72
|
.option('--activate', 'Focus the new target')).action(async (runtimeId, options) => {
|
|
59
|
-
await
|
|
73
|
+
await requestOperationAndPrint(factory, 'runtimes.targets.create', {
|
|
74
|
+
pathParams: { runtimeId },
|
|
60
75
|
body: {
|
|
61
76
|
...(options.uri ? { uri: options.uri } : {}),
|
|
62
77
|
...(options.activate ? { activate: true } : {}),
|
|
63
78
|
},
|
|
64
|
-
output: options,
|
|
79
|
+
output: outputFlags(options),
|
|
65
80
|
});
|
|
66
81
|
}));
|
|
67
82
|
command.addCommand(addOutputFlags(new Command('get').description('Get a target').argument('<runtimeId>').argument('<targetId>')).action(async (runtimeId, targetId, options) => {
|
|
68
|
-
await
|
|
83
|
+
await requestOperationAndPrint(factory, 'runtimes.targets.get', {
|
|
84
|
+
pathParams: { runtimeId, targetId },
|
|
85
|
+
output: outputFlags(options),
|
|
86
|
+
});
|
|
69
87
|
}));
|
|
70
88
|
command.addCommand(addOutputFlags(new Command('activate')
|
|
71
89
|
.description('Focus a target')
|
|
72
90
|
.argument('<runtimeId>')
|
|
73
91
|
.argument('<targetId>')).action(async (runtimeId, targetId, options) => {
|
|
74
|
-
await
|
|
92
|
+
await requestOperationAndPrint(factory, 'runtimes.targets.activate', {
|
|
93
|
+
pathParams: { runtimeId, targetId },
|
|
94
|
+
output: outputFlags(options),
|
|
95
|
+
});
|
|
75
96
|
}));
|
|
76
97
|
command.addCommand(addOutputFlags(new Command('delete')
|
|
77
98
|
.description('Close a target')
|
|
78
99
|
.argument('<runtimeId>')
|
|
79
100
|
.argument('<targetId>')).action(async (runtimeId, targetId, options) => {
|
|
80
|
-
await
|
|
101
|
+
await requestOperationAndPrint(factory, 'runtimes.targets.delete', {
|
|
102
|
+
pathParams: { runtimeId, targetId },
|
|
103
|
+
output: outputFlags(options),
|
|
104
|
+
});
|
|
81
105
|
}));
|
|
82
106
|
return command;
|
|
83
107
|
}
|
|
84
108
|
function createRuntimeCreateCommand(factory) {
|
|
85
|
-
return
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
])
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
config: buildRuntimeCreateConfig(config, options),
|
|
126
|
-
metadata: typeof options.metadataFile === 'string'
|
|
127
|
-
? await readJsonFile(options.metadataFile, '--metadata-file')
|
|
128
|
-
: undefined,
|
|
129
|
-
};
|
|
130
|
-
},
|
|
109
|
+
return addOutputFlags(new Command('create')
|
|
110
|
+
.description('Create a runtime')
|
|
111
|
+
.option('--space <id>', 'Space id; omitted uses caller default space')
|
|
112
|
+
.option('--name <name>', 'Runtime name')
|
|
113
|
+
.option('--profile', 'Persist browser state across runtime starts')
|
|
114
|
+
.option('--proxy <id-or-url>', 'Saved proxy id or inline custom proxy URL')
|
|
115
|
+
.addOption(new Option('--device <device>', 'Fingerprint device filter').choices(['desktop', 'mobile']))
|
|
116
|
+
.addOption(new Option('--os <os>', 'Fingerprint OS filter').choices([
|
|
117
|
+
'windows',
|
|
118
|
+
'macos',
|
|
119
|
+
'android',
|
|
120
|
+
'ios',
|
|
121
|
+
]))
|
|
122
|
+
.addOption(new Option('--browser <browser>', 'Fingerprint browser filter').choices([
|
|
123
|
+
'chrome',
|
|
124
|
+
'edge',
|
|
125
|
+
'safari',
|
|
126
|
+
]))
|
|
127
|
+
.option('--browser-version <version>', 'Fingerprint browser version filter')
|
|
128
|
+
.option('--locale <locale>', 'Fingerprint locale/language filter; repeat to set an ordered language stack', collectLocale, [])
|
|
129
|
+
.option('--config-file <path>', 'Runtime config JSON file')
|
|
130
|
+
.option('--metadata-file <path>', 'Runtime metadata JSON file')
|
|
131
|
+
.option('--input <path>', 'Read full JSON request body from file, or - for stdin')).action(async (options) => {
|
|
132
|
+
const config = typeof options.configFile === 'string'
|
|
133
|
+
? await readJsonFile(options.configFile, '--config-file')
|
|
134
|
+
: undefined;
|
|
135
|
+
await requestOperationAndPrint(factory, 'runtimes.create', {
|
|
136
|
+
body: typeof options.input === 'string'
|
|
137
|
+
? (await readJsonFile(options.input))
|
|
138
|
+
: {
|
|
139
|
+
type: 'browser',
|
|
140
|
+
spaceId: options.space,
|
|
141
|
+
name: options.name,
|
|
142
|
+
config: buildRuntimeCreateConfig(config, options),
|
|
143
|
+
metadata: typeof options.metadataFile === 'string'
|
|
144
|
+
? await readJsonFile(options.metadataFile, '--metadata-file')
|
|
145
|
+
: undefined,
|
|
146
|
+
},
|
|
147
|
+
output: outputFlags(options),
|
|
148
|
+
});
|
|
131
149
|
});
|
|
132
150
|
}
|
|
133
151
|
function collectLocale(value, previous) {
|
|
@@ -173,28 +191,26 @@ function buildRuntimeCreateConfig(config, options) {
|
|
|
173
191
|
};
|
|
174
192
|
}
|
|
175
193
|
function createRuntimePatchCommand(factory) {
|
|
176
|
-
return
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
};
|
|
197
|
-
},
|
|
194
|
+
return addOutputFlags(new Command('patch')
|
|
195
|
+
.description('Update a runtime')
|
|
196
|
+
.argument('<runtimeId>')
|
|
197
|
+
.option('--name <name>', 'Runtime name')
|
|
198
|
+
.option('--idle-timeout-minutes <minutes>', 'Idle timeout in minutes', parsePositiveInteger)
|
|
199
|
+
.option('--config-file <path>', 'Runtime config JSON file')
|
|
200
|
+
.option('--input <path>', 'Read full JSON request body from file, or - for stdin')).action(async (runtimeId, options) => {
|
|
201
|
+
await requestOperationAndPrint(factory, 'runtimes.update', {
|
|
202
|
+
pathParams: { runtimeId },
|
|
203
|
+
body: typeof options.input === 'string'
|
|
204
|
+
? (await readJsonFile(options.input))
|
|
205
|
+
: {
|
|
206
|
+
name: options.name,
|
|
207
|
+
idleTimeoutMinutes: options.idleTimeoutMinutes,
|
|
208
|
+
config: typeof options.configFile === 'string'
|
|
209
|
+
? await readJsonFile(options.configFile, '--config-file')
|
|
210
|
+
: undefined,
|
|
211
|
+
},
|
|
212
|
+
output: outputFlags(options),
|
|
213
|
+
});
|
|
198
214
|
});
|
|
199
215
|
}
|
|
200
216
|
function createRuntimeStartCommand(factory) {
|
|
@@ -202,9 +218,10 @@ function createRuntimeStartCommand(factory) {
|
|
|
202
218
|
.description('Start a runtime')
|
|
203
219
|
.argument('<runtimeId>')
|
|
204
220
|
.option('--idempotency-key <key>', 'Idempotency key for retry-safe start')).action(async (runtimeId, options) => {
|
|
205
|
-
await
|
|
221
|
+
await requestOperationAndPrint(factory, 'runtimes.start', {
|
|
222
|
+
pathParams: { runtimeId },
|
|
206
223
|
idempotencyKey: options.idempotencyKey,
|
|
207
|
-
output: options,
|
|
224
|
+
output: outputFlags(options),
|
|
208
225
|
});
|
|
209
226
|
});
|
|
210
227
|
}
|
|
@@ -216,7 +233,10 @@ function createRuntimeInvocationCommand(factory) {
|
|
|
216
233
|
.description('Cancel an invocation')
|
|
217
234
|
.argument('<runtimeId>')
|
|
218
235
|
.argument('<invocationId>')).action(async (runtimeId, invocationId, options) => {
|
|
219
|
-
await
|
|
236
|
+
await requestOperationAndPrint(factory, 'runtimes.invocations.cancel', {
|
|
237
|
+
pathParams: { runtimeId, invocationId },
|
|
238
|
+
output: outputFlags(options),
|
|
239
|
+
});
|
|
220
240
|
}));
|
|
221
241
|
return command;
|
|
222
242
|
}
|
|
@@ -248,37 +268,42 @@ function createRuntimeInvocationCreateCommand(factory) {
|
|
|
248
268
|
toolsetId: options.toolset,
|
|
249
269
|
timeoutMs: options.timeoutMs,
|
|
250
270
|
};
|
|
251
|
-
await
|
|
252
|
-
|
|
271
|
+
await requestOperationAndPrint(factory, 'runtimes.invocations.create', {
|
|
272
|
+
pathParams: { runtimeId },
|
|
273
|
+
body: body,
|
|
253
274
|
idempotencyKey: options.idempotencyKey,
|
|
254
|
-
output: options,
|
|
275
|
+
output: outputFlags(options),
|
|
255
276
|
});
|
|
256
277
|
});
|
|
257
278
|
}
|
|
258
279
|
function createRuntimeInvocationWaitCommand(factory) {
|
|
259
|
-
return
|
|
280
|
+
return createOperationJsonBodyCommand(factory, {
|
|
281
|
+
operationId: 'runtimes.invocations.wait',
|
|
260
282
|
name: 'wait',
|
|
261
283
|
description: 'Wait for an invocation',
|
|
262
|
-
method: 'post',
|
|
263
|
-
path: '/runtimes/{runtimeId}/invocations/{invocationId}/wait',
|
|
264
284
|
argNames: ['runtimeId', 'invocationId'],
|
|
265
285
|
configure: (cmd) => cmd
|
|
266
286
|
.option('--timeout-ms <ms>', 'Wait timeout in milliseconds', parsePositiveInteger)
|
|
267
287
|
.option('--input <path>', 'Read JSON request body from file, or - for stdin'),
|
|
268
288
|
body: async (_args, options) => {
|
|
269
|
-
if (typeof options.input === 'string')
|
|
270
|
-
return readJsonFile(options.input);
|
|
289
|
+
if (typeof options.input === 'string') {
|
|
290
|
+
return (await readJsonFile(options.input));
|
|
291
|
+
}
|
|
271
292
|
return { timeoutMs: options.timeoutMs };
|
|
272
293
|
},
|
|
273
294
|
});
|
|
274
295
|
}
|
|
275
296
|
function createRuntimeFileCommand(factory) {
|
|
276
297
|
const command = new Command('file').description('Move files into and out of runtimes');
|
|
277
|
-
command.addCommand(addOutputFlags(addPaginationFlags(new Command('list').description('List runtime files').argument('<runtimeId>'))
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
query: {
|
|
281
|
-
|
|
298
|
+
command.addCommand(addOutputFlags(addPaginationFlags(new Command('list').description('List runtime files').argument('<runtimeId>')).option('--type <type>', 'Filter by file type')).action(async (runtimeId, options) => {
|
|
299
|
+
await requestOperationAndPrint(factory, 'runtimes.files.list', {
|
|
300
|
+
pathParams: { runtimeId },
|
|
301
|
+
query: {
|
|
302
|
+
type: options.type,
|
|
303
|
+
limit: options.limit,
|
|
304
|
+
cursor: options.cursor,
|
|
305
|
+
},
|
|
306
|
+
output: outputFlags(options),
|
|
282
307
|
});
|
|
283
308
|
}));
|
|
284
309
|
command.addCommand(createRuntimeFileUploadCommand(factory));
|
|
@@ -295,12 +320,12 @@ function createRuntimeFileUploadCommand(factory) {
|
|
|
295
320
|
.option('--runtime-path <path>', 'Runtime workspace destination')
|
|
296
321
|
.option('--name <name>', 'Display name')
|
|
297
322
|
.option('--metadata-file <path>', 'Metadata JSON file')).action(async (runtimeId, localPath, options) => {
|
|
298
|
-
const client = await factory.apiClient();
|
|
299
323
|
const file = await readBlob(localPath);
|
|
300
324
|
const metadata = typeof options.metadataFile === 'string'
|
|
301
325
|
? JSON.stringify(await readJsonFile(options.metadataFile, '--metadata-file'))
|
|
302
326
|
: undefined;
|
|
303
|
-
const result = await
|
|
327
|
+
const result = await uploadOperationFile(factory, 'runtimes.files.upload', {
|
|
328
|
+
pathParams: { runtimeId },
|
|
304
329
|
file: file.blob,
|
|
305
330
|
fileName: options.name ?? file.fileName,
|
|
306
331
|
fields: {
|
|
@@ -314,11 +339,10 @@ function createRuntimeFileUploadCommand(factory) {
|
|
|
314
339
|
});
|
|
315
340
|
}
|
|
316
341
|
function createRuntimeFileStageCommand(factory) {
|
|
317
|
-
return
|
|
342
|
+
return createOperationJsonBodyCommand(factory, {
|
|
343
|
+
operationId: 'runtimes.files.stage',
|
|
318
344
|
name: 'stage',
|
|
319
345
|
description: 'Stage a durable file into a runtime',
|
|
320
|
-
method: 'post',
|
|
321
|
-
path: '/runtimes/{runtimeId}/files/stage',
|
|
322
346
|
argNames: ['runtimeId'],
|
|
323
347
|
configure: (cmd) => cmd
|
|
324
348
|
.option('--file <id>', 'Durable file id')
|
|
@@ -326,18 +350,22 @@ function createRuntimeFileStageCommand(factory) {
|
|
|
326
350
|
.option('--name <name>', 'Runtime-local display name')
|
|
327
351
|
.option('--input <path>', 'Read JSON request body from file, or - for stdin'),
|
|
328
352
|
body: async (_args, options) => {
|
|
329
|
-
if (typeof options.input === 'string')
|
|
330
|
-
return readJsonFile(options.input);
|
|
331
|
-
|
|
353
|
+
if (typeof options.input === 'string') {
|
|
354
|
+
return (await readJsonFile(options.input));
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
fileId: options.file,
|
|
358
|
+
runtimePath: options.runtimePath,
|
|
359
|
+
name: options.name,
|
|
360
|
+
};
|
|
332
361
|
},
|
|
333
362
|
});
|
|
334
363
|
}
|
|
335
364
|
function createRuntimeFileCollectCommand(factory) {
|
|
336
|
-
return
|
|
365
|
+
return createOperationJsonBodyCommand(factory, {
|
|
366
|
+
operationId: 'runtimes.files.collect',
|
|
337
367
|
name: 'collect',
|
|
338
368
|
description: 'Collect a runtime-local file into durable storage',
|
|
339
|
-
method: 'post',
|
|
340
|
-
path: '/runtimes/{runtimeId}/files/collect',
|
|
341
369
|
argNames: ['runtimeId'],
|
|
342
370
|
configure: (cmd) => cmd
|
|
343
371
|
.requiredOption('--runtime-path <path>', 'Runtime workspace source')
|
|
@@ -345,8 +373,9 @@ function createRuntimeFileCollectCommand(factory) {
|
|
|
345
373
|
.option('--destination-path <path>', 'Durable BCTRL storage destination')
|
|
346
374
|
.option('--input <path>', 'Read JSON request body from file, or - for stdin'),
|
|
347
375
|
body: async (_args, options) => {
|
|
348
|
-
if (typeof options.input === 'string')
|
|
349
|
-
return readJsonFile(options.input);
|
|
376
|
+
if (typeof options.input === 'string') {
|
|
377
|
+
return (await readJsonFile(options.input));
|
|
378
|
+
}
|
|
350
379
|
return {
|
|
351
380
|
runtimePath: options.runtimePath,
|
|
352
381
|
name: options.name,
|
|
@@ -22,3 +22,4 @@ export type CommandHelpSpec = {
|
|
|
22
22
|
};
|
|
23
23
|
export declare function addStructuredHelp(command: Command, spec: CommandHelpSpec): Command;
|
|
24
24
|
export declare function addCliHelp(command: Command, commandId: CliHelpCommandId): Command;
|
|
25
|
+
export declare function addCliOperationHelp(command: Command, operationId: string): Command;
|
|
@@ -6,6 +6,12 @@ export function addStructuredHelp(command, spec) {
|
|
|
6
6
|
export function addCliHelp(command, commandId) {
|
|
7
7
|
return addStructuredHelp(command, toCommandHelpSpec(CLI_HELP_COMMANDS[commandId]));
|
|
8
8
|
}
|
|
9
|
+
export function addCliOperationHelp(command, operationId) {
|
|
10
|
+
return isCliHelpCommandId(operationId) ? addCliHelp(command, operationId) : command;
|
|
11
|
+
}
|
|
12
|
+
function isCliHelpCommandId(value) {
|
|
13
|
+
return value in CLI_HELP_COMMANDS;
|
|
14
|
+
}
|
|
9
15
|
function toCommandHelpSpec(help) {
|
|
10
16
|
const raw = help;
|
|
11
17
|
return {
|
|
@@ -54,11 +60,9 @@ function renderFlags(flags) {
|
|
|
54
60
|
function renderFields(title, fields) {
|
|
55
61
|
const rows = fields.map((field) => ({
|
|
56
62
|
left: field.name,
|
|
57
|
-
right: [
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
field.description,
|
|
61
|
-
].filter(Boolean).join(' '),
|
|
63
|
+
right: [field.type, field.required === true ? 'required' : 'optional', field.description]
|
|
64
|
+
.filter(Boolean)
|
|
65
|
+
.join(' '),
|
|
62
66
|
}));
|
|
63
67
|
return renderRows(title, rows);
|
|
64
68
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { CliOperationId, CliOperationJsonBody, CliOperationPathParams, CliOperationQuery } from '../../openapi.js';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import type { BctrlApiClient } from '../../api/client.js';
|
|
4
|
+
import type { IOStreams } from '../../io/streams.js';
|
|
5
|
+
import { type OutputFlags } from './output.js';
|
|
6
|
+
export type ApiDeps = {
|
|
7
|
+
io: IOStreams;
|
|
8
|
+
apiClient: () => Promise<BctrlApiClient>;
|
|
9
|
+
};
|
|
10
|
+
type UploadFileInput<OperationId extends CliOperationId> = OperationPathInput<OperationId> & OperationQueryInput<OperationId> & {
|
|
11
|
+
file: Blob;
|
|
12
|
+
fileName: string;
|
|
13
|
+
fields?: Record<string, string>;
|
|
14
|
+
};
|
|
15
|
+
type DownloadInput<OperationId extends CliOperationId> = OperationPathInput<OperationId>;
|
|
16
|
+
type StreamInput<OperationId extends CliOperationId> = OperationPathInput<OperationId> & OperationQueryInput<OperationId>;
|
|
17
|
+
type OperationPathInput<OperationId extends CliOperationId> = [
|
|
18
|
+
CliOperationPathParams<OperationId>
|
|
19
|
+
] extends [never] ? {
|
|
20
|
+
pathParams?: never;
|
|
21
|
+
} : {
|
|
22
|
+
pathParams: CliOperationPathParams<OperationId>;
|
|
23
|
+
};
|
|
24
|
+
type OperationQueryInput<OperationId extends CliOperationId> = [
|
|
25
|
+
CliOperationQuery<OperationId>
|
|
26
|
+
] extends [never] ? {
|
|
27
|
+
query?: never;
|
|
28
|
+
} : {
|
|
29
|
+
query?: CliOperationQuery<OperationId>;
|
|
30
|
+
};
|
|
31
|
+
type OperationBodyInput<OperationId extends CliOperationId> = [
|
|
32
|
+
CliOperationJsonBody<OperationId>
|
|
33
|
+
] extends [never] ? {
|
|
34
|
+
body?: never;
|
|
35
|
+
} : {
|
|
36
|
+
body?: CliOperationJsonBody<OperationId>;
|
|
37
|
+
};
|
|
38
|
+
export type OperationRequestInput<OperationId extends CliOperationId> = OperationPathInput<OperationId> & OperationQueryInput<OperationId> & OperationBodyInput<OperationId> & {
|
|
39
|
+
idempotencyKey?: string;
|
|
40
|
+
output?: OutputFlags;
|
|
41
|
+
};
|
|
42
|
+
export declare function addPaginationFlags(command: Command): Command;
|
|
43
|
+
export declare function addJsonBodyFlag(command: Command): Command;
|
|
44
|
+
export declare function outputFlags(options: Record<string, unknown>): OutputFlags;
|
|
45
|
+
export declare function operationPath<OperationId extends CliOperationId>(operationId: OperationId, pathParams?: CliOperationPathParams<OperationId>): string;
|
|
46
|
+
export declare function requestOperationAndPrint<OperationId extends CliOperationId>(deps: ApiDeps, operationId: OperationId, input: OperationRequestInput<OperationId>): Promise<void>;
|
|
47
|
+
export declare function requestOperation<OperationId extends CliOperationId>(deps: ApiDeps, operationId: OperationId, input: OperationRequestInput<OperationId>): Promise<unknown>;
|
|
48
|
+
export declare function uploadOperationFile<OperationId extends CliOperationId>(deps: ApiDeps, operationId: OperationId, input: UploadFileInput<OperationId>): Promise<unknown>;
|
|
49
|
+
export declare function downloadOperation<OperationId extends CliOperationId>(deps: ApiDeps, operationId: OperationId, input: DownloadInput<OperationId>): Promise<Uint8Array>;
|
|
50
|
+
export declare function streamOperationText<OperationId extends CliOperationId>(deps: ApiDeps, operationId: OperationId, input: StreamInput<OperationId>): Promise<AsyncIterable<string>>;
|
|
51
|
+
export declare function createOperationListCommand<OperationId extends CliOperationId>(factory: ApiDeps, config: {
|
|
52
|
+
operationId: OperationId;
|
|
53
|
+
name?: string;
|
|
54
|
+
description: string;
|
|
55
|
+
configure?: (command: Command) => Command;
|
|
56
|
+
query?: (options: Record<string, unknown>) => CliOperationQuery<OperationId>;
|
|
57
|
+
}): Command;
|
|
58
|
+
export declare function createOperationViewCommand<OperationId extends CliOperationId>(factory: ApiDeps, config: {
|
|
59
|
+
operationId: OperationId;
|
|
60
|
+
name?: string;
|
|
61
|
+
description: string;
|
|
62
|
+
argName?: string;
|
|
63
|
+
configure?: (command: Command) => Command;
|
|
64
|
+
query?: (id: string, options: Record<string, unknown>) => CliOperationQuery<OperationId>;
|
|
65
|
+
}): Command;
|
|
66
|
+
export declare function createOperationDeleteCommand<OperationId extends CliOperationId>(factory: ApiDeps, config: {
|
|
67
|
+
operationId: OperationId;
|
|
68
|
+
name?: string;
|
|
69
|
+
description: string;
|
|
70
|
+
argNames?: string[];
|
|
71
|
+
configure?: (command: Command) => Command;
|
|
72
|
+
query?: (args: Record<string, string>, options: Record<string, unknown>) => CliOperationQuery<OperationId>;
|
|
73
|
+
}): Command;
|
|
74
|
+
export declare function createOperationJsonBodyCommand<OperationId extends CliOperationId>(factory: ApiDeps, config: {
|
|
75
|
+
operationId: OperationId;
|
|
76
|
+
name: string;
|
|
77
|
+
description: string;
|
|
78
|
+
argNames?: string[];
|
|
79
|
+
configure?: (command: Command) => Command;
|
|
80
|
+
body?: (args: Record<string, string>, options: Record<string, unknown>) => Promise<CliOperationJsonBody<OperationId>>;
|
|
81
|
+
query?: (args: Record<string, string>, options: Record<string, unknown>) => CliOperationQuery<OperationId>;
|
|
82
|
+
}): Command;
|
|
83
|
+
export {};
|