@cloudbase/cli 2.0.3 → 2.0.4-alpha.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/.editorconfig +9 -9
- package/.eslintignore +7 -7
- package/.eslintrc +35 -35
- package/.prettierrc.js +29 -29
- package/.vscode/launch.json +16 -16
- package/LICENSE +5 -5
- package/README.md +35 -35
- package/bin/cloudbase.js +5 -5
- package/bin/tcb.js +0 -0
- package/changelog.md +6 -6
- package/jest.config.js +17 -17
- package/lib/commands/account/login.js +18 -18
- package/lib/commands/storage/storage.js +1 -1
- package/lib/env/login.js +7 -7
- package/package.json +2 -2
- package/post-install.js +61 -61
- package/runtime/nodejs/bootstrap.js +255 -255
- package/runtime/nodejs/runtime.js +183 -183
- package/src/auth/index.ts +1 -1
- package/src/auth/login.ts +91 -91
- package/src/auth/logout.ts +7 -7
- package/src/commands/account/index.ts +2 -2
- package/src/commands/account/login.ts +192 -192
- package/src/commands/account/logout.ts +24 -24
- package/src/commands/env/base.ts +90 -90
- package/src/commands/env/create.ts +92 -92
- package/src/commands/env/domain.ts +186 -186
- package/src/commands/env/index.ts +4 -4
- package/src/commands/env/login.ts +235 -235
- package/src/commands/framework/index.ts +124 -124
- package/src/commands/functions/alias/getRoute.ts +76 -76
- package/src/commands/functions/alias/index.ts +2 -2
- package/src/commands/functions/alias/setRoute.ts +82 -82
- package/src/commands/functions/code-download.ts +100 -100
- package/src/commands/functions/code-update.ts +62 -62
- package/src/commands/functions/concurrency/delete.ts +45 -45
- package/src/commands/functions/concurrency/index.ts +2 -2
- package/src/commands/functions/concurrency/list.ts +58 -58
- package/src/commands/functions/concurrency/set.ts +47 -47
- package/src/commands/functions/config-update.ts +76 -76
- package/src/commands/functions/copy.ts +62 -62
- package/src/commands/functions/delete.ts +79 -79
- package/src/commands/functions/deploy.ts +293 -293
- package/src/commands/functions/detail.ts +138 -138
- package/src/commands/functions/index.ts +16 -16
- package/src/commands/functions/invoke.ts +121 -121
- package/src/commands/functions/layer/bind.ts +182 -182
- package/src/commands/functions/layer/common.ts +8 -8
- package/src/commands/functions/layer/create.ts +49 -49
- package/src/commands/functions/layer/delete.ts +73 -73
- package/src/commands/functions/layer/download.ts +92 -92
- package/src/commands/functions/layer/index.ts +7 -7
- package/src/commands/functions/layer/list.ts +94 -94
- package/src/commands/functions/layer/sort.ts +76 -76
- package/src/commands/functions/list.ts +68 -68
- package/src/commands/functions/log.ts +148 -148
- package/src/commands/functions/run.ts +249 -249
- package/src/commands/functions/trigger-create.ts +79 -79
- package/src/commands/functions/trigger-delete.ts +105 -105
- package/src/commands/functions/version/index.ts +1 -1
- package/src/commands/functions/version/list.ts +73 -73
- package/src/commands/functions/version/publish.ts +43 -43
- package/src/commands/gateway/create.ts +109 -109
- package/src/commands/gateway/delete.ts +81 -81
- package/src/commands/gateway/domain.ts +159 -159
- package/src/commands/gateway/index.ts +5 -5
- package/src/commands/gateway/list.ts +76 -76
- package/src/commands/gateway/switch.ts +107 -107
- package/src/commands/helpers/index.ts +2 -2
- package/src/commands/helpers/init.ts +431 -431
- package/src/commands/helpers/new.ts +117 -117
- package/src/commands/helpers/open.ts +67 -67
- package/src/commands/hosting/hosting.ts +360 -360
- package/src/commands/index.ts +13 -13
- package/src/commands/lowcode/app.ts +34 -34
- package/src/commands/lowcode/comps.ts +322 -322
- package/src/commands/lowcode/index.ts +1 -1
- package/src/commands/lowcode/utils.ts +24 -24
- package/src/commands/run/image/index.ts +4 -4
- package/src/commands/run/standalonegateway/common.ts +7 -7
- package/src/commands/run/standalonegateway/create.ts +85 -85
- package/src/commands/run/standalonegateway/destroy.ts +59 -59
- package/src/commands/run/standalonegateway/index.ts +4 -4
- package/src/commands/run/standalonegateway/list.ts +53 -53
- package/src/commands/run/standalonegateway/package.ts +62 -62
- package/src/commands/run/standalonegateway/turn.ts +63 -63
- package/src/commands/run/version/index.ts +4 -4
- package/src/commands/smart.ts +132 -132
- package/src/commands/storage/storage.ts +464 -464
- package/src/commands/third/thirdAttach.ts +49 -49
- package/src/completion/index.ts +13 -13
- package/src/decorators/captureError.ts +25 -25
- package/src/decorators/constants.ts +12 -12
- package/src/decorators/deprecate.ts +25 -25
- package/src/decorators/guard.ts +42 -42
- package/src/decorators/index.ts +7 -7
- package/src/decorators/injectParams.ts +54 -54
- package/src/decorators/params/common.ts +28 -28
- package/src/decorators/params/index.ts +35 -35
- package/src/env/domain.ts +33 -33
- package/src/env/index.ts +63 -63
- package/src/env/login.ts +80 -80
- package/src/error.ts +36 -36
- package/src/function/alias.ts +43 -43
- package/src/function/base.ts +253 -253
- package/src/function/code.ts +55 -55
- package/src/function/concurrency.ts +57 -57
- package/src/function/create.ts +78 -78
- package/src/function/delete.ts +42 -42
- package/src/function/index.ts +10 -10
- package/src/function/layer/attach.ts +68 -68
- package/src/function/layer/create.ts +63 -63
- package/src/function/layer/delete.ts +21 -21
- package/src/function/layer/download.ts +54 -54
- package/src/function/layer/index.ts +7 -7
- package/src/function/layer/list.ts +32 -32
- package/src/function/layer/sort.ts +24 -24
- package/src/function/trigger.ts +97 -97
- package/src/function/update.ts +35 -35
- package/src/function/version.ts +38 -38
- package/src/function/vpc.ts +22 -22
- package/src/gateway/index.ts +137 -137
- package/src/hosting.ts +212 -212
- package/src/index.ts +13 -13
- package/src/logger.ts +17 -17
- package/src/run/create.ts +23 -23
- package/src/run/delete.ts +15 -15
- package/src/run/image/build.ts +36 -36
- package/src/run/image/delete.ts +13 -13
- package/src/run/image/index.ts +3 -3
- package/src/run/image/info.ts +26 -26
- package/src/run/list.ts +29 -29
- package/src/run/repo.ts +24 -24
- package/src/run/standalonegateway/create.ts +24 -24
- package/src/run/standalonegateway/destroy.ts +19 -19
- package/src/run/standalonegateway/index.ts +4 -4
- package/src/run/standalonegateway/list.ts +74 -74
- package/src/run/standalonegateway/package/list.ts +24 -24
- package/src/run/standalonegateway/turn/index.ts +1 -1
- package/src/run/standalonegateway/turn/off.ts +19 -19
- package/src/run/standalonegateway/turn/on.ts +19 -19
- package/src/run/version/create.ts +68 -68
- package/src/run/version/delete.ts +15 -15
- package/src/run/version/index.ts +5 -5
- package/src/run/version/list.ts +16 -16
- package/src/run/version/modify.ts +16 -16
- package/src/run/version/repo.ts +27 -27
- package/src/run/version/update.ts +58 -58
- package/src/storage.ts +114 -114
- package/src/third/index.ts +12 -12
- package/src/utils/auth.ts +15 -15
- package/src/utils/cli-table.ts +23 -23
- package/src/utils/config.ts +39 -39
- package/src/utils/env.ts +244 -244
- package/src/utils/fs/del.ts +5 -5
- package/src/utils/fs/index.ts +71 -71
- package/src/utils/function-packer.ts +97 -97
- package/src/utils/log.ts +81 -81
- package/src/utils/net/cloud-api-request.ts +62 -62
- package/src/utils/net/credential.ts +53 -53
- package/src/utils/net/index.ts +4 -4
- package/src/utils/net/manager-service.ts +36 -36
- package/src/utils/net/proxy.ts +6 -6
- package/src/utils/notice.ts +28 -28
- package/src/utils/output/highlight.ts +5 -5
- package/src/utils/output/index.ts +2 -2
- package/src/utils/output/link.ts +10 -10
- package/src/utils/output/loading.ts +82 -82
- package/src/utils/parallel.ts +82 -82
- package/src/utils/platform/index.ts +2 -2
- package/src/utils/platform/mac.ts +21 -21
- package/src/utils/platform/os.ts +64 -64
- package/src/utils/platform/port.ts +10 -10
- package/src/utils/progress-bar.ts +38 -38
- package/src/utils/prompt/select.ts +59 -59
- package/src/utils/reporter/agree.ts +20 -20
- package/src/utils/reporter/download.ts +26 -26
- package/src/utils/reporter/index.ts +3 -3
- package/src/utils/reporter/usage.ts +20 -20
- package/src/utils/store/auth.ts +49 -49
- package/src/utils/store/common.ts +8 -8
- package/src/utils/store/db.ts +68 -68
- package/src/utils/store/index.ts +4 -4
- package/src/utils/store/usage.ts +12 -12
- package/src/utils/template.ts +170 -170
- package/src/utils/tools/encoding.ts +8 -8
- package/src/utils/tools/index.ts +4 -4
- package/src/utils/tools/object.ts +33 -33
- package/src/utils/tools/time.ts +38 -38
- package/src/utils/tools/uid.ts +19 -19
- package/templates/html/loginFail.html +90 -90
- package/templates/html/loginSuccess.html +86 -86
- package/templates/server/node/_gitignore +54 -54
- package/templates/server/node/cloudbaserc.json +10 -10
- package/templates/server/node/index.js +5 -5
- package/templates/server/node/package.json +9 -9
- package/tsconfig.json +19 -19
- package/tsconfig.test.json +13 -13
- package/.vscode/settings.json +0 -3
package/src/utils/store/db.ts
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
import os from 'os'
|
|
2
|
-
import fse from 'fs-extra'
|
|
3
|
-
import low from 'lowdb'
|
|
4
|
-
import path from 'path'
|
|
5
|
-
import FileAsync from 'lowdb/adapters/FileAsync'
|
|
6
|
-
import FileSync from 'lowdb/adapters/FileSync'
|
|
7
|
-
import xdgBasedir from 'xdg-basedir'
|
|
8
|
-
|
|
9
|
-
// 系统配置目录
|
|
10
|
-
const configDir = xdgBasedir.config || path.join(os.tmpdir(), '.config')
|
|
11
|
-
// cloudbase 配置目录
|
|
12
|
-
export const cloudbaseConfigDir = path.join(configDir, '.cloudbase')
|
|
13
|
-
|
|
14
|
-
// 确保目录存在
|
|
15
|
-
|
|
16
|
-
fse.ensureDirSync(cloudbaseConfigDir)
|
|
17
|
-
|
|
18
|
-
export function getAsyncDB(file: string) {
|
|
19
|
-
const dbPath = path.join(cloudbaseConfigDir, `${file}.json`)
|
|
20
|
-
const adapter = new FileAsync(dbPath)
|
|
21
|
-
const db = low(adapter)
|
|
22
|
-
return db
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function getSyncDB(file: string) {
|
|
26
|
-
const dbPath = path.join(cloudbaseConfigDir, `${file}.json`)
|
|
27
|
-
const adapter = new FileSync(dbPath)
|
|
28
|
-
const db = low(adapter)
|
|
29
|
-
return db
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export class LocalStore {
|
|
33
|
-
db: any
|
|
34
|
-
dbKey: string
|
|
35
|
-
defaults: any
|
|
36
|
-
|
|
37
|
-
constructor(defaults: any, dbKey = 'common') {
|
|
38
|
-
this.defaults = defaults
|
|
39
|
-
this.dbKey = dbKey
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async getDB() {
|
|
43
|
-
const db = this.db || (await getAsyncDB(this.dbKey))
|
|
44
|
-
this.db = db
|
|
45
|
-
return db
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async get(key: string): Promise<any> {
|
|
49
|
-
const defaultValue = this.defaults[key]
|
|
50
|
-
const db = await this.getDB()
|
|
51
|
-
return db.get(key).value() || defaultValue
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async set(key: string, value: any) {
|
|
55
|
-
const db = await this.getDB()
|
|
56
|
-
await db.set(key, value).write()
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async push(key: string, value: any) {
|
|
60
|
-
const db = await this.getDB()
|
|
61
|
-
await db.get(key).push(value).write()
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async delete(key) {
|
|
65
|
-
const db = await this.getDB()
|
|
66
|
-
await db.unset(key).write()
|
|
67
|
-
}
|
|
68
|
-
}
|
|
1
|
+
import os from 'os'
|
|
2
|
+
import fse from 'fs-extra'
|
|
3
|
+
import low from 'lowdb'
|
|
4
|
+
import path from 'path'
|
|
5
|
+
import FileAsync from 'lowdb/adapters/FileAsync'
|
|
6
|
+
import FileSync from 'lowdb/adapters/FileSync'
|
|
7
|
+
import xdgBasedir from 'xdg-basedir'
|
|
8
|
+
|
|
9
|
+
// 系统配置目录
|
|
10
|
+
const configDir = xdgBasedir.config || path.join(os.tmpdir(), '.config')
|
|
11
|
+
// cloudbase 配置目录
|
|
12
|
+
export const cloudbaseConfigDir = path.join(configDir, '.cloudbase')
|
|
13
|
+
|
|
14
|
+
// 确保目录存在
|
|
15
|
+
|
|
16
|
+
fse.ensureDirSync(cloudbaseConfigDir)
|
|
17
|
+
|
|
18
|
+
export function getAsyncDB(file: string) {
|
|
19
|
+
const dbPath = path.join(cloudbaseConfigDir, `${file}.json`)
|
|
20
|
+
const adapter = new FileAsync(dbPath)
|
|
21
|
+
const db = low(adapter)
|
|
22
|
+
return db
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getSyncDB(file: string) {
|
|
26
|
+
const dbPath = path.join(cloudbaseConfigDir, `${file}.json`)
|
|
27
|
+
const adapter = new FileSync(dbPath)
|
|
28
|
+
const db = low(adapter)
|
|
29
|
+
return db
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class LocalStore {
|
|
33
|
+
db: any
|
|
34
|
+
dbKey: string
|
|
35
|
+
defaults: any
|
|
36
|
+
|
|
37
|
+
constructor(defaults: any, dbKey = 'common') {
|
|
38
|
+
this.defaults = defaults
|
|
39
|
+
this.dbKey = dbKey
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async getDB() {
|
|
43
|
+
const db = this.db || (await getAsyncDB(this.dbKey))
|
|
44
|
+
this.db = db
|
|
45
|
+
return db
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async get(key: string): Promise<any> {
|
|
49
|
+
const defaultValue = this.defaults[key]
|
|
50
|
+
const db = await this.getDB()
|
|
51
|
+
return db.get(key).value() || defaultValue
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async set(key: string, value: any) {
|
|
55
|
+
const db = await this.getDB()
|
|
56
|
+
await db.set(key, value).write()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async push(key: string, value: any) {
|
|
60
|
+
const db = await this.getDB()
|
|
61
|
+
await db.get(key).push(value).write()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async delete(key) {
|
|
65
|
+
const db = await this.getDB()
|
|
66
|
+
await db.unset(key).write()
|
|
67
|
+
}
|
|
68
|
+
}
|
package/src/utils/store/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from './auth'
|
|
2
|
-
export * from './db'
|
|
3
|
-
export * from './auth'
|
|
4
|
-
export * from './usage'
|
|
1
|
+
export * from './auth'
|
|
2
|
+
export * from './db'
|
|
3
|
+
export * from './auth'
|
|
4
|
+
export * from './usage'
|
|
5
5
|
export * from './common'
|
package/src/utils/store/usage.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { LocalStore } from './db'
|
|
2
|
-
|
|
3
|
-
const DB_KEY = 'usage'
|
|
4
|
-
|
|
5
|
-
export const usageStore = new LocalStore(
|
|
6
|
-
{
|
|
7
|
-
// 是否同意收集使用数据
|
|
8
|
-
agreeCollect: false,
|
|
9
|
-
commands: []
|
|
10
|
-
},
|
|
11
|
-
DB_KEY
|
|
12
|
-
)
|
|
1
|
+
import { LocalStore } from './db'
|
|
2
|
+
|
|
3
|
+
const DB_KEY = 'usage'
|
|
4
|
+
|
|
5
|
+
export const usageStore = new LocalStore(
|
|
6
|
+
{
|
|
7
|
+
// 是否同意收集使用数据
|
|
8
|
+
agreeCollect: false,
|
|
9
|
+
commands: []
|
|
10
|
+
},
|
|
11
|
+
DB_KEY
|
|
12
|
+
)
|
package/src/utils/template.ts
CHANGED
|
@@ -1,170 +1,170 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import _ from 'lodash'
|
|
3
|
-
import path from 'path'
|
|
4
|
-
import fse from 'fs-extra'
|
|
5
|
-
import { prompt } from 'enquirer'
|
|
6
|
-
import { searchConfig, unzipStream, ConfigParser } from '@cloudbase/toolbox'
|
|
7
|
-
import { CloudBaseError } from '../error'
|
|
8
|
-
import { fetch, fetchStream } from './net'
|
|
9
|
-
|
|
10
|
-
import { logger } from './log'
|
|
11
|
-
import { checkFullAccess } from './fs'
|
|
12
|
-
import { execWithLoading } from './output'
|
|
13
|
-
import { templateDownloadReport } from './reporter'
|
|
14
|
-
|
|
15
|
-
const listUrl = 'https://tcli.service.tcloudbase.com/templates'
|
|
16
|
-
|
|
17
|
-
const getTemplateAddress = (templatePath: string) =>
|
|
18
|
-
`https://7463-tcli-1258016615.tcb.qcloud.la/cloudbase-templates/${templatePath}.zip`
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 将初始化项目的过程拆成多步,以在 new 命令和 tcb 命令中复用
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
// 获取并下载模板,返回项目地址
|
|
25
|
-
export async function downloadTemplate(
|
|
26
|
-
options: {
|
|
27
|
-
appName?: string
|
|
28
|
-
newProject?: boolean
|
|
29
|
-
templateUri?: string
|
|
30
|
-
projectPath?: string
|
|
31
|
-
} = {}
|
|
32
|
-
) {
|
|
33
|
-
let { templateUri, appName, newProject, projectPath = process.cwd() } = options
|
|
34
|
-
// 拉取模板
|
|
35
|
-
const templates = await execWithLoading(() => fetch(listUrl), {
|
|
36
|
-
startTip: '获取应用模板列表中'
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
let templateName
|
|
40
|
-
let tempateId
|
|
41
|
-
|
|
42
|
-
if (templateUri) {
|
|
43
|
-
tempateId = templateUri
|
|
44
|
-
} else {
|
|
45
|
-
// 确定模板名称
|
|
46
|
-
const { selectTemplateName } = await prompt<any>({
|
|
47
|
-
type: 'select',
|
|
48
|
-
name: 'selectTemplateName',
|
|
49
|
-
message: '请选择应用模板',
|
|
50
|
-
choices: templates.map((item) => item.name)
|
|
51
|
-
})
|
|
52
|
-
templateName = selectTemplateName
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const selectedTemplate = templateName
|
|
56
|
-
? templates.find((item) => item.name === templateName)
|
|
57
|
-
: templates.find((item) => item.path === tempateId)
|
|
58
|
-
|
|
59
|
-
if (!selectedTemplate) {
|
|
60
|
-
logger.info(`模板 \`${templateName || tempateId}\` 不存在`)
|
|
61
|
-
return
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 新建项目
|
|
66
|
-
*/
|
|
67
|
-
if (newProject) {
|
|
68
|
-
// appName 不存在时,输入应用
|
|
69
|
-
if (!appName) {
|
|
70
|
-
const { projectName } = await prompt<any>({
|
|
71
|
-
type: 'input',
|
|
72
|
-
name: 'projectName',
|
|
73
|
-
message: '请输入项目名称',
|
|
74
|
-
initial: selectedTemplate.path
|
|
75
|
-
})
|
|
76
|
-
appName = projectName
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// 确定项目权限
|
|
80
|
-
projectPath = path.join(process.cwd(), appName)
|
|
81
|
-
|
|
82
|
-
if (checkFullAccess(projectPath)) {
|
|
83
|
-
const { cover } = await prompt<any>({
|
|
84
|
-
type: 'confirm',
|
|
85
|
-
name: 'cover',
|
|
86
|
-
message: `已存在同名文件夹:${appName},是否覆盖?`,
|
|
87
|
-
initial: false
|
|
88
|
-
})
|
|
89
|
-
// 不覆盖,操作终止
|
|
90
|
-
if (!cover) {
|
|
91
|
-
throw new CloudBaseError('操作终止!')
|
|
92
|
-
} else {
|
|
93
|
-
// 覆盖操作不会删除不冲突的文件夹或文件
|
|
94
|
-
// 删除原有文件夹,防止生成的项目包含用户原有文件
|
|
95
|
-
fse.removeSync(projectPath)
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// 下载并解压文件
|
|
101
|
-
await execWithLoading(
|
|
102
|
-
async () => {
|
|
103
|
-
await templateDownloadReport(selectedTemplate.path, selectedTemplate.name)
|
|
104
|
-
await extractTemplate(projectPath, selectedTemplate.path, selectedTemplate.url)
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
startTip: '下载文件中'
|
|
108
|
-
}
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
return projectPath
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// 下载并解压
|
|
115
|
-
export async function extractTemplate(
|
|
116
|
-
projectPath: string,
|
|
117
|
-
templatePath: string,
|
|
118
|
-
remoteUrl?: string
|
|
119
|
-
) {
|
|
120
|
-
// 文件下载链接
|
|
121
|
-
const url = remoteUrl || getTemplateAddress(templatePath)
|
|
122
|
-
|
|
123
|
-
return fetchStream(url).then(async (res) => {
|
|
124
|
-
if (!res) {
|
|
125
|
-
throw new CloudBaseError('请求异常')
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (res.status !== 200) {
|
|
129
|
-
throw new CloudBaseError('未找到文件')
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// 解压缩文件
|
|
133
|
-
await unzipStream(res.body, projectPath)
|
|
134
|
-
})
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// 初始化项目配置
|
|
138
|
-
export async function initProjectConfig(
|
|
139
|
-
envId: string,
|
|
140
|
-
region: string,
|
|
141
|
-
projectPath: string = process.cwd()
|
|
142
|
-
) {
|
|
143
|
-
// 配置文件初始化,写入环境id
|
|
144
|
-
let filepath = (await searchConfig(projectPath))?.filepath
|
|
145
|
-
|
|
146
|
-
// 配置文件不存在
|
|
147
|
-
if (!filepath) {
|
|
148
|
-
fs.writeFileSync(
|
|
149
|
-
path.join(projectPath, 'cloudbaserc.json'),
|
|
150
|
-
JSON.stringify({
|
|
151
|
-
envId,
|
|
152
|
-
region,
|
|
153
|
-
version: '2.0',
|
|
154
|
-
$schema: 'https://framework-1258016615.tcloudbaseapp.com/schema/latest.json'
|
|
155
|
-
})
|
|
156
|
-
)
|
|
157
|
-
} else {
|
|
158
|
-
// 设置环境 Id
|
|
159
|
-
const configContent = fs.readFileSync(filepath).toString()
|
|
160
|
-
fs.writeFileSync(filepath, configContent.replace('{{envId}}', envId))
|
|
161
|
-
|
|
162
|
-
// 设置 region
|
|
163
|
-
const configPath = filepath || path.join(projectPath, 'cloudbaserc.json')
|
|
164
|
-
const parser = new ConfigParser({
|
|
165
|
-
configPath
|
|
166
|
-
})
|
|
167
|
-
// 把 region 写入到配置文件中
|
|
168
|
-
parser.update('region', region)
|
|
169
|
-
}
|
|
170
|
-
}
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import _ from 'lodash'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import fse from 'fs-extra'
|
|
5
|
+
import { prompt } from 'enquirer'
|
|
6
|
+
import { searchConfig, unzipStream, ConfigParser } from '@cloudbase/toolbox'
|
|
7
|
+
import { CloudBaseError } from '../error'
|
|
8
|
+
import { fetch, fetchStream } from './net'
|
|
9
|
+
|
|
10
|
+
import { logger } from './log'
|
|
11
|
+
import { checkFullAccess } from './fs'
|
|
12
|
+
import { execWithLoading } from './output'
|
|
13
|
+
import { templateDownloadReport } from './reporter'
|
|
14
|
+
|
|
15
|
+
const listUrl = 'https://tcli.service.tcloudbase.com/templates'
|
|
16
|
+
|
|
17
|
+
const getTemplateAddress = (templatePath: string) =>
|
|
18
|
+
`https://7463-tcli-1258016615.tcb.qcloud.la/cloudbase-templates/${templatePath}.zip`
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 将初始化项目的过程拆成多步,以在 new 命令和 tcb 命令中复用
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// 获取并下载模板,返回项目地址
|
|
25
|
+
export async function downloadTemplate(
|
|
26
|
+
options: {
|
|
27
|
+
appName?: string
|
|
28
|
+
newProject?: boolean
|
|
29
|
+
templateUri?: string
|
|
30
|
+
projectPath?: string
|
|
31
|
+
} = {}
|
|
32
|
+
) {
|
|
33
|
+
let { templateUri, appName, newProject, projectPath = process.cwd() } = options
|
|
34
|
+
// 拉取模板
|
|
35
|
+
const templates = await execWithLoading(() => fetch(listUrl), {
|
|
36
|
+
startTip: '获取应用模板列表中'
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
let templateName
|
|
40
|
+
let tempateId
|
|
41
|
+
|
|
42
|
+
if (templateUri) {
|
|
43
|
+
tempateId = templateUri
|
|
44
|
+
} else {
|
|
45
|
+
// 确定模板名称
|
|
46
|
+
const { selectTemplateName } = await prompt<any>({
|
|
47
|
+
type: 'select',
|
|
48
|
+
name: 'selectTemplateName',
|
|
49
|
+
message: '请选择应用模板',
|
|
50
|
+
choices: templates.map((item) => item.name)
|
|
51
|
+
})
|
|
52
|
+
templateName = selectTemplateName
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const selectedTemplate = templateName
|
|
56
|
+
? templates.find((item) => item.name === templateName)
|
|
57
|
+
: templates.find((item) => item.path === tempateId)
|
|
58
|
+
|
|
59
|
+
if (!selectedTemplate) {
|
|
60
|
+
logger.info(`模板 \`${templateName || tempateId}\` 不存在`)
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 新建项目
|
|
66
|
+
*/
|
|
67
|
+
if (newProject) {
|
|
68
|
+
// appName 不存在时,输入应用
|
|
69
|
+
if (!appName) {
|
|
70
|
+
const { projectName } = await prompt<any>({
|
|
71
|
+
type: 'input',
|
|
72
|
+
name: 'projectName',
|
|
73
|
+
message: '请输入项目名称',
|
|
74
|
+
initial: selectedTemplate.path
|
|
75
|
+
})
|
|
76
|
+
appName = projectName
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 确定项目权限
|
|
80
|
+
projectPath = path.join(process.cwd(), appName)
|
|
81
|
+
|
|
82
|
+
if (checkFullAccess(projectPath)) {
|
|
83
|
+
const { cover } = await prompt<any>({
|
|
84
|
+
type: 'confirm',
|
|
85
|
+
name: 'cover',
|
|
86
|
+
message: `已存在同名文件夹:${appName},是否覆盖?`,
|
|
87
|
+
initial: false
|
|
88
|
+
})
|
|
89
|
+
// 不覆盖,操作终止
|
|
90
|
+
if (!cover) {
|
|
91
|
+
throw new CloudBaseError('操作终止!')
|
|
92
|
+
} else {
|
|
93
|
+
// 覆盖操作不会删除不冲突的文件夹或文件
|
|
94
|
+
// 删除原有文件夹,防止生成的项目包含用户原有文件
|
|
95
|
+
fse.removeSync(projectPath)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 下载并解压文件
|
|
101
|
+
await execWithLoading(
|
|
102
|
+
async () => {
|
|
103
|
+
await templateDownloadReport(selectedTemplate.path, selectedTemplate.name)
|
|
104
|
+
await extractTemplate(projectPath, selectedTemplate.path, selectedTemplate.url)
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
startTip: '下载文件中'
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return projectPath
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 下载并解压
|
|
115
|
+
export async function extractTemplate(
|
|
116
|
+
projectPath: string,
|
|
117
|
+
templatePath: string,
|
|
118
|
+
remoteUrl?: string
|
|
119
|
+
) {
|
|
120
|
+
// 文件下载链接
|
|
121
|
+
const url = remoteUrl || getTemplateAddress(templatePath)
|
|
122
|
+
|
|
123
|
+
return fetchStream(url).then(async (res) => {
|
|
124
|
+
if (!res) {
|
|
125
|
+
throw new CloudBaseError('请求异常')
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (res.status !== 200) {
|
|
129
|
+
throw new CloudBaseError('未找到文件')
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 解压缩文件
|
|
133
|
+
await unzipStream(res.body, projectPath)
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 初始化项目配置
|
|
138
|
+
export async function initProjectConfig(
|
|
139
|
+
envId: string,
|
|
140
|
+
region: string,
|
|
141
|
+
projectPath: string = process.cwd()
|
|
142
|
+
) {
|
|
143
|
+
// 配置文件初始化,写入环境id
|
|
144
|
+
let filepath = (await searchConfig(projectPath))?.filepath
|
|
145
|
+
|
|
146
|
+
// 配置文件不存在
|
|
147
|
+
if (!filepath) {
|
|
148
|
+
fs.writeFileSync(
|
|
149
|
+
path.join(projectPath, 'cloudbaserc.json'),
|
|
150
|
+
JSON.stringify({
|
|
151
|
+
envId,
|
|
152
|
+
region,
|
|
153
|
+
version: '2.0',
|
|
154
|
+
$schema: 'https://framework-1258016615.tcloudbaseapp.com/schema/latest.json'
|
|
155
|
+
})
|
|
156
|
+
)
|
|
157
|
+
} else {
|
|
158
|
+
// 设置环境 Id
|
|
159
|
+
const configContent = fs.readFileSync(filepath).toString()
|
|
160
|
+
fs.writeFileSync(filepath, configContent.replace('{{envId}}', envId))
|
|
161
|
+
|
|
162
|
+
// 设置 region
|
|
163
|
+
const configPath = filepath || path.join(projectPath, 'cloudbaserc.json')
|
|
164
|
+
const parser = new ConfigParser({
|
|
165
|
+
configPath
|
|
166
|
+
})
|
|
167
|
+
// 把 region 写入到配置文件中
|
|
168
|
+
parser.update('region', region)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import crypto from 'crypto'
|
|
2
|
-
|
|
3
|
-
// MD5
|
|
4
|
-
export function md5(str = ''): string {
|
|
5
|
-
const hash = crypto.createHash('md5')
|
|
6
|
-
hash.update(str)
|
|
7
|
-
return hash.digest('hex')
|
|
8
|
-
}
|
|
1
|
+
import crypto from 'crypto'
|
|
2
|
+
|
|
3
|
+
// MD5
|
|
4
|
+
export function md5(str = ''): string {
|
|
5
|
+
const hash = crypto.createHash('md5')
|
|
6
|
+
hash.update(str)
|
|
7
|
+
return hash.digest('hex')
|
|
8
|
+
}
|
package/src/utils/tools/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './uid'
|
|
2
|
-
export * from './time'
|
|
3
|
-
export * from './object'
|
|
4
|
-
export * from './encoding'
|
|
1
|
+
export * from './uid'
|
|
2
|
+
export * from './time'
|
|
3
|
+
export * from './object'
|
|
4
|
+
export * from './encoding'
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import _ from 'lodash'
|
|
2
|
-
|
|
3
|
-
// declare module 'lodash' {
|
|
4
|
-
// interface LoDashStatic {
|
|
5
|
-
// deep(v: any, m: any): any;
|
|
6
|
-
// }
|
|
7
|
-
// }
|
|
8
|
-
|
|
9
|
-
_.mixin({
|
|
10
|
-
deep: function(obj, mapper) {
|
|
11
|
-
return mapper(
|
|
12
|
-
_.mapValues(obj, function(v) {
|
|
13
|
-
if (_.isPlainObject(v)) {
|
|
14
|
-
return _.deep(v, mapper)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (_.isArray(v)) {
|
|
18
|
-
return _.map(v, val => _.deep(val, mapper))
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return v
|
|
22
|
-
})
|
|
23
|
-
)
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
export function firstLetterToLowerCase(data: Record<string, any>) {
|
|
28
|
-
return _.deep(data, function(x) {
|
|
29
|
-
return _.mapKeys(x, function(val, key) {
|
|
30
|
-
return key.charAt(0).toLowerCase() + key.slice(1)
|
|
31
|
-
})
|
|
32
|
-
})
|
|
33
|
-
}
|
|
1
|
+
import _ from 'lodash'
|
|
2
|
+
|
|
3
|
+
// declare module 'lodash' {
|
|
4
|
+
// interface LoDashStatic {
|
|
5
|
+
// deep(v: any, m: any): any;
|
|
6
|
+
// }
|
|
7
|
+
// }
|
|
8
|
+
|
|
9
|
+
_.mixin({
|
|
10
|
+
deep: function(obj, mapper) {
|
|
11
|
+
return mapper(
|
|
12
|
+
_.mapValues(obj, function(v) {
|
|
13
|
+
if (_.isPlainObject(v)) {
|
|
14
|
+
return _.deep(v, mapper)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (_.isArray(v)) {
|
|
18
|
+
return _.map(v, val => _.deep(val, mapper))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return v
|
|
22
|
+
})
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
export function firstLetterToLowerCase(data: Record<string, any>) {
|
|
28
|
+
return _.deep(data, function(x) {
|
|
29
|
+
return _.mapKeys(x, function(val, key) {
|
|
30
|
+
return key.charAt(0).toLowerCase() + key.slice(1)
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
}
|