@openyida/yidacli 0.1.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/bin/yidacli.js +200 -0
- package/dist/babel-transform/index.js +1 -0
- package/dist/babel-transform/jsx-utils.js +1 -0
- package/dist/check-update.js +5 -0
- package/dist/create-app.js +12 -0
- package/dist/create-form.js +2 -0
- package/dist/create-page.js +2 -0
- package/dist/env.js +1 -0
- package/dist/get-page-config.js +3 -0
- package/dist/get-schema.js +2 -0
- package/dist/login.js +34 -0
- package/dist/publish.js +7 -0
- package/dist/save-share-config.js +3 -0
- package/dist/update-form-config.js +3 -0
- package/dist/utils.js +1 -0
- package/dist/verify-short-url.js +3 -0
- package/openyida/.cache/.gitkeep +0 -0
- package/openyida/config.json +4 -0
- package/openyida/package.json +15 -0
- package/openyida/pages/dist/.gitkeep +0 -0
- package/openyida/pages/src/demo-birthday-game.js +833 -0
- package/openyida/pages/src/demo-future-vision-2026.js +1102 -0
- package/openyida/pages/src/demo-salary-calculator.js +904 -0
- package/openyida/prd/demo-birthday-game.md +39 -0
- package/openyida/prd/demo-future-vision-2026.md +78 -0
- package/openyida/prd/demo-salary-calculator.md +101 -0
- package/package.json +41 -0
- package/scripts/build.js +93 -0
- package/scripts/postinstall.js +111 -0
- package/scripts/prepublish.js +162 -0
package/bin/yidacli.js
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* yidacli - 宜搭命令行工具
|
|
4
|
+
*
|
|
5
|
+
* 命令列表:
|
|
6
|
+
* yidacli env 检测当前 AI 工具环境和登录态
|
|
7
|
+
* yidacli login 登录态管理
|
|
8
|
+
* yidacli logout 退出登录
|
|
9
|
+
* yidacli create-app "<名称>" [desc] [icon] [color] 创建应用
|
|
10
|
+
* yidacli create-page <appType> "<页面名>" 创建自定义页面
|
|
11
|
+
* yidacli create-form create <appType> "<表单名>" <字段JSON> 创建表单页面
|
|
12
|
+
* yidacli create-form update <appType> <formUuid> <修改JSON> 更新表单页面
|
|
13
|
+
* yidacli get-schema <appType> <formUuid> 获取表单 Schema
|
|
14
|
+
* yidacli publish <源文件路径> <appType> <formUuid> 编译并发布自定义页面
|
|
15
|
+
* yidacli verify-short-url <appType> <formUuid> <url> 验证短链接 URL 是否可用
|
|
16
|
+
* yidacli save-share-config <appType> <formUuid> <url> <isOpen> [openAuth] 保存公开访问/分享配置
|
|
17
|
+
* yidacli get-page-config <appType> <formUuid> 查询页面公开访问/分享配置
|
|
18
|
+
* yidacli update-form-config <appType> <formUuid> <isRenderNav> <title> 更新表单配置
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
"use strict";
|
|
22
|
+
|
|
23
|
+
const { checkUpdate } = require('../src/check-update');
|
|
24
|
+
const { version: currentVersion } = require('../package.json');
|
|
25
|
+
|
|
26
|
+
// 异步检查更新,fire-and-forget,不阻塞主流程
|
|
27
|
+
const updateCheckPromise = checkUpdate(currentVersion);
|
|
28
|
+
|
|
29
|
+
const command = process.argv[2];
|
|
30
|
+
const args = process.argv.slice(3);
|
|
31
|
+
|
|
32
|
+
function printHelp() {
|
|
33
|
+
console.log(`
|
|
34
|
+
yidacli - 宜搭命令行工具
|
|
35
|
+
|
|
36
|
+
用法:
|
|
37
|
+
yidacli <命令> [参数...]
|
|
38
|
+
|
|
39
|
+
命令:
|
|
40
|
+
env 检测当前 AI 工具环境和登录态
|
|
41
|
+
login 登录态管理(优先缓存,否则扫码)
|
|
42
|
+
logout 退出登录 / 切换账号
|
|
43
|
+
create-app "<名称>" [描述] [图标] [颜色] 创建应用,输出 appType
|
|
44
|
+
create-page <appType> "<页面名>" 创建自定义页面,输出 pageId
|
|
45
|
+
create-form create <appType> "<表单名>" <字段JSON> 创建表单页面
|
|
46
|
+
create-form update <appType> <formUuid> <修改JSON> 更新表单页面
|
|
47
|
+
get-schema <appType> <formUuid> 获取表单 Schema
|
|
48
|
+
publish <源文件路径> <appType> <formUuid> 编译并发布自定义页面
|
|
49
|
+
verify-short-url <appType> <formUuid> <url> 验证短链接 URL 是否可用
|
|
50
|
+
save-share-config <appType> <formUuid> <url> <isOpen> [auth] 保存公开访问/分享配置
|
|
51
|
+
get-page-config <appType> <formUuid> 查询页面公开访问/分享配置
|
|
52
|
+
update-form-config <appType> <formUuid> <isRenderNav> <title> 更新表单配置
|
|
53
|
+
|
|
54
|
+
示例:
|
|
55
|
+
yidacli login
|
|
56
|
+
yidacli logout
|
|
57
|
+
yidacli create-app "考勤管理"
|
|
58
|
+
yidacli create-page APP_XXX "游戏主页"
|
|
59
|
+
yidacli create-form create APP_XXX "员工信息" fields.json
|
|
60
|
+
yidacli create-form update APP_XXX FORM-XXX '[{"action":"add","field":{"type":"TextField","label":"备注"}}]'
|
|
61
|
+
yidacli get-schema APP_XXX FORM-XXX
|
|
62
|
+
yidacli publish pages/src/home.jsx APP_XXX FORM-XXX
|
|
63
|
+
yidacli verify-short-url APP_XXX FORM-XXX /o/myapp
|
|
64
|
+
yidacli save-share-config APP_XXX FORM-XXX /o/myapp y n
|
|
65
|
+
yidacli get-page-config APP_XXX FORM-XXX
|
|
66
|
+
yidacli update-form-config APP_XXX FORM-XXX false "页面标题"
|
|
67
|
+
`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function main() {
|
|
71
|
+
if (!command || command === '--help' || command === '-h') {
|
|
72
|
+
printHelp();
|
|
73
|
+
process.exit(0);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
switch (command) {
|
|
77
|
+
case 'env': {
|
|
78
|
+
const { run } = require('../dist/env');
|
|
79
|
+
run();
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
case 'login': {
|
|
84
|
+
const { ensureLogin, checkLoginOnly } = require('../dist/login');
|
|
85
|
+
if (args[0] === '--check-only') {
|
|
86
|
+
const result = checkLoginOnly();
|
|
87
|
+
console.log(JSON.stringify(result, null, 2));
|
|
88
|
+
} else {
|
|
89
|
+
const result = ensureLogin();
|
|
90
|
+
console.log(JSON.stringify(result));
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
case 'logout': {
|
|
96
|
+
const { logout } = require('../dist/login');
|
|
97
|
+
logout();
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
case 'create-app': {
|
|
102
|
+
const { run } = require('../dist/create-app');
|
|
103
|
+
await run(args);
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
case 'create-page': {
|
|
108
|
+
const { run } = require('../dist/create-page');
|
|
109
|
+
await run(args);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
case 'create-form': {
|
|
114
|
+
// 透传所有参数给 create-form.js(它自己处理 create/update 模式)
|
|
115
|
+
// 原脚本通过 process.argv.slice(2) 读取参数,需要注入到 argv
|
|
116
|
+
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
117
|
+
require('../dist/create-form');
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
case 'get-schema': {
|
|
122
|
+
const { run } = require('../dist/get-schema');
|
|
123
|
+
await run(args);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
case 'publish': {
|
|
128
|
+
// 原 publish.js 参数顺序:<appType> <formUuid> <源文件路径>
|
|
129
|
+
// yidacli 新顺序:<源文件路径> <appType> <formUuid>
|
|
130
|
+
// 需要重排参数
|
|
131
|
+
if (args.length < 3) {
|
|
132
|
+
console.error('用法: yidacli publish <源文件路径> <appType> <formUuid>');
|
|
133
|
+
console.error('示例: yidacli publish pages/src/home.jsx APP_XXX FORM-XXX');
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
const [sourceFile, appType, formUuid] = args;
|
|
137
|
+
// 注入重排后的参数(原脚本读取 argv[2]=appType, argv[3]=formUuid, argv[4]=sourceFile)
|
|
138
|
+
process.argv = [process.argv[0], process.argv[1], appType, formUuid, sourceFile];
|
|
139
|
+
require('../dist/publish');
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
case 'verify-short-url': {
|
|
144
|
+
if (args.length < 3) {
|
|
145
|
+
console.error('用法: yidacli verify-short-url <appType> <formUuid> <url>');
|
|
146
|
+
console.error('示例: yidacli verify-short-url APP_XXX FORM-XXX /o/myapp');
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
150
|
+
require('../dist/verify-short-url');
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
case 'save-share-config': {
|
|
155
|
+
if (args.length < 4) {
|
|
156
|
+
console.error('用法: yidacli save-share-config <appType> <formUuid> <url> <isOpen> [openAuth]');
|
|
157
|
+
console.error('示例: yidacli save-share-config APP_XXX FORM-XXX /o/myapp y n');
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
161
|
+
require('../dist/save-share-config');
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
case 'get-page-config': {
|
|
166
|
+
if (args.length < 2) {
|
|
167
|
+
console.error('用法: yidacli get-page-config <appType> <formUuid>');
|
|
168
|
+
console.error('示例: yidacli get-page-config APP_XXX FORM-XXX');
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
172
|
+
require('../dist/get-page-config');
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
case 'update-form-config': {
|
|
177
|
+
if (args.length < 4) {
|
|
178
|
+
console.error('用法: yidacli update-form-config <appType> <formUuid> <isRenderNav> <title>');
|
|
179
|
+
console.error('示例: yidacli update-form-config APP_XXX FORM-XXX false "页面标题"');
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
183
|
+
require('../dist/update-form-config');
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
default: {
|
|
188
|
+
console.error(`未知命令: ${command}`);
|
|
189
|
+
console.error('运行 yidacli --help 查看帮助');
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
main()
|
|
196
|
+
.then(() => updateCheckPromise)
|
|
197
|
+
.catch((err) => {
|
|
198
|
+
console.error(`\n❌ 执行失败: ${err.message}`);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"JSXUtil",{enumerable:!0,get:function(){return _jsxUtils.default}}),exports.default=compile,exports.getCode=getCode;var _jsxUtils=_interopRequireDefault(require("./jsx-utils"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function ownKeys(n,e){var t,o=Object.keys(n);return Object.getOwnPropertySymbols&&(t=Object.getOwnPropertySymbols(n),e&&(t=t.filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable})),o.push.apply(o,t)),o}function _objectSpread(n){for(var e=1;e<arguments.length;e++){var t=null!=arguments[e]?arguments[e]:{};e%2?ownKeys(Object(t),!0).forEach(function(e){_defineProperty(n,e,t[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(t)):ownKeys(Object(t)).forEach(function(e){Object.defineProperty(n,e,Object.getOwnPropertyDescriptor(t,e))})}return n}function _defineProperty(e,n,t){return(n=_toPropertyKey(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function _toPropertyKey(e){e=_toPrimitive(e,"string");return"symbol"===_typeof(e)?e:String(e)}function _toPrimitive(e,n){if("object"!==_typeof(e)||null===e)return e;var t=e[Symbol.toPrimitive];if(void 0===t)return("string"===n?String:Number)(e);t=t.call(e,n||"default");if("object"!==_typeof(t))return t;throw new TypeError("@@toPrimitive must return a primitive value.")}function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var VisualEngine,Babel=require("@babel/standalone"),RE_VERSION="4.0.0";function isString(e){return"[object String]"==={}.toString.call(e)}function findComps(e){var r,n=1<arguments.length&&void 0!==arguments[1]?arguments[1]:"normal",t=("object"===("undefined"==typeof window?"undefined":_typeof(window))?window:{}).MyBabel;e&&t&&(r=[],t.traverse(e,{CallExpression:function(e){if(e.node.callee&&"MemberExpression"===e.node.callee.type&&e.node.callee.property&&["createElement","getComponentView"].includes(e.node.callee.property.name)){for(var n=Array.isArray(e.node.arguments)?e.node.arguments[0]:{},t="";;){if(!n||"MemberExpression"!==n.type||!n.object){if(n&&"Identifier"===n.type){t="".concat(n.name).concat(""==t?"":".")+t;break}if(n&&"StringLiteral"===n.type){t+="".concat(n.value)+t;break}break}var o,t="".concat(null==(o=n)||null==(o=o.property)?void 0:o.name).concat(""==t?"":".")+t,n=n.object}r.push(t)}}}),_jsxUtils.default.setComps(n,r))}"object"===("undefined"==typeof window?"undefined":_typeof(window))&&(VisualEngine=window.VisualEngine,RE_VERSION=window.pageConfig&&window.pageConfig.RE_VERSION||VisualEngine&&VisualEngine.Env&&VisualEngine.Env.get("RE_VERSION")||window.RenderEngine&&window.RenderEngine.version||"4.0.0");var EMPTY_FUNC_STRING="function emptyCall() {}";function getCode(e){var n,t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{compiled:!1,allowEmpty:!1};return"string"==typeof e?e:"object"===_typeof(e)&&null!==e?(n=t.compiled?"value"in e?e.value:e.compiled:e.source,t.allowEmpty?n:n||EMPTY_FUNC_STRING):t.allowEmpty?e:EMPTY_FUNC_STRING}function compile(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:"",n=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},c=2<arguments.length&&void 0!==arguments[2]&&arguments[2],t=3<arguments.length&&void 0!==arguments[3]?arguments[3]:{},o=4<arguments.length&&void 0!==arguments[4]?arguments[4]:{},r="",i={},t=_objectSpread({RE_VERSION:RE_VERSION},t),a=parseFloat(t.RE_VERSION,10)<4.2;if(isString(e)&&""!==e){if(a&&!t.shouldCompile)return e;a=e;c&&(a="var __compiledFunc__ = ".concat(e,";"));try{var l,s,p,u,d,f=6<parseInt(Babel.version,10)?["react",["env",{loose:!0,spec:!0,targets:{browsers:["ie >= 11","chrome >= 62"]}}]]:["react","es2015-loose","stage-0"];r=parseFloat(t.RE_VERSION,10)<7?(r=(l=Babel.transform(a,_objectSpread({presets:f,ast:!0},n))).code,findComps(l.ast,t.id),c?"function main(){\n ".concat(r,"\n return __compiledFunc__.apply(this, arguments);\n }"):"".concat(r,"\n")):(s=[],p=[function(e){var i=e.types;var a=(0,e.template)("const TAGNAME = this._getComponentView(TAGNAME_S)");return{visitor:{JSXElement:function(e){var n,t,o=e.node,r=e.scope,o=function e(n){return"JSXMemberExpression"===n.type?e(n.object):"JSXIdentifier"===n.type?n.name:null}(o.openingElement.name);o&&/^[A-Z]/.test(o)&&!r.hasBinding(o)&&(c?-1<s.indexOf(o)||s.push(o):(t=o,(n=r).addonBindings&&-1<n.addonBindings.indexOf(t)||((n=e.getStatementParent()).parentPath.isProgram()||n.insertBefore(a({TAGNAME:i.identifier(o),TAGNAME_S:i.stringLiteral(o)})),t=o,(e=r).addonBindings||(e.addonBindings=[]),e.addonBindings.push(t))))}}}}],n.plugins&&(p=p.concat(n.plugins)),r=(u=Babel.transform(a,_objectSpread(_objectSpread({presets:f,ast:!0},n),{},{plugins:p}))).code,findComps(u.ast,t.id),c?(d=s.map(function(e){return"const ".concat(e," = this._getComponentView('").concat(e,"');")}).join("\n"),"function main(){\n ".concat(d,"\n ").concat(r,"\n return __compiledFunc__.apply(this, arguments);\n }")):"".concat(r,"\n"))}catch(e){console.error(e),i=e}}return null!=o&&o.preferJSExpression?{type:"JSExpression",source:e,value:r,extType:"function",error:i}:{type:"js",source:e,compiled:r,error:i}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var r=0;r<t.length;r++){var o=t[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,_toPropertyKey(o.key),o)}}function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function _defineProperty(e,t,r){return(t=_toPropertyKey(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function _toPropertyKey(e){e=_toPrimitive(e,"string");return"symbol"===_typeof(e)?e:String(e)}function _toPrimitive(e,t){if("object"!==_typeof(e)||null===e)return e;var r=e[Symbol.toPrimitive];if(void 0===r)return("string"===t?String:Number)(e);r=r.call(e,t||"default");if("object"!==_typeof(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var _window,_global,JSXUtil=(()=>{function e(){_classCallCheck(this,e),_defineProperty(this,"tags",{})}return _createClass(e,[{key:"setComps",value:function(e,t){var r,o;Array.isArray(t)&&(r=new Set(t),t=Array.from(r),e=e||"normal",Array.isArray(this.tags[e])||(this.tags[e]=[]),"normal"===e?(o=this.tags[e],t.forEach(function(e){return!o.includes(e)&&o.push(e)})):this.tags[e]=t)}},{key:"getComponentList",value:function(){var t=this,r=new Set;return Object.keys(this.tags).forEach(function(e){e=t.tags[e]||[];Array.isArray(e)&&e.forEach(function(e){return r.add(e)})}),Array.from(r)}},{key:"reset",value:function(){this.tags={}}}]),e})(),__vu_jsx_util__=("object"===("undefined"==typeof window?"undefined":_typeof(window))?(window.__vu_jsx_util__=(null==(_window=window)?void 0:_window.__vu_jsx_util__)||new JSXUtil,window):(global.__vu_jsx_util__=(null==(_global=global)?void 0:_global.__vu_jsx_util__)||new JSXUtil,global)).__vu_jsx_util__,_default=__vu_jsx_util__;exports.default=_default,module.exports=exports.default;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
let fs=require("fs"),path=require("path"),os=require("os"),https=require("https"),CACHE_FILE=path.join(os.homedir(),".yidacli-update-check.json"),CHECK_INTERVAL_MS=864e5,REGISTRY_URL="https://registry.npmjs.org/yidacli/latest";function fetchLatestVersion(){return new Promise(r=>{let e=https.get(REGISTRY_URL,{timeout:5e3},e=>{let t="";e.on("data",e=>{t+=e}),e.on("end",()=>{try{var e=JSON.parse(t);r(e.version||null)}catch{r(null)}})});e.on("error",()=>r(null)),e.on("timeout",()=>{e.destroy(),r(null)})})}function readCache(){try{return fs.existsSync(CACHE_FILE)?JSON.parse(fs.readFileSync(CACHE_FILE,"utf-8")):null}catch{return null}}function writeCache(e){try{fs.writeFileSync(CACHE_FILE,JSON.stringify({lastCheck:Date.now(),latestVersion:e}),"utf-8")}catch{}}function isNewer(e,t){var r=e=>(e||"").split(".").map(e=>parseInt(e,10)||0),[e,n,s]=r(e),[r,t,a]=r(t);return r!==e?e<r:t!==n?n<t:s<a}async function checkUpdate(t){try{var r=readCache(),n=Date.now();let e;r&&n-r.lastCheck<CHECK_INTERVAL_MS?e=r.latestVersion:(e=await fetchLatestVersion())&&writeCache(e),e&&isNewer(t,e)&&process.nextTick(()=>{console.error(`
|
|
2
|
+
💡 发现新版本 ${e}(当前 ${t})`+`
|
|
3
|
+
运行以下命令更新:
|
|
4
|
+
npm install -g yidacli@latest
|
|
5
|
+
`)})}catch{}}module.exports={checkUpdate:checkUpdate};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
let fs=require("fs"),path=require("path"),querystring=require("querystring"),{findProjectRoot,loadCookieData,triggerLogin,refreshCsrfToken,resolveBaseUrl,httpPost,requestWithAutoLogin}=require("./utils");function findPrdFile(){let r=process.cwd();for(let e=0;e<5;e++){var o=path.join(r,"prd");if(fs.existsSync(o)){var n=fs.readdirSync(o).find(e=>e.endsWith(".md"));if(n)return path.join(o,n)}o=path.dirname(r);if(o===r)break;r=o}return null}function updatePrdCorpId(r,o,n,a){if(!r||!fs.existsSync(r))return console.error(`
|
|
2
|
+
⚠️ 未找到 prd 文档,跳过 corpId 写入`),!1;try{let e=fs.readFileSync(r,"utf-8");var i,s,c=e.includes("## 应用配置")||e.includes("| appType |");return e=c?(i=/\| corpId \| [^\|]*\|/,(e=(e=i.test(e)?e.replace(i,`| corpId | ${o} |`):e.replace(/(\| appType \| [^\|]*\|)(\r?\n)/,`$1$2| corpId | ${o} |$2`)).replace(/\| appType \| [^\|]*\|/,`| appType | ${n} |`)).replace(/\| baseUrl \| [^\|]*\|/,`| baseUrl | ${a} |`)):(s=`## 应用配置
|
|
3
|
+
|
|
4
|
+
| 配置项 | 值 |
|
|
5
|
+
| --- | --- |
|
|
6
|
+
| appType | ${n} |
|
|
7
|
+
| corpId | ${o} |
|
|
8
|
+
| baseUrl | ${a} |
|
|
9
|
+
|
|
10
|
+
`,e.startsWith("#")?e.replace(/^(# .*\r?\n)/,`$1
|
|
11
|
+
`+s):s+e),fs.writeFileSync(r,e,"utf-8"),console.error(" ✅ 已更新 prd 文档: "+path.basename(r)),!0}catch(e){return console.error(" ⚠️ 更新 prd 文档失败: "+e.message),!1}}async function run(e){e.length<1&&(console.error('用法: yidacli create-app "<appName>" [description] [icon] [iconColor]'),console.error('示例: yidacli create-app "考勤管理" "员工考勤打卡系统" "xian-daka" "#00B853"'),console.error("\n可用图标:"),console.error(" xian-xinwen, xian-zhengfu, xian-yingyong, xian-xueshimao, xian-qiye,"),console.error(" xian-danju, xian-shichang, xian-jingli, xian-falv, xian-baogao,"),console.error(" huoche, xian-shenbao, xian-diqiu, xian-qiche, xian-feiji,"),console.error(" xian-diannao, xian-gongzuozheng, xian-gouwuche, xian-xinyongka,"),console.error(" xian-huodong, xian-jiangbei, xian-liucheng, xian-chaxun, xian-daka"),console.error("\n可用颜色:"),console.error(" #0089FF #00B853 #FFA200 #FF7357 #5C72FF"),console.error(" #85C700 #FFC505 #FF6B7A #8F66FF #14A9FF"),process.exit(1));let o=e[0],n=e[1]||o;var r=e[2]||"xian-yingyong",e=e[3]||"#0089FF";console.error("=".repeat(50)),console.error(" yidacli create-app - 宜搭应用创建工具"),console.error("=".repeat(50)),console.error(`
|
|
12
|
+
应用名称: `+o),console.error(" 应用描述: "+n),console.error(` 图标: ${r} (${e})`),console.error("\n🔑 Step 1: 读取登录态");let a=loadCookieData();a||(console.error(" ⚠️ 未找到本地登录态,触发登录..."),a=triggerLogin());var i={csrfToken:a.csrf_token,cookies:a.cookies,baseUrl:resolveBaseUrl(a),cookieData:a};console.error(` ✅ 登录态已就绪(${i.baseUrl})`),console.error("\n📦 Step 2: 创建应用\n");let s=r+"%%"+e;var c,t,l,r=await requestWithAutoLogin(e=>{var r=querystring.stringify({_csrf_token:e.csrfToken,appName:JSON.stringify({zh_CN:o,en_US:o,type:"i18n"}),description:JSON.stringify({zh_CN:n,en_US:n,type:"i18n"}),icon:s,iconUrl:s,colour:"blue",defaultLanguage:"zh_CN",openExclusive:"n",openPhysicColumn:"n",openIsolationDatabase:"n",openExclusiveUnit:"n",group:"全部应用"});return httpPost(e.baseUrl,"/query/app/registerApp.json",r,e.cookies)},i);console.error("\n"+"=".repeat(50)),r&&r.success&&r.content?(e=r.content,c=i.baseUrl+`/${e}/admin`,t=i.cookieData.corp_id||"",console.error(" ✅ 应用创建成功!"),console.error(" appType: "+e),console.error(" corpId: "+(t||"未获取")),console.error(" 访问地址: "+c),console.error("=".repeat(50)),(l=findPrdFile())&&updatePrdCorpId(l,t,e,i.baseUrl),console.log(JSON.stringify({success:!0,appType:e,appName:o,corpId:t,url:c}))):(l=r?r.errorMsg||"未知错误":"请求失败",console.error(" ❌ 创建失败: "+l),console.error("=".repeat(50)),console.log(JSON.stringify({success:!1,error:l})),process.exit(1))}module.exports={run:run};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
let https=require("https"),http=require("http"),fs=require("fs"),path=require("path"),querystring=require("querystring"),execSync=require("child_process").execSync,{findProjectRoot,loadCookieData,triggerLogin,refreshCsrfToken,resolveBaseUrl,isLoginExpired,isCsrfTokenExpired}=require("./utils"),CONFIG=fs.existsSync(path.resolve(findProjectRoot(),"config.json"))?JSON.parse(fs.readFileSync(path.resolve(findProjectRoot(),"config.json"),"utf-8")):{},DEFAULT_BASE_URL=CONFIG.defaultBaseUrl||"https://www.aliwork.com",PROJECT_ROOT=findProjectRoot(),COOKIE_FILE=path.join(PROJECT_ROOT,".cache","cookies.json"),OPTION_FIELD_TYPES=["RadioField","SelectField","CheckboxField","MultiSelectField"];function buildApiPath(e,o,r={}){var{prefix:r="",namespace:n="dingtalk",addTimestamp:t=!1}=r;return`/${n}/web/${e}${r?"/"+r:""}/query/formdesign/${o}.json`+(t?"?_stamp="+Date.now():"")}function parseArgs(){var e=process.argv.slice(2),o=e[0];return"create"===o?(e.length<4&&(console.error("用法: node create-form-page.js create <appType> <formTitle> <fieldsJsonFile>"),console.error('示例:node .claude/skills/yida-create-form-page/scripts/create-form-page.js create "APP_XXX" "员工信息登记" fields.json'),process.exit(1)),{mode:"create",appType:e[1],formTitle:e[2],fieldsJsonOrFile:e[3]}):"update"===o?(e.length<4&&(console.error("用法: node create-form-page.js update <appType> <formUuid> <changesJsonOrFile>"),console.error('示例:node .claude/skills/yida-create-form-page/scripts/create-form-page.js update "APP_XXX" "FORM-YYY" \'[{"action":"add","field":{"type":"TextField","label":"备注"}}]\''),process.exit(1)),{mode:"update",appType:e[1],formUuid:e[2],changesJsonOrFile:e[3]}):3<=e.length&&"create"!==o&&"update"!==o?{mode:"create",appType:e[0],formTitle:e[1],fieldsJsonOrFile:e[2]}:(console.error("用法:"),console.error(" 创建: node create-form-page.js create <appType> <formTitle> <fieldsJsonFile>"),console.error(" 更新: node create-form-page.js update <appType> <formUuid> <changesJsonOrFile>"),console.error("\n示例:"),console.error(' node .claude/skills/yida-create-form-page/scripts/create-form-page.js create "APP_XXX" "员工信息登记" fields.json'),console.error(' node .claude/skills/yida-create-form-page/scripts/create-form-page.js update "APP_XXX" "FORM-YYY" \'[{"action":"add","field":{"type":"TextField","label":"备注"}}]\''),void process.exit(1))}function extractInfoFromCookies(e){let o=null,r=null;for(var n of e){var t;"tianshu_csrf_token"===n.name?o=n.value:"tianshu_corp_user"===n.name&&0<(t=n.value.lastIndexOf("_"))&&(r=n.value.slice(0,t))}return{csrfToken:o,corpId:r}}function readFieldsDefinition(r){r=r.trimStart().startsWith("[")||r.trimStart().startsWith("{")?r:(r=path.resolve(r),fs.existsSync(r)||(console.error(" ❌ 字段定义文件不存在: "+r),process.exit(1)),fs.readFileSync(r,"utf-8"));try{var n=JSON.parse(r);let e,o=1;if(Array.isArray(n))e=n;else{if("object"!=typeof n||null===n)throw new Error("字段定义格式不正确");e=n.fields||[],o=void 0!==n.columns?n.columns:1}if(Array.isArray(e)&&0!==e.length)return{fields:e,columns:o};throw new Error("字段定义必须是非空数组")}catch(e){console.error(" ❌ 解析字段定义失败: "+e.message),process.exit(1)}}function readChangesDefinition(e){e=e.trimStart().startsWith("[")?e:(e=path.resolve(e),fs.existsSync(e)||(console.error(" ❌ 修改定义文件不存在: "+e),process.exit(1)),fs.readFileSync(e,"utf-8"));try{var o=JSON.parse(e);if(Array.isArray(o)&&0!==o.length)return o;throw new Error("修改定义必须是非空数组")}catch(e){console.error(" ❌ 解析修改定义失败: "+e.message),process.exit(1)}}let nodeIdCounter=1;function nextNodeId(){return"node_oc"+Date.now().toString(36)+(nodeIdCounter++).toString(36)}function generateFieldId(e){return e.charAt(0).toLowerCase()+e.slice(1)+"_"+(Date.now().toString(36).slice(-4)+Math.random().toString(36).substring(2,6))}function i18n(e,o){return{type:"i18n",zh_CN:e,en_US:o||e}}let PLACEHOLDER_INPUT=i18n("请输入","Please enter"),PLACEHOLDER_SELECT=i18n("请选择","please select");function buildOptionDataSource(e){return e.map(function(e,o){return{text:{zh_CN:e,en_US:e,type:"i18n"},value:e,sid:"serial_"+Date.now().toString(36)+o,disable:!1,defaultChecked:!1}})}function buildFieldComponent(e){var o,r=e.type,n=generateFieldId(r),t=nextNodeId(),i=[],i=(e.required&&i.push({type:"required"}),{__useMediator:"value",fieldId:n,label:i18n(e.label,r),__category__:"form",behavior:"NORMAL",visibility:["PC","MOBILE"],dataEntryMode:!1,submittable:"DEFAULT",submittable:"ALWAYS",validation:i,labelAlign:"top",labelTextAlign:"left",labelColSpan:4,size:"medium"}),a=("TextField"!==r&&"TextareaField"!==r||(i.hasClear=!0,i.placeholder=e.placeholder?i18n(e.placeholder):PLACEHOLDER_INPUT,i.valueType="custom",i.validationType="text",i.value=i18n("",""),i.hasLimitHint=!1,i.maxLength=200,i.rows=4,i.linkage="",i.__gridSpan=1,i.tips=i18n("",""),i.autoHeight=!1,i.scanCode={enabled:!1,type:"all",editable:!0},i.complexValue={complexType:"custom",formula:"",value:{en_US:"",zh_CN:"",type:"i18n"}},i.variable="",i.formula="",i.isCustomStore=!0,"TextareaField"===r&&(i.htmlType="textarea",i.showEmptyRows=!1)),"NumberField"===r&&(i.hasClear=!0,i.placeholder=e.placeholder?i18n(e.placeholder):i18n("请输入数字","Please enter a number"),i.valueType="custom",i.__gridSpan=1,i.tips=i18n("",""),i.linkage="",i.precision=0,i.step=1,i.thousandsSeparators=!1,i.innerAfter=e.innerAfter||"",i.value="",i.labelColOffset=0,i.wrapperColSpan=0,i.wrapperColOffset=0,i.complexValue={complexType:"custom",formula:"",value:""},i.variable="",i.formula="",i.isCustomStore=!0),"RateField"===r&&(i.count=5,i.allowHalf=!1,i.showGrade=!1,i.__gridSpan=1,i.tips=i18n("","")),"DateField"===r&&(i.placeholder=e.placeholder?i18n(e.placeholder):PLACEHOLDER_SELECT,i.__gridSpan=1,i.tips=i18n("",""),i.linkage="",i.format=e.format||"YYYY-MM-DD",i.hasClear=!0,i.disabledDate={type:"none"},i.valueType="custom",i.value="",i.formula="",i.variable="",i.resetTime=!1,i.complexValue={complexType:"custom",value:"",formula:""}),"CascadeDateField"===r&&(i.__gridSpan=1,i.tips=i18n("",""),i.format=e.format||"YYYY-MM-DD",i.hasClear=!0,i.resetTime=!1,i.disabledDate=!1),-1!==OPTION_FIELD_TYPES.indexOf(r)&&(a=buildOptionDataSource(e.options||["选项一","选项二","选项三"]),i.dataSource=a,i.dataSourceType="custom",i.defaultDataSource={customStashOptions:[],complexType:"custom",options:a,formula:{data:[],event:{"onPageReady,onChange":[]}},url:"",searchConfig:{afterFetch:"",type:"JSONP",beforeFetch:"",url:""}},i.__gridSpan=1,i.tips=i18n("",""),i.linkage="","RadioField"!==r&&"CheckboxField"!==r||(i.value="",i.valueType="custom",i.complexValue={complexType:"custom",formula:"",value:""},i.variable="",i.formula=""),"SelectField"!==r&&"MultiSelectField"!==r||(i.hasClear=!0,i.showSearch=!0,i.autoWidth=!0,i.placeholder=e.placeholder?i18n(e.placeholder):PLACEHOLDER_SELECT,i.value="",i.valueType="custom",i.reusePrivilege=!1,i.isUseDataSourceColor=!1,i.dataSourceLinkage="",i.filterLocal=!0,i.notFoundContent=i18n("无数据","Not Found"),i.searchConfig={dataType:"jsonp",url:"",beforeFetch:"function willFetch(params) {\n return params;\n}",afterFetch:"function didFetch(content) {\n return content;\n}"},i.complexValue={complexType:"custom",formula:"",value:""},i.variable="",i.formula=""),"SelectField"===r?i.mode="single":"MultiSelectField"===r&&(i.mode="multiple")),"EmployeeField"===r&&(i.placeholder=PLACEHOLDER_SELECT,i.__gridSpan=1,i.tips=i18n("",""),i.multiple=e.multiple||!1,i.hasClear=!0,i.userRangeType="ALL",i.roleRange=[],i.userRange=[],i.showEmpIdType="NAME",i.startWithDepartmentId="SELF",i.renderLinkForView=!0,i.showEmplId=!1,i.closeOnSelect=!1,i.useAliworkUrl=!1,i.linkage="",i.valueType="variable",i.complexValue={complexType:"formula",formula:"USER()",value:[]},i.variable={type:"user"},i.formula="",i.value=[]),"DepartmentSelectField"===r&&(i.placeholder=i18n("请输入关键字进行搜索","Please enter keyword"),i.__gridSpan=1,i.tips=i18n("",""),i.multiple=e.multiple||!1,i.valueType="custom",i.value=[],i.deptRangeType="ALL",i.deptRange=[],i.mode="single",i.hasClear=!0,i.dataSource={searchConfig:{dataType:"json",url:"/query/deptService/searchDepts.json",beforeFetch:'function willFetch(data) {\n data.key = data.key || data.q || "";\n return data;\n}',afterFetch:"function didFetch(content) {\n var data = [];\n if (content && content.values) {\n content.values.forEach(function (item) {\n data.push({ value: item.emplId, text: item.name, deptFullPath: item.deptFullPath });\n });\n }\n return data;\n}"}},i.complexValue={complexType:"custom",value:[],formula:""},i.variable="",i.formula="",i.linkage="",i.isShowDeptFullName=!1,i.hasSelectAll=!1),"CountrySelectField"===r&&(i.placeholder=PLACEHOLDER_SELECT,i.__gridSpan=1,i.tips=i18n("",""),i.multiple=e.multiple||!1,i.value=[],i.mode="single",i.hasClear=!0,i.showSearch=!0,i.hasSelectAll=!1),"AddressField"===r&&(i.__gridSpan=1,i.tips=i18n("",""),i.placeholder=e.placeholder?i18n(e.placeholder):PLACEHOLDER_SELECT,i.countryMode="default",i.countryScope=1,i.addressType="ADDRESS",i.subLabel=i18n("详细地址","Detailed Address"),i.detailPlaceholder=i18n("请输入详细地址","Please input detailed address"),i.hasClear=!0,i.enableLocation=!0,i.value={},i.optionAutoWidth=!0,i.showCountry=!1),"AttachmentField"===r&&(i.__gridSpan=1,i.tips=i18n("",""),i.valueType="custom",i.value="",i.complexValue={complexType:"custom",value:"",formula:""},i.type="normal",i.listType="text",i.buttonText=i18n("上传文件","Upload"),i.buttonSize="medium",i.buttonType="normal",i.multiple=!0,i.method="post",i.limit=9,i.maxFileSize=100,i.autoUpload=!0,i.accept="",i.formula="",i.linkage="",i.variable="",i.onlineEdit=!1,i.withCredentials=!1),"ImageField"===r&&(i.__gridSpan=1,i.tips=i18n("",""),i.valueType="custom",i.value="",i.complexValue={complexType:"custom",value:"",formula:""},i.aiRecognitionConfig={},i.type="normal",i.normalListType="image",i.cardListType="card",i.listType="image",i.buttonText=i18n("图片上传","Upload"),i.buttonSize="medium",i.buttonType="normal",i.enableCameraDate=!0,i.enableCameraLocation=!0,i.saveCameraImageToLocal=!0,i.multiple=!0,i.method="post",i.limit=9,i.maxFileSize=50,i.autoUpload=!0,i.accept="image/*",i.formula="",i.linkage="",i.variable="",i.aiRecognitionSwitch=!1,i.onlyCameraUpload=!1,i.enableCameraWatermark=!1,i.enableCameraCompression=!1),"TableField"===r&&(i.__gridSpan=1,i.linkage="",i.tips=i18n("",""),i.showIndex=!0,i.copyButtonText=i18n("复制","Copy"),i.addButtonBehavior="NORMAL",i.pageSize=20,i.addButtonText=i18n("新增一项","Add item"),i.enableExport=!0,i.addButtonPosition="bottom",i.actionsColumnWidth=70,i.theme="split",i.delButtonText=i18n("删除","Remove"),i.useCustomColumnsWidth=!1,i.showSortable=!1,i.moveUp=i18n("上移","Up"),i.maxItems=500,i.tableLayout="fixed",i.showActions=!0,i.indexName=i18n("项目","Line"),i.showCopyAction=!1,i.showDelAction=!0,i.showTableHead=!0,i.moveDown=i18n("下移","Down"),i.pcFreezeColumnStartCounts="0",i.layout="TABLE",i.showDeleteConfirm=!0,i.minItems=1,i.enableImport=!0,i.defaultCollapseStatus=!0,i.isFreezeOperateColumn=!0,i.actions=[],i.complexValue={complexType:"custom",formula:""},i.valueType="custom",i.__designerDevice="pc",i.mobileLayout="TILED",i.mobileFreezeColumnStartCounts="0",i.enableBatchDelete=!1,i.filterEmptyRowData=!1,i.enableSummary=!1),"AssociationFormField"===r&&(a=e.associationForm||{},i.__gridSpan=1,i.tips=i18n("",""),i.placeholder=PLACEHOLDER_SELECT,i.notFoundContent=i18n("无数据","Not Found"),i.hasClear=!0,i.multiple=e.multiple||!1,i.dataEntryMode=!1,i.submittable="ALWAYS",i.isCustomStore=!0,i.isShowSearchBar=!0,i.validateFilter=!1,i.__useMediator="value",i.associationForm={formType:"receipt",formUuid:a.formUuid||"",appType:a.appType||"",appName:a.appName||"",formTitle:a.formTitle||"",mainFieldId:a.mainFieldId||"",mainFieldLabel:a.mainFieldLabel?i18n(a.mainFieldLabel):i18n("",""),mainComponentName:a.mainComponentName||"TextField",tableShowType:a.tableShowType||"all",customTableFields:a.customTableFields||[],subFieldId:a.subFieldId||"",subComponentName:a.subComponentName||"",linkageFields:a.linkageFields||[]},o=a.dataFilterRules&&a.dataFilterRules.rules&&0<a.dataFilterRules.rules.length,i.dataFilterRules=o?a.dataFilterRules:{condition:"AND",rules:[],ruleId:"group-"+Date.now().toString(36),instanceFieldId:"",version:"v2"},i.supportDataFilter=o,o=a.dataFillingRules&&(a.dataFillingRules.mainRules&&0<a.dataFillingRules.mainRules.length||a.dataFillingRules.tableRules&&0<a.dataFillingRules.tableRules.length),i.dataFillingRules=o?normalizeFillingRules(a.dataFillingRules):{mainRules:[],tableRules:[],version:"v2"},i.supportDataFilling=o,i.orderEnable=!!(a.orderConfig&&0<a.orderConfig.length),i.orderConfig=a.orderConfig||[]),"SerialNumberField"===r&&(i.__gridSpan=1,i.tips=i18n("",""),i.dataEntryMode=!1,i.submittable="DEFAULT",o=[{__hide_delete__:!(i.validation=[]),ruleType:"character",content:"serial",formField:"",dateFormat:"yyyyMMdd",timeZone:"+8",digitCount:4,isFixed:!0,isFixedTips:"",resetPeriod:"noClean",resetPeriodTips:"",initialValue:1,__sid:"item_"+Date.now().toString(36)+"1",__sid__:"serial_"+Date.now().toString(36)+"1"},{__hide_delete__:!0,ruleType:"autoCount",content:"",formField:"",dateFormat:"yyyyMMdd",timeZone:"+8",digitCount:5,isFixed:!0,isFixedTips:"",resetPeriod:"noClean",resetPeriodTips:"",initialValue:1,__sid:"item_"+Date.now().toString(36)+"2",__sid__:"serial_"+Date.now().toString(36)+"2"}],i.serialNumberRule=e.serialNumberRule||o,i.serialNumPreview="serial00001",i.serialNumReset=1,i.syncSerialConfig=!1,i.formula={}),void 0!==e.behavior&&(i.behavior=e.behavior),void 0!==e.visibility&&(i.visibility=e.visibility),void 0!==e.labelAlign&&(i.labelAlign=e.labelAlign),void 0!==e.placeholder&&(i.placeholder=i18n(e.placeholder)),{componentName:r,id:t,fieldId:n,props:i,condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:""});return"TableField"===r&&e.children&&(a.children=e.children.map(function(e){return buildFieldComponent(e)})),a}function collectComponentNames(e){let o=new Set(["Page","RootHeader","RootContent","RootFooter","FooterYida","FormContainer"]);return e.forEach(function(e){o.add(e.type),"TableField"===e.type&&e.children&&e.children.forEach(function(e){o.add(e.type)})}),Array.from(o)}function buildComponentsMap(e){return e.map(function(e){return{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:e}})}function inferComponentNameFromFieldId(e){var o;return!e||"string"!=typeof e||-1===(o=e.lastIndexOf("_"))?"":(e=e.slice(0,o)).charAt(0).toUpperCase()+e.slice(1)}function normalizeFillingRule(e){var o=e.sourceFieldId||e.source||"",r=e.targetFieldId||e.target||"";return{sourceFieldId:o,targetFieldId:r,source:o,sourceType:e.sourceType||inferComponentNameFromFieldId(o),target:r,targetType:e.targetType||inferComponentNameFromFieldId(r)}}function normalizeFillingRules(e){var o;return e&&(o=Object.assign({},e),Array.isArray(o.mainRules)&&(o.mainRules=o.mainRules.map(normalizeFillingRule)),Array.isArray(o.tableRules)&&(o.tableRules=o.tableRules.map(function(e){e=Object.assign({},e);return Array.isArray(e.rules)&&(e.rules=e.rules.map(normalizeFillingRule)),e})),o)}function resolveFieldIdReferences(e){var t={};e.forEach(function(e){var o=extractLabelText(e);o&&e.props&&e.props.fieldId&&(t[o]=e.props.fieldId)}),e.forEach(function(e){var o,r,n;"AssociationFormField"===e.componentName&&(n=e.props.dataFillingRules)&&(n.mainRules&&(o=n.mainRules,Array.isArray(o))&&o.forEach(function(e){var o,r;e.target&&"string"==typeof e.target&&e.target.startsWith("@label:")&&(r=e.target.slice(7),(o=t[r])?(console.error(" 🔗 回填规则解析: @label:"+r+" → "+o),e.target=o):console.error(" ⚠️ 回填规则解析失败: 找不到标签为「"+r+"」的字段,请检查字段名是否正确")),e.source&&"string"==typeof e.source&&e.source.startsWith("@label:")&&(o=e.source.slice(7),(r=t[o])?(console.error(" 🔗 回填规则解析: @label:"+o+" → "+r),e.source=r):console.error(" ⚠️ 回填规则解析失败: 找不到标签为「"+o+"」的字段,请检查字段名是否正确"))}),n.tableRules&&(o=n.tableRules,Array.isArray(o))&&o.forEach(function(e,o){e.rules&&Array.isArray(e.rules)&&(console.error(" 📋 处理子表回填规则 ["+(o+1)+"]: tableId="+e.tableId),e.rules.forEach(function(e,o){var r,n;e.target&&"string"==typeof e.target&&e.target.startsWith("@label:")&&(r=e.target.slice(7),(n=t[r])?(console.error(" 🔗 子表规则解析 ["+(o+1)+"]: @label:"+r+" → "+n),e.target=n):console.error(" ⚠️ 子表规则解析失败: 找不到标签为「"+r+"」的字段,请检查字段名是否正确"))}))}),e.props.dataFillingRules=normalizeFillingRules(n),r=n.mainRules&&0<n.mainRules.length,n=n.tableRules&&n.tableRules.some(function(e){return e.rules&&0<e.rules.length}),e.props.supportDataFilling=r||n)})}function buildFormSchema(e,o,n,t,i,r){r=r||1;var a=o.map(function(e){return buildFieldComponent(e)}),o=(a.forEach(function(e){var o,r;"SerialNumberField"===e.componentName&&e.props&&(o=e.props.fieldId,r=e.props.serialNumberRule,r=JSON.stringify({type:"custom",value:r}).replace(/\\/g,"\\\\").replace(/"/g,'\\"'),e.props.formula={expression:'SERIALNUMBER("'+t+'", "'+i+'", "'+n+'", "'+o+'", "'+r+'")'})}),resolveFieldIdReferences(a),collectComponentNames(o)),l="function constructor() {\nvar module = { exports: {} };\nvar _this = this;\nthis.__initMethods__(module.exports, module);\nObject.keys(module.exports).forEach(function(item) {\n if(typeof module.exports[item] === 'function'){\n _this[item] = module.exports[item];\n }\n});\n\n}",l=[{componentName:"Page",id:nextNodeId(),props:{contentBgColor:"white",pageStyle:{backgroundColor:"#f2f3f5"},contentMargin:"20",contentPadding:"20",showTitle:!1,contentPaddingMobile:"0",templateVersion:"1.0.0",contentMarginMobile:"0",className:"page_"+Date.now().toString(36),contentBgColorMobile:"white",titleName:i18n("标题名称","title"),titleDesc:i18n("标题描述","title"),titleColor:"light",titleBg:"https://img.alicdn.com/imgextra/i2/O1CN0143ATPP1wIa9TrVvzN_!!6000000006285-2-tps-3360-400.png_.webp",backgroundColorCustom:"#f1f2f3",sizePc:"medium",labelAlignPc:"top",labelWidthPc:"130px",labelWeightPc:"normal",labelAlignMobile:"top",labelWidthMobile:"80px",labelWeightMobile:"normal"},condition:!0,css:"body{background-color:#f2f3f5}",methods:{__initMethods__:{type:"js",source:"function (exports, module) { /*set actions code here*/ }",compiled:"function (exports, module) { /*set actions code here*/ }"}},dataSource:{offline:[],globalConfig:{fit:{compiled:"'use strict';\n\nvar __preParser__ = function fit(response) {\n var content = response.content !== undefined ? response.content : response;\n var error = {\n message: response.errorMsg || response.errors && response.errors[0] && response.errors[0].msg || response.content || '远程数据源请求出错,success is false'\n };\n var success = true;\n if (response.success !== undefined) {\n success = response.success;\n } else if (response.hasError !== undefined) {\n success = !response.hasError;\n }\n return {\n content: content,\n success: success,\n error: error\n };\n};",source:"function fit(response) {\r\n const content = (response.content !== undefined) ? response.content : response;\r\n const error = {\r\n message: response.errorMsg ||\r\n (response.errors && response.errors[0] && response.errors[0].msg) ||\r\n response.content || '远程数据源请求出错,success is false',\r\n };\r\n let success = true;\r\n if (response.success !== undefined) {\r\n success = response.success;\r\n } else if (response.hasError !== undefined) {\r\n success = !response.hasError;\r\n }\r\n return {\r\n content,\r\n success,\r\n error,\r\n };\r\n}",type:"js",error:{}}},online:[],list:[],sync:!0},lifeCycles:{constructor:{type:"js",compiled:l,source:l}},hidden:!1,title:"",isLocked:!1,conditionGroup:"",children:[{componentName:"RootHeader",id:nextNodeId(),props:{},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:""},{componentName:"RootContent",id:nextNodeId(),props:{},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:"",children:[{componentName:"FormContainer",id:nextNodeId(),props:{formLabel:i18n(e,e),formLabelVisible:!0,columns:r,labelAlign:"top",submitText:i18n("提交","Submit"),stageText:i18n("暂存","Stage"),submitAndNewText:i18n("提交并继续","Submit and New"),fieldId:"formContainer_"+Date.now().toString(36),aiFormConfig:{systemPrompt:"",model:"qwen"},beforeSubmit:!1,afterSubmit:!1,onProcessActionValidate:!1,afterFormDataInit:!1},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:"",children:a}]},{componentName:"RootFooter",id:nextNodeId(),props:{},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:"",children:[{componentName:"FooterYida",id:nextNodeId(),props:{},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:""}]}]}];return{schemaType:"superform",schemaVersion:"5.0",pages:[{utils:[{name:"legaoBuiltin",type:"npm",content:{package:"@ali/vu-legao-builtin",version:"3.0.0",exportName:"legaoBuiltin"}},{name:"yidaPlugin",type:"npm",content:{package:"@ali/vu-yida-plugin",version:"1.1.0",exportName:"yidaPlugin"}}],componentsMap:buildComponentsMap(o),componentsTree:l,componentAlias:{items:[]},id:n,connectComponent:[]}],actions:{module:{compiled:'"use strict";\n\nexports.__esModule = true;\nexports.didMount = didMount;\nfunction didMount() {\n console.log("\\u300C\\u9875\\u9762 JS\\u300D\\uFF1A\\u5F53\\u524D\\u9875\\u9762\\u5730\\u5740 " + location.href);\n}\n',source:"export function didMount() {\n console.log(`「页面 JS」:当前页面地址 ${location.href}`);\n}"},type:"FUNCTION",list:[{id:"didMount",title:"didMount"}]},config:{connectComponent:[]}}}function sendGetRequest(l,s,c,d){return new Promise((n,o)=>{var e=querystring.stringify(d),e=c+"?"+e,r=s.map(e=>e.name+"="+e.value).join("; "),t=new URL(l),i="https:"===t.protocol;let a=(i?https:http).request({hostname:t.hostname,port:t.port||(i?443:80),path:e,method:"GET",headers:{Origin:l,Referer:l+"/",Cookie:r},timeout:3e4},o=>{let r="";o.on("data",e=>{r+=e}),o.on("end",()=>{console.error(" HTTP 状态码: "+o.statusCode);let e;try{e=JSON.parse(r)}catch(e){return console.error(" 响应内容: "+r.substring(0,500)),void n({success:!1,errorMsg:"HTTP "+o.statusCode+": 响应非 JSON"})}isLoginExpired(e)?(console.error(" 检测到登录过期: "+e.errorMsg),n({__needLogin:!0})):isCsrfTokenExpired(e)?(console.error(" 检测到 csrf_token 过期: "+e.errorMsg),n({__csrfExpired:!0})):n(e)})});a.on("timeout",()=>{console.error(" ❌ 请求超时"),a.destroy(),o(new Error("请求超时"))}),a.on("error",e=>{o(e)}),a.end()})}function buildEmptyFormSchema(){var e="function constructor() {\nvar module = { exports: {} };\nvar _this = this;\nthis.__initMethods__(module.exports, module);\nObject.keys(module.exports).forEach(function(item) {\n if(typeof module.exports[item] === 'function'){\n _this[item] = module.exports[item];\n }\n});\n\n}";return{schemaType:"superform",schemaVersion:"5.0",actions:{module:{compiled:'"use strict";\n\nexports.__esModule = true;\nexports.didMount = didMount;\nfunction didMount() {\n console.log("\\u300C\\u9875\\u9762 JS\\u300D\\uFF1A\\u5F53\\u524D\\u9875\\u9762\\u5730\\u5740 " + location.href);\n}\n',source:"export function didMount() {\n console.log(`「页面 JS」:当前页面地址 ${location.href}`);\n}"},type:"FUNCTION",list:[{id:nextNodeId(),type:"lifeCycleEvent",name:"didMount",relatedEventId:"lifecycle:didMount",params:{}}]},pages:[{utils:[{name:"legaoBuiltin",type:"npm",content:{package:"@ali/vu-legao-builtin",version:"3.0.0",exportName:"legaoBuiltin"}},{name:"yidaPlugin",type:"npm",content:{package:"@ali/vu-yida-plugin",version:"1.1.0",exportName:"yidaPlugin"}}],componentsTree:[{componentName:"Page",id:nextNodeId(),props:{contentBgColor:"white",pageStyle:{backgroundColor:"#f2f3f5"},contentMargin:"20",contentPadding:"20",showTitle:!1,contentPaddingMobile:"0",templateVersion:"1.0.0",contentMarginMobile:"0",className:"page_"+Date.now().toString(36),contentBgColorMobile:"white"},condition:!0,css:"body{background-color:#f2f3f5}",methods:{__initMethods__:{type:"js",source:"function (exports, module) { /*set actions code here*/ }",compiled:"function (exports, module) { /*set actions code here*/ }"}},dataSource:{offline:[],globalConfig:{},online:[],list:[],sync:!0},lifeCycles:{constructor:{type:"js",compiled:e,source:e},componentDidMount:{name:"didMount",id:"didMount",params:{},type:"actionRef"}},hidden:!1,title:"",isLocked:!1,conditionGroup:"",children:[{componentName:"RootHeader",id:nextNodeId(),props:{},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:""},{componentName:"RootContent",id:nextNodeId(),props:{},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:"",children:[{componentName:"FormContainer",id:nextNodeId(),props:{beforeSubmit:!1,"submitProps.text":i18n("提交","Submit"),submitText:i18n("提交","Submit"),submitProps:{text:i18n("提交","Submit")},labelAlign:"top",columns:1,afterSubmit:!1,fieldId:"formContainer_"+Date.now().toString(36),stageText:i18n("暂存","Stage"),submitAndNewText:i18n("提交并继续","Submit and New"),onProcessActionValidate:!1,afterFormDataInit:!1},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:"",children:[]}]},{componentName:"RootFooter",id:nextNodeId(),props:{},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:"",children:[{componentName:"FooterYida",id:nextNodeId(),props:{},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:""}]}]}],componentsMap:[{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:"RootHeader"},{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:"FormContainer"},{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:"RootContent"},{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:"FooterYida"},{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:"RootFooter"},{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:"Page"}]}]}}function extractLabelText(e){return e&&e.props&&e.props.label?"string"==typeof(e=e.props.label)?e:e.zh_CN||"":""}function findFormContainer(e){if("FormContainer"===e.componentName)return e;if(e.children&&Array.isArray(e.children))for(var o=0;o<e.children.length;o++){var r=findFormContainer(e.children[o]);if(r)return r}return null}function findFieldIndexByLabel(e,o){for(var r=0;r<e.length;r++)if(extractLabelText(e[r])===o)return r;return-1}function applyFieldChanges(e,o){var r,n=e.props,t=["label","required","placeholder","options","associationForm","linkageFields","mainFieldId","mainComponentName","mainFieldLabel","subFieldId","subComponentName","dataFillingRules"];void 0!==o.label&&(n.label=i18n(o.label,e.componentName)),void 0!==o.required&&(o.required?(n.validation||[]).some(function(e){return"required"===e.type})||(n.validation=n.validation||[],n.validation.push({type:"required"})):n.validation=(n.validation||[]).filter(function(e){return"required"!==e.type})),void 0!==o.placeholder&&(n.placeholder=i18n(o.placeholder)),void 0!==o.dataSource&&-1!==OPTION_FIELD_TYPES.indexOf(e.componentName)&&(r=o.dataSource,n.dataSource=r,n.defaultDataSource)&&(n.defaultDataSource.options=r),"AssociationFormField"===e.componentName&&(n.associationForm||(n.associationForm={}),void 0!==o.linkageFields&&(n.associationForm.linkageFields=o.linkageFields),void 0!==o.mainFieldId&&(n.associationForm.mainFieldId=o.mainFieldId),void 0!==o.mainComponentName&&(n.associationForm.mainComponentName=o.mainComponentName),void 0!==o.mainFieldLabel&&(n.associationForm.mainFieldLabel=i18n(o.mainFieldLabel)),void 0!==o.subFieldId&&(n.associationForm.subFieldId=o.subFieldId),void 0!==o.subComponentName&&(n.associationForm.subComponentName=o.subComponentName),void 0!==o.dataFillingRules)&&(n.dataFillingRules=normalizeFillingRules(o.dataFillingRules),r=o.dataFillingRules.mainRules&&0<o.dataFillingRules.mainRules.length,e=o.dataFillingRules.tableRules&&o.dataFillingRules.tableRules.some(function(e){return e.rules&&0<e.rules.length}),n.supportDataFilling=r||e),Object.keys(o).forEach(function(e){-1===t.indexOf(e)&&void 0!==o[e]&&(n[e]=o[e])})}function ensureComponentsMap(e,o){e=e.pages[0];-1===e.componentsMap.map(function(e){return e.componentName}).indexOf(o)&&e.componentsMap.push({package:"@ali/vc-deep-yida",version:"1.5.169",componentName:o})}function applyChangesToSchema(i,e){var o=i.pages[0].componentsTree,o=(o&&0!==o.length||(console.error(" ❌ Schema 中未找到 componentsTree"),process.exit(1)),findFormContainer(o[0])),a=(o||(console.error(" ❌ Schema 中未找到 FormContainer"),process.exit(1)),o.children||[]),l=[];return e.forEach(function(e,o){o="操作 "+(o+1)+": "+e.action;if("add"===e.action)e.field&&e.field.type&&e.field.label?(r=buildFieldComponent(e.field),ensureComponentsMap(i,e.field.type),"TableField"===e.field.type&&e.field.children&&e.field.children.forEach(function(e){ensureComponentsMap(i,e.type)}),e.after?-1!==(n=findFieldIndexByLabel(a,e.after))?(a.splice(n+1,0,r),console.error(" ✅ "+o+" - 在「"+e.after+"」后新增字段「"+e.field.label+"」("+e.field.type+")")):(a.push(r),console.error(" ⚠️ "+o+" - 未找到「"+e.after+"」,字段「"+e.field.label+"」追加到末尾")):e.before?-1!==(n=findFieldIndexByLabel(a,e.before))?(a.splice(n,0,r),console.error(" ✅ "+o+" - 在「"+e.before+"」前新增字段「"+e.field.label+"」("+e.field.type+")")):(a.push(r),console.error(" ⚠️ "+o+" - 未找到「"+e.before+"」,字段「"+e.field.label+"」追加到末尾")):(a.push(r),console.error(" ✅ "+o+" - 新增字段「"+e.field.label+"」("+e.field.type+")")),l.push({action:"add",label:e.field.label,type:e.field.type})):console.error(" ⚠️ "+o+" - 缺少 field.type 或 field.label,跳过");else if("delete"===e.action)e.label?-1!==(n=findFieldIndexByLabel(a,e.label))?(a.splice(n,1),console.error(" ✅ "+o+" - 删除字段「"+e.label+"」"),l.push({action:"delete",label:e.label})):console.error(" ⚠️ "+o+" - 未找到字段「"+e.label+"」,跳过删除"):console.error(" ⚠️ "+o+" - 缺少 label,跳过");else if("update"===e.action)if(e.label)if(e.changes&&0!==Object.keys(e.changes).length){var r=a,n="";if(e.tableLabel){var t=findFieldIndexByLabel(a,e.tableLabel);if(-1===t)return void console.error(" ⚠️ "+o+" - 未找到子表「"+e.tableLabel+"」,跳过更新");t=a[t];if("TableField"!==t.componentName||!t.children)return void console.error(" ⚠️ "+o+" - 「"+e.tableLabel+"」不是有效的子表字段,跳过更新");r=t.children,n="子表「"+e.tableLabel+"」中的"}t=findFieldIndexByLabel(r,e.label);-1!==t?(applyFieldChanges(r[t],e.changes),r=Object.keys(e.changes).join(", "),console.error(" ✅ "+o+" - 更新"+n+"字段「"+e.label+"」的属性: "+r),l.push({action:"update",label:e.label,tableLabel:e.tableLabel||null,changedProps:r})):console.error(" ⚠️ "+o+" - 未找到"+n+"字段「"+e.label+"」,跳过更新")}else console.error(" ⚠️ "+o+" - 缺少 changes,跳过");else console.error(" ⚠️ "+o+" - 缺少 label,跳过");else console.error(" ⚠️ "+o+" - 未知操作类型「"+e.action+"」,跳过")}),function o(e){e.forEach(function(e){!e.fieldId&&e.props&&e.props.fieldId&&(e.fieldId=e.props.fieldId),e.children&&Array.isArray(e.children)&&o(e.children)})}(a),resolveFieldIdReferences(a),o.children=a,l}function sendPostRequest(c,d,p,u,m,f){return new Promise((n,o)=>{var e=querystring.stringify(Object.assign({_csrf_token:d},m)),r=p.map(e=>e.name+"="+e.value).join("; "),t=new URL(c),i="https:"===t.protocol,a=i?https:http,l=f?`${c}/alibaba/web/${m.appType||""}/design/pageDesigner?formUuid=`+f:c+"/",t={hostname:t.hostname,port:t.port||(i?443:80),path:u,method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded","Content-Length":Buffer.byteLength(e),Origin:c,Referer:l,Cookie:r},timeout:3e4};let s=a.request(t,o=>{let r="";o.on("data",e=>{r+=e}),o.on("end",()=>{console.error(" HTTP 状态码: "+o.statusCode);let e;try{e=JSON.parse(r)}catch(e){return console.error(" 响应内容: "+r.substring(0,500)),void n({success:!1,errorMsg:`HTTP ${o.statusCode}: 响应非 JSON`})}isLoginExpired(e)?(console.error(" 检测到登录过期: "+e.errorMsg),n({__needLogin:!0})):isCsrfTokenExpired(e)?(console.error(" 检测到 csrf_token 过期: "+e.errorMsg),n({__csrfExpired:!0})):n(e)})});s.on("timeout",()=>{console.error(" ❌ 请求超时"),s.destroy(),o(new Error("请求超时"))}),s.on("error",e=>{o(e)}),s.write(e),s.end()})}function sendUpdateConfigRequest(s,c,d,p,u,m,f){return new Promise((n,o)=>{var e=querystring.stringify({_csrf_token:c,formUuid:u,version:m,configType:"MINI_RESOURCE",value:f}),r=d.map(e=>e.name+"="+e.value).join("; "),t=new URL(s),i="https:"===t.protocol,a=i?https:http,t={hostname:t.hostname,port:t.port||(i?443:80),path:`/dingtalk/web/${p}/query/formdesign/updateFormConfig.json`,method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded","Content-Length":Buffer.byteLength(e),Origin:s,Referer:s+"/",Cookie:r},timeout:3e4};let l=a.request(t,o=>{let r="";o.on("data",e=>{r+=e}),o.on("end",()=>{console.error(" HTTP 状态码: "+o.statusCode);let e;try{e=JSON.parse(r)}catch(e){return console.error(" 响应内容: "+r.substring(0,500)),void n({success:!1,errorMsg:`HTTP ${o.statusCode}: 响应非 JSON`})}isLoginExpired(e)?(console.error(" 检测到登录过期: "+e.errorMsg),n({__needLogin:!0})):isCsrfTokenExpired(e)?(console.error(" 检测到 csrf_token 过期: "+e.errorMsg),n({__csrfExpired:!0})):n(e)})});l.on("timeout",()=>{console.error(" ❌ 请求超时"),l.destroy(),o(new Error("请求超时"))}),l.on("error",e=>{o(e)}),l.write(e),l.end()})}function resolveCorpId(e){if(e.corp_id)return e.corp_id;if(e.cookies){e=e.cookies.find(function(e){return"tianshu_corp_user"===e.name});if(e&&e.value){var o=e.value.lastIndexOf("_");if(0<o)return e.value.slice(0,o)}}return""}async function requestWithAutoLogin(e,o){var r,n=await e(o);return n&&n.__csrfExpired&&(r=refreshCsrfToken(),o.cookieData=r,o.csrfToken=r.csrf_token,o.cookies=r.cookies,o.baseUrl=resolveBaseUrl(r),console.error(" 🔄 csrf_token 已刷新,重试..."),n=await e(o)),n&&n.__needLogin&&(r=triggerLogin(),o.cookieData=r,o.csrfToken=r.csrf_token,o.cookies=r.cookies,o.baseUrl=resolveBaseUrl(r),console.error(" 🔄 重新登录后重试..."),n=await e(o)),n}async function saveSchemaAndUpdateConfig(e,o,r,n,t,i){var a,i=i||4,l=i+1,i=(console.error("\n📝 Step "+i+": 保存表单 Schema"),console.error(" 发送 saveFormSchema 请求..."),await requestWithAutoLogin(function(e){return sendPostRequest(e.baseUrl,e.csrfToken,e.cookies,buildApiPath(o,"saveFormSchema",{prefix:"_view"}),{appType:o,formUuid:r,content:JSON.stringify(n),schemaVersion:"V5",prefix:"_view"},r)},e));return i&&i.success||(a=i?i.errorMsg||"未知错误":"请求失败",console.error("\n❌ 保存 Schema 失败: "+a),i&&!i.__needLogin&&console.error(" 响应详情: "+JSON.stringify(i,null,2)),console.error("=".repeat(50)),console.log(JSON.stringify({success:!1,formUuid:r,error:a})),process.exit(1)),console.error(" ✅ Schema 保存成功!"),void 0!==t&&console.error(" 当前版本号: "+t),console.error("\n⚙️ Step "+l+": 更新表单配置"),console.error(" 发送 updateFormConfig 请求..."),{saveResult:i,configResult:await requestWithAutoLogin(function(e){return sendUpdateConfigRequest(e.baseUrl,e.csrfToken,e.cookies,o,r,t||1,0)},e)}}async function mainCreate(e,o,r,n,t){let{appType:i,formTitle:a,fieldsJsonOrFile:l}=e;console.error("=".repeat(50)),console.error(" yida-create-form-page - 宜搭表单页面创建工具"),console.error("=".repeat(50)),console.error("\n 应用 ID: "+i),console.error(" 表单名称: "+a),console.error(" 字段定义: "+l);var e={csrfToken:o,cookies:r,baseUrl:n,cookieData:t},{fields:o,columns:r}=(console.error("\n📋 Step 2: 读取字段定义"),readFieldsDefinition(l)),n=(console.error(" ✅ 已读取 "+o.length+" 个字段定义"),console.error(" PC端列数: "+r),o.forEach(function(e,o){console.error(" "+(o+1)+". "+e.type+": "+e.label)}),console.error("\n📄 Step 3: 创建空白表单"),console.error(" 发送 saveFormSchemaInfo 请求..."),await requestWithAutoLogin(function(e){return sendPostRequest(e.baseUrl,e.csrfToken,e.cookies,buildApiPath(i,"saveFormSchemaInfo"),{formType:"receipt",title:JSON.stringify(i18n(a))})},e)),t=(n&&n.success&&n.content||(t=n?n.errorMsg||"未知错误":"请求失败",console.error(" ❌ 创建空白表单失败: "+t),console.log(JSON.stringify({success:!1,error:t})),process.exit(1)),n.content.formUuid||n.content),n=(console.error(" ✅ 空白表单已创建: "+t),resolveCorpId(e.cookieData)),n=(n?console.error(" ✅ corpId: "+n):console.error(" ⚠️ 警告: 未能获取 corpId,SerialNumberField 的 formula 可能无法正常工作"),buildFormSchema(a,o,t,n,i,r)),r=(await saveSchemaAndUpdateConfig(e,i,t,n,1,4)).configResult,n=(console.error("\n"+"=".repeat(50)),e.baseUrl+"/"+i+"/workbench/"+t);r&&r.success?(console.error(" ✅ 表单创建成功!"),console.error(" formUuid: "+t),console.error(" 访问地址: "+n),console.error(" 配置已更新: MINI_RESOURCE = 0"),console.error("=".repeat(50)),console.log(JSON.stringify({success:!0,formUuid:t,formTitle:a,appType:i,fieldCount:o.length,url:n}))):(e=r?r.errorMsg||"未知错误":"请求失败",console.error(" ⚠️ 配置更新失败: "+e),console.error(" Schema 已保存,但配置更新失败"),console.error(" formUuid: "+t),console.error(" 访问地址: "+n),r&&!r.__needLogin&&console.error(" 响应详情: "+JSON.stringify(r,null,2)),console.error("=".repeat(50)),console.log(JSON.stringify({success:!0,formUuid:t,formTitle:a,appType:i,fieldCount:o.length,url:n,configWarning:e})))}function fillSerialNumberFormulas(e,n,t,i){Array.isArray(e)&&e.forEach(function(e){var o,r;"SerialNumberField"===e.componentName&&e.props&&!((o=e.props.formula)&&"object"==typeof o&&"string"==typeof o.expression&&0<o.expression.length)&&(o=e.props.fieldId,r=e.props.serialNumberRule)&&(r=JSON.stringify({type:"custom",value:r}).replace(/\\/g,"\\\\").replace(/"/g,'\\"'),e.props.formula={expression:'SERIALNUMBER("'+n+'", "'+t+'", "'+i+'", "'+o+'", "'+r+'")'},console.error(" 🔢 SerialNumberField 「"+(e.props.label&&e.props.label.zh_CN||o)+"」formula 已设置")),"TableField"===e.componentName&&Array.isArray(e.children)&&fillSerialNumberFormulas(e.children,n,t,i)})}async function mainUpdate(e,o,r,n,t){let{appType:i,formUuid:a,changesJsonOrFile:l}=e;console.error("=".repeat(50)),console.error(" yida-create-form-page - 宜搭表单页面更新工具"),console.error("=".repeat(50)),console.error("\n 应用 ID: "+i),console.error(" 表单 UUID: "+a),console.error(" 修改定义: "+l);var s,e={csrfToken:o,cookies:r,baseUrl:n,cookieData:t},o=(console.error("\n📄 Step 2: 获取当前表单 Schema"),console.error(" 发送 getFormSchema 请求..."),await requestWithAutoLogin(function(e){return sendGetRequest(e.baseUrl,e.cookies,buildApiPath(i,"getFormSchema",{prefix:"_view",namespace:"alibaba"}),{formUuid:a,schemaVersion:"V5"})},e)),n=(o&&!1!==o.success&&!o.__needLogin||(r=o?o.errorMsg||"未知错误":"请求失败",console.error(" ❌ 获取表单 Schema 失败: "+r),console.log(JSON.stringify({success:!1,error:r})),process.exit(1)),1),t=(o.content&&"object"==typeof o.content&&void 0!==o.content.version?n=o.content.version:void 0!==o.version&&(n=o.version),o.content?s="string"==typeof o.content?JSON.parse(o.content):o.content:o.pages?s=o:(console.error(" ❌ 无法从返回结果中提取 Schema"),console.error(" 响应结构: "+JSON.stringify(Object.keys(o))),console.log(JSON.stringify({success:!1,error:"无法解析 Schema 结构"})),process.exit(1)),s.pages&&Array.isArray(s.pages)&&0!==s.pages.length||(console.error(" ⚠️ Schema 为空,使用基础表单模板初始化"),s=buildEmptyFormSchema()),findFormContainer(s.pages[0].componentsTree[0])),r=(t&&t.children?(console.error(" ✅ Schema 获取成功,当前共 "+t.children.length+" 个字段:"),t.children.forEach(function(e,o){var r=extractLabelText(e);console.error(" "+(o+1)+". "+e.componentName+": "+r)})):console.error(" ✅ Schema 获取成功(表单暂无字段)"),console.error("\n📋 Step 3: 读取修改定义"),readChangesDefinition(l)),o=(console.error(" ✅ 已读取 "+r.length+" 条修改操作"),r.forEach(function(e,o){"add"===e.action?console.error(" "+(o+1)+". [新增] "+e.field.type+": "+e.field.label):"delete"===e.action?console.error(" "+(o+1)+". [删除] "+e.label):"update"===e.action&&console.error(" "+(o+1)+". [修改] "+e.label+" → "+Object.keys(e.changes||{}).join(", "))}),console.error("\n🔧 Step 4: 应用修改"),applyChangesToSchema(s,r)),t=resolveCorpId(e.cookieData),r=(t||console.error(" ⚠️ 警告: 未能获取 corpId,SerialNumberField 的 formula 可能无法正常工作"),findFormContainer(s.pages[0].componentsTree[0])),r=(r&&r.children&&fillSerialNumberFormulas(r.children,t,i,a),await saveSchemaAndUpdateConfig(e,i,a,s,n,5)).configResult,t=(console.error("\n"+"=".repeat(50)),e.baseUrl+"/"+i+"/workbench/"+a);r&&r.success?(console.error(" ✅ 表单更新成功!"),console.error(" formUuid: "+a),console.error(" 访问地址: "+t),console.error(" 应用修改: "+o.length+" 条"),console.error(" 配置已更新: MINI_RESOURCE = 0"),console.error("=".repeat(50)),console.log(JSON.stringify({success:!0,formUuid:a,appType:i,changesApplied:o.length,changes:o,url:t}))):(s=r?r.errorMsg||"未知错误":"请求失败",console.error(" ⚠️ 配置更新失败: "+s),console.error(" Schema 已保存,但配置更新失败"),console.error(" formUuid: "+a),console.error(" 访问地址: "+t),console.error(" 应用修改: "+o.length+" 条"),r&&!r.__needLogin&&console.error(" 响应详情: "+JSON.stringify(r,null,2)),console.error("=".repeat(50)),console.log(JSON.stringify({success:!0,formUuid:a,appType:i,changesApplied:o.length,changes:o,url:t,configWarning:s})))}async function main(){var e=parseArgs();console.error("\n🔑 Step 1: 读取登录态");let o=loadCookieData();o||(console.error(" ⚠️ 未找到本地登录态,触发登录..."),o=triggerLogin());var{csrf_token:r,cookies:n}=o,t=resolveBaseUrl(o);console.error(" ✅ 登录态已就绪("+t+")"),"update"===e.mode?await mainUpdate(e,r,n,t,o):await mainCreate(e,r,n,t,o)}main().catch(e=>{console.error("\n❌ 异常: "+e.message),process.exit(1)});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let querystring=require("querystring"),{loadCookieData,triggerLogin,resolveBaseUrl,httpPost,requestWithAutoLogin}=require("./utils");async function run(e){e.length<2&&(console.error('用法: yidacli create-page <appType> "<pageName>"'),console.error('示例: yidacli create-page "APP_XXX" "游戏主页"'),process.exit(1));let o=e[0],s=e[1],r=(console.error("=".repeat(50)),console.error(" yidacli create-page - 宜搭自定义页面创建工具"),console.error("=".repeat(50)),console.error(`
|
|
2
|
+
应用 ID: `+o),console.error(" 页面名称: "+s),console.error("\n🔑 Step 1: 读取登录态"),loadCookieData());r||(console.error(" ⚠️ 未找到本地登录态,触发登录..."),r=triggerLogin());var n,e={csrfToken:r.csrf_token,cookies:r.cookies,baseUrl:resolveBaseUrl(r),cookieData:r},t=(console.error(` ✅ 登录态已就绪(${e.baseUrl})`),console.error("\n📄 Step 2: 创建自定义页面\n"),console.error(" 发送 saveFormSchemaInfo 请求..."),await requestWithAutoLogin(e=>{var r=querystring.stringify({_csrf_token:e.csrfToken,formType:"display",title:JSON.stringify({zh_CN:s,en_US:s,type:"i18n"})});return httpPost(e.baseUrl,`/dingtalk/web/${o}/query/formdesign/saveFormSchemaInfo.json`,r,e.cookies)},e));console.error("\n"+"=".repeat(50)),t&&t.success&&t.content?(n=t.content.formUuid||t.content,e=`${e.baseUrl}/${o}/workbench/`+n,console.error(" ✅ 页面创建成功!"),console.error(" pageId: "+n),console.error(" 访问地址: "+e),console.error("=".repeat(50)),console.log(JSON.stringify({success:!0,pageId:n,pageName:s,appType:o,url:e}))):(n=t?t.errorMsg||"未知错误":"请求失败",console.error(" ❌ 创建失败: "+n),console.error("=".repeat(50)),console.log(JSON.stringify({success:!1,error:n})),process.exit(1))}module.exports={run:run};
|
package/dist/env.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
let fs=require("fs"),path=require("path"),os=require("os"),{loadCookieData,resolveBaseUrl,extractInfoFromCookies}=require("./utils"),home=os.homedir(),TOOL_DETECTORS=[{dirName:".real",displayName:"悟空(Wukong)",detect:o=>{o=path.join(o,".real");return fs.existsSync(path.join(o,"daemon.sock"))||fs.existsSync(path.join(o,".mcp"))||fs.existsSync(path.join(o,".skills"))}},{dirName:".opencode",displayName:"OpenCode",detect:o=>{o=path.join(o,".opencode");return fs.existsSync(path.join(o,"bun.lock"))}},{dirName:".claudecode",displayName:"Claude Code",detect:o=>{o=path.join(o,".claudecode");return fs.existsSync(path.join(o,"settings.json"))||!!process.env.CLAUDE_CODE||!!process.env.ANTHROPIC_API_KEY}},{dirName:".aone_copilot",displayName:"Aone Copilot",detect:o=>{o=path.join(o,".aone_copilot");return fs.existsSync(path.join(o,"hardware_id.txt"))}},{dirName:".cursor",displayName:"Cursor",detect:o=>{var o=path.join(o,".cursor"),o=fs.existsSync(path.join(o,"extensions"))&&fs.existsSync(path.join(o,"argv.json")),e=(process.env.VSCODE_GIT_ASKPASS_NODE||"").toLowerCase().includes("cursor");return o&&e}},{dirName:".qoder",displayName:"Qoder",detect:o=>{o=path.join(o,".qoder");return fs.existsSync(path.join(o,".config.json"))&&fs.existsSync(path.join(o,"agents"))}},{dirName:".iflow",displayName:"iFlow",detect:o=>{o=path.join(o,".iflow");return fs.existsSync(path.join(o,"aone_token.json"))||fs.existsSync(path.join(o,"installation_id"))}}];function detectEnvironment(){var n=[];let t=null,l=null;for(let{dirName:o,displayName:e,detect:s}of TOOL_DETECTORS){var r,c,a=path.join(home,o);fs.existsSync(a)&&(r=(()=>{try{return s(home)}catch{return!1}})(),a=path.join(a,"workspace","openyida"),c=fs.existsSync(a),n.push({displayName:e,dirName:o,isActive:r,hasProject:c,workspaceRoot:a}),r)&&c&&!t&&(t=e,l=a)}return{activeToolName:t,activeProjectRoot:l,results:n}}function detectLoginStatus(o){var e,s,n,o=loadCookieData(o);return o&&o.cookies?({csrfToken:e,corpId:s,userId:n}=extractInfoFromCookies(o.cookies),{loggedIn:!!e,csrfToken:e,corpId:s,userId:n,baseUrl:resolveBaseUrl(o)}):{loggedIn:!1,csrfToken:null,corpId:null,userId:null,baseUrl:null}}function run(){var o="=".repeat(55),{activeToolName:e,activeProjectRoot:s,results:n}=(console.log(o),console.log(" yidacli env - 环境检测"),console.log(o),console.log("\n📋 系统信息"),console.log(` 操作系统: ${process.platform} (${os.arch()})`),console.log(" Node.js: "+process.version),console.log(" 主目录: "+os.homedir()),console.log(" 工作目录: "+process.cwd()),console.log("\n🤖 AI 工具检测"),detectEnvironment());if(0===n.length)console.log(" ⚠️ 未检测到任何已知 AI 工具");else for(var{displayName:t,isActive:l,hasProject:r,workspaceRoot:c}of n){let o,e;e=l&&r?(o="✅","← 当前活跃,项目已就绪"):l&&!r?(o="🟡","← 当前活跃,但无 openyida 项目"):!l&&r?(o="⬜","(已安装,项目存在,但未活跃)"):(o="⬜","(已安装,未活跃)"),console.log(` ${o} ${t.padEnd(18)} `+e)}console.log("\n🎯 当前生效环境"),e&&s?(console.log(" AI 工具: "+e),console.log(" 项目根目录: "+s)):(0<(e=n.filter(o=>o.isActive)).length?console.log(` AI 工具: ${e.map(o=>o.displayName).join(", ")} (活跃,但无 openyida 项目)`):console.log(" AI 工具: 未检测到活跃工具"),console.log(` 项目根目录: ${process.cwd()} (fallback)`)),console.log("\n🔐 登录态检测");n=detectLoginStatus(s||process.cwd());n.loggedIn?(console.log(" 状态: ✅ 已登录"),console.log(" 域名: "+n.baseUrl),console.log(" 组织 ID: "+(n.corpId||"(未知)")),console.log(" 用户 ID: "+(n.userId||"(未知)")),console.log(` csrf_token: ${n.csrfToken.slice(0,16)}...`)):console.log(" 状态: ❌ 未登录(运行 yidacli login 进行登录)"),console.log("\n"+o)}module.exports={run:run,detectEnvironment:detectEnvironment,detectLoginStatus:detectLoginStatus};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
let querystring=require("querystring"),{loadCookieData,triggerLogin,refreshCsrfToken,resolveBaseUrl,httpPost,requestWithAutoLogin}=require("./utils");function parseArgs(){var e=process.argv.slice(2);return e.length<2&&(console.error("用法: yidacli get-page-config <appType> <formUuid>"),console.error("示例: yidacli get-page-config APP_XXX FORM-XXX"),process.exit(1)),{appType:e[0],formUuid:e[1]}}async function main(){let{appType:o,formUuid:s}=parseArgs(),e=(console.error("=".repeat(50)),console.error(" get-page-config - 宜搭页面配置查询工具"),console.error("=".repeat(50)),console.error(`
|
|
2
|
+
应用 ID: `+o),console.error(" 表单 UUID: "+s),console.error("\n🔑 Step 1: 读取登录态"),loadCookieData());e||(console.error(" ⚠️ 未找到本地登录态,触发登录..."),e=triggerLogin());var r,n={csrfToken:e.csrf_token,cookies:e.cookies,baseUrl:resolveBaseUrl(e),cookieData:e},l=(console.error(` ✅ 登录态已就绪(${n.baseUrl})`),console.error("\n🔍 Step 2: 查询页面配置"),console.error(" 发送 getShareConfig 请求..."),await requestWithAutoLogin(e=>{var r=querystring.stringify({_api:"Share.getShareConfig",_csrf_token:e.csrfToken,_locale_time_zone_offset:"28800000",formUuid:s});return httpPost(e.baseUrl,`/dingtalk/web/${o}/query/formdesign/getShareConfig.json`,r,e.cookies)},n));console.error("\n"+"=".repeat(50)),!l||!1===l.success||l.__needLogin||l.__csrfExpired?(r=l?l.errorMsg||"未知错误":"请求失败",console.error(" ❌ 查询失败: "+r),console.error("=".repeat(50)),process.exit(1)):(l={isOpen:"y"===(r=l.content||{}).isOpen,openUrl:r.openUrl||null,shareUrl:r.shareUrl||null},console.error(" ✅ 查询成功!"),console.error("=".repeat(50)),l.openUrl&&console.error(" 公开访问: "+n.baseUrl+l.openUrl),l.shareUrl&&console.error(" 组织内分享: "+n.baseUrl+l.shareUrl),l.openUrl||l.shareUrl||console.error(" (暂未配置公开访问或分享链接)"),console.log(JSON.stringify(l,null,2)))}main().catch(e=>{console.error(`
|
|
3
|
+
❌ 查询异常: `+e.message),process.exit(1)});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let{loadCookieData,triggerLogin,resolveBaseUrl,httpGet,requestWithAutoLogin}=require("./utils");async function run(e){e.length<2&&(console.error("用法: yidacli get-schema <appType> <formUuid>"),console.error('示例: yidacli get-schema "APP_XXX" "FORM-XXX"'),process.exit(1));let r=e[0],o=e[1],s=(console.error("=".repeat(50)),console.error(" yidacli get-schema - 宜搭表单 Schema 获取工具"),console.error("=".repeat(50)),console.error(`
|
|
2
|
+
应用 ID: `+r),console.error(" 表单 UUID: "+o),console.error("\n🔑 Step 1: 读取登录态"),loadCookieData());s||(console.error(" ⚠️ 未找到本地登录态,触发登录..."),s=triggerLogin());var c,e={csrfToken:s.csrf_token,cookies:s.cookies,baseUrl:resolveBaseUrl(s),cookieData:s},e=(console.error(` ✅ 登录态已就绪(${e.baseUrl})`),console.error("\n📄 Step 2: 获取表单 Schema"),console.error(" 发送 getFormSchema 请求..."),await requestWithAutoLogin(e=>httpGet(e.baseUrl,`/alibaba/web/${r}/_view/query/formdesign/getFormSchema.json`,{formUuid:o,schemaVersion:"V5"},e.cookies),e));console.error("\n"+"=".repeat(50)),!e||!1===e.success||e.__needLogin||e.__csrfExpired?(c=e?e.errorMsg||"未知错误":"请求失败",console.error(" ❌ 获取 Schema 失败: "+c),console.error("=".repeat(50)),process.exit(1)):(console.error(" ✅ Schema 获取成功!"),console.error("=".repeat(50)),console.log(JSON.stringify(e,null,2)))}module.exports={run:run};
|
package/dist/login.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
let fs=require("fs"),path=require("path"),os=require("os"),execSync=require("child_process").execSync,{findProjectRoot,extractInfoFromCookies,loadCookieData,resolveBaseUrl}=require("./utils"),DEFAULT_BASE_URL="https://www.aliwork.com",DEFAULT_LOGIN_URL="https://www.aliwork.com/workPlatform";function loadConfig(){var o=findProjectRoot(),o=path.join(o,"config.json");if(fs.existsSync(o))try{return JSON.parse(fs.readFileSync(o,"utf-8"))}catch{}return{loginUrl:DEFAULT_LOGIN_URL,defaultBaseUrl:DEFAULT_BASE_URL}}function saveCookieCache(o,e){var r=findProjectRoot(),r=path.join(r,".cache"),s=path.join(r,"cookies.json");fs.mkdirSync(r,{recursive:!0}),fs.writeFileSync(s,JSON.stringify({cookies:o,base_url:e},null,2),"utf-8"),console.error(" Cookie 已保存到 "+s)}function checkLoginOnly(){var o,e,r,s=loadCookieData();return s&&s.cookies?({csrfToken:r,corpId:o,userId:e}=extractInfoFromCookies(s.cookies),r?{status:"ok",can_auto_use:!0,csrf_token:r,corp_id:o,user_id:e,base_url:r=resolveBaseUrl(s),cookies:s.cookies,message:`✅ 已有有效登录态,可直接使用
|
|
2
|
+
组织: ${o}
|
|
3
|
+
用户: ${e}
|
|
4
|
+
域名: `+r}:{status:"not_logged_in",can_auto_use:!1,message:"Cookie 中无 tianshu_csrf_token,需要重新登录"}):{status:"not_logged_in",can_auto_use:!1,message:"本地无 Cookie 缓存,需要扫码登录"}}function refreshCsrfFromCache(){var o=loadCookieData(),{csrfToken:e,corpId:r,userId:s}=(o&&o.cookies||(console.error(" ❌ 本地无有效 Cookie,无法刷新,需要重新登录。"),process.exit(1)),extractInfoFromCookies(o.cookies)),i=(e||(console.error(" ❌ Cookie 中无 tianshu_csrf_token,需要重新登录。"),process.exit(1)),resolveBaseUrl(o));return console.error(` ✅ csrf_token 提取成功: ${e.slice(0,16)}...`),{csrf_token:e,corp_id:r,user_id:s,base_url:i,cookies:o.cookies}}function ensureLogin(){var o=loadCookieData();if(o&&o.cookies){var{csrfToken:e,corpId:r,userId:s}=extractInfoFromCookies(o.cookies);if(e)return console.error("🔍 检测到本地 Cookie,直接使用..."),console.error(` ✅ csrf_token: ${e.slice(0,16)}...`),r&&console.error(" ✅ corpId: "+r),{csrf_token:e,corp_id:r,user_id:s,base_url:resolveBaseUrl(o),cookies:o.cookies}}return interactiveLogin()}function interactiveLogin(){var o=loadConfig().loginUrl||DEFAULT_LOGIN_URL,o=(console.error("\n🔐 正在打开浏览器,请扫码登录..."),console.error(" 登录地址: "+o),`
|
|
5
|
+
const { chromium } = require('playwright');
|
|
6
|
+
const { URL } = require('url');
|
|
7
|
+
|
|
8
|
+
(async () => {
|
|
9
|
+
const browser = await chromium.launch({ headless: false });
|
|
10
|
+
const context = await browser.newContext();
|
|
11
|
+
const page = await context.newPage();
|
|
12
|
+
await page.goto(${JSON.stringify(o)}, { timeout: 120000 });
|
|
13
|
+
|
|
14
|
+
console.error(' 等待登录完成(最长等待 10 分钟)...');
|
|
15
|
+
try {
|
|
16
|
+
await page.waitForURL('**/workPlatform**', { timeout: 600000 });
|
|
17
|
+
} catch {
|
|
18
|
+
console.error(' ⏰ 登录超时(10分钟),请重试。');
|
|
19
|
+
await browser.close();
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
await page.waitForLoadState('networkidle');
|
|
24
|
+
console.error(' ✅ 登录成功!');
|
|
25
|
+
|
|
26
|
+
const postLoginParsed = new URL(page.url());
|
|
27
|
+
const baseUrl = postLoginParsed.origin;
|
|
28
|
+
const cookies = await context.cookies();
|
|
29
|
+
await browser.close();
|
|
30
|
+
|
|
31
|
+
console.log(JSON.stringify({ cookies, base_url: baseUrl }));
|
|
32
|
+
})();
|
|
33
|
+
`),e=path.join(os.tmpdir(),`yidacli-login-${Date.now()}.js`);fs.writeFileSync(e,o,"utf-8");try{var r=execSync(`node "${e}"`,{encoding:"utf-8",stdio:["inherit","pipe","inherit"],timeout:66e4}).trim().split("\n"),s=r[r.length-1],i=JSON.parse(s),{csrfToken:t,corpId:c,userId:n}=extractInfoFromCookies(i.cookies);return t||(console.error(" ❌ 登录成功但 Cookie 中无 tianshu_csrf_token,请重试。"),process.exit(1)),saveCookieCache(i.cookies,i.base_url),console.error(` ✅ csrf_token: ${t.slice(0,16)}...`),c&&console.error(" ✅ corpId: "+c),{csrf_token:t,corp_id:c,user_id:n,base_url:i.base_url,cookies:i.cookies}}finally{try{fs.unlinkSync(e)}catch{}}}function logout(){console.error("=".repeat(50)),console.error(" yidacli logout - 宜搭退出登录工具"),console.error("=".repeat(50));var o=findProjectRoot(),o=path.join(o,".cache","cookies.json");console.error(`
|
|
34
|
+
Cookie 文件: `+o),fs.existsSync(o)?(fs.writeFileSync(o,"","utf-8"),console.error(" ✅ 已清空 Cookie,登录态已失效。"),console.error(" 下次调用 yidacli login 时将重新触发扫码登录。")):console.error(" ℹ️ Cookie 文件不存在,无需清空。"),console.error("=".repeat(50))}module.exports={ensureLogin:ensureLogin,checkLoginOnly:checkLoginOnly,refreshCsrfFromCache:refreshCsrfFromCache,interactiveLogin:interactiveLogin,logout:logout};
|
package/dist/publish.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
let fs=require("fs"),path=require("path"),execSync=require("child_process").execSync,https=require("https"),http=require("http"),querystring=require("querystring"),babelTransform=require("./babel-transform").default,UglifyJS=require("uglify-js"),{findProjectRoot,loadCookieData,triggerLogin,refreshCsrfToken,resolveBaseUrl,isLoginExpired,isCsrfTokenExpired}=require("./utils"),CONFIG=fs.existsSync(path.resolve(findProjectRoot(),"config.json"))?JSON.parse(fs.readFileSync(path.resolve(findProjectRoot(),"config.json"),"utf-8")):{},DEFAULT_BASE_URL=CONFIG.defaultBaseUrl||"https://www.aliwork.com",SCHEMA_VERSION="V5",DOMAIN_CODE="tEXDRG",PREFIX="_view",PROJECT_ROOT=findProjectRoot();function parseArgs(){var e=process.argv.slice(2);return e.length<3&&(console.error("用法: node publish.js <appType> <formUuid> <源文件路径>"),console.error("示例:node publish.js APP_XXX FORM-XXX pages/src/xxx.js"),process.exit(1)),{appType:e[0],formUuid:e[1],sourceFile:e[2]}}function resolveBaseUrl(e){return(e.base_url||DEFAULT_BASE_URL).replace(/\/+$/,"")}function compileSource(e){var o=path.basename(e),r=path.parse(e).name+".js",n=path.join(findProjectRoot(),"pages","dist",r),e=(console.error(`[1/4] 读取 ${o} 源码...`),fs.readFileSync(e,"utf-8")),o=(console.error(`[2/4] Babel 编译 ${o}...`),babelTransform(e,{},!1,{RE_VERSION:"7.4.0"}));if(o.error instanceof Error){var s=o.error;let e=" ❌ 编译失败:"+s.message;s.loc&&(e+=`
|
|
3
|
+
位置: 第 ${s.loc.line} 行, 第 ${s.loc.column} 列`),s.code&&(e+=`
|
|
4
|
+
错误码: `+s.code),console.error(e),process.exit(1)}console.error(`[3/4] UglifyJS 压缩 → ${r}...`);s=UglifyJS.minify(o.compiled),s.error&&(console.error(" 压缩失败:"+s.error.message),process.exit(1)),r=path.dirname(n);return fs.existsSync(r)||fs.mkdirSync(r,{recursive:!0}),fs.writeFileSync(n,s.code,"utf-8"),console.error(" ✅ 编译压缩完成:"+n),{sourceCode:e,compiledCode:s.code}}let nodeIdCounter=1;function nextNodeId(){return"node_oc"+Date.now().toString(36)+(nodeIdCounter++).toString(36)}function generateSuffix(){return Date.now().toString(36)+Math.random().toString(36).substring(2,8)}function buildSchemaContent(e,o,r){console.error("[4/4] 构建 Schema...");var n="function constructor() {\nvar module = { exports: {} };\nvar _this = this;\nthis.__initMethods__(module.exports, module);\nObject.keys(module.exports).forEach(function(item) {\n if(typeof module.exports[item] === 'function'){\n _this[item] = module.exports[item];\n }\n});\n\n}",n={schemaType:"superform",schemaVersion:"5.0",pages:[{utils:[{name:"legaoBuiltin",type:"npm",content:{package:"@ali/vu-legao-builtin",version:"3.0.0",exportName:"legaoBuiltin"}},{name:"yidaPlugin",type:"npm",content:{package:"@ali/vu-yida-plugin",version:"1.1.0",exportName:"yidaPlugin"}}],componentsMap:[{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:"RootHeader"},{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:"Jsx"},{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:"RootContent"},{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:"RootFooter"},{package:"@ali/vc-deep-yida",version:"1.5.169",componentName:"Page"}],componentsTree:[{componentName:"Page",id:nextNodeId(),props:{contentBgColor:"white",pageStyle:{backgroundColor:"#f2f3f5"},contentMargin:"0",contentPadding:"0",showTitle:!1,contentPaddingMobile:"0",templateVersion:"1.0.0",contentMarginMobile:"0",className:"page_"+generateSuffix(),contentBgColorMobile:"white"},condition:!0,css:"body{background-color:#f2f3f5}",methods:{__initMethods__:{type:"js",source:"function (exports, module) { /*set actions code here*/ }",compiled:"function (exports, module) { /*set actions code here*/ }"}},dataSource:{offline:[],globalConfig:{fit:{compiled:"'use strict';\n\nvar __preParser__ = function fit(response) {\n var content = response.content !== undefined ? response.content : response;\n var error = {\n message: response.errorMsg || response.errors && response.errors[0] && response.errors[0].msg || response.content || '远程数据源请求出错,success is false'\n };\n var success = true;\n if (response.success !== undefined) {\n success = response.success;\n } else if (response.hasError !== undefined) {\n success = !response.hasError;\n }\n return {\n content: content,\n success: success,\n error: error\n };\n};",source:"function fit(response) {\r\n const content = (response.content !== undefined) ? response.content : response;\r\n const error = {\r\n message: response.errorMsg ||\r\n (response.errors && response.errors[0] && response.errors[0].msg) ||\r\n response.content || '远程数据源请求出错,success is false',\r\n };\r\n let success = true;\r\n if (response.success !== undefined) {\r\n success = response.success;\r\n } else if (response.hasError !== undefined) {\r\n success = !response.hasError;\r\n }\r\n return {\r\n content,\r\n success,\r\n error,\r\n };\r\n}",type:"js",error:{}}},online:[{id:"VCB660714833IBHEOXK376TA7XJH2AXUWR8MMW",name:"urlParams",description:"当前页面地址的参数:如 aliwork.com/APP_XXX/workbench?id=1&name=宜搭,可通过 this.state.urlParams.name 获取到宜搭",formUuid:r,protocal:"URI",isReadonly:!0},{id:"",name:"timestamp",description:"",formUuid:r,protocal:"VALUE",initialData:""}],list:[{id:"VCB660714833IBHEOXK376TA7XJH2AXUWR8MMW",name:"urlParams",description:"当前页面地址的参数:如 aliwork.com/APP_XXX/workbench?id=1&name=宜搭,可通过 this.state.urlParams.name 获取到宜搭",formUuid:r,protocal:"URI",isReadonly:!0},{id:"",name:"timestamp",description:"",formUuid:r,protocal:"VALUE",initialData:""}],sync:!0},lifeCycles:{constructor:{type:"js",compiled:n,source:n},componentWillUnmount:{name:"didUnmount",id:"didUnmount",type:"actionRef",params:{}},componentDidMount:{name:"didMount",id:"didMount",params:{},type:"actionRef"}},hidden:!1,title:"",isLocked:!1,conditionGroup:"",children:[{componentName:"RootHeader",id:nextNodeId(),props:{},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:""},{componentName:"RootContent",id:nextNodeId(),props:{},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:"",children:[{componentName:"Jsx",id:nextNodeId(),props:{render:{type:"js",compiled:'function main(){\n \n "use strict";\n\nvar __compiledFunc__ = function render() {\n return this.renderJsx();\n};\n return __compiledFunc__.apply(this, arguments);\n }',source:"function render() {\n return this.renderJsx();\n}",error:{}},__style__:{},fieldId:"jsx_"+generateSuffix()},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:""}]},{componentName:"RootFooter",id:nextNodeId(),props:{},condition:!0,hidden:!1,title:"",isLocked:!1,conditionGroup:""}]}],id:r,connectComponent:[]}],actions:{module:{compiled:o,source:e},type:"FUNCTION",list:[{id:"getCustomState",title:"getCustomState"},{id:"setCustomState",title:"setCustomState"},{id:"forceUpdate",title:"forceUpdate"},{id:"didMount",title:"didMount"},{id:"didUnmount",title:"didUnmount"},{id:"renderJsx",title:"renderJsx"}]},config:{connectComponent:[]}};return JSON.stringify(n)}let COOKIES_PATH=path.join(PROJECT_ROOT,".cache","cookies.json");function sendSaveRequest(a,d,p,l,u,m){return new Promise((n,o)=>{var e=`/alibaba/web/${u}/${PREFIX}/query/formdesign/saveFormSchema.json?_stamp=`+Date.now(),r=querystring.stringify({_csrf_token:a,prefix:PREFIX,content:p,formUuid:m,schemaVersion:SCHEMA_VERSION,domainCode:DOMAIN_CODE,importSchema:!0}),s=d.map(e=>e.name+"="+e.value).join("; "),t=new URL(l),i="https:"===t.protocol,c=i?https:http,t={hostname:t.hostname,port:t.port||(i?443:80),path:e,method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded","Content-Length":Buffer.byteLength(r),Origin:l,Referer:l+"/",Cookie:s}},i=c.request(t,o=>{let r="";o.on("data",e=>{r+=e}),o.on("end",()=>{console.error(" HTTP 状态码: "+o.statusCode);let e;try{e=JSON.parse(r)}catch(e){return console.error(" 响应内容: "+r.substring(0,500)),void n({success:!1,errorMsg:`HTTP ${o.statusCode}: 响应非 JSON`})}isLoginExpired(e)?(console.error(" 检测到登录过期: "+e.errorMsg),n({__needLogin:!0})):isCsrfTokenExpired(e)?(console.error(" 检测到 csrf_token 过期: "+e.errorMsg),n({__csrfExpired:!0})):n(e)})});i.on("error",e=>{o(e)}),i.write(r),i.end()})}function sendUpdateConfigRequest(a,d,p,l,u,m,f){return new Promise((n,o)=>{var e=`/dingtalk/web/${l}/query/formdesign/updateFormConfig.json`,r=querystring.stringify({_csrf_token:a,formUuid:u,version:m,configType:"MINI_RESOURCE",value:f}),s=d.map(e=>e.name+"="+e.value).join("; "),t=new URL(p),i="https:"===t.protocol,c=i?https:http,t={hostname:t.hostname,port:t.port||(i?443:80),path:e,method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded","Content-Length":Buffer.byteLength(r),Origin:p,Referer:p+"/",Cookie:s}},i=c.request(t,o=>{let r="";o.on("data",e=>{r+=e}),o.on("end",()=>{console.error(" HTTP 状态码: "+o.statusCode);let e;try{e=JSON.parse(r)}catch(e){return console.error(" 响应内容: "+r.substring(0,500)),void n({success:!1,errorMsg:`HTTP ${o.statusCode}: 响应非 JSON`})}isLoginExpired(e)?(console.error(" 检测到登录过期: "+e.errorMsg),n({__needLogin:!0})):isCsrfTokenExpired(e)?(console.error(" 检测到 csrf_token 过期: "+e.errorMsg),n({__csrfExpired:!0})):n(e)})});i.on("error",e=>{o(e)}),i.write(r),i.end()})}async function main(){var{appType:e,formUuid:o,sourceFile:r}=parseArgs(),r=path.resolve(r),n=(fs.existsSync(r)||(console.error("❌ 源文件不存在:"+r),process.exit(1)),path.parse(r)),n=path.join(findProjectRoot(),"pages","dist",n.name+".js"),{sourceCode:s,compiledCode:t}=(console.error("\n📦 Step 1: 编译源码 & 构建 Schema\n"),compileSource(r)),s=buildSchemaContent(s,t,o);console.error(" ✅ Schema 构建完成!"),console.error("\n🔑 Step 2: 读取登录态");let i=loadCookieData(),{csrf_token:c,cookies:a}=(i&&i.csrf_token||(console.error(" ⚠️ 未找到本地登录态或 csrf_token,触发登录..."),i=triggerLogin()),i),d=resolveBaseUrl(i),p=(console.error("=".repeat(50)),console.error(" yida-publish - 宜搭页面发布工具"),console.error("=".repeat(50)),console.error(`
|
|
5
|
+
平台地址: `+d),console.error(" 应用ID: "+e),console.error(" 表单ID: "+o),console.error(" 源文件: "+r),console.error(" 编译产物:"+n),console.error(" 输出目录:pages/dist/"),console.error("\n📤 Step 3: 发布 Schema\n"),await sendSaveRequest(c,a,s,d,e,o));p&&p.__csrfExpired&&(i=refreshCsrfToken(),c=i.csrf_token,a=i.cookies,d=resolveBaseUrl(i),console.error(" 🔄 重新发送 saveFormSchema 请求(csrf_token 已刷新)..."),p=await sendSaveRequest(c,a,s,d,e,o)),p&&p.__needLogin&&(i=triggerLogin(),c=i.csrf_token,a=i.cookies,d=resolveBaseUrl(i),console.error(" 🔄 重新发送 saveFormSchema 请求..."),p=await sendSaveRequest(c,a,s,d,e,o)),p&&p.success||(t=p?p.errorMsg||"未知错误":"请求失败",console.error(`
|
|
6
|
+
❌ 发布失败: `+t),!p||p.__needLogin||p.__csrfExpired||console.error(" 响应详情: "+JSON.stringify(p,null,2)),process.exit(1));r=p.content||{},n=r.formUuid||o,s=r.version||0;console.error(" ✅ Schema 发布成功!"),console.error(" formUuid: "+n),console.error(" version: "+s),console.error("\n⚙️ Step 4: 更新表单配置\n"),console.error(" 发送 updateFormConfig 请求...");let l=await sendUpdateConfigRequest(c,a,d,e,n,s,8);l&&l.__csrfExpired&&(i=refreshCsrfToken(),c=i.csrf_token,a=i.cookies,d=resolveBaseUrl(i),console.error(" 🔄 重新发送 updateFormConfig 请求(csrf_token 已刷新)..."),l=await sendUpdateConfigRequest(c,a,d,e,n,s,8)),l&&l.__needLogin&&(i=triggerLogin(),c=i.csrf_token,a=i.cookies,d=resolveBaseUrl(i),console.error(" 🔄 重新发送 updateFormConfig 请求..."),l=await sendUpdateConfigRequest(c,a,d,e,n,s,8)),console.error("\n"+"=".repeat(50)),l&&l.success?(console.error(" ✅ 发布成功!"),console.error(" formUuid: "+n),console.error(" version: "+s),console.error(" 配置已更新: MINI_RESOURCE = 8")):(t=l?l.errorMsg||"未知错误":"请求失败",console.error(" ⚠️ 配置更新失败: "+t),console.error(" Schema 已发布,但配置更新失败"),!l||l.__needLogin||l.__csrfExpired||console.error(" 响应详情: "+JSON.stringify(l,null,2))),console.error("=".repeat(50))}main().catch(e=>{console.error(`
|
|
7
|
+
❌ 发布异常: `+e.message),process.exit(1)});
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
let https=require("https"),http=require("http"),fs=require("fs"),path=require("path"),querystring=require("querystring"),{findProjectRoot,loadCookieData,triggerLogin,refreshCsrfToken,resolveBaseUrl,isLoginExpired,isCsrfTokenExpired}=require("./utils"),PROJECT_ROOT=findProjectRoot(),CONFIG_PATH=path.resolve(PROJECT_ROOT,"config.json"),CONFIG=fs.existsSync(CONFIG_PATH)?JSON.parse(fs.readFileSync(CONFIG_PATH,"utf-8")):{},DEFAULT_BASE_URL=CONFIG.defaultBaseUrl||"https://www.aliwork.com";function parseArgs(){var e=process.argv.slice(2);return e.length<4&&(console.error("用法: node save-share-config.js <appType> <formUuid> <openUrl> <isOpen> [openAuth]"),console.error('示例: node .claude/skills/yida-save-share-config/scripts/save-share-config.js "APP_XXX" "FORM-XXX" "/o/xxx" "y" "n"'),console.error(" isOpen: y=开启公开访问, n=关闭公开访问"),console.error(" openAuth: y=需要授权, n=不需要授权(默认)"),process.exit(1)),{appType:e[0],formUuid:e[1],openUrl:e[2],isOpen:e[3],openAuth:e[4]||"n"}}function validateParams(e){if("y"!==e.isOpen&&"n"!==e.isOpen)throw new Error("isOpen 必须为 y 或 n,当前值: "+e.isOpen);if("y"!==e.openAuth&&"n"!==e.openAuth)throw new Error("openAuth 必须为 y 或 n,当前值: "+e.openAuth);if("y"===e.isOpen&&!e.openUrl)throw new Error("开启公开访问时,openUrl 不能为空");if("n"===e.isOpen)return!0;if(!e.openUrl.startsWith("/o/"))throw new Error("openUrl 必须以 /o/ 开头,当前值: "+e.openUrl);var r=e.openUrl.slice(3);if(/^[a-zA-Z0-9_-]+$/.test(r))return!0;throw new Error("openUrl 路径部分只支持 a-z A-Z 0-9 _ -,当前值: "+e.openUrl)}function sendPostRequest(i,a,l,p){return new Promise((s,r)=>{var e=a.map(e=>e.name+"="+e.value).join("; "),o=new URL(i),n="https:"===o.protocol;let t=(n?https:http).request({hostname:o.hostname,port:o.port||(n?443:80),path:l,method:"POST",headers:{Origin:i,Referer:i+"/",Cookie:e,Accept:"application/json, text/json","Content-Type":"application/x-www-form-urlencoded","x-requested-with":"XMLHttpRequest"},timeout:3e4},r=>{let o="";r.on("data",e=>{o+=e}),r.on("end",()=>{console.error(" HTTP 状态码: "+r.statusCode);let e;try{e=JSON.parse(o)}catch(e){return console.error(" 响应内容: "+o.substring(0,500)),void s({success:!1,errorMsg:`HTTP ${r.statusCode}: 响应非 JSON`})}isLoginExpired(e)?(console.error(" 检测到登录过期: "+e.errorMsg),s({__needLogin:!0})):isCsrfTokenExpired(e)?(console.error(" 检测到 csrf_token 过期: "+e.errorMsg),s({__csrfExpired:!0})):s(e)})});t.on("timeout",()=>{console.error(" ❌ 请求超时"),t.destroy(),r(new Error("请求超时"))}),t.on("error",e=>{r(e)}),t.write(p),t.end()})}async function main(){var{appType:e,formUuid:r,openUrl:o,isOpen:s,openAuth:n}=parseArgs();console.error("=".repeat(50)),console.error(" save-share-config - 宜搭公开访问配置保存工具"),console.error("=".repeat(50)),console.error(`
|
|
2
|
+
应用 ID: `+e),console.error(" 表单 UUID: "+r),console.error(" 公开访问路径: "+(o||"(空)")),console.error(" 是否开放: "+("y"===s?"是":"否")),console.error(" 是否需要授权: "+("y"===n?"是":"否")),console.error("\n📋 Step 0: 验证参数");try{validateParams({openUrl:o,isOpen:s,openAuth:n}),console.error(" ✅ 参数验证通过")}catch(e){console.error(" ❌ 参数验证失败: "+e.message),process.exit(1)}console.error("\n🔑 Step 1: 读取登录态");let t=loadCookieData(),i=(t||(console.error(" ⚠️ 未找到本地登录态,触发登录..."),t=triggerLogin()),t).cookies,a=resolveBaseUrl(t),l=(console.error(` ✅ 登录态已就绪(${a})`),console.error("\n💾 Step 2: 保存公开访问配置"),console.error(" 发送 saveShareConfig 请求..."),t).csrf_token;var n=JSON.stringify({openAuth:n,authSources:[]}),p=querystring.stringify({_api:"Share.saveShareConfig",_csrf_token:l,_locale_time_zone_offset:"28800000",formUuid:r,shareUrl:"",openUrl:o,isOpen:s,openPageAuthConfig:n});let c=await sendPostRequest(a,i,`/dingtalk/web/${e}/query/formdesign/saveShareConfig.json`,p);c&&c.__csrfExpired&&(t=refreshCsrfToken(),l=t.csrf_token,i=t.cookies,a=resolveBaseUrl(t),p=querystring.stringify({_api:"Share.saveShareConfig",_csrf_token:l,_locale_time_zone_offset:"28800000",formUuid:r,shareUrl:"",openUrl:o,isOpen:s,openPageAuthConfig:n}),console.error(" 🔄 重新发送 saveShareConfig 请求(csrf_token 已刷新)..."),c=await sendPostRequest(a,i,`/dingtalk/web/${e}/query/formdesign/saveShareConfig.json`,p)),c&&c.__needLogin&&(t=triggerLogin(),l=t.csrf_token,i=t.cookies,a=resolveBaseUrl(t),p=querystring.stringify({_api:"Share.saveShareConfig",_csrf_token:l,_locale_time_zone_offset:"28800000",formUuid:r,shareUrl:"",openUrl:o,isOpen:s,openPageAuthConfig:n}),console.error(" 🔄 重新发送 saveShareConfig 请求..."),c=await sendPostRequest(a,i,`/dingtalk/web/${e}/query/formdesign/saveShareConfig.json`,p)),console.error("\n"+"=".repeat(50)),!c||c.__needLogin||c.__csrfExpired?(console.error(" ❌ 请求失败"),console.error("=".repeat(50)),process.exit(1)):c.success?(console.error(" ✅ 配置保存成功!"),console.error("=".repeat(50)),console.log(JSON.stringify({success:!0,openUrl:"y"===s?o:null,isOpen:"y"===s,message:"公开访问配置已保存"},null,2))):(console.error(" ❌ 保存失败: "+(c.errorMsg||"未知错误")),console.error("=".repeat(50)),console.log(JSON.stringify({success:!1,message:c.errorMsg||"保存失败",errorCode:c.errorCode},null,2)))}main().catch(e=>{console.error(`
|
|
3
|
+
❌ 保存异常: `+e.message),process.exit(1)});
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
let https=require("https"),http=require("http"),fs=require("fs"),path=require("path"),querystring=require("querystring"),{findProjectRoot,loadCookieData,triggerLogin,refreshCsrfToken,resolveBaseUrl,isLoginExpired,isCsrfTokenExpired}=require("./utils"),PROJECT_ROOT=findProjectRoot(),CONFIG_PATH=path.resolve(PROJECT_ROOT,"config.json"),CONFIG=fs.existsSync(CONFIG_PATH)?JSON.parse(fs.readFileSync(CONFIG_PATH,"utf-8")):{},DEFAULT_BASE_URL=CONFIG.defaultBaseUrl||"https://www.aliwork.com";function parseArgs(){var e=process.argv.slice(2);return e.length<4&&(console.error("用法: node update-form-config.js <appType> <formUuid> <isRenderNav> <title>"),console.error('示例: node .claude/skills/yida-page-config/scripts/update-form-config.js "APP_XXX" "FORM_XXX" "false" "我的页面"'),console.error(""),console.error("参数说明:"),console.error(" isRenderNav: true=显示顶部导航, false=隐藏顶部导航"),console.error(" title: 页面标题(必填)"),process.exit(1)),{appType:e[0],formUuid:e[1],isRenderNav:e[2],title:e[3]}}function buildPostData(e,r,o,s){s=JSON.stringify({pureEn_US:s,en_US:s,zh_CN:s,envLocale:null,type:"i18n",ja_JP:null,key:null});return querystring.stringify({_api:"Form.updateFormSchemaInfo",_csrf_token:e,_locale_time_zone_offset:"28800000",formUuid:r,serialSwitch:"n",consultPerson:"",defaultManager:"n",submissionRule:"RESUBMIT",redirectConfig:"",pushTask:"y",defaultOrder:"cd",showPrint:"y",relateUuid:"",title:s,pageType:"web,mobile",isInner:"y",isNew:"n",isAgent:"y",showAgent:"n",showDingGroup:"y",reStart:"n",previewConfig:"y",formulaType:"n",displayTitle:"%24%7Blegao_creator%7D%E5%8F%91%E8%B5%B7%E7%9A%84%24%7Blegao_formname%7D",displayType:"RE",isRenderNav:o,manageCustomActionInfo:"[]"})}function sendPostRequest(i,a,l,c){return new Promise((s,r)=>{var e=a.map(e=>e.name+"="+e.value).join("; "),o=new URL(i),n="https:"===o.protocol;let t=(n?https:http).request({hostname:o.hostname,port:o.port||(n?443:80),path:l,method:"POST",headers:{Origin:i,Referer:i+"/",Cookie:e,Accept:"application/json, text/json","Content-Type":"application/x-www-form-urlencoded","x-requested-with":"XMLHttpRequest"},timeout:3e4},r=>{let o="";r.on("data",e=>{o+=e}),r.on("end",()=>{console.error(" HTTP 状态码: "+r.statusCode);let e;try{e=JSON.parse(o)}catch(e){return console.error(" 响应内容: "+o.substring(0,500)),void s({success:!1,errorMsg:`HTTP ${r.statusCode}: 响应非 JSON`})}isLoginExpired(e)?(console.error(" 检测到登录过期: "+e.errorMsg),s({__needLogin:!0})):isCsrfTokenExpired(e)?(console.error(" 检测到 csrf_token 过期: "+e.errorMsg),s({__csrfExpired:!0})):s(e)})});t.on("timeout",()=>{console.error(" ❌ 请求超时"),t.destroy(),r(new Error("请求超时"))}),t.on("error",e=>{r(e)}),t.write(c),t.end()})}async function main(){var{appType:e,formUuid:r,isRenderNav:o,title:s}=parseArgs();console.error("=".repeat(50)),console.error(" update-form-config - 宜搭表单配置更新工具"),console.error("=".repeat(50)),console.error(`
|
|
2
|
+
应用 ID: `+e),console.error(" 表单 UUID: "+r),console.error(" 显示导航: "+("true"===o?"是":"否")),console.error(" 页面标题: "+s),console.error("\n🔑 Step 1: 读取登录态");let n=loadCookieData(),t=(n||(console.error(" ⚠️ 未找到本地登录态,触发登录..."),n=triggerLogin()),n).cookies,i=resolveBaseUrl(n),a=(console.error(` ✅ 登录态已就绪(${i})`),console.error("\n💾 Step 2: 更新表单配置(隐藏顶部导航)"),console.error(" 发送 updateFormSchemaInfo 请求..."),n).csrf_token;var l=buildPostData(a,r,o,s);let c=await sendPostRequest(i,t,`/dingtalk/web/${e}/query/formdesign/updateFormSchemaInfo.json`,l);c&&c.__csrfExpired&&(n=refreshCsrfToken(),a=n.csrf_token,t=n.cookies,i=resolveBaseUrl(n),l=buildPostData(a,r,o,s),console.error(" 🔄 重新发送请求(csrf_token 已刷新)..."),c=await sendPostRequest(i,t,`/dingtalk/web/${e}/query/formdesign/updateFormSchemaInfo.json`,l)),c&&c.__needLogin&&(n=triggerLogin(),a=n.csrf_token,t=n.cookies,i=resolveBaseUrl(n),l=buildPostData(a,r,o,s),console.error(" 🔄 重新发送请求..."),c=await sendPostRequest(i,t,`/dingtalk/web/${e}/query/formdesign/updateFormSchemaInfo.json`,l)),console.error("\n"+"=".repeat(50)),!c||c.__needLogin||c.__csrfExpired?(console.error(" ❌ 请求失败"),console.error("=".repeat(50)),process.exit(1)):c.success?(console.error(" ✅ 配置更新成功!"),console.error("=".repeat(50)),console.log(JSON.stringify({success:!0,isRenderNav:"true"===o,message:"true"===o?"已显示顶部导航":"已隐藏顶部导航"},null,2))):(console.error(" ❌ 更新失败: "+(c.errorMsg||"未知错误")),console.error("=".repeat(50)),console.log(JSON.stringify({success:!1,message:c.errorMsg||"更新失败",errorCode:c.errorCode},null,2)))}main().catch(e=>{console.error(`
|
|
3
|
+
❌ 更新异常: `+e.message),process.exit(1)});
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
let fs=require("fs"),path=require("path"),os=require("os"),execSync=require("child_process").execSync,WORKSPACE_ROOT_DIR_NAMES=[".real",".opencode",".claudecode",".aone_copilot",".cursor",".qoder",".iflow"];function findProjectRoot(){var e,r=os.homedir();for(e of WORKSPACE_ROOT_DIR_NAMES){var o=path.join(r,e,"workspace","openyida");if(fs.existsSync(o))return o}return process.cwd()}function extractInfoFromCookies(e){let r=null,o=null,t=null;for(var n of e){var s;"tianshu_csrf_token"===n.name?r=n.value:"tianshu_corp_user"===n.name&&0<(s=n.value.lastIndexOf("_"))&&(o=n.value.slice(0,s),t=n.value.slice(s+1))}return{csrfToken:r,corpId:o,userId:t}}function loadCookieData(r,o){r=r||findProjectRoot(),o=o||"https://www.aliwork.com",r=path.join(r,".cache","cookies.json");if(!fs.existsSync(r))return null;try{var t=fs.readFileSync(r,"utf-8").trim();if(!t)return null;var n,s,i,a=JSON.parse(t);let e;return(e=Array.isArray(a)?{cookies:a,base_url:o}:a).cookies&&0<e.cookies.length&&({csrfToken:n,corpId:s,userId:i}=extractInfoFromCookies(e.cookies),n&&(e.csrf_token=n),s&&(e.corp_id=s),i)&&(e.user_id=i),e}catch{return null}}function triggerLogin(){console.error("\n🔐 登录态失效,正在打开浏览器扫码登录...\n");var e=require("./login").ensureLogin;return e()}function refreshCsrfToken(){console.error("\n🔄 csrf_token 已过期,正在从 Cookie 重新提取...\n");var e=require("./login").refreshCsrfFromCache;return e()}function isLoginExpired(e){return e&&!1===e.success&&("307"===e.errorCode||"302"===e.errorCode)}function isCsrfTokenExpired(e){return e&&!1===e.success&&"TIANSHU_000030"===e.errorCode}function resolveBaseUrl(e,r){r=r||"https://www.aliwork.com";return(e&&e.base_url||r).replace(/\/+$/,"")}function httpPost(a,c,u,l){let f=require("https"),d=require("http");return new Promise((t,e)=>{var r=l.map(e=>e.name+"="+e.value).join("; "),o=new URL(a),n="https:"===o.protocol,s=n?f:d,o={hostname:o.hostname,port:o.port||(n?443:80),path:c,method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded","Content-Length":Buffer.byteLength(u),Origin:a,Referer:a+"/",Cookie:r},timeout:3e4};let i=s.request(o,r=>{let o="";r.on("data",e=>{o+=e}),r.on("end",()=>{console.error(" HTTP 状态码: "+r.statusCode);try{var e=JSON.parse(o);isLoginExpired(e)?t({__needLogin:!0}):isCsrfTokenExpired(e)?t({__csrfExpired:!0}):t(e)}catch{console.error(" 响应内容: "+o.substring(0,500)),t({success:!1,errorMsg:`HTTP ${r.statusCode}: 响应非 JSON`})}})});i.on("timeout",()=>{i.destroy(),e(new Error("请求超时"))}),i.on("error",e),i.write(u),i.end()})}function httpGet(c,u,l,f){let d=require("https"),p=require("http"),h=require("querystring");return new Promise((t,e)=>{var r=f.map(e=>e.name+"="+e.value).join("; "),o=new URL(c),n="https:"===o.protocol,s=n?d:p,i=l?u+"?"+h.stringify(l):u;let a=s.request({hostname:o.hostname,port:o.port||(n?443:80),path:i,method:"GET",headers:{Origin:c,Referer:c+"/",Cookie:r},timeout:3e4},r=>{let o="";r.on("data",e=>{o+=e}),r.on("end",()=>{console.error(" HTTP 状态码: "+r.statusCode);try{var e=JSON.parse(o);isLoginExpired(e)?t({__needLogin:!0}):isCsrfTokenExpired(e)?t({__csrfExpired:!0}):t(e)}catch{console.error(" 响应内容: "+o.substring(0,500)),t({success:!1,errorMsg:`HTTP ${r.statusCode}: 响应非 JSON`})}})});a.on("timeout",()=>{a.destroy(),e(new Error("请求超时"))}),a.on("error",e),a.end()})}async function requestWithAutoLogin(e,r){let o=await e(r);var t;return o&&o.__csrfExpired&&(t=refreshCsrfToken(),r.cookieData=t,r.csrfToken=t.csrf_token,r.cookies=t.cookies,r.baseUrl=resolveBaseUrl(t),console.error(" 🔄 csrf_token 已刷新,重试..."),o=await e(r)),o&&o.__needLogin&&(t=triggerLogin(),r.cookieData=t,r.csrfToken=t.csrf_token,r.cookies=t.cookies,r.baseUrl=resolveBaseUrl(t),console.error(" 🔄 重新登录后重试..."),o=await e(r)),o}module.exports={findProjectRoot:findProjectRoot,extractInfoFromCookies:extractInfoFromCookies,loadCookieData:loadCookieData,triggerLogin:triggerLogin,refreshCsrfToken:refreshCsrfToken,resolveBaseUrl:resolveBaseUrl,isLoginExpired:isLoginExpired,isCsrfTokenExpired:isCsrfTokenExpired,httpPost:httpPost,httpGet:httpGet,requestWithAutoLogin:requestWithAutoLogin};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
let https=require("https"),http=require("http"),fs=require("fs"),path=require("path"),querystring=require("querystring"),{findProjectRoot,loadCookieData,triggerLogin,refreshCsrfToken,resolveBaseUrl,isLoginExpired,isCsrfTokenExpired}=require("./utils"),PROJECT_ROOT=findProjectRoot(),CONFIG_PATH=path.resolve(PROJECT_ROOT,"config.json"),CONFIG=fs.existsSync(CONFIG_PATH)?JSON.parse(fs.readFileSync(CONFIG_PATH,"utf-8")):{},DEFAULT_BASE_URL=CONFIG.defaultBaseUrl||"https://www.aliwork.com";function parseArgs(){var r=process.argv.slice(2),e=(r.length<3&&(console.error("用法: node verify-short-url.js <appType> <formUuid> <url>"),console.error('示例: node .claude/skills/yida-verify-short-url/scripts/verify-short-url.js "APP_XXX" "FORM-XXX" "/o/aaa"'),console.error(" 支持两种格式:"),console.error(" /o/xxx - 公开访问(对外)"),console.error(" /s/xxx - 组织内分享(对内)"),process.exit(1)),r[2]),o=e.startsWith("/o/")?"open":e.startsWith("/s/")?"share":null;return{appType:r[0],formUuid:r[1],url:e,urlType:o}}function validateUrl(r,e){if(!e)throw new Error("URL 必须以 /o/ 或 /s/ 开头,当前值: "+r);e=r.slice(3);if(!/^[a-zA-Z0-9_-]+$/.test(e))throw new Error("URL 路径部分只支持 a-z A-Z 0-9 _ -,当前值: "+r);if(0===e.length)throw new Error("URL 路径部分不能为空: "+r);return!0}function sendGetRequest(l,a,c,p){return new Promise((s,e)=>{var r=querystring.stringify(p),r=c+"?"+r,o=a.map(r=>r.name+"="+r.value).join("; "),t=new URL(l),n="https:"===t.protocol;let i=(n?https:http).request({hostname:t.hostname,port:t.port||(n?443:80),path:r,method:"GET",headers:{Origin:l,Referer:l+"/",Cookie:o,Accept:"application/json, text/json","x-requested-with":"XMLHttpRequest"},timeout:3e4},e=>{let o="";e.on("data",r=>{o+=r}),e.on("end",()=>{console.error(" HTTP 状态码: "+e.statusCode);let r;try{r=JSON.parse(o)}catch(r){return console.error(" 响应内容: "+o.substring(0,500)),void s({success:!1,errorMsg:`HTTP ${e.statusCode}: 响应非 JSON`})}isLoginExpired(r)?(console.error(" 检测到登录过期: "+r.errorMsg),s({__needLogin:!0})):isCsrfTokenExpired(r)?(console.error(" 检测到 csrf_token 过期: "+r.errorMsg),s({__csrfExpired:!0})):s(r)})});i.on("timeout",()=>{console.error(" ❌ 请求超时"),i.destroy(),e(new Error("请求超时"))}),i.on("error",r=>{e(r)}),i.end()})}async function main(){var{appType:r,formUuid:e,url:o,urlType:s}=parseArgs(),t="open"===s?"公开访问路径":"组织内分享路径";console.error("=".repeat(50)),console.error(" verify-short-url - 宜搭 URL 验证工具"),console.error("=".repeat(50)),console.error(`
|
|
2
|
+
应用 ID: `+r),console.error(" 表单 UUID: "+e),console.error(` ${t}: `+o),console.error("\n📋 Step 0: 验证 URL 格式");try{validateUrl(o,s),console.error(" ✅ 格式验证通过")}catch(r){console.error(" ❌ 格式验证失败: "+r.message),process.exit(1)}console.error("\n🔑 Step 1: 读取登录态");let n=loadCookieData(),i=(n||(console.error(" ⚠️ 未找到本地登录态,触发登录..."),n=triggerLogin()),n).cookies,l=resolveBaseUrl(n),a=(console.error(` ✅ 登录态已就绪(${l})`),console.error("\n🔍 Step 2: 验证 URL"),console.error(" 发送 verifyShortUrl 请求..."),n).csrf_token;t={_api:"App.verifyShortUrlForm",formUuid:e,_csrf_token:a,_locale_time_zone_offset:"28800000",_stamp:Date.now().toString()};"open"===s?t.openUrl=o:t.shareUrl=o;let c=await sendGetRequest(l,i,`/dingtalk/web/${r}/query/formdesign/verifyShortUrl.json`,t);c&&c.__csrfExpired&&(n=refreshCsrfToken(),a=n.csrf_token,i=n.cookies,l=resolveBaseUrl(n),t._csrf_token=a,t._stamp=Date.now().toString(),console.error(" 🔄 重新发送 verifyShortUrl 请求(csrf_token 已刷新)..."),c=await sendGetRequest(l,i,`/dingtalk/web/${r}/query/formdesign/verifyShortUrl.json`,t)),c&&c.__needLogin&&(n=triggerLogin(),a=n.csrf_token,i=n.cookies,l=resolveBaseUrl(n),t._csrf_token=a,t._stamp=Date.now().toString(),console.error(" 🔄 重新发送 verifyShortUrl 请求..."),c=await sendGetRequest(l,i,`/dingtalk/web/${r}/query/formdesign/verifyShortUrl.json`,t)),console.error("\n"+"=".repeat(50)),!c||c.__needLogin||c.__csrfExpired?(console.error(" ❌ 验证请求失败"),console.error("=".repeat(50)),process.exit(1)):c.success&&c.content?(console.error(" ✅ URL 可用!"),console.error("=".repeat(50)),console.log(JSON.stringify({available:!0,url:o,urlType:s,message:"open"===s?"该公开访问路径可用":"该组织内分享路径可用"},null,2))):(console.error(" ❌ URL 被占用"),console.error("=".repeat(50)),console.log(JSON.stringify({available:!1,url:o,urlType:s,message:c.errorMsg||"该短链接已被占用",errorCode:c.errorCode},null,2)))}main().catch(r=>{console.error(`
|
|
3
|
+
❌ 验证异常: `+r.message),process.exit(1)});
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openyida",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"yidacli": "^0.0.1"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
File without changes
|