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.
Files changed (85) hide show
  1. package/.claude/settings.json +28 -1
  2. package/.cursor/skills/cloudcc-cli-dev/SKILL.md +175 -0
  3. package/.cursor/skills/cloudcc-dev-skill/SKILL.md +71 -0
  4. package/README.md +65 -7
  5. package/bin/cc.js +106 -28
  6. package/bin/index.js +54 -53
  7. package/mcp/cliRunner.js +11 -4
  8. package/mcp/index.js +12 -2
  9. package/mcp/tools/CloudCC Development Overview/handler.js +1 -1
  10. package/mcp/tools/JSP Migrator/handler.js +46 -0
  11. package/package.json +4 -5
  12. package/src/button/create.js +169 -0
  13. package/src/button/delete.js +35 -0
  14. package/src/button/doc.js +36 -0
  15. package/src/button/docs/devguide.md +133 -0
  16. package/src/button/docs/introduction.md +60 -0
  17. package/src/button/get.js +60 -0
  18. package/src/button/index.js +20 -0
  19. package/src/classes/docs/introduction.md +0 -20
  20. package/src/fields/create.js +12 -0
  21. package/src/identityProvider/create.js +78 -0
  22. package/src/identityProvider/delete.js +61 -0
  23. package/src/identityProvider/doc.js +46 -0
  24. package/src/identityProvider/docs/devguide.md +107 -0
  25. package/src/identityProvider/docs/introduction.md +31 -0
  26. package/src/identityProvider/download.js +105 -0
  27. package/src/identityProvider/get.js +70 -0
  28. package/src/identityProvider/index.js +12 -0
  29. package/src/menu/create-object.js +1 -0
  30. package/src/menu/create-page.js +1 -0
  31. package/src/menu/create-script.js +1 -0
  32. package/src/menu/create-site.js +1 -0
  33. package/src/object/create.js +2 -1
  34. package/src/object/docs/devguide.md +1 -5
  35. package/src/permission/add.js +164 -0
  36. package/src/permission/assign.js +84 -0
  37. package/src/permission/docs/devguide.md +238 -0
  38. package/src/permission/docs/introduction.md +200 -0
  39. package/src/permission/get.js +107 -0
  40. package/src/permission/index.js +10 -0
  41. package/src/permission/remove.js +145 -0
  42. package/src/project/docs/devguide.md +7 -6
  43. package/src/role/create.js +2 -1
  44. package/src/role/delete.js +1 -0
  45. package/src/singleSignOn/delete.js +61 -0
  46. package/src/singleSignOn/doc.js +46 -0
  47. package/src/singleSignOn/docs/devguide.md +61 -0
  48. package/src/singleSignOn/docs/introduction.md +3 -0
  49. package/src/singleSignOn/get.js +70 -0
  50. package/src/singleSignOn/index.js +10 -0
  51. package/src/staticResource/docs/introduction.md +44 -1
  52. package/src/user/create.js +502 -19
  53. package/src/validationRule/create.js +153 -0
  54. package/src/validationRule/delete.js +60 -0
  55. package/src/validationRule/doc.js +46 -0
  56. package/src/validationRule/docs/devguide.md +76 -0
  57. package/src/validationRule/docs/introduction.md +122 -0
  58. package/src/validationRule/get.js +47 -0
  59. package/src/validationRule/index.js +10 -0
  60. package/src/version/actionHelp.js +25 -0
  61. package/src/version/docs.js +26 -0
  62. package/src/version/doctor.js +25 -0
  63. package/src/version/get.js +7 -1
  64. package/src/version/help.js +47 -0
  65. package/src/version/index.js +9 -2
  66. package/src/version/initHelp.js +13 -0
  67. package/src/version/listModuleCommands.js +241 -0
  68. package/src/version/stats.js +44 -0
  69. package/src/version/uninstall.js +30 -0
  70. package/src/version/update.js +13 -0
  71. package/utils/checkVersion.js +31 -2
  72. package/utils/commandStats.js +94 -0
  73. package/utils/formatReleaseNotes.js +312 -0
  74. package/utils/readmeReleases.js +69 -0
  75. package/.cloudcc-cache.json +0 -38
  76. package/.cursor/skills/cloudcc-cli-dev.zip +0 -0
  77. package/.cursor/skills/cloudcc-cli-usage/SKILL.md +0 -68
  78. package/build/component-CCPlugin1774500425584.common.js +0 -831
  79. package/build/component-CCPlugin1774500425584.common.js.map +0 -1
  80. package/build/component-CCPlugin1774500425584.css +0 -1
  81. package/build/component-CCPlugin1774500425584.umd.js +0 -874
  82. package/build/component-CCPlugin1774500425584.umd.js.map +0 -1
  83. package/build/component-CCPlugin1774500425584.umd.min.js +0 -8
  84. package/build/component-CCPlugin1774500425584.umd.min.js.map +0 -1
  85. package/build/demo.html +0 -1
@@ -0,0 +1,241 @@
1
+ const fs = require("fs")
2
+ const path = require("path")
3
+
4
+ /**
5
+ * 与 bin/index.js 中 modules 的 key 顺序、以及各 require 路径一致。
6
+ * schedule 与 timer 均指向 src/timer。
7
+ */
8
+ const MODULE_KEYS_ORDER = [
9
+ "project",
10
+ "plugin",
11
+ "classes",
12
+ "customSetting",
13
+ "globalSelectList",
14
+ "button",
15
+ "staticResource",
16
+ "customPage",
17
+ "schedule",
18
+ "triggers",
19
+ "timer",
20
+ "script",
21
+ "token",
22
+ "object",
23
+ "recordType",
24
+ "config",
25
+ "version",
26
+ "brief",
27
+ "fields",
28
+ "menu",
29
+ "application",
30
+ "scheduleJob",
31
+ "profile",
32
+ "user",
33
+ "role",
34
+ "identityProvider",
35
+ "singleSignOn",
36
+ "pagelayout",
37
+ "validationRule",
38
+ "permission",
39
+ ]
40
+
41
+ /**
42
+ * 各 resource 一句话说明(供 --help 展示)。与自动解析的 action 列表互补,不替代 `cc doc <resource> introduction`。
43
+ */
44
+ const MODULE_HINT = {
45
+ project: "创建/初始化 CloudCC 开发项目。",
46
+ plugin: "自定义组件:创建、发布、拉取、删除与文档。",
47
+ classes: "自定义类:服务端 Java 业务逻辑,与平台同步,可供按钮、触发器、定时类等调用。",
48
+ customSetting: "自定义设置:查询、创建、字段维护等。",
49
+ globalSelectList: "全局选项列表。",
50
+ button: "自定义按钮。",
51
+ staticResource: "静态资源上传与管理。",
52
+ customPage: "自定义页面。",
53
+ schedule: "定时类(Scheduled Class):与平台同步 Java 与配置(resource 亦可用 timer)。",
54
+ triggers: "触发器:本地 Java 与平台同步。",
55
+ script: "客户端脚本:创建、发布、拉取等。",
56
+ token: "访问令牌/凭证。",
57
+ object: "标准对象与自定义对象。",
58
+ recordType: "记录类型。",
59
+ config: "配置与切换。",
60
+ version: "版本信息、帮助与全局安装维护(非业务资源)。",
61
+ brief: "摘要/概要信息。",
62
+ fields: "对象字段。",
63
+ menu: "菜单。",
64
+ application: "应用。",
65
+ scheduleJob: "计划任务(平台侧任务)。",
66
+ profile: "简档。",
67
+ user: "用户。",
68
+ role: "角色。",
69
+ identityProvider: "身份提供商(IdP)。",
70
+ singleSignOn: "单点登录(SSO)配置。",
71
+ pagelayout: "页面布局。",
72
+ validationRule: "验证规则。",
73
+ permission: "权限:分配、查询、增删等。",
74
+ }
75
+
76
+ const MODULE_FOLDER = {
77
+ project: "project",
78
+ plugin: "plugin",
79
+ classes: "classes",
80
+ customSetting: "customSetting",
81
+ globalSelectList: "globalSelectList",
82
+ button: "button",
83
+ staticResource: "staticResource",
84
+ customPage: "customPage",
85
+ schedule: "timer",
86
+ triggers: "triggers",
87
+ timer: "timer",
88
+ script: "script",
89
+ token: "token",
90
+ object: "object",
91
+ recordType: "recordType",
92
+ config: "config",
93
+ version: "version",
94
+ brief: "brief",
95
+ fields: "fields",
96
+ menu: "menu",
97
+ application: "application",
98
+ scheduleJob: "scheduleJob",
99
+ profile: "profile",
100
+ user: "user",
101
+ role: "role",
102
+ identityProvider: "identityProvider",
103
+ singleSignOn: "singleSignOn",
104
+ pagelayout: "pagelayout",
105
+ validationRule: "validationRule",
106
+ permission: "permission",
107
+ }
108
+
109
+ function extractActions(indexFilePath) {
110
+ const src = fs.readFileSync(indexFilePath, "utf8")
111
+ const actions = new Set()
112
+ const re = /^\s*cc\.(\w+)\s*=/gm
113
+ let m
114
+ while ((m = re.exec(src))) {
115
+ actions.add(m[1])
116
+ }
117
+ return Array.from(actions).sort()
118
+ }
119
+
120
+ /**
121
+ * 按 index.js 文件合并资源名(如 timer 与 schedule),顺序与 MODULE_KEYS_ORDER 一致。
122
+ */
123
+ function getModuleGroups() {
124
+ const seen = new Map()
125
+ for (const key of MODULE_KEYS_ORDER) {
126
+ const folder = MODULE_FOLDER[key]
127
+ const abs = path.join(__dirname, "..", folder, "index.js")
128
+ if (!seen.has(abs)) {
129
+ seen.set(abs, { resources: [], indexPath: abs })
130
+ }
131
+ seen.get(abs).resources.push(key)
132
+ }
133
+ return Array.from(seen.values()).map((g) => ({
134
+ resources: g.resources,
135
+ actions: extractActions(g.indexPath),
136
+ hint: describeModuleGroup(g.resources),
137
+ }))
138
+ }
139
+
140
+ function describeModuleGroup(resources) {
141
+ const sorted = [...resources].sort()
142
+ if (sorted.length === 2 && sorted[0] === "schedule" && sorted[1] === "timer") {
143
+ return "定时类(Scheduled Class):与平台同步 Java 与配置(resource 可用 schedule 或 timer)。"
144
+ }
145
+ const r0 = resources[0]
146
+ return MODULE_HINT[r0] || ""
147
+ }
148
+
149
+ /** resource 中文名,用于拼「创建 xxx」等行内说明 */
150
+ const RESOURCE_CN = {
151
+ project: "项目",
152
+ plugin: "自定义组件",
153
+ classes: "自定义类",
154
+ customSetting: "自定义设置",
155
+ globalSelectList: "全局选项列表",
156
+ button: "自定义按钮",
157
+ staticResource: "静态资源",
158
+ customPage: "自定义页面",
159
+ schedule: "定时类",
160
+ timer: "定时类",
161
+ triggers: "触发器",
162
+ script: "客户端脚本",
163
+ token: "访问令牌",
164
+ object: "对象",
165
+ recordType: "记录类型",
166
+ config: "配置",
167
+ version: "版本",
168
+ brief: "摘要",
169
+ fields: "字段",
170
+ menu: "菜单",
171
+ application: "应用",
172
+ scheduleJob: "计划任务",
173
+ profile: "简档",
174
+ user: "用户",
175
+ role: "角色",
176
+ identityProvider: "身份提供商",
177
+ singleSignOn: "单点登录",
178
+ pagelayout: "页面布局",
179
+ validationRule: "验证规则",
180
+ permission: "权限",
181
+ }
182
+
183
+ /**
184
+ * 单行命令说明(替代行尾「…」),与 cc <action> <resource> 对应。
185
+ */
186
+ function describeActionLine(resource, action) {
187
+ const n = RESOURCE_CN[resource] || resource
188
+ const line = {
189
+ create: () => `创建${n}`,
190
+ get: () => `查询${n}`,
191
+ delete: () => `删除${n}`,
192
+ doc: () => `查看${n}文档(子命令如 introduction、devguide)`,
193
+ publish: () => `将本地${n}发布到平台`,
194
+ pull: () => `从平台拉取${n}到本地`,
195
+ pullList: () => `按列表批量拉取${n}`,
196
+ detail: () => `查看${n}详情`,
197
+ assign: () => `分配${n}`,
198
+ add: () => `添加${n}`,
199
+ remove: () => `移除${n}`,
200
+ update: () => (resource === "version" ? "升级全局 cloudcc-cli" : `更新${n}`),
201
+ view: () => `查看${n}信息`,
202
+ use: () => `切换使用的${n}`,
203
+ count: () => `统计${n}数量`,
204
+ modify: () => `修改${n}`,
205
+ download: () => `下载${n}相关文件`,
206
+ getList: () => `获取${n}列表`,
207
+ newInfo: () => `获取新建${n}所需信息`,
208
+ editInfo: () => `获取编辑${n}前信息`,
209
+ editSave: () => `保存${n}编辑`,
210
+ validDelete: () => `校验${n}是否可删除`,
211
+ deleteCustomSettingField: () => `删除自定义设置中的字段`,
212
+ editCustomSettingField: () => `编辑自定义设置字段`,
213
+ saveCustomSettingField: () => `保存自定义设置字段`,
214
+ help: () => (resource === "version" ? "(内部)帮助" : `查看 ${n} 帮助`),
215
+ uninstall: () => (resource === "version" ? "卸载全局 cloudcc-cli" : `卸载 ${n}`),
216
+ }
217
+ if (line[action]) {
218
+ return line[action]()
219
+ }
220
+ return `${action} · ${n}`
221
+ }
222
+
223
+ /**
224
+ * 返回支持给定 action 的所有 resource 名(去重、排序)。
225
+ */
226
+ function getResourcesForAction(actionName) {
227
+ const groups = getModuleGroups()
228
+ const out = new Set()
229
+ for (const g of groups) {
230
+ if (g.actions.includes(actionName)) {
231
+ g.resources.forEach((r) => out.add(r))
232
+ }
233
+ }
234
+ return Array.from(out).sort((a, b) => a.localeCompare(b))
235
+ }
236
+
237
+ module.exports = {
238
+ getModuleGroups,
239
+ describeActionLine,
240
+ getResourcesForAction,
241
+ }
@@ -0,0 +1,44 @@
1
+ const chalk = require("chalk")
2
+ const {
3
+ readStats,
4
+ isEnabled,
5
+ statsFilePath,
6
+ } = require("../../utils/commandStats")
7
+
8
+ function stats() {
9
+ const data = readStats()
10
+ const entries = Object.entries(data.counts || {}).sort((a, b) => b[1] - a[1])
11
+
12
+ console.error()
13
+ console.error(chalk.bold.cyan("cc command statistics"))
14
+ console.error(chalk.gray("File: ") + chalk.dim(statsFilePath()))
15
+ console.error(
16
+ chalk.gray("Recording: ") +
17
+ (isEnabled()
18
+ ? chalk.green("ON")
19
+ : chalk.yellow("OFF — remove CLOUDCC_CLI_STATS or set 1/true to record again"))
20
+ )
21
+ if (data.updatedAt) {
22
+ console.error(chalk.gray("Last update: ") + chalk.dim(data.updatedAt))
23
+ }
24
+ console.error()
25
+
26
+ if (entries.length === 0) {
27
+ console.error(chalk.dim(" (no data yet)"))
28
+ console.error()
29
+ return
30
+ }
31
+
32
+ console.error(chalk.gray(" command → count"))
33
+ for (const [key, n] of entries) {
34
+ console.error(
35
+ " " +
36
+ chalk.green(key) +
37
+ chalk.gray(" → ") +
38
+ chalk.bold.white(String(n))
39
+ )
40
+ }
41
+ console.error()
42
+ }
43
+
44
+ module.exports = stats
@@ -0,0 +1,30 @@
1
+ const chalk = require("chalk")
2
+ const inquirer = require("inquirer")
3
+ const exec = require("child_process").execSync
4
+
5
+ async function uninstall() {
6
+ const { confirm } = await inquirer.prompt([
7
+ {
8
+ type: "confirm",
9
+ name: "confirm",
10
+ default: false,
11
+ message: "Uninstall global package cloudcc-cli?",
12
+ },
13
+ ])
14
+ if (!confirm) {
15
+ console.error(chalk.yellow("Cancelled."))
16
+ return
17
+ }
18
+ const os = process.platform
19
+ const prefix = os === "darwin" ? "sudo " : ""
20
+ try {
21
+ console.error(chalk.green("Uninstalling..."))
22
+ exec(`${prefix}npm uninstall -g cloudcc-cli`, { stdio: "inherit" })
23
+ console.error(chalk.green("Done."))
24
+ } catch (e) {
25
+ console.error(chalk.red("Uninstall failed."), e.message || e)
26
+ process.exitCode = 1
27
+ }
28
+ }
29
+
30
+ module.exports = uninstall
@@ -0,0 +1,13 @@
1
+ const chalk = require("chalk")
2
+ const { checkNpmVersion, update } = require("../../utils/checkVersion")
3
+
4
+ function runUpdate() {
5
+ const onlineVersion = checkNpmVersion()
6
+ if (!onlineVersion) {
7
+ console.error(chalk.green("\ncloudcc-cli is already up to date.\n"))
8
+ return
9
+ }
10
+ update(onlineVersion)
11
+ }
12
+
13
+ module.exports = runUpdate
@@ -5,6 +5,13 @@ const chalk = require("chalk")
5
5
  const { readCache, writeCache } = require("./cache")
6
6
  const fs = require('fs');
7
7
  const path = require('path');
8
+ const {
9
+ semverCompare,
10
+ getReleaseForExact,
11
+ getReleasesBetween,
12
+ defaultReadmePath,
13
+ } = require("./readmeReleases");
14
+ const { printReleaseNotesBlocks } = require("./formatReleaseNotes");
8
15
 
9
16
  function checkNpmVersion() {
10
17
  let currentVersion = Number(config.version.replace(/\./g, ""));
@@ -31,7 +38,9 @@ function checkNpmVersion() {
31
38
  console.error(' ' + chalk.yellow('★') + ' Published At : ' + chalk.gray(formattedTime));
32
39
  console.error(' ' + chalk.magenta('★') + ' Developer Docs : ' + chalk.cyan('https://help.cloudcc.cn/'));
33
40
  console.error(' ' + chalk.magenta('★') + ' Changelog : ' + chalk.cyan('https://www.npmjs.com/package/cloudcc-cli'));
34
- console.error(' ' + chalk.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
41
+ console.error(' ' + chalk.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
42
+
43
+ printReadmeReleaseNotes(config.version, onlineVersion);
35
44
 
36
45
  if (onlineVersionNum - currentVersion > 0) {
37
46
  return onlineVersion;
@@ -39,6 +48,26 @@ function checkNpmVersion() {
39
48
  return null;
40
49
  }
41
50
 
51
+ /**
52
+ * Prints README `# ReleaseV*` sections: all versions between current and latest when an update
53
+ * exists; otherwise the section for the current version only.
54
+ */
55
+ function printReadmeReleaseNotes(currentVersion, latestVersion) {
56
+ const readmePath = defaultReadmePath();
57
+ let blocks = [];
58
+ if (semverCompare(latestVersion, currentVersion) > 0) {
59
+ blocks = getReleasesBetween(readmePath, currentVersion, latestVersion);
60
+ } else {
61
+ const one = getReleaseForExact(readmePath, currentVersion);
62
+ if (one) blocks = [one];
63
+ }
64
+ if (blocks.length === 0) {
65
+ console.error('\n');
66
+ return;
67
+ }
68
+ printReleaseNotesBlocks(blocks, console.error);
69
+ }
70
+
42
71
 
43
72
  function askUpdate() {
44
73
  console.error();
@@ -154,4 +183,4 @@ function checkAndReplaceJar(projectPath = process.cwd()) {
154
183
  }
155
184
  }
156
185
 
157
- module.exports = { checkUpdate };
186
+ module.exports = { checkUpdate, checkNpmVersion, update };
@@ -0,0 +1,94 @@
1
+ const fs = require("fs")
2
+ const path = require("path")
3
+ const os = require("os")
4
+
5
+ /**
6
+ * 默认开启:在 ~/.cloudcc-cli/command-stats.json 累计调用次数;
7
+ * 键为人类可读形式,如 `cc doc classes`、`cc get brief`。
8
+ * 设 `CLOUDCC_CLI_STATS=0` / `false` / `off` 可关闭。
9
+ */
10
+ function isEnabled() {
11
+ const v = process.env.CLOUDCC_CLI_STATS
12
+ if (v == null || String(v).trim() === "") return true
13
+ const s = String(v).trim().toLowerCase()
14
+ if (s === "0" || s === "false" || s === "no" || s === "off") return false
15
+ return true
16
+ }
17
+
18
+ function statsFilePath() {
19
+ return path.join(os.homedir(), ".cloudcc-cli", "command-stats.json")
20
+ }
21
+
22
+ /**
23
+ * @param {string} action 第一参数(或全局标志如 -v、--help)
24
+ * @param {string} resource 第二参数;无第二段时用 "_";子帮助用 "_help";action 级 -h 用 "-h"
25
+ */
26
+ function formatRecordKey(action, resource) {
27
+ const res = resource == null || resource === "" ? "_" : String(resource)
28
+ if (res === "_") {
29
+ if (
30
+ action === "-v" ||
31
+ action === "--v" ||
32
+ action === "-version" ||
33
+ action === "--version"
34
+ ) {
35
+ return "cc --version"
36
+ }
37
+ if (action === "-h" || action === "--h" || action === "--help") {
38
+ return "cc --help"
39
+ }
40
+ return `cc ${action}`
41
+ }
42
+ if (res === "_help") {
43
+ return `cc ${action} --help`
44
+ }
45
+ if (res === "-h" || res === "--help") {
46
+ return `cc ${action} -h`
47
+ }
48
+ return `cc ${action} ${res}`
49
+ }
50
+
51
+ /**
52
+ * @param {string} action 第一参数,如 get、doc、create
53
+ * @param {string} resource 第二参数;无第二段时用 "_"(全局子命令)
54
+ */
55
+ function record(action, resource) {
56
+ if (!isEnabled()) return
57
+ if (!action || typeof action !== "string") return
58
+ const res = resource == null || resource === "" ? "_" : String(resource)
59
+ const key = formatRecordKey(action, res)
60
+ try {
61
+ const file = statsFilePath()
62
+ const dir = path.dirname(file)
63
+ if (!fs.existsSync(dir)) {
64
+ fs.mkdirSync(dir, { recursive: true })
65
+ }
66
+ let data = { version: 1, counts: {}, updatedAt: null }
67
+ if (fs.existsSync(file)) {
68
+ data = JSON.parse(fs.readFileSync(file, "utf8"))
69
+ if (!data.counts || typeof data.counts !== "object") data.counts = {}
70
+ }
71
+ data.counts[key] = (data.counts[key] || 0) + 1
72
+ data.updatedAt = new Date().toISOString()
73
+ fs.writeFileSync(file, JSON.stringify(data, null, 2), "utf8")
74
+ } catch (_e) {
75
+ // 统计失败不影响 CLI
76
+ }
77
+ }
78
+
79
+ function readStats() {
80
+ try {
81
+ const file = statsFilePath()
82
+ if (fs.existsSync(file)) {
83
+ return JSON.parse(fs.readFileSync(file, "utf8"))
84
+ }
85
+ } catch (_e) {}
86
+ return { version: 1, counts: {}, updatedAt: null }
87
+ }
88
+
89
+ module.exports = {
90
+ isEnabled,
91
+ record,
92
+ readStats,
93
+ statsFilePath,
94
+ }