@amaster.ai/runtime-cli 1.1.7 → 1.1.8
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 +337 -126
- package/dist/cli.cjs +959 -255
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +961 -257
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +959 -255
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +961 -257
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
|
@@ -7,24 +7,18 @@ var os = require('os');
|
|
|
7
7
|
var commander = require('commander');
|
|
8
8
|
var chalk7 = require('chalk');
|
|
9
9
|
var client = require('@amaster.ai/client');
|
|
10
|
-
var
|
|
10
|
+
var ora = require('ora');
|
|
11
11
|
var yaml = require('yaml');
|
|
12
12
|
|
|
13
13
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
14
14
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
15
|
|
|
16
16
|
var chalk7__default = /*#__PURE__*/_interopDefault(chalk7);
|
|
17
|
-
var
|
|
17
|
+
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
18
18
|
var yaml__default = /*#__PURE__*/_interopDefault(yaml);
|
|
19
19
|
|
|
20
20
|
var __defProp = Object.defineProperty;
|
|
21
21
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
22
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
23
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
24
|
-
}) : x)(function(x) {
|
|
25
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
26
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
27
|
-
});
|
|
28
22
|
var __esm = (fn, res) => function __init() {
|
|
29
23
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
30
24
|
};
|
|
@@ -64,7 +58,6 @@ function getConfig() {
|
|
|
64
58
|
}
|
|
65
59
|
function saveConfig(config) {
|
|
66
60
|
if (!fs.existsSync(AMASTER_CONFIG_DIR)) {
|
|
67
|
-
const fs = __require("fs");
|
|
68
61
|
fs.mkdirSync(AMASTER_CONFIG_DIR, { recursive: true });
|
|
69
62
|
}
|
|
70
63
|
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
@@ -133,7 +126,6 @@ function getAuthSession(appCode) {
|
|
|
133
126
|
}
|
|
134
127
|
function saveAuthSession(appCode, session) {
|
|
135
128
|
if (!fs.existsSync(AMASTER_CONFIG_DIR)) {
|
|
136
|
-
const fs = __require("fs");
|
|
137
129
|
fs.mkdirSync(AMASTER_CONFIG_DIR, { recursive: true });
|
|
138
130
|
}
|
|
139
131
|
const authFile = path.join(AMASTER_CONFIG_DIR, `auth-${appCode}.json`);
|
|
@@ -181,8 +173,163 @@ init_config();
|
|
|
181
173
|
|
|
182
174
|
// src/commands/auth.ts
|
|
183
175
|
init_config();
|
|
176
|
+
var OUTPUT_FORMATS = ["json", "pretty", "table", "ndjson", "csv"];
|
|
177
|
+
function createFormatOption(description = "Output format") {
|
|
178
|
+
return new commander.Option(
|
|
179
|
+
"--format <format>",
|
|
180
|
+
`${description}: ${OUTPUT_FORMATS.join(", ")}`
|
|
181
|
+
).choices([...OUTPUT_FORMATS]).default("json");
|
|
182
|
+
}
|
|
183
|
+
function resolveOutputFormat(format) {
|
|
184
|
+
if (!format) {
|
|
185
|
+
return "json";
|
|
186
|
+
}
|
|
187
|
+
if (OUTPUT_FORMATS.includes(format)) {
|
|
188
|
+
return format;
|
|
189
|
+
}
|
|
190
|
+
throw new Error(`Unsupported output format: ${format}`);
|
|
191
|
+
}
|
|
192
|
+
function isPrettyOutput(format) {
|
|
193
|
+
return resolveOutputFormat(format) === "pretty";
|
|
194
|
+
}
|
|
195
|
+
function createSpinner(text, format) {
|
|
196
|
+
return ora__default.default({
|
|
197
|
+
text,
|
|
198
|
+
isSilent: !isPrettyOutput(format)
|
|
199
|
+
}).start();
|
|
200
|
+
}
|
|
201
|
+
function renderOutput(data, options = {}) {
|
|
202
|
+
const format = resolveOutputFormat(options.format);
|
|
203
|
+
switch (format) {
|
|
204
|
+
case "pretty":
|
|
205
|
+
if (options.pretty) {
|
|
206
|
+
options.pretty();
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
renderPrettyFallback(data);
|
|
210
|
+
return;
|
|
211
|
+
case "json":
|
|
212
|
+
console.log(JSON.stringify(data ?? null, null, 2));
|
|
213
|
+
return;
|
|
214
|
+
case "ndjson":
|
|
215
|
+
renderNdjson(options.ndjsonItems ?? data);
|
|
216
|
+
return;
|
|
217
|
+
case "table":
|
|
218
|
+
renderTable(options.tableRows ?? inferRows(data));
|
|
219
|
+
return;
|
|
220
|
+
case "csv":
|
|
221
|
+
renderCsv(options.csvRows ?? inferRows(data));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function renderPrettyFallback(data) {
|
|
226
|
+
const rows = inferRows(data);
|
|
227
|
+
if (rows.length === 0) {
|
|
228
|
+
console.log(JSON.stringify(data ?? null, null, 2));
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
renderTable(rows);
|
|
232
|
+
}
|
|
233
|
+
function renderNdjson(data) {
|
|
234
|
+
const items = inferNdjsonItems(data);
|
|
235
|
+
for (const item of items) {
|
|
236
|
+
console.log(JSON.stringify(item ?? null));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function renderTable(rows) {
|
|
240
|
+
console.table(rows);
|
|
241
|
+
}
|
|
242
|
+
function renderCsv(rows) {
|
|
243
|
+
if (rows.length === 0) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const headers = [];
|
|
247
|
+
for (const row of rows) {
|
|
248
|
+
for (const key of Object.keys(row)) {
|
|
249
|
+
if (!headers.includes(key)) {
|
|
250
|
+
headers.push(key);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (headers.length === 0) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
console.log(headers.join(","));
|
|
258
|
+
for (const row of rows) {
|
|
259
|
+
console.log(headers.map((header) => escapeCsv(row[header])).join(","));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function inferNdjsonItems(data) {
|
|
263
|
+
const collection = extractCollection(data);
|
|
264
|
+
if (collection) {
|
|
265
|
+
return collection;
|
|
266
|
+
}
|
|
267
|
+
if (Array.isArray(data)) {
|
|
268
|
+
return data;
|
|
269
|
+
}
|
|
270
|
+
return [data ?? null];
|
|
271
|
+
}
|
|
272
|
+
function inferRows(data) {
|
|
273
|
+
const collection = extractCollection(data);
|
|
274
|
+
if (collection) {
|
|
275
|
+
return normalizeRows(collection);
|
|
276
|
+
}
|
|
277
|
+
if (Array.isArray(data)) {
|
|
278
|
+
return normalizeRows(data);
|
|
279
|
+
}
|
|
280
|
+
if (isPlainObject(data)) {
|
|
281
|
+
return [normalizeRow(data)];
|
|
282
|
+
}
|
|
283
|
+
return [{ value: normalizeCell(data) }];
|
|
284
|
+
}
|
|
285
|
+
function extractCollection(data) {
|
|
286
|
+
if (!isPlainObject(data)) {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
if (Array.isArray(data.items)) {
|
|
290
|
+
return data.items;
|
|
291
|
+
}
|
|
292
|
+
if (Array.isArray(data.list)) {
|
|
293
|
+
return data.list;
|
|
294
|
+
}
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
function normalizeRows(items) {
|
|
298
|
+
return items.map((item) => {
|
|
299
|
+
if (isPlainObject(item)) {
|
|
300
|
+
return normalizeRow(item);
|
|
301
|
+
}
|
|
302
|
+
return { value: normalizeCell(item) };
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
function normalizeRow(row) {
|
|
306
|
+
return Object.fromEntries(
|
|
307
|
+
Object.entries(row).map(([key, value]) => [key, normalizeCell(value)])
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
function normalizeCell(value) {
|
|
311
|
+
if (value === null || value === void 0) {
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
315
|
+
return value;
|
|
316
|
+
}
|
|
317
|
+
return JSON.stringify(value);
|
|
318
|
+
}
|
|
319
|
+
function escapeCsv(value) {
|
|
320
|
+
const cell = value === null || value === void 0 ? "" : typeof value === "string" ? value : typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
|
|
321
|
+
if (/[",\n]/.test(cell)) {
|
|
322
|
+
return `"${cell.replace(/"/g, '""')}"`;
|
|
323
|
+
}
|
|
324
|
+
return cell;
|
|
325
|
+
}
|
|
326
|
+
function isPlainObject(value) {
|
|
327
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// src/commands/auth.ts
|
|
184
331
|
async function login(appCode, options) {
|
|
185
|
-
const spinner =
|
|
332
|
+
const spinner = createSpinner(`Logging in to ${appCode}...`, options.format);
|
|
186
333
|
try {
|
|
187
334
|
const appConfig = getAppConfig(appCode);
|
|
188
335
|
if (!appConfig) {
|
|
@@ -192,16 +339,16 @@ async function login(appCode, options) {
|
|
|
192
339
|
console.log(chalk7__default.default.yellow(`Initialize it first: amaster init --app-code ${appCode} --url <url>`));
|
|
193
340
|
process.exit(1);
|
|
194
341
|
}
|
|
342
|
+
let username = options.username;
|
|
195
343
|
let email = options.email;
|
|
196
344
|
let password = options.password;
|
|
197
|
-
if (!
|
|
345
|
+
if (!username && !email) {
|
|
198
346
|
const { default: inquirer } = await import('inquirer');
|
|
199
347
|
const answers = await inquirer.prompt([
|
|
200
348
|
{
|
|
201
349
|
type: "input",
|
|
202
|
-
name: "
|
|
203
|
-
message: "Email:"
|
|
204
|
-
when: !email
|
|
350
|
+
name: "login",
|
|
351
|
+
message: "Username or Email:"
|
|
205
352
|
},
|
|
206
353
|
{
|
|
207
354
|
type: "password",
|
|
@@ -210,11 +357,32 @@ async function login(appCode, options) {
|
|
|
210
357
|
when: !password
|
|
211
358
|
}
|
|
212
359
|
]);
|
|
213
|
-
|
|
360
|
+
const login2 = answers.login;
|
|
361
|
+
if (login2.includes("@")) {
|
|
362
|
+
email = login2;
|
|
363
|
+
} else {
|
|
364
|
+
username = login2;
|
|
365
|
+
}
|
|
214
366
|
password = password || answers.password;
|
|
367
|
+
} else if (!password) {
|
|
368
|
+
const { default: inquirer } = await import('inquirer');
|
|
369
|
+
const answers = await inquirer.prompt([
|
|
370
|
+
{
|
|
371
|
+
type: "password",
|
|
372
|
+
name: "password",
|
|
373
|
+
message: "Password:"
|
|
374
|
+
}
|
|
375
|
+
]);
|
|
376
|
+
password = answers.password;
|
|
215
377
|
}
|
|
216
378
|
const client$1 = client.createClient({ baseURL: appConfig.baseURL });
|
|
217
|
-
const
|
|
379
|
+
const loginParams = { password };
|
|
380
|
+
if (email) {
|
|
381
|
+
loginParams.email = email;
|
|
382
|
+
} else if (username) {
|
|
383
|
+
loginParams.username = username;
|
|
384
|
+
}
|
|
385
|
+
const result = await client$1.auth.login(loginParams);
|
|
218
386
|
if (result.error) {
|
|
219
387
|
spinner.fail("Login failed");
|
|
220
388
|
console.error(chalk7__default.default.red(result.error.message));
|
|
@@ -225,29 +393,53 @@ async function login(appCode, options) {
|
|
|
225
393
|
spinner.fail("Login failed: No access token received");
|
|
226
394
|
process.exit(1);
|
|
227
395
|
}
|
|
396
|
+
const loggedInAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
397
|
+
const expiresAt = loginData.expiresIn ? new Date(Date.now() + loginData.expiresIn * 1e3).toISOString() : void 0;
|
|
398
|
+
const sessionUser = loginData.user ? {
|
|
399
|
+
uid: loginData.user.uid,
|
|
400
|
+
email: loginData.user.email || "",
|
|
401
|
+
name: loginData.user.displayName || loginData.user.username || void 0
|
|
402
|
+
} : void 0;
|
|
228
403
|
saveAuthSession(appCode, {
|
|
229
404
|
accessToken: loginData.accessToken,
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
loggedInAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
405
|
+
expiresAt,
|
|
406
|
+
user: sessionUser,
|
|
407
|
+
loggedInAt
|
|
234
408
|
});
|
|
235
409
|
spinner.succeed(`Login successful: ${appCode}`);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
410
|
+
renderOutput(
|
|
411
|
+
{
|
|
412
|
+
appCode,
|
|
413
|
+
baseURL: appConfig.baseURL,
|
|
414
|
+
user: loginData.user ?? null,
|
|
415
|
+
expiresAt: expiresAt ?? null,
|
|
416
|
+
loggedInAt
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
format: options.format,
|
|
420
|
+
pretty: () => {
|
|
421
|
+
console.log(
|
|
422
|
+
chalk7__default.default.green(
|
|
423
|
+
`
|
|
424
|
+
Welcome, ${loginData.user?.displayName || loginData.user?.email || loginData.user?.username || email}!`
|
|
425
|
+
)
|
|
426
|
+
);
|
|
427
|
+
console.log(chalk7__default.default.gray(`App: ${appCode}`));
|
|
428
|
+
console.log(chalk7__default.default.gray(`URL: ${appConfig.baseURL}`));
|
|
429
|
+
if (expiresAt) {
|
|
430
|
+
const expires = new Date(expiresAt);
|
|
431
|
+
console.log(chalk7__default.default.gray(`Session expires: ${expires.toLocaleString()}`));
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
);
|
|
244
436
|
} catch (error) {
|
|
245
437
|
spinner.fail("Login failed");
|
|
246
438
|
throw error;
|
|
247
439
|
}
|
|
248
440
|
}
|
|
249
|
-
async function logout(appCode) {
|
|
250
|
-
const spinner =
|
|
441
|
+
async function logout(appCode, options = {}) {
|
|
442
|
+
const spinner = createSpinner(`Logging out from ${appCode}...`, options.format);
|
|
251
443
|
try {
|
|
252
444
|
const appConfig = getAppConfig(appCode);
|
|
253
445
|
if (appConfig) {
|
|
@@ -264,13 +456,25 @@ async function logout(appCode) {
|
|
|
264
456
|
}
|
|
265
457
|
clearAuthSession(appCode);
|
|
266
458
|
spinner.succeed(`Logout successful: ${appCode}`);
|
|
459
|
+
renderOutput(
|
|
460
|
+
{
|
|
461
|
+
appCode,
|
|
462
|
+
loggedOut: true
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
format: options.format,
|
|
466
|
+
pretty: () => {
|
|
467
|
+
console.log(chalk7__default.default.green(`Logged out from ${appCode}`));
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
);
|
|
267
471
|
} catch (error) {
|
|
268
472
|
spinner.fail("Logout failed");
|
|
269
473
|
throw error;
|
|
270
474
|
}
|
|
271
475
|
}
|
|
272
|
-
async function getMe(getClient) {
|
|
273
|
-
const spinner =
|
|
476
|
+
async function getMe(getClient, options = {}) {
|
|
477
|
+
const spinner = createSpinner("Fetching user info...", options.format);
|
|
274
478
|
try {
|
|
275
479
|
const client = getClient();
|
|
276
480
|
const result = await client.auth.getMe();
|
|
@@ -281,160 +485,462 @@ async function getMe(getClient) {
|
|
|
281
485
|
}
|
|
282
486
|
spinner.succeed("User info retrieved");
|
|
283
487
|
const user = result.data;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
488
|
+
renderOutput(user, {
|
|
489
|
+
format: options.format,
|
|
490
|
+
pretty: () => {
|
|
491
|
+
console.log(chalk7__default.default.blue("\n\u{1F464} User Profile\n"));
|
|
492
|
+
console.log(` ${chalk7__default.default.bold("UID:")} ${user?.uid}`);
|
|
493
|
+
console.log(` ${chalk7__default.default.bold("Email:")} ${user?.email}`);
|
|
494
|
+
console.log(` ${chalk7__default.default.bold("Name:")} ${user?.displayName || user?.username || "N/A"}`);
|
|
495
|
+
console.log(` ${chalk7__default.default.bold("Status:")} ${user?.isActive ? "Active" : "Inactive"}`);
|
|
496
|
+
}
|
|
497
|
+
});
|
|
289
498
|
} catch (error) {
|
|
290
499
|
spinner.fail("Failed to fetch user info");
|
|
291
500
|
throw error;
|
|
292
501
|
}
|
|
293
502
|
}
|
|
503
|
+
function isPlainObject2(value) {
|
|
504
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
505
|
+
}
|
|
506
|
+
function resolveInputSource(input) {
|
|
507
|
+
if (!input.startsWith("@")) {
|
|
508
|
+
return input;
|
|
509
|
+
}
|
|
510
|
+
const filePath = input.slice(1);
|
|
511
|
+
if (!filePath) {
|
|
512
|
+
throw new Error("File path is required after '@'.");
|
|
513
|
+
}
|
|
514
|
+
return fs.readFileSync(filePath, "utf8");
|
|
515
|
+
}
|
|
516
|
+
function parseJsonInput(input, label) {
|
|
517
|
+
const source = resolveInputSource(input).trim();
|
|
518
|
+
if (!source) {
|
|
519
|
+
throw new Error(`${label} is required.`);
|
|
520
|
+
}
|
|
521
|
+
try {
|
|
522
|
+
return JSON.parse(source);
|
|
523
|
+
} catch (error) {
|
|
524
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
525
|
+
throw new Error(`Invalid ${label}: ${reason}`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
async function promptForJson(message, defaultValue) {
|
|
529
|
+
const { default: inquirer } = await import('inquirer');
|
|
530
|
+
const { jsonData } = await inquirer.prompt([
|
|
531
|
+
{
|
|
532
|
+
type: "editor",
|
|
533
|
+
name: "jsonData",
|
|
534
|
+
message,
|
|
535
|
+
default: defaultValue
|
|
536
|
+
}
|
|
537
|
+
]);
|
|
538
|
+
return jsonData;
|
|
539
|
+
}
|
|
540
|
+
async function loadJsonObjectInput(input, label, promptMessage) {
|
|
541
|
+
const source = input ?? await promptForJson(promptMessage, "{}");
|
|
542
|
+
const value = parseJsonInput(source, label);
|
|
543
|
+
if (!isPlainObject2(value)) {
|
|
544
|
+
throw new Error(`${label} must be a JSON object.`);
|
|
545
|
+
}
|
|
546
|
+
return value;
|
|
547
|
+
}
|
|
548
|
+
async function loadJsonArrayInput(input, label, promptMessage) {
|
|
549
|
+
const source = input ?? await promptForJson(promptMessage, "[]");
|
|
550
|
+
const value = parseJsonInput(source, label);
|
|
551
|
+
if (!Array.isArray(value)) {
|
|
552
|
+
throw new Error(`${label} must be a JSON array.`);
|
|
553
|
+
}
|
|
554
|
+
return value;
|
|
555
|
+
}
|
|
556
|
+
function loadOptionalJsonObjectInput(input, label) {
|
|
557
|
+
if (!input) {
|
|
558
|
+
return {};
|
|
559
|
+
}
|
|
560
|
+
const value = parseJsonInput(input, label);
|
|
561
|
+
if (!isPlainObject2(value)) {
|
|
562
|
+
throw new Error(`${label} must be a JSON object.`);
|
|
563
|
+
}
|
|
564
|
+
return value;
|
|
565
|
+
}
|
|
566
|
+
function parseCommaSeparatedValues(value) {
|
|
567
|
+
if (!value) {
|
|
568
|
+
return void 0;
|
|
569
|
+
}
|
|
570
|
+
const values = value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
571
|
+
return values.length > 0 ? values : void 0;
|
|
572
|
+
}
|
|
573
|
+
function validateBulkUpdateItems(items) {
|
|
574
|
+
return items.map((item, index) => {
|
|
575
|
+
if (!isPlainObject2(item)) {
|
|
576
|
+
throw new Error(`Bulk update item at index ${index} must be a JSON object.`);
|
|
577
|
+
}
|
|
578
|
+
if (typeof item.id !== "string" && typeof item.id !== "number") {
|
|
579
|
+
throw new Error(`Bulk update item at index ${index} must include an 'id'.`);
|
|
580
|
+
}
|
|
581
|
+
return item;
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
function parseIdsInput(input) {
|
|
585
|
+
const source = resolveInputSource(input).trim();
|
|
586
|
+
if (!source) {
|
|
587
|
+
throw new Error("IDs are required.");
|
|
588
|
+
}
|
|
589
|
+
if (source.startsWith("[")) {
|
|
590
|
+
const value = parseJsonInput(input, "IDs");
|
|
591
|
+
if (!Array.isArray(value)) {
|
|
592
|
+
throw new Error("IDs must be a JSON array.");
|
|
593
|
+
}
|
|
594
|
+
return value.map((id, index) => {
|
|
595
|
+
if (typeof id !== "string" && typeof id !== "number") {
|
|
596
|
+
throw new Error(`ID at index ${index} must be a string or number.`);
|
|
597
|
+
}
|
|
598
|
+
return id;
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
const ids = source.split(/[,\n]/).map((id) => id.trim()).filter(Boolean);
|
|
602
|
+
if (ids.length === 0) {
|
|
603
|
+
throw new Error("IDs are required.");
|
|
604
|
+
}
|
|
605
|
+
return ids;
|
|
606
|
+
}
|
|
607
|
+
async function loadIdsInput(input) {
|
|
608
|
+
if (input) {
|
|
609
|
+
return parseIdsInput(input);
|
|
610
|
+
}
|
|
611
|
+
const { default: inquirer } = await import('inquirer');
|
|
612
|
+
const { ids } = await inquirer.prompt([
|
|
613
|
+
{
|
|
614
|
+
type: "input",
|
|
615
|
+
name: "ids",
|
|
616
|
+
message: "Enter IDs (comma-separated or JSON array):"
|
|
617
|
+
}
|
|
618
|
+
]);
|
|
619
|
+
return parseIdsInput(ids);
|
|
620
|
+
}
|
|
621
|
+
function exitWithCommandError(spinner, failureMessage, error) {
|
|
622
|
+
spinner.fail(failureMessage);
|
|
623
|
+
const details = error instanceof Error ? error.message : String(error);
|
|
624
|
+
if (details) {
|
|
625
|
+
console.error(chalk7__default.default.red(details));
|
|
626
|
+
}
|
|
627
|
+
process.exit(1);
|
|
628
|
+
}
|
|
629
|
+
function buildListQueryParams(options) {
|
|
630
|
+
const params = loadOptionalJsonObjectInput(options.query, "query params");
|
|
631
|
+
const fields = parseCommaSeparatedValues(options.fields);
|
|
632
|
+
const relations = parseCommaSeparatedValues(options.relations);
|
|
633
|
+
const keywordFields = parseCommaSeparatedValues(options.keywordFields);
|
|
634
|
+
if (keywordFields && !options.keyword) {
|
|
635
|
+
throw new Error("--keyword-fields requires --keyword.");
|
|
636
|
+
}
|
|
637
|
+
if (options.orderDir && !options.orderBy) {
|
|
638
|
+
throw new Error("--order-dir requires --order-by.");
|
|
639
|
+
}
|
|
640
|
+
if (options.orders && (options.orderBy || options.orderDir)) {
|
|
641
|
+
throw new Error("--orders cannot be used together with --order-by or --order-dir.");
|
|
642
|
+
}
|
|
643
|
+
if (fields) {
|
|
644
|
+
params.__fields = fields;
|
|
645
|
+
}
|
|
646
|
+
if (relations) {
|
|
647
|
+
params.__relations = relations;
|
|
648
|
+
}
|
|
649
|
+
if (options.keyword) {
|
|
650
|
+
params.__keywords = keywordFields ? { fields: keywordFields, value: options.keyword } : options.keyword;
|
|
651
|
+
}
|
|
652
|
+
if (options.orderBy) {
|
|
653
|
+
params.orderBy = options.orderBy;
|
|
654
|
+
}
|
|
655
|
+
if (options.orderDir) {
|
|
656
|
+
params.orderDir = options.orderDir;
|
|
657
|
+
}
|
|
658
|
+
if (options.orders) {
|
|
659
|
+
params.__orders = options.orders;
|
|
660
|
+
}
|
|
661
|
+
if (options.filter) {
|
|
662
|
+
params.__filter = loadOptionalJsonObjectInput(options.filter, "filter");
|
|
663
|
+
}
|
|
664
|
+
if (options.limit !== void 0) {
|
|
665
|
+
params.limit = options.limit;
|
|
666
|
+
}
|
|
667
|
+
if (options.offset !== void 0) {
|
|
668
|
+
params.offset = options.offset;
|
|
669
|
+
}
|
|
670
|
+
return params;
|
|
671
|
+
}
|
|
294
672
|
async function listEntities(client, options) {
|
|
295
|
-
const spinner =
|
|
673
|
+
const spinner = createSpinner(`Fetching ${options.entity}...`, options.format);
|
|
296
674
|
try {
|
|
297
|
-
const
|
|
675
|
+
const entityClient = client.entity;
|
|
676
|
+
const query = buildListQueryParams(options);
|
|
677
|
+
const result = await entityClient.list(options.namespace, options.entity, {
|
|
678
|
+
...query,
|
|
298
679
|
page: options.page || 1,
|
|
299
|
-
|
|
680
|
+
perPage: options.pageSize || 10
|
|
300
681
|
});
|
|
301
682
|
if (result.error) {
|
|
302
683
|
spinner.fail("Failed to fetch entities");
|
|
303
684
|
console.error(chalk7__default.default.red(result.error.message));
|
|
304
685
|
process.exit(1);
|
|
305
686
|
}
|
|
306
|
-
spinner.
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
687
|
+
spinner.stop();
|
|
688
|
+
const listData = result.data;
|
|
689
|
+
let items = [];
|
|
690
|
+
let total = 0;
|
|
691
|
+
if (Array.isArray(listData)) {
|
|
692
|
+
items = listData;
|
|
693
|
+
total = items.length;
|
|
694
|
+
} else if (listData?.items) {
|
|
695
|
+
items = listData.items;
|
|
696
|
+
total = listData.total || items.length;
|
|
697
|
+
} else if (listData?.list) {
|
|
698
|
+
items = listData.list;
|
|
699
|
+
total = listData.total || items.length;
|
|
700
|
+
}
|
|
701
|
+
renderOutput(result.data, {
|
|
702
|
+
format: options.format,
|
|
703
|
+
pretty: () => {
|
|
704
|
+
console.log(chalk7__default.default.blue(`
|
|
705
|
+
\u{1F4E6} ${options.entity} in ${options.namespace}`));
|
|
706
|
+
console.log(chalk7__default.default.gray(`\u5171 ${total} \u6761\u8BB0\u5F55:
|
|
310
707
|
`));
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
708
|
+
if (items.length === 0) {
|
|
709
|
+
console.log(chalk7__default.default.gray(" \u6682\u65E0\u6570\u636E"));
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
const firstItem = items[0];
|
|
713
|
+
const keys = Object.keys(firstItem).slice(0, 8);
|
|
714
|
+
const widths = {};
|
|
715
|
+
keys.forEach((key) => {
|
|
716
|
+
const maxValueWidth = Math.max(
|
|
717
|
+
key.length,
|
|
718
|
+
...items.map((item) => {
|
|
719
|
+
const val = item[key];
|
|
720
|
+
if (val === null || val === void 0) return 4;
|
|
721
|
+
const str = typeof val === "object" ? JSON.stringify(val) : String(val);
|
|
722
|
+
return str.length;
|
|
723
|
+
})
|
|
724
|
+
);
|
|
725
|
+
widths[key] = Math.min(maxValueWidth + 2, 30);
|
|
726
|
+
});
|
|
727
|
+
const headerLine = keys.map((key) => {
|
|
728
|
+
const width = widths[key] ?? 0;
|
|
729
|
+
return chalk7__default.default.bold(key.slice(0, width).padEnd(width));
|
|
730
|
+
}).join("\u2502");
|
|
731
|
+
console.log(" " + headerLine);
|
|
732
|
+
console.log(" " + keys.map((key) => "\u2500".repeat(widths[key] ?? 0)).join("\u253C"));
|
|
733
|
+
for (const item of items) {
|
|
734
|
+
const rowLine = keys.map((key) => {
|
|
735
|
+
const width = widths[key] ?? 0;
|
|
736
|
+
let val = item[key];
|
|
737
|
+
if (val === null || val === void 0) val = "null";
|
|
738
|
+
const str = typeof val === "object" ? JSON.stringify(val).slice(0, width - 2) : String(val).slice(0, width - 2);
|
|
739
|
+
return str.padEnd(width);
|
|
740
|
+
}).join("\u2502");
|
|
741
|
+
console.log(" " + rowLine);
|
|
742
|
+
}
|
|
743
|
+
console.log();
|
|
744
|
+
if (items.length < total) {
|
|
745
|
+
console.log(chalk7__default.default.gray(` ... \u8FD8\u6709 ${total - items.length} \u6761\u8BB0\u5F55`));
|
|
319
746
|
}
|
|
320
747
|
}
|
|
321
|
-
|
|
322
|
-
console.log(` ${chalk7__default.default.gray("...")}`);
|
|
323
|
-
}
|
|
324
|
-
console.log();
|
|
325
|
-
}
|
|
326
|
-
if (items.length > 10) {
|
|
327
|
-
console.log(chalk7__default.default.gray(` ... and ${items.length - 10} more`));
|
|
328
|
-
}
|
|
748
|
+
});
|
|
329
749
|
} catch (error) {
|
|
330
|
-
spinner
|
|
331
|
-
throw error;
|
|
750
|
+
exitWithCommandError(spinner, "Failed to fetch entities", error);
|
|
332
751
|
}
|
|
333
752
|
}
|
|
334
753
|
async function getEntity(client, options) {
|
|
335
|
-
const spinner =
|
|
754
|
+
const spinner = createSpinner(`Fetching ${options.entity}...`, options.format);
|
|
336
755
|
try {
|
|
337
|
-
const
|
|
756
|
+
const entityClient = client.entity;
|
|
757
|
+
const result = await entityClient.get(options.namespace, options.entity, options.id);
|
|
338
758
|
if (result.error) {
|
|
339
759
|
spinner.fail("Failed to fetch entity");
|
|
340
760
|
console.error(chalk7__default.default.red(result.error.message));
|
|
341
761
|
process.exit(1);
|
|
342
762
|
}
|
|
343
763
|
spinner.succeed("Entity retrieved");
|
|
344
|
-
|
|
764
|
+
renderOutput(result.data, {
|
|
765
|
+
format: options.format,
|
|
766
|
+
pretty: () => {
|
|
767
|
+
console.log(chalk7__default.default.blue(`
|
|
345
768
|
\u{1F4C4} ${options.entity}
|
|
346
769
|
`));
|
|
347
|
-
|
|
770
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
771
|
+
}
|
|
772
|
+
});
|
|
348
773
|
} catch (error) {
|
|
349
|
-
spinner
|
|
350
|
-
throw error;
|
|
774
|
+
exitWithCommandError(spinner, "Failed to fetch entity", error);
|
|
351
775
|
}
|
|
352
776
|
}
|
|
353
777
|
async function createEntity(client, options) {
|
|
354
|
-
const spinner =
|
|
778
|
+
const spinner = createSpinner(`Creating ${options.entity}...`, options.format);
|
|
355
779
|
try {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
} else {
|
|
360
|
-
const { default: inquirer } = await import('inquirer');
|
|
361
|
-
const { jsonData } = await inquirer.prompt([
|
|
362
|
-
{
|
|
363
|
-
type: "editor",
|
|
364
|
-
name: "jsonData",
|
|
365
|
-
message: "Enter JSON data:",
|
|
366
|
-
default: "{}"
|
|
367
|
-
}
|
|
368
|
-
]);
|
|
369
|
-
data = JSON.parse(jsonData);
|
|
370
|
-
}
|
|
371
|
-
const result = await client.entity.create(options.namespace, options.entity, data);
|
|
780
|
+
const entityClient = client.entity;
|
|
781
|
+
const data = await loadJsonObjectInput(options.data, "entity data", "Enter JSON data:");
|
|
782
|
+
const result = await entityClient.create(options.namespace, options.entity, data);
|
|
372
783
|
if (result.error) {
|
|
373
784
|
spinner.fail("Failed to create entity");
|
|
374
785
|
console.error(chalk7__default.default.red(result.error.message));
|
|
375
786
|
process.exit(1);
|
|
376
787
|
}
|
|
377
788
|
spinner.succeed("Entity created");
|
|
378
|
-
|
|
379
|
-
|
|
789
|
+
renderOutput(result.data, {
|
|
790
|
+
format: options.format,
|
|
791
|
+
pretty: () => {
|
|
792
|
+
console.log(chalk7__default.default.green("\nCreated entity:"));
|
|
793
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
794
|
+
}
|
|
795
|
+
});
|
|
380
796
|
} catch (error) {
|
|
381
|
-
spinner
|
|
382
|
-
throw error;
|
|
797
|
+
exitWithCommandError(spinner, "Failed to create entity", error);
|
|
383
798
|
}
|
|
384
799
|
}
|
|
385
800
|
async function updateEntity(client, options) {
|
|
386
|
-
const spinner =
|
|
801
|
+
const spinner = createSpinner(`Updating ${options.entity}...`, options.format);
|
|
387
802
|
try {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
} else {
|
|
392
|
-
const { default: inquirer } = await import('inquirer');
|
|
393
|
-
const { jsonData } = await inquirer.prompt([
|
|
394
|
-
{
|
|
395
|
-
type: "editor",
|
|
396
|
-
name: "jsonData",
|
|
397
|
-
message: "Enter JSON data:",
|
|
398
|
-
default: "{}"
|
|
399
|
-
}
|
|
400
|
-
]);
|
|
401
|
-
data = JSON.parse(jsonData);
|
|
402
|
-
}
|
|
403
|
-
const result = await client.entity.update(options.namespace, options.entity, options.id, data);
|
|
803
|
+
const entityClient = client.entity;
|
|
804
|
+
const data = await loadJsonObjectInput(options.data, "entity data", "Enter JSON data:");
|
|
805
|
+
const result = await entityClient.update(options.namespace, options.entity, options.id, data);
|
|
404
806
|
if (result.error) {
|
|
405
807
|
spinner.fail("Failed to update entity");
|
|
406
808
|
console.error(chalk7__default.default.red(result.error.message));
|
|
407
809
|
process.exit(1);
|
|
408
810
|
}
|
|
409
811
|
spinner.succeed("Entity updated");
|
|
410
|
-
|
|
411
|
-
|
|
812
|
+
renderOutput(result.data, {
|
|
813
|
+
format: options.format,
|
|
814
|
+
pretty: () => {
|
|
815
|
+
console.log(chalk7__default.default.green("\nUpdated entity:"));
|
|
816
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
817
|
+
}
|
|
818
|
+
});
|
|
412
819
|
} catch (error) {
|
|
413
|
-
spinner
|
|
414
|
-
throw error;
|
|
820
|
+
exitWithCommandError(spinner, "Failed to update entity", error);
|
|
415
821
|
}
|
|
416
822
|
}
|
|
417
823
|
async function deleteEntity(client, options) {
|
|
418
|
-
const spinner =
|
|
824
|
+
const spinner = createSpinner(`Deleting ${options.entity}...`, options.format);
|
|
419
825
|
try {
|
|
420
|
-
const
|
|
826
|
+
const entityClient = client.entity;
|
|
827
|
+
const result = await entityClient.delete(options.namespace, options.entity, options.id);
|
|
421
828
|
if (result.error) {
|
|
422
829
|
spinner.fail("Failed to delete entity");
|
|
423
830
|
console.error(chalk7__default.default.red(result.error.message));
|
|
424
831
|
process.exit(1);
|
|
425
832
|
}
|
|
426
833
|
spinner.succeed("Entity deleted");
|
|
427
|
-
|
|
834
|
+
renderOutput(
|
|
835
|
+
{
|
|
836
|
+
namespace: options.namespace,
|
|
837
|
+
entity: options.entity,
|
|
838
|
+
id: options.id,
|
|
839
|
+
deleted: true
|
|
840
|
+
},
|
|
841
|
+
{
|
|
842
|
+
format: options.format,
|
|
843
|
+
pretty: () => {
|
|
844
|
+
console.log(chalk7__default.default.green(`
|
|
428
845
|
Deleted ${options.entity} with ID: ${options.id}`));
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
);
|
|
429
849
|
} catch (error) {
|
|
430
|
-
spinner
|
|
431
|
-
|
|
850
|
+
exitWithCommandError(spinner, "Failed to delete entity", error);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
async function listEntityOptions(client, options) {
|
|
854
|
+
const spinner = createSpinner(`Fetching ${options.entity} options...`, options.format);
|
|
855
|
+
try {
|
|
856
|
+
const entityClient = client.entity;
|
|
857
|
+
const fields = parseCommaSeparatedValues(options.fields);
|
|
858
|
+
const result = await entityClient.options(options.namespace, options.entity, fields);
|
|
859
|
+
if (result.error) {
|
|
860
|
+
spinner.fail("Failed to fetch entity options");
|
|
861
|
+
console.error(chalk7__default.default.red(result.error.message));
|
|
862
|
+
process.exit(1);
|
|
863
|
+
}
|
|
864
|
+
spinner.succeed(`Found ${result.data?.length || 0} options`);
|
|
865
|
+
renderOutput(result.data || [], {
|
|
866
|
+
format: options.format,
|
|
867
|
+
pretty: () => {
|
|
868
|
+
console.log(chalk7__default.default.blue(`
|
|
869
|
+
\u{1F9FE} ${options.entity} options
|
|
870
|
+
`));
|
|
871
|
+
console.log(JSON.stringify(result.data || [], null, 2));
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
} catch (error) {
|
|
875
|
+
exitWithCommandError(spinner, "Failed to fetch entity options", error);
|
|
432
876
|
}
|
|
433
877
|
}
|
|
434
|
-
async function
|
|
435
|
-
const spinner =
|
|
878
|
+
async function bulkUpdateEntities(client, options) {
|
|
879
|
+
const spinner = createSpinner(`Bulk updating ${options.entity}...`, options.format);
|
|
436
880
|
try {
|
|
437
|
-
const
|
|
881
|
+
const entityClient = client.entity;
|
|
882
|
+
const rawItems = await loadJsonArrayInput(
|
|
883
|
+
options.items,
|
|
884
|
+
"bulk update items",
|
|
885
|
+
"Enter JSON array of items:"
|
|
886
|
+
);
|
|
887
|
+
const items = validateBulkUpdateItems(rawItems);
|
|
888
|
+
const result = await entityClient.bulkUpdate(options.namespace, options.entity, items);
|
|
889
|
+
if (result.error) {
|
|
890
|
+
spinner.fail("Failed to bulk update entities");
|
|
891
|
+
console.error(chalk7__default.default.red(result.error.message));
|
|
892
|
+
process.exit(1);
|
|
893
|
+
}
|
|
894
|
+
spinner.succeed(`Updated ${items.length} entities`);
|
|
895
|
+
renderOutput(result.data, {
|
|
896
|
+
format: options.format,
|
|
897
|
+
pretty: () => {
|
|
898
|
+
console.log(chalk7__default.default.green(`
|
|
899
|
+
Bulk updated ${items.length} ${options.entity} records:`));
|
|
900
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
901
|
+
}
|
|
902
|
+
});
|
|
903
|
+
} catch (error) {
|
|
904
|
+
exitWithCommandError(spinner, "Failed to bulk update entities", error);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
async function bulkDeleteEntities(client, options) {
|
|
908
|
+
const spinner = createSpinner(`Bulk deleting ${options.entity}...`, options.format);
|
|
909
|
+
try {
|
|
910
|
+
const entityClient = client.entity;
|
|
911
|
+
const ids = await loadIdsInput(options.ids);
|
|
912
|
+
const result = await entityClient.bulkDelete(options.namespace, options.entity, ids);
|
|
913
|
+
if (result.error) {
|
|
914
|
+
spinner.fail("Failed to bulk delete entities");
|
|
915
|
+
console.error(chalk7__default.default.red(result.error.message));
|
|
916
|
+
process.exit(1);
|
|
917
|
+
}
|
|
918
|
+
spinner.succeed(`Deleted ${ids.length} entities`);
|
|
919
|
+
renderOutput(
|
|
920
|
+
{
|
|
921
|
+
namespace: options.namespace,
|
|
922
|
+
entity: options.entity,
|
|
923
|
+
ids,
|
|
924
|
+
deleted: true,
|
|
925
|
+
count: ids.length
|
|
926
|
+
},
|
|
927
|
+
{
|
|
928
|
+
format: options.format,
|
|
929
|
+
pretty: () => {
|
|
930
|
+
console.log(chalk7__default.default.green(`
|
|
931
|
+
Deleted ${ids.length} ${options.entity} records.`));
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
);
|
|
935
|
+
} catch (error) {
|
|
936
|
+
exitWithCommandError(spinner, "Failed to bulk delete entities", error);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
async function listProcesses(client, options = {}) {
|
|
940
|
+
const spinner = createSpinner("Fetching process definitions...", options.format);
|
|
941
|
+
try {
|
|
942
|
+
const bpmClient = client.bpm;
|
|
943
|
+
const result = await bpmClient.getProcessDefinitions();
|
|
438
944
|
if (result.error) {
|
|
439
945
|
spinner.fail("Failed to fetch processes");
|
|
440
946
|
console.error(chalk7__default.default.red(result.error.message));
|
|
@@ -442,23 +948,29 @@ async function listProcesses(client) {
|
|
|
442
948
|
}
|
|
443
949
|
spinner.succeed(`Found ${result.data?.length || 0} process definitions`);
|
|
444
950
|
const processes = result.data || [];
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
951
|
+
renderOutput(processes, {
|
|
952
|
+
format: options.format,
|
|
953
|
+
pretty: () => {
|
|
954
|
+
console.log(chalk7__default.default.blue("\n\u{1F4CA} Process Definitions\n"));
|
|
955
|
+
for (const proc of processes) {
|
|
956
|
+
console.log(` ${chalk7__default.default.green("\u2022")} ${chalk7__default.default.bold(proc.key)}`);
|
|
957
|
+
console.log(` ${chalk7__default.default.gray("Name:")} ${proc.name || "N/A"}`);
|
|
958
|
+
console.log(` ${chalk7__default.default.gray("Version:")} ${proc.version || "N/A"}`);
|
|
959
|
+
console.log();
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
});
|
|
452
963
|
} catch (error) {
|
|
453
964
|
spinner.fail("Failed to fetch processes");
|
|
454
965
|
throw error;
|
|
455
966
|
}
|
|
456
967
|
}
|
|
457
968
|
async function startProcess(client, options) {
|
|
458
|
-
const spinner =
|
|
969
|
+
const spinner = createSpinner(`Starting process: ${options.key}...`, options.format);
|
|
459
970
|
try {
|
|
971
|
+
const bpmClient = client.bpm;
|
|
460
972
|
const variables = options.variables ? JSON.parse(options.variables) : {};
|
|
461
|
-
const result = await
|
|
973
|
+
const result = await bpmClient.startProcess({
|
|
462
974
|
processKey: options.key,
|
|
463
975
|
variables
|
|
464
976
|
});
|
|
@@ -468,24 +980,30 @@ async function startProcess(client, options) {
|
|
|
468
980
|
process.exit(1);
|
|
469
981
|
}
|
|
470
982
|
spinner.succeed("Process started");
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
983
|
+
renderOutput(result.data, {
|
|
984
|
+
format: options.format,
|
|
985
|
+
pretty: () => {
|
|
986
|
+
console.log(chalk7__default.default.green("\nProcess Instance:"));
|
|
987
|
+
console.log(` ${chalk7__default.default.bold("ID:")} ${result.data?.id}`);
|
|
988
|
+
console.log(` ${chalk7__default.default.bold("Definition ID:")} ${result.data?.definitionId}`);
|
|
989
|
+
console.log(` ${chalk7__default.default.bold("Business Key:")} ${result.data?.businessKey || "N/A"}`);
|
|
990
|
+
console.log(` ${chalk7__default.default.bold("Status:")} ${result.data?.suspended ? "Suspended" : "Active"}`);
|
|
991
|
+
}
|
|
992
|
+
});
|
|
476
993
|
} catch (error) {
|
|
477
994
|
spinner.fail("Failed to start process");
|
|
478
995
|
throw error;
|
|
479
996
|
}
|
|
480
997
|
}
|
|
481
998
|
async function listTasks(client, options) {
|
|
482
|
-
const spinner =
|
|
999
|
+
const spinner = createSpinner("Fetching tasks...", options.format);
|
|
483
1000
|
try {
|
|
1001
|
+
const bpmClient = client.bpm;
|
|
484
1002
|
const params = {};
|
|
485
1003
|
if (options.assignee) {
|
|
486
1004
|
params.assignee = options.assignee;
|
|
487
1005
|
}
|
|
488
|
-
const result = await
|
|
1006
|
+
const result = await bpmClient.getMyTasks(params);
|
|
489
1007
|
if (result.error) {
|
|
490
1008
|
spinner.fail("Failed to fetch tasks");
|
|
491
1009
|
console.error(chalk7__default.default.red(result.error.message));
|
|
@@ -493,39 +1011,58 @@ async function listTasks(client, options) {
|
|
|
493
1011
|
}
|
|
494
1012
|
spinner.succeed(`Found ${result.data?.length || 0} tasks`);
|
|
495
1013
|
const tasks = result.data || [];
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
}
|
|
1014
|
+
renderOutput(tasks, {
|
|
1015
|
+
format: options.format,
|
|
1016
|
+
pretty: () => {
|
|
1017
|
+
console.log(chalk7__default.default.blue("\n\u{1F4DD} Tasks\n"));
|
|
1018
|
+
for (const task of tasks) {
|
|
1019
|
+
console.log(` ${chalk7__default.default.green("\u2022")} ${chalk7__default.default.bold(task.name || task.id)}`);
|
|
1020
|
+
console.log(` ${chalk7__default.default.gray("ID:")} ${task.id}`);
|
|
1021
|
+
console.log(` ${chalk7__default.default.gray("Assignee:")} ${task.assignee || "Unassigned"}`);
|
|
1022
|
+
console.log(` ${chalk7__default.default.gray("Created:")} ${task.created || "N/A"}`);
|
|
1023
|
+
console.log();
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
});
|
|
504
1027
|
} catch (error) {
|
|
505
1028
|
spinner.fail("Failed to fetch tasks");
|
|
506
1029
|
throw error;
|
|
507
1030
|
}
|
|
508
1031
|
}
|
|
509
1032
|
async function completeTask(client, options) {
|
|
510
|
-
const spinner =
|
|
1033
|
+
const spinner = createSpinner(`Completing task: ${options.id}...`, options.format);
|
|
511
1034
|
try {
|
|
1035
|
+
const bpmClient = client.bpm;
|
|
512
1036
|
const variables = options.variables ? JSON.parse(options.variables) : {};
|
|
513
|
-
const result = await
|
|
1037
|
+
const result = await bpmClient.completeTask(options.id, { variables });
|
|
514
1038
|
if (result.error) {
|
|
515
1039
|
spinner.fail("Failed to complete task");
|
|
516
1040
|
console.error(chalk7__default.default.red(result.error.message));
|
|
517
1041
|
process.exit(1);
|
|
518
1042
|
}
|
|
519
1043
|
spinner.succeed("Task completed");
|
|
1044
|
+
renderOutput(
|
|
1045
|
+
{
|
|
1046
|
+
id: options.id,
|
|
1047
|
+
completed: true
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
format: options.format,
|
|
1051
|
+
pretty: () => {
|
|
1052
|
+
console.log(chalk7__default.default.green(`Completed task: ${options.id}`));
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
);
|
|
520
1056
|
} catch (error) {
|
|
521
1057
|
spinner.fail("Failed to complete task");
|
|
522
1058
|
throw error;
|
|
523
1059
|
}
|
|
524
1060
|
}
|
|
525
|
-
async function listWorkflows(client) {
|
|
526
|
-
const spinner =
|
|
1061
|
+
async function listWorkflows(client, options = {}) {
|
|
1062
|
+
const spinner = createSpinner("Fetching workflows...", options.format);
|
|
527
1063
|
try {
|
|
528
|
-
const
|
|
1064
|
+
const workflowClient = client.workflow;
|
|
1065
|
+
const result = await workflowClient.listWorkflows();
|
|
529
1066
|
if (result.error) {
|
|
530
1067
|
spinner.fail("Failed to fetch workflows");
|
|
531
1068
|
console.error(chalk7__default.default.red(result.error.message));
|
|
@@ -533,24 +1070,30 @@ async function listWorkflows(client) {
|
|
|
533
1070
|
}
|
|
534
1071
|
spinner.succeed(`Found ${result.data?.length || 0} workflows`);
|
|
535
1072
|
const workflows = result.data || [];
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}
|
|
1073
|
+
renderOutput(workflows, {
|
|
1074
|
+
format: options.format,
|
|
1075
|
+
pretty: () => {
|
|
1076
|
+
console.log(chalk7__default.default.blue("\n\u26A1 Workflows\n"));
|
|
1077
|
+
for (const workflow of workflows) {
|
|
1078
|
+
console.log(` ${chalk7__default.default.green("\u2022")} ${chalk7__default.default.bold(workflow.code || workflow.id)}`);
|
|
1079
|
+
console.log(` ${chalk7__default.default.gray("Name:")} ${workflow.name || "N/A"}`);
|
|
1080
|
+
console.log(` ${chalk7__default.default.gray("Description:")} ${workflow.description || "N/A"}`);
|
|
1081
|
+
console.log(` ${chalk7__default.default.gray("Status:")} ${workflow.status || "N/A"}`);
|
|
1082
|
+
console.log();
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
});
|
|
544
1086
|
} catch (error) {
|
|
545
1087
|
spinner.fail("Failed to fetch workflows");
|
|
546
1088
|
throw error;
|
|
547
1089
|
}
|
|
548
1090
|
}
|
|
549
1091
|
async function executeWorkflow(client, options) {
|
|
550
|
-
const spinner =
|
|
1092
|
+
const spinner = createSpinner(`Executing workflow: ${options.id}...`, options.format);
|
|
551
1093
|
try {
|
|
1094
|
+
const workflowClient = client.workflow;
|
|
552
1095
|
const input = options.input ? JSON.parse(options.input) : {};
|
|
553
|
-
const result = await
|
|
1096
|
+
const result = await workflowClient.execute(options.id, {
|
|
554
1097
|
input,
|
|
555
1098
|
version: options.version
|
|
556
1099
|
});
|
|
@@ -560,22 +1103,28 @@ async function executeWorkflow(client, options) {
|
|
|
560
1103
|
process.exit(1);
|
|
561
1104
|
}
|
|
562
1105
|
spinner.succeed("Workflow executed");
|
|
563
|
-
|
|
564
|
-
|
|
1106
|
+
renderOutput(result.data, {
|
|
1107
|
+
format: options.format,
|
|
1108
|
+
pretty: () => {
|
|
1109
|
+
console.log(chalk7__default.default.green("\nExecution Result:"));
|
|
1110
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
1111
|
+
}
|
|
1112
|
+
});
|
|
565
1113
|
} catch (error) {
|
|
566
1114
|
spinner.fail("Failed to execute workflow");
|
|
567
1115
|
throw error;
|
|
568
1116
|
}
|
|
569
1117
|
}
|
|
570
1118
|
async function uploadFile(client, options) {
|
|
571
|
-
const spinner =
|
|
1119
|
+
const spinner = createSpinner("Uploading file...", options.format);
|
|
572
1120
|
try {
|
|
1121
|
+
const s3Client = client.s3;
|
|
573
1122
|
const filePath = path.resolve(options.file);
|
|
574
1123
|
if (!fs.existsSync(filePath)) {
|
|
575
1124
|
spinner.fail(`File not found: ${options.file}`);
|
|
576
1125
|
process.exit(1);
|
|
577
1126
|
}
|
|
578
|
-
const result = await
|
|
1127
|
+
const result = await s3Client.uploadFile(filePath, {
|
|
579
1128
|
key: options.key,
|
|
580
1129
|
bucket: options.bucket,
|
|
581
1130
|
isPublic: options.public
|
|
@@ -586,19 +1135,25 @@ async function uploadFile(client, options) {
|
|
|
586
1135
|
process.exit(1);
|
|
587
1136
|
}
|
|
588
1137
|
spinner.succeed("Upload complete");
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
1138
|
+
renderOutput(result.data, {
|
|
1139
|
+
format: options.format,
|
|
1140
|
+
pretty: () => {
|
|
1141
|
+
console.log(chalk7__default.default.green("\nFile uploaded:"));
|
|
1142
|
+
console.log(` ${chalk7__default.default.bold("Key:")} ${result.data?.key}`);
|
|
1143
|
+
console.log(` ${chalk7__default.default.bold("URL:")} ${result.data?.url || "N/A"}`);
|
|
1144
|
+
console.log(` ${chalk7__default.default.bold("Bucket:")} ${result.data?.bucket || options.bucket || "default"}`);
|
|
1145
|
+
}
|
|
1146
|
+
});
|
|
593
1147
|
} catch (error) {
|
|
594
1148
|
spinner.fail("Upload failed");
|
|
595
1149
|
throw error;
|
|
596
1150
|
}
|
|
597
1151
|
}
|
|
598
1152
|
async function listFiles(client, options) {
|
|
599
|
-
const spinner =
|
|
1153
|
+
const spinner = createSpinner("Fetching files...", options.format);
|
|
600
1154
|
try {
|
|
601
|
-
const
|
|
1155
|
+
const s3Client = client.s3;
|
|
1156
|
+
const result = await s3Client.listFiles({
|
|
602
1157
|
bucket: options.bucket,
|
|
603
1158
|
prefix: options.prefix,
|
|
604
1159
|
page: options.page || 1,
|
|
@@ -611,15 +1166,20 @@ async function listFiles(client, options) {
|
|
|
611
1166
|
}
|
|
612
1167
|
spinner.succeed(`Found ${result.data?.total || 0} files`);
|
|
613
1168
|
const files = result.data?.list || [];
|
|
614
|
-
|
|
1169
|
+
renderOutput(result.data, {
|
|
1170
|
+
format: options.format,
|
|
1171
|
+
pretty: () => {
|
|
1172
|
+
console.log(chalk7__default.default.blue(`
|
|
615
1173
|
\u{1F4C1} Files${options.bucket ? ` in ${options.bucket}` : ""}
|
|
616
1174
|
`));
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
1175
|
+
for (const file of files) {
|
|
1176
|
+
console.log(` ${chalk7__default.default.green("\u2022")} ${chalk7__default.default.bold(file.key)}`);
|
|
1177
|
+
console.log(` ${chalk7__default.default.gray("Size:")} ${formatBytes(file.size || 0)}`);
|
|
1178
|
+
console.log(` ${chalk7__default.default.gray("Modified:")} ${file.lastModified || "N/A"}`);
|
|
1179
|
+
console.log();
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
});
|
|
623
1183
|
} catch (error) {
|
|
624
1184
|
spinner.fail("Failed to fetch files");
|
|
625
1185
|
throw error;
|
|
@@ -658,7 +1218,14 @@ function getAppMcpConfigPath(appCode) {
|
|
|
658
1218
|
return `/openclaw/apps/${appCode}/mcp-config.yaml`;
|
|
659
1219
|
}
|
|
660
1220
|
async function initOpenClaw(options) {
|
|
661
|
-
const spinner =
|
|
1221
|
+
const spinner = createSpinner(`Initializing app: ${options.appCode}...`, options.format);
|
|
1222
|
+
const pretty = isPrettyOutput(options.format);
|
|
1223
|
+
const ossEndpoint = options.ossEndpoint || DEFAULT_OSS_ENDPOINT;
|
|
1224
|
+
let installedSkills = 0;
|
|
1225
|
+
let configuredMcpServers = 0;
|
|
1226
|
+
let skillsError = null;
|
|
1227
|
+
let mcpError = null;
|
|
1228
|
+
const openClawDetected = fs.existsSync(OPENCLAW_CONFIG_DIR);
|
|
662
1229
|
try {
|
|
663
1230
|
const existingConfig = getAppConfig(options.appCode);
|
|
664
1231
|
if (existingConfig && !options.force) {
|
|
@@ -667,29 +1234,45 @@ async function initOpenClaw(options) {
|
|
|
667
1234
|
console.log(chalk7__default.default.gray(`Current URL: ${existingConfig.baseURL}`));
|
|
668
1235
|
process.exit(1);
|
|
669
1236
|
}
|
|
670
|
-
if (!fs.existsSync(OPENCLAW_CONFIG_DIR)) {
|
|
671
|
-
spinner.fail("OpenClaw not detected");
|
|
672
|
-
console.log(chalk7__default.default.yellow("\n\u26A0\uFE0F Please install OpenClaw first:"));
|
|
673
|
-
console.log(chalk7__default.default.gray(" npm install -g openclaw"));
|
|
674
|
-
process.exit(1);
|
|
675
|
-
}
|
|
676
1237
|
addApp(options.appCode, {
|
|
677
1238
|
baseURL: options.baseURL,
|
|
678
|
-
ossEndpoint
|
|
1239
|
+
ossEndpoint,
|
|
679
1240
|
initializedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
680
1241
|
});
|
|
1242
|
+
if (!openClawDetected) {
|
|
1243
|
+
spinner.succeed(`App initialized: ${options.appCode}`);
|
|
1244
|
+
if (pretty) {
|
|
1245
|
+
console.log(chalk7__default.default.yellow("\n\u26A0\uFE0F OpenClaw not detected, skipping skill download"));
|
|
1246
|
+
console.log(chalk7__default.default.gray(" Install OpenClaw: npm install -g openclaw"));
|
|
1247
|
+
} else {
|
|
1248
|
+
renderOutput(
|
|
1249
|
+
{
|
|
1250
|
+
appCode: options.appCode,
|
|
1251
|
+
baseURL: options.baseURL,
|
|
1252
|
+
ossEndpoint,
|
|
1253
|
+
openClawDetected: false,
|
|
1254
|
+
installedSkills: 0,
|
|
1255
|
+
configuredMcpServers: 0
|
|
1256
|
+
},
|
|
1257
|
+
{ format: options.format }
|
|
1258
|
+
);
|
|
1259
|
+
}
|
|
1260
|
+
return;
|
|
1261
|
+
}
|
|
681
1262
|
spinner.succeed(`App initialized: ${options.appCode}`);
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
1263
|
+
if (pretty) {
|
|
1264
|
+
console.log(chalk7__default.default.blue("\n\u{1F4CB} Configuration:\n"));
|
|
1265
|
+
console.log(` App Code: ${chalk7__default.default.green(options.appCode)}`);
|
|
1266
|
+
console.log(` Base URL: ${chalk7__default.default.gray(options.baseURL)}`);
|
|
1267
|
+
console.log();
|
|
1268
|
+
}
|
|
687
1269
|
spinner.start("Downloading skills...");
|
|
688
1270
|
try {
|
|
689
1271
|
const skills = await downloadSkillManifest(ossEndpoint, options.appCode);
|
|
690
1272
|
if (skills.length === 0) {
|
|
691
1273
|
spinner.warn("No skills found");
|
|
692
1274
|
} else {
|
|
1275
|
+
installedSkills = skills.length;
|
|
693
1276
|
spinner.text = `Installing ${skills.length} skills...`;
|
|
694
1277
|
const appSkillsDir = path.join(OPENCLAW_SKILLS_DIR, options.appCode);
|
|
695
1278
|
if (options.force && fs.existsSync(appSkillsDir)) {
|
|
@@ -705,12 +1288,14 @@ async function initOpenClaw(options) {
|
|
|
705
1288
|
spinner.succeed(`Installed ${skills.length} skills`);
|
|
706
1289
|
}
|
|
707
1290
|
} catch (error) {
|
|
1291
|
+
skillsError = error instanceof Error ? error.message : String(error);
|
|
708
1292
|
spinner.warn("Skills download failed (optional)");
|
|
709
1293
|
}
|
|
710
1294
|
spinner.start("Configuring MCP servers...");
|
|
711
1295
|
try {
|
|
712
1296
|
const mcpServers = await downloadMcpConfig(ossEndpoint, options.appCode);
|
|
713
1297
|
if (Object.keys(mcpServers).length > 0) {
|
|
1298
|
+
configuredMcpServers = Object.keys(mcpServers).length;
|
|
714
1299
|
const openClawConfig = getOpenClawConfig();
|
|
715
1300
|
if (!openClawConfig.mcpServers) {
|
|
716
1301
|
openClawConfig.mcpServers = {};
|
|
@@ -724,23 +1309,48 @@ async function initOpenClaw(options) {
|
|
|
724
1309
|
spinner.succeed("No MCP servers to configure");
|
|
725
1310
|
}
|
|
726
1311
|
} catch (error) {
|
|
1312
|
+
mcpError = error instanceof Error ? error.message : String(error);
|
|
727
1313
|
spinner.warn("MCP configuration failed (optional)");
|
|
728
1314
|
}
|
|
729
|
-
console.log();
|
|
730
|
-
console.log(chalk7__default.default.green("\u2705 Initialization complete!"));
|
|
731
|
-
console.log();
|
|
732
|
-
console.log(`Next step: Login to your app`);
|
|
733
|
-
console.log(chalk7__default.default.gray(` amaster login --app ${options.appCode}`));
|
|
734
|
-
console.log();
|
|
735
1315
|
const apps = listApps();
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
1316
|
+
const configuredApps = apps.map((app) => {
|
|
1317
|
+
const config = getAppConfig(app);
|
|
1318
|
+
return {
|
|
1319
|
+
appCode: app,
|
|
1320
|
+
baseURL: config?.baseURL || null
|
|
1321
|
+
};
|
|
1322
|
+
});
|
|
1323
|
+
const summary = {
|
|
1324
|
+
appCode: options.appCode,
|
|
1325
|
+
baseURL: options.baseURL,
|
|
1326
|
+
ossEndpoint,
|
|
1327
|
+
openClawDetected: true,
|
|
1328
|
+
installedSkills,
|
|
1329
|
+
configuredMcpServers,
|
|
1330
|
+
configuredApps,
|
|
1331
|
+
warnings: {
|
|
1332
|
+
skills: skillsError,
|
|
1333
|
+
mcpServers: mcpError
|
|
741
1334
|
}
|
|
1335
|
+
};
|
|
1336
|
+
if (pretty) {
|
|
1337
|
+
console.log();
|
|
1338
|
+
console.log(chalk7__default.default.green("\u2705 Initialization complete!"));
|
|
742
1339
|
console.log();
|
|
1340
|
+
console.log(`Next step: Login to your app`);
|
|
1341
|
+
console.log(chalk7__default.default.gray(` amaster login --app ${options.appCode}`));
|
|
1342
|
+
console.log();
|
|
1343
|
+
if (apps.length > 1) {
|
|
1344
|
+
console.log(chalk7__default.default.blue("Configured apps:"));
|
|
1345
|
+
for (const app of apps) {
|
|
1346
|
+
const config = getAppConfig(app);
|
|
1347
|
+
console.log(` ${chalk7__default.default.gray("\u2022")} ${app} - ${config?.baseURL}`);
|
|
1348
|
+
}
|
|
1349
|
+
console.log();
|
|
1350
|
+
}
|
|
1351
|
+
return;
|
|
743
1352
|
}
|
|
1353
|
+
renderOutput(summary, { format: options.format });
|
|
744
1354
|
} catch (error) {
|
|
745
1355
|
spinner.fail("Initialization failed");
|
|
746
1356
|
throw error;
|
|
@@ -863,163 +1473,257 @@ function createAmasterClient(appCode) {
|
|
|
863
1473
|
process.exit(1);
|
|
864
1474
|
}
|
|
865
1475
|
if (shouldRefreshToken(appCode)) {
|
|
866
|
-
console.
|
|
1476
|
+
console.error(chalk7__default.default.yellow("\u26A0\uFE0F Session expiring soon. Please login again."));
|
|
867
1477
|
}
|
|
868
|
-
|
|
1478
|
+
const client$1 = client.createClient({
|
|
869
1479
|
baseURL: appConfig.baseURL,
|
|
870
1480
|
headers: {
|
|
871
1481
|
Authorization: `Bearer ${token}`
|
|
872
1482
|
},
|
|
873
1483
|
onUnauthorized: () => {
|
|
874
1484
|
console.error(chalk7__default.default.red("\n\u274C Session expired. Please login again."));
|
|
875
|
-
console.
|
|
1485
|
+
console.error(chalk7__default.default.yellow(`Run: amaster login --app ${appCode}`));
|
|
876
1486
|
process.exit(1);
|
|
877
1487
|
}
|
|
878
1488
|
});
|
|
1489
|
+
client$1.setAccessToken(token);
|
|
1490
|
+
return client$1;
|
|
879
1491
|
}
|
|
880
1492
|
var program = new commander.Command();
|
|
881
1493
|
program.name("amaster").description("CLI for Amaster SDK - Multi-app support for OpenClaw").version("1.0.0");
|
|
882
|
-
program.command("apps").description("List all configured apps").action(() => {
|
|
1494
|
+
program.command("apps").description("List all configured apps").addOption(createFormatOption()).action((options) => {
|
|
883
1495
|
const apps = listApps();
|
|
884
1496
|
const current = getCurrentApp();
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
console.log(
|
|
1497
|
+
const appSummaries = apps.map((appCode) => {
|
|
1498
|
+
const config = getAppConfig(appCode);
|
|
1499
|
+
return {
|
|
1500
|
+
appCode,
|
|
1501
|
+
baseURL: config?.baseURL || null,
|
|
1502
|
+
authenticated: isAuthenticated(appCode),
|
|
1503
|
+
current: appCode === current
|
|
1504
|
+
};
|
|
1505
|
+
});
|
|
1506
|
+
renderOutput(appSummaries, {
|
|
1507
|
+
format: options.format,
|
|
1508
|
+
pretty: () => {
|
|
1509
|
+
console.log(chalk7__default.default.blue("\n\u{1F4F1} Configured Apps\n"));
|
|
1510
|
+
if (appSummaries.length === 0) {
|
|
1511
|
+
console.log(chalk7__default.default.gray(" No apps configured"));
|
|
1512
|
+
console.log(chalk7__default.default.gray(" Run: amaster init --app-code <code> --url <url>"));
|
|
1513
|
+
} else {
|
|
1514
|
+
for (const app of appSummaries) {
|
|
1515
|
+
const prefix = app.current ? chalk7__default.default.green("\u2192 ") : " ";
|
|
1516
|
+
console.log(`${prefix}${chalk7__default.default.bold(app.appCode)}${app.current ? chalk7__default.default.green(" (current)") : ""}`);
|
|
1517
|
+
console.log(` ${chalk7__default.default.gray(app.baseURL || "No URL")}`);
|
|
1518
|
+
console.log(
|
|
1519
|
+
` ${app.authenticated ? chalk7__default.default.green("\u25CF Authenticated") : chalk7__default.default.yellow("\u25CB Not authenticated")}`
|
|
1520
|
+
);
|
|
1521
|
+
console.log();
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
898
1524
|
console.log();
|
|
899
1525
|
}
|
|
900
|
-
}
|
|
901
|
-
console.log();
|
|
1526
|
+
});
|
|
902
1527
|
});
|
|
903
|
-
program.command("use <app-code>").description("Set the default app for subsequent commands").action((appCode) => {
|
|
1528
|
+
program.command("use <app-code>").description("Set the default app for subsequent commands").addOption(createFormatOption()).action((appCode, options) => {
|
|
904
1529
|
if (setCurrentApp(appCode)) {
|
|
905
|
-
|
|
1530
|
+
renderOutput(
|
|
1531
|
+
{
|
|
1532
|
+
appCode,
|
|
1533
|
+
current: true
|
|
1534
|
+
},
|
|
1535
|
+
{
|
|
1536
|
+
format: options.format,
|
|
1537
|
+
pretty: () => {
|
|
1538
|
+
console.log(chalk7__default.default.green(`\u2705 Now using app: ${appCode}`));
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
);
|
|
906
1542
|
} else {
|
|
907
1543
|
console.error(chalk7__default.default.red(`\u274C App not found: ${appCode}`));
|
|
908
1544
|
process.exit(1);
|
|
909
1545
|
}
|
|
910
1546
|
});
|
|
911
|
-
program.command("init").description("Initialize an app for OpenClaw integration").requiredOption("--app-code <code>", "Application code (e.g., fhv94bto1)").requiredOption("--url <url>", "Base URL (e.g., https://fhv94bto1.helige.cn)").option("--api-key <key>", "API Key for OSS access").option("--oss-endpoint <endpoint>", "OSS endpoint").action(async (options) => {
|
|
1547
|
+
program.command("init").description("Initialize an app for OpenClaw integration").requiredOption("--app-code <code>", "Application code (e.g., fhv94bto1)").requiredOption("--url <url>", "Base URL (e.g., https://fhv94bto1.helige.cn)").option("--api-key <key>", "API Key for OSS access").option("--oss-endpoint <endpoint>", "OSS endpoint").option("--force", "Reinitialize an existing app").addOption(createFormatOption()).action(async (options) => {
|
|
912
1548
|
await initOpenClaw({
|
|
913
1549
|
appCode: options.appCode,
|
|
914
1550
|
baseURL: options.url,
|
|
915
1551
|
apiKey: options.apiKey,
|
|
916
|
-
ossEndpoint: options.ossEndpoint
|
|
1552
|
+
ossEndpoint: options.ossEndpoint,
|
|
1553
|
+
force: options.force,
|
|
1554
|
+
format: options.format
|
|
917
1555
|
});
|
|
918
1556
|
});
|
|
919
|
-
program.command("login").description("Authenticate with an app").option("--app <app-code>", "App code (uses default if not specified)").option("-e, --email <email>", "Email address").option("-p, --password <password>", "Password").action(async (options) => {
|
|
1557
|
+
program.command("login").description("Authenticate with an app").option("--app <app-code>", "App code (uses default if not specified)").option("-u, --username <username>", "Username").option("-e, --email <email>", "Email address").option("-p, --password <password>", "Password").addOption(createFormatOption()).action(async (options) => {
|
|
920
1558
|
const appCode = resolveAppCode(options.app);
|
|
921
|
-
await login(appCode, {
|
|
1559
|
+
await login(appCode, {
|
|
1560
|
+
username: options.username,
|
|
1561
|
+
email: options.email,
|
|
1562
|
+
password: options.password,
|
|
1563
|
+
format: options.format
|
|
1564
|
+
});
|
|
922
1565
|
});
|
|
923
|
-
program.command("logout").description("Logout from an app").option("--app <app-code>", "App code (uses default if not specified)").action(async (options) => {
|
|
1566
|
+
program.command("logout").description("Logout from an app").option("--app <app-code>", "App code (uses default if not specified)").addOption(createFormatOption()).action(async (options) => {
|
|
924
1567
|
const appCode = resolveAppCode(options.app);
|
|
925
|
-
await logout(appCode);
|
|
1568
|
+
await logout(appCode, { format: options.format });
|
|
926
1569
|
});
|
|
927
|
-
program.command("whoami").description("Show current user information").option("--app <app-code>", "App code (uses default if not specified)").action(async (options) => {
|
|
1570
|
+
program.command("whoami").description("Show current user information").option("--app <app-code>", "App code (uses default if not specified)").addOption(createFormatOption()).action(async (options) => {
|
|
928
1571
|
const appCode = resolveAppCode(options.app);
|
|
929
|
-
await getMe(() => createAmasterClient(appCode));
|
|
1572
|
+
await getMe(() => createAmasterClient(appCode), { format: options.format });
|
|
930
1573
|
});
|
|
931
1574
|
var entityCmd = program.command("entity").description("Manage entities");
|
|
932
|
-
entityCmd.command("list <namespace> <entity>").description("List entities").option("--app <app-code>", "App code (uses default if not specified)").option("--page <page>", "Page number", "1").option("--page-size <size>", "Page size", "10").action(async (namespace, entityName, options) => {
|
|
1575
|
+
entityCmd.command("list <namespace> <entity>").description("List entities").option("--app <app-code>", "App code (uses default if not specified)").option("--page <page>", "Page number", "1").option("--page-size <size>", "Page size", "10").option("-f, --fields <fields>", "Comma-separated fields to return").option("-r, --relations <relations>", "Comma-separated relations to load").option("-k, --keyword <keyword>", "Keyword to search").option("--keyword-fields <fields>", "Comma-separated fields for keyword search").option("--order-by <field>", "Field to sort by").addOption(new commander.Option("--order-dir <dir>", "Sort direction").choices(["asc", "desc"])).option("--orders <orders>", "Multi-order expression, e.g. created_at:desc,name:asc").option("--filter <json>", "Advanced __filter JSON or @file").option("--limit <limit>", "Limit number of records").option("--offset <offset>", "Offset number of records").option("-q, --query <json>", "Additional EntityQueryParams as JSON or @file").addOption(createFormatOption()).action(async (namespace, entityName, options) => {
|
|
933
1576
|
const appCode = resolveAppCode(options.app);
|
|
934
1577
|
await listEntities(createAmasterClient(appCode), {
|
|
935
1578
|
namespace,
|
|
936
1579
|
entity: entityName,
|
|
937
1580
|
page: parseInt(options.page),
|
|
938
|
-
pageSize: parseInt(options.pageSize)
|
|
1581
|
+
pageSize: parseInt(options.pageSize),
|
|
1582
|
+
fields: options.fields,
|
|
1583
|
+
relations: options.relations,
|
|
1584
|
+
keyword: options.keyword,
|
|
1585
|
+
keywordFields: options.keywordFields,
|
|
1586
|
+
orderBy: options.orderBy,
|
|
1587
|
+
orderDir: options.orderDir,
|
|
1588
|
+
orders: options.orders,
|
|
1589
|
+
filter: options.filter,
|
|
1590
|
+
limit: options.limit ? parseInt(options.limit) : void 0,
|
|
1591
|
+
offset: options.offset ? parseInt(options.offset) : void 0,
|
|
1592
|
+
query: options.query,
|
|
1593
|
+
format: options.format
|
|
939
1594
|
});
|
|
940
1595
|
});
|
|
941
|
-
entityCmd.command("get <namespace> <entity> <id>").description("Get entity by ID").option("--app <app-code>", "App code (uses default if not specified)").action(async (namespace, entityName, id, options) => {
|
|
1596
|
+
entityCmd.command("get <namespace> <entity> <id>").description("Get entity by ID").option("--app <app-code>", "App code (uses default if not specified)").addOption(createFormatOption()).action(async (namespace, entityName, id, options) => {
|
|
942
1597
|
const appCode = resolveAppCode(options.app);
|
|
943
|
-
await getEntity(createAmasterClient(appCode), {
|
|
1598
|
+
await getEntity(createAmasterClient(appCode), {
|
|
1599
|
+
namespace,
|
|
1600
|
+
entity: entityName,
|
|
1601
|
+
id,
|
|
1602
|
+
format: options.format
|
|
1603
|
+
});
|
|
944
1604
|
});
|
|
945
|
-
entityCmd.command("create <namespace> <entity>").description("Create new entity").option("--app <app-code>", "App code (uses default if not specified)").option("-d, --data <json>", "Entity data as JSON").action(async (namespace, entityName, options) => {
|
|
1605
|
+
entityCmd.command("create <namespace> <entity>").description("Create new entity").option("--app <app-code>", "App code (uses default if not specified)").option("-d, --data <json>", "Entity data as JSON or @file").addOption(createFormatOption()).action(async (namespace, entityName, options) => {
|
|
946
1606
|
const appCode = resolveAppCode(options.app);
|
|
947
1607
|
await createEntity(createAmasterClient(appCode), {
|
|
948
1608
|
namespace,
|
|
949
1609
|
entity: entityName,
|
|
950
|
-
data: options.data
|
|
1610
|
+
data: options.data,
|
|
1611
|
+
format: options.format
|
|
951
1612
|
});
|
|
952
1613
|
});
|
|
953
|
-
entityCmd.command("update <namespace> <entity> <id>").description("Update entity").option("--app <app-code>", "App code (uses default if not specified)").option("-d, --data <json>", "Entity data as JSON").action(async (namespace, entityName, id, options) => {
|
|
1614
|
+
entityCmd.command("update <namespace> <entity> <id>").description("Update entity").option("--app <app-code>", "App code (uses default if not specified)").option("-d, --data <json>", "Entity data as JSON or @file").addOption(createFormatOption()).action(async (namespace, entityName, id, options) => {
|
|
954
1615
|
const appCode = resolveAppCode(options.app);
|
|
955
1616
|
await updateEntity(createAmasterClient(appCode), {
|
|
956
1617
|
namespace,
|
|
957
1618
|
entity: entityName,
|
|
958
1619
|
id,
|
|
959
|
-
data: options.data
|
|
1620
|
+
data: options.data,
|
|
1621
|
+
format: options.format
|
|
960
1622
|
});
|
|
961
1623
|
});
|
|
962
|
-
entityCmd.command("delete <namespace> <entity> <id>").description("Delete entity").option("--app <app-code>", "App code (uses default if not specified)").action(async (namespace, entityName, id, options) => {
|
|
1624
|
+
entityCmd.command("delete <namespace> <entity> <id>").description("Delete entity").option("--app <app-code>", "App code (uses default if not specified)").addOption(createFormatOption()).action(async (namespace, entityName, id, options) => {
|
|
963
1625
|
const appCode = resolveAppCode(options.app);
|
|
964
1626
|
await deleteEntity(createAmasterClient(appCode), {
|
|
965
1627
|
namespace,
|
|
966
1628
|
entity: entityName,
|
|
967
|
-
id
|
|
1629
|
+
id,
|
|
1630
|
+
format: options.format
|
|
1631
|
+
});
|
|
1632
|
+
});
|
|
1633
|
+
entityCmd.command("options <namespace> <entity>").description("List entity options").option("--app <app-code>", "App code (uses default if not specified)").option("-f, --fields <fields>", "Comma-separated fields to return").addOption(createFormatOption()).action(async (namespace, entityName, options) => {
|
|
1634
|
+
const appCode = resolveAppCode(options.app);
|
|
1635
|
+
await listEntityOptions(createAmasterClient(appCode), {
|
|
1636
|
+
namespace,
|
|
1637
|
+
entity: entityName,
|
|
1638
|
+
fields: options.fields,
|
|
1639
|
+
format: options.format
|
|
1640
|
+
});
|
|
1641
|
+
});
|
|
1642
|
+
entityCmd.command("bulk-update <namespace> <entity>").description("Bulk update entities").option("--app <app-code>", "App code (uses default if not specified)").option("-i, --items <json>", "Items array as JSON or @file").addOption(createFormatOption()).action(async (namespace, entityName, options) => {
|
|
1643
|
+
const appCode = resolveAppCode(options.app);
|
|
1644
|
+
await bulkUpdateEntities(createAmasterClient(appCode), {
|
|
1645
|
+
namespace,
|
|
1646
|
+
entity: entityName,
|
|
1647
|
+
items: options.items,
|
|
1648
|
+
format: options.format
|
|
1649
|
+
});
|
|
1650
|
+
});
|
|
1651
|
+
entityCmd.command("bulk-delete <namespace> <entity>").description("Bulk delete entities").option("--app <app-code>", "App code (uses default if not specified)").option("--ids <ids>", "Comma-separated IDs, JSON array, or @file").addOption(createFormatOption()).action(async (namespace, entityName, options) => {
|
|
1652
|
+
const appCode = resolveAppCode(options.app);
|
|
1653
|
+
await bulkDeleteEntities(createAmasterClient(appCode), {
|
|
1654
|
+
namespace,
|
|
1655
|
+
entity: entityName,
|
|
1656
|
+
ids: options.ids,
|
|
1657
|
+
format: options.format
|
|
968
1658
|
});
|
|
969
1659
|
});
|
|
970
1660
|
var bpmCmd = program.command("bpm").description("Manage BPM processes and tasks");
|
|
971
|
-
bpmCmd.command("processes").description("List process definitions").option("--app <app-code>", "App code (uses default if not specified)").action(async (options) => {
|
|
1661
|
+
bpmCmd.command("processes").description("List process definitions").option("--app <app-code>", "App code (uses default if not specified)").addOption(createFormatOption()).action(async (options) => {
|
|
972
1662
|
const appCode = resolveAppCode(options.app);
|
|
973
|
-
await listProcesses(createAmasterClient(appCode));
|
|
1663
|
+
await listProcesses(createAmasterClient(appCode), { format: options.format });
|
|
974
1664
|
});
|
|
975
|
-
bpmCmd.command("start <key>").description("Start a process instance").option("--app <app-code>", "App code (uses default if not specified)").option("-v, --variables <json>", "Process variables as JSON").action(async (key, options) => {
|
|
1665
|
+
bpmCmd.command("start <key>").description("Start a process instance").option("--app <app-code>", "App code (uses default if not specified)").option("-v, --variables <json>", "Process variables as JSON").addOption(createFormatOption()).action(async (key, options) => {
|
|
976
1666
|
const appCode = resolveAppCode(options.app);
|
|
977
1667
|
await startProcess(createAmasterClient(appCode), {
|
|
978
1668
|
key,
|
|
979
|
-
variables: options.variables
|
|
1669
|
+
variables: options.variables,
|
|
1670
|
+
format: options.format
|
|
980
1671
|
});
|
|
981
1672
|
});
|
|
982
|
-
bpmCmd.command("tasks").description("List tasks").option("--app <app-code>", "App code (uses default if not specified)").option("-a, --assignee <assignee>", "Filter by assignee").action(async (options) => {
|
|
1673
|
+
bpmCmd.command("tasks").description("List tasks").option("--app <app-code>", "App code (uses default if not specified)").option("-a, --assignee <assignee>", "Filter by assignee").addOption(createFormatOption()).action(async (options) => {
|
|
983
1674
|
const appCode = resolveAppCode(options.app);
|
|
984
|
-
await listTasks(createAmasterClient(appCode), {
|
|
1675
|
+
await listTasks(createAmasterClient(appCode), {
|
|
1676
|
+
assignee: options.assignee,
|
|
1677
|
+
format: options.format
|
|
1678
|
+
});
|
|
985
1679
|
});
|
|
986
|
-
bpmCmd.command("complete <id>").description("Complete a task").option("--app <app-code>", "App code (uses default if not specified)").option("-v, --variables <json>", "Task variables as JSON").action(async (id, options) => {
|
|
1680
|
+
bpmCmd.command("complete <id>").description("Complete a task").option("--app <app-code>", "App code (uses default if not specified)").option("-v, --variables <json>", "Task variables as JSON").addOption(createFormatOption()).action(async (id, options) => {
|
|
987
1681
|
const appCode = resolveAppCode(options.app);
|
|
988
1682
|
await completeTask(createAmasterClient(appCode), {
|
|
989
1683
|
id,
|
|
990
|
-
variables: options.variables
|
|
1684
|
+
variables: options.variables,
|
|
1685
|
+
format: options.format
|
|
991
1686
|
});
|
|
992
1687
|
});
|
|
993
1688
|
var workflowCmd = program.command("workflow").description("Manage workflows");
|
|
994
|
-
workflowCmd.command("list").description("List workflows").option("--app <app-code>", "App code (uses default if not specified)").action(async (options) => {
|
|
1689
|
+
workflowCmd.command("list").description("List workflows").option("--app <app-code>", "App code (uses default if not specified)").addOption(createFormatOption()).action(async (options) => {
|
|
995
1690
|
const appCode = resolveAppCode(options.app);
|
|
996
|
-
await listWorkflows(createAmasterClient(appCode));
|
|
1691
|
+
await listWorkflows(createAmasterClient(appCode), { format: options.format });
|
|
997
1692
|
});
|
|
998
|
-
workflowCmd.command("execute <id>").description("Execute a workflow").option("--app <app-code>", "App code (uses default if not specified)").option("-i, --input <json>", "Workflow input as JSON").action(async (id, options) => {
|
|
1693
|
+
workflowCmd.command("execute <id>").description("Execute a workflow").option("--app <app-code>", "App code (uses default if not specified)").option("-i, --input <json>", "Workflow input as JSON").addOption(createFormatOption()).action(async (id, options) => {
|
|
999
1694
|
const appCode = resolveAppCode(options.app);
|
|
1000
1695
|
await executeWorkflow(createAmasterClient(appCode), {
|
|
1001
1696
|
id,
|
|
1002
|
-
input: options.input
|
|
1697
|
+
input: options.input,
|
|
1698
|
+
format: options.format
|
|
1003
1699
|
});
|
|
1004
1700
|
});
|
|
1005
1701
|
var s3Cmd = program.command("s3").description("Manage S3 files");
|
|
1006
|
-
s3Cmd.command("list").description("List files").option("--app <app-code>", "App code (uses default if not specified)").option("-b, --bucket <bucket>", "Bucket name").action(async (options) => {
|
|
1702
|
+
s3Cmd.command("list").description("List files").option("--app <app-code>", "App code (uses default if not specified)").option("-b, --bucket <bucket>", "Bucket name").addOption(createFormatOption()).action(async (options) => {
|
|
1007
1703
|
const appCode = resolveAppCode(options.app);
|
|
1008
1704
|
await listFiles(createAmasterClient(appCode), {
|
|
1009
|
-
bucket: options.bucket
|
|
1705
|
+
bucket: options.bucket,
|
|
1706
|
+
format: options.format
|
|
1010
1707
|
});
|
|
1011
1708
|
});
|
|
1012
|
-
s3Cmd.command("upload <file>").description("Upload a file").option("--app <app-code>", "App code (uses default if not specified)").option("-b, --bucket <bucket>", "Bucket name").option("-k, --key <key>", "Object key").action(async (file, options) => {
|
|
1709
|
+
s3Cmd.command("upload <file>").description("Upload a file").option("--app <app-code>", "App code (uses default if not specified)").option("-b, --bucket <bucket>", "Bucket name").option("-k, --key <key>", "Object key").addOption(createFormatOption()).action(async (file, options) => {
|
|
1013
1710
|
const appCode = resolveAppCode(options.app);
|
|
1014
1711
|
await uploadFile(createAmasterClient(appCode), {
|
|
1015
1712
|
file,
|
|
1016
1713
|
bucket: options.bucket,
|
|
1017
|
-
key: options.key
|
|
1714
|
+
key: options.key,
|
|
1715
|
+
format: options.format
|
|
1018
1716
|
});
|
|
1019
1717
|
});
|
|
1020
1718
|
var isMainModule = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.cjs', document.baseURI).href)) === new URL(process.argv[1] || "", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.cjs', document.baseURI).href))).href || (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.cjs', document.baseURI).href)).endsWith(process.argv[1] || "") || process.argv[1]?.includes("cli.js") || false;
|
|
1021
1719
|
if (isMainModule) {
|
|
1022
|
-
program.
|
|
1720
|
+
program.parseAsync(process.argv).then(
|
|
1721
|
+
() => process.exit(0),
|
|
1722
|
+
(err) => {
|
|
1723
|
+
console.error(err);
|
|
1724
|
+
process.exit(1);
|
|
1725
|
+
}
|
|
1726
|
+
);
|
|
1023
1727
|
}
|
|
1024
1728
|
|
|
1025
1729
|
exports.createAmasterClient = createAmasterClient;
|