cloudcc-cli 2.3.3 → 2.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.json +28 -1
- package/.cursor/skills/cloudcc-cli-dev/SKILL.md +175 -0
- package/.cursor/skills/cloudcc-dev-skill/SKILL.md +71 -0
- package/README.md +65 -7
- package/bin/cc.js +106 -28
- package/bin/index.js +54 -53
- package/mcp/cliRunner.js +11 -4
- package/mcp/index.js +12 -2
- package/mcp/tools/CloudCC Development Overview/handler.js +1 -1
- package/mcp/tools/JSP Migrator/handler.js +46 -0
- package/package.json +4 -5
- package/src/button/create.js +169 -0
- package/src/button/delete.js +35 -0
- package/src/button/doc.js +36 -0
- package/src/button/docs/devguide.md +133 -0
- package/src/button/docs/introduction.md +60 -0
- package/src/button/get.js +60 -0
- package/src/button/index.js +20 -0
- package/src/classes/docs/introduction.md +0 -20
- package/src/fields/create.js +12 -0
- package/src/identityProvider/create.js +78 -0
- package/src/identityProvider/delete.js +61 -0
- package/src/identityProvider/doc.js +46 -0
- package/src/identityProvider/docs/devguide.md +107 -0
- package/src/identityProvider/docs/introduction.md +31 -0
- package/src/identityProvider/download.js +105 -0
- package/src/identityProvider/get.js +70 -0
- package/src/identityProvider/index.js +12 -0
- package/src/menu/create-object.js +1 -0
- package/src/menu/create-page.js +1 -0
- package/src/menu/create-script.js +1 -0
- package/src/menu/create-site.js +1 -0
- package/src/object/create.js +2 -1
- package/src/object/docs/devguide.md +1 -5
- package/src/permission/add.js +164 -0
- package/src/permission/assign.js +84 -0
- package/src/permission/docs/devguide.md +238 -0
- package/src/permission/docs/introduction.md +200 -0
- package/src/permission/get.js +107 -0
- package/src/permission/index.js +10 -0
- package/src/permission/remove.js +145 -0
- package/src/project/docs/devguide.md +7 -6
- package/src/role/create.js +2 -1
- package/src/role/delete.js +1 -0
- package/src/singleSignOn/delete.js +61 -0
- package/src/singleSignOn/doc.js +46 -0
- package/src/singleSignOn/docs/devguide.md +61 -0
- package/src/singleSignOn/docs/introduction.md +3 -0
- package/src/singleSignOn/get.js +70 -0
- package/src/singleSignOn/index.js +10 -0
- package/src/staticResource/docs/introduction.md +44 -1
- package/src/user/create.js +502 -19
- package/src/validationRule/create.js +153 -0
- package/src/validationRule/delete.js +60 -0
- package/src/validationRule/doc.js +46 -0
- package/src/validationRule/docs/devguide.md +76 -0
- package/src/validationRule/docs/introduction.md +122 -0
- package/src/validationRule/get.js +47 -0
- package/src/validationRule/index.js +10 -0
- package/src/version/actionHelp.js +25 -0
- package/src/version/docs.js +26 -0
- package/src/version/doctor.js +25 -0
- package/src/version/get.js +7 -1
- package/src/version/help.js +47 -0
- package/src/version/index.js +9 -2
- package/src/version/initHelp.js +13 -0
- package/src/version/listModuleCommands.js +241 -0
- package/src/version/stats.js +44 -0
- package/src/version/uninstall.js +30 -0
- package/src/version/update.js +13 -0
- package/utils/checkVersion.js +31 -2
- package/utils/commandStats.js +94 -0
- package/utils/formatReleaseNotes.js +312 -0
- package/utils/readmeReleases.js +69 -0
- package/.cloudcc-cache.json +0 -38
- package/.cursor/skills/cloudcc-cli-dev.zip +0 -0
- package/.cursor/skills/cloudcc-cli-usage/SKILL.md +0 -68
- package/build/component-CCPlugin1774500425584.common.js +0 -831
- package/build/component-CCPlugin1774500425584.common.js.map +0 -1
- package/build/component-CCPlugin1774500425584.css +0 -1
- package/build/component-CCPlugin1774500425584.umd.js +0 -874
- package/build/component-CCPlugin1774500425584.umd.js.map +0 -1
- package/build/component-CCPlugin1774500425584.umd.min.js +0 -8
- package/build/component-CCPlugin1774500425584.umd.min.js.map +0 -1
- package/build/demo.html +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const cc = {};
|
|
2
|
+
cc.doc = require("./doc");
|
|
3
|
+
cc.get = require("./get");
|
|
4
|
+
cc.create = require("./create");
|
|
5
|
+
cc.delete = require("./delete");
|
|
6
|
+
|
|
7
|
+
function Button(action, argvs) {
|
|
8
|
+
if (action === "doc") {
|
|
9
|
+
cc.doc(argvs);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (action === "create") {
|
|
13
|
+
// cc create button <projectPath> <objid> <label> [name] [btnType] [event]
|
|
14
|
+
cc.create(argvs[2], argvs[3], argvs[4], argvs[5], argvs[6], argvs[7]);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
cc[action](argvs[2], argvs[3], argvs[4]);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = Button;
|
|
@@ -232,26 +232,6 @@
|
|
|
232
232
|
|
|
233
233
|
---
|
|
234
234
|
|
|
235
|
-
## 11. 线上现状观察(来自当前环境)
|
|
236
|
-
|
|
237
|
-
线上共 87 个自定义类,命名与职责呈现明显分层趋势:
|
|
238
|
-
|
|
239
|
-
- `Controller` 类:承接流程入口与动作编排
|
|
240
|
-
- `Util` 类:沉淀通用方法与查询能力
|
|
241
|
-
- `Service` 类:承担外部集成与业务服务
|
|
242
|
-
- `Handler` 类:承接触发器下沉逻辑
|
|
243
|
-
- `Bot` 类:承载智能助手相关业务
|
|
244
|
-
|
|
245
|
-
从源码统计看,当前环境中大量类已在使用:
|
|
246
|
-
|
|
247
|
-
- `CCService`(数据 CRUD 与查询)
|
|
248
|
-
- JSON 处理能力
|
|
249
|
-
- 异常机制(`Exception` 相关)
|
|
250
|
-
|
|
251
|
-
这说明自定义类已成为该环境中“复杂逻辑与复用能力”的核心载体。
|
|
252
|
-
|
|
253
|
-
---
|
|
254
|
-
|
|
255
235
|
## 12. 一句话结论
|
|
256
236
|
|
|
257
237
|
当业务进入“多对象、复杂规则、跨系统、可复用、可治理”阶段时,CloudCC 自定义类是最关键的后端实现手段:它不仅能实现功能,更能提升系统长期可维护性与稳定性。
|
package/src/fields/create.js
CHANGED
|
@@ -180,6 +180,18 @@ async function create(argvs) {
|
|
|
180
180
|
let lookupObj = argvs[6];
|
|
181
181
|
fieldData = M(objid, nameLabel, apiname, lookupObj, briefData.data);
|
|
182
182
|
}
|
|
183
|
+
// 查询页面布局列表,取第一个绑定到字段
|
|
184
|
+
if (fieldData) {
|
|
185
|
+
const layoutRes = await postClass(
|
|
186
|
+
config.setupSvc + "/api/layout/newpage",
|
|
187
|
+
{ objid: objid },
|
|
188
|
+
config.accessToken
|
|
189
|
+
);
|
|
190
|
+
if (layoutRes && layoutRes.result && Array.isArray(layoutRes.data) && layoutRes.data.length > 0) {
|
|
191
|
+
fieldData.layoutIds = layoutRes.data[0].id;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
fieldData.remark = "auto created by cloudcc-cli ai agent";
|
|
183
195
|
// 发送请求到服务器
|
|
184
196
|
const result = await postClass(
|
|
185
197
|
config.setupSvc + "/api/fieldSetup/save",
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const chalk = require("chalk");
|
|
2
|
+
const { postClass } = require("../../utils/http");
|
|
3
|
+
const { getPackageJson } = require("../../utils/config");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 创建身份提供商
|
|
7
|
+
* 接口: /samlSp/save
|
|
8
|
+
* 用法:cc create identityProvider <path> <entityid> <acsurl>
|
|
9
|
+
*/
|
|
10
|
+
async function create(argvs) {
|
|
11
|
+
try {
|
|
12
|
+
const projectPath = argvs[2] || process.cwd();
|
|
13
|
+
const entityid = argvs[3];
|
|
14
|
+
const acsurl = argvs[4];
|
|
15
|
+
|
|
16
|
+
if (!entityid || !acsurl) {
|
|
17
|
+
console.error();
|
|
18
|
+
console.error(chalk.red("Error: 缺少必需参数"));
|
|
19
|
+
console.error(chalk.yellow("用法: cc create identityProvider <path> <entityid> <acsurl>"));
|
|
20
|
+
console.error(chalk.yellow("示例: cc create identityProvider . 'http://testdev.cloudcc.cn/ccdomaingateway/apisvc' 'http://testdev.cloudcc.cn/ccdomaingateway/apisvc/saml2/sp/sso/acs'"));
|
|
21
|
+
console.error();
|
|
22
|
+
throw new Error("缺少必需参数: entityid 和 acsurl");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const config = await getPackageJson(projectPath);
|
|
26
|
+
if (!config || !config.accessToken) {
|
|
27
|
+
console.error();
|
|
28
|
+
console.error(chalk.red("Error: 配置未找到或 accessToken 缺失"));
|
|
29
|
+
console.error();
|
|
30
|
+
throw new Error("配置未找到或 accessToken 缺失");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
console.error();
|
|
34
|
+
console.error(chalk.green(`Creating identity provider, please wait...`));
|
|
35
|
+
console.error();
|
|
36
|
+
|
|
37
|
+
// 构建请求参数
|
|
38
|
+
const body = {
|
|
39
|
+
entityid: entityid,
|
|
40
|
+
acsurl: acsurl,
|
|
41
|
+
issuername: "",
|
|
42
|
+
nameidtype: "FederationId",
|
|
43
|
+
nameidformat: "1",
|
|
44
|
+
enablelogout: false,
|
|
45
|
+
logouturl: "",
|
|
46
|
+
custattrname: "",
|
|
47
|
+
id: ""
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const res = await postClass(
|
|
51
|
+
config.setupSvc + "/api/samlSp/save",
|
|
52
|
+
body,
|
|
53
|
+
config.accessToken
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
if (res && res.result) {
|
|
57
|
+
console.error();
|
|
58
|
+
console.error(chalk.green("Success! Identity provider created."));
|
|
59
|
+
if (res.data) {
|
|
60
|
+
console.error(chalk.gray(`Response: ${JSON.stringify(res.data, null, 2)}`));
|
|
61
|
+
}
|
|
62
|
+
console.error();
|
|
63
|
+
return res;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const msg = res && (res.returnInfo || res.message) ? (res.returnInfo || res.message) : "Unknown error";
|
|
67
|
+
console.error();
|
|
68
|
+
console.error(chalk.red("Error: " + msg));
|
|
69
|
+
console.error();
|
|
70
|
+
throw new Error("Create IdentityProvider Failed: " + msg);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error();
|
|
73
|
+
console.error(chalk.red("身份提供商创建失败:"), error.message || error);
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = create;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const chalk = require("chalk");
|
|
2
|
+
const { postClass } = require("../../utils/http");
|
|
3
|
+
const { getPackageJson } = require("../../utils/config");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 删除身份提供商
|
|
7
|
+
* 接口: /samlSp/delete
|
|
8
|
+
* 用法:cc delete identityProvider <projectPath> <appId>
|
|
9
|
+
*/
|
|
10
|
+
async function remove(argvs) {
|
|
11
|
+
try {
|
|
12
|
+
const projectPath = argvs[2] || process.cwd();
|
|
13
|
+
const appId = argvs[3];
|
|
14
|
+
|
|
15
|
+
if (!appId) {
|
|
16
|
+
console.error();
|
|
17
|
+
console.error(chalk.red("Error: 缺少身份提供商 app ID"));
|
|
18
|
+
console.error(chalk.yellow("用法: cc delete identityProvider <projectPath> <appId>"));
|
|
19
|
+
console.error(chalk.yellow("示例: cc delete identityProvider . QbjH30d9Oy"));
|
|
20
|
+
console.error();
|
|
21
|
+
throw new Error("缺少必需参数: appId");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const config = await getPackageJson(projectPath);
|
|
25
|
+
if (!config || !config.accessToken) {
|
|
26
|
+
console.error();
|
|
27
|
+
console.error(chalk.red("Error: 配置未找到或 accessToken 缺失"));
|
|
28
|
+
console.error();
|
|
29
|
+
throw new Error("配置未找到或 accessToken 缺失");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.error();
|
|
33
|
+
console.error(chalk.green(`Deleting identity provider (${appId}), please wait...`));
|
|
34
|
+
console.error();
|
|
35
|
+
|
|
36
|
+
const result = await postClass(
|
|
37
|
+
config.setupSvc + "/api/samlSp/delete",
|
|
38
|
+
{ app: appId },
|
|
39
|
+
config.accessToken
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
if (result && result.result) {
|
|
43
|
+
console.error();
|
|
44
|
+
console.error(chalk.green("Success! Identity provider deleted."));
|
|
45
|
+
console.error();
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const msg = result && (result.returnInfo || result.message) ? (result.returnInfo || result.message) : "Unknown error";
|
|
50
|
+
console.error();
|
|
51
|
+
console.error(chalk.red("Error: " + msg));
|
|
52
|
+
console.error();
|
|
53
|
+
throw new Error("Delete IdentityProvider Failed: " + msg);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error();
|
|
56
|
+
console.error(chalk.red("身份提供商删除失败:"), error);
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = remove;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* identityProvider 文档入口:正文均在 `docs/` 目录。
|
|
3
|
+
*/
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
const DOCS_DIR = path.join(__dirname, "docs");
|
|
8
|
+
|
|
9
|
+
function readDocFile(basename) {
|
|
10
|
+
return fs.readFileSync(path.join(DOCS_DIR, `${basename}.md`), "utf8");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** 介绍文档:身份提供商能力、类型与入口 */
|
|
14
|
+
function getIntroductionDoc() {
|
|
15
|
+
return readDocFile("introduction");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** 开发指导:CLI 创建/查询/删除等 */
|
|
19
|
+
function getDevGuideDoc() {
|
|
20
|
+
return readDocFile("devguide");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* cc doc identityProvider <introduction|devguide>
|
|
25
|
+
* @param {string[]} argvs [doc, type, introduction|devguide, ...]
|
|
26
|
+
*/
|
|
27
|
+
function doc(argvs) {
|
|
28
|
+
const subType = argvs[2];
|
|
29
|
+
const key = String(subType || "").trim().toLowerCase();
|
|
30
|
+
if (!key) {
|
|
31
|
+
throw new Error("cc doc identityProvider 需要子命令:introduction 或 devguide");
|
|
32
|
+
}
|
|
33
|
+
if (key === "introduction") {
|
|
34
|
+
const content = getIntroductionDoc();
|
|
35
|
+
console.log(content);
|
|
36
|
+
return content;
|
|
37
|
+
}
|
|
38
|
+
if (key === "devguide") {
|
|
39
|
+
const content = getDevGuideDoc();
|
|
40
|
+
console.log(content);
|
|
41
|
+
return content;
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`doc 不支持的子命令: ${subType},请使用 introduction 或 devguide`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = doc;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# CloudCC 身份提供商 CLI 命令说明
|
|
2
|
+
|
|
3
|
+
## 支持的命令
|
|
4
|
+
|
|
5
|
+
| 操作 | 说明 |
|
|
6
|
+
|------|------|
|
|
7
|
+
| `create` | 创建新身份提供商 |
|
|
8
|
+
| `get` | 查询身份提供商列表 |
|
|
9
|
+
| `delete` | 删除身份提供商 |
|
|
10
|
+
| `download` | 下载身份提供商证书 |
|
|
11
|
+
|
|
12
|
+
## CLI 命令详解
|
|
13
|
+
|
|
14
|
+
### 创建身份提供商
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
cc create identityProvider <path> <entityid> <acsurl>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**参数说明:**
|
|
21
|
+
|
|
22
|
+
| 参数 | 必填 | 说明 |
|
|
23
|
+
|------|------|------|
|
|
24
|
+
| `path` | 是 | 项目路径,`.` 表示当前目录 |
|
|
25
|
+
| `entityid` | 是 | 实体 ID(Service Provider Entity ID)|
|
|
26
|
+
| `acsurl` | 是 | ACS URL(Assertion Consumer Service URL)|
|
|
27
|
+
|
|
28
|
+
**示例:**
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# 创建身份提供商
|
|
32
|
+
cc create identityProvider . "http://testdev.cloudcc.cn/ccdomaingateway/apisvc" "http://testdev.cloudcc.cn/ccdomaingateway/apisvc/saml2/sp/sso/acs"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 查询身份提供商列表
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cc get identityProvider <projectPath> [encodedCondJson]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**参数说明:**
|
|
42
|
+
|
|
43
|
+
| 参数 | 必填 | 说明 |
|
|
44
|
+
|------|------|------|
|
|
45
|
+
| `projectPath` | 否 | 项目路径,默认当前目录 |
|
|
46
|
+
| `encodedCondJson` | 否 | URI 编码后的查询条件 JSON |
|
|
47
|
+
|
|
48
|
+
**查询条件参数:**
|
|
49
|
+
|
|
50
|
+
| 参数名 | 类型 | 说明 |
|
|
51
|
+
|--------|------|------|
|
|
52
|
+
| `start` | number | 起始位置,默认 0 |
|
|
53
|
+
| `limit` | number | 每页条数,默认 30 |
|
|
54
|
+
| `keyword` | string | 搜索关键词 |
|
|
55
|
+
|
|
56
|
+
**示例:**
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# 获取所有身份提供商
|
|
60
|
+
cc get identityProvider .
|
|
61
|
+
|
|
62
|
+
# 带查询条件(搜索关键词)
|
|
63
|
+
cc get identityProvider . '%7B%22keyword%22%3A%22test%22%2C%22limit%22%3A50%7D'
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 删除身份提供商
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
cc delete identityProvider <projectPath> <appId>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**参数说明:**
|
|
73
|
+
|
|
74
|
+
| 参数 | 必填 | 说明 |
|
|
75
|
+
|------|------|------|
|
|
76
|
+
| `projectPath` | 否 | 项目路径,默认当前目录 |
|
|
77
|
+
| `appId` | 是 | 身份提供商的 app 字段值(从列表接口获取)|
|
|
78
|
+
|
|
79
|
+
**示例:**
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# 删除身份提供商
|
|
83
|
+
cc delete identityProvider . QbjH30d9Oy
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 下载身份提供商证书
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
cc download identityProvider <projectPath> [savePath]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**参数说明:**
|
|
93
|
+
|
|
94
|
+
| 参数 | 必填 | 说明 |
|
|
95
|
+
|------|------|------|
|
|
96
|
+
| `projectPath` | 否 | 项目路径,默认当前目录 |
|
|
97
|
+
| `savePath` | 否 | 证书保存路径,默认当前目录 |
|
|
98
|
+
|
|
99
|
+
**示例:**
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# 下载证书到当前目录
|
|
103
|
+
cc download identityProvider .
|
|
104
|
+
|
|
105
|
+
# 下载证书到指定路径
|
|
106
|
+
cc download identityProvider . ./certificates
|
|
107
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 身份提供商介绍
|
|
2
|
+
|
|
3
|
+
## 功能概述
|
|
4
|
+
|
|
5
|
+
身份提供商(Identity Provider)模块用于管理 CloudCC 平台的 SAML 身份提供商配置,支持以下功能:
|
|
6
|
+
|
|
7
|
+
- **查看身份提供商列表**:查询已配置的所有 SAML 身份提供商
|
|
8
|
+
- **新建身份提供商**:创建新的 SAML 身份提供商配置
|
|
9
|
+
- **删除身份提供商**:删除已配置的 SAML 身份提供商
|
|
10
|
+
- **下载证书**:下载身份提供商的 SAML 证书
|
|
11
|
+
|
|
12
|
+
## 适用场景
|
|
13
|
+
|
|
14
|
+
- 企业单点登录(SSO)集成
|
|
15
|
+
- SAML 2.0 身份提供商配置
|
|
16
|
+
- 多身份提供商管理
|
|
17
|
+
|
|
18
|
+
## 字段说明
|
|
19
|
+
|
|
20
|
+
### 身份提供商字段
|
|
21
|
+
|
|
22
|
+
| 字段名 | 说明 | 默认值 |
|
|
23
|
+
|--------|------|--------|
|
|
24
|
+
| `entityid` | Service Provider Entity ID | 用户输入 |
|
|
25
|
+
| `acsurl` | Assertion Consumer Service URL | 用户输入 |
|
|
26
|
+
| `issuername` | 签发者名称 | 空字符串 |
|
|
27
|
+
| `nameidtype` | Name ID 类型 | FederationId |
|
|
28
|
+
| `nameidformat` | Name ID 格式 | 1 |
|
|
29
|
+
| `enablelogout` | 启用注销 | false |
|
|
30
|
+
| `logouturl` | 注销 URL | 空字符串 |
|
|
31
|
+
| `custattrname` | 自定义属性名称 | 空字符串 |
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const chalk = require("chalk");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const axios = require("axios");
|
|
5
|
+
const https = require("https");
|
|
6
|
+
const { getPackageJson } = require("../../utils/config");
|
|
7
|
+
const { postClass } = require("../../utils/http");
|
|
8
|
+
|
|
9
|
+
const httpsAgent = new https.Agent({
|
|
10
|
+
rejectUnauthorized: false,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 下载身份提供商证书
|
|
15
|
+
* 接口: /LoginHistory/getExportReportURL 获取下载链接,然后下载文件
|
|
16
|
+
* 用法:cc download identityProvider <projectPath> [savePath]
|
|
17
|
+
*/
|
|
18
|
+
async function download(argvs) {
|
|
19
|
+
try {
|
|
20
|
+
const projectPath = argvs[2] || process.cwd();
|
|
21
|
+
const savePath = argvs[3] || process.cwd();
|
|
22
|
+
|
|
23
|
+
const config = await getPackageJson(projectPath);
|
|
24
|
+
if (!config || !config.accessToken) {
|
|
25
|
+
console.error();
|
|
26
|
+
console.error(chalk.red("Error: 配置未找到或 accessToken 缺失"));
|
|
27
|
+
console.error();
|
|
28
|
+
throw new Error("配置未找到或 accessToken 缺失");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.error();
|
|
32
|
+
console.error(chalk.green("Downloading certificate, please wait..."));
|
|
33
|
+
console.error();
|
|
34
|
+
|
|
35
|
+
// 确保证书保存目录存在
|
|
36
|
+
if (!fs.existsSync(savePath)) {
|
|
37
|
+
fs.mkdirSync(savePath, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 第一步:调用接口获取下载 URL
|
|
41
|
+
const result = await postClass(
|
|
42
|
+
config.setupSvc + "/api/LoginHistory/getExportReportURL",
|
|
43
|
+
{},
|
|
44
|
+
config.accessToken
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
if (result && result.result && result.data) {
|
|
48
|
+
const downloadUrl = result.data;
|
|
49
|
+
|
|
50
|
+
console.error(chalk.gray(`Got download URL: ${downloadUrl}`));
|
|
51
|
+
console.error(chalk.gray(`Downloading file...`));
|
|
52
|
+
console.error();
|
|
53
|
+
|
|
54
|
+
// 第二步:根据返回的 URL 下载文件
|
|
55
|
+
const response = await axios({
|
|
56
|
+
method: 'get',
|
|
57
|
+
url: downloadUrl,
|
|
58
|
+
httpsAgent: httpsAgent,
|
|
59
|
+
responseType: 'arraybuffer',
|
|
60
|
+
timeout: 120000
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// 尝试从响应头获取文件名
|
|
64
|
+
let filename = "identity-provider.crt";
|
|
65
|
+
const contentDisposition = response.headers['content-disposition'];
|
|
66
|
+
if (contentDisposition) {
|
|
67
|
+
const match = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
|
|
68
|
+
if (match && match[1]) {
|
|
69
|
+
filename = match[1].replace(/['"]/g, '');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 如果 URL 中包含文件名,也尝试从中提取
|
|
74
|
+
const urlPath = new URL(downloadUrl).pathname;
|
|
75
|
+
const urlFilename = urlPath.split('/').pop();
|
|
76
|
+
if (urlFilename && urlFilename.includes('.')) {
|
|
77
|
+
filename = urlFilename;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const filePath = path.join(savePath, filename);
|
|
81
|
+
fs.writeFileSync(filePath, response.data);
|
|
82
|
+
|
|
83
|
+
console.error();
|
|
84
|
+
console.error(chalk.green("Success! Certificate downloaded."));
|
|
85
|
+
console.error(chalk.gray(`Saved to: ${filePath}`));
|
|
86
|
+
console.error();
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
result: true,
|
|
90
|
+
filePath: filePath,
|
|
91
|
+
filename: filename,
|
|
92
|
+
downloadUrl: downloadUrl
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const msg = result && (result.returnInfo || result.message) ? (result.returnInfo || result.message) : "Unknown error";
|
|
97
|
+
throw new Error("Get download URL failed: " + msg);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error();
|
|
100
|
+
console.error(chalk.red("证书下载失败:"), error.message || error);
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = download;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const { postClass } = require("../../utils/http");
|
|
2
|
+
const { getPackageJson } = require("../../utils/config");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 查询身份提供商列表
|
|
7
|
+
* 接口: /samlSp/queryList
|
|
8
|
+
* 用法:cc get identityProvider <projectPath> [encodedCondJson]
|
|
9
|
+
*/
|
|
10
|
+
async function get(argvs, isMcp = false) {
|
|
11
|
+
const projectPath = argvs[2] || process.cwd();
|
|
12
|
+
const condArg = argvs[3];
|
|
13
|
+
|
|
14
|
+
let body = {};
|
|
15
|
+
if (condArg) {
|
|
16
|
+
try {
|
|
17
|
+
body = JSON.parse(decodeURI(condArg));
|
|
18
|
+
} catch (e) {
|
|
19
|
+
try {
|
|
20
|
+
body = JSON.parse(condArg);
|
|
21
|
+
} catch (e2) {
|
|
22
|
+
throw new Error("Get IdentityProvider Failed: encodedCondJson 解析失败,请传 encodeURI(JSON.stringify(...))");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const config = await getPackageJson(projectPath);
|
|
28
|
+
|
|
29
|
+
const res = await postClass(
|
|
30
|
+
config.setupSvc + "/api/samlSp/queryList",
|
|
31
|
+
{
|
|
32
|
+
start: 0,
|
|
33
|
+
limit: 30,
|
|
34
|
+
keyword: "",
|
|
35
|
+
...body
|
|
36
|
+
},
|
|
37
|
+
config.accessToken
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (res && res.result) {
|
|
41
|
+
const data = res.data;
|
|
42
|
+
let rawList = [];
|
|
43
|
+
if (Array.isArray(data)) {
|
|
44
|
+
rawList = data;
|
|
45
|
+
} else if (data && Array.isArray(data.list)) {
|
|
46
|
+
rawList = data.list;
|
|
47
|
+
} else if (data && Array.isArray(data.data)) {
|
|
48
|
+
rawList = data.data;
|
|
49
|
+
} else if (data && typeof data === "object") {
|
|
50
|
+
rawList = Object.keys(data)
|
|
51
|
+
.filter((key) => /list$/i.test(key) && Array.isArray(data[key]))
|
|
52
|
+
.flatMap((key) =>
|
|
53
|
+
data[key].map((item) => ({
|
|
54
|
+
...item,
|
|
55
|
+
__group: key
|
|
56
|
+
}))
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!isMcp) {
|
|
61
|
+
console.log(JSON.stringify(rawList, null, 2));
|
|
62
|
+
}
|
|
63
|
+
return rawList;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const msg = res && (res.returnInfo || res.message) ? (res.returnInfo || res.message) : "Unknown error";
|
|
67
|
+
throw new Error("Get IdentityProvider Failed: " + msg);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = get;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const cc = {}
|
|
2
|
+
cc.create = require("./create")
|
|
3
|
+
cc.delete = require("./delete")
|
|
4
|
+
cc.get = require("./get")
|
|
5
|
+
cc.download = require("./download")
|
|
6
|
+
cc.doc = require("./doc")
|
|
7
|
+
|
|
8
|
+
function main(action, argvs) {
|
|
9
|
+
cc[action](argvs)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = main;
|
package/src/menu/create-page.js
CHANGED
package/src/menu/create-site.js
CHANGED
package/src/object/create.js
CHANGED
|
@@ -59,13 +59,9 @@ cc get object <projectPath> custom
|
|
|
59
59
|
### 4.1 基本命令
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
|
-
cc create object <projectPath> <label>
|
|
62
|
+
cc create object <projectPath> <label>
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
规则:
|
|
66
|
-
|
|
67
|
-
- 若传入 `nameLabel`,则使用传入值作为对象 API 名称
|
|
68
|
-
- 若未传入 `nameLabel`,CLI 会根据 `label` 自动生成一个英文可用的 slug,并拼成对象 API 名称
|
|
69
65
|
|
|
70
66
|
### 4.2 创建过程
|
|
71
67
|
|