@kdcloudjs/cli 0.0.1
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 +22 -0
- package/package.json +28 -0
- package/src/actions/env/auth/index.js +33 -0
- package/src/actions/env/auth/openapi.js +83 -0
- package/src/actions/env/auth/web.js +3 -0
- package/src/actions/env/config.js +102 -0
- package/src/actions/env/create.js +36 -0
- package/src/actions/env/info.js +28 -0
- package/src/actions/env/list.js +21 -0
- package/src/actions/env/remote.js +59 -0
- package/src/actions/env/remove.js +23 -0
- package/src/actions/env/resolveEnv.js +27 -0
- package/src/actions/env/setDefault.js +20 -0
- package/src/actions/project/constants.js +33 -0
- package/src/actions/project/create/createMetaXml.js +26 -0
- package/src/actions/project/create/index.js +24 -0
- package/src/actions/project/create/kwc.js +25 -0
- package/src/actions/project/create/page.js +42 -0
- package/src/actions/project/create/validate.js +45 -0
- package/src/actions/project/create/writeKwcFiles/index.js +15 -0
- package/src/actions/project/create/writeKwcFiles/lwc.js +25 -0
- package/src/actions/project/create/writeKwcFiles/react.js +49 -0
- package/src/actions/project/create/writeKwcFiles/vue.js +48 -0
- package/src/actions/project/deploy/collect.js +43 -0
- package/src/actions/project/deploy/context.js +26 -0
- package/src/actions/project/deploy/index.js +38 -0
- package/src/actions/project/deploy/projectRoot.js +32 -0
- package/src/actions/project/deploy/updateIsv.js +109 -0
- package/src/actions/project/deploy/upload.js +60 -0
- package/src/actions/project/deploy/validate.js +13 -0
- package/src/actions/project/init/index.js +42 -0
- package/src/actions/project/init/post.js +20 -0
- package/src/actions/project/init/prompts.js +50 -0
- package/src/api/index.js +99 -0
- package/src/api/uploader/index.js +7 -0
- package/src/api/uploader/updateKwcMeta.js +90 -0
- package/src/api/uploader/updatePageMeta.js +94 -0
- package/src/commands/env/auth.js +8 -0
- package/src/commands/env/create.js +2 -0
- package/src/commands/env/delete.js +2 -0
- package/src/commands/env/index.js +72 -0
- package/src/commands/env/info.js +2 -0
- package/src/commands/env/list.js +2 -0
- package/src/commands/env/remote.js +2 -0
- package/src/commands/env/set.js +2 -0
- package/src/commands/project/create.js +8 -0
- package/src/commands/project/deploy.js +2 -0
- package/src/commands/project/index.js +28 -0
- package/src/commands/project/init.js +5 -0
- package/src/index.js +24 -0
- package/src/utils/checkUpdate.js +18 -0
- package/src/utils/crypto.js +53 -0
- package/src/utils/download.js +21 -0
- package/src/utils/index.js +9 -0
- package/src/utils/log.js +20 -0
- package/src/utils/printTable.js +28 -0
- package/src/utils/projectConfig.js +32 -0
- package/src/utils/prompts.js +14 -0
- package/src/utils/validator.js +14 -0
package/README.MD
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# kd
|
|
2
|
+
# 起步
|
|
3
|
+
#### 安装
|
|
4
|
+
```
|
|
5
|
+
npm install -g @kdcloudjs/cli
|
|
6
|
+
# OR
|
|
7
|
+
yarn global add @kdcloudjs/cli
|
|
8
|
+
```
|
|
9
|
+
#### 初始化项目:
|
|
10
|
+
```
|
|
11
|
+
kd project init demo
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
#### 创建组件
|
|
15
|
+
```
|
|
16
|
+
kd project create kwcdemo --type kwc
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
#### 创建页面元数据
|
|
20
|
+
```
|
|
21
|
+
kd project create kwcdemo --type page
|
|
22
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kdcloudjs/cli",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Kingdee CLI",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"cli",
|
|
10
|
+
"kd"
|
|
11
|
+
],
|
|
12
|
+
"bin": {
|
|
13
|
+
"kd": "./src/index.js"
|
|
14
|
+
},
|
|
15
|
+
"author": "rubing_yan@kingdee.com",
|
|
16
|
+
"license": "ISC",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"axios": "^1.12.2",
|
|
19
|
+
"chalk": "4.1.2",
|
|
20
|
+
"commander": "12.1.0",
|
|
21
|
+
"download-git-repo": "^3.0.2",
|
|
22
|
+
"form-data": "^4.0.4",
|
|
23
|
+
"ora": "5.4.1",
|
|
24
|
+
"prompts": "2.4.2",
|
|
25
|
+
"update-notifier": "^7.3.1"
|
|
26
|
+
},
|
|
27
|
+
"type": "commonjs"
|
|
28
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
const { loadDefaultEnv, getEnvByName } = require('../config')
|
|
5
|
+
const webAuth = require('./web')
|
|
6
|
+
const openapiAuth = require('./openapi')
|
|
7
|
+
const { error } = require('../../../utils/log')
|
|
8
|
+
|
|
9
|
+
module.exports = async function doAuth(options ={}) {
|
|
10
|
+
let { type, env } = options
|
|
11
|
+
|
|
12
|
+
if (env === undefined) {
|
|
13
|
+
env = loadDefaultEnv()?.name
|
|
14
|
+
if (!env) {
|
|
15
|
+
error('❌ No environment specified and default environment is invalid, cannot authenticate') // 待产品提供
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const envInfo = getEnvByName(env)
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
if (type === 'web') {
|
|
24
|
+
return webAuth({ env: envInfo })
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (type === 'openapi') {
|
|
28
|
+
return openapiAuth({ env: envInfo })
|
|
29
|
+
}
|
|
30
|
+
} catch (e) {
|
|
31
|
+
error(`❌ Authentication failed: ${e.message}`)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const { loadEnv, saveEnv } = require('../config')
|
|
2
|
+
const { getAllDataCenters, getAccessToken, getIsv } = require('../../../api')
|
|
3
|
+
const { safePrompts } = require('../../../utils/prompts')
|
|
4
|
+
const { encrypt } = require('../../../utils/crypto')
|
|
5
|
+
const { isValidUrl } = require('../../../utils/validator')
|
|
6
|
+
const { error } = require('../../../utils/log')
|
|
7
|
+
module.exports = async function authOpenAPI(options = {}) {
|
|
8
|
+
const { env } = options
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const { url, name }= env || {}
|
|
12
|
+
if (!isValidUrl(url)) {
|
|
13
|
+
console.error('Invalid URL format:', url)
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 获取数据中心
|
|
18
|
+
let dataCenter
|
|
19
|
+
const dataCenters = await getAllDataCenters(url) || []
|
|
20
|
+
if (dataCenters.length === 0) return
|
|
21
|
+
|
|
22
|
+
const datacenterPrompt = {
|
|
23
|
+
type: 'select',
|
|
24
|
+
name: 'datacenterId',
|
|
25
|
+
message: 'Please select a data center',
|
|
26
|
+
choices: [...dataCenters]
|
|
27
|
+
}
|
|
28
|
+
const dcRes = await safePrompts(datacenterPrompt)
|
|
29
|
+
dataCenter = dataCenters.find(dc => dc.value === dcRes.datacenterId) || {}
|
|
30
|
+
|
|
31
|
+
// 获取client信息
|
|
32
|
+
const clientRes = await safePrompts([
|
|
33
|
+
{
|
|
34
|
+
type: 'text',
|
|
35
|
+
name: 'client_id',
|
|
36
|
+
message: '*Please enter OpenAPI third-party app client_id',
|
|
37
|
+
validate: v => !!v || 'OpenAPI third-party app client_id cannot be empty'
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: 'text',
|
|
41
|
+
name: 'client_secret',
|
|
42
|
+
message: '*Please enter OpenAPI third-party app client_secret',
|
|
43
|
+
validate: v => !!v || 'OpenAPI third-party app client_secret cannot be empty'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: 'text',
|
|
47
|
+
name: 'username',
|
|
48
|
+
message: '*Please enter OpenAPI third-party app username',
|
|
49
|
+
validate: v => !!v || 'OpenAPI third-party app username cannot be empty'
|
|
50
|
+
}
|
|
51
|
+
])
|
|
52
|
+
|
|
53
|
+
// 获取token
|
|
54
|
+
const getAccessTokenParams = {
|
|
55
|
+
client_id: clientRes.client_id,
|
|
56
|
+
client_secret: clientRes.client_secret,
|
|
57
|
+
username: clientRes.username,
|
|
58
|
+
accountId: dataCenter?.accountId
|
|
59
|
+
}
|
|
60
|
+
const tokenData = await getAccessToken(url, getAccessTokenParams) || {}
|
|
61
|
+
let token = tokenData.access_token || ''
|
|
62
|
+
if (!token) {
|
|
63
|
+
error('Failed to obtain access_token. Please check your credentials and reauthentication.')
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 获取isv
|
|
68
|
+
const { isv } = await getIsv(url, token) || {}
|
|
69
|
+
if (!isv) return
|
|
70
|
+
|
|
71
|
+
// 环境信息更新存储
|
|
72
|
+
const envs = loadEnv()
|
|
73
|
+
getAccessTokenParams.client_secret = encrypt(getAccessTokenParams.client_secret)
|
|
74
|
+
envs[name] = Object.assign({}, env, getAccessTokenParams, {
|
|
75
|
+
access_token: encrypt(token),
|
|
76
|
+
isv
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
saveEnv(envs)
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error('auth error:', error)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const os = require('os')
|
|
4
|
+
const { warn } = require('../../utils/log')
|
|
5
|
+
|
|
6
|
+
const KD_DIR = path.join(os.homedir(), '.kd')
|
|
7
|
+
const CONFIG_FILE = path.join(KD_DIR, 'config.json')
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 确保 ~/.kd 目录存在
|
|
11
|
+
*/
|
|
12
|
+
function ensureKdDir() {
|
|
13
|
+
if (!fs.existsSync(KD_DIR)) {
|
|
14
|
+
fs.mkdirSync(KD_DIR, { recursive: true })
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 读取完整配置(容错)
|
|
20
|
+
*/
|
|
21
|
+
function loadConfig() {
|
|
22
|
+
try {
|
|
23
|
+
if (!fs.existsSync(CONFIG_FILE)) {
|
|
24
|
+
return {}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const content = fs.readFileSync(CONFIG_FILE, 'utf-8').trim()
|
|
28
|
+
if (!content) {
|
|
29
|
+
return {}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return JSON.parse(content)
|
|
33
|
+
} catch (e) {
|
|
34
|
+
warn('⚠️ ~/.kd/config.json parse failed, using empty config')
|
|
35
|
+
return {}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 写入完整配置(原子性写入)
|
|
41
|
+
*/
|
|
42
|
+
function saveConfig(config) {
|
|
43
|
+
try {
|
|
44
|
+
ensureKdDir()
|
|
45
|
+
|
|
46
|
+
const tmpFile = `${CONFIG_FILE}.tmp`
|
|
47
|
+
|
|
48
|
+
fs.writeFileSync(
|
|
49
|
+
tmpFile,
|
|
50
|
+
JSON.stringify(config, null, 2),
|
|
51
|
+
'utf-8'
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
fs.renameSync(tmpFile, CONFIG_FILE)
|
|
55
|
+
} catch (e) {
|
|
56
|
+
warn('⚠️ Failed to save ~/.kd/config.json')
|
|
57
|
+
return {}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 读取 env 配置
|
|
63
|
+
*/
|
|
64
|
+
function loadEnv() {
|
|
65
|
+
const config = loadConfig()
|
|
66
|
+
return config.env || {}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 读取 env 默认配置
|
|
71
|
+
*/
|
|
72
|
+
function loadDefaultEnv() {
|
|
73
|
+
const envs = loadEnv()
|
|
74
|
+
const envsList = Object.values(envs) || []
|
|
75
|
+
return envsList.find(env => env.default) || {}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 根据环境名获取环境配置
|
|
80
|
+
*/
|
|
81
|
+
function getEnvByName(name) {
|
|
82
|
+
const envs = loadEnv() || {}
|
|
83
|
+
return envs[name] || {}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 保存 env 配置(不破坏其他字段)
|
|
88
|
+
*/
|
|
89
|
+
function saveEnv(env) {
|
|
90
|
+
const config = loadConfig()
|
|
91
|
+
config.env = env
|
|
92
|
+
saveConfig(config)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = {
|
|
96
|
+
loadConfig,
|
|
97
|
+
saveConfig,
|
|
98
|
+
loadEnv,
|
|
99
|
+
saveEnv,
|
|
100
|
+
loadDefaultEnv,
|
|
101
|
+
getEnvByName
|
|
102
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const { loadEnv, saveEnv } = require('./config')
|
|
2
|
+
const { info, error } = require('../../utils/log')
|
|
3
|
+
|
|
4
|
+
module.exports = function createEnv(name, options) {
|
|
5
|
+
const url = options?.url
|
|
6
|
+
if (!url) {
|
|
7
|
+
error('--url is required')
|
|
8
|
+
return
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// url 校验
|
|
12
|
+
const urlPattern = /^https?:\/\/.+/
|
|
13
|
+
if (!urlPattern.test(url)) {
|
|
14
|
+
error(`Invalid URL: ${url}`)
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const envs = loadEnv()
|
|
19
|
+
|
|
20
|
+
if (envs[name]) {
|
|
21
|
+
error(`Environment ${name} already exists`)
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const isFirst = Object.keys(envs).length === 0
|
|
26
|
+
|
|
27
|
+
envs[name] = {
|
|
28
|
+
name,
|
|
29
|
+
url,
|
|
30
|
+
default: isFirst
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
saveEnv(envs)
|
|
34
|
+
|
|
35
|
+
info(`✅ Environment ${name} created successfully${isFirst ? ' (set as default)' : ''}`)
|
|
36
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const { loadEnv } = require('./config')
|
|
2
|
+
const { info, error } = require('../../utils/log')
|
|
3
|
+
const printTable = require('../../utils/printTable')
|
|
4
|
+
|
|
5
|
+
module.exports = function envInfo() {
|
|
6
|
+
const envs = loadEnv()
|
|
7
|
+
const envsList = Object.values(envs)
|
|
8
|
+
if (!envsList?.length) {
|
|
9
|
+
error('No environments configured')
|
|
10
|
+
return
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const current = envsList.find(e => e.default)
|
|
14
|
+
|
|
15
|
+
if (!current) {
|
|
16
|
+
error('No default environment configured')
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
info('Current Environment:')
|
|
21
|
+
const headers = ['Name', 'URL', 'Default']
|
|
22
|
+
const rows = [current].map(env => [
|
|
23
|
+
env.name,
|
|
24
|
+
env.url || '',
|
|
25
|
+
env.default ? '★' : ''
|
|
26
|
+
])
|
|
27
|
+
printTable(headers, rows)
|
|
28
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const { loadEnv } = require('./config')
|
|
2
|
+
const { warn } = require('../../utils/log')
|
|
3
|
+
const printTable = require('../../utils/printTable')
|
|
4
|
+
|
|
5
|
+
module.exports = function listEnv() {
|
|
6
|
+
const envs = loadEnv()
|
|
7
|
+
const names = Object.keys(envs)
|
|
8
|
+
|
|
9
|
+
if (names.length === 0) {
|
|
10
|
+
warn('No environment configuration found')
|
|
11
|
+
return
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const headers = ['Name', 'URL', 'Default']
|
|
15
|
+
const rows = names.map(name => [
|
|
16
|
+
name,
|
|
17
|
+
envs[name].url || '',
|
|
18
|
+
envs[name].default ? '★' : ''
|
|
19
|
+
])
|
|
20
|
+
printTable(headers, rows)
|
|
21
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const { exec } = require('child_process')
|
|
2
|
+
const { getEnvByName, loadDefaultEnv } = require('./config')
|
|
3
|
+
const { error, info } = require('../../utils/log')
|
|
4
|
+
|
|
5
|
+
module.exports = async function remote(envName, options) {
|
|
6
|
+
const { formId } = options
|
|
7
|
+
|
|
8
|
+
if (!formId) {
|
|
9
|
+
error('Error: --form-id (-f) is required')
|
|
10
|
+
return
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let env
|
|
14
|
+
if (envName) {
|
|
15
|
+
env = getEnvByName(envName)
|
|
16
|
+
if (!env) {
|
|
17
|
+
error(`Error: Environment "${envName}" not found`)
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
} else {
|
|
21
|
+
env = loadDefaultEnv()
|
|
22
|
+
if (!env || !env.name) {
|
|
23
|
+
error('Error: No environment specified and no default environment found')
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
info(`Using default environment: ${env.name}`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!env.url) {
|
|
30
|
+
error(`Error: Environment "${env.name}" has no URL configured`)
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const targetUrl = new URL(env.url)
|
|
36
|
+
targetUrl.searchParams.append('formId', formId)
|
|
37
|
+
targetUrl.searchParams.append('kdkwc_cdn', 'http://localhost:3333')
|
|
38
|
+
|
|
39
|
+
const finalUrl = targetUrl.toString()
|
|
40
|
+
info(`Opening: ${finalUrl}`)
|
|
41
|
+
|
|
42
|
+
let cmd
|
|
43
|
+
if (process.platform === 'win32') {
|
|
44
|
+
cmd = `start "" "${finalUrl}"`
|
|
45
|
+
} else if (process.platform === 'darwin') {
|
|
46
|
+
cmd = `open "${finalUrl}"`
|
|
47
|
+
} else {
|
|
48
|
+
cmd = `xdg-open "${finalUrl}"`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
exec(cmd, (err) => {
|
|
52
|
+
if (err) {
|
|
53
|
+
error(`Failed to open browser: ${err.message}`)
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
} catch (e) {
|
|
57
|
+
error(`Invalid Environment URL: ${env.url}`)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const { loadEnv, saveEnv } = require('./config')
|
|
2
|
+
const { info, error } = require('../../utils/log')
|
|
3
|
+
|
|
4
|
+
module.exports = function removeEnv(name) {
|
|
5
|
+
const envs = loadEnv()
|
|
6
|
+
|
|
7
|
+
if (!envs[name]) {
|
|
8
|
+
error(`Environment ${name} does not exist`)
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const wasDefault = envs[name].default
|
|
13
|
+
delete envs[name]
|
|
14
|
+
|
|
15
|
+
let first
|
|
16
|
+
if (wasDefault) {
|
|
17
|
+
first = Object.values(envs)[0]
|
|
18
|
+
if (first) first.default = true
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
saveEnv(envs)
|
|
22
|
+
info(`✅ Environment ${name} deleted${first ? `, default environment switched to ${first?.name || 'none'}` : ''}`)
|
|
23
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const { loadDefaultEnv, getEnvByName } = require('./config')
|
|
2
|
+
const { error } = require('../../utils/log')
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 根据环境名解析环境
|
|
6
|
+
* - 未传:使用默认环境
|
|
7
|
+
* - 已传:使用指定环境
|
|
8
|
+
*/
|
|
9
|
+
module.exports = function resolveEnv(envName) {
|
|
10
|
+
let name = envName
|
|
11
|
+
|
|
12
|
+
if (name === undefined) {
|
|
13
|
+
name = loadDefaultEnv()?.name
|
|
14
|
+
if (!name) {
|
|
15
|
+
error('❌ No environment specified and no default environment exists')
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const env = getEnvByName(name)
|
|
21
|
+
if (!env?.name) {
|
|
22
|
+
error(`❌ Environment ${name} does not exist`)
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return { envName: name, env }
|
|
27
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const { loadEnv, saveEnv } = require('./config')
|
|
2
|
+
const { info, error } = require('../../utils/log')
|
|
3
|
+
|
|
4
|
+
module.exports = function setDefault(name) {
|
|
5
|
+
const envs = loadEnv()
|
|
6
|
+
|
|
7
|
+
if (!envs[name]) {
|
|
8
|
+
error(`Environment ${name} does not exist`)
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
Object.values(envs).forEach(env => {
|
|
13
|
+
env.default = false
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
envs[name].default = true
|
|
17
|
+
saveEnv(envs)
|
|
18
|
+
|
|
19
|
+
info(`✅ ${name} has been set as the default environment`)
|
|
20
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
PROJECT_TYPES: {
|
|
3
|
+
KWC: 'kwc',
|
|
4
|
+
PAGE: 'page'
|
|
5
|
+
},
|
|
6
|
+
|
|
7
|
+
TEMPLATES: {
|
|
8
|
+
lwc_js: 'direct:https://github.com/kingdee/cli-template.git#kwc-project',
|
|
9
|
+
react_ts: 'direct:https://github.com/kingdee/cli-template.git#kwc-project-react',
|
|
10
|
+
react_js: 'direct:https://github.com/kingdee/cli-template.git#kwc-project-react-js',
|
|
11
|
+
vue_ts: 'direct:https://github.com/kingdee/cli-template.git#kwc-project-vue',
|
|
12
|
+
vue_js: 'direct:https://github.com/kingdee/cli-template.git#kwc-project-vue-js'
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
INNER_TEMPLATES: {
|
|
16
|
+
lwc_js: 'direct:http://gitlab.kingdee.com/bos-cli-template/kd-custom-control-template.git#kwc-project',
|
|
17
|
+
react_ts: 'direct:http://gitlab.kingdee.com/bos-cli-template/kd-custom-control-template.git#kwc-project-react',
|
|
18
|
+
react_js: 'direct:http://gitlab.kingdee.com/bos-cli-template/kd-custom-control-template.git#kwc-project-react-js',
|
|
19
|
+
vue_ts: 'direct:http://gitlab.kingdee.com/bos-cli-template/kd-custom-control-template.git#kwc-project-vue',
|
|
20
|
+
vue_js: 'direct:http://gitlab.kingdee.com/bos-cli-template/kd-custom-control-template.git#kwc-project-vue-js'
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
FRAMEWORKS: {
|
|
24
|
+
React: 'react',
|
|
25
|
+
Vue: 'vue',
|
|
26
|
+
LWC: 'lwc'
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
LANGUAGES: {
|
|
30
|
+
TypeScript: 'ts',
|
|
31
|
+
JavaScript: 'js'
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module.exports = function createMetaXml({ name, moduleId, framework }) {
|
|
2
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
3
|
+
<KingdeeComponentBundle
|
|
4
|
+
xmlns="http://dev.kingdee.com/2025/10/metadata"
|
|
5
|
+
>
|
|
6
|
+
<version></version>
|
|
7
|
+
<name>${name}</name>
|
|
8
|
+
<masterLabel>${name}</masterLabel>
|
|
9
|
+
<isv></isv>
|
|
10
|
+
<moduleid>${moduleId}</moduleid>
|
|
11
|
+
<framework>${framework}</framework>
|
|
12
|
+
<targets>
|
|
13
|
+
<target>BaseFormModel</target>
|
|
14
|
+
<target>BillFormModel</target>
|
|
15
|
+
<target>DynamicFormModel</target>
|
|
16
|
+
<target>MobileBillFormModel</target>
|
|
17
|
+
<target>MobileFormModel</target>
|
|
18
|
+
<target>KWCFormModel</target>
|
|
19
|
+
</targets>
|
|
20
|
+
<targetConfigs>
|
|
21
|
+
<targetConfig>
|
|
22
|
+
<targets>BaseFormModel,BillFormModel,DynamicFormModel,MobileBillFormModel,MobileFormModel,KWCFormModel</targets>
|
|
23
|
+
</targetConfig>
|
|
24
|
+
</targetConfigs>
|
|
25
|
+
</KingdeeComponentBundle>`
|
|
26
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const { PROJECT_TYPES } = require('../constants')
|
|
2
|
+
const validate = require('./validate')
|
|
3
|
+
const createKwc = require('./kwc')
|
|
4
|
+
const createPage = require('./page')
|
|
5
|
+
const { error } = require('../../../utils/log')
|
|
6
|
+
const { getConfig } = require('../../../utils/projectConfig')
|
|
7
|
+
|
|
8
|
+
module.exports = async function create({ name, type }) {
|
|
9
|
+
const cwd = process.cwd()
|
|
10
|
+
const config = getConfig(cwd) || {}
|
|
11
|
+
validate({ name, type, ...config })
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
if (type === PROJECT_TYPES.KWC) {
|
|
15
|
+
return createKwc(name, cwd, config)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (type === PROJECT_TYPES.PAGE) {
|
|
19
|
+
return createPage(name, cwd)
|
|
20
|
+
}
|
|
21
|
+
} catch (e) {
|
|
22
|
+
error(`❌ Failed to create: ${e.message}`)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const { info } = require('../../../utils/log')
|
|
4
|
+
const writeKwcFiles = require('./writeKwcFiles')
|
|
5
|
+
|
|
6
|
+
module.exports = function createKwc(name, cwd, config) {
|
|
7
|
+
const kwcRoot = path.join(cwd, 'app', 'kwc')
|
|
8
|
+
const dir = path.join(kwcRoot, name)
|
|
9
|
+
|
|
10
|
+
if (!fs.existsSync(kwcRoot)) {
|
|
11
|
+
throw new Error('Directory app/kwc not found')
|
|
12
|
+
}
|
|
13
|
+
if (fs.existsSync(dir)) {
|
|
14
|
+
throw new Error(`Component ${name} already exists`)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
console.time('🕒 KWC component creation time')
|
|
18
|
+
fs.mkdirSync(dir, { recursive: true })
|
|
19
|
+
|
|
20
|
+
writeKwcFiles({ dir, name, ...config })
|
|
21
|
+
|
|
22
|
+
info(`✅ KWC Component ${name} created successfully`)
|
|
23
|
+
console.timeEnd('🕒 KWC component creation time')
|
|
24
|
+
}
|
|
25
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const { info } = require('../../../utils/log')
|
|
4
|
+
|
|
5
|
+
module.exports = function createPage(name, cwd) {
|
|
6
|
+
const pagesDir = path.join(cwd, 'app/pages')
|
|
7
|
+
|
|
8
|
+
if (!fs.existsSync(pagesDir)) {
|
|
9
|
+
throw new Error('Directory app/pages not found')
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const file = path.join(pagesDir, `${name}.page-meta.kwp`)
|
|
13
|
+
if (fs.existsSync(file)) {
|
|
14
|
+
throw new Error(`Page ${name} already exists`)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
console.time(`🕒 Page ${name} creation time`)
|
|
18
|
+
fs.writeFileSync(file, createPageXml(name))
|
|
19
|
+
|
|
20
|
+
info(`✅ Page ${name} created successfully`)
|
|
21
|
+
console.timeEnd(`🕒 Page ${name} creation time`)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function createPageXml(name) {
|
|
25
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
26
|
+
|
|
27
|
+
<Page>
|
|
28
|
+
<name>${name}</name>
|
|
29
|
+
<masterLabel>${name}</masterLabel>
|
|
30
|
+
<template>oneregion</template>
|
|
31
|
+
<app></app>
|
|
32
|
+
<isv></isv>
|
|
33
|
+
<version>1</version>
|
|
34
|
+
<regions>
|
|
35
|
+
<region>
|
|
36
|
+
<name>region1</name>
|
|
37
|
+
<controls>
|
|
38
|
+
</controls>
|
|
39
|
+
</region>
|
|
40
|
+
</regions>
|
|
41
|
+
</Page>`
|
|
42
|
+
}
|