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