weaver-work-cli 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/README.md +14 -9
  2. package/dist/cmd/skills/index.js +60 -0
  3. package/dist/internal/e10/auth/commands.js +48 -32
  4. package/dist/internal/e10/auth/session.js +44 -3
  5. package/dist/internal/e10/auth/xiaoe.js +363 -11
  6. package/dist/internal/e10/context.js +4 -2
  7. package/dist/internal/skills/detector.js +42 -0
  8. package/dist/internal/skills/install.js +50 -3
  9. package/dist/shortcuts/archive/render/search-format.js +12 -3
  10. package/dist/shortcuts/ebuilder-form/continuation.js +70 -0
  11. package/dist/shortcuts/ebuilder-form/errors.js +54 -0
  12. package/dist/shortcuts/ebuilder-form/host.js +1238 -0
  13. package/dist/shortcuts/ebuilder-form/index.js +108 -0
  14. package/dist/shortcuts/ebuilder-form/manifest.js +347 -0
  15. package/dist/shortcuts/ebuilder-form/operations/read.js +157 -0
  16. package/dist/shortcuts/ebuilder-form/operations/registry.js +56 -0
  17. package/dist/shortcuts/ebuilder-form/operations/shared.js +132 -0
  18. package/dist/shortcuts/ebuilder-form/operations/types.js +19 -0
  19. package/dist/shortcuts/ebuilder-form/operations/write.js +277 -0
  20. package/dist/shortcuts/ebuilder-form/operations.js +8 -0
  21. package/dist/shortcuts/ehr/operations/salary.js +2 -140
  22. package/dist/shortcuts/im/continuation.js +70 -0
  23. package/dist/shortcuts/{yimiaoban → im}/errors.js +14 -14
  24. package/dist/shortcuts/{yimiaoban → im}/host.js +26 -26
  25. package/dist/shortcuts/{yimiaoban → im}/index.js +42 -42
  26. package/dist/shortcuts/{yimiaoban → im}/manifest.js +7 -6
  27. package/dist/shortcuts/{yimiaoban → im}/operations/file-user.js +54 -41
  28. package/dist/shortcuts/{yimiaoban → im}/operations/group-read.js +46 -44
  29. package/dist/shortcuts/{yimiaoban → im}/operations/group-write.js +113 -66
  30. package/dist/shortcuts/{yimiaoban → im}/operations/msg-sync.js +164 -141
  31. package/dist/shortcuts/{yimiaoban → im}/operations/msg-write.js +47 -47
  32. package/dist/shortcuts/{yimiaoban → im}/operations/person.js +10 -10
  33. package/dist/shortcuts/{yimiaoban → im}/operations/registry.js +10 -8
  34. package/dist/shortcuts/{yimiaoban → im}/operations/session.js +82 -83
  35. package/dist/shortcuts/im/operations/shared.js +442 -0
  36. package/dist/shortcuts/{yimiaoban → im}/operations/types.js +1 -1
  37. package/dist/shortcuts/im/operations/user-remind.js +201 -0
  38. package/dist/shortcuts/{yimiaoban → im}/operations/write-util.js +7 -7
  39. package/dist/shortcuts/{yimiaoban → im}/operations.js +3 -3
  40. package/dist/shortcuts/index.js +10 -2
  41. package/dist/shortcuts/invoice/manifest.js +113 -10
  42. package/dist/shortcuts/invoice/operations/import.js +39 -14
  43. package/dist/shortcuts/invoice/operations/reim.js +38 -18
  44. package/dist/shortcuts/invoice/operations/shared.js +35 -6
  45. package/dist/shortcuts/jiuchuanhui/manifest.js +3 -3
  46. package/dist/shortcuts/jiuchuanhui/operations/registry.js +2 -2
  47. package/dist/shortcuts/{yimiaoban → okr}/continuation.js +10 -10
  48. package/dist/shortcuts/okr/errors.js +70 -0
  49. package/dist/shortcuts/okr/host.js +169 -0
  50. package/dist/shortcuts/okr/index.js +155 -0
  51. package/dist/shortcuts/okr/manifest.js +70 -0
  52. package/dist/shortcuts/okr/operations/link.js +305 -0
  53. package/dist/shortcuts/okr/operations/read.js +481 -0
  54. package/dist/shortcuts/okr/operations/registry.js +31 -0
  55. package/dist/shortcuts/okr/operations/shared.js +381 -0
  56. package/dist/shortcuts/okr/operations/types.js +88 -0
  57. package/dist/shortcuts/okr/operations/write.js +838 -0
  58. package/dist/shortcuts/okr/operations.js +8 -0
  59. package/dist/shortcuts/project/continuation.js +70 -0
  60. package/dist/shortcuts/project/errors.js +53 -0
  61. package/dist/shortcuts/project/host.js +160 -0
  62. package/dist/shortcuts/project/index.js +106 -0
  63. package/dist/shortcuts/project/manifest.js +36 -0
  64. package/dist/shortcuts/project/operations/read.js +551 -0
  65. package/dist/shortcuts/project/operations/registry.js +31 -0
  66. package/dist/shortcuts/project/operations/shared.js +68 -0
  67. package/dist/shortcuts/project/operations/types.js +39 -0
  68. package/dist/shortcuts/project/operations/write.js +266 -0
  69. package/dist/shortcuts/project/operations.js +8 -0
  70. package/dist/shortcuts/workflow/continuation.js +508 -0
  71. package/dist/shortcuts/workflow/endpoints.js +149 -0
  72. package/dist/shortcuts/workflow/errors.js +112 -0
  73. package/dist/shortcuts/workflow/host.js +224 -0
  74. package/dist/shortcuts/workflow/index.js +116 -0
  75. package/dist/shortcuts/workflow/manifest.js +30 -0
  76. package/dist/shortcuts/workflow/operations/form.js +4159 -0
  77. package/dist/shortcuts/workflow/operations/read.js +3778 -0
  78. package/dist/shortcuts/workflow/operations/registry.js +33 -0
  79. package/dist/shortcuts/workflow/operations/shared.js +167 -0
  80. package/dist/shortcuts/workflow/operations/types.js +44 -0
  81. package/dist/shortcuts/workflow/operations/write.js +1991 -0
  82. package/dist/shortcuts/workflow/operations.js +119 -0
  83. package/dist/shortcuts/workflow/state.js +182 -0
  84. package/docs/SKILL.md +5 -3
  85. package/docs/_catalog.md +10 -1
  86. package/docs/agent-invoice.md +2 -2
  87. package/docs/agent-skill-install.md +2 -2
  88. package/docs/e10-auth.md +3 -1
  89. package/docs/ebuilder-form.md +38 -0
  90. package/docs/im.md +104 -0
  91. package/docs/invoice.md +5 -5
  92. package/docs/okr.md +122 -0
  93. package/docs/operation-manual.md +10 -7
  94. package/docs/project.md +69 -0
  95. package/docs/skill-review-2026-09-19.md +68 -0
  96. package/package.json +3 -2
  97. package/scripts/package-skill.mjs +38 -11
  98. package/scripts/sync-connector-skills.mjs +172 -0
  99. package/skill-template/business-info.json +357 -16
  100. package/skill-template/domains/ebuilder-form.md +5 -0
  101. package/skill-template/domains/okr.md +18 -0
  102. package/skill-template/domains/shijingran.md +3 -0
  103. package/skill-template/domains/skill-maker.md +4 -4
  104. package/skill-template/domains/workflow.md +22 -0
  105. package/skill-template/domains/yepiaotong.md +4 -2
  106. package/skill-template/domains/yimiaoban.md +13 -10
  107. package/skill-template/product.json +5 -0
  108. package/skill-template/skill-template.md +1 -0
  109. package/skills/weaver-e10-calendar/SKILL.md +5 -1
  110. package/skills/weaver-e10-calendar/references/calendar-query.md +7 -0
  111. package/skills/weaver-e10-calendar/references/source-manifest.json +314 -32
  112. package/skills/weaver-e10-ebuilder-form/SKILL.md +123 -0
  113. package/skills/weaver-e10-ebuilder-form/references/context-routing.md +90 -0
  114. package/skills/weaver-e10-ebuilder-form/references/custom-api.md +86 -0
  115. package/skills/weaver-e10-ebuilder-form/references/disabled-capabilities.md +50 -0
  116. package/skills/weaver-e10-ebuilder-form/references/fields-browser.md +100 -0
  117. package/skills/weaver-e10-ebuilder-form/references/list-nlist.md +91 -0
  118. package/skills/weaver-e10-ebuilder-form/references/openapi-read.md +74 -0
  119. package/skills/weaver-e10-ebuilder-form/references/openapi-write.md +86 -0
  120. package/skills/weaver-e10-ebuilder-form/references/source-manifest.json +107 -0
  121. package/skills/weaver-e10-esb/SKILL.md +1 -1
  122. package/skills/weaver-e10-esb/references/source-manifest.json +15 -14
  123. package/skills/weaver-e10-hrm/SKILL.md +1 -1
  124. package/skills/weaver-e10-hrm/references/source-manifest.json +357 -38
  125. package/skills/weaver-e10-jiuchuanhui/SKILL.md +22 -4
  126. package/skills/weaver-e10-jiuchuanhui/references/clue.md +4 -2
  127. package/skills/weaver-e10-jiuchuanhui/references/contact.md +1 -1
  128. package/skills/weaver-e10-jiuchuanhui/references/customer.md +3 -3
  129. package/skills/weaver-e10-jiuchuanhui/references/disabled-capabilities.md +1 -1
  130. package/skills/weaver-e10-jiuchuanhui/references/discovery-config.md +10 -10
  131. package/skills/weaver-e10-jiuchuanhui/references/general-helpers.md +3 -3
  132. package/skills/weaver-e10-jiuchuanhui/references/sale.md +7 -7
  133. package/skills/weaver-e10-jiuchuanhui/references/source-manifest.json +3 -3
  134. package/skills/weaver-e10-jucailin/SKILL.md +2 -2
  135. package/skills/weaver-e10-mail/SKILL.md +22 -6
  136. package/skills/weaver-e10-meeting/SKILL.md +22 -1
  137. package/skills/weaver-e10-okr/SKILL.md +139 -0
  138. package/skills/weaver-e10-okr/references/okr-align.md +59 -0
  139. package/skills/weaver-e10-okr/references/okr-keyresult.md +68 -0
  140. package/skills/weaver-e10-okr/references/okr-link-routing.md +67 -0
  141. package/skills/weaver-e10-okr/references/okr-query.md +105 -0
  142. package/skills/weaver-e10-okr/references/okr-write.md +94 -0
  143. package/skills/weaver-e10-okr/references/source-manifest.json +672 -0
  144. package/skills/weaver-e10-plan/SKILL.md +3 -3
  145. package/skills/weaver-e10-plan/references/plan-report-write.md +1 -1
  146. package/skills/weaver-e10-plan/references/source-manifest.json +20 -20
  147. package/skills/weaver-e10-qiyecheng/SKILL.md +21 -1
  148. package/skills/weaver-e10-qiyecheng/references/source-manifest.json +17 -17
  149. package/skills/weaver-e10-shared/SKILL.md +79 -11
  150. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +41 -8
  151. package/skills/weaver-e10-shared/references/non-interactive-environment.md +78 -0
  152. package/skills/weaver-e10-shared/references/weaver-e10-installation.md +39 -0
  153. package/skills/weaver-e10-shijingran/SKILL.md +83 -0
  154. package/skills/weaver-e10-shijingran/references/field-resolution.md +105 -0
  155. package/skills/weaver-e10-shijingran/references/operations.md +154 -0
  156. package/skills/weaver-e10-shijingran/references/source-manifest.json +1380 -0
  157. package/skills/weaver-e10-shijingran/references/write-operations.md +90 -0
  158. package/skills/weaver-e10-skill-maker/SKILL.md +26 -9
  159. package/skills/weaver-e10-skill-maker/references/business-skill-generation.md +39 -8
  160. package/skills/weaver-e10-skill-maker/references/detector-validation.md +25 -8
  161. package/skills/weaver-e10-skill-maker/references/module-cli-generation.md +66 -5
  162. package/skills/weaver-e10-skill-maker/references/module-gap-audit-and-repair.md +86 -0
  163. package/skills/weaver-e10-skill-maker/references/source-update-detection.md +59 -5
  164. package/skills/weaver-e10-skill-maker/references/weaver-skill-style.md +16 -8
  165. package/skills/weaver-e10-wenshuding/SKILL.md +28 -4
  166. package/skills/weaver-e10-wenshuding/references/archive-search.md +14 -0
  167. package/skills/weaver-e10-wenshuding/references/source-manifest.json +27 -26
  168. package/skills/weaver-e10-workflow/SKILL.md +250 -0
  169. package/skills/weaver-e10-workflow/references/source-manifest.json +1062 -0
  170. package/skills/weaver-e10-workflow/references/workflow-agent-entry.md +96 -0
  171. package/skills/weaver-e10-workflow/references/workflow-batch.md +275 -0
  172. package/skills/weaver-e10-workflow/references/workflow-create.md +182 -0
  173. package/skills/weaver-e10-workflow/references/workflow-edit.md +106 -0
  174. package/skills/weaver-e10-workflow/references/workflow-memory.md +165 -0
  175. package/skills/weaver-e10-workflow/references/workflow-operate.md +153 -0
  176. package/skills/weaver-e10-workflow/references/workflow-query.md +821 -0
  177. package/skills/weaver-e10-workflow/references/workflow-share.md +117 -0
  178. package/skills/weaver-e10-workflow/references/workflow-view.md +189 -0
  179. package/skills/weaver-e10-yepiaotong/SKILL.md +28 -28
  180. package/skills/weaver-e10-yepiaotong/references/invoice-disabled-capabilities.md +11 -5
  181. package/skills/weaver-e10-yepiaotong/references/invoice-import.md +14 -8
  182. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +9 -43
  183. package/skills/weaver-e10-yepiaotong/references/invoice-issuing.md +8 -0
  184. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +13 -17
  185. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +6 -7
  186. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +2 -2
  187. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +1155 -553
  188. package/skills/weaver-e10-yimiaoban/SKILL.md +56 -38
  189. package/skills/weaver-e10-yimiaoban/references/ding-write.md +8 -8
  190. package/skills/weaver-e10-yimiaoban/references/error-codes.md +16 -0
  191. package/skills/weaver-e10-yimiaoban/references/field-resolution.md +10 -10
  192. package/skills/weaver-e10-yimiaoban/references/file-user-i18n.md +12 -12
  193. package/skills/weaver-e10-yimiaoban/references/group-read.md +16 -16
  194. package/skills/weaver-e10-yimiaoban/references/group-write.md +17 -15
  195. package/skills/weaver-e10-yimiaoban/references/msg-read.md +21 -17
  196. package/skills/weaver-e10-yimiaoban/references/msg-write.md +10 -10
  197. package/skills/weaver-e10-yimiaoban/references/person.md +6 -6
  198. package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +15 -11
  199. package/skills/weaver-e10-yimiaoban/references/session-sysmsg.md +11 -10
  200. package/skills/weaver-e10-yimiaoban/references/source-manifest.json +2164 -154
  201. package/skills/weaver-e10-yimiaoban/references/user-remind.md +75 -0
  202. package/skills/weaver-e10-ziguanjia/SKILL.md +4 -2
  203. package/skills/weaver-e10-ziguanjia/references/source-manifest.json +99 -29
  204. package/tools/weaver-skill-detector-1.0.13/SKILL.md +253 -0
  205. package/tools/weaver-skill-detector-1.0.13/_meta.json +6 -0
  206. package/tools/weaver-skill-detector-1.0.13/references/checklist.md +298 -0
  207. package/tools/weaver-skill-detector-1.0.13/scripts/validate_skill.py +4190 -0
  208. package/dist/shortcuts/yimiaoban/operations/shared.js +0 -236
  209. package/docs/yimiaoban.md +0 -86
  210. package/skills/weaver-e10-calendar/product.json +0 -8
  211. package/skills/weaver-e10-esb/product.json +0 -8
  212. package/skills/weaver-e10-hrm/product.json +0 -8
  213. package/skills/weaver-e10-jiuchuanhui/product.json +0 -8
  214. package/skills/weaver-e10-jucailin/product.json +0 -8
  215. package/skills/weaver-e10-mail/product.json +0 -8
  216. package/skills/weaver-e10-meeting/product.json +0 -8
  217. package/skills/weaver-e10-plan/product.json +0 -8
  218. package/skills/weaver-e10-qiyecheng/product.json +0 -8
  219. package/skills/weaver-e10-skill-maker/product.json +0 -8
  220. package/skills/weaver-e10-wenshuding/product.json +0 -8
  221. package/skills/weaver-e10-yepiaotong/product.json +0 -8
  222. package/skills/weaver-e10-yepiaotong/references/invoice-red.md +0 -261
  223. package/skills/weaver-e10-yimiaoban/product.json +0 -8
  224. package/skills/weaver-e10-ziguanjia/product.json +0 -8
  225. /package/dist/shortcuts/{yimiaoban → im}/operations/msg-parse.js +0 -0
@@ -0,0 +1,108 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { ExitCode, isCliError, toErrorEnvelope } from '../../core/errors.js';
3
+ import { createEbuilderFormContinuationSigner } from './continuation.js';
4
+ import { ebuilderValidationError } from './errors.js';
5
+ import { createEbuilderFormHost } from './host.js';
6
+ import { ebuilderFormManifest } from './manifest.js';
7
+ import { executeEbuilderFormOperation } from './operations.js';
8
+ function asOptions(value) {
9
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
10
+ }
11
+ async function readStdin() {
12
+ const chunks = [];
13
+ for await (const chunk of process.stdin) {
14
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
15
+ }
16
+ return Buffer.concat(chunks).toString('utf8');
17
+ }
18
+ function stripBom(value) {
19
+ return value.replace(/^\uFEFF+/u, '');
20
+ }
21
+ function parseJsonInput(raw, label) {
22
+ try {
23
+ const parsed = JSON.parse(stripBom(raw));
24
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
25
+ throw new Error('input must be an object');
26
+ }
27
+ return parsed;
28
+ }
29
+ catch {
30
+ throw ebuilderValidationError('input_invalid', `${label} 不是合法 JSON 对象`);
31
+ }
32
+ }
33
+ export async function inputFrom(options, extra = {}) {
34
+ const opts = asOptions(options);
35
+ let input = {};
36
+ if (opts.input && opts.inputJson) {
37
+ throw ebuilderValidationError('input_conflict', '不能同时传 --input 和 --input-json');
38
+ }
39
+ if (opts.inputJson) {
40
+ input = parseJsonInput(String(opts.inputJson), '--input-json');
41
+ }
42
+ if (opts.input) {
43
+ let raw;
44
+ try {
45
+ raw = stripBom(opts.input === '-' ? await readStdin() : await readFile(String(opts.input), 'utf8'));
46
+ }
47
+ catch {
48
+ throw ebuilderValidationError('input_unreadable', `无法读取 --input:${String(opts.input)}`);
49
+ }
50
+ input = parseJsonInput(raw, '--input');
51
+ }
52
+ return {
53
+ ...input,
54
+ ...Object.fromEntries(Object.entries(extra).filter(([, value]) => value !== undefined && value !== '')),
55
+ };
56
+ }
57
+ export function successEnvelope(operation, result) {
58
+ return {
59
+ schemaVersion: 1,
60
+ ok: true,
61
+ operation,
62
+ data: result.data === undefined ? null : result.data,
63
+ ...(result.meta ? { meta: result.meta } : {}),
64
+ warnings: result.warnings ?? [],
65
+ };
66
+ }
67
+ function failureEnvelope(error) {
68
+ return {
69
+ schemaVersion: 1,
70
+ ok: false,
71
+ error: toErrorEnvelope(error),
72
+ };
73
+ }
74
+ async function executeAndPrint(ctx, operation, input) {
75
+ try {
76
+ const result = await executeEbuilderFormOperation(operation, input, {
77
+ ctx,
78
+ host: createEbuilderFormHost(ctx),
79
+ continuation: createEbuilderFormContinuationSigner(ctx),
80
+ });
81
+ ctx.output.write(successEnvelope(operation, result), { json: true });
82
+ }
83
+ catch (error) {
84
+ console.error(JSON.stringify(failureEnvelope(error), null, 2));
85
+ process.exitCode = isCliError(error) ? error.exitCode : ExitCode.GeneralError;
86
+ }
87
+ }
88
+ export const ebuilderFormShortcut = {
89
+ name: 'ebuilder-form',
90
+ description: '泛微E10 eBuilder 表单菜单、列表和表单数据 CLI',
91
+ category: 'shortcut',
92
+ register({ program, action }) {
93
+ const ebuilder = program.command('ebuilder-form').description('泛微E10 eBuilder 表单菜单、List/NList、OpenAPI 与自定义接口能力');
94
+ ebuilder.command('schema')
95
+ .description('Print ebuilder-form operation manifest for agents')
96
+ .action(action((ctx) => {
97
+ ctx.output.write(ebuilderFormManifest, { json: true });
98
+ }));
99
+ ebuilder.command('run')
100
+ .description('Run an ebuilder-form operation with JSON input')
101
+ .argument('<operation>', 'operation name, e.g. ebuilder-form.context.resolve')
102
+ .option('--input <path>', 'JSON input file, or - for stdin')
103
+ .option('--input-json <json>', 'inline JSON input object')
104
+ .action(action(async (ctx, operation, options) => {
105
+ await executeAndPrint(ctx, String(operation), await inputFrom(options));
106
+ }));
107
+ },
108
+ };
@@ -0,0 +1,347 @@
1
+ const contextProperties = {
2
+ context: { type: 'object', description: '已解析的 eBuilder 上下文,可由 ebuilder-form.context.resolve 返回' },
3
+ menuKeywords: { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: 5 },
4
+ menu: { type: 'string' },
5
+ menuId: { type: 'string', pattern: '^\\d+$' },
6
+ url: { type: 'string', description: 'E10 列表页面 URL;支持 /sp/ebdfpage/list、viewport 和 /ebdapp/view' },
7
+ appId: { type: 'string', pattern: '^\\d+$' },
8
+ apiPrefix: { type: 'string', pattern: '^/api/ebuilder\\d*$' },
9
+ objId: { type: 'string', pattern: '^\\d+$' },
10
+ listId: { type: 'string', pattern: '^\\d+$' },
11
+ hostPageId: { type: 'string', pattern: '^\\d+$' },
12
+ listKind: { type: 'string', enum: ['List', 'NList'] },
13
+ menuUrl: { type: 'string' },
14
+ entryUrl: { type: 'string' },
15
+ };
16
+ const preparedWriteProperties = {
17
+ confirm: { const: true },
18
+ continuation: { type: 'string', minLength: 1 },
19
+ };
20
+ function schema(properties, options = {}) {
21
+ return {
22
+ type: 'object',
23
+ additionalProperties: false,
24
+ properties,
25
+ ...(options.required?.length ? { required: options.required } : {}),
26
+ ...(options.anyOf ? { anyOf: options.anyOf } : {}),
27
+ ...(options.oneOf ? { oneOf: options.oneOf } : {}),
28
+ ...(options.description ? { description: options.description } : {}),
29
+ };
30
+ }
31
+ export const ebuilderFormOperations = [
32
+ {
33
+ name: 'ebuilder-form.menu.search',
34
+ summary: '按业务关键词查询当前账号有权限访问的 eBuilder 表格/数据列表菜单',
35
+ risk: 'read',
36
+ inputSchema: schema({
37
+ menuKeywords: { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: 5 },
38
+ }, { required: ['menuKeywords'] }),
39
+ },
40
+ {
41
+ name: 'ebuilder-form.context.resolve',
42
+ summary: '从菜单关键词、页面 URL、objId 或现有 context 解析 appId、apiPrefix、listId、objId 和页面地址上下文',
43
+ risk: 'read',
44
+ inputSchema: schema(contextProperties, {
45
+ anyOf: [
46
+ { required: ['context'] },
47
+ { required: ['url'] },
48
+ { required: ['menuKeywords'] },
49
+ { required: ['menu'] },
50
+ { required: ['objId'] },
51
+ { required: ['listId', 'appId', 'listKind'] },
52
+ ],
53
+ }),
54
+ },
55
+ {
56
+ name: 'ebuilder-form.views.list',
57
+ summary: '枚举某个表单对象下的 List/NList 视图',
58
+ risk: 'read',
59
+ inputSchema: schema(contextProperties, { required: ['objId'] }),
60
+ },
61
+ {
62
+ name: 'ebuilder-form.list.config',
63
+ summary: '读取传统表格 List 的基础设置、显示列、排序、搜索、统计和固定条件配置',
64
+ risk: 'read',
65
+ inputSchema: schema(contextProperties, {
66
+ anyOf: [{ required: ['context'] }, { required: ['listId', 'appId'] }, { required: ['menuKeywords'] }, { required: ['url'] }],
67
+ }),
68
+ },
69
+ {
70
+ name: 'ebuilder-form.list.query',
71
+ summary: '按 List 运行时接口查询分页数据和真实总数,保留明细展开重复行',
72
+ risk: 'read',
73
+ inputSchema: schema({
74
+ ...contextProperties,
75
+ pageNo: { type: 'integer', minimum: 1, default: 1 },
76
+ pageSize: { type: 'integer', minimum: 1, maximum: 200 },
77
+ allPages: { type: 'boolean', default: false },
78
+ tableuid: { type: 'string' },
79
+ searchParamData: { type: 'object' },
80
+ filterCondition: { type: 'object' },
81
+ orderParams: { type: 'array' },
82
+ passid: { type: 'string' },
83
+ cid: { type: 'string' },
84
+ }),
85
+ },
86
+ {
87
+ name: 'ebuilder-form.nlist.config',
88
+ summary: '读取数据列表 NList 的页面、组件与 comps[1].config 运行时配置',
89
+ risk: 'read',
90
+ inputSchema: schema(contextProperties, {
91
+ anyOf: [{ required: ['context'] }, { required: ['hostPageId', 'appId'] }, { required: ['menuKeywords'] }, { required: ['url'] }],
92
+ }),
93
+ },
94
+ {
95
+ name: 'ebuilder-form.nlist.query',
96
+ summary: '按 NList eblist 运行时接口查询分页数据和真实总数,使用 customConfig LZW 数字串编码',
97
+ risk: 'read',
98
+ inputSchema: schema({
99
+ ...contextProperties,
100
+ pageNo: { type: 'integer', minimum: 1, default: 1 },
101
+ pageSize: { type: 'integer', minimum: 1, maximum: 200 },
102
+ allPages: { type: 'boolean', default: false },
103
+ compId: { type: 'string' },
104
+ tableuid: { type: 'string' },
105
+ filter: {},
106
+ fieldFilter: {},
107
+ pageFilter: {},
108
+ customConfig: { type: 'object' },
109
+ refPluginPackageId: { type: 'string' },
110
+ }),
111
+ },
112
+ {
113
+ name: 'ebuilder-form.fields.get',
114
+ summary: '读取 eBuilder 字段定义,返回主表与明细表字段、config.dataKey、browserParams 和组件类型',
115
+ risk: 'read',
116
+ fixed: { path: '/api/ebuilder/common/ds/fields' },
117
+ inputSchema: schema({
118
+ ...contextProperties,
119
+ groupId: { type: 'string' },
120
+ sourceId: { type: 'string' },
121
+ sourceType: { type: 'string', default: 'FORM' },
122
+ detailFieldsGroup: { type: ['boolean', 'string'], default: true },
123
+ enableMerge: { type: ['boolean', 'string'], default: true },
124
+ customParam: {},
125
+ params: {},
126
+ }),
127
+ },
128
+ {
129
+ name: 'ebuilder-form.options.get',
130
+ summary: '按字段元数据 ID 读取选择类字段选项',
131
+ risk: 'read',
132
+ fixed: { path: '/api/ebuilder/common/ds/options' },
133
+ inputSchema: schema({
134
+ ...contextProperties,
135
+ fieldName: { type: 'string', pattern: '^\\d+$' },
136
+ fieldId: { type: 'string', pattern: '^\\d+$' },
137
+ sourceType: { type: 'string', default: 'FORM' },
138
+ groupId: { type: 'string' },
139
+ optionLevel: { type: ['integer', 'string'], default: 1 },
140
+ }, {
141
+ anyOf: [{ required: ['fieldName'] }, { required: ['fieldId'] }],
142
+ }),
143
+ },
144
+ {
145
+ name: 'ebuilder-form.mapping.get',
146
+ summary: '读取 objId 的 mainTable/detailN 与主表/明细表标识映射',
147
+ risk: 'read',
148
+ fixed: { path: '/api/ebuilder/form/dataset/v1/getTableMapping' },
149
+ inputSchema: schema({
150
+ ...contextProperties,
151
+ reverse: { type: 'boolean', default: false },
152
+ }, { required: ['objId'] }),
153
+ },
154
+ {
155
+ name: 'ebuilder-form.browser.resolve',
156
+ summary: '调用字段配置或已知模块对应的通用浏览 complete 接口,将名称解析为可选项 ID',
157
+ risk: 'read',
158
+ inputSchema: schema({
159
+ module: { type: 'string', description: '浏览接口模块,例如 hrm、workflow/core、doc、task' },
160
+ browserType: { type: 'string', description: '浏览类型,例如 resource、department、wfcRequest' },
161
+ query: { type: 'string', minLength: 1 },
162
+ multiple: { type: 'boolean', default: false },
163
+ limit: { type: 'integer', minimum: 1, maximum: 50, default: 20 },
164
+ extra: { type: 'object' },
165
+ }, { required: ['module', 'browserType', 'query'] }),
166
+ },
167
+ {
168
+ name: 'ebuilder-form.openapi.detail',
169
+ summary: 'OpenAPI getDataById 获取单条表单数据详情',
170
+ risk: 'read',
171
+ fixed: { path: '/api/ebuilder/form/dataset/v2/getDataById' },
172
+ inputSchema: schema({
173
+ ...contextProperties,
174
+ dataId: { type: 'string', pattern: '^\\d+$' },
175
+ isReturnDetail: { type: ['boolean', 'string'], default: 'y' },
176
+ fieldNoFindIgnore: { type: ['boolean', 'string'], default: 'false' },
177
+ }, { required: ['objId', 'dataId'] }),
178
+ },
179
+ {
180
+ name: 'ebuilder-form.openapi.query',
181
+ summary: 'OpenAPI getAllData 表单级分页查询',
182
+ risk: 'read',
183
+ fixed: { path: '/api/ebuilder/form/dataset/v2/getAllData' },
184
+ inputSchema: schema({
185
+ ...contextProperties,
186
+ mainTable: { type: 'object' },
187
+ pageNo: { type: 'integer', minimum: 1, default: 1 },
188
+ pageSize: { type: 'integer', minimum: 1, maximum: 1000, default: 10 },
189
+ isReturnDetail: { type: ['boolean', 'string'], default: 'n' },
190
+ fieldNoFindIgnore: { type: ['boolean', 'string'], default: 'false' },
191
+ }, { required: ['objId'] }),
192
+ },
193
+ {
194
+ name: 'ebuilder-form.openapi.count',
195
+ summary: 'OpenAPI getAllDataCount 表单级总数查询',
196
+ risk: 'read',
197
+ fixed: { path: '/api/ebuilder/form/dataset/v2/getAllDataCount' },
198
+ inputSchema: schema({
199
+ ...contextProperties,
200
+ mainTable: { type: 'object' },
201
+ fieldNoFindIgnore: { type: ['boolean', 'string'], default: 'false' },
202
+ }, { required: ['objId'] }),
203
+ },
204
+ {
205
+ name: 'ebuilder-form.openapi.add.prepare',
206
+ summary: '准备 OpenAPI saveFormData 新增请求,签发 continuation,不写入',
207
+ risk: 'read-before-write',
208
+ inputSchema: schema({
209
+ ...contextProperties,
210
+ datas: { type: 'array', minItems: 1 },
211
+ operationinfo: { type: 'object' },
212
+ }, { required: ['objId', 'datas'] }),
213
+ },
214
+ {
215
+ name: 'ebuilder-form.openapi.add.apply',
216
+ summary: '确认后执行 OpenAPI saveFormData 新增请求',
217
+ risk: 'high-risk-write',
218
+ inputSchema: schema(preparedWriteProperties, { required: ['confirm', 'continuation'] }),
219
+ },
220
+ {
221
+ name: 'ebuilder-form.openapi.update.prepare',
222
+ summary: '准备 OpenAPI updateFormData 修改请求,签发 continuation,不写入',
223
+ risk: 'read-before-write',
224
+ inputSchema: schema({
225
+ ...contextProperties,
226
+ datas: { type: 'array', minItems: 1 },
227
+ operationinfo: { type: 'object' },
228
+ }, { required: ['objId', 'datas'] }),
229
+ },
230
+ {
231
+ name: 'ebuilder-form.openapi.update.apply',
232
+ summary: '确认后执行 OpenAPI updateFormData 修改请求',
233
+ risk: 'high-risk-write',
234
+ inputSchema: schema(preparedWriteProperties, { required: ['confirm', 'continuation'] }),
235
+ },
236
+ {
237
+ name: 'ebuilder-form.openapi.delete.prepare',
238
+ summary: '准备 OpenAPI deleteData 删除请求,签发 continuation,不写入',
239
+ risk: 'read-before-write',
240
+ inputSchema: schema({
241
+ ...contextProperties,
242
+ mainTable: { type: 'object', description: '删除条件;按数据 ID 删除时传 {"id":"..."}' },
243
+ dataId: { type: 'string', pattern: '^\\d+$' },
244
+ operationinfo: { type: 'object' },
245
+ }, {
246
+ required: ['objId'],
247
+ anyOf: [{ required: ['dataId'] }, { required: ['mainTable'] }],
248
+ }),
249
+ },
250
+ {
251
+ name: 'ebuilder-form.openapi.delete.apply',
252
+ summary: '确认后执行 OpenAPI deleteData 删除请求',
253
+ risk: 'high-risk-write',
254
+ inputSchema: schema(preparedWriteProperties, { required: ['confirm', 'continuation'] }),
255
+ },
256
+ {
257
+ name: 'ebuilder-form.custom.detail',
258
+ summary: '已发布自定义接口 getFormDataByPk 根据主键查询详情',
259
+ risk: 'read',
260
+ fixed: { path: '/api/ebuilder/form/formdata/v2/getFormDataByPk/{interfacePk}' },
261
+ inputSchema: schema({
262
+ ...contextProperties,
263
+ interfacePk: { type: 'string', minLength: 1 },
264
+ dataId: { type: 'string', pattern: '^\\d+$' },
265
+ }, { required: ['interfacePk', 'dataId'] }),
266
+ },
267
+ {
268
+ name: 'ebuilder-form.custom.query',
269
+ summary: '已发布自定义接口 getFormDataList 分页查询',
270
+ risk: 'read',
271
+ fixed: { path: '/api/ebuilder/form/formdata/v2/getFormDataList/{interfacePk}' },
272
+ inputSchema: schema({
273
+ ...contextProperties,
274
+ interfacePk: { type: 'string', minLength: 1 },
275
+ mainTable: { type: 'object' },
276
+ pageNo: { type: 'integer', minimum: 1, default: 1 },
277
+ pageSize: { type: 'integer', minimum: 1, maximum: 1000, default: 10 },
278
+ }, { required: ['interfacePk'] }),
279
+ },
280
+ {
281
+ name: 'ebuilder-form.custom.count',
282
+ summary: '已发布自定义接口 getFormDataCount 查询总数',
283
+ risk: 'read',
284
+ fixed: { path: '/api/ebuilder/form/formdata/v2/getFormDataCount/{interfacePk}' },
285
+ inputSchema: schema({
286
+ ...contextProperties,
287
+ interfacePk: { type: 'string', minLength: 1 },
288
+ mainTable: { type: 'object' },
289
+ }, { required: ['interfacePk'] }),
290
+ },
291
+ {
292
+ name: 'ebuilder-form.custom.add.prepare',
293
+ summary: '准备已发布自定义接口 saveFormData 新增请求,签发 continuation',
294
+ risk: 'read-before-write',
295
+ inputSchema: schema({
296
+ ...contextProperties,
297
+ interfacePk: { type: 'string', minLength: 1 },
298
+ datas: { type: 'array', minItems: 1 },
299
+ operationinfo: { type: 'object' },
300
+ }, { required: ['interfacePk', 'datas'] }),
301
+ },
302
+ {
303
+ name: 'ebuilder-form.custom.add.apply',
304
+ summary: '确认后执行已发布自定义接口 saveFormData 新增请求',
305
+ risk: 'high-risk-write',
306
+ inputSchema: schema(preparedWriteProperties, { required: ['confirm', 'continuation'] }),
307
+ },
308
+ {
309
+ name: 'ebuilder-form.custom.update.prepare',
310
+ summary: '准备已发布自定义接口 updateFormData 修改请求,签发 continuation',
311
+ risk: 'read-before-write',
312
+ inputSchema: schema({
313
+ ...contextProperties,
314
+ interfacePk: { type: 'string', minLength: 1 },
315
+ datas: { type: 'array', minItems: 1 },
316
+ operationinfo: { type: 'object' },
317
+ }, { required: ['interfacePk', 'datas'] }),
318
+ },
319
+ {
320
+ name: 'ebuilder-form.custom.update.apply',
321
+ summary: '确认后执行已发布自定义接口 updateFormData 修改请求',
322
+ risk: 'high-risk-write',
323
+ inputSchema: schema(preparedWriteProperties, { required: ['confirm', 'continuation'] }),
324
+ },
325
+ {
326
+ name: 'ebuilder-form.custom.delete.prepare',
327
+ summary: '准备已发布自定义接口 deleteFormData 删除请求,签发 continuation',
328
+ risk: 'read-before-write',
329
+ inputSchema: schema({
330
+ ...contextProperties,
331
+ interfacePk: { type: 'string', minLength: 1 },
332
+ dataIds: { type: 'array', items: { type: 'string', pattern: '^\\d+$' }, minItems: 1 },
333
+ operationinfo: { type: 'object' },
334
+ }, { required: ['interfacePk', 'dataIds'] }),
335
+ },
336
+ {
337
+ name: 'ebuilder-form.custom.delete.apply',
338
+ summary: '确认后执行已发布自定义接口 deleteFormData 删除请求',
339
+ risk: 'high-risk-write',
340
+ inputSchema: schema(preparedWriteProperties, { required: ['confirm', 'continuation'] }),
341
+ },
342
+ ];
343
+ export const ebuilderFormManifest = {
344
+ module: 'ebuilder-form',
345
+ version: 1,
346
+ operations: ebuilderFormOperations,
347
+ };
@@ -0,0 +1,157 @@
1
+ import { ebuilderSuccess } from './types.js';
2
+ import { asObject, assertKnownKeys, optionalString, requiredArray, } from './shared.js';
3
+ const CONTEXT_KEYS = [
4
+ 'context',
5
+ 'menuKeywords',
6
+ 'menu',
7
+ 'menuId',
8
+ 'url',
9
+ 'appId',
10
+ 'apiPrefix',
11
+ 'objId',
12
+ 'listId',
13
+ 'hostPageId',
14
+ 'listKind',
15
+ 'menuUrl',
16
+ 'entryUrl',
17
+ ];
18
+ export class EbuilderMenuSearchOperation {
19
+ name = 'ebuilder-form.menu.search';
20
+ async execute(input, { host }) {
21
+ assertKnownKeys(input, ['menuKeywords'], this.name);
22
+ const keywords = requiredArray(input.menuKeywords, 'menuKeywords').map((item) => String(item));
23
+ const menus = await host.searchMenus(keywords);
24
+ return ebuilderSuccess(this.name, { menus, count: menus.length }, { status: 'COMPLETE' });
25
+ }
26
+ }
27
+ export class EbuilderContextResolveOperation {
28
+ name = 'ebuilder-form.context.resolve';
29
+ async execute(input, { host }) {
30
+ const context = await host.resolveContext(input);
31
+ return ebuilderSuccess(this.name, {
32
+ context,
33
+ listUrl: host.buildListUrl(context),
34
+ }, { status: 'COMPLETE' });
35
+ }
36
+ }
37
+ export class EbuilderViewsListOperation {
38
+ name = 'ebuilder-form.views.list';
39
+ async execute(input, { host }) {
40
+ const result = await host.formViews(input);
41
+ return ebuilderSuccess(this.name, result, { status: 'COMPLETE' });
42
+ }
43
+ }
44
+ export class EbuilderListConfigOperation {
45
+ name = 'ebuilder-form.list.config';
46
+ async execute(input, { host }) {
47
+ const context = await host.resolveContext({ ...input, listKind: input.listKind || input.context?.listKind || 'List' });
48
+ const result = await host.listConfig(context, this.name);
49
+ return ebuilderSuccess(this.name, result, { status: 'COMPLETE' });
50
+ }
51
+ }
52
+ export class EbuilderListQueryOperation {
53
+ name = 'ebuilder-form.list.query';
54
+ async execute(input, { host }) {
55
+ const result = await host.listQuery(input, this.name);
56
+ return ebuilderSuccess(this.name, result, { status: 'COMPLETE' });
57
+ }
58
+ }
59
+ export class EbuilderNlistConfigOperation {
60
+ name = 'ebuilder-form.nlist.config';
61
+ async execute(input, { host }) {
62
+ const context = await host.resolveContext({ ...input, listKind: input.listKind || input.context?.listKind || 'NList' });
63
+ const result = await host.nlistConfig(context, this.name);
64
+ return ebuilderSuccess(this.name, result, { status: 'COMPLETE' });
65
+ }
66
+ }
67
+ export class EbuilderNlistQueryOperation {
68
+ name = 'ebuilder-form.nlist.query';
69
+ async execute(input, { host }) {
70
+ const result = await host.nlistQuery(input, this.name);
71
+ return ebuilderSuccess(this.name, result, { status: 'COMPLETE' });
72
+ }
73
+ }
74
+ export class EbuilderFieldsGetOperation {
75
+ name = 'ebuilder-form.fields.get';
76
+ async execute(input, { host }) {
77
+ const result = await host.fields(input, this.name);
78
+ return ebuilderSuccess(this.name, { result }, { status: 'COMPLETE' });
79
+ }
80
+ }
81
+ export class EbuilderOptionsGetOperation {
82
+ name = 'ebuilder-form.options.get';
83
+ async execute(input, { host }) {
84
+ const result = await host.options(input, this.name);
85
+ return ebuilderSuccess(this.name, { result }, { status: 'COMPLETE' });
86
+ }
87
+ }
88
+ export class EbuilderMappingGetOperation {
89
+ name = 'ebuilder-form.mapping.get';
90
+ async execute(input, { host }) {
91
+ const result = await host.mapping(input, this.name);
92
+ return ebuilderSuccess(this.name, { result }, { status: 'COMPLETE' });
93
+ }
94
+ }
95
+ export class EbuilderBrowserResolveOperation {
96
+ name = 'ebuilder-form.browser.resolve';
97
+ async execute(input, { host }) {
98
+ assertKnownKeys(input, ['module', 'browserType', 'query', 'multiple', 'limit', 'extra'], this.name);
99
+ const result = await host.browserResolve(input, this.name);
100
+ return ebuilderSuccess(this.name, result, { status: 'COMPLETE' });
101
+ }
102
+ }
103
+ export class EbuilderOpenapiReadOperation {
104
+ endpoint;
105
+ name;
106
+ constructor(endpoint) {
107
+ this.endpoint = endpoint;
108
+ this.name = `ebuilder-form.openapi.${endpoint}`;
109
+ }
110
+ async execute(input, { host }) {
111
+ const allowed = [
112
+ ...CONTEXT_KEYS,
113
+ 'dataId',
114
+ 'mainTable',
115
+ 'pageNo',
116
+ 'pageSize',
117
+ 'isReturnDetail',
118
+ 'fieldNoFindIgnore',
119
+ ];
120
+ assertKnownKeys(input, allowed, this.name);
121
+ const result = await host.openapiRead(this.endpoint, input, this.name);
122
+ const data = addLinks(result, host, this.endpoint === 'detail' ? optionalString(input.dataId, 'dataId') : undefined);
123
+ return ebuilderSuccess(this.name, data, { status: 'COMPLETE' });
124
+ }
125
+ }
126
+ export class EbuilderCustomReadOperation {
127
+ endpoint;
128
+ name;
129
+ constructor(endpoint) {
130
+ this.endpoint = endpoint;
131
+ this.name = `ebuilder-form.custom.${endpoint}`;
132
+ }
133
+ async execute(input, { host }) {
134
+ const allowed = [
135
+ ...CONTEXT_KEYS,
136
+ 'interfacePk',
137
+ 'dataId',
138
+ 'mainTable',
139
+ 'pageNo',
140
+ 'pageSize',
141
+ ];
142
+ assertKnownKeys(input, allowed, this.name);
143
+ const result = await host.customRead(this.endpoint, input, this.name);
144
+ const data = addLinks(result, host, this.endpoint === 'detail' ? optionalString(input.dataId, 'dataId') : undefined);
145
+ return ebuilderSuccess(this.name, data, { status: 'COMPLETE' });
146
+ }
147
+ }
148
+ function addLinks(result, host, dataId) {
149
+ const context = asObject(result.context || {}, 'context');
150
+ const payload = asObject(result.result || {}, 'result');
151
+ return {
152
+ context,
153
+ result: payload,
154
+ ...(dataId ? { dataUrl: host.buildDataUrl(context, dataId) } : {}),
155
+ listUrl: host.buildListUrl(context),
156
+ };
157
+ }
@@ -0,0 +1,56 @@
1
+ import { ebuilderValidationError } from '../errors.js';
2
+ import { ebuilderFormOperations } from '../manifest.js';
3
+ import { EbuilderBrowserResolveOperation, EbuilderContextResolveOperation, EbuilderCustomReadOperation, EbuilderFieldsGetOperation, EbuilderListConfigOperation, EbuilderListQueryOperation, EbuilderMappingGetOperation, EbuilderMenuSearchOperation, EbuilderNlistConfigOperation, EbuilderNlistQueryOperation, EbuilderOpenapiReadOperation, EbuilderOptionsGetOperation, EbuilderViewsListOperation, } from './read.js';
4
+ import { EbuilderCustomApplyOperation, EbuilderCustomPrepareOperation, EbuilderOpenapiApplyOperation, EbuilderOpenapiPrepareOperation, } from './write.js';
5
+ function buildRegistry() {
6
+ const handlers = [
7
+ new EbuilderMenuSearchOperation(),
8
+ new EbuilderContextResolveOperation(),
9
+ new EbuilderViewsListOperation(),
10
+ new EbuilderListConfigOperation(),
11
+ new EbuilderListQueryOperation(),
12
+ new EbuilderNlistConfigOperation(),
13
+ new EbuilderNlistQueryOperation(),
14
+ new EbuilderFieldsGetOperation(),
15
+ new EbuilderOptionsGetOperation(),
16
+ new EbuilderMappingGetOperation(),
17
+ new EbuilderBrowserResolveOperation(),
18
+ new EbuilderOpenapiReadOperation('detail'),
19
+ new EbuilderOpenapiReadOperation('query'),
20
+ new EbuilderOpenapiReadOperation('count'),
21
+ new EbuilderOpenapiPrepareOperation('add'),
22
+ new EbuilderOpenapiApplyOperation('add'),
23
+ new EbuilderOpenapiPrepareOperation('update'),
24
+ new EbuilderOpenapiApplyOperation('update'),
25
+ new EbuilderOpenapiPrepareOperation('delete'),
26
+ new EbuilderOpenapiApplyOperation('delete'),
27
+ new EbuilderCustomReadOperation('detail'),
28
+ new EbuilderCustomReadOperation('query'),
29
+ new EbuilderCustomReadOperation('count'),
30
+ new EbuilderCustomPrepareOperation('add'),
31
+ new EbuilderCustomApplyOperation('add'),
32
+ new EbuilderCustomPrepareOperation('update'),
33
+ new EbuilderCustomApplyOperation('update'),
34
+ new EbuilderCustomPrepareOperation('delete'),
35
+ new EbuilderCustomApplyOperation('delete'),
36
+ ];
37
+ const registry = new Map();
38
+ for (const handler of handlers) {
39
+ if (registry.has(handler.name))
40
+ throw new Error(`duplicate ebuilder-form operation handler: ${handler.name}`);
41
+ registry.set(handler.name, handler);
42
+ }
43
+ for (const contract of ebuilderFormOperations) {
44
+ if (!registry.has(contract.name))
45
+ throw new Error(`missing ebuilder-form operation handler: ${contract.name}`);
46
+ }
47
+ return registry;
48
+ }
49
+ const registry = buildRegistry();
50
+ export function getEbuilderFormOperation(operation) {
51
+ const handler = registry.get(operation);
52
+ if (!handler) {
53
+ throw ebuilderValidationError('operation_unknown', `eBuilder 表单不支持操作:${operation}`);
54
+ }
55
+ return handler;
56
+ }