@cloudbase/cli 2.4.0 → 2.5.0

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/bin/tcb.js CHANGED
@@ -14,6 +14,7 @@ const { CloudApiService } = require('@cloudbase/cloud-api')
14
14
  const { getCredentialWithoutCheck } = require('@cloudbase/toolbox')
15
15
  const { Confirm } = require('enquirer')
16
16
  const execa = require('execa')
17
+ const semver = require('semver')
17
18
 
18
19
  const pkg = require('../package.json')
19
20
  const store = require('../lib/utils/store')
@@ -22,15 +23,14 @@ const { getProxy } = require('../lib/utils/net')
22
23
  const { getCloudBaseConfig, getPrivateSettings } = require('../lib/utils/config')
23
24
  const { registerCommands } = require('../lib')
24
25
 
25
-
26
26
  const regionSupported = ['ap-shanghai', 'ap-beijing', 'ap-guangzhou']
27
27
  const regionSupportedMap = {
28
28
  'ap-shanghai': '上海',
29
29
  'ap-beijing': '北京',
30
30
  'ap-guangzhou': '广州',
31
- 'sh': '上海',
32
- 'bj': '北京',
33
- 'gz': '广州'
31
+ sh: '上海',
32
+ bj: '北京',
33
+ gz: '广州'
34
34
  }
35
35
 
36
36
  async function main() {
@@ -38,13 +38,36 @@ async function main() {
38
38
  const isBeta = pkg.version.indexOf('-') > -1
39
39
  process.CLI_VERSION = pkg.version
40
40
 
41
- const [major, minor] = process.versions.node.split('.').slice(0, 2)
41
+ const currentMajorVersion = +semver.major(process.version)
42
+
43
+ // 定义最小版本和推荐版本
44
+ const NODE_MIN_VERSION = 14
45
+ const NODE_RECOMMENDED_VERSIONS = [16, 18]
42
46
 
43
- // Node 版本检验提示
44
- if (Number(major) < 8 || (Number(major) === 8 && Number(minor) < 6)) {
45
- console.log(
47
+ // 检查当前版本是否满足最小版本要求
48
+ if (NODE_MIN_VERSION > currentMajorVersion) {
49
+ console.error(
46
50
  chalk.bold.red(
47
- '您的 Node 版本较低,CloudBase CLI 可能无法正常运行,请升级 Node 到 v8.6.0 以上!\n'
51
+ `当前 Node.js 版本为 v${currentMajorVersion}。请升级到至少 v${NODE_MIN_VERSION} 版本。`
52
+ )
53
+ )
54
+ console.warn(
55
+ chalk.bold.yellow(
56
+ `建议使用 ${NODE_RECOMMENDED_VERSIONS.map((item) => `v${item}`).join(
57
+ ' 或 '
58
+ )} 版本。`
59
+ )
60
+ )
61
+ process.exit(1)
62
+ }
63
+
64
+ // 检查当前版本是否在推荐版本列表中
65
+ if (!NODE_RECOMMENDED_VERSIONS.some((version) => currentMajorVersion === version)) {
66
+ console.warn(
67
+ chalk.bold.yellow(
68
+ `当前 Node.js 版本为 v${currentMajorVersion}。建议使用 ${NODE_RECOMMENDED_VERSIONS.map(
69
+ (item) => `v${item}`
70
+ ).join(' 或 ')} 版本。`
48
71
  )
49
72
  )
50
73
  }
@@ -67,17 +90,15 @@ async function main() {
67
90
  console.log(chalk.gray(`CloudBase Framework ${frameworkPkg.version}`))
68
91
  console.log(chalk.gray(`Weda ${wedaPkg.version}`))
69
92
 
70
-
71
- const yargsParsedResult = yargsParser(process.argv.slice(2));
72
- const config = await getCloudBaseConfig(yargsParsedResult.configFile);
73
- const privateSettings = getPrivateSettings(config);
93
+ const yargsParsedResult = yargsParser(process.argv.slice(2))
94
+ const config = await getCloudBaseConfig(yargsParsedResult.configFile)
95
+ const privateSettings = getPrivateSettings(config)
74
96
  if (privateSettings) {
75
97
  console.log(chalk.gray(`检测到私有化配置`))
76
98
  if (privateSettings.endpoints && privateSettings.endpoints.cliApi) {
77
99
  // 初始化 lowcode 服务cliapi入口
78
- process.env.CLOUDBASE_LOWCODE_CLOUDAPI_URL = privateSettings.endpoints.cliApi;
100
+ process.env.CLOUDBASE_LOWCODE_CLOUDAPI_URL = privateSettings.endpoints.cliApi
79
101
  }
80
-
81
102
  }
82
103
  // 注册命令
83
104
  await registerCommands()
@@ -106,7 +127,7 @@ async function main() {
106
127
  // HACK: 隐藏自动生成的 help 信息
107
128
  program.helpOption(false)
108
129
  }
109
- const isCommandEmpty = yargsParsedResult._.length === 0;
130
+ const isCommandEmpty = yargsParsedResult._.length === 0
110
131
 
111
132
  // -v 时输出的版本信息,设置时避免影响其他命令使用 -v
112
133
  if (isCommandEmpty) {
@@ -161,7 +182,9 @@ async function main() {
161
182
  try {
162
183
  program.parse(processArgv)
163
184
  } catch (e) {
164
- const errMsg = `${logSymbols.error} ${e.message || '参数异常,请检查您是否使用了正确的命令!'}`
185
+ const errMsg = `${logSymbols.error} ${
186
+ e.message || '参数异常,请检查您是否使用了正确的命令!'
187
+ }`
165
188
  console.log(errMsg)
166
189
  }
167
190
 
@@ -185,11 +208,13 @@ async function main() {
185
208
  // 多地域错误提示
186
209
  if (errMsg.includes('Environment') && errMsg.includes('not found')) {
187
210
  // 检查是否已经指定了 -r 或 --region 参数,如未指定则尝试获取地域信息
188
- const regionSpecified = processArgv.indexOf('-r') !== -1 || processArgv.indexOf('--region') !== -1
211
+ const regionSpecified =
212
+ processArgv.indexOf('-r') !== -1 || processArgv.indexOf('--region') !== -1
189
213
  const region = yargsParsedResult.r || yargsParsedResult.region
190
- const multiRegionErrMsg = `\n此环境可能不属于当前账号,或为非${regionSupportedMap[region] || '上海'}地域环境,如需切换地域请追加参数(例:-r gz),请检查环境归属,参考多地域使用方法:https://docs.cloudbase.net/cli-v1/region.html`
214
+ const multiRegionErrMsg = `\n此环境可能不属于当前账号,或为非${
215
+ regionSupportedMap[region] || '上海'
216
+ }地域环境,如需切换地域请追加参数(例:-r gz),请检查环境归属,参考多地域使用方法:https://docs.cloudbase.net/cli-v1/region.html`
191
217
  if (!regionSpecified) {
192
-
193
218
  // 从 -e 参数、--envId 参数和配置文件中获取环境 id
194
219
  const envId = yargsParsedResult.e || yargsParsedResult.envId || config.envId
195
220
 
@@ -215,7 +240,9 @@ async function main() {
215
240
  }
216
241
  // 重新执行命令
217
242
  const newArgvStr = processArgv.slice(2).join(' ')
218
- console.log(`\n${chalk.yellow.bold('正在重新执行命令:')} tcb ${newArgvStr}\n`)
243
+ console.log(
244
+ `\n${chalk.yellow.bold('正在重新执行命令:')} tcb ${newArgvStr}\n`
245
+ )
219
246
  await execa('tcb', processArgv.slice(2), {
220
247
  stdio: 'inherit'
221
248
  })
@@ -243,20 +270,23 @@ async function main() {
243
270
  }
244
271
 
245
272
  const isTokenExpired = (credential, gap = 120) =>
246
- credential.accessTokenExpired && Number(credential.accessTokenExpired) < Date.now() + gap * 1000
273
+ credential.accessTokenExpired &&
274
+ Number(credential.accessTokenExpired) < Date.now() + gap * 1000
247
275
 
248
276
  async function tryTellEnvRegion(envId) {
249
277
  // 依次调用不同地域的 API 接口查询环境信息
250
- const fetchedRegion = await Promise.all(regionSupported.map(async region => {
251
- const { EnvList = [] } = await fetchEnvInfoWithRegion(envId, region)
252
- if (EnvList.length !== 0 && EnvList.find(item => item.EnvId === envId)) {
253
- return res.EnvList[0].Region
254
- }
255
- return ''
256
- }))
278
+ const fetchedRegion = await Promise.all(
279
+ regionSupported.map(async (region) => {
280
+ const { EnvList = [] } = await fetchEnvInfoWithRegion(envId, region)
281
+ if (EnvList.length !== 0 && EnvList.find((item) => item.EnvId === envId)) {
282
+ return res.EnvList[0].Region
283
+ }
284
+ return ''
285
+ })
286
+ )
257
287
 
258
288
  let predictRegion = ''
259
- fetchedRegion.forEach(region => {
289
+ fetchedRegion.forEach((region) => {
260
290
  if (region) {
261
291
  predictRegion = region
262
292
  }
@@ -293,7 +323,7 @@ async function main() {
293
323
  region
294
324
  })
295
325
  const res = await tcbApi.request(apiName, {
296
- EnvId: envId,
326
+ EnvId: envId
297
327
  })
298
328
  return res
299
329
  }
@@ -316,7 +346,6 @@ async function main() {
316
346
  notifier.notify({
317
347
  isGlobal: true
318
348
  })
319
-
320
349
  }
321
350
 
322
351
  if (require.main === module) {
@@ -330,4 +359,4 @@ process.on('unhandledRejection', (err) => {
330
359
  console.log('unhandledRejection', err)
331
360
  })
332
361
 
333
- exports.main = main
362
+ exports.main = main
package/jest.config.js CHANGED
@@ -2,7 +2,7 @@ module.exports = {
2
2
  roots: ['<rootDir>/test'],
3
3
  globals: {
4
4
  'ts-jest': {
5
- tsConfig: 'tsconfig.test.json'
5
+ tsconfig: 'tsconfig.test.json'
6
6
  }
7
7
  },
8
8
  transform: {
@@ -11,7 +11,7 @@ module.exports = {
11
11
  transformIgnorePatterns: ['node_modules'],
12
12
  testEnvironment: 'node',
13
13
  // https://github.com/facebook/jest/issues/5164
14
- globalSetup: './test/global-setup-hook.js',
14
+ // globalSetup: './test/global-setup-hook.js',
15
15
  // globalTeardown: './test/global-teardown-hook.js',
16
16
  coverageReporters: ['json', 'lcov', 'clover', 'text-summary']
17
17
  }
@@ -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');
@@ -0,0 +1,395 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16
+ return new (P || (P = Promise))(function (resolve, reject) {
17
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
21
+ });
22
+ };
23
+ var __importDefault = (this && this.__importDefault) || function (mod) {
24
+ return (mod && mod.__esModule) ? mod : { "default": mod };
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.DbPushCommand = exports.DbPullCommand = exports.DbListCommand = void 0;
28
+ const path_1 = __importDefault(require("path"));
29
+ const common_1 = require("../common");
30
+ const error_1 = require("../../error");
31
+ const lodash_1 = require("lodash");
32
+ const db_1 = require("../../db");
33
+ const env_1 = require("../../env");
34
+ const decorators_1 = require("../../decorators");
35
+ const utils_1 = require("../../utils");
36
+ const inquirer_1 = __importDefault(require("inquirer"));
37
+ const fs_extra_1 = __importDefault(require("fs-extra"));
38
+ const dts_1 = require("../../utils/dts");
39
+ let DbListCommand = class DbListCommand extends common_1.Command {
40
+ get options() {
41
+ return {
42
+ cmd: 'db',
43
+ childCmd: 'list',
44
+ options: [
45
+ {
46
+ flags: '-e, --envId <envId>',
47
+ desc: '环境 Id'
48
+ },
49
+ ],
50
+ requiredEnvId: false,
51
+ autoRunLogin: true,
52
+ desc: '列出云端所有数据模型',
53
+ };
54
+ }
55
+ execute(envId, log) {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ const loading = (0, utils_1.loadingFactory)();
58
+ if (!envId) {
59
+ envId = yield selectEnv();
60
+ }
61
+ else {
62
+ log.info(`当前环境 Id:${envId}`);
63
+ }
64
+ if (!(yield fs_extra_1.default.pathExists('cloudbaserc.json'))) {
65
+ yield fs_extra_1.default.writeFile('cloudbaserc.json', JSON.stringify({
66
+ version: '2.0',
67
+ envId
68
+ }, null, 2), 'utf8');
69
+ }
70
+ loading.start('数据加载中...');
71
+ const data = yield (0, db_1.listModels)({ envId });
72
+ loading.stop();
73
+ const head = ['名称', '标识', '创建时间'];
74
+ const sortData = data.sort((prev, next) => {
75
+ if (prev.Alias > next.Alias) {
76
+ return 1;
77
+ }
78
+ if (prev.Alias < next.Alias) {
79
+ return -1;
80
+ }
81
+ return 0;
82
+ });
83
+ const tableData = sortData.map((item) => [
84
+ item.Title,
85
+ item.Name,
86
+ item.CreatedAt
87
+ ]);
88
+ (0, utils_1.printHorizontalTable)(head, tableData);
89
+ });
90
+ }
91
+ };
92
+ __decorate([
93
+ (0, decorators_1.InjectParams)(),
94
+ __param(0, (0, decorators_1.EnvId)()),
95
+ __param(1, (0, decorators_1.Log)()),
96
+ __metadata("design:type", Function),
97
+ __metadata("design:paramtypes", [Object, decorators_1.Logger]),
98
+ __metadata("design:returntype", Promise)
99
+ ], DbListCommand.prototype, "execute", null);
100
+ DbListCommand = __decorate([
101
+ (0, common_1.ICommand)()
102
+ ], DbListCommand);
103
+ exports.DbListCommand = DbListCommand;
104
+ let DbPullCommand = class DbPullCommand extends common_1.Command {
105
+ get options() {
106
+ return {
107
+ cmd: 'db',
108
+ childCmd: 'pull',
109
+ options: [
110
+ {
111
+ flags: '-e, --envId <envId>',
112
+ desc: '环境 Id'
113
+ },
114
+ {
115
+ flags: '-d, --dir <dir>',
116
+ desc: '本地存储数据库模型定义的目录,默认为 database-schemas'
117
+ },
118
+ {
119
+ flags: '-n, --name <name>',
120
+ desc: '要拉取的模型英文标识列表,可指定多个,使用逗号分隔.不指定的情况下默认会拉取所有模型'
121
+ }
122
+ ],
123
+ requiredEnvId: false,
124
+ autoRunLogin: true,
125
+ desc: '从云端拉取多个数据模型到本地',
126
+ };
127
+ }
128
+ execute(envId, params, log) {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ if (!(yield fs_extra_1.default.pathExists('tsconfig.json'))) {
131
+ yield fs_extra_1.default.writeFile('tsconfig.json', JSON.stringify({
132
+ compilerOptions: {
133
+ allowJs: true
134
+ }
135
+ }, null, 2), 'utf8');
136
+ }
137
+ else {
138
+ const config = yield fs_extra_1.default.readJson('tsconfig.json', 'utf8');
139
+ (0, lodash_1.set)(config, 'compilerOptions.allowJs', true);
140
+ yield fs_extra_1.default.writeFile('tsconfig.json', JSON.stringify(config, null, 2), 'utf8');
141
+ }
142
+ if (!envId) {
143
+ envId = yield selectEnv();
144
+ }
145
+ else {
146
+ log.info(`当前环境 Id:${envId}`);
147
+ }
148
+ if (!(yield fs_extra_1.default.pathExists('cloudbaserc.json'))) {
149
+ yield fs_extra_1.default.writeFile('cloudbaserc.json', JSON.stringify({
150
+ version: '2.0',
151
+ envId
152
+ }, null, 2), 'utf8');
153
+ }
154
+ let { name = '', dir } = params;
155
+ name = name.split(',').map(item => item.trim()).filter(item => item);
156
+ if (!name.length) {
157
+ name = yield selectModel(envId);
158
+ }
159
+ const data = yield (0, db_1.listModels)({
160
+ envId,
161
+ name
162
+ });
163
+ const dataModelList = data.map((item) => {
164
+ const schema = JSON.parse(item.Schema);
165
+ schema.title = item.Title;
166
+ return {
167
+ name: item.Name,
168
+ schema,
169
+ title: item.Title
170
+ };
171
+ });
172
+ if (!dir) {
173
+ dir = 'database-schemas';
174
+ if (!fs_extra_1.default.existsSync(dir)) {
175
+ fs_extra_1.default.mkdirSync(dir);
176
+ }
177
+ dataModelList.forEach((item) => {
178
+ const fileName = `${dir}/${item.name}.json`;
179
+ fs_extra_1.default.writeFileSync(fileName, JSON.stringify(item.schema, null, 4));
180
+ log.success(`同步数据模型成功。文件名称:${fileName}`);
181
+ });
182
+ }
183
+ const dts = yield (0, dts_1.generateDataModelDTS)(dataModelList);
184
+ const dtsFileName = 'cloud-models.d.ts';
185
+ yield fs_extra_1.default.writeFile(dtsFileName, dts);
186
+ log.success('同步数据模型类型定义文件成功,调用 SDK 时可支持智能字段提示。文件名称:' + dtsFileName);
187
+ });
188
+ }
189
+ };
190
+ __decorate([
191
+ (0, decorators_1.InjectParams)(),
192
+ __param(0, (0, decorators_1.EnvId)()),
193
+ __param(1, (0, decorators_1.ArgsParams)()),
194
+ __param(2, (0, decorators_1.Log)()),
195
+ __metadata("design:type", Function),
196
+ __metadata("design:paramtypes", [Object, Object, decorators_1.Logger]),
197
+ __metadata("design:returntype", Promise)
198
+ ], DbPullCommand.prototype, "execute", null);
199
+ DbPullCommand = __decorate([
200
+ (0, common_1.ICommand)()
201
+ ], DbPullCommand);
202
+ exports.DbPullCommand = DbPullCommand;
203
+ let DbPushCommand = class DbPushCommand extends common_1.Command {
204
+ get options() {
205
+ return {
206
+ cmd: 'db',
207
+ childCmd: 'push',
208
+ options: [
209
+ {
210
+ flags: '-e, --envId <envId>',
211
+ desc: '环境 Id'
212
+ },
213
+ {
214
+ flags: '-d, --dir <dir>',
215
+ desc: '本地存储数据库模型定义的目录,默认为 database-schemas'
216
+ },
217
+ {
218
+ flags: '-n, --name <name>',
219
+ desc: '要推送的模型名称列表,可指定多个,使用逗号分隔.不指定的情况下默认会推送本地目录下的所有数据模型'
220
+ }
221
+ ],
222
+ requiredEnvId: false,
223
+ autoRunLogin: true,
224
+ desc: '从云端拉取多个数据模型到本地',
225
+ };
226
+ }
227
+ execute(envId, params, log) {
228
+ return __awaiter(this, void 0, void 0, function* () {
229
+ if (!envId) {
230
+ envId = yield selectEnv();
231
+ }
232
+ else {
233
+ log.info(`使用环境 Id:${envId}`);
234
+ }
235
+ let { name = '', dir } = params;
236
+ name = name.split(',').map(item => item.trim()).filter(item => item);
237
+ if (!dir) {
238
+ dir = 'database-schemas';
239
+ if (!fs_extra_1.default.existsSync(dir)) {
240
+ throw new error_1.CloudBaseError(`目录 ${dir} 不存在,请指定正确的目录`);
241
+ }
242
+ }
243
+ if (!name.length) {
244
+ name = fs_extra_1.default.readdirSync(dir).map(item => item.replace('.json', ''));
245
+ }
246
+ if (!name.length) {
247
+ throw new error_1.CloudBaseError(`目录 ${dir} 中没有找到任何数据模型`);
248
+ }
249
+ const ids = [];
250
+ for (const modelName of name) {
251
+ log.info(`开始检查数据模型 ${modelName}`);
252
+ const modelPath = path_1.default.join(process.cwd(), dir, `${modelName}.json`);
253
+ const model = require(modelPath);
254
+ const existModel = yield (0, db_1.getModel)({
255
+ envId,
256
+ name: modelName
257
+ });
258
+ if (existModel) {
259
+ const confirm = yield inquirer_1.default.prompt([
260
+ {
261
+ type: 'confirm',
262
+ name: 'confirm',
263
+ message: `数据模型 ${modelName} 已存在,是否更新?`
264
+ }
265
+ ]);
266
+ if (!confirm.confirm) {
267
+ log.info(`跳过更新数据模型 ${modelName}`);
268
+ continue;
269
+ }
270
+ yield (0, db_1.updateModel)({
271
+ envId,
272
+ id: existModel.Id,
273
+ title: model.title || existModel.Title,
274
+ schema: model
275
+ });
276
+ ids.push(existModel.Id);
277
+ const link = (0, utils_1.genClickableLink)(`https://tcb.cloud.tencent.com/cloud-admin/#/management/data-model/${existModel.Id}}`);
278
+ log.success(`更新数据模型 ${modelName} 成功,点击查看 ${link}`);
279
+ }
280
+ else {
281
+ const confirm = yield inquirer_1.default.prompt([
282
+ {
283
+ type: 'confirm',
284
+ name: 'confirm',
285
+ message: `数据模型 ${modelName} 不存在,是否创建?`
286
+ }
287
+ ]);
288
+ if (!confirm.confirm) {
289
+ log.info(`跳过创建数据模型 ${modelName}`);
290
+ continue;
291
+ }
292
+ const createModelRes = yield (0, db_1.createModel)({
293
+ envId,
294
+ name: modelName,
295
+ title: model.title || modelName,
296
+ schema: model
297
+ });
298
+ ids.push(createModelRes.Id);
299
+ const link = (0, utils_1.genClickableLink)(`https://tcb.cloud.tencent.com/cloud-admin/#/management/data-model/${createModelRes.Id}}`);
300
+ log.success(`创建数据模型 ${modelName} 成功, 点击查看 ${link}`);
301
+ }
302
+ }
303
+ const confirmPublish = yield inquirer_1.default.prompt([
304
+ {
305
+ type: 'confirm',
306
+ name: 'confirm',
307
+ message: `数据模型已经导入成功,是否发布?`
308
+ }
309
+ ]);
310
+ if (confirmPublish.confirm) {
311
+ const publishRes = yield (0, db_1.publishModel)({
312
+ envId,
313
+ ids
314
+ });
315
+ }
316
+ });
317
+ }
318
+ };
319
+ __decorate([
320
+ (0, decorators_1.InjectParams)(),
321
+ __param(0, (0, decorators_1.EnvId)()),
322
+ __param(1, (0, decorators_1.ArgsParams)()),
323
+ __param(2, (0, decorators_1.Log)()),
324
+ __metadata("design:type", Function),
325
+ __metadata("design:paramtypes", [Object, Object, decorators_1.Logger]),
326
+ __metadata("design:returntype", Promise)
327
+ ], DbPushCommand.prototype, "execute", null);
328
+ DbPushCommand = __decorate([
329
+ (0, common_1.ICommand)()
330
+ ], DbPushCommand);
331
+ exports.DbPushCommand = DbPushCommand;
332
+ function selectEnv() {
333
+ return __awaiter(this, void 0, void 0, function* () {
334
+ const data = yield (0, env_1.listEnvs)();
335
+ const sortData = data.sort((prev, next) => {
336
+ if (prev.Alias > next.Alias) {
337
+ return 1;
338
+ }
339
+ if (prev.Alias < next.Alias) {
340
+ return -1;
341
+ }
342
+ return 0;
343
+ });
344
+ const choices = sortData.map((item) => {
345
+ return {
346
+ name: `${item.Alias || item.EnvId} (${item.EnvId}) ${item.Status === 'NORMAL' ? '正常' : '不可用'}`,
347
+ value: item.EnvId,
348
+ short: item.envId
349
+ };
350
+ });
351
+ const questions = [
352
+ {
353
+ type: 'list',
354
+ name: 'env',
355
+ message: '请先选择一个云开发环境',
356
+ choices: choices
357
+ }
358
+ ];
359
+ const answers = yield inquirer_1.default.prompt(questions);
360
+ return answers.env;
361
+ });
362
+ }
363
+ function selectModel(envId) {
364
+ return __awaiter(this, void 0, void 0, function* () {
365
+ const data = yield (0, db_1.listModels)({
366
+ envId
367
+ });
368
+ const sortData = data.sort((prev, next) => {
369
+ if (prev.CreatedAt > next.CreatedAt) {
370
+ return 1;
371
+ }
372
+ if (prev.CreatedAt < next.CreatedAt) {
373
+ return -1;
374
+ }
375
+ return 0;
376
+ });
377
+ const choices = sortData.map((item) => {
378
+ return {
379
+ name: `${item.Title} (${item.Name})`,
380
+ value: item.Name,
381
+ short: item.Name
382
+ };
383
+ });
384
+ const questions = [
385
+ {
386
+ type: 'checkbox',
387
+ name: 'model',
388
+ message: '请选择数据模型',
389
+ choices: choices
390
+ }
391
+ ];
392
+ const answers = yield inquirer_1.default.prompt(questions);
393
+ return answers.model;
394
+ });
395
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./base"), exports);
@@ -27,3 +27,4 @@ __exportStar(require("./framework"), exports);
27
27
  __exportStar(require("./smart"), exports);
28
28
  __exportStar(require("./lowcode"), exports);
29
29
  __exportStar(require("./run"), exports);
30
+ __exportStar(require("./db"), exports);
@@ -54,12 +54,20 @@ var __rest = (this && this.__rest) || function (s, e) {
54
54
  }
55
55
  return t;
56
56
  };
57
+ var __importDefault = (this && this.__importDefault) || function (mod) {
58
+ return (mod && mod.__esModule) ? mod : { "default": mod };
59
+ };
57
60
  Object.defineProperty(exports, "__esModule", { value: true });
58
- exports.LowCodeDeployApp = exports.LowCodePreviewApp = exports.LowCodeBuildApp = exports.LowCodeWatch = void 0;
61
+ exports.ModelTypeSync = exports.LowCodeDeployApp = exports.LowCodeBuildAppConfig = exports.LowCodePreviewApp = exports.LowCodeBuildApp = exports.LowCodeWatch = void 0;
62
+ const lodash_1 = require("lodash");
59
63
  const common_1 = require("../common");
60
64
  const decorators_1 = require("../../decorators");
61
65
  const utils_1 = require("./utils");
62
66
  const utils_2 = require("../../utils");
67
+ const cloud_api_1 = require("@cloudbase/cloud-api");
68
+ const toolbox_1 = require("@cloudbase/toolbox");
69
+ const fs_extra_1 = __importDefault(require("fs-extra"));
70
+ const dts_1 = require("../../utils/dts");
63
71
  let lowcodeCli;
64
72
  if (process.argv.includes('lowcode')) {
65
73
  (0, utils_1.getLowcodeCli)().then((_) => (lowcodeCli = _));
@@ -210,6 +218,55 @@ LowCodePreviewApp = __decorate([
210
218
  (0, common_1.ICommand)({ supportPrivate: true })
211
219
  ], LowCodePreviewApp);
212
220
  exports.LowCodePreviewApp = LowCodePreviewApp;
221
+ let LowCodeBuildAppConfig = class LowCodeBuildAppConfig extends common_1.Command {
222
+ get options() {
223
+ return {
224
+ cmd: 'lowcode',
225
+ childCmd: 'build:app-config',
226
+ options: [
227
+ {
228
+ flags: '--out <out>',
229
+ desc: '输出目录'
230
+ },
231
+ {
232
+ flags: '--build-type-list <type...>',
233
+ desc: '输出目录'
234
+ },
235
+ {
236
+ flags: '--domain <domain>',
237
+ desc: '托管域名'
238
+ }
239
+ ],
240
+ desc: '构建应用配置',
241
+ requiredEnvId: false
242
+ };
243
+ }
244
+ execute(ctx, log, options) {
245
+ return __awaiter(this, void 0, void 0, function* () {
246
+ const config = (0, utils_1.getCmdConfig)(ctx.config, this.options);
247
+ const mergesOptions = (0, utils_1.getMergedOptions)(config, options);
248
+ yield lowcodeCli.buildAppConfig({
249
+ envId: ctx.envId || ctx.config.envId,
250
+ projectPath: process.cwd(),
251
+ logger: log,
252
+ privateSettings: (0, utils_2.getPrivateSettings)(ctx.config, this.options.cmd)
253
+ }, mergesOptions);
254
+ });
255
+ }
256
+ };
257
+ __decorate([
258
+ (0, decorators_1.InjectParams)(),
259
+ __param(0, (0, decorators_1.CmdContext)()),
260
+ __param(1, (0, decorators_1.Log)()),
261
+ __param(2, (0, decorators_1.ArgsOptions)()),
262
+ __metadata("design:type", Function),
263
+ __metadata("design:paramtypes", [Object, decorators_1.Logger, Object]),
264
+ __metadata("design:returntype", Promise)
265
+ ], LowCodeBuildAppConfig.prototype, "execute", null);
266
+ LowCodeBuildAppConfig = __decorate([
267
+ (0, common_1.ICommand)({ supportPrivate: true })
268
+ ], LowCodeBuildAppConfig);
269
+ exports.LowCodeBuildAppConfig = LowCodeBuildAppConfig;
213
270
  let LowCodeDeployApp = class LowCodeDeployApp extends common_1.Command {
214
271
  get options() {
215
272
  return {
@@ -219,6 +276,10 @@ let LowCodeDeployApp = class LowCodeDeployApp extends common_1.Command {
219
276
  {
220
277
  flags: '--src <src>',
221
278
  desc: '部署目录'
279
+ },
280
+ {
281
+ flags: '--sync-cloud',
282
+ desc: '是否同步云端部署记录'
222
283
  }
223
284
  ],
224
285
  desc: '发布应用',
@@ -260,3 +321,95 @@ LowCodeDeployApp = __decorate([
260
321
  (0, common_1.ICommand)({ supportPrivate: true })
261
322
  ], LowCodeDeployApp);
262
323
  exports.LowCodeDeployApp = LowCodeDeployApp;
324
+ let ModelTypeSync = class ModelTypeSync extends common_1.Command {
325
+ get options() {
326
+ return {
327
+ cmd: 'sync-model-dts',
328
+ options: [
329
+ {
330
+ flags: '--envId <envId>',
331
+ desc: '环境 ID'
332
+ }
333
+ ],
334
+ desc: '同步数据模型类型定义文件',
335
+ requiredEnvId: true,
336
+ autoRunLogin: true
337
+ };
338
+ }
339
+ execute(ctx, log, options) {
340
+ return __awaiter(this, void 0, void 0, function* () {
341
+ log.info('同步中...');
342
+ if (!(yield fs_extra_1.default.pathExists('cloudbaserc.json'))) {
343
+ yield fs_extra_1.default.writeFile('cloudbaserc.json', JSON.stringify({
344
+ version: '2.0',
345
+ envId: ctx.envId
346
+ }, null, 2), 'utf8');
347
+ }
348
+ if (!(yield fs_extra_1.default.pathExists('tsconfig.json'))) {
349
+ yield fs_extra_1.default.writeFile('tsconfig.json', JSON.stringify({
350
+ compilerOptions: {
351
+ allowJs: true
352
+ }
353
+ }, null, 2), 'utf8');
354
+ }
355
+ else {
356
+ const config = yield fs_extra_1.default.readJson('tsconfig.json', 'utf8');
357
+ (0, lodash_1.set)(config, 'compilerOptions.allowJs', true);
358
+ yield fs_extra_1.default.writeFile('tsconfig.json', JSON.stringify(config, null, 2), 'utf8');
359
+ }
360
+ const cloudService = yield getCloudServiceInstance(ctx);
361
+ const datasourceList = yield cloudService.lowcode.request('DescribeDataSourceList', {
362
+ EnvId: ctx.envId,
363
+ PageIndex: 1,
364
+ PageSize: 1000,
365
+ QuerySystemModel: true,
366
+ QueryConnector: 0
367
+ });
368
+ const rows = datasourceList.Data.Rows;
369
+ const dataModelList = rows.map((item) => ({
370
+ name: item.Name,
371
+ schema: JSON.parse(item.Schema),
372
+ title: item.Title
373
+ }));
374
+ const dts = yield (0, dts_1.generateDataModelDTS)(dataModelList);
375
+ const dtsFileName = 'cloud-models.d.ts';
376
+ yield fs_extra_1.default.writeFile(dtsFileName, dts);
377
+ log.success('同步数据模型类型定义文件成功。文件名称:' + dtsFileName);
378
+ });
379
+ }
380
+ };
381
+ __decorate([
382
+ (0, decorators_1.InjectParams)(),
383
+ __param(0, (0, decorators_1.CmdContext)()),
384
+ __param(1, (0, decorators_1.Log)()),
385
+ __param(2, (0, decorators_1.ArgsOptions)()),
386
+ __metadata("design:type", Function),
387
+ __metadata("design:paramtypes", [Object, decorators_1.Logger, Object]),
388
+ __metadata("design:returntype", Promise)
389
+ ], ModelTypeSync.prototype, "execute", null);
390
+ ModelTypeSync = __decorate([
391
+ (0, common_1.ICommand)({ supportPrivate: true })
392
+ ], ModelTypeSync);
393
+ exports.ModelTypeSync = ModelTypeSync;
394
+ function getCloudServiceInstance(ctx) {
395
+ return __awaiter(this, void 0, void 0, function* () {
396
+ let credential;
397
+ if (ctx.hasPrivateSettings) {
398
+ process.env.IS_PRIVATE = 'true';
399
+ const privateSettings = (0, utils_2.getPrivateSettings)(ctx.config, this.options.cmd);
400
+ credential = privateSettings.credential;
401
+ }
402
+ else {
403
+ credential = yield utils_2.authSupevisor.getLoginState();
404
+ }
405
+ return {
406
+ lowcode: cloud_api_1.CloudApiService.getInstance({
407
+ service: 'lowcode',
408
+ proxy: (0, toolbox_1.getProxy)(),
409
+ credential,
410
+ version: '2021-01-08'
411
+ }),
412
+ tcb: cloud_api_1.CloudApiService.getInstance({ service: 'tcb', proxy: (0, toolbox_1.getProxy)(), credential })
413
+ };
414
+ });
415
+ }
@@ -123,7 +123,7 @@ let LowCodeCreateComps = class LowCodeCreateComps extends common_1.Command {
123
123
  else {
124
124
  const comp = comps.rows.find((row) => row.groupName === compsName);
125
125
  if (!comp) {
126
- throw new error_1.CloudBaseError(`云端不存在组件库 ${compsName},请到低码控制台新建该组件库!`);
126
+ throw new error_1.CloudBaseError(`云端不存在组件库 ${compsName},请在微搭控制台-应用菜单中,打开任意一个应用的编辑器,点击素材-组件库管理模块,并创建组件库`);
127
127
  }
128
128
  }
129
129
  yield lowcodeCli.bootstrap(compsName, log);
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.publishModel = exports.getModel = exports.updateModel = exports.createModel = exports.listModels = void 0;
13
+ const net_1 = require("../utils/net");
14
+ const lowCodeService = new net_1.CloudApiService('lowcode', {}, '2021-01-08');
15
+ function listModels(options = {}) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ const { envId } = options;
18
+ const datasourceList = yield lowCodeService.request('DescribeDataSourceList', {
19
+ EnvId: envId,
20
+ PageIndex: 1,
21
+ PageSize: 1000,
22
+ DataSourceNames: options.name,
23
+ QuerySystemModel: true,
24
+ QueryConnector: 0
25
+ });
26
+ const rows = datasourceList.Data.Rows;
27
+ return rows;
28
+ });
29
+ }
30
+ exports.listModels = listModels;
31
+ function createModel({ envId, name, title, schema }) {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ return ((yield lowCodeService.request('CreateDataSourceDetail', {
34
+ EnvId: envId,
35
+ Title: title,
36
+ Name: name,
37
+ Type: 'database',
38
+ TableNameRule: "only_name",
39
+ Schema: JSON.stringify(schema)
40
+ })).Data);
41
+ });
42
+ }
43
+ exports.createModel = createModel;
44
+ function updateModel({ envId, id, title, schema }) {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ return ((yield lowCodeService.request('ModifyDataSource', {
47
+ Id: id,
48
+ EnvId: envId,
49
+ Title: title,
50
+ Schema: JSON.stringify(schema)
51
+ })).Data);
52
+ });
53
+ }
54
+ exports.updateModel = updateModel;
55
+ function getModel(options) {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ const { envId, name } = options;
58
+ try {
59
+ return (yield lowCodeService.request('DescribeDataSource', {
60
+ EnvId: envId,
61
+ Name: name
62
+ })).Data;
63
+ }
64
+ catch (e) {
65
+ if (e.original.Code === 'ResourceNotFound') {
66
+ return null;
67
+ }
68
+ else {
69
+ throw e;
70
+ }
71
+ }
72
+ });
73
+ }
74
+ exports.getModel = getModel;
75
+ function publishModel(options) {
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ const { envId, ids } = options;
78
+ return (yield lowCodeService.request('BatchPublishDataSources', {
79
+ EnvId: envId,
80
+ DataSourceIds: ids
81
+ })).Data;
82
+ });
83
+ }
84
+ exports.publishModel = publishModel;
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.generateDataModelDTS = void 0;
13
+ const json_schema_to_typescript_1 = require("json-schema-to-typescript");
14
+ const lodash_1 = require("lodash");
15
+ const tools_1 = require("./tools");
16
+ function generateDataModelDTS(dataModelList) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ const dtsList = yield Promise.all(dataModelList.map((item) => __awaiter(this, void 0, void 0, function* () {
19
+ let dts = yield _handleOne(item.name, item.schema);
20
+ return {
21
+ name: item.name,
22
+ title: item.title,
23
+ dts
24
+ };
25
+ })));
26
+ const result = `
27
+ import { DataModelMethods } from "@cloudbase/wx-cloud-client-sdk";
28
+ ${dtsList.map((item) => item.dts).join('\n')}
29
+
30
+ interface IModels {
31
+ ${dtsList
32
+ .map((item) => {
33
+ return `
34
+ /**
35
+ * 数据模型:${item.title}
36
+ */
37
+ ${_toValidFieldName(item.name)}: DataModelMethods<${getModelInterfaceName(item.name)}>;`;
38
+ })
39
+ .join('\n')}
40
+ }
41
+
42
+ declare module "@cloudbase/wx-cloud-client-sdk" {
43
+ interface OrmClient extends IModels {}
44
+ }
45
+
46
+ declare global {
47
+ interface WxCloud {
48
+ models: IModels;
49
+ }
50
+ }`;
51
+ return result;
52
+ function _handleOne(name, schema) {
53
+ return __awaiter(this, void 0, void 0, function* () {
54
+ if (!(schema === null || schema === void 0 ? void 0 : schema.properties))
55
+ return `interface ${getModelInterfaceName(name)} {}`;
56
+ Object.keys(schema.properties).forEach((key) => {
57
+ if (schema.properties[key]['x-system']) {
58
+ delete schema.properties[key];
59
+ }
60
+ });
61
+ Object.keys(schema.properties).forEach((key) => {
62
+ const field = schema.properties[key];
63
+ if (['related', 'father-son'].includes(field.format)) {
64
+ schema.properties[`@${key}`] = {
65
+ type: 'object',
66
+ description: `关联${field.title}对象`,
67
+ properties: {
68
+ v1: {
69
+ type: 'object',
70
+ properties: {
71
+ record: {
72
+ type: 'string',
73
+ format: field.format,
74
+ 'x-parent': {
75
+ parentDataSourceName: field['x-parent'].parentDataSourceName
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+ };
82
+ schema.properties[key].format = '';
83
+ }
84
+ });
85
+ schema = JSON.parse(JSON.stringify(schema, (_, value) => {
86
+ if ((0, lodash_1.has)(value, 'title') && !(0, lodash_1.has)(value, 'title.title')) {
87
+ (0, lodash_1.set)(value, 'description', value['title'] + '\n' + value['description']);
88
+ delete value['title'];
89
+ }
90
+ return value;
91
+ }));
92
+ const dts = yield _compile(name, schema);
93
+ return dts;
94
+ });
95
+ }
96
+ function _compile(name, jsonschema) {
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ try {
99
+ let dts = yield (0, json_schema_to_typescript_1.compile)(jsonschema, getModelInterfaceName(name), {
100
+ additionalProperties: false,
101
+ bannerComment: '',
102
+ format: true,
103
+ unknownAny: false,
104
+ customName(_schema) {
105
+ var _a, _b;
106
+ const format = _schema.format;
107
+ let name = '';
108
+ if (['one-one', 'many-one', 'related', 'father-son'].includes(format)) {
109
+ name = getModelInterfaceName((_a = _schema === null || _schema === void 0 ? void 0 : _schema['x-parent']) === null || _a === void 0 ? void 0 : _a.parentDataSourceName);
110
+ }
111
+ if (['one-many', 'many-many'].includes(format)) {
112
+ name = `ARRAY_TYPE_${getModelInterfaceName((_b = _schema === null || _schema === void 0 ? void 0 : _schema['x-parent']) === null || _b === void 0 ? void 0 : _b.parentDataSourceName)}`;
113
+ }
114
+ if (name) {
115
+ name = `${name}_TAIL${(0, tools_1.uuidv4)()}_END_`;
116
+ }
117
+ return name || undefined;
118
+ }
119
+ });
120
+ dts = dts
121
+ .replace(/export interface/g, 'interface')
122
+ .replace(/ARRAY_TYPE_(.*);/g, '$1[]')
123
+ .replace(/_TAIL.*?_END_/g, '')
124
+ .replace(/[\s\S]*?(?=interface)/, '');
125
+ return dts;
126
+ }
127
+ catch (e) {
128
+ console.error('_compile error:', e);
129
+ return '';
130
+ }
131
+ });
132
+ }
133
+ function _toValidFieldName(name) {
134
+ let result = name.replace(/[^a-zA-Z0-9_$]/g, '_');
135
+ if (/^[0-9]/.test(result)) {
136
+ result = '_' + result;
137
+ }
138
+ return result;
139
+ }
140
+ function getModelInterfaceName(name) {
141
+ if (!name)
142
+ return '';
143
+ return (0, lodash_1.upperFirst)((0, lodash_1.deburr)(`IModal_${name}`)
144
+ .replace(/(^\s*[^a-zA-Z_$])|([^a-zA-Z_$\d])/g, ' ')
145
+ .replace(/^_[a-z]/g, (match) => match.toUpperCase())
146
+ .replace(/_[a-z]/g, (match) => match.substr(1, match.length).toUpperCase())
147
+ .replace(/([\d$]+[a-zA-Z])/g, (match) => match.toUpperCase())
148
+ .replace(/\s+([a-zA-Z])/g, (match) => (0, lodash_1.trim)(match.toUpperCase()))
149
+ .replace(/\s/g, ''));
150
+ }
151
+ });
152
+ }
153
+ exports.generateDataModelDTS = generateDataModelDTS;
@@ -30,7 +30,7 @@ class CloudApiService {
30
30
  constructor(service, baseParams, version = '') {
31
31
  this.apiService = new cloud_api_1.CloudApiService({
32
32
  service,
33
- version: service === 'tcr' ? version : '2019-09-24',
33
+ version: version || '2019-09-24',
34
34
  baseParams,
35
35
  proxy: (0, toolbox_1.getProxy)(),
36
36
  timeout: constant_1.REQUEST_TIMEOUT,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/cli",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "cli tool for cloudbase",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -8,7 +8,7 @@
8
8
  "watch": "rimraf lib types && tsc -w",
9
9
  "dev": "rimraf lib types && tsc -w",
10
10
  "eslint": "eslint \"./**/*.ts\"",
11
- "test": "jest --runInBand --forceExit --detectOpenHandles --coverage --verbose --testTimeout=10000",
11
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --forceExit --detectOpenHandles --coverage --verbose --testTimeout=10000",
12
12
  "tsc": "tsc",
13
13
  "pkg": "pkg ./bin/cloudbase.js --out-path ./pkg",
14
14
  "postinstall": "node ./post-install.js || exit 0",
@@ -33,7 +33,7 @@
33
33
  "dependencies": {
34
34
  "@cloudbase/cloud-api": "^0.5.5",
35
35
  "@cloudbase/framework-core": "^1.9.7",
36
- "@cloudbase/lowcode-cli": "^0.21.0",
36
+ "@cloudbase/lowcode-cli": "^0.21.1",
37
37
  "@cloudbase/manager-node": "4.2.8",
38
38
  "@cloudbase/toolbox": "^0.7.5",
39
39
  "@sentry/node": "^5.10.2",
@@ -48,6 +48,7 @@
48
48
  "fs-extra": "^8.1.0",
49
49
  "https-proxy-agent": "^5.0.1",
50
50
  "inquirer": "^6.5.0",
51
+ "json-schema-to-typescript": "^14.0.5",
51
52
  "lodash": "^4.17.21",
52
53
  "log-symbols": "^3.0.0",
53
54
  "lowdb": "^1.0.0",
@@ -69,6 +70,7 @@
69
70
  "yargs-parser": "^21.0.1"
70
71
  },
71
72
  "devDependencies": {
73
+ "@types/fs-extra": "^11.0.4",
72
74
  "@types/jest": "^27",
73
75
  "@types/koa__router": "^8.0.11",
74
76
  "@types/lodash": "^4.14.182",
@@ -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';
@@ -0,0 +1,44 @@
1
+ import { Command } from '../common';
2
+ import { Logger } from '../../decorators';
3
+ export declare class DbListCommand extends Command {
4
+ get options(): {
5
+ cmd: string;
6
+ childCmd: string;
7
+ options: {
8
+ flags: string;
9
+ desc: string;
10
+ }[];
11
+ requiredEnvId: boolean;
12
+ autoRunLogin: boolean;
13
+ desc: string;
14
+ };
15
+ execute(envId: any, log: Logger): Promise<void>;
16
+ }
17
+ export declare class DbPullCommand extends Command {
18
+ get options(): {
19
+ cmd: string;
20
+ childCmd: string;
21
+ options: {
22
+ flags: string;
23
+ desc: string;
24
+ }[];
25
+ requiredEnvId: boolean;
26
+ autoRunLogin: boolean;
27
+ desc: string;
28
+ };
29
+ execute(envId: any, params: any, log: Logger): Promise<void>;
30
+ }
31
+ export declare class DbPushCommand extends Command {
32
+ get options(): {
33
+ cmd: string;
34
+ childCmd: string;
35
+ options: {
36
+ flags: string;
37
+ desc: string;
38
+ }[];
39
+ requiredEnvId: boolean;
40
+ autoRunLogin: boolean;
41
+ desc: string;
42
+ };
43
+ execute(envId: any, params: any, log: Logger): Promise<void>;
44
+ }
@@ -0,0 +1 @@
1
+ export * from './base';
@@ -11,3 +11,4 @@ export * from './framework';
11
11
  export * from './smart';
12
12
  export * from './lowcode';
13
13
  export * from './run';
14
+ export * from './db';
@@ -40,6 +40,19 @@ export declare class LowCodePreviewApp extends Command {
40
40
  };
41
41
  execute(ctx: ICommandContext, log: Logger, options: any): Promise<void>;
42
42
  }
43
+ export declare class LowCodeBuildAppConfig extends Command {
44
+ get options(): {
45
+ cmd: string;
46
+ childCmd: string;
47
+ options: {
48
+ flags: string;
49
+ desc: string;
50
+ }[];
51
+ desc: string;
52
+ requiredEnvId: boolean;
53
+ };
54
+ execute(ctx: ICommandContext, log: Logger, options: any): Promise<void>;
55
+ }
43
56
  export declare class LowCodeDeployApp extends Command {
44
57
  get options(): {
45
58
  cmd: string;
@@ -53,3 +66,16 @@ export declare class LowCodeDeployApp extends Command {
53
66
  };
54
67
  execute(ctx: ICommandContext, log: Logger, options: any): Promise<void>;
55
68
  }
69
+ export declare class ModelTypeSync extends Command {
70
+ get options(): {
71
+ cmd: string;
72
+ options: {
73
+ flags: string;
74
+ desc: string;
75
+ }[];
76
+ desc: string;
77
+ requiredEnvId: boolean;
78
+ autoRunLogin: boolean;
79
+ };
80
+ execute(ctx: ICommandContext, log: Logger, options: any): Promise<void>;
81
+ }
@@ -0,0 +1,24 @@
1
+ export declare function listModels(options?: {
2
+ envId?: string;
3
+ name?: string[];
4
+ }): Promise<any[]>;
5
+ export declare function createModel({ envId, name, title, schema }: {
6
+ envId: string;
7
+ name: string;
8
+ title: string;
9
+ schema: any;
10
+ }): Promise<any>;
11
+ export declare function updateModel({ envId, id, title, schema }: {
12
+ envId: string;
13
+ id: string;
14
+ title: string;
15
+ schema: any;
16
+ }): Promise<any>;
17
+ export declare function getModel(options: {
18
+ envId: string;
19
+ name: string;
20
+ }): Promise<any>;
21
+ export declare function publishModel(options: {
22
+ envId: string;
23
+ ids: string[];
24
+ }): Promise<any>;
@@ -0,0 +1,6 @@
1
+ import { type JSONSchema } from 'json-schema-to-typescript';
2
+ export declare function generateDataModelDTS(dataModelList: {
3
+ name: string;
4
+ title: string;
5
+ schema: JSONSchema;
6
+ }[]): Promise<string>;