@microi.net/cli 5.3.7 → 5.3.8
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/.codebuddy-plugin/marketplace.json +2 -2
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.workbuddy-plugin/marketplace.json +2 -2
- package/.workbuddy-plugin/plugin.json +1 -1
- package/assets/build-meta.json +3 -3
- package/cordis.patch.yml +1 -1
- package/package.json +1 -1
- package/scripts/microi-skills.meta.json +200 -200
- package/skills/.microi-skills-version.json +2 -2
- package/skills/.progressive-disclosure-manifest.json +33 -33
- package/skills/microi-deployment/SKILL.md +3 -3
- package/skills/microi-form-engine/SKILL.md +5 -2
- package/skills/microi-form-engine/references/component-catalog.md +2 -1
- package/skills/microi-frontend-sdk/SKILL.md +5 -4
- package/skills/microi-uniapp-frontend/SKILL.md +3 -1
- package/skills/microi.v8.js +86 -86
- package/skills/ocr-engine/SKILL.md +113 -113
- package/skills/translate-engine/SKILL.md +140 -140
- package/skills/v8-file-upload/SKILL.md +11 -4
- package/skills/v8-file-upload/references/progressive-01-/345/205/254/346/234/211/346/241/266-vs-/347/247/201/346/234/211/346/241/266.md +9 -2
- package/skills/v8-file-upload/references/progressive-02-office-/346/226/207/344/273/266/345/234/250/347/272/277/347/274/226/350/276/221/347/211/210/346/234/254/345/217/267/350/247/204/345/210/231.md +1 -1
- package/skills/v8-security/SKILL.md +10 -4
- package/skills/v8-security/references/progressive-02-7-/346/227/245/345/277/227/350/256/260/345/275/225.md +123 -123
- package/skills/v8-utilities/SKILL.md +2 -1
- package/skills/v8-utilities/references/server-api-index.md +40 -10
- package/skills/workspace-conventions/SKILL.md +194 -194
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
|
-
"generatedAt": "2026-08-
|
|
3
|
+
"generatedAt": "2026-08-26T19:09:39.599Z",
|
|
4
4
|
"policy": {
|
|
5
5
|
"maxEntryLines": 285,
|
|
6
6
|
"referenceBudgetLines": 245,
|
|
@@ -407,11 +407,11 @@
|
|
|
407
407
|
]
|
|
408
408
|
},
|
|
409
409
|
"microi-frontend-sdk": {
|
|
410
|
-
"originalSha256": "
|
|
411
|
-
"originalLines":
|
|
410
|
+
"originalSha256": "27802e252aa4c9d85e4e10c70baa9d05c7207dcf943c5305c24a586b17e0fac7",
|
|
411
|
+
"originalLines": 318,
|
|
412
412
|
"prefixSha256": "5ee94a9174a22577011c64f29a93f6983c8450d471d26f12fa884d7c4b3a879a",
|
|
413
413
|
"prefixBytes": 895,
|
|
414
|
-
"entryLines":
|
|
414
|
+
"entryLines": 191,
|
|
415
415
|
"chunks": [
|
|
416
416
|
{
|
|
417
417
|
"id": "microi-frontend-sdk-000",
|
|
@@ -433,7 +433,7 @@
|
|
|
433
433
|
"id": "microi-frontend-sdk-002",
|
|
434
434
|
"ordinal": 2,
|
|
435
435
|
"destination": "microi-frontend-sdk/SKILL.md",
|
|
436
|
-
"sha256": "
|
|
436
|
+
"sha256": "b71205548e4701f8bf53e2bed3da914da4ca0f49e0cce952a1c938fc77218ed8",
|
|
437
437
|
"lines": 48,
|
|
438
438
|
"heading": "登录与验证码封装"
|
|
439
439
|
},
|
|
@@ -449,8 +449,8 @@
|
|
|
449
449
|
"id": "microi-frontend-sdk-004",
|
|
450
450
|
"ordinal": 5,
|
|
451
451
|
"destination": "microi-frontend-sdk/SKILL.md",
|
|
452
|
-
"sha256": "
|
|
453
|
-
"lines":
|
|
452
|
+
"sha256": "1ecb73f5b1246c7157d782b62cba59850389858baeefdc5351a255d4d04b11b6",
|
|
453
|
+
"lines": 18,
|
|
454
454
|
"heading": "上传规则"
|
|
455
455
|
},
|
|
456
456
|
{
|
|
@@ -942,11 +942,11 @@
|
|
|
942
942
|
]
|
|
943
943
|
},
|
|
944
944
|
"microi-uniapp-frontend": {
|
|
945
|
-
"originalSha256": "
|
|
946
|
-
"originalLines":
|
|
947
|
-
"prefixSha256": "
|
|
948
|
-
"prefixBytes":
|
|
949
|
-
"entryLines":
|
|
945
|
+
"originalSha256": "a9e7ebb927e8be11a7d4d273f83b3a6f200835c2361daa944ec200d0580c3e2b",
|
|
946
|
+
"originalLines": 501,
|
|
947
|
+
"prefixSha256": "05053116f81ef9286c72590cd6c5670e3b38c594bf76fc5d41a32675f391d9a5",
|
|
948
|
+
"prefixBytes": 2988,
|
|
949
|
+
"entryLines": 192,
|
|
950
950
|
"chunks": [
|
|
951
951
|
{
|
|
952
952
|
"id": "microi-uniapp-frontend-000",
|
|
@@ -976,7 +976,7 @@
|
|
|
976
976
|
"id": "microi-uniapp-frontend-003",
|
|
977
977
|
"ordinal": 3,
|
|
978
978
|
"destination": "microi-uniapp-frontend/SKILL.md",
|
|
979
|
-
"sha256": "
|
|
979
|
+
"sha256": "5cedd05cb29746019a92db56a21123718fde23d5d9df4b8064dfc260bc89ee05",
|
|
980
980
|
"lines": 17,
|
|
981
981
|
"heading": "登录页与手机号快捷登录"
|
|
982
982
|
},
|
|
@@ -2221,11 +2221,11 @@
|
|
|
2221
2221
|
]
|
|
2222
2222
|
},
|
|
2223
2223
|
"v8-file-upload": {
|
|
2224
|
-
"originalSha256": "
|
|
2225
|
-
"originalLines":
|
|
2226
|
-
"prefixSha256": "
|
|
2227
|
-
"prefixBytes":
|
|
2228
|
-
"entryLines":
|
|
2224
|
+
"originalSha256": "69f7195bfeb618f0020da92535f47c8eb183d431cf16492a12f6f61dbcc7a851",
|
|
2225
|
+
"originalLines": 571,
|
|
2226
|
+
"prefixSha256": "796e8308ae21c36dde1b9268ae71ccb8c2afe9f393d7f9865b6648d2f7f0f22e",
|
|
2227
|
+
"prefixBytes": 8923,
|
|
2228
|
+
"entryLines": 226,
|
|
2229
2229
|
"chunks": [
|
|
2230
2230
|
{
|
|
2231
2231
|
"id": "v8-file-upload-000",
|
|
@@ -2247,7 +2247,7 @@
|
|
|
2247
2247
|
"id": "v8-file-upload-002",
|
|
2248
2248
|
"ordinal": 2,
|
|
2249
2249
|
"destination": "v8-file-upload/SKILL.md",
|
|
2250
|
-
"sha256": "
|
|
2250
|
+
"sha256": "ed7e727c51bd2416ae1f38cf3c4bd09491e616df08473a610372e0ca648e1298",
|
|
2251
2251
|
"lines": 101,
|
|
2252
2252
|
"heading": "接收前端上传的文件"
|
|
2253
2253
|
},
|
|
@@ -2271,8 +2271,8 @@
|
|
|
2271
2271
|
"id": "v8-file-upload-005",
|
|
2272
2272
|
"ordinal": 3,
|
|
2273
2273
|
"destination": "v8-file-upload/references/progressive-01-公有桶-vs-私有桶.md",
|
|
2274
|
-
"sha256": "
|
|
2275
|
-
"lines":
|
|
2274
|
+
"sha256": "b09a96f25aef20eb8cbb204bd785cce370dcd2c9a28563c6f6d720fbdaa5218f",
|
|
2275
|
+
"lines": 150,
|
|
2276
2276
|
"heading": "公有桶 vs 私有桶"
|
|
2277
2277
|
},
|
|
2278
2278
|
{
|
|
@@ -2295,7 +2295,7 @@
|
|
|
2295
2295
|
"id": "v8-file-upload-008",
|
|
2296
2296
|
"ordinal": 8,
|
|
2297
2297
|
"destination": "v8-file-upload/references/progressive-02-office-文件在线编辑版本号规则.md",
|
|
2298
|
-
"sha256": "
|
|
2298
|
+
"sha256": "5e3b59486745d3c54bd8ad25c43cbe2396e6d614394340b93d93794b6df56292",
|
|
2299
2299
|
"lines": 36,
|
|
2300
2300
|
"heading": "Office 文件在线编辑版本号规则"
|
|
2301
2301
|
},
|
|
@@ -2786,11 +2786,11 @@
|
|
|
2786
2786
|
]
|
|
2787
2787
|
},
|
|
2788
2788
|
"v8-security": {
|
|
2789
|
-
"originalSha256": "
|
|
2790
|
-
"originalLines":
|
|
2789
|
+
"originalSha256": "f3624718dfa642f4c3ab5d48a33022014aa467af1be756fdbc78c4bae2231d1c",
|
|
2790
|
+
"originalLines": 503,
|
|
2791
2791
|
"prefixSha256": "c3b2ae10a39461ee69fda3c7e994d072ca6d8c9dc6f2338742bc8f07e0dcffd0",
|
|
2792
2792
|
"prefixBytes": 1648,
|
|
2793
|
-
"entryLines":
|
|
2793
|
+
"entryLines": 190,
|
|
2794
2794
|
"chunks": [
|
|
2795
2795
|
{
|
|
2796
2796
|
"id": "v8-security-000",
|
|
@@ -2804,8 +2804,8 @@
|
|
|
2804
2804
|
"id": "v8-security-001",
|
|
2805
2805
|
"ordinal": 1,
|
|
2806
2806
|
"destination": "v8-security/SKILL.md",
|
|
2807
|
-
"sha256": "
|
|
2808
|
-
"lines":
|
|
2807
|
+
"sha256": "aad35b2c3e1876d98ead7e604307bcb7d39fe8c480d72f102ae956972580a35b",
|
|
2808
|
+
"lines": 19,
|
|
2809
2809
|
"heading": "0.5 接口引擎配置安全"
|
|
2810
2810
|
},
|
|
2811
2811
|
{
|
|
@@ -2860,7 +2860,7 @@
|
|
|
2860
2860
|
"id": "v8-security-008",
|
|
2861
2861
|
"ordinal": 8,
|
|
2862
2862
|
"destination": "v8-security/references/progressive-02-7-日志记录.md",
|
|
2863
|
-
"sha256": "
|
|
2863
|
+
"sha256": "6e0b7de3cd72cc030c93566c03ddf2191af6163d378e5ec8a40828eee9873477",
|
|
2864
2864
|
"lines": 40,
|
|
2865
2865
|
"heading": "7. 日志记录"
|
|
2866
2866
|
},
|
|
@@ -2868,7 +2868,7 @@
|
|
|
2868
2868
|
"id": "v8-security-009",
|
|
2869
2869
|
"ordinal": 9,
|
|
2870
2870
|
"destination": "v8-security/references/progressive-02-7-日志记录.md",
|
|
2871
|
-
"sha256": "
|
|
2871
|
+
"sha256": "b7a65ce2785a6a3d02dc1bc08c16c5ae03e38aa199d4bc204abe5978057f1ea1",
|
|
2872
2872
|
"lines": 20,
|
|
2873
2873
|
"heading": "8. 错误处理"
|
|
2874
2874
|
},
|
|
@@ -2876,7 +2876,7 @@
|
|
|
2876
2876
|
"id": "v8-security-010",
|
|
2877
2877
|
"ordinal": 10,
|
|
2878
2878
|
"destination": "v8-security/references/progressive-02-7-日志记录.md",
|
|
2879
|
-
"sha256": "
|
|
2879
|
+
"sha256": "4b68e2730cc6ac2ba8eeb4458c71e9ee157b9ac8054dcab364f364b2e0bd1c05",
|
|
2880
2880
|
"lines": 25,
|
|
2881
2881
|
"heading": "9. Token、终端会话与租户隔离"
|
|
2882
2882
|
},
|
|
@@ -2884,7 +2884,7 @@
|
|
|
2884
2884
|
"id": "v8-security-011",
|
|
2885
2885
|
"ordinal": 11,
|
|
2886
2886
|
"destination": "v8-security/references/progressive-02-7-日志记录.md",
|
|
2887
|
-
"sha256": "
|
|
2887
|
+
"sha256": "78053ef853bdffb4eaad90354204555d836d67b9a18f2a6c0ac74a0142df2794",
|
|
2888
2888
|
"lines": 11,
|
|
2889
2889
|
"heading": "10. Jint 运行时升级边界"
|
|
2890
2890
|
},
|
|
@@ -2892,7 +2892,7 @@
|
|
|
2892
2892
|
"id": "v8-security-012",
|
|
2893
2893
|
"ordinal": 12,
|
|
2894
2894
|
"destination": "v8-security/references/progressive-02-7-日志记录.md",
|
|
2895
|
-
"sha256": "
|
|
2895
|
+
"sha256": "f7ac9ee1702759fbf5b256ef7b7069ebce75cb845b59786d4eab928335001bf6",
|
|
2896
2896
|
"lines": 30,
|
|
2897
2897
|
"heading": "安全检查清单"
|
|
2898
2898
|
},
|
|
@@ -2900,7 +2900,7 @@
|
|
|
2900
2900
|
"id": "v8-security-013",
|
|
2901
2901
|
"ordinal": 13,
|
|
2902
2902
|
"destination": "v8-security/references/progressive-02-7-日志记录.md",
|
|
2903
|
-
"sha256": "
|
|
2903
|
+
"sha256": "809cd12c1b5fbba76a0b09ebbddf5d2e34189d26ee510c285389294c35b91176",
|
|
2904
2904
|
"lines": 22,
|
|
2905
2905
|
"heading": "浏览器访问密钥"
|
|
2906
2906
|
}
|
|
@@ -74,12 +74,12 @@ Microi API 安装时,`AppSettings` 与同名容器环境变量只允许以下
|
|
|
74
74
|
- 每次修改 `数据库、案例、文档、资料/install-microi.sh`,必须同时更新文件头版本和 `SCRIPT_VERSION`,两处完全一致。
|
|
75
75
|
- 固定格式为 `vYYYY-MM-DD HH:mm:ss`,使用 `Asia/Shanghai` 时间并精确到秒;禁止只写日期或沿用上一次修改时间。
|
|
76
76
|
- 验收同时断言两处版本一致、格式正确,并以脚本实际启动输出为准;官网静态地址尚未发布新文件时,不能把本地版本误报为客户已经可下载。
|
|
77
|
-
- 恢复旧数据库时,OCR
|
|
77
|
+
- 恢复旧数据库时,OCR、翻译等附加字段先出现不代表完整升级链已经成功。安装器必须先回读 `sys_config.ServerVersion` 达到本脚本最低版本并通过 API liveness/readiness,才能部署和配置附加能力;核心中间迁移失败或超时应失败关闭,禁止用部分字段就绪冒充整个平台升级成功,也禁止在升级事务仍执行时主动重启 API。
|
|
78
78
|
- Compose v2 生成文件不再写顶层 `version`;所有模板直接以 `services:` 开始,避免 `the attribute version is obsolete` 告警。
|
|
79
79
|
- LibreTranslate 属于一键安装默认组件:安装选择空输入按 `1` 处理,语言套餐空输入按基础套餐 `1` 处理;因此用户一路按 Enter 使用官方推荐组合。只有明确输入 `0` 才跳过,提示、端口预算、官网文档和静态回归测试必须一致。
|
|
80
|
-
- OCR 的 Upgrade29 与 LibreTranslate 的 Upgrade31
|
|
80
|
+
- OCR 的 Upgrade29 与 LibreTranslate 的 Upgrade31 字段门禁只在对应附加服务部署检查通过后回读,每秒一次、最多 15 秒;首轮成功就继续,超时快速关闭对应能力并提示镜像/迁移版本,不得退回 5 分钟空等,也不得直接创建字段绕过平台升级。附加能力门禁失败不得中断已通过完整升级链和 readiness 的核心平台。
|
|
81
81
|
- 官方 API/Web 使用浮动 `latest` 时,生成的 Compose 必须设置 `pull_policy: always` 或在启动前显式拉取并核对,不能因宿主机已有同名镜像就复用旧版本;测试专用本机镜像覆盖必须明确使用 `never`,避免误访问或覆盖远端镜像。
|
|
82
|
-
-
|
|
82
|
+
- 端口、密码和数据目录全部生成后,安装器必须注册统一的失败收尾:数据库、缓存、存储、API/Web、完整升级链或 API liveness/readiness 等核心后段错误保留原始非零退出码,并输出标题为“安装未完成”的恢复汇总,列出已生成端口、凭据、目录、失败阶段和全部容器状态。OCR/LibreTranslate 的网络、镜像、容器或 SaaS 配置失败只记录附加能力警告、保持对应能力未启用并继续核心安装。两种结果都不得把 `Running` 当 readiness,也不得绕过 Upgrade29/Upgrade31 或完整升级链门禁。
|
|
83
83
|
- 从客户/旧库恢复安装时,安装器只按 `OsClient + OsClientType + OsClientNetwork + IsEnable + IsDeleted` 处理目标主租户:0 条时幂等创建最小可运行记录,1 条时原位复用,超过 1 条失败关闭。禁止把所有活动 `sys_osclients` 批量改成输入的 OsClient;新记录不得落库 `DbConn/DbReadConn/DbMongoConnection` 或 Redis 主机、端口、密码,这些继续由十项编排启动配置提供。MinIO、OCR 等安装值随后只更新这个精确三元组并回读唯一性。
|
|
84
84
|
|
|
85
85
|
## 多节点与滚动发布
|
|
@@ -57,8 +57,11 @@ Config/Data、菜单查询列与缓存保持一致。
|
|
|
57
57
|
图片默认压缩到约 500 KB、最长边 1920 px。
|
|
58
58
|
- 私有富文本只能持久化稳定对象标识,禁止把 HDFS 签名 URL、审计代理 Ticket 或 DiyToken 写入
|
|
59
59
|
HTML。每次查看/编辑按当前菜单、表、记录和字段权限换取新短效地址;外部匿名页面没有此权限
|
|
60
|
-
上下文,因此不能把私有 RichText
|
|
61
|
-
|
|
60
|
+
上下文,因此不能把私有 RichText 当作公开正文。普通用户通过当前表单新增/编辑授权后,后端
|
|
61
|
+
必须回读 `diy_field.Config.RichText.Limit` 决定公私桶;只改请求 `Limit=false` 不能绕过字段配置。
|
|
62
|
+
- 图片、文件和富文本上传必须携带 `FormEngineKey + FieldId + SysMenuId`,编辑记录再带
|
|
63
|
+
`FormDataId`,TableChild 再带父子授权上下文。后端不得按用户等级统一覆盖字段的“禁止匿名访问”;
|
|
64
|
+
无法回查字段与动作权限的普通上传才安全降级为私有桶。
|
|
62
65
|
|
|
63
66
|
新建表/模块时,除非用户显式指定或表单达到极重阈值(约 36+ 业务字段、2+ 子表或同等
|
|
64
67
|
重型控件密度),默认保存 `diy_table.FormOpenType=Dialog` 与 `FormOpenWidth=80%`。
|
|
@@ -178,7 +178,7 @@ if (V8.LoadMode !== 'Design') {
|
|
|
178
178
|
}
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
-
- `Limit=true` 表示字段配置为私有桶,`false`
|
|
181
|
+
- `Limit=true` 表示字段配置为私有桶,`false` 表示配置为公有桶。普通用户有当前表单新增/编辑权限时也按此权威配置执行;运行时提交表、字段、菜单、记录上下文,后端回读 `diy_field.Config`,不得信任客户端 `Limit/Path`,也不得按用户等级统一强制私有。
|
|
182
182
|
- `Multiple=true` 时 `MaxCount` 必须是正整数;`MaxSize` 单位为 MB。`Preview` 未配置时按 `true` 压缩,普通列表、卡片、商品图不要关闭。
|
|
183
183
|
- `Crop.Enabled` 只决定运行时裁剪开关的初始状态;`false` 或缺失时用户仍可在紧凑上传面板主动开启。裁剪前原图始终进入 HDFS 私有桶,业务字段只保存展示图元数据。
|
|
184
184
|
- 图片和文件都把拖放提示、存储范围、单/多文件、最大数量、处理方式和最大体积合并到同一个紧凑面板;不要在字段外再生成重复说明卡片。
|
|
@@ -205,6 +205,7 @@ if (V8.LoadMode !== 'Design') {
|
|
|
205
205
|
```
|
|
206
206
|
|
|
207
207
|
- 公开公告、商品详情等匿名网页内容显式用 `Limit=false`;内部公告、合同说明等用 `true`。旧字段缺失时默认私有,不能由 AI 猜成公有。
|
|
208
|
+
- 普通用户经当前表单新增/编辑授权后可以发布公有 RichText;后端按字段权威配置选择桶。缺少 `FormEngineKey/FieldId` 等可验证上下文的普通上传仍保持私有,不能用裸 `Limit=false` 代替授权。
|
|
208
209
|
- `MaxSize` 单位 MB,`CompressMaxSize` 单位 KB。图片压缩开启时原图仍先进入 HDFS 私有桶,正文只引用展示图。
|
|
209
210
|
- 私有正文只保存 `/__microi_richtext_private__/...` 稳定标识;运行时携带当前菜单、表、记录和字段上下文换取短效代理 URL,禁止把临时 Token/Ticket 回写字段。
|
|
210
211
|
- 普通文件通过富文本工具栏附件入口插入 `a.href`;私有授权只接受真实 `img/video/source.src` 与 `a.href` 的精确路径,不接受正文文字、`data-*` 或脚本标签。
|
|
@@ -71,7 +71,7 @@ export function createApp() {
|
|
|
71
71
|
`Microi.Client` 主后台运行时已内置前后端同构的 `V8.Http.Get/Post/Patch` 及对应 Response 方法;表单事件、按钮 V8 等宿主前端新代码必须优先使用 `V8.Http`,旧 `V8.Post/Get` 仅作兼容保留,其参数和兼容规则以 `v8-http-integration/SKILL.md` 为准。独立项目使用本 SDK、且不在主后台 V8 宿主中时,才使用 SDK 自身的小写 `V8.get/post`、`ApiEngine`、`FormEngine`;不要把它们与宿主旧版大写 `V8.Post/Get` 混为一谈,也不要假设浏览器可以绕过第三方接口的 CORS。
|
|
72
72
|
|
|
73
73
|
<!-- /microi-progressive:chunk -->
|
|
74
|
-
<!-- microi-progressive:chunk id=microi-frontend-sdk-002 sha256=
|
|
74
|
+
<!-- microi-progressive:chunk id=microi-frontend-sdk-002 sha256=b71205548e4701f8bf53e2bed3da914da4ca0f49e0cce952a1c938fc77218ed8 -->
|
|
75
75
|
## 登录与验证码封装
|
|
76
76
|
|
|
77
77
|
SDK 或项目请求模块必须提供登录所需的系统配置和验证码薄封装,不要让页面散落手写。
|
|
@@ -132,15 +132,16 @@ SDK 的 `buildHeaders` 必须集中处理所有请求头,不能让页面、业
|
|
|
132
132
|
- 验收时检查真实网络请求:不得出现 `osclient: demo, demo`、`Authorization: Bearer xxx, Bearer xxx` 这类逗号合并值。
|
|
133
133
|
|
|
134
134
|
<!-- /microi-progressive:chunk -->
|
|
135
|
-
<!-- microi-progressive:chunk id=microi-frontend-sdk-004 sha256=
|
|
135
|
+
<!-- microi-progressive:chunk id=microi-frontend-sdk-004 sha256=1ecb73f5b1246c7157d782b62cba59850389858baeefdc5351a255d4d04b11b6 -->
|
|
136
136
|
## 上传规则
|
|
137
137
|
|
|
138
138
|
`V8.uploadFile` 是 Microi 前端唯一允许的上传入口。SDK 实现必须:
|
|
139
139
|
|
|
140
140
|
- 使用 multipart 上传头。`uni.uploadFile` 或 `fetch(FormData)` 不得发送 `Content-Type: application/json`。
|
|
141
141
|
- 租户请求头只发送一个键:`osclient`。添加配置租户前,先移除传入的 `osclient` / `OsClient` 重复键。
|
|
142
|
-
- `formData` 中发送 `OsClient`;开启 `appendOsClientQuery` 时保留接口查询参数 `?OsClient=tenant`。
|
|
143
|
-
-
|
|
142
|
+
- `formData` 中发送 `OsClient`;开启 `appendOsClientQuery` 时保留接口查询参数 `?OsClient=tenant`。
|
|
143
|
+
- 标准表单的 `ImgUpload`、`FileUpload`、`RichText` 必须通过 `formFieldContext`(或等价 `formData`)发送 `FormEngineKey + FieldId + SysMenuId`;编辑已有记录再传 `FormDataId`,TableChild 再传 JSON 化的 `_TableChildAuth`。服务端以当前租户字段配置和 FormEngine 动作授权决定实际 `Limit/Path`,SDK 不能按帐号等级强制私有,也不能信任页面传入的 `Limit=false`。
|
|
144
|
+
- 上传 `Path` 统一从 `options.path`、`formData.Path` 或 `formData.path` 归一化。
|
|
144
145
|
- 移动端上传路径必须是安全相对路径,例如 `mall/pay-proof` 或 `mall/member/avatar`。不要使用 `/mall/pay-proof`、完整 URL、磁盘路径、`..`、`:`、`//` 或 `~`。
|
|
145
146
|
- 项目薄封装要通过 `{ ...options, path: options.path || defaultPath }` 透传全部选项,避免丢失页面级 `headers`、`action`、`anonymous`、`file`、`formData` 和 `silentError`。
|
|
146
147
|
- H5 页面要保留 `uni.chooseImage` 返回的真实 `File` 对象(可用时为 `tempFiles[0].file`)。如果 H5 只返回 `tempFiles[0]` 或 `blob:` / `data:` 临时路径,也要继续传入,不要丢弃。调用 `V8.uploadFile(..., { file, preferFetch:true })`。SDK 必须识别 `File` / `Blob`、`file` / `raw` / `blob` / `originFileObj` 等常见嵌套字段,以及 `blob:` / `data:` 路径,然后优先使用 `fetch + FormData`,必要时在 `uni.uploadFile` 与 fetch 之间回退。
|
|
@@ -13,6 +13,8 @@ description: Microi 吾码 UniApp/H5 前端通用规范。用于构建或修复
|
|
|
13
13
|
|
|
14
14
|
UniApp/H5/小程序必须通过项目统一 `microi.v8.js` 的 `V8.uploadFile` / `V8.uploadFiles` 上传图片。调用方省略 `options.preview` 时,SDK 必须发送 `Preview=true` 并默认使用 `img` 路径;只有显式 `preview:false` 才允许关闭。服务端仍是最终事实源:即使旧客户端完全不传该字段,也要默认压缩到约 `500 KB`、最长边约 `1920 px`,并在 HDFS 私有桶保留一份 `_origin` 原图。页面不得为了“上传成功”自行改成 `preview:false`,也不得把私有原图或临时签名地址保存进业务字段。
|
|
15
15
|
|
|
16
|
+
动态表单上传还必须把控件已有的文件访问上下文透传为 `formFieldContext`:至少包含 `FormEngineKey + FieldId + SysMenuId`,编辑时再带 `FormDataId`,TableChild 再带 `_TableChildAuth`。后端回读 `diy_field.Config` 后决定“禁止匿名访问”与真实桶;普通用户不能被一刀切为私有桶,客户端自己传 `Limit=false` 也不能放宽私有字段。没有字段上下文的聊天、打卡、临时业务上传仍按普通私有上传处理。
|
|
17
|
+
|
|
16
18
|
## 平台方通用 App 登录连接器(明确例外)
|
|
17
19
|
|
|
18
20
|
登录页默认不得展示 ApiBase、OsClient 或调试配置;但用户明确要求、且安装包由 Microi 平台方作为多租户聚合客户端发布时,允许仅在 `APP-PLUS` 登录页提供通用连接器。协议必须使用固定 `https://` / `http://` 下拉框,地址框禁止重复输入协议,HTTPS 默认,HTTP 显示明文风险并二次确认;H5、小程序和客户专属包不得因此自动开放。候选地址先匿名读取 `GetSysConfig`,验证成功后再持久化。真正切换时必须清除旧 DiyToken、用户、SignalR、菜单/元数据/页面缓存,按 `ApiBase + OsClient` 隔离记住的账号及 RSA 密文,并用端点代次拒绝切换前的迟到响应。支持任意 HTTP 时,最终 IPA 必须显式包含 ATS 例外,Android 安装包必须显式包含 cleartext 例外;不需要任意 HTTP 的正式包应保持平台默认安全策略,iOS ATS 例外还必须在 App Store 审核中说明。
|
|
@@ -55,7 +57,7 @@ Microi 标准小程序必须采用“平台内核 + 版本化元数据 + Profile
|
|
|
55
57
|
- 自动化验收必须同时使用桌面视口与移动视口截图:桌面端断言手机壳存在,移动端断言 `.phone-status` 隐藏且 `.phone` 无圆角、无边框、宽高铺满;每个底部菜单的图标元素和文字都必须可见、可点击。
|
|
56
58
|
|
|
57
59
|
<!-- /microi-progressive:chunk -->
|
|
58
|
-
<!-- microi-progressive:chunk id=microi-uniapp-frontend-003 sha256=
|
|
60
|
+
<!-- microi-progressive:chunk id=microi-uniapp-frontend-003 sha256=5cedd05cb29746019a92db56a21123718fde23d5d9df4b8064dfc260bc89ee05 -->
|
|
59
61
|
## 登录页与手机号快捷登录
|
|
60
62
|
|
|
61
63
|
- 登录页必须是直接登录面,不要默认做“员工登录 / 客户登录”身份 Tab 切换,除非用户明确要求。默认展示系统账号密码登录,同时提供客户手机号快捷登录入口。
|
package/skills/microi.v8.js
CHANGED
|
@@ -188,14 +188,14 @@ function normalizeUploadValue(value) {
|
|
|
188
188
|
return [text];
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
function normalizeUploadData(body) {
|
|
192
|
-
const raw = Array.isArray(body && body.Data) ? (body.Data[0] || {}) : ((body && body.Data) || {});
|
|
193
|
-
const path = raw.Path || raw.FilePathName || raw.FilePath || raw.FullPath || raw.Url || raw.FileUrl || '';
|
|
194
|
-
const url = raw.Url || raw.FileUrl || raw.FileURL || raw.PreviewUrl || raw.PreviewURL || '';
|
|
195
|
-
return { ...raw, Path: path, Url: url };
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
function normalizeClientUploadPath(value) {
|
|
191
|
+
function normalizeUploadData(body) {
|
|
192
|
+
const raw = Array.isArray(body && body.Data) ? (body.Data[0] || {}) : ((body && body.Data) || {});
|
|
193
|
+
const path = raw.Path || raw.FilePathName || raw.FilePath || raw.FullPath || raw.Url || raw.FileUrl || '';
|
|
194
|
+
const url = raw.Url || raw.FileUrl || raw.FileURL || raw.PreviewUrl || raw.PreviewURL || '';
|
|
195
|
+
return { ...raw, Path: path, Url: url };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function normalizeClientUploadPath(value) {
|
|
199
199
|
let path = String(value || 'upload').trim().replace(/\\/g, '/');
|
|
200
200
|
if (/^(https?:|data:|blob:|file:)/i.test(path)) throw new Error('上传路径不合法。');
|
|
201
201
|
path = path.replace(/^\/+/, '').replace(/\/+$/, '').replace(/\/{2,}/g, '/');
|
|
@@ -209,30 +209,30 @@ function normalizeClientUploadPath(value) {
|
|
|
209
209
|
return parts.join('/');
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
function normalizeFileUrlData(data, assetUrl, fallback = '') {
|
|
212
|
+
function normalizeFileUrlData(data, assetUrl, fallback = '') {
|
|
213
213
|
const raw = Array.isArray(data) ? (data[0] || '') : (data || '');
|
|
214
214
|
if (typeof raw === 'string') return assetUrl(raw || fallback);
|
|
215
215
|
const url = raw.Url || raw.FileUrl || raw.FileURL || raw.PreviewUrl || raw.PreviewURL || raw.FullUrl || '';
|
|
216
216
|
const path = raw.Path || raw.FilePathName || raw.FilePath || raw.FullPath || '';
|
|
217
217
|
return assetUrl(url || path || fallback);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function isLocalPackagedAsset(path) {
|
|
221
|
-
return /^(?:\.\/)?\/?static\//i.test(String(path || ''));
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function hasPublicUploadFlag(value) {
|
|
225
|
-
if (!value || typeof value !== 'object') return false;
|
|
226
|
-
const raw = Array.isArray(value) ? (value[0] || {}) : value;
|
|
227
|
-
return raw.Limit === false || raw.Limit === 0 || String(raw.Limit).toLowerCase() === 'false' ||
|
|
228
|
-
raw.IsPrivate === false || raw.Private === false || raw.Public === true;
|
|
229
|
-
}
|
|
230
|
-
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function isLocalPackagedAsset(path) {
|
|
221
|
+
return /^(?:\.\/)?\/?static\//i.test(String(path || ''));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function hasPublicUploadFlag(value) {
|
|
225
|
+
if (!value || typeof value !== 'object') return false;
|
|
226
|
+
const raw = Array.isArray(value) ? (value[0] || {}) : value;
|
|
227
|
+
return raw.Limit === false || raw.Limit === 0 || String(raw.Limit).toLowerCase() === 'false' ||
|
|
228
|
+
raw.IsPrivate === false || raw.Private === false || raw.Public === true;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
231
|
function isKnownPublicUploadPath(path) {
|
|
232
232
|
// Ordinary form uploads such as /xjy/img and /xjy/file are private by default.
|
|
233
233
|
// They must use the Managed signer instead of being mistaken for CDN assets.
|
|
234
|
-
return /^\/?(?:public|mci-public|xjy\/xjy\/miniapp-assets|xjy\/miniapp\/share)\//i.test(String(path || ''));
|
|
235
|
-
}
|
|
234
|
+
return /^\/?(?:public|mci-public|xjy\/xjy\/miniapp-assets|xjy\/miniapp\/share)\//i.test(String(path || ''));
|
|
235
|
+
}
|
|
236
236
|
|
|
237
237
|
function getHeaderValue(headers, key) {
|
|
238
238
|
if (!headers) return '';
|
|
@@ -935,12 +935,12 @@ export function createMicroiV8(options = {}) {
|
|
|
935
935
|
}
|
|
936
936
|
|
|
937
937
|
// 资源地址统一过滤占位图,并兼容 HDFS 私有文件、FileServer 和绝对地址。
|
|
938
|
-
function assetUrl(value) {
|
|
938
|
+
function assetUrl(value) {
|
|
939
939
|
const picked = extractUploadPath(value);
|
|
940
940
|
if (!picked || isBlockedAsset(picked)) return '';
|
|
941
941
|
if (/^(https?:|data:|blob:|file:)/i.test(picked)) return picked;
|
|
942
|
-
if (isLocalPackagedAsset(picked)) return picked;
|
|
943
|
-
if (/^\/?file\//i.test(picked)) return joinUrl(config.apiBase, picked);
|
|
942
|
+
if (isLocalPackagedAsset(picked)) return picked;
|
|
943
|
+
if (/^\/?file\//i.test(picked)) return joinUrl(config.apiBase, picked);
|
|
944
944
|
if (/^\//.test(picked) || /^[a-z0-9_-]+\//i.test(picked)) return joinUrl(config.fileServer || config.apiBase, picked);
|
|
945
945
|
return picked;
|
|
946
946
|
}
|
|
@@ -949,59 +949,59 @@ export function createMicroiV8(options = {}) {
|
|
|
949
949
|
return config.blockedAssetPattern ? config.blockedAssetPattern.test(String(value || '')) : false;
|
|
950
950
|
}
|
|
951
951
|
|
|
952
|
-
function hasPrivateFileAccessContext(options = {}) {
|
|
953
|
-
const resourceKind = String(options.resourceKind || options.ResourceKind || 'FormField').trim();
|
|
954
|
-
const resourceId = String(options.resourceId || options.ResourceId || '').trim();
|
|
955
|
-
const formEngineKey = String(options.formEngineKey || options.FormEngineKey || '').trim();
|
|
956
|
-
const formDataId = String(options.formDataId || options.FormDataId || '').trim();
|
|
957
|
-
const fieldId = String(options.fieldId || options.FieldId || '').trim();
|
|
958
|
-
const sysMenuId = String(options.sysMenuId || options.SysMenuId || options.menuId || options.MenuId || '').trim();
|
|
959
|
-
const formFieldReady = Boolean(formEngineKey && formDataId && fieldId && sysMenuId);
|
|
960
|
-
|
|
961
|
-
if (resourceKind === 'UserAvatar' || resourceKind === 'MenuImportTemplate' || resourceKind === 'DeptImportTemplate') {
|
|
962
|
-
return Boolean(resourceId);
|
|
963
|
-
}
|
|
964
|
-
if (resourceKind === 'FileManagerObject') return Boolean(resourceId && sysMenuId);
|
|
965
|
-
if (resourceKind === 'FormFieldDerivedPreview') {
|
|
966
|
-
return formFieldReady && Boolean(options.originalFilePathName || options.OriginalFilePathName);
|
|
967
|
-
}
|
|
968
|
-
return resourceKind === 'FormField' && formFieldReady;
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
async function resolveFileUrl(filePathName, options = {}) {
|
|
972
|
-
const path = extractUploadPath(filePathName);
|
|
973
|
-
if (!path || isBlockedAsset(path)) return '';
|
|
974
|
-
if (/^(https?:|blob:|data:|file:)/i.test(path)) return assetUrl(path);
|
|
975
|
-
if (isLocalPackagedAsset(path) || options.private === false || hasPublicUploadFlag(filePathName) || isKnownPublicUploadPath(path)) {
|
|
976
|
-
return assetUrl(path);
|
|
977
|
-
}
|
|
978
|
-
// 私有对象没有权威资源上下文时直接失败关闭,禁止以裸路径换取签名。
|
|
979
|
-
if (!hasPrivateFileAccessContext(options)) return '';
|
|
980
|
-
|
|
981
|
-
async function requestPrivateFileUrl() {
|
|
982
|
-
try {
|
|
983
|
-
const body = await apiEngineRun('platform-private-file-url', {
|
|
984
|
-
OsClient: config.osClient,
|
|
985
|
-
FilePathName: path,
|
|
986
|
-
FormEngineKey: options.formEngineKey || options.FormEngineKey,
|
|
987
|
-
FormDataId: options.formDataId || options.FormDataId,
|
|
988
|
-
FieldId: options.fieldId || options.FieldId,
|
|
989
|
-
SysMenuId: options.sysMenuId || options.SysMenuId || options.menuId || options.MenuId,
|
|
990
|
-
ResourceKind: options.resourceKind || options.ResourceKind,
|
|
991
|
-
ResourceId: options.resourceId || options.ResourceId,
|
|
992
|
-
OriginalFilePathName: options.originalFilePathName || options.OriginalFilePathName,
|
|
993
|
-
_TableChildAuth: options.tableChildAuth || options._TableChildAuth,
|
|
994
|
-
HDFS: options.hdfs || options.HDFS
|
|
995
|
-
}, {
|
|
996
|
-
checkCode: false,
|
|
997
|
-
silentError: true
|
|
998
|
-
});
|
|
999
|
-
if (body && body.Code === 1 && body.Data) return normalizeFileUrlData(body.Data, assetUrl, path);
|
|
952
|
+
function hasPrivateFileAccessContext(options = {}) {
|
|
953
|
+
const resourceKind = String(options.resourceKind || options.ResourceKind || 'FormField').trim();
|
|
954
|
+
const resourceId = String(options.resourceId || options.ResourceId || '').trim();
|
|
955
|
+
const formEngineKey = String(options.formEngineKey || options.FormEngineKey || '').trim();
|
|
956
|
+
const formDataId = String(options.formDataId || options.FormDataId || '').trim();
|
|
957
|
+
const fieldId = String(options.fieldId || options.FieldId || '').trim();
|
|
958
|
+
const sysMenuId = String(options.sysMenuId || options.SysMenuId || options.menuId || options.MenuId || '').trim();
|
|
959
|
+
const formFieldReady = Boolean(formEngineKey && formDataId && fieldId && sysMenuId);
|
|
960
|
+
|
|
961
|
+
if (resourceKind === 'UserAvatar' || resourceKind === 'MenuImportTemplate' || resourceKind === 'DeptImportTemplate') {
|
|
962
|
+
return Boolean(resourceId);
|
|
963
|
+
}
|
|
964
|
+
if (resourceKind === 'FileManagerObject') return Boolean(resourceId && sysMenuId);
|
|
965
|
+
if (resourceKind === 'FormFieldDerivedPreview') {
|
|
966
|
+
return formFieldReady && Boolean(options.originalFilePathName || options.OriginalFilePathName);
|
|
967
|
+
}
|
|
968
|
+
return resourceKind === 'FormField' && formFieldReady;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
async function resolveFileUrl(filePathName, options = {}) {
|
|
972
|
+
const path = extractUploadPath(filePathName);
|
|
973
|
+
if (!path || isBlockedAsset(path)) return '';
|
|
974
|
+
if (/^(https?:|blob:|data:|file:)/i.test(path)) return assetUrl(path);
|
|
975
|
+
if (isLocalPackagedAsset(path) || options.private === false || hasPublicUploadFlag(filePathName) || isKnownPublicUploadPath(path)) {
|
|
976
|
+
return assetUrl(path);
|
|
977
|
+
}
|
|
978
|
+
// 私有对象没有权威资源上下文时直接失败关闭,禁止以裸路径换取签名。
|
|
979
|
+
if (!hasPrivateFileAccessContext(options)) return '';
|
|
980
|
+
|
|
981
|
+
async function requestPrivateFileUrl() {
|
|
982
|
+
try {
|
|
983
|
+
const body = await apiEngineRun('platform-private-file-url', {
|
|
984
|
+
OsClient: config.osClient,
|
|
985
|
+
FilePathName: path,
|
|
986
|
+
FormEngineKey: options.formEngineKey || options.FormEngineKey,
|
|
987
|
+
FormDataId: options.formDataId || options.FormDataId,
|
|
988
|
+
FieldId: options.fieldId || options.FieldId,
|
|
989
|
+
SysMenuId: options.sysMenuId || options.SysMenuId || options.menuId || options.MenuId,
|
|
990
|
+
ResourceKind: options.resourceKind || options.ResourceKind,
|
|
991
|
+
ResourceId: options.resourceId || options.ResourceId,
|
|
992
|
+
OriginalFilePathName: options.originalFilePathName || options.OriginalFilePathName,
|
|
993
|
+
_TableChildAuth: options.tableChildAuth || options._TableChildAuth,
|
|
994
|
+
HDFS: options.hdfs || options.HDFS
|
|
995
|
+
}, {
|
|
996
|
+
checkCode: false,
|
|
997
|
+
silentError: true
|
|
998
|
+
});
|
|
999
|
+
if (body && body.Code === 1 && body.Data) return normalizeFileUrlData(body.Data, assetUrl, path);
|
|
1000
1000
|
} catch (e) {}
|
|
1001
1001
|
return '';
|
|
1002
1002
|
}
|
|
1003
1003
|
|
|
1004
|
-
return (await requestPrivateFileUrl()) || '';
|
|
1004
|
+
return (await requestPrivateFileUrl()) || '';
|
|
1005
1005
|
}
|
|
1006
1006
|
|
|
1007
1007
|
// 文件上传同时支持 uni.uploadFile 与浏览器 fetch/FormData。
|
|
@@ -1009,9 +1009,9 @@ export function createMicroiV8(options = {}) {
|
|
|
1009
1009
|
const runtimeUni = getUni();
|
|
1010
1010
|
const action = options.action || (options.anonymous ? 'UniappUploadAnonymous' : 'UniappUpload');
|
|
1011
1011
|
const rawFormData = options.formData || {};
|
|
1012
|
-
const uploadData = {
|
|
1013
|
-
...rawFormData,
|
|
1014
|
-
OsClient: config.osClient,
|
|
1012
|
+
const uploadData = {
|
|
1013
|
+
...rawFormData,
|
|
1014
|
+
OsClient: config.osClient,
|
|
1015
1015
|
Limit: options.limit === false ? 'false' : 'true',
|
|
1016
1016
|
Preview: options.preview === false ? 'false' : 'true',
|
|
1017
1017
|
Multiple: options.multiple ? 'true' : 'false'
|
|
@@ -1291,7 +1291,7 @@ export function createMicroiV8(options = {}) {
|
|
|
1291
1291
|
|
|
1292
1292
|
function legacyGetCurrentUser(refresh, callback) {
|
|
1293
1293
|
if (refresh) {
|
|
1294
|
-
legacyPost('/apiengine/platform-current-user', {}, (result) => {
|
|
1294
|
+
legacyPost('/apiengine/platform-current-user', {}, (result) => {
|
|
1295
1295
|
if (result && result.Code) legacySetCurrentUser(result.Data || {});
|
|
1296
1296
|
if (typeof callback === 'function') callback(result);
|
|
1297
1297
|
});
|
|
@@ -1538,7 +1538,7 @@ export function createMicroiV8(options = {}) {
|
|
|
1538
1538
|
// 旧版前端 V8 依赖的后端接口路径,保留原名称以减少迁移成本。
|
|
1539
1539
|
const legacyApi = {
|
|
1540
1540
|
MicroiInit: '/apiengine/microi-init',
|
|
1541
|
-
GetSysConfig: '/apiengine/platform-sys-config',
|
|
1541
|
+
GetSysConfig: '/apiengine/platform-sys-config',
|
|
1542
1542
|
Login: '/api/SysUser/login',
|
|
1543
1543
|
AddFormData: '/api/FormEngine/addFormData',
|
|
1544
1544
|
AddFormDataBatch: '/api/FormEngine/addFormDataBatch',
|
|
@@ -1555,17 +1555,17 @@ export function createMicroiV8(options = {}) {
|
|
|
1555
1555
|
GetTableDataTree: '/api/FormEngine/getTableDataTree',
|
|
1556
1556
|
GetTableDataTreeAnonymous: '/api/FormEngine/getTableDataTreeAnonymous',
|
|
1557
1557
|
ApiEngineRun: '/api/ApiEngine/run',
|
|
1558
|
-
ModuleEngineRun: '/apiengine/platform-module-data',
|
|
1558
|
+
ModuleEngineRun: '/apiengine/platform-module-data',
|
|
1559
1559
|
RefreshToken: '/api/SysUser/refreshToken',
|
|
1560
1560
|
RefreshLoginUser: '/api/SysUser/refreshLoginUser',
|
|
1561
1561
|
Upload: '/api/HDFS/Upload',
|
|
1562
1562
|
UploadAnonymous: '/api/HDFS/uploadAnonymous',
|
|
1563
1563
|
UniappUpload: '/api/HDFS/UniappUpload',
|
|
1564
1564
|
UniappUploadAnonymous: '/api/HDFS/uniappUploadAnonymous',
|
|
1565
|
-
GetCurrentUser: '/apiengine/platform-current-user',
|
|
1565
|
+
GetCurrentUser: '/apiengine/platform-current-user',
|
|
1566
1566
|
GetDateTimeNow: '/api/os/getDateTimeNow',
|
|
1567
|
-
AddSysLog: '/apiengine/platform-client-log',
|
|
1568
|
-
GetOsClientByDomain: '/apiengine/platform-os-client-by-domain',
|
|
1567
|
+
AddSysLog: '/apiengine/platform-client-log',
|
|
1568
|
+
GetOsClientByDomain: '/apiengine/platform-os-client-by-domain',
|
|
1569
1569
|
ApiEngine: {}
|
|
1570
1570
|
};
|
|
1571
1571
|
|
|
@@ -1816,7 +1816,7 @@ export function createMicroiV8(options = {}) {
|
|
|
1816
1816
|
? { ModuleEngineKey: moduleKeyOrParam, ...(dataOrCallback || {}) }
|
|
1817
1817
|
: (moduleKeyOrParam || {});
|
|
1818
1818
|
const cb = typeof dataOrCallback === 'function' ? dataOrCallback : callback;
|
|
1819
|
-
return withCallback(legacyPost(legacyApi.ModuleEngineRun, { Action: 'GetTableData', ...data }), cb);
|
|
1819
|
+
return withCallback(legacyPost(legacyApi.ModuleEngineRun, { Action: 'GetTableData', ...data }), cb);
|
|
1820
1820
|
}
|
|
1821
1821
|
};
|
|
1822
1822
|
|