openyida 0.1.2 → 1.0.0-beta.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/README.md +68 -38
- package/bin/yida.js +164 -761
- package/lib/babel-transform/index.js +244 -0
- package/lib/babel-transform/jsx-utils.js +89 -0
- package/lib/check-update.js +72 -0
- package/lib/copy.js +258 -0
- package/lib/create-app.js +174 -0
- package/lib/create-form.js +2244 -0
- package/lib/create-page.js +89 -0
- package/lib/env.js +164 -0
- package/lib/get-page-config.js +102 -0
- package/lib/get-schema.js +76 -0
- package/lib/login.js +323 -0
- package/lib/publish.js +610 -0
- package/lib/save-share-config.js +268 -0
- package/lib/update-form-config.js +237 -0
- package/lib/utils.js +443 -0
- package/lib/verify-short-url.js +279 -0
- package/package.json +20 -7
- package/project/.cache/demo-schema.json +2353 -0
- package/project/pages/src/demo-birthday-game.js +833 -0
- package/project/pages/src/demo-future-vision-2026.js +1102 -0
- package/project/pages/src/demo-salary-calculator.js +904 -0
- package/project/prd/demo-birthday-game.md +39 -0
- package/project/prd/demo-future-vision-2026.md +78 -0
- package/project/prd/demo-salary-calculator.md +101 -0
- package/scripts/postinstall.js +114 -0
- package/yida-skills/SKILL.md +273 -0
- package/yida-skills/reference/association-form-field.md +469 -0
- package/yida-skills/reference/employee-field.md +17 -0
- package/yida-skills/reference/model-api.md +73 -0
- package/yida-skills/reference/serial-number-field.md +132 -0
- package/yida-skills/reference/yida-api.md +1208 -0
- package/yida-skills/skills/yida-app/SKILL.md +394 -0
- package/yida-skills/skills/yida-create-app/SKILL.md +158 -0
- package/yida-skills/skills/yida-create-form-page/SKILL.md +598 -0
- package/yida-skills/skills/yida-create-page/SKILL.md +103 -0
- package/yida-skills/skills/yida-custom-page/SKILL.md +533 -0
- package/yida-skills/skills/yida-get-schema/SKILL.md +90 -0
- package/yida-skills/skills/yida-login/SKILL.md +200 -0
- package/yida-skills/skills/yida-logout/SKILL.md +58 -0
- package/yida-skills/skills/yida-page-config/SKILL.md +261 -0
- package/yida-skills/skills/yida-publish-page/SKILL.md +113 -0
- package/.eslintrc.json +0 -25
- package/.github/workflows/ci.yml +0 -123
- package/.github/workflows/publish.yml +0 -105
- package/.github/workflows/update-contributors.yml +0 -151
- package/.openclaw/skills/yida-issue/SKILL.md +0 -27
- package/.openclaw/skills/yida-issue/scripts/create-issue.js +0 -317
- package/CLAUDE.md +0 -168
- package/CONTRIBUTING.md +0 -59
- package/install-skills.ps1 +0 -162
- package/install-skills.sh +0 -175
- package/pages/dist/.gitkeep +0 -0
- package/pages/src/.gitkeep +0 -0
- package/prd/salary-calculator.md +0 -15
- package/tests/cli.test.js +0 -930
- package/tests/install.test.js +0 -277
- package/tests/yida-issue.test.js +0 -314
- /package/{config.json → project/config.json} +0 -0
- /package/{.cache → project/pages/dist}/.gitkeep +0 -0
package/bin/yida.js
CHANGED
|
@@ -1,811 +1,214 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* openyida - 宜搭命令行工具
|
|
4
4
|
*
|
|
5
5
|
* 安装:npm install -g openyida
|
|
6
|
-
* 用法:
|
|
6
|
+
* 用法:openyida <命令> [参数](别名:yida)
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* 命令列表:
|
|
9
|
+
* openyida env 检测当前 AI 工具环境和登录态
|
|
10
|
+
* openyida copy [--force] 复制 project 工作目录到当前 AI 工具环境
|
|
11
|
+
* openyida login 登录态管理
|
|
12
|
+
* openyida logout 退出登录
|
|
13
|
+
* openyida create-app "<名称>" [desc] [icon] [color] 创建应用
|
|
14
|
+
* openyida create-page <appType> "<页面名>" 创建自定义页面
|
|
15
|
+
* openyida create-form create <appType> "<表单名>" <字段JSON> 创建表单页面
|
|
16
|
+
* openyida create-form update <appType> <formUuid> <修改JSON> 更新表单页面
|
|
17
|
+
* openyida get-schema <appType> <formUuid> 获取表单 Schema
|
|
18
|
+
* openyida publish <源文件路径> <appType> <formUuid> 编译并发布自定义页面
|
|
19
|
+
* openyida verify-short-url <appType> <formUuid> <url> 验证短链接 URL 是否可用
|
|
20
|
+
* openyida save-share-config <appType> <formUuid> <url> <isOpen> [openAuth] 保存公开访问/分享配置
|
|
21
|
+
* openyida get-page-config <appType> <formUuid> 查询页面公开访问/分享配置
|
|
22
|
+
* openyida update-form-config <appType> <formUuid> <isRenderNav> <title> 更新表单配置
|
|
10
23
|
*/
|
|
11
24
|
|
|
12
25
|
"use strict";
|
|
13
26
|
|
|
14
|
-
const {
|
|
15
|
-
const {
|
|
16
|
-
|
|
17
|
-
|
|
27
|
+
const { checkUpdate } = require('../lib/check-update');
|
|
28
|
+
const { version: currentVersion } = require('../package.json');
|
|
29
|
+
|
|
30
|
+
// 异步检查更新,fire-and-forget,不阻塞主流程
|
|
31
|
+
const updateCheckPromise = checkUpdate(currentVersion);
|
|
32
|
+
|
|
33
|
+
const command = process.argv[2];
|
|
34
|
+
const args = process.argv.slice(3);
|
|
35
|
+
|
|
36
|
+
function printHelp() {
|
|
37
|
+
console.log(`
|
|
38
|
+
openyida - 宜搭命令行工具
|
|
39
|
+
|
|
40
|
+
用法:
|
|
41
|
+
openyida <命令> [参数...](别名:yida)
|
|
42
|
+
|
|
43
|
+
命令:
|
|
44
|
+
env 检测当前 AI 工具环境和登录态
|
|
45
|
+
copy [--force] 复制 project 工作目录到当前 AI 工具环境
|
|
46
|
+
login 登录态管理(优先缓存,否则扫码)
|
|
47
|
+
logout 退出登录 / 切换账号
|
|
48
|
+
create-app "<名称>" [描述] [图标] [颜色] 创建应用,输出 appType
|
|
49
|
+
create-page <appType> "<页面名>" 创建自定义页面,输出 pageId
|
|
50
|
+
create-form create <appType> "<表单名>" <字段JSON> 创建表单页面
|
|
51
|
+
create-form update <appType> <formUuid> <修改JSON> 更新表单页面
|
|
52
|
+
get-schema <appType> <formUuid> 获取表单 Schema
|
|
53
|
+
publish <源文件路径> <appType> <formUuid> 编译并发布自定义页面
|
|
54
|
+
verify-short-url <appType> <formUuid> <url> 验证短链接 URL 是否可用
|
|
55
|
+
save-share-config <appType> <formUuid> <url> <isOpen> [auth] 保存公开访问/分享配置
|
|
56
|
+
get-page-config <appType> <formUuid> 查询页面公开访问/分享配置
|
|
57
|
+
update-form-config <appType> <formUuid> <isRenderNav> <title> 更新表单配置
|
|
18
58
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
) {
|
|
34
|
-
return currentDir;
|
|
35
|
-
}
|
|
36
|
-
currentDir = path.dirname(currentDir);
|
|
37
|
-
}
|
|
38
|
-
return process.cwd();
|
|
59
|
+
示例:
|
|
60
|
+
openyida login
|
|
61
|
+
openyida logout
|
|
62
|
+
openyida create-app "考勤管理"
|
|
63
|
+
openyida create-page APP_XXX "游戏主页"
|
|
64
|
+
openyida create-form create APP_XXX "员工信息" fields.json
|
|
65
|
+
openyida create-form update APP_XXX FORM-XXX '[{"action":"add","field":{"type":"TextField","label":"备注"}}]'
|
|
66
|
+
openyida get-schema APP_XXX FORM-XXX
|
|
67
|
+
openyida publish pages/src/home.jsx APP_XXX FORM-XXX
|
|
68
|
+
openyida verify-short-url APP_XXX FORM-XXX /o/myapp
|
|
69
|
+
openyida save-share-config APP_XXX FORM-XXX /o/myapp y n
|
|
70
|
+
openyida get-page-config APP_XXX FORM-XXX
|
|
71
|
+
openyida update-form-config APP_XXX FORM-XXX false "页面标题"
|
|
72
|
+
`);
|
|
39
73
|
}
|
|
40
74
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const projectRoot = findProjectRoot();
|
|
46
|
-
const scriptPath = path.join(projectRoot, ".claude", "skills", "skills", skillName, "scripts", scriptFile);
|
|
47
|
-
|
|
48
|
-
if (!fs.existsSync(scriptPath)) {
|
|
49
|
-
console.error(`\n❌ 未找到 skill 脚本:${scriptPath}`);
|
|
50
|
-
console.error(`\n请先运行安装脚本:`);
|
|
51
|
-
console.error(` Mac/Linux:bash install-skills.sh`);
|
|
52
|
-
console.error(` Windows: .\\install-skills.ps1`);
|
|
53
|
-
console.error(`\n或手动克隆 yida-skills:`);
|
|
54
|
-
console.error(` git clone --branch main --depth 1 https://github.com/openyida/yida-skills.git .claude/skills`);
|
|
55
|
-
process.exit(1);
|
|
75
|
+
async function main() {
|
|
76
|
+
if (!command || command === '--help' || command === '-h') {
|
|
77
|
+
printHelp();
|
|
78
|
+
process.exit(0);
|
|
56
79
|
}
|
|
57
80
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
* 运行 Node.js skill 脚本,将 stdout/stderr 透传到终端
|
|
63
|
-
*/
|
|
64
|
-
function runNodeScript(scriptPath, args = []) {
|
|
65
|
-
const child = spawn("node", [scriptPath, ...args], {
|
|
66
|
-
stdio: "inherit",
|
|
67
|
-
cwd: findProjectRoot(),
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
child.on("close", (exitCode) => {
|
|
71
|
-
process.exit(exitCode ?? 0);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
child.on("error", (error) => {
|
|
75
|
-
console.error(`\n❌ 执行失败:${error.message}`);
|
|
76
|
-
process.exit(1);
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* 运行 Python skill 脚本,将 stdout/stderr 透传到终端
|
|
82
|
-
*/
|
|
83
|
-
function runPythonScript(scriptPath, args = []) {
|
|
84
|
-
const child = spawn("python3", [scriptPath, ...args], {
|
|
85
|
-
stdio: "inherit",
|
|
86
|
-
cwd: findProjectRoot(),
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
child.on("close", (exitCode) => {
|
|
90
|
-
process.exit(exitCode ?? 0);
|
|
91
|
-
});
|
|
81
|
+
if (command === '--version' || command === '-v') {
|
|
82
|
+
console.log(currentVersion);
|
|
83
|
+
process.exit(0);
|
|
84
|
+
}
|
|
92
85
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
86
|
+
switch (command) {
|
|
87
|
+
case 'env': {
|
|
88
|
+
const { run } = require('../lib/env');
|
|
89
|
+
run();
|
|
90
|
+
break;
|
|
98
91
|
}
|
|
99
|
-
process.exit(1);
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// ── CLI 配置 ──────────────────────────────────────────────────────────
|
|
104
|
-
|
|
105
|
-
program
|
|
106
|
-
.name("yida / openyida")
|
|
107
|
-
.description("OpenYida CLI - 宜搭命令行工具")
|
|
108
|
-
.version("0.1.0");
|
|
109
|
-
|
|
110
|
-
// ── yida login ────────────────────────────────────────────────────────
|
|
111
|
-
|
|
112
|
-
program
|
|
113
|
-
.command("login")
|
|
114
|
-
.description("扫码登录宜搭(打开浏览器扫码)")
|
|
115
|
-
.action(() => {
|
|
116
|
-
console.log("🔐 正在启动登录流程,请扫码...\n");
|
|
117
|
-
const scriptPath = getSkillScript("yida-login", "login.py");
|
|
118
|
-
runPythonScript(scriptPath);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// ── yida logout ───────────────────────────────────────────────────────
|
|
122
|
-
|
|
123
|
-
program
|
|
124
|
-
.command("logout")
|
|
125
|
-
.description("退出登录,清除本地登录态")
|
|
126
|
-
.action(() => {
|
|
127
|
-
console.log("👋 正在退出登录...\n");
|
|
128
|
-
const scriptPath = getSkillScript("yida-logout", "logout.py");
|
|
129
|
-
runPythonScript(scriptPath);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
// ── yida create-app ───────────────────────────────────────────────────
|
|
133
|
-
|
|
134
|
-
program
|
|
135
|
-
.command("create-app <name>")
|
|
136
|
-
.description("创建宜搭应用")
|
|
137
|
-
.option("-d, --description <desc>", "应用描述(默认同应用名称)")
|
|
138
|
-
.option("-i, --icon <icon>", "图标标识(默认 xian-yingyong)", "xian-yingyong")
|
|
139
|
-
.option("-c, --color <color>", "图标颜色(默认 #0089FF)", "#0089FF")
|
|
140
|
-
.addHelpText("after", `
|
|
141
|
-
示例:
|
|
142
|
-
$ yida create-app "考勤管理"
|
|
143
|
-
$ yida create-app "考勤管理" -d "员工考勤打卡系统" -i xian-daka -c "#00B853"
|
|
144
|
-
|
|
145
|
-
可用图标:
|
|
146
|
-
xian-xinwen, xian-zhengfu, xian-yingyong, xian-xueshimao, xian-qiye,
|
|
147
|
-
xian-danju, xian-shichang, xian-jingli, xida-falv, xian-baogao,
|
|
148
|
-
huoche, xian-shenbao, xian-diqiu, xian-qiche, xian-feiji,
|
|
149
|
-
xian-diannao, xian-gongzuozheng, xian-gouwuche, xian-xinyongka,
|
|
150
|
-
xian-huodong, xian-jiangbei, xian-liucheng, xian-chaxun, xian-daka
|
|
151
|
-
|
|
152
|
-
可用颜色:
|
|
153
|
-
#0089FF #00B853 #FFA200 #FF7357 #5C72FF
|
|
154
|
-
#85C700 #FFC505 #FF6B7A #8F66FF #14A9FF`)
|
|
155
|
-
.action((name, options) => {
|
|
156
|
-
const scriptPath = getSkillScript("yida-create-app", "create-app.js");
|
|
157
|
-
const args = [name];
|
|
158
|
-
if (options.description) args.push(options.description);
|
|
159
|
-
else args.push(name); // 默认 description 同 name
|
|
160
|
-
args.push(options.icon);
|
|
161
|
-
args.push(options.color);
|
|
162
|
-
runNodeScript(scriptPath, args);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
// ── yida create-page ──────────────────────────────────────────────────
|
|
166
|
-
|
|
167
|
-
program
|
|
168
|
-
.command("create-page")
|
|
169
|
-
.description("在指定应用中创建自定义展示页面")
|
|
170
|
-
.argument("<app>", "应用 ID(如 APP_XXXXXXXXXXXXX)")
|
|
171
|
-
.argument("<name>", "页面名称")
|
|
172
|
-
.addHelpText("after", `
|
|
173
|
-
示例:
|
|
174
|
-
$ yida create-page APP_XXXXXXXXXXXXX "游戏主页"
|
|
175
|
-
$ yida create-page APP_XXXXXXXXXXXXX "数据看板"`)
|
|
176
|
-
.action((app, name) => {
|
|
177
|
-
const scriptPath = getSkillScript("yida-create-page", "create-page.js");
|
|
178
|
-
runNodeScript(scriptPath, [app, name]);
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// ── yida create-form ──────────────────────────────────────────────────
|
|
182
|
-
|
|
183
|
-
program
|
|
184
|
-
.command("create-form")
|
|
185
|
-
.description("在指定应用中创建表单页面")
|
|
186
|
-
.argument("<app>", "应用 ID(如 APP_XXXXXXXXXXXXX)")
|
|
187
|
-
.argument("<name>", "表单名称")
|
|
188
|
-
.argument("<fields>", "字段定义(JSON 字符串或 JSON 文件路径)")
|
|
189
|
-
.addHelpText("after", `
|
|
190
|
-
示例:
|
|
191
|
-
$ yida create-form APP_XXX "客户信息" fields.json
|
|
192
|
-
$ yida create-form APP_XXX "客户信息" '[{"type":"TextField","label":"姓名"}]'`)
|
|
193
|
-
.action((app, name, fields) => {
|
|
194
|
-
const scriptPath = getSkillScript("yida-create-form-page", "create-form-page.js");
|
|
195
|
-
runNodeScript(scriptPath, [app, name, fields]);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
// ── yida publish ──────────────────────────────────────────────────────
|
|
199
|
-
|
|
200
|
-
program
|
|
201
|
-
.command("publish")
|
|
202
|
-
.description("编译并发布自定义页面到宜搭")
|
|
203
|
-
.argument("<file>", "源文件路径(如 pages/src/myapp.js)")
|
|
204
|
-
.argument("<app>", "应用 ID(如 APP_XXXXXXXXXXXXX)")
|
|
205
|
-
.argument("<form>", "表单/页面 UUID(如 FORM-XXXXXXXXXXXXX)")
|
|
206
|
-
.addHelpText("after", `
|
|
207
|
-
示例:
|
|
208
|
-
$ yida publish pages/src/myapp.js APP_XXXXXXXXXXXXX FORM-XXXXXXXXXXXXX`)
|
|
209
|
-
.action((file, app, form) => {
|
|
210
|
-
const scriptPath = getSkillScript("yida-publish-page", "publish.js");
|
|
211
|
-
runNodeScript(scriptPath, [app, form, file]);
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
// ── yida get-schema ───────────────────────────────────────────────────
|
|
215
|
-
|
|
216
|
-
program
|
|
217
|
-
.command("get-schema")
|
|
218
|
-
.description("获取表单/页面的完整 Schema 结构")
|
|
219
|
-
.argument("<app>", "应用 ID(如 APP_XXXXXXXXXXXXX)")
|
|
220
|
-
.argument("<form>", "表单 UUID(如 FORM-XXXXXXXXXXXXX)")
|
|
221
|
-
.addHelpText("after", `
|
|
222
|
-
示例:
|
|
223
|
-
$ yida get-schema APP_XXXXXXXXXXXXX FORM-XXXXXXXXXXXXX
|
|
224
|
-
$ yida get-schema APP_XXXXXXXXXXXXX FORM-XXXXXXXXXXXXX > schema.json`)
|
|
225
|
-
.action((app, form) => {
|
|
226
|
-
const scriptPath = getSkillScript("yida-get-schema", "get-schema.js");
|
|
227
|
-
runNodeScript(scriptPath, [app, form]);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
// ── yida config ───────────────────────────────────────────────────────
|
|
231
92
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
.option("--rollback", "回滚到上一个备份配置(.cache/config.backup.json)")
|
|
237
|
-
.option("--show", "显示当前配置(同默认行为)")
|
|
238
|
-
.addHelpText("after", `
|
|
239
|
-
示例:
|
|
240
|
-
$ yida config # 查看配置和环境状态
|
|
241
|
-
$ yida config --validate # 校验配置格式
|
|
242
|
-
$ yida config --rollback # 回滚到备份配置`)
|
|
243
|
-
.action((options) => {
|
|
244
|
-
const projectRoot = findProjectRoot();
|
|
245
|
-
const configPath = path.join(projectRoot, "config.json");
|
|
246
|
-
const backupPath = path.join(projectRoot, ".cache", "config.backup.json");
|
|
247
|
-
|
|
248
|
-
// --rollback:回滚到备份配置
|
|
249
|
-
if (options.rollback) {
|
|
250
|
-
if (!fs.existsSync(backupPath)) {
|
|
251
|
-
console.error("❌ 未找到备份配置文件:.cache/config.backup.json");
|
|
252
|
-
console.error(" 请先运行 yida config 生成备份,或手动创建 config.json");
|
|
253
|
-
process.exit(1);
|
|
254
|
-
}
|
|
255
|
-
try {
|
|
256
|
-
const backupContent = fs.readFileSync(backupPath, "utf-8");
|
|
257
|
-
JSON.parse(backupContent); // 验证备份文件是合法 JSON
|
|
258
|
-
fs.writeFileSync(configPath, backupContent, "utf-8");
|
|
259
|
-
console.log("✅ 已回滚到备份配置:");
|
|
260
|
-
const config = JSON.parse(backupContent);
|
|
261
|
-
Object.entries(config).forEach(([key, value]) => {
|
|
262
|
-
console.log(` ${key}: ${value}`);
|
|
263
|
-
});
|
|
264
|
-
} catch (err) {
|
|
265
|
-
console.error(`❌ 回滚失败:${err.message}`);
|
|
266
|
-
process.exit(1);
|
|
267
|
-
}
|
|
268
|
-
return;
|
|
93
|
+
case 'copy': {
|
|
94
|
+
const { run } = require('../lib/copy');
|
|
95
|
+
run();
|
|
96
|
+
break;
|
|
269
97
|
}
|
|
270
98
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
console.log(
|
|
99
|
+
case 'login': {
|
|
100
|
+
const { ensureLogin, checkLoginOnly } = require('../lib/login');
|
|
101
|
+
if (args[0] === '--check-only') {
|
|
102
|
+
const result = checkLoginOnly();
|
|
103
|
+
console.log(JSON.stringify(result, null, 2));
|
|
276
104
|
} else {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
process.exit(1);
|
|
105
|
+
const result = ensureLogin();
|
|
106
|
+
console.log(JSON.stringify(result));
|
|
280
107
|
}
|
|
281
|
-
|
|
108
|
+
break;
|
|
282
109
|
}
|
|
283
110
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (!fs.existsSync(configPath)) {
|
|
290
|
-
console.log("⚠️ 未找到 config.json,使用默认配置");
|
|
291
|
-
console.log(" defaultBaseUrl: https://www.aliwork.com");
|
|
292
|
-
console.log("");
|
|
293
|
-
console.log("💡 运行 yida doctor --repair 自动创建配置模板");
|
|
294
|
-
return;
|
|
111
|
+
case 'logout': {
|
|
112
|
+
const { logout } = require('../lib/login');
|
|
113
|
+
logout();
|
|
114
|
+
break;
|
|
295
115
|
}
|
|
296
116
|
|
|
297
|
-
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
console.log(` ${key}: ${value}`);
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
// 自动备份有效配置
|
|
305
|
-
const cacheDir = path.join(projectRoot, ".cache");
|
|
306
|
-
if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true });
|
|
307
|
-
fs.copyFileSync(configPath, backupPath);
|
|
308
|
-
} catch {
|
|
309
|
-
console.error("❌ 读取配置文件失败(JSON 格式错误)");
|
|
310
|
-
console.error(" 运行 yida config --rollback 回滚到上一个有效配置");
|
|
117
|
+
case 'create-app': {
|
|
118
|
+
const { run } = require('../lib/create-app');
|
|
119
|
+
await run(args);
|
|
120
|
+
break;
|
|
311
121
|
}
|
|
312
122
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
try {
|
|
318
|
-
const cookieData = JSON.parse(fs.readFileSync(cookiePath, "utf-8"));
|
|
319
|
-
const cookies = Array.isArray(cookieData) ? cookieData : cookieData.cookies || [];
|
|
320
|
-
const hasToken = cookies.some((c) => c.name === "tianshu_csrf_token");
|
|
321
|
-
console.log(`🔑 登录态:${hasToken ? "✅ 已登录" : "⚠️ Cookie 存在但可能已过期"}`);
|
|
322
|
-
} catch {
|
|
323
|
-
console.log("🔑 登录态:⚠️ Cookie 文件损坏");
|
|
324
|
-
}
|
|
325
|
-
} else {
|
|
326
|
-
console.log("🔑 登录态:❌ 未登录(运行 yida login 登录)");
|
|
123
|
+
case 'create-page': {
|
|
124
|
+
const { run } = require('../lib/create-page');
|
|
125
|
+
await run(args);
|
|
126
|
+
break;
|
|
327
127
|
}
|
|
328
128
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
fs.statSync(path.join(skillsPath, name)).isDirectory()
|
|
335
|
-
);
|
|
336
|
-
console.log(`📦 已安装 Skills(${skills.length} 个):`);
|
|
337
|
-
skills.forEach((skill) => console.log(` - ${skill}`));
|
|
338
|
-
} else {
|
|
339
|
-
console.log("📦 Skills:❌ 未安装(运行 bash install-skills.sh 安装)");
|
|
129
|
+
case 'create-form': {
|
|
130
|
+
// create-form.js 通过 process.argv.slice(2) 读取参数,注入子命令及其参数
|
|
131
|
+
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
132
|
+
require('../lib/create-form');
|
|
133
|
+
break;
|
|
340
134
|
}
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
// ── yida doctor ───────────────────────────────────────────────────────
|
|
344
|
-
|
|
345
|
-
program
|
|
346
|
-
.command("doctor")
|
|
347
|
-
.description("检查 OpenYida 环境依赖,发现问题并给出修复建议")
|
|
348
|
-
.option("--repair", "自动修复可修复的问题(如创建 config.json 模板)")
|
|
349
|
-
.addHelpText("after", `
|
|
350
|
-
示例:
|
|
351
|
-
$ yida doctor # 检查环境
|
|
352
|
-
$ yida doctor --repair # 检查并自动修复`)
|
|
353
|
-
.action((options) => {
|
|
354
|
-
runDoctorCheck(options.repair);
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
// ── yida completion ───────────────────────────────────────────────────
|
|
358
|
-
|
|
359
|
-
program
|
|
360
|
-
.command("completion")
|
|
361
|
-
.description("输出 shell 自动补全脚本(bash/zsh/fish)")
|
|
362
|
-
.argument("<shell>", "目标 shell 类型:bash | zsh | fish")
|
|
363
|
-
.addHelpText("after", `
|
|
364
|
-
安装方法:
|
|
365
|
-
bash: yida completion bash >> ~/.bashrc && source ~/.bashrc
|
|
366
|
-
zsh: yida completion zsh >> ~/.zshrc && source ~/.zshrc
|
|
367
|
-
fish: yida completion fish > ~/.config/fish/completions/yida.fish`)
|
|
368
|
-
.action((shellType) => {
|
|
369
|
-
printCompletionScript(shellType);
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
// ── yida shell ────────────────────────────────────────────────────────
|
|
373
|
-
|
|
374
|
-
program
|
|
375
|
-
.command("shell")
|
|
376
|
-
.description("进入交互式 REPL 模式")
|
|
377
|
-
.action(() => {
|
|
378
|
-
const readline = require("readline");
|
|
379
|
-
|
|
380
|
-
const rl = readline.createInterface({
|
|
381
|
-
input: process.stdin,
|
|
382
|
-
output: process.stdout,
|
|
383
|
-
prompt: "yida> ",
|
|
384
|
-
historySize: 100,
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
console.log("🤖 OpenYida Shell(输入 help 查看命令,输入 exit 退出)\n");
|
|
388
|
-
rl.prompt();
|
|
389
|
-
|
|
390
|
-
rl.on("line", (line) => {
|
|
391
|
-
const input = line.trim();
|
|
392
135
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
if (input === "exit" || input === "quit") {
|
|
399
|
-
console.log("👋 再见!");
|
|
400
|
-
rl.close();
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
if (input === "help") {
|
|
405
|
-
console.log(`
|
|
406
|
-
可用命令:
|
|
407
|
-
login 扫码登录
|
|
408
|
-
logout 退出登录
|
|
409
|
-
create-app <name> 创建应用
|
|
410
|
-
create-page <app> <name> 创建自定义页面
|
|
411
|
-
create-form <app> <name> <fields> 创建表单页面
|
|
412
|
-
publish <file> <app> <form> 发布页面
|
|
413
|
-
get-schema <app> <form> 获取表单 Schema
|
|
414
|
-
config 查看配置
|
|
415
|
-
exit / quit 退出 Shell
|
|
416
|
-
`);
|
|
417
|
-
rl.prompt();
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
// 将输入解析为 argv 并交给 Commander 处理
|
|
422
|
-
const args = parseShellArgs(input);
|
|
423
|
-
try {
|
|
424
|
-
// 暂停 readline,等待子命令完成后恢复
|
|
425
|
-
rl.pause();
|
|
426
|
-
const child = spawn(process.execPath, [process.argv[1], ...args], {
|
|
427
|
-
stdio: "inherit",
|
|
428
|
-
cwd: process.cwd(),
|
|
429
|
-
});
|
|
430
|
-
child.on("close", () => {
|
|
431
|
-
rl.resume();
|
|
432
|
-
rl.prompt();
|
|
433
|
-
});
|
|
434
|
-
child.on("error", (error) => {
|
|
435
|
-
console.error(`\n❌ 执行失败:${error.message}`);
|
|
436
|
-
rl.resume();
|
|
437
|
-
rl.prompt();
|
|
438
|
-
});
|
|
439
|
-
} catch (error) {
|
|
440
|
-
console.error(`\n❌ 错误:${error.message}`);
|
|
441
|
-
rl.prompt();
|
|
442
|
-
}
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
rl.on("close", () => {
|
|
446
|
-
process.exit(0);
|
|
447
|
-
});
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
// ── doctor / completion / config 辅助函数 ────────────────────────────
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* 校验 config.json 格式和必填字段
|
|
454
|
-
* @param {string} configPath - config.json 的完整路径
|
|
455
|
-
* @returns {string[]} 错误列表,空数组表示校验通过
|
|
456
|
-
*/
|
|
457
|
-
function validateConfig(configPath) {
|
|
458
|
-
const errors = [];
|
|
459
|
-
if (!fs.existsSync(configPath)) {
|
|
460
|
-
errors.push("config.json 不存在");
|
|
461
|
-
return errors;
|
|
462
|
-
}
|
|
463
|
-
let config;
|
|
464
|
-
try {
|
|
465
|
-
config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
466
|
-
} catch {
|
|
467
|
-
errors.push("config.json 不是合法的 JSON 格式");
|
|
468
|
-
return errors;
|
|
469
|
-
}
|
|
470
|
-
if (!config.loginUrl) {
|
|
471
|
-
errors.push("缺少必填字段:loginUrl(宜搭登录页面地址)");
|
|
472
|
-
} else if (!/^https?:\/\/.+/.test(config.loginUrl)) {
|
|
473
|
-
errors.push("loginUrl 不是合法的 URL");
|
|
474
|
-
}
|
|
475
|
-
if (!config.defaultBaseUrl) {
|
|
476
|
-
errors.push("缺少必填字段:defaultBaseUrl(API 请求基础地址)");
|
|
477
|
-
} else if (!/^https?:\/\/.+/.test(config.defaultBaseUrl)) {
|
|
478
|
-
errors.push("defaultBaseUrl 不是合法的 URL");
|
|
479
|
-
}
|
|
480
|
-
return errors;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
/**
|
|
484
|
-
* 执行 yida doctor 环境检查
|
|
485
|
-
* @param {boolean} repair - 是否自动修复可修复的问题
|
|
486
|
-
*/
|
|
487
|
-
function runDoctorCheck(repair) {
|
|
488
|
-
const projectRoot = findProjectRoot();
|
|
489
|
-
const configPath = path.join(projectRoot, "config.json");
|
|
490
|
-
const cookiePath = path.join(projectRoot, ".cache", "cookies.json");
|
|
491
|
-
const skillsPath = path.join(projectRoot, ".claude", "skills", "skills");
|
|
492
|
-
|
|
493
|
-
console.log("🔍 检查 OpenYida 环境依赖...\n");
|
|
494
|
-
|
|
495
|
-
const issues = [];
|
|
496
|
-
|
|
497
|
-
// 1. Node.js 版本
|
|
498
|
-
const nodeVersion = process.versions.node;
|
|
499
|
-
const nodeMajor = parseInt(nodeVersion.split(".")[0], 10);
|
|
500
|
-
if (nodeMajor >= 16) {
|
|
501
|
-
console.log(`✅ Node.js v${nodeVersion}(要求 ≥ 16)`);
|
|
502
|
-
} else {
|
|
503
|
-
console.log(`❌ Node.js v${nodeVersion}(要求 ≥ 16,请升级)`);
|
|
504
|
-
issues.push({ type: "error", msg: `Node.js 版本过低(${nodeVersion}),请升级到 v16+` });
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
// 2. Python 版本
|
|
508
|
-
try {
|
|
509
|
-
const pythonVersion = execSync("python3 --version 2>&1", { encoding: "utf-8" }).trim();
|
|
510
|
-
const versionMatch = pythonVersion.match(/Python (\d+)\.(\d+)/);
|
|
511
|
-
if (versionMatch) {
|
|
512
|
-
const major = parseInt(versionMatch[1], 10);
|
|
513
|
-
const minor = parseInt(versionMatch[2], 10);
|
|
514
|
-
if (major > 3 || (major === 3 && minor >= 10)) {
|
|
515
|
-
console.log(`✅ ${pythonVersion}(要求 ≥ 3.10)`);
|
|
516
|
-
} else {
|
|
517
|
-
console.log(`❌ ${pythonVersion}(要求 ≥ 3.10,请升级)`);
|
|
518
|
-
issues.push({ type: "error", msg: `Python 版本过低(${pythonVersion}),请升级到 3.10+` });
|
|
519
|
-
}
|
|
136
|
+
case 'get-schema': {
|
|
137
|
+
const { run } = require('../lib/get-schema');
|
|
138
|
+
await run(args);
|
|
139
|
+
break;
|
|
520
140
|
}
|
|
521
|
-
} catch {
|
|
522
|
-
console.log("❌ 未找到 python3,请安装 Python 3.10+");
|
|
523
|
-
issues.push({ type: "error", msg: "未找到 python3,请安装:https://www.python.org/" });
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
// 3. Playwright 安装
|
|
527
|
-
try {
|
|
528
|
-
execSync("python3 -c \"import playwright\"", { encoding: "utf-8", stdio: "pipe" });
|
|
529
|
-
console.log("✅ Playwright 已安装");
|
|
530
|
-
} catch {
|
|
531
|
-
console.log("❌ Playwright 未安装");
|
|
532
|
-
issues.push({ type: "fix", msg: "Playwright 未安装", fix: "pip install playwright" });
|
|
533
|
-
}
|
|
534
141
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
// 5. gh CLI 安装
|
|
548
|
-
try {
|
|
549
|
-
const ghVersion = execSync("gh --version 2>&1", { encoding: "utf-8" }).split("\n")[0].trim();
|
|
550
|
-
console.log(`✅ ${ghVersion}`);
|
|
551
|
-
} catch {
|
|
552
|
-
console.log("❌ gh CLI 未安装");
|
|
553
|
-
issues.push({ type: "error", msg: "gh CLI 未安装,请安装:https://cli.github.com/" });
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// 6. gh CLI 登录态
|
|
557
|
-
try {
|
|
558
|
-
execSync("gh auth status 2>&1", { encoding: "utf-8", stdio: "pipe" });
|
|
559
|
-
console.log("✅ gh CLI 已登录");
|
|
560
|
-
} catch {
|
|
561
|
-
console.log("⚠️ gh CLI 未登录");
|
|
562
|
-
issues.push({ type: "fix", msg: "gh CLI 未登录", fix: "gh auth login" });
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
// 7. config.json
|
|
566
|
-
const configErrors = validateConfig(configPath);
|
|
567
|
-
if (configErrors.length === 0) {
|
|
568
|
-
console.log("✅ config.json 存在且格式正确");
|
|
569
|
-
} else {
|
|
570
|
-
const isNotExist = configErrors[0].includes("不存在");
|
|
571
|
-
console.log(`${isNotExist ? "⚠️ " : "❌"} config.json:${configErrors.join(";")}`);
|
|
572
|
-
issues.push({
|
|
573
|
-
type: isNotExist ? "fix" : "error",
|
|
574
|
-
msg: `config.json 问题:${configErrors.join(";")}`,
|
|
575
|
-
fix: isNotExist ? "create-config" : null,
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
// 8. Skills 安装
|
|
580
|
-
if (fs.existsSync(skillsPath)) {
|
|
581
|
-
const skills = fs.readdirSync(skillsPath).filter((name) =>
|
|
582
|
-
fs.statSync(path.join(skillsPath, name)).isDirectory()
|
|
583
|
-
);
|
|
584
|
-
console.log(`✅ Skills 已安装(${skills.length} 个)`);
|
|
585
|
-
} else {
|
|
586
|
-
console.log("⚠️ Skills 未安装");
|
|
587
|
-
issues.push({ type: "warn", msg: "Skills 未安装,运行 bash install-skills.sh 安装" });
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
// 9. 宜搭登录态
|
|
591
|
-
if (fs.existsSync(cookiePath)) {
|
|
592
|
-
try {
|
|
593
|
-
const cookieData = JSON.parse(fs.readFileSync(cookiePath, "utf-8"));
|
|
594
|
-
const cookies = Array.isArray(cookieData) ? cookieData : cookieData.cookies || [];
|
|
595
|
-
const hasToken = cookies.some((c) => c.name === "tianshu_csrf_token");
|
|
596
|
-
console.log(`${hasToken ? "✅" : "⚠️ "} 宜搭登录态:${hasToken ? "已登录" : "Cookie 存在但可能已过期"}`);
|
|
597
|
-
} catch {
|
|
598
|
-
console.log("⚠️ 宜搭登录态:Cookie 文件损坏");
|
|
142
|
+
case 'publish': {
|
|
143
|
+
// 参数顺序:<源文件路径> <appType> <formUuid>
|
|
144
|
+
// publish.js 内部读取顺序:argv[2]=appType, argv[3]=formUuid, argv[4]=sourceFile
|
|
145
|
+
if (args.length < 3) {
|
|
146
|
+
console.error('用法: openyida publish <源文件路径> <appType> <formUuid>');
|
|
147
|
+
console.error('示例: openyida publish pages/src/home.jsx APP_XXX FORM-XXX');
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
const [sourceFile, appType, formUuid] = args;
|
|
151
|
+
process.argv = [process.argv[0], process.argv[1], appType, formUuid, sourceFile];
|
|
152
|
+
require('../lib/publish');
|
|
153
|
+
break;
|
|
599
154
|
}
|
|
600
|
-
} else {
|
|
601
|
-
console.log("⚠️ 宜搭登录态:未登录(运行 yida login 登录)");
|
|
602
|
-
}
|
|
603
155
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
if (issues.length === 0) {
|
|
611
|
-
console.log("🎉 所有检查通过,环境配置完整!");
|
|
612
|
-
return;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
console.log(`发现 ${issues.length} 个问题(${errorCount} 个错误,${fixableCount} 个可自动修复,${warnCount} 个警告)`);
|
|
616
|
-
|
|
617
|
-
if (repair) {
|
|
618
|
-
console.log("\n🔧 正在自动修复...\n");
|
|
619
|
-
let fixedCount = 0;
|
|
620
|
-
for (const issue of issues) {
|
|
621
|
-
if (issue.type !== "fix") continue;
|
|
622
|
-
if (issue.fix === "create-config") {
|
|
623
|
-
const template = {
|
|
624
|
-
loginUrl: "https://www.aliwork.com/workPlatform",
|
|
625
|
-
defaultBaseUrl: "https://www.aliwork.com",
|
|
626
|
-
};
|
|
627
|
-
fs.writeFileSync(configPath, JSON.stringify(template, null, 2), "utf-8");
|
|
628
|
-
console.log("✅ 已创建 config.json 模板,请根据实际情况修改 loginUrl");
|
|
629
|
-
fixedCount++;
|
|
630
|
-
} else if (issue.fix) {
|
|
631
|
-
console.log(` 💡 请手动运行:${issue.fix}`);
|
|
156
|
+
case 'verify-short-url': {
|
|
157
|
+
if (args.length < 3) {
|
|
158
|
+
console.error('用法: openyida verify-short-url <appType> <formUuid> <url>');
|
|
159
|
+
console.error('示例: openyida verify-short-url APP_XXX FORM-XXX /o/myapp');
|
|
160
|
+
process.exit(1);
|
|
632
161
|
}
|
|
162
|
+
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
163
|
+
require('../lib/verify-short-url');
|
|
164
|
+
break;
|
|
633
165
|
}
|
|
634
|
-
if (fixedCount > 0) {
|
|
635
|
-
console.log(`\n✅ 自动修复了 ${fixedCount} 个问题`);
|
|
636
|
-
}
|
|
637
|
-
const remaining = issues.filter(
|
|
638
|
-
(i) => i.type === "error" || (i.type === "fix" && i.fix !== "create-config")
|
|
639
|
-
);
|
|
640
|
-
if (remaining.length > 0) {
|
|
641
|
-
console.log("\n需要手动处理的问题:");
|
|
642
|
-
remaining.forEach((i) => console.log(` - ${i.msg}${i.fix ? `(运行:${i.fix})` : ""}`));
|
|
643
|
-
}
|
|
644
|
-
} else {
|
|
645
|
-
console.log(`\n运行 yida doctor --repair 自动修复可修复的问题`);
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
/**
|
|
650
|
-
* 输出 shell 自动补全脚本
|
|
651
|
-
* @param {string} shellType - bash | zsh | fish
|
|
652
|
-
*/
|
|
653
|
-
function printCompletionScript(shellType) {
|
|
654
|
-
const allCommands = [
|
|
655
|
-
"login", "logout", "create-app", "create-page", "create-form",
|
|
656
|
-
"publish", "get-schema", "config", "doctor", "completion", "shell",
|
|
657
|
-
];
|
|
658
|
-
const commandsStr = allCommands.join(" ");
|
|
659
|
-
|
|
660
|
-
switch (shellType.toLowerCase()) {
|
|
661
|
-
case "bash":
|
|
662
|
-
console.log(`# OpenYida CLI bash completion
|
|
663
|
-
# 安装:yida completion bash >> ~/.bashrc && source ~/.bashrc
|
|
664
|
-
|
|
665
|
-
_yida_completion() {
|
|
666
|
-
local cur prev words cword
|
|
667
|
-
_init_completion || return
|
|
668
|
-
|
|
669
|
-
local commands="${commandsStr}"
|
|
670
|
-
|
|
671
|
-
case "$prev" in
|
|
672
|
-
yida)
|
|
673
|
-
COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
|
|
674
|
-
return ;;
|
|
675
|
-
config)
|
|
676
|
-
COMPREPLY=( $(compgen -W "--validate --rollback --show" -- "$cur") )
|
|
677
|
-
return ;;
|
|
678
|
-
doctor)
|
|
679
|
-
COMPREPLY=( $(compgen -W "--repair" -- "$cur") )
|
|
680
|
-
return ;;
|
|
681
|
-
completion)
|
|
682
|
-
COMPREPLY=( $(compgen -W "bash zsh fish" -- "$cur") )
|
|
683
|
-
return ;;
|
|
684
|
-
create-app)
|
|
685
|
-
COMPREPLY=( $(compgen -W "--description --icon --color" -- "$cur") )
|
|
686
|
-
return ;;
|
|
687
|
-
esac
|
|
688
|
-
}
|
|
689
166
|
|
|
690
|
-
|
|
167
|
+
case 'save-share-config': {
|
|
168
|
+
if (args.length < 4) {
|
|
169
|
+
console.error('用法: openyida save-share-config <appType> <formUuid> <url> <isOpen> [openAuth]');
|
|
170
|
+
console.error('示例: openyida save-share-config APP_XXX FORM-XXX /o/myapp y n');
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
174
|
+
require('../lib/save-share-config');
|
|
691
175
|
break;
|
|
176
|
+
}
|
|
692
177
|
|
|
693
|
-
case
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
'logout:退出登录'
|
|
702
|
-
'create-app:创建宜搭应用'
|
|
703
|
-
'create-page:创建自定义页面'
|
|
704
|
-
'create-form:创建表单页面'
|
|
705
|
-
'publish:发布页面到宜搭'
|
|
706
|
-
'get-schema:获取表单 Schema'
|
|
707
|
-
'config:查看/校验/回滚配置'
|
|
708
|
-
'doctor:检查环境依赖'
|
|
709
|
-
'completion:输出 shell 补全脚本'
|
|
710
|
-
'shell:进入交互式 REPL 模式'
|
|
711
|
-
)
|
|
712
|
-
|
|
713
|
-
_arguments -C \\\\
|
|
714
|
-
'1: :->command' \\\\
|
|
715
|
-
'*: :->args'
|
|
716
|
-
|
|
717
|
-
case $state in
|
|
718
|
-
command)
|
|
719
|
-
_describe 'yida commands' commands ;;
|
|
720
|
-
args)
|
|
721
|
-
case $words[2] in
|
|
722
|
-
config)
|
|
723
|
-
_arguments '--validate[校验配置]' '--rollback[回滚配置]' '--show[显示配置]' ;;
|
|
724
|
-
doctor)
|
|
725
|
-
_arguments '--repair[自动修复]' ;;
|
|
726
|
-
completion)
|
|
727
|
-
_arguments '1: :(bash zsh fish)' ;;
|
|
728
|
-
create-app)
|
|
729
|
-
_arguments '--description[应用描述]' '--icon[图标]' '--color[颜色]' ;;
|
|
730
|
-
esac ;;
|
|
731
|
-
esac
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
# 仅在交互式 shell 中注册补全(避免非交互式 shell 报错)
|
|
735
|
-
if [[ -n \${ZSH_VERSION-} ]] && [[ \$- == *i* ]]; then
|
|
736
|
-
compdef _yida yida
|
|
737
|
-
fi`);
|
|
178
|
+
case 'get-page-config': {
|
|
179
|
+
if (args.length < 2) {
|
|
180
|
+
console.error('用法: openyida get-page-config <appType> <formUuid>');
|
|
181
|
+
console.error('示例: openyida get-page-config APP_XXX FORM-XXX');
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
185
|
+
require('../lib/get-page-config');
|
|
738
186
|
break;
|
|
187
|
+
}
|
|
739
188
|
|
|
740
|
-
case
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
complete -c yida -f -n '__fish_use_subcommand' -a 'create-page' -d '创建自定义页面'
|
|
749
|
-
complete -c yida -f -n '__fish_use_subcommand' -a 'create-form' -d '创建表单页面'
|
|
750
|
-
complete -c yida -f -n '__fish_use_subcommand' -a 'publish' -d '发布页面到宜搭'
|
|
751
|
-
complete -c yida -f -n '__fish_use_subcommand' -a 'get-schema' -d '获取表单 Schema'
|
|
752
|
-
complete -c yida -f -n '__fish_use_subcommand' -a 'config' -d '查看/校验/回滚配置'
|
|
753
|
-
complete -c yida -f -n '__fish_use_subcommand' -a 'doctor' -d '检查环境依赖'
|
|
754
|
-
complete -c yida -f -n '__fish_use_subcommand' -a 'completion' -d '输出 shell 补全脚本'
|
|
755
|
-
complete -c yida -f -n '__fish_use_subcommand' -a 'shell' -d '进入交互式 REPL 模式'
|
|
756
|
-
complete -c yida -f -n '__fish_seen_subcommand_from config' -l validate -d '校验配置格式'
|
|
757
|
-
complete -c yida -f -n '__fish_seen_subcommand_from config' -l rollback -d '回滚到备份配置'
|
|
758
|
-
complete -c yida -f -n '__fish_seen_subcommand_from config' -l show -d '显示当前配置'
|
|
759
|
-
complete -c yida -f -n '__fish_seen_subcommand_from doctor' -l repair -d '自动修复可修复的问题'
|
|
760
|
-
complete -c yida -f -n '__fish_seen_subcommand_from completion' -a 'bash zsh fish'
|
|
761
|
-
complete -c yida -f -n '__fish_seen_subcommand_from create-app' -l description -d '应用描述'
|
|
762
|
-
complete -c yida -f -n '__fish_seen_subcommand_from create-app' -l icon -d '图标标识'
|
|
763
|
-
complete -c yida -f -n '__fish_seen_subcommand_from create-app' -l color -d '图标颜色'`);
|
|
189
|
+
case 'update-form-config': {
|
|
190
|
+
if (args.length < 4) {
|
|
191
|
+
console.error('用法: openyida update-form-config <appType> <formUuid> <isRenderNav> <title>');
|
|
192
|
+
console.error('示例: openyida update-form-config APP_XXX FORM-XXX false "页面标题"');
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
195
|
+
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
196
|
+
require('../lib/update-form-config');
|
|
764
197
|
break;
|
|
198
|
+
}
|
|
765
199
|
|
|
766
|
-
default:
|
|
767
|
-
console.error(
|
|
768
|
-
console.error(
|
|
200
|
+
default: {
|
|
201
|
+
console.error(`未知命令: ${command}`);
|
|
202
|
+
console.error('运行 openyida --help 查看帮助');
|
|
769
203
|
process.exit(1);
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
/**
|
|
774
|
-
* 简单的 shell 参数解析(支持引号包裹的参数)
|
|
775
|
-
*/
|
|
776
|
-
function parseShellArgs(input) {
|
|
777
|
-
const args = [];
|
|
778
|
-
let current = "";
|
|
779
|
-
let inQuote = false;
|
|
780
|
-
let quoteChar = "";
|
|
781
|
-
|
|
782
|
-
for (const char of input) {
|
|
783
|
-
if (inQuote) {
|
|
784
|
-
if (char === quoteChar) {
|
|
785
|
-
inQuote = false;
|
|
786
|
-
} else {
|
|
787
|
-
current += char;
|
|
788
|
-
}
|
|
789
|
-
} else if (char === '"' || char === "'") {
|
|
790
|
-
inQuote = true;
|
|
791
|
-
quoteChar = char;
|
|
792
|
-
} else if (char === " ") {
|
|
793
|
-
if (current) {
|
|
794
|
-
args.push(current);
|
|
795
|
-
current = "";
|
|
796
|
-
}
|
|
797
|
-
} else {
|
|
798
|
-
current += char;
|
|
799
204
|
}
|
|
800
205
|
}
|
|
801
|
-
|
|
802
|
-
if (current) {
|
|
803
|
-
args.push(current);
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
return args;
|
|
807
206
|
}
|
|
808
207
|
|
|
809
|
-
|
|
208
|
+
main()
|
|
209
|
+
.then(() => updateCheckPromise)
|
|
210
|
+
.catch((err) => {
|
|
211
|
+
console.error(`\n❌ 执行失败: ${err.message}`);
|
|
212
|
+
process.exit(1);
|
|
213
|
+
});
|
|
810
214
|
|
|
811
|
-
program.parse(process.argv);
|