@cloudbase/cli 2.5.1-alpha.3 → 2.5.1-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -42,7 +42,9 @@ const events_1 = require("events");
42
42
  const commander_1 = require("commander");
43
43
  const yargs_parser_1 = __importDefault(require("yargs-parser"));
44
44
  const error_1 = require("../error");
45
+ const toolbox_1 = require("@cloudbase/toolbox");
45
46
  const utils_1 = require("../utils");
47
+ const auth_1 = require("../auth");
46
48
  const registrableCommands = [];
47
49
  const cmdMap = new Map();
48
50
  const defaultCmdDecoratorOpts = {
@@ -134,7 +136,7 @@ class Command extends events_1.EventEmitter {
134
136
  }
135
137
  }
136
138
  createProgram(instance, deprecate, newCmd) {
137
- const { cmd, desc, options, requiredEnvId = true, withoutAuth = false } = this.options;
139
+ const { cmd, desc, options, requiredEnvId = true, withoutAuth = false, autoRunLogin = false } = this.options;
138
140
  instance.storeOptionsAsProperties(false);
139
141
  options.forEach((option) => {
140
142
  const { hideHelp } = option;
@@ -161,7 +163,16 @@ class Command extends events_1.EventEmitter {
161
163
  loginState = (yield utils_1.authSupevisor.getLoginState());
162
164
  }
163
165
  if (!withoutAuth && !loginState) {
164
- throw new error_1.CloudBaseError('无有效身份信息,请使用 cloudbase login 登录');
166
+ if (autoRunLogin) {
167
+ console.log(chalk_1.default.bold.yellowBright('无有效身份信息,将自动为您打开授权页面。'));
168
+ yield (0, toolbox_1.execWithLoading)(() => (0, auth_1.login)(), {
169
+ startTip: '请在浏览器中打开的授权页面进行授权...',
170
+ successTip: '授权登录成功!'
171
+ });
172
+ }
173
+ else {
174
+ throw new error_1.CloudBaseError('无有效身份信息,请使用 cloudbase login 登录');
175
+ }
165
176
  }
166
177
  if (!envId && requiredEnvId) {
167
178
  throw new error_1.CloudBaseError('未识别到有效的环境 Id,请使用 cloudbaserc 配置文件进行操作或通过 -e 参数指定环境 Id');
@@ -70,6 +70,7 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
70
70
  const os_1 = __importDefault(require("os"));
71
71
  const path_1 = __importDefault(require("path"));
72
72
  const dts_1 = require("../../utils/dts");
73
+ const cals_1 = require("@cloudbase/cals");
73
74
  let lowcodeCli;
74
75
  if (process.argv.includes('lowcode')) {
75
76
  (0, utils_1.getLowcodeCli)().then((_) => (lowcodeCli = _));
@@ -335,7 +336,8 @@ let ModelTypeSync = class ModelTypeSync extends common_1.Command {
335
336
  }
336
337
  ],
337
338
  desc: '同步数据模型类型定义文件',
338
- requiredEnvId: true
339
+ requiredEnvId: true,
340
+ autoRunLogin: true
339
341
  };
340
342
  }
341
343
  execute(ctx, log, options) {
@@ -400,84 +402,239 @@ let TemplateSync = class TemplateSync extends common_1.Command {
400
402
  childCmd: 'sync',
401
403
  options: [
402
404
  {
403
- flags: '--envId <envId>',
404
- desc: '环境 ID'
405
+ flags: '--source <source>',
406
+ desc: '来源: 1-野鹤 2-自建模板'
405
407
  }
406
408
  ],
407
409
  desc: '同步官方模板应用内容',
408
- requiredEnvId: true
410
+ requiredEnvId: false
409
411
  };
410
412
  }
411
413
  execute(ctx, log, options) {
414
+ var _a;
412
415
  return __awaiter(this, void 0, void 0, function* () {
413
416
  log.info('同步中...');
417
+ const SourceType = {
418
+ YEHE: '1',
419
+ CUSTOM_MODULE: '2'
420
+ };
421
+ const source = Object.values(SourceType).includes(options.source)
422
+ ? options.source
423
+ : SourceType.YEHE;
414
424
  const envId = 'lowcode-5g5llxbq5bc9299e';
425
+ const cloudService = yield getCloudServiceInstance(ctx);
426
+ const files = [];
427
+ const limit = 50;
428
+ let count = 1;
415
429
  const fileDir = path_1.default.resolve(os_1.default.tmpdir(), 'templates');
416
430
  yield fs_extra_1.default.ensureDir(fileDir);
417
431
  yield fs_extra_1.default.rmdir(fileDir, { recursive: true });
418
432
  yield fs_extra_1.default.ensureDir(fileDir);
419
- const cloudService = yield getCloudServiceInstance(ctx);
420
- let total = Infinity;
421
- let currentTotal = 0;
422
- const limit = 50;
423
- const files = [];
424
- let count = 1;
425
- while (currentTotal < total) {
426
- const solutionListResult = yield cloudService.lowcode.request('DescribeSolutionList', {
427
- Limit: limit,
428
- Offset: currentTotal,
429
- KeyWords: '',
430
- EnvId: envId,
431
- TypeList: ['SELFBUILD', 'TPLEXPORT']
432
- });
433
- const solutionList = solutionListResult.SolutionInfoList;
434
- const handledSolutionList = yield Promise.all(solutionList.map((item) => __awaiter(this, void 0, void 0, function* () {
435
- const solution = yield cloudService.lowcode.request('DescribeSolution', {
433
+ if (source === SourceType.YEHE) {
434
+ const templates = yield fs_extra_1.default.readJSON('data.json', 'utf8');
435
+ console.log('模板总数:', templates.length);
436
+ while (templates.length > 0) {
437
+ const handledSolutionList = yield Promise.all(templates.splice(0, limit).map((item) => __awaiter(this, void 0, void 0, function* () {
438
+ if (item.appIds.length > 0) {
439
+ const apps = yield getAppsContent(item.appIds);
440
+ return {
441
+ name: item.templateName,
442
+ templateId: item.templateId,
443
+ status: item.status,
444
+ apps
445
+ };
446
+ }
447
+ else {
448
+ return null;
449
+ }
450
+ })));
451
+ const filePath = path_1.default.resolve(fileDir, `templates_${count}.json`);
452
+ yield fs_extra_1.default.writeFile(filePath, JSON.stringify(handledSolutionList, null, 2), 'utf8');
453
+ files.push(filePath);
454
+ count += 1;
455
+ }
456
+ }
457
+ else if (source === SourceType.CUSTOM_MODULE) {
458
+ let total = Infinity;
459
+ let currentTotal = 0;
460
+ while (currentTotal < total) {
461
+ const solutionListResult = yield cloudService.lowcode.request('DescribeSolutionList', {
462
+ Limit: limit,
463
+ Offset: currentTotal,
464
+ KeyWords: '',
436
465
  EnvId: envId,
437
- SolutionId: item.SolutionId
466
+ TypeList: ['SELFBUILD', 'TPLEXPORT']
438
467
  });
439
- if (solution.SolutionAppInfos.length > 0) {
440
- const appIds = solution.SolutionAppInfos.map((item) => item.AppId);
441
- const apps = yield Promise.all(appIds.map((appId) => __awaiter(this, void 0, void 0, function* () {
442
- var _a, _b, _c, _d, _e;
443
- try {
444
- let result = yield cloudService.lowcode.request('DescribeHistoryListByAppId', {
445
- WeAppId: appId,
446
- PageNum: 1,
447
- PageSize: 1
448
- });
449
- result = yield cloudService.lowcode.request('DescribeAppHistoryPreSignUrl', {
450
- HisIds: [(_c = (_b = (_a = result === null || result === void 0 ? void 0 : result.Data) === null || _a === void 0 ? void 0 : _a.List) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.Id],
451
- HttpMethod: 'get',
452
- WeAppsId: appId
453
- });
454
- result = yield (0, toolbox_1.fetch)((_e = (_d = result === null || result === void 0 ? void 0 : result.Data) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.UploadUrl);
455
- return { appId, content: result };
456
- }
457
- catch (e) {
458
- return { appId, error: e.message };
459
- }
460
- })));
461
- return {
462
- name: item.Name,
463
- solutionId: item.SolutionId,
464
- version: item.Version,
465
- apps
466
- };
468
+ const solutionList = solutionListResult.SolutionInfoList;
469
+ const handledSolutionList = yield Promise.all(solutionList.map((item) => __awaiter(this, void 0, void 0, function* () {
470
+ const solution = yield cloudService.lowcode.request('DescribeSolution', {
471
+ EnvId: envId,
472
+ SolutionId: item.SolutionId
473
+ });
474
+ if (solution.SolutionAppInfos.length > 0) {
475
+ const appIds = solution.SolutionAppInfos.map((item) => item.AppId);
476
+ const apps = yield getAppsContent(appIds);
477
+ return {
478
+ name: item.Name,
479
+ solutionId: item.SolutionId,
480
+ version: item.Version,
481
+ apps
482
+ };
483
+ }
484
+ else {
485
+ return null;
486
+ }
487
+ })));
488
+ const filePath = path_1.default.resolve(fileDir, `templates_${count}.json`);
489
+ yield fs_extra_1.default.writeFile(filePath, JSON.stringify(handledSolutionList, null, 2), 'utf8');
490
+ files.push(filePath);
491
+ total = solutionListResult.TotalCount;
492
+ currentTotal += limit;
493
+ count += 1;
494
+ }
495
+ }
496
+ log.success(`同步官方模板应用内容已完成. 文件路径:`);
497
+ log.success(files.join('\n'));
498
+ const appIdNameMap = {};
499
+ const appsPath = path_1.default.resolve(process.cwd(), 'apps');
500
+ try {
501
+ const items = yield fs_extra_1.default.readdir(appsPath);
502
+ const directories = [];
503
+ for (const item of items) {
504
+ const itemPath = path_1.default.join(appsPath, item);
505
+ const stats = yield fs_extra_1.default.stat(itemPath);
506
+ if (stats.isDirectory()) {
507
+ directories.push(item);
508
+ const appConfig = yield fs_extra_1.default.readJSON(path_1.default.resolve(itemPath, 'src', 'app-config.json'));
509
+ const appId = appConfig.id;
510
+ appIdNameMap[appId] = item;
511
+ }
512
+ }
513
+ }
514
+ catch (error) {
515
+ console.error('Error reading directory:', error);
516
+ }
517
+ for (let fileUrl of files) {
518
+ const items = yield fs_extra_1.default.readJSON(fileUrl);
519
+ for (let item of items) {
520
+ if (!item)
521
+ continue;
522
+ let done = false;
523
+ if (((_a = item === null || item === void 0 ? void 0 : item.apps) === null || _a === void 0 ? void 0 : _a.length) > 0) {
524
+ try {
525
+ yield Promise.all(item === null || item === void 0 ? void 0 : item.apps.map((app) => __awaiter(this, void 0, void 0, function* () {
526
+ var _b, _c;
527
+ if (app === null || app === void 0 ? void 0 : app.error) {
528
+ return null;
529
+ }
530
+ else {
531
+ if (appIdNameMap[app.appId]) {
532
+ app.name = appIdNameMap[app.appId];
533
+ }
534
+ else {
535
+ const result = yield (0, toolbox_1.fetch)('http://localhost:1234/v1/chat/completions', {
536
+ method: 'POST',
537
+ headers: {
538
+ 'Content-Type': 'application/json'
539
+ },
540
+ body: JSON.stringify({
541
+ model: 'TheBloke/Mistral-7B-Instruct-v0.2-GGUF',
542
+ messages: [
543
+ {
544
+ role: 'system',
545
+ content: '你是一个目录命名专家。目录名只包括小写字母,数字和下划线, 不能包含其它符号。\n正确的示例: community_deals_platform\n错误的示例: restaurant_company_website'
546
+ },
547
+ {
548
+ role: 'user',
549
+ content: `请为“${(_b = app === null || app === void 0 ? void 0 : app.content) === null || _b === void 0 ? void 0 : _b.label}”起一个目录名。请始终只返回一个目录名,其它不用返回`
550
+ }
551
+ ],
552
+ temperature: 1,
553
+ stream: false
554
+ }),
555
+ timeout: 30 * 60 * 1000
556
+ });
557
+ app.name = result.choices[0].message.content
558
+ .replace(/[\s\\]+/g, '')
559
+ .replace(/-/g, '_');
560
+ }
561
+ if (app.content) {
562
+ const calsAppData = app.content;
563
+ calsAppData.id = app.appId;
564
+ const { clientId, originHistoryId, mpAppId, uin } = app.extra;
565
+ calsAppData.extra.clientId = clientId;
566
+ calsAppData.extra.originHistoryId = `${originHistoryId}`;
567
+ calsAppData.extra.mpAppId = mpAppId;
568
+ calsAppData.extra.envId = envId;
569
+ calsAppData.extra.uin = uin;
570
+ calsAppData.extra.domain =
571
+ 'lowcode-5g5llxbq5bc9299e-1300677802.tcloudbaseapp.com';
572
+ calsAppData.extra.resourceAppId = '';
573
+ calsAppData.extra.endpointType = '';
574
+ const codeItems = (0, cals_1.calsToCode)(app.content, 'v0');
575
+ yield Promise.all(codeItems.map((codeItem) => __awaiter(this, void 0, void 0, function* () {
576
+ const codePath = path_1.default.resolve(appsPath, app.name, codeItem.path);
577
+ yield fs_extra_1.default.ensureFile(codePath);
578
+ yield fs_extra_1.default.writeFile(codePath, codeItem.code || '', 'utf8');
579
+ })));
580
+ console.log('写入成功:', app.appId, (_c = app === null || app === void 0 ? void 0 : app.content) === null || _c === void 0 ? void 0 : _c.label, app.name);
581
+ }
582
+ else {
583
+ console.error('写入异常:', app.appId, app.error);
584
+ }
585
+ }
586
+ })));
587
+ }
588
+ catch (e) {
589
+ console.error('异常:', item.templateId, e.message);
590
+ }
591
+ done = true;
467
592
  }
468
593
  else {
469
- return null;
594
+ done = true;
595
+ }
596
+ if (done) {
597
+ if (source === SourceType.YEHE) {
598
+ let templates = yield fs_extra_1.default.readJSON('data.json', 'utf8');
599
+ templates = templates.filter((tItem) => tItem.templateId !== item.templateId);
600
+ yield fs_extra_1.default.writeFile('data.json', JSON.stringify(templates, null, 2), 'utf8');
601
+ }
470
602
  }
471
- })));
472
- const filePath = path_1.default.resolve(fileDir, `templates_${count}.json`);
473
- yield fs_extra_1.default.writeFile(filePath, JSON.stringify(handledSolutionList, null, 2), 'utf8');
474
- files.push(filePath);
475
- total = solutionListResult.TotalCount;
476
- currentTotal += limit;
477
- count += 1;
603
+ }
604
+ yield fs_extra_1.default.writeFile(fileUrl, JSON.stringify(items, null, 2), 'utf8');
605
+ }
606
+ function getAppsContent(appIds) {
607
+ return __awaiter(this, void 0, void 0, function* () {
608
+ return yield Promise.all(appIds.map((appId) => __awaiter(this, void 0, void 0, function* () {
609
+ var _a, _b, _c;
610
+ try {
611
+ let result = yield cloudService.lowcode.request('DescribeAppDetail', {
612
+ WeAppId: appId
613
+ });
614
+ const { Title, LatestHistory, OwnerInfo, MpAppId, ClientId } = result.Data;
615
+ const label = Title;
616
+ const historyId = (_a = JSON.parse(LatestHistory)) === null || _a === void 0 ? void 0 : _a.id;
617
+ const extra = {
618
+ originHistoryId: historyId,
619
+ uin: OwnerInfo.Uin,
620
+ mpAppId: MpAppId,
621
+ clientId: ClientId
622
+ };
623
+ result = yield cloudService.lowcode.request('DescribeAppHistoryPreSignUrl', {
624
+ HisIds: [historyId],
625
+ HttpMethod: 'get',
626
+ WeAppsId: appId
627
+ });
628
+ result = yield (0, toolbox_1.fetch)((_c = (_b = result === null || result === void 0 ? void 0 : result.Data) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.UploadUrl);
629
+ result.label = label;
630
+ return { appId, content: result, extra };
631
+ }
632
+ catch (e) {
633
+ return { appId, error: e.message };
634
+ }
635
+ })));
636
+ });
478
637
  }
479
- log.success(`同步官方模板应用内容已完成. 文件路径:`);
480
- log.success(files.join('\n'));
481
638
  });
482
639
  }
483
640
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/cli",
3
- "version": "2.5.1-alpha.3",
3
+ "version": "2.5.1-alpha.5",
4
4
  "description": "cli tool for cloudbase",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -18,6 +18,7 @@ export interface ICommandOptions {
18
18
  desc: string;
19
19
  requiredEnvId?: boolean;
20
20
  withoutAuth?: boolean;
21
+ autoRunLogin?: boolean;
21
22
  }
22
23
  interface ICommandDecoratorOptions {
23
24
  supportPrivate: boolean | 'only';
@@ -76,6 +76,7 @@ export declare class ModelTypeSync extends Command {
76
76
  }[];
77
77
  desc: string;
78
78
  requiredEnvId: boolean;
79
+ autoRunLogin: boolean;
79
80
  };
80
81
  execute(ctx: ICommandContext, log: Logger, options: any): Promise<void>;
81
82
  }