weaver-work-cli 0.1.29 → 0.1.32
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/dist/chunks/archive-UMGX72K6.js +2537 -0
- package/dist/chunks/archive-oa-N2IYBLF3.js +1317 -0
- package/dist/chunks/asset-GLEGKFG5.js +2109 -0
- package/dist/chunks/attachment-content-AQNX5N3S.js +23 -0
- package/dist/chunks/blog-E44OTVDA.js +2157 -0
- package/dist/chunks/caizhilian-DQUFZXZL.js +10087 -0
- package/dist/chunks/calendar-JKPIRKFD.js +1195 -0
- package/dist/chunks/chunk-2GA5ZIQL.js +1615 -0
- package/dist/chunks/chunk-4YC43QQ4.js +403 -0
- package/dist/chunks/chunk-6EFWDL7Y.js +161 -0
- package/dist/chunks/chunk-6RKD4DRZ.js +5556 -0
- package/dist/chunks/chunk-AJ62BGAW.js +29 -0
- package/dist/chunks/chunk-BUSC6UAE.js +43 -0
- package/dist/chunks/chunk-C6R3B2ML.js +358 -0
- package/dist/chunks/chunk-CVZ2JOSW.js +62 -0
- package/dist/chunks/chunk-DW6AUUKS.js +508 -0
- package/dist/chunks/chunk-E4Z23GHM.js +6962 -0
- package/dist/chunks/chunk-EG6ZU444.js +654 -0
- package/dist/chunks/chunk-EZALDOQH.js +383 -0
- package/dist/chunks/chunk-FMPJJYYI.js +106 -0
- package/dist/chunks/chunk-G2JSIUWF.js +769 -0
- package/dist/chunks/chunk-G3QJULO2.js +387 -0
- package/dist/chunks/chunk-GCG2NMWR.js +703 -0
- package/dist/chunks/chunk-GPMFD4RD.js +75 -0
- package/dist/chunks/chunk-H6XSTSLM.js +2357 -0
- package/dist/chunks/chunk-H7J4DC5R.js +464 -0
- package/dist/chunks/chunk-IURUFGZK.js +477 -0
- package/dist/chunks/chunk-LUSPKZKY.js +53 -0
- package/dist/chunks/chunk-NIAJ5ZCG.js +73 -0
- package/dist/chunks/chunk-NOODWMCL.js +584 -0
- package/dist/chunks/chunk-OOUTBLZ4.js +51 -0
- package/dist/chunks/chunk-P26ZWSKU.js +73 -0
- package/dist/chunks/chunk-QWY6PGL6.js +3472 -0
- package/dist/chunks/chunk-WKI2FBIQ.js +15606 -0
- package/dist/chunks/chunk-WSKBSQ2U.js +231 -0
- package/dist/chunks/chunk-YLCYX7LE.js +371 -0
- package/dist/chunks/chunk-YRVDW4WN.js +205 -0
- package/dist/chunks/chunk-ZEDWSH32.js +68 -0
- package/dist/chunks/continuation-2CKSBLA6.js +11 -0
- package/dist/chunks/continuation-HZIZRZBX.js +13 -0
- package/dist/chunks/continuation-NLECEJPX.js +11 -0
- package/dist/chunks/ebuilder-form-V5FG2EHC.js +2276 -0
- package/dist/chunks/ehr-HMFY6VIL.js +5241 -0
- package/dist/chunks/employee-SAK2QYXX.js +11 -0
- package/dist/chunks/esb-ZYSVB7SG.js +141 -0
- package/dist/chunks/fna-B7RKPAZD.js +1444 -0
- package/dist/chunks/host-45WED2KK.js +21 -0
- package/dist/chunks/host-I4Z6BFYX.js +23 -0
- package/dist/chunks/host-KNZ52LJZ.js +17 -0
- package/dist/chunks/host-OCH2BCCV.js +19 -0
- package/dist/chunks/hrm-2KAZGUHI.js +244 -0
- package/dist/chunks/im-ACJJWH4U.js +252 -0
- package/dist/chunks/invoice-ZK3WCX2U.js +5179 -0
- package/dist/chunks/jiuchuanhui-5PQD3IL2.js +1940 -0
- package/dist/chunks/lazy-dispatch-JQXBW3GM.js +28 -0
- package/dist/chunks/mail-S2HDDXO2.js +2695 -0
- package/dist/chunks/meeting-QVN3I37L.js +504 -0
- package/dist/chunks/msg-parse-4GSQ2WTO.js +41 -0
- package/dist/chunks/okr-QNG4VC2Q.js +2482 -0
- package/dist/chunks/plan-A25EMW6U.js +2025 -0
- package/dist/chunks/project-G6XV66DZ.js +1361 -0
- package/dist/chunks/registry-2VLUAESA.js +14 -0
- package/dist/chunks/registry-7C5UMIPL.js +19 -0
- package/dist/chunks/registry-DC6KR3NH.js +18 -0
- package/dist/chunks/registry-NYPYMZXG.js +16 -0
- package/dist/chunks/registry-TI3CIUXF.js +19 -0
- package/dist/chunks/room-recommend-WRTHO6Y2.js +20 -0
- package/dist/chunks/schedule-KFIITGSK.js +24 -0
- package/dist/chunks/state-Y2XBP6YE.js +15 -0
- package/dist/chunks/workflow-DJ7SYWAF.js +245 -0
- package/dist/cmd/argv.js +45 -0
- package/dist/cmd/docs/index.js +3 -3
- package/dist/cmd/lazy-dispatch.js +20 -0
- package/dist/cmd/root.js +2 -4
- package/dist/cmd/setup/index.js +2 -2
- package/dist/cmd/skills/index.js +2 -2
- package/dist/core/package-paths.js +61 -0
- package/dist/index.js +163 -7
- package/dist/internal/e10/auth/xiaoe.js +3 -3
- package/dist/internal/e10/request-runtime.js +18 -62
- package/dist/internal/skills/detector.js +2 -2
- package/dist/shortcuts/contract/data/performance-catalog.js +1306 -0
- package/dist/shortcuts/contract/host.js +91 -35
- package/dist/shortcuts/contract/index.js +213 -0
- package/dist/shortcuts/contract/manifest.js +928 -0
- package/dist/shortcuts/contract/ooxml/docx.js +295 -0
- package/dist/shortcuts/contract/ooxml/xlsx.js +221 -0
- package/dist/shortcuts/contract/ooxml/zip.js +158 -0
- package/dist/shortcuts/contract/operations/assistant.js +1156 -0
- package/dist/shortcuts/contract/operations/clause-library.js +522 -0
- package/dist/shortcuts/contract/operations/compare.js +193 -0
- package/dist/shortcuts/contract/operations/credit-page.js +34 -0
- package/dist/shortcuts/contract/operations/flow.js +98 -0
- package/dist/shortcuts/contract/operations/page.js +66 -0
- package/dist/shortcuts/contract/operations/performance.js +733 -0
- package/dist/shortcuts/contract/operations/quote.js +557 -0
- package/dist/shortcuts/contract/operations/recommend.js +78 -0
- package/dist/shortcuts/contract/operations/registry.js +18 -0
- package/dist/shortcuts/contract/operations/review.js +83 -0
- package/dist/shortcuts/contract/operations/shared.js +37 -0
- package/dist/shortcuts/contract/operations/upload.js +108 -0
- package/dist/shortcuts/contract/operations/write.js +3 -2
- package/dist/shortcuts/index.js +140 -40
- package/dist/shortcuts/invoice/manifest.js +34 -11
- package/dist/shortcuts/invoice/operations/reim-auto.js +9 -0
- package/dist/shortcuts/invoice/operations/reim.js +81 -5
- package/dist/shortcuts/invoice/operations/shared.js +12 -5
- package/dist/shortcuts/meeting/host.js +45 -3
- package/dist/shortcuts/meeting/invitation/docx.js +442 -0
- package/dist/shortcuts/meeting/operations/attachment-content.js +418 -0
- package/dist/shortcuts/meeting/operations/attachment.js +442 -0
- package/dist/shortcuts/meeting/operations/eb/cache.js +57 -0
- package/dist/shortcuts/meeting/operations/eb/catalog.js +343 -28
- package/dist/shortcuts/meeting/operations/eb/conflict.js +372 -11
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +710 -0
- package/dist/shortcuts/meeting/operations/eb/decision.js +47 -1
- package/dist/shortcuts/meeting/operations/eb/factory.js +129 -11
- package/dist/shortcuts/meeting/operations/eb/index.js +122 -2
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +378 -0
- package/dist/shortcuts/meeting/operations/eb/room-summary.js +84 -0
- package/dist/shortcuts/meeting/operations/eb/schedule.js +450 -0
- package/dist/shortcuts/meeting/operations/from-group-chat.js +576 -0
- package/dist/shortcuts/meeting/operations/invitation.js +458 -0
- package/dist/shortcuts/meeting/operations/minute-content.js +266 -0
- package/dist/shortcuts/meeting/operations/pipeline.js +489 -0
- package/dist/shortcuts/meeting/operations/qrcode.js +131 -0
- package/dist/shortcuts/meeting/operations/receipts.js +1 -1
- package/dist/shortcuts/meeting/operations/registry.js +18 -0
- package/dist/shortcuts/meeting/operations/summary.js +276 -0
- package/dist/shortcuts/meeting/operations/task-notify.js +325 -0
- package/dist/shortcuts/meeting/operations.js +42 -1
- package/dist/shortcuts/meeting/qr/encoder.js +427 -0
- package/dist/shortcuts/meeting/qr/render.js +103 -0
- package/dist/shortcuts/workflow/operations/form.js +17 -5
- package/docs/contract.md +39 -4
- package/docs/invoice.md +5 -5
- package/package.json +3 -2
- package/scripts/bundle.mjs +63 -0
- package/skill-template/business-info.json +25 -4
- package/skill-template/domains/jinchengda.md +16 -3
- package/skill-template/domains/yepiaotong.md +1 -1
- package/skills/weaver-e10-jinchengda/SKILL.md +111 -31
- package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +7 -13
- package/skills/weaver-e10-jinchengda/references/contract-ai-assistant.md +150 -0
- package/skills/weaver-e10-jinchengda/references/contract-ai-review.md +87 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +111 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-recommender.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +0 -13
- package/skills/weaver-e10-jinchengda/references/contract-credit-page.md +50 -0
- package/skills/weaver-e10-jinchengda/references/contract-disabled-capabilities.md +4 -2
- package/skills/weaver-e10-jinchengda/references/contract-doc-compare.md +74 -0
- package/skills/weaver-e10-jinchengda/references/contract-flow-launch.md +84 -0
- package/skills/weaver-e10-jinchengda/references/contract-performance-query.md +29 -0
- package/skills/weaver-e10-jinchengda/references/contract-quote-to-contract.md +28 -0
- package/skills/weaver-e10-jinchengda/references/contract-request-status.md +2 -21
- package/skills/weaver-e10-jinchengda/references/contract-request-write.md +0 -24
- package/skills/weaver-e10-jinchengda/references/contract-signing-subjects.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-subject-create.md +0 -17
- package/skills/weaver-e10-jinchengda/references/contract-template-recommend.md +70 -0
- package/skills/weaver-e10-jinchengda/references/contract-template-selector.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-workflow-discovery.md +0 -15
- package/skills/weaver-e10-jinchengda/references/source-manifest.json +1168 -152
- package/skills/weaver-e10-meeting/SKILL.md +493 -17
- package/skills/weaver-e10-meeting/references/meeting-change.md +4 -4
- package/skills/weaver-e10-meeting/references/meeting-create.md +6 -6
- package/skills/weaver-e10-meeting/references/meeting-eb.md +503 -27
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +113 -0
- package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +6 -6
- package/skills/weaver-e10-meeting/references/meeting-minute-file.md +425 -0
- package/skills/weaver-e10-meeting/references/meeting-queries.md +4 -4
- package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +15 -15
- package/skills/weaver-e10-meeting/references/meeting-verification.md +19 -11
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-yepiaotong/SKILL.md +9 -5
- package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +1 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +6 -5
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +14 -11
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +97 -56
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +84 -60
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +142 -105
- package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +53 -194
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -7
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +164 -72
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +6 -0
- package/templates/meeting/invitation.docx +0 -0
|
@@ -0,0 +1,1361 @@
|
|
|
1
|
+
import { createRequire as __esbuildCreateRequire } from 'node:module';
|
|
2
|
+
const require = __esbuildCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
E10ApiError,
|
|
5
|
+
createE10RequestRuntime,
|
|
6
|
+
requireE10Session
|
|
7
|
+
} from "./chunk-DW6AUUKS.js";
|
|
8
|
+
import {
|
|
9
|
+
E10_SESSION_EXPIRED_MESSAGE,
|
|
10
|
+
getActiveProfile
|
|
11
|
+
} from "./chunk-2GA5ZIQL.js";
|
|
12
|
+
import {
|
|
13
|
+
CliError,
|
|
14
|
+
isCliError,
|
|
15
|
+
toErrorEnvelope
|
|
16
|
+
} from "./chunk-LUSPKZKY.js";
|
|
17
|
+
import "./chunk-BUSC6UAE.js";
|
|
18
|
+
|
|
19
|
+
// src/shortcuts/project/index.ts
|
|
20
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
21
|
+
|
|
22
|
+
// src/shortcuts/project/continuation.ts
|
|
23
|
+
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
24
|
+
import { existsSync } from "node:fs";
|
|
25
|
+
import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
26
|
+
import { homedir } from "node:os";
|
|
27
|
+
import { resolve } from "node:path";
|
|
28
|
+
|
|
29
|
+
// src/shortcuts/project/errors.ts
|
|
30
|
+
var ProjectCliError = class extends CliError {
|
|
31
|
+
type;
|
|
32
|
+
subtype;
|
|
33
|
+
code;
|
|
34
|
+
retryable;
|
|
35
|
+
stage;
|
|
36
|
+
details;
|
|
37
|
+
partialData;
|
|
38
|
+
constructor(type, subtype, message, options = {}) {
|
|
39
|
+
super(message, options.exitCode ?? 5 /* InternalError */);
|
|
40
|
+
this.name = "ProjectCliError";
|
|
41
|
+
this.type = type;
|
|
42
|
+
this.subtype = subtype;
|
|
43
|
+
this.code = options.code;
|
|
44
|
+
this.retryable = options.retryable ?? false;
|
|
45
|
+
this.stage = options.stage;
|
|
46
|
+
this.details = options.details;
|
|
47
|
+
this.partialData = options.partialData;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
function projectValidationError(subtype, message, details) {
|
|
51
|
+
return new ProjectCliError("validation", subtype, message, {
|
|
52
|
+
details,
|
|
53
|
+
exitCode: 2 /* UsageError */
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function projectAuthError(subtype, message, details) {
|
|
57
|
+
return new ProjectCliError("authentication", subtype, message, {
|
|
58
|
+
details,
|
|
59
|
+
exitCode: 3 /* AuthError */
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function projectNetworkError(subtype, message, options = {}) {
|
|
63
|
+
return new ProjectCliError("network", subtype, message, {
|
|
64
|
+
...options,
|
|
65
|
+
retryable: options.retryable ?? true,
|
|
66
|
+
exitCode: 4 /* NetworkError */
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function projectApiError(subtype, message, details) {
|
|
70
|
+
return new ProjectCliError("api", subtype, message, {
|
|
71
|
+
details,
|
|
72
|
+
exitCode: 1 /* GeneralError */
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function projectPartialError(message, partialData, details) {
|
|
76
|
+
return new ProjectCliError("partial", "write_uncertain", message, {
|
|
77
|
+
details,
|
|
78
|
+
partialData,
|
|
79
|
+
exitCode: 11 /* Partial */
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/shortcuts/project/continuation.ts
|
|
84
|
+
function projectStateRoot(ctx) {
|
|
85
|
+
const configured = ctx?.config?.path();
|
|
86
|
+
if (configured) return resolve(configured, "..");
|
|
87
|
+
return process.env.WEAVER_WORK_CLI_HOME || process.env.WORK_CLI_HOME || resolve(homedir(), ".weaver-work-cli");
|
|
88
|
+
}
|
|
89
|
+
async function loadKey(ctx) {
|
|
90
|
+
const keysDir = resolve(projectStateRoot(ctx), "keys");
|
|
91
|
+
const filename = resolve(keysDir, "project-continuation.key");
|
|
92
|
+
await mkdir(keysDir, { recursive: true, mode: 448 });
|
|
93
|
+
if (existsSync(filename)) return readFile(filename);
|
|
94
|
+
const key = randomBytes(32);
|
|
95
|
+
try {
|
|
96
|
+
await writeFile(filename, key, { flag: "wx", mode: 384 });
|
|
97
|
+
if (process.platform !== "win32") await chmod(filename, 384).catch(() => void 0);
|
|
98
|
+
return key;
|
|
99
|
+
} catch {
|
|
100
|
+
return readFile(filename);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function encode(value) {
|
|
104
|
+
return Buffer.from(JSON.stringify(value)).toString("base64url");
|
|
105
|
+
}
|
|
106
|
+
function signature(payload, key) {
|
|
107
|
+
return createHmac("sha256", key).update(payload).digest("base64url");
|
|
108
|
+
}
|
|
109
|
+
function createProjectContinuationSigner(ctx) {
|
|
110
|
+
return {
|
|
111
|
+
async issue(payload, ttlMs = 10 * 6e4) {
|
|
112
|
+
const issuedAt = Date.now();
|
|
113
|
+
const body = encode({ ...payload, issuedAt, expiresAt: issuedAt + ttlMs });
|
|
114
|
+
const sig = signature(body, await loadKey(ctx));
|
|
115
|
+
return `${body}.${sig}`;
|
|
116
|
+
},
|
|
117
|
+
async verify(token, expectedOperation) {
|
|
118
|
+
if (typeof token !== "string" || !token.includes(".")) {
|
|
119
|
+
throw projectValidationError("continuation_invalid", "continuation \u65E0\u6548");
|
|
120
|
+
}
|
|
121
|
+
const [body, provided] = token.split(".");
|
|
122
|
+
const expected = signature(body, await loadKey(ctx));
|
|
123
|
+
const valid = provided.length === expected.length && timingSafeEqual(Buffer.from(provided), Buffer.from(expected));
|
|
124
|
+
if (!valid) throw projectValidationError("continuation_invalid", "continuation \u7B7E\u540D\u6821\u9A8C\u5931\u8D25");
|
|
125
|
+
let value;
|
|
126
|
+
try {
|
|
127
|
+
value = JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
|
|
128
|
+
} catch {
|
|
129
|
+
throw projectValidationError("continuation_invalid", "continuation \u5185\u5BB9\u65E0\u6CD5\u89E3\u6790");
|
|
130
|
+
}
|
|
131
|
+
if (value.operation !== expectedOperation) {
|
|
132
|
+
throw projectValidationError("continuation_mismatch", "continuation \u4E0D\u5C5E\u4E8E\u5F53\u524D\u64CD\u4F5C");
|
|
133
|
+
}
|
|
134
|
+
if (!Number.isSafeInteger(value.expiresAt) || value.expiresAt < Date.now()) {
|
|
135
|
+
throw projectValidationError("continuation_expired", "continuation \u5DF2\u8FC7\u671F");
|
|
136
|
+
}
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/shortcuts/project/host.ts
|
|
143
|
+
var PROJECT_PATH_PREFIXES = [
|
|
144
|
+
"/api/ebuilder/form/formdata/v2/",
|
|
145
|
+
"/api/ebuilder/form/dataset/v2/",
|
|
146
|
+
"/api/ebuilder/common/ds/",
|
|
147
|
+
"/api/ebproject/backendConsole/",
|
|
148
|
+
"/api/bs/ebuilder/app/tags/",
|
|
149
|
+
"/api/hrm/common/browser/",
|
|
150
|
+
"/api/installer/public/"
|
|
151
|
+
];
|
|
152
|
+
function inferProfile(ctx) {
|
|
153
|
+
const options = ctx.getGlobalOptions();
|
|
154
|
+
return options.profile || getActiveProfile();
|
|
155
|
+
}
|
|
156
|
+
function businessMessage(value) {
|
|
157
|
+
if (!value || typeof value !== "object") return "\u6CDB\u5FAE\u63A5\u53E3\u8FD4\u56DE\u4E1A\u52A1\u5931\u8D25";
|
|
158
|
+
const candidates = [
|
|
159
|
+
value.msg,
|
|
160
|
+
value.message,
|
|
161
|
+
value.resultMsg,
|
|
162
|
+
value.datajson?.message,
|
|
163
|
+
value.datajson?.msg,
|
|
164
|
+
value.data?.message
|
|
165
|
+
];
|
|
166
|
+
for (const item of candidates) {
|
|
167
|
+
if (typeof item === "string" && item.trim()) return item;
|
|
168
|
+
}
|
|
169
|
+
return "\u6CDB\u5FAE\u63A5\u53E3\u8FD4\u56DE\u4E1A\u52A1\u5931\u8D25";
|
|
170
|
+
}
|
|
171
|
+
function isDatajsonSuccess(value) {
|
|
172
|
+
const status = value?.datajson?.status;
|
|
173
|
+
return status === true || status === "true";
|
|
174
|
+
}
|
|
175
|
+
function isWeaverSuccess(value) {
|
|
176
|
+
if (!value || typeof value !== "object") return false;
|
|
177
|
+
return Number(value.code) === 200 && value.fail !== true && value.status !== false && value.status !== "false";
|
|
178
|
+
}
|
|
179
|
+
function assertDatajsonSuccess(value, operation) {
|
|
180
|
+
if (!isDatajsonSuccess(value)) {
|
|
181
|
+
throw projectApiError("business_failed", businessMessage(value), { operation, response: value });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function assertWeaverSuccess(value, operation) {
|
|
185
|
+
if (!isWeaverSuccess(value)) {
|
|
186
|
+
throw projectApiError("business_failed", businessMessage(value), { operation, response: value });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function assertPath(requestPath) {
|
|
190
|
+
if (typeof requestPath !== "string" || !requestPath.startsWith("/") || requestPath.startsWith("//")) {
|
|
191
|
+
throw projectValidationError("path_invalid", "\u8BF7\u6C42\u8DEF\u5F84\u5FC5\u987B\u662F\u76F8\u5BF9\u7EDD\u5BF9\u8DEF\u5F84");
|
|
192
|
+
}
|
|
193
|
+
if (/^https?:/i.test(requestPath) || /[\r\n]/.test(requestPath) || requestPath.includes("/../")) {
|
|
194
|
+
throw projectValidationError("path_invalid", "\u8BF7\u6C42\u8DEF\u5F84\u4E0D\u5141\u8BB8\u8DE8\u57DF\u6216\u8DEF\u5F84\u9003\u9038");
|
|
195
|
+
}
|
|
196
|
+
if (!PROJECT_PATH_PREFIXES.some((prefix) => requestPath.startsWith(prefix))) {
|
|
197
|
+
throw projectValidationError("path_not_allowed", "\u4E8B\u4E95\u7136\u9879\u76EE\u6A21\u5757\u53EA\u80FD\u8C03\u7528\u6E90\u8D44\u6599\u5141\u8BB8\u7684 /api/ \u8DEF\u5F84");
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function omitEmptyQueryValues(query) {
|
|
201
|
+
if (!query) return void 0;
|
|
202
|
+
return Object.fromEntries(
|
|
203
|
+
Object.entries(query).filter(([, value]) => value !== "" && value !== void 0 && value !== null)
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
function mapRuntimeNetworkError(error) {
|
|
207
|
+
if (error instanceof E10ApiError && error.type === "network") {
|
|
208
|
+
throw projectNetworkError(error.subtype, error.message, {
|
|
209
|
+
retryable: error.retryable,
|
|
210
|
+
details: error.details
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
function createProjectHost(ctx, dependencies = {}) {
|
|
216
|
+
let e10Session = null;
|
|
217
|
+
let sessionContext = null;
|
|
218
|
+
const requireSession = dependencies.requireSession || requireE10Session;
|
|
219
|
+
async function ensureSession() {
|
|
220
|
+
if (!e10Session) {
|
|
221
|
+
e10Session = await requireSession(ctx);
|
|
222
|
+
sessionContext = {
|
|
223
|
+
baseUrl: e10Session.getBaseUrl(),
|
|
224
|
+
profile: inferProfile(ctx),
|
|
225
|
+
userId: e10Session.userId,
|
|
226
|
+
tenantKey: e10Session.tenantKey,
|
|
227
|
+
eteamsId: e10Session.eteamsId
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
return e10Session;
|
|
231
|
+
}
|
|
232
|
+
async function getSession() {
|
|
233
|
+
await ensureSession();
|
|
234
|
+
return sessionContext;
|
|
235
|
+
}
|
|
236
|
+
async function runtime() {
|
|
237
|
+
return createE10RequestRuntime(ctx, await ensureSession(), {
|
|
238
|
+
interceptors: dependencies.interceptors,
|
|
239
|
+
fetch: dependencies.fetch
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
async function request(request2) {
|
|
243
|
+
const { method, path, query, body, formData, operation, timeoutMs = 3e4 } = request2;
|
|
244
|
+
assertPath(path);
|
|
245
|
+
let effectiveBody = body;
|
|
246
|
+
let effectiveFormData;
|
|
247
|
+
if (formData) {
|
|
248
|
+
effectiveFormData = new FormData();
|
|
249
|
+
for (const [key, value] of Object.entries(formData)) {
|
|
250
|
+
if (value !== void 0) effectiveFormData.append(key, String(value));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
let response;
|
|
254
|
+
try {
|
|
255
|
+
response = await (await runtime()).requestJson({
|
|
256
|
+
module: "project",
|
|
257
|
+
operation,
|
|
258
|
+
method: (method || "POST").toUpperCase(),
|
|
259
|
+
path,
|
|
260
|
+
query: omitEmptyQueryValues(query),
|
|
261
|
+
body: effectiveBody,
|
|
262
|
+
formData: effectiveFormData,
|
|
263
|
+
headers: { "X-Requested-With": "XMLHttpRequest" },
|
|
264
|
+
timeoutMs
|
|
265
|
+
});
|
|
266
|
+
} catch (error) {
|
|
267
|
+
mapRuntimeNetworkError(error);
|
|
268
|
+
}
|
|
269
|
+
if (response.status === 401 || response.status === 302) {
|
|
270
|
+
throw projectAuthError("session_expired", E10_SESSION_EXPIRED_MESSAGE, {
|
|
271
|
+
httpStatus: response.status
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
if (response.parseError) {
|
|
275
|
+
throw projectNetworkError("protocol", `\u63A5\u53E3\u8FD4\u56DE\u4E0D\u662F\u5408\u6CD5 JSON\uFF08HTTP ${response.status}\uFF09`, { retryable: false });
|
|
276
|
+
}
|
|
277
|
+
if (response.status === 404) {
|
|
278
|
+
throw new ProjectCliError("api", "endpoint_not_found", `\u63A5\u53E3\u8FD4\u56DE 404\uFF0C\u5F53\u524D\u73AF\u5883\u53EF\u80FD\u672A\u5B89\u88C5\u4E8B\u4E95\u7136\u9879\u76EE\u5E94\u7528\u6216\u63A5\u53E3\u4E0D\u5B58\u5728\uFF08${path}\uFF09`, {
|
|
279
|
+
code: response.status,
|
|
280
|
+
details: { path },
|
|
281
|
+
exitCode: 1
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
if (response.status < 200 || response.status >= 300) {
|
|
285
|
+
throw new ProjectCliError("api", "http_error", `\u6CDB\u5FAE\u63A5\u53E3 HTTP ${response.status}`, {
|
|
286
|
+
code: response.status,
|
|
287
|
+
details: { status: response.status, message: businessMessage(response.value) },
|
|
288
|
+
exitCode: 1
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
return response.value;
|
|
292
|
+
}
|
|
293
|
+
return { request, getSession };
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// src/shortcuts/project/operations/types.ts
|
|
297
|
+
function projectSuccess(action, data, meta) {
|
|
298
|
+
const payload = { ok: true, action, data };
|
|
299
|
+
if (meta && Object.keys(meta).length > 0) payload.meta = meta;
|
|
300
|
+
return payload;
|
|
301
|
+
}
|
|
302
|
+
function schemaOf(properties, options = {}) {
|
|
303
|
+
return {
|
|
304
|
+
type: "object",
|
|
305
|
+
additionalProperties: false,
|
|
306
|
+
properties,
|
|
307
|
+
...options.required?.length ? { required: options.required } : {},
|
|
308
|
+
...options.oneOf?.length ? { oneOf: options.oneOf } : {},
|
|
309
|
+
...options.anyOf?.length ? { anyOf: options.anyOf } : {},
|
|
310
|
+
...options.description ? { description: options.description } : {}
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
var SCHEMA_ID_STRING = { type: "string", minLength: 1, pattern: "^\\d+$" };
|
|
314
|
+
var SCHEMA_PAGE_NO = { type: "integer", minimum: 1, default: 1 };
|
|
315
|
+
var SCHEMA_PAGE_SIZE = { type: "integer", minimum: 1, maximum: 1e3, default: 10 };
|
|
316
|
+
var SCHEMA_FILTERS = {
|
|
317
|
+
type: "object",
|
|
318
|
+
additionalProperties: true,
|
|
319
|
+
description: "\u6E90\u63A5\u53E3 mainTable \u8FC7\u6EE4\u5B57\u6BB5\u3002\u4EC5\u4F20\u7528\u6237\u660E\u786E\u6307\u5B9A\u7684\u5B57\u6BB5\uFF1B\u7A7A\u5B57\u7B26\u4E32\u4F1A\u88AB\u89C6\u4E3A\u672A\u6307\u5B9A\u3002"
|
|
320
|
+
};
|
|
321
|
+
var SCHEMA_FIELDS = {
|
|
322
|
+
type: "object",
|
|
323
|
+
additionalProperties: true,
|
|
324
|
+
description: "\u6E90\u63A5\u53E3 mainTable \u5B57\u6BB5\u3002\u5B57\u6BB5\u540D\u548C\u53D6\u503C\u5FC5\u987B\u5148\u6309\u6A21\u5757 reference \u5B8C\u6210\u540D\u79F0\u5230 ID \u7684\u89E3\u6790\u3002"
|
|
325
|
+
};
|
|
326
|
+
var SCHEMA_RECORDS = {
|
|
327
|
+
type: "array",
|
|
328
|
+
minItems: 1,
|
|
329
|
+
maxItems: 100,
|
|
330
|
+
items: SCHEMA_FIELDS,
|
|
331
|
+
description: "\u5F85\u5199\u5165\u8BB0\u5F55\uFF0C\u6700\u591A 100 \u6761\uFF0C\u603B\u5927\u5C0F\u4E0D\u5F97\u8D85\u8FC7 10M\u3002"
|
|
332
|
+
};
|
|
333
|
+
var SCHEMA_CONFIRM = { const: true, description: "\u5FC5\u987B\u4E3A true\uFF0C\u8868\u793A\u7528\u6237\u5DF2\u660E\u786E\u786E\u8BA4\u672C\u6B21\u5199\u5165\u3002" };
|
|
334
|
+
var SCHEMA_CONTINUATION = { type: "string", minLength: 1, description: "prepare \u8FD4\u56DE\u7684 continuation\uFF0C\u5FC5\u987B\u539F\u6837\u4F20\u5165\u3002" };
|
|
335
|
+
|
|
336
|
+
// src/shortcuts/project/operations/shared.ts
|
|
337
|
+
function asObject(value, field = "input") {
|
|
338
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
339
|
+
throw projectValidationError("field_invalid", `${field} \u5FC5\u987B\u662F JSON \u5BF9\u8C61`);
|
|
340
|
+
}
|
|
341
|
+
return value;
|
|
342
|
+
}
|
|
343
|
+
function assertNoForbiddenKeys(input) {
|
|
344
|
+
for (const key of Object.keys(input)) {
|
|
345
|
+
if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(key)) {
|
|
346
|
+
throw projectValidationError("field_invalid", `\u4E0D\u5141\u8BB8\u7684\u5B57\u6BB5\u540D\uFF1A${key}`);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function idString(value, field) {
|
|
351
|
+
if (value === void 0 || value === null || value === "") {
|
|
352
|
+
throw projectValidationError("field_required", `${field} \u4E0D\u80FD\u4E3A\u7A7A`);
|
|
353
|
+
}
|
|
354
|
+
const text = String(value);
|
|
355
|
+
if (!/^\d+$/.test(text)) throw projectValidationError("field_invalid", `${field} \u5FC5\u987B\u662F\u6570\u5B57 ID \u5B57\u7B26\u4E32`);
|
|
356
|
+
return text;
|
|
357
|
+
}
|
|
358
|
+
function positiveInt(value, field, fallback, maximum = 1e3) {
|
|
359
|
+
if (value === void 0 || value === null || value === "") return fallback;
|
|
360
|
+
const parsed = Number(value);
|
|
361
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > maximum) {
|
|
362
|
+
throw projectValidationError("field_invalid", `${field} \u5FC5\u987B\u662F 1-${maximum} \u7684\u6574\u6570`);
|
|
363
|
+
}
|
|
364
|
+
return parsed;
|
|
365
|
+
}
|
|
366
|
+
function compactFilters(value) {
|
|
367
|
+
if (!value) return {};
|
|
368
|
+
return Object.fromEntries(
|
|
369
|
+
Object.entries(value).filter(([, item]) => item !== void 0 && item !== null && item !== "")
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
function queryText(value, field) {
|
|
373
|
+
if (value === void 0 || value === null || value === "") return void 0;
|
|
374
|
+
if (typeof value !== "string") throw projectValidationError("field_invalid", `${field} \u5FC5\u987B\u662F\u5B57\u7B26\u4E32`);
|
|
375
|
+
return value;
|
|
376
|
+
}
|
|
377
|
+
async function operatorId(host) {
|
|
378
|
+
const session = await host.getSession();
|
|
379
|
+
if (!session.userId) throw projectValidationError("operator_missing", "\u5F53\u524D\u767B\u5F55\u4F1A\u8BDD\u7F3A\u5C11 operator\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55");
|
|
380
|
+
return session.userId;
|
|
381
|
+
}
|
|
382
|
+
function stableFingerprint(value) {
|
|
383
|
+
const text = JSON.stringify(value, (_key, item) => {
|
|
384
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
385
|
+
return Object.fromEntries(Object.entries(item).sort(([a], [b]) => a.localeCompare(b)));
|
|
386
|
+
}
|
|
387
|
+
return item;
|
|
388
|
+
});
|
|
389
|
+
let hash = 0;
|
|
390
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
391
|
+
hash = hash * 31 + text.charCodeAt(index) >>> 0;
|
|
392
|
+
}
|
|
393
|
+
return `${text.length}:${hash.toString(16)}`;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// src/shortcuts/project/operations/read.ts
|
|
397
|
+
var APP_TAG = "weaver-project-eb";
|
|
398
|
+
var DEFAULT_OBJ_IDS = { task: "1020270486210527232", project: "1020275562853482532" };
|
|
399
|
+
var MIN_VERSION = [20, 6, 11];
|
|
400
|
+
function buildCardUrl(baseUrl, objId, dataId) {
|
|
401
|
+
if (!baseUrl || !objId || !dataId || /[\s/\\?#]/u.test(dataId)) return null;
|
|
402
|
+
return `${baseUrl.replace(/\/+$/u, "")}/sp/ebdfpage/card/0/${objId}/${dataId}`;
|
|
403
|
+
}
|
|
404
|
+
var CURRENT_USER_FILTERS = /* @__PURE__ */ new Set([
|
|
405
|
+
"manager",
|
|
406
|
+
"participant",
|
|
407
|
+
"participants",
|
|
408
|
+
"tester",
|
|
409
|
+
"customer_manager",
|
|
410
|
+
"acceptance_manager"
|
|
411
|
+
]);
|
|
412
|
+
var SCHEMA_OUTPUT_FIELDS = {
|
|
413
|
+
type: "array",
|
|
414
|
+
minItems: 1,
|
|
415
|
+
maxItems: 50,
|
|
416
|
+
uniqueItems: true,
|
|
417
|
+
items: { type: "string", minLength: 1, maxLength: 100, pattern: "^[A-Za-z][A-Za-z0-9_]*" },
|
|
418
|
+
description: "\u53EF\u9009\uFF1B\u53EA\u4FDD\u7559\u6307\u5B9A mainTable \u5B57\u6BB5\u3002id \u548C\u8BB0\u5F55\u540D\u79F0\u5B57\u6BB5\u59CB\u7EC8\u4FDD\u7559\uFF1Bfields \u4E0D\u542B detail_url \u65F6\u4E0D\u4F1A\u89E3\u6790\u8BE6\u60C5\u94FE\u63A5\u3002"
|
|
419
|
+
};
|
|
420
|
+
async function resolveCurrentUserFilters(filters, host) {
|
|
421
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
422
|
+
if (value === "@me" && CURRENT_USER_FILTERS.has(key)) {
|
|
423
|
+
filters[key] = await operatorId(host);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
function outputFields(value) {
|
|
428
|
+
if (value === void 0) return null;
|
|
429
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
430
|
+
throw projectValidationError("field_invalid", "fields \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\u6570\u7EC4");
|
|
431
|
+
}
|
|
432
|
+
const fields = [];
|
|
433
|
+
for (const item of value) {
|
|
434
|
+
if (typeof item !== "string" || !/^[A-Za-z]/.test(item) || /[^A-Za-z0-9_]/.test(item)) {
|
|
435
|
+
throw projectValidationError("field_invalid", "fields \u5305\u542B\u975E\u6CD5\u5B57\u6BB5\u540D");
|
|
436
|
+
}
|
|
437
|
+
fields.push(item);
|
|
438
|
+
}
|
|
439
|
+
return [...new Set(fields)];
|
|
440
|
+
}
|
|
441
|
+
function compactDatajson(datajson, fields, requiredFields) {
|
|
442
|
+
if (!fields) return datajson;
|
|
443
|
+
const keep = /* @__PURE__ */ new Set([...fields, "id", "detail_url", ...requiredFields]);
|
|
444
|
+
const value = datajson;
|
|
445
|
+
const rows = Array.isArray(value?.datas) ? value.datas : [];
|
|
446
|
+
for (const row of rows) {
|
|
447
|
+
const mainTable = row?.mainTable;
|
|
448
|
+
if (!mainTable || typeof mainTable !== "object" || Array.isArray(mainTable)) continue;
|
|
449
|
+
row.mainTable = Object.fromEntries(
|
|
450
|
+
Object.entries(mainTable).filter(([key]) => keep.has(key))
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
return datajson;
|
|
454
|
+
}
|
|
455
|
+
function normalizeFieldNames(value, inputName) {
|
|
456
|
+
if (value === void 0) return [];
|
|
457
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
458
|
+
throw projectValidationError("field_invalid", `${inputName} \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\u6570\u7EC4`);
|
|
459
|
+
}
|
|
460
|
+
const names = [];
|
|
461
|
+
for (const item of value) {
|
|
462
|
+
if (typeof item !== "string" || item.trim() === "" || item.length > 100) {
|
|
463
|
+
throw projectValidationError("field_invalid", `${inputName} \u5305\u542B\u975E\u6CD5\u5B57\u6BB5\u540D`);
|
|
464
|
+
}
|
|
465
|
+
names.push(item);
|
|
466
|
+
}
|
|
467
|
+
return [...new Set(names)];
|
|
468
|
+
}
|
|
469
|
+
function filterFormFieldResponse(response, fieldNames, fieldKeyword) {
|
|
470
|
+
if (fieldNames.length === 0 && !fieldKeyword) return response;
|
|
471
|
+
if (!response || typeof response !== "object") return response;
|
|
472
|
+
const groups = response?.data?.data;
|
|
473
|
+
if (!Array.isArray(groups)) return response;
|
|
474
|
+
const keyword = fieldKeyword?.toLowerCase() ?? null;
|
|
475
|
+
const nextGroups = groups.map((group) => {
|
|
476
|
+
if (!group || typeof group !== "object" || !Array.isArray(group.fields)) return group;
|
|
477
|
+
return {
|
|
478
|
+
...group,
|
|
479
|
+
fields: group.fields.filter((field) => {
|
|
480
|
+
if (!field || typeof field !== "object") return false;
|
|
481
|
+
const name = typeof field.name === "string" ? field.name : "";
|
|
482
|
+
const text = typeof field.text === "string" ? field.text : "";
|
|
483
|
+
if (fieldNames.length > 0) return fieldNames.includes(name);
|
|
484
|
+
return keyword ? name.toLowerCase().includes(keyword) || text.toLowerCase().includes(keyword) : true;
|
|
485
|
+
})
|
|
486
|
+
};
|
|
487
|
+
});
|
|
488
|
+
return { ...response, data: { ...response.data, data: nextGroups } };
|
|
489
|
+
}
|
|
490
|
+
function operationTable(name) {
|
|
491
|
+
return name === "project.project.list" || name === "project.project.detail" ? "project" : "task";
|
|
492
|
+
}
|
|
493
|
+
async function decorateDetailUrls(host, operation, datajson) {
|
|
494
|
+
const value = datajson;
|
|
495
|
+
const rows = Array.isArray(value?.datas) ? value.datas : [];
|
|
496
|
+
const targets = rows.map((row) => row?.mainTable).filter((row) => row?.id !== void 0 && row?.id !== null);
|
|
497
|
+
if (targets.length === 0) return datajson;
|
|
498
|
+
try {
|
|
499
|
+
const objId = await getObject(host, operationTable(operation));
|
|
500
|
+
const session = await host.getSession();
|
|
501
|
+
for (const row of targets) {
|
|
502
|
+
const url = buildCardUrl(session.baseUrl, objId, String(row.id));
|
|
503
|
+
if (url) row.detail_url = url;
|
|
504
|
+
}
|
|
505
|
+
} catch (error) {
|
|
506
|
+
if (value && typeof value === "object") {
|
|
507
|
+
value.detail_url_warning = `\u8BE6\u60C5\u94FE\u63A5\u6682\u4E0D\u53EF\u7528\uFF1A${error instanceof Error ? error.message : String(error)}\uFF1B\u4E3B\u67E5\u8BE2\u5DF2\u6210\u529F\uFF0C\u4E0D\u8981\u56E0\u6B64\u91CD\u8BD5\u3002`;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
return datajson;
|
|
511
|
+
}
|
|
512
|
+
function table(value) {
|
|
513
|
+
if (value !== "task" && value !== "project") {
|
|
514
|
+
throw projectValidationError("field_invalid", "table \u5FC5\u987B\u662F task \u6216 project");
|
|
515
|
+
}
|
|
516
|
+
return value;
|
|
517
|
+
}
|
|
518
|
+
function versionAtLeast(version) {
|
|
519
|
+
const parts = version.split(".").map((item) => Number(item) || 0);
|
|
520
|
+
for (let index = 0; index < Math.max(parts.length, MIN_VERSION.length); index += 1) {
|
|
521
|
+
const left = parts[index] ?? 0;
|
|
522
|
+
const right = MIN_VERSION[index] ?? 0;
|
|
523
|
+
if (left > right) return true;
|
|
524
|
+
if (left < right) return false;
|
|
525
|
+
}
|
|
526
|
+
return true;
|
|
527
|
+
}
|
|
528
|
+
async function getAppId(host) {
|
|
529
|
+
const response = await host.request({
|
|
530
|
+
method: "GET",
|
|
531
|
+
path: "/api/bs/ebuilder/app/tags/getAppIds",
|
|
532
|
+
query: { tag: APP_TAG },
|
|
533
|
+
operation: "project.app.ids"
|
|
534
|
+
});
|
|
535
|
+
assertWeaverSuccess(response, "project.app.ids");
|
|
536
|
+
const data = response?.data;
|
|
537
|
+
const appId = Array.isArray(data) && data.length > 0 ? String(data[0]) : "";
|
|
538
|
+
if (!appId) throw new Error("\u5F53\u524D\u73AF\u5883\u672A\u5B89\u88C5\u4E8B\u4E95\u7136\u9879\u76EE\u7BA1\u7406\u5E94\u7528");
|
|
539
|
+
return appId;
|
|
540
|
+
}
|
|
541
|
+
async function getObject(host, value) {
|
|
542
|
+
const response = await host.request({
|
|
543
|
+
method: "GET",
|
|
544
|
+
path: "/api/ebproject/backendConsole/getCurrentObjId",
|
|
545
|
+
query: { objId: DEFAULT_OBJ_IDS[value] },
|
|
546
|
+
operation: "project.object.id"
|
|
547
|
+
});
|
|
548
|
+
assertWeaverSuccess(response, "project.object.id");
|
|
549
|
+
const object = String(response?.data ?? "");
|
|
550
|
+
if (!object) throw new Error("\u63A5\u53E3\u672A\u8FD4\u56DE\u5F53\u524D\u73AF\u5883\u5BF9\u8C61 ID");
|
|
551
|
+
return object;
|
|
552
|
+
}
|
|
553
|
+
async function datajsonRequest(host, operation, path, payload, query) {
|
|
554
|
+
const response = await host.request({
|
|
555
|
+
method: "POST",
|
|
556
|
+
path,
|
|
557
|
+
query,
|
|
558
|
+
body: { datajson: JSON.stringify(payload) },
|
|
559
|
+
operation
|
|
560
|
+
});
|
|
561
|
+
assertDatajsonSuccess(response, operation);
|
|
562
|
+
return response;
|
|
563
|
+
}
|
|
564
|
+
function listOperation(name, path, nameField, descField, statusField) {
|
|
565
|
+
return {
|
|
566
|
+
name,
|
|
567
|
+
resource: "project",
|
|
568
|
+
method: "list",
|
|
569
|
+
action: name,
|
|
570
|
+
summary: "\u5206\u9875\u67E5\u8BE2\u9879\u76EE/\u4EFB\u52A1\u5217\u8868\uFF0C\u9ED8\u8BA4\u7B2C 1 \u9875 10 \u6761\uFF0C\u672A\u6307\u5B9A\u72B6\u6001\u65F6\u4EC5\u67E5\u8BE2\u672A\u5F00\u59CB\u548C\u8FDB\u884C\u4E2D",
|
|
571
|
+
risk: "read",
|
|
572
|
+
inputSchema: schemaOf({
|
|
573
|
+
filters: SCHEMA_FILTERS,
|
|
574
|
+
pageNo: SCHEMA_PAGE_NO,
|
|
575
|
+
pageSize: SCHEMA_PAGE_SIZE,
|
|
576
|
+
name: { type: "string", description: `${nameField} \u6A21\u7CCA\u641C\u7D22\uFF0C\u901A\u8FC7 URL Query \u4F20\u9012` },
|
|
577
|
+
description: { type: "string", description: `${descField} \u6A21\u7CCA\u641C\u7D22\uFF0C\u901A\u8FC7 URL Query \u4F20\u9012` },
|
|
578
|
+
allStatuses: { type: "boolean", default: false, description: "\u4E3A true \u65F6\u4E0D\u4F20\u7CFB\u7EDF\u72B6\u6001\u548C\u4E1A\u52A1\u72B6\u6001\uFF0C\u67E5\u8BE2\u5168\u90E8\u72B6\u6001\uFF1B\u4E0D\u80FD\u4E0E\u4E1A\u52A1\u72B6\u6001\u540C\u65F6\u4F20" },
|
|
579
|
+
withDetailUrl: { type: "boolean", default: true, description: "\u662F\u5426\u4E3A\u6BCF\u6761\u8BB0\u5F55\u8865\u5145 detail_url\uFF1B\u4F20 false \u53EF\u8DF3\u8FC7\u94FE\u63A5\u89E3\u6790" },
|
|
580
|
+
fields: SCHEMA_OUTPUT_FIELDS
|
|
581
|
+
}),
|
|
582
|
+
handler: async (args, { host }) => {
|
|
583
|
+
const pageNo = positiveInt(args.pageNo, "pageNo", 1);
|
|
584
|
+
const pageSize = positiveInt(args.pageSize, "pageSize", 10);
|
|
585
|
+
const filters = compactFilters(args.filters);
|
|
586
|
+
await resolveCurrentUserFilters(filters, host);
|
|
587
|
+
const allStatuses = args.allStatuses === true;
|
|
588
|
+
if (allStatuses && (filters.sys_status !== void 0 || filters[statusField] !== void 0)) {
|
|
589
|
+
throw projectValidationError("field_conflict", "allStatuses \u4E0D\u80FD\u4E0E sys_status \u6216\u4E1A\u52A1\u72B6\u6001\u540C\u65F6\u4F20");
|
|
590
|
+
}
|
|
591
|
+
if (allStatuses) {
|
|
592
|
+
delete filters.sys_status;
|
|
593
|
+
} else if (filters[statusField] === void 0 && filters.sys_status === void 0) {
|
|
594
|
+
filters.sys_status = "todo,doing";
|
|
595
|
+
} else if (filters[statusField] !== void 0) {
|
|
596
|
+
delete filters.sys_status;
|
|
597
|
+
}
|
|
598
|
+
const response = await datajsonRequest(host, name, path, {
|
|
599
|
+
mainTable: filters,
|
|
600
|
+
pageInfo: { pageNo, pageSize },
|
|
601
|
+
header: { operator: await operatorId(host) }
|
|
602
|
+
}, {
|
|
603
|
+
[nameField]: queryText(args.name, "name"),
|
|
604
|
+
[descField]: queryText(args.description, "description")
|
|
605
|
+
});
|
|
606
|
+
const fields = outputFields(args.fields);
|
|
607
|
+
const shouldDecorate = args.withDetailUrl !== false && (!fields || fields.includes("detail_url"));
|
|
608
|
+
const decorated = shouldDecorate ? await decorateDetailUrls(host, name, response?.datajson ?? null) : response?.datajson ?? null;
|
|
609
|
+
const datajson = compactDatajson(decorated, fields, [nameField]);
|
|
610
|
+
return projectSuccess(name, datajson, { pageNo, pageSize });
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
function detailOperation(name, path, nameField) {
|
|
615
|
+
return {
|
|
616
|
+
name,
|
|
617
|
+
resource: "project",
|
|
618
|
+
method: "detail",
|
|
619
|
+
action: name,
|
|
620
|
+
summary: "\u6309\u4E3B\u952E\u67E5\u8BE2\u5355\u6761\u9879\u76EE/\u4EFB\u52A1\u8BE6\u60C5",
|
|
621
|
+
risk: "read",
|
|
622
|
+
inputSchema: schemaOf({
|
|
623
|
+
id: SCHEMA_ID_STRING,
|
|
624
|
+
withDetailUrl: { type: "boolean", default: true, description: "\u662F\u5426\u4E3A\u8BB0\u5F55\u8865\u5145 detail_url\uFF1B\u4F20 false \u53EF\u8DF3\u8FC7\u94FE\u63A5\u89E3\u6790" },
|
|
625
|
+
fields: SCHEMA_OUTPUT_FIELDS
|
|
626
|
+
}, { required: ["id"] }),
|
|
627
|
+
handler: async (args, { host }) => {
|
|
628
|
+
const id = idString(args.id, "id");
|
|
629
|
+
const response = await datajsonRequest(host, name, path, {
|
|
630
|
+
mainTable: { id },
|
|
631
|
+
header: { operator: await operatorId(host) }
|
|
632
|
+
});
|
|
633
|
+
const fields = outputFields(args.fields);
|
|
634
|
+
const shouldDecorate = args.withDetailUrl !== false && (!fields || fields.includes("detail_url"));
|
|
635
|
+
const decorated = shouldDecorate ? await decorateDetailUrls(host, name, response?.datajson ?? null) : response?.datajson ?? null;
|
|
636
|
+
const datajson = compactDatajson(decorated, fields, [nameField]);
|
|
637
|
+
return projectSuccess(name, datajson, { id });
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
function dictionaryOperation(name, path, summary) {
|
|
642
|
+
return {
|
|
643
|
+
name,
|
|
644
|
+
resource: "project",
|
|
645
|
+
method: "dictionary",
|
|
646
|
+
action: name,
|
|
647
|
+
summary,
|
|
648
|
+
risk: "read",
|
|
649
|
+
inputSchema: schemaOf({
|
|
650
|
+
filters: SCHEMA_FILTERS,
|
|
651
|
+
pageNo: { ...SCHEMA_PAGE_NO, default: 1 },
|
|
652
|
+
pageSize: { ...SCHEMA_PAGE_SIZE, default: 100 },
|
|
653
|
+
fields: SCHEMA_OUTPUT_FIELDS
|
|
654
|
+
}),
|
|
655
|
+
handler: async (args, { host }) => {
|
|
656
|
+
const pageNo = positiveInt(args.pageNo, "pageNo", 1);
|
|
657
|
+
const pageSize = positiveInt(args.pageSize, "pageSize", 100);
|
|
658
|
+
const response = await datajsonRequest(host, name, path, {
|
|
659
|
+
mainTable: compactFilters(args.filters),
|
|
660
|
+
pageInfo: { pageNo, pageSize },
|
|
661
|
+
header: { operator: await operatorId(host) }
|
|
662
|
+
});
|
|
663
|
+
const datajson = compactDatajson(response?.datajson ?? null, outputFields(args.fields), []);
|
|
664
|
+
return projectSuccess(name, datajson, { pageNo, pageSize });
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
function hrmOperation(name, path, kind, summary) {
|
|
669
|
+
return {
|
|
670
|
+
name,
|
|
671
|
+
resource: "project",
|
|
672
|
+
method: "resolve",
|
|
673
|
+
action: name,
|
|
674
|
+
summary,
|
|
675
|
+
risk: "read",
|
|
676
|
+
inputSchema: schemaOf({
|
|
677
|
+
name: { type: "string", minLength: 1 },
|
|
678
|
+
match: { type: "string", enum: ["exact", "fuzzy"], default: "exact" },
|
|
679
|
+
...kind === "employee" ? { status: { type: "string", enum: ["normal", "all"], default: "normal" } } : {}
|
|
680
|
+
}, { required: ["name"] }),
|
|
681
|
+
handler: async (args, { host }) => {
|
|
682
|
+
const body = kind === "employee" ? {
|
|
683
|
+
browserMultiple: true,
|
|
684
|
+
authWecahtBook: false,
|
|
685
|
+
wxDepNeedConvertCount: 0,
|
|
686
|
+
wxEmpNeedConvertCount: 0,
|
|
687
|
+
wxTotalNeedConvertCount: 0,
|
|
688
|
+
cmd: "all",
|
|
689
|
+
current: 1,
|
|
690
|
+
pageSize: 30,
|
|
691
|
+
formDatas: {
|
|
692
|
+
username: [{ usernameOpt: args.match === "fuzzy" ? "in" : "eq", usernameInput: args.name }],
|
|
693
|
+
status: [{ statusSelect: args.status === "all" ? [] : ["normal"] }]
|
|
694
|
+
},
|
|
695
|
+
quickSearchDatas: {},
|
|
696
|
+
type: "and",
|
|
697
|
+
containsNoneAccount: false,
|
|
698
|
+
containsPartTimeEmployee: false
|
|
699
|
+
} : {
|
|
700
|
+
browserMultiple: true,
|
|
701
|
+
virtualType: "ALL",
|
|
702
|
+
cmd: "list",
|
|
703
|
+
current: 1,
|
|
704
|
+
pageSize: 200,
|
|
705
|
+
formDatas: {
|
|
706
|
+
name: [{
|
|
707
|
+
nameCondition: { id: args.match === "fuzzy" ? "in" : "eq", content: "\u7B49\u4E8E", disabled: false },
|
|
708
|
+
name: args.name
|
|
709
|
+
}]
|
|
710
|
+
},
|
|
711
|
+
quickSearchDatas: {},
|
|
712
|
+
type: "and",
|
|
713
|
+
stopDepartment: false
|
|
714
|
+
};
|
|
715
|
+
const response = await host.request({ method: "POST", path, body, operation: name });
|
|
716
|
+
assertWeaverSuccess(response, name);
|
|
717
|
+
const data = response?.data;
|
|
718
|
+
const rows = Array.isArray(data?.data) ? data.data : [];
|
|
719
|
+
return projectSuccess(name, {
|
|
720
|
+
total: typeof data?.total === "number" ? data.total : rows.length,
|
|
721
|
+
rows: rows.map((row) => ({
|
|
722
|
+
id: row?.id === void 0 || row?.id === null ? null : String(row.id),
|
|
723
|
+
name: row?.name ?? row?.title ?? null,
|
|
724
|
+
department: row?.department ?? row?.supDepartment ?? row?.supSubDepartment ?? null,
|
|
725
|
+
title: row?.title ?? null
|
|
726
|
+
}))
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
var projectReadOperations = [
|
|
732
|
+
{
|
|
733
|
+
name: "project.app.ids",
|
|
734
|
+
resource: "project",
|
|
735
|
+
method: "metadata",
|
|
736
|
+
action: "project.app.ids",
|
|
737
|
+
summary: "\u6309\u56FA\u5B9A\u5E94\u7528\u6807\u7B7E\u83B7\u53D6\u5F53\u524D\u73AF\u5883\u7684\u4E8B\u4E95\u7136\u5E94\u7528 ID",
|
|
738
|
+
risk: "read",
|
|
739
|
+
inputSchema: schemaOf({}),
|
|
740
|
+
handler: async (_args, { host }) => projectSuccess("project.app.ids", {
|
|
741
|
+
appId: await getAppId(host)
|
|
742
|
+
})
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
name: "project.object.id",
|
|
746
|
+
resource: "project",
|
|
747
|
+
method: "metadata",
|
|
748
|
+
action: "project.object.id",
|
|
749
|
+
summary: "\u5C06\u4EFB\u52A1/\u9879\u76EE\u51FA\u5382\u951A\u70B9\u8F6C\u6362\u6210\u5F53\u524D\u73AF\u5883\u5BF9\u8C61 ID",
|
|
750
|
+
risk: "read",
|
|
751
|
+
inputSchema: schemaOf(
|
|
752
|
+
{ table: { type: "string", enum: ["task", "project"] } },
|
|
753
|
+
{ required: ["table"] }
|
|
754
|
+
),
|
|
755
|
+
handler: async (args, { host }) => {
|
|
756
|
+
const value = table(args.table);
|
|
757
|
+
return projectSuccess("project.object.id", { table: value, objId: await getObject(host, value) });
|
|
758
|
+
}
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
name: "project.form.fields",
|
|
762
|
+
resource: "project",
|
|
763
|
+
method: "metadata",
|
|
764
|
+
action: "project.form.fields",
|
|
765
|
+
summary: "\u83B7\u53D6\u4EFB\u52A1/\u9879\u76EE\u8868\u5355\u5B57\u6BB5\u5B9A\u4E49\uFF1B\u672A\u4F20 groupId/sourceId \u65F6\u81EA\u52A8\u89E3\u6790",
|
|
766
|
+
risk: "read",
|
|
767
|
+
inputSchema: schemaOf({
|
|
768
|
+
table: { type: "string", enum: ["task", "project"] },
|
|
769
|
+
groupId: { type: "string", description: "\u53EF\u9009\uFF1B\u7F3A\u7701\u65F6\u81EA\u52A8\u8C03\u7528 project.app.ids" },
|
|
770
|
+
sourceId: { type: "string", description: "\u53EF\u9009\uFF1B\u7F3A\u7701\u65F6\u6309 table \u81EA\u52A8\u89E3\u6790\u5F53\u524D\u73AF\u5883 objId" },
|
|
771
|
+
detailFieldsGroup: { type: "boolean", default: true },
|
|
772
|
+
enableMerge: { type: "boolean", default: true },
|
|
773
|
+
fieldNames: {
|
|
774
|
+
type: "array",
|
|
775
|
+
minItems: 1,
|
|
776
|
+
maxItems: 50,
|
|
777
|
+
uniqueItems: true,
|
|
778
|
+
items: { type: "string", minLength: 1, maxLength: 100 },
|
|
779
|
+
description: "\u53EF\u9009\uFF1B\u53EA\u8FD4\u56DE\u6307\u5B9A name \u7684\u5B57\u6BB5\u5B9A\u4E49\u3002\u4E0E fieldKeyword \u540C\u65F6\u4F20\u65F6 fieldNames \u4F18\u5148\u3002"
|
|
780
|
+
},
|
|
781
|
+
fieldKeyword: {
|
|
782
|
+
type: "string",
|
|
783
|
+
minLength: 1,
|
|
784
|
+
maxLength: 100,
|
|
785
|
+
description: "\u53EF\u9009\uFF1B\u6309\u5B57\u6BB5 name/text \u6A21\u7CCA\u8FC7\u6EE4\u5B57\u6BB5\u5B9A\u4E49\uFF0C\u7528\u4E8E\u628A\u4E2D\u6587\u5B57\u6BB5\u540D\u89E3\u6790\u6210 field name\u3002"
|
|
786
|
+
}
|
|
787
|
+
}, { required: ["table"] }),
|
|
788
|
+
handler: async (args, { host }) => {
|
|
789
|
+
const value = table(args.table);
|
|
790
|
+
const groupId = args.groupId ? String(args.groupId) : await getAppId(host);
|
|
791
|
+
const sourceId = args.sourceId ? String(args.sourceId) : await getObject(host, value);
|
|
792
|
+
const response = await host.request({
|
|
793
|
+
method: "POST",
|
|
794
|
+
path: "/api/ebuilder/common/ds/fields",
|
|
795
|
+
formData: {
|
|
796
|
+
groupId,
|
|
797
|
+
sourceId,
|
|
798
|
+
sourceType: "FORM",
|
|
799
|
+
detailFieldsGroup: args.detailFieldsGroup === false ? "false" : "true",
|
|
800
|
+
enableMerge: args.enableMerge === false ? "false" : "true",
|
|
801
|
+
customParam: JSON.stringify({ terminal: "" }),
|
|
802
|
+
params: "[]"
|
|
803
|
+
},
|
|
804
|
+
operation: "project.form.fields"
|
|
805
|
+
});
|
|
806
|
+
assertWeaverSuccess(response, "project.form.fields");
|
|
807
|
+
const data = filterFormFieldResponse(
|
|
808
|
+
response,
|
|
809
|
+
normalizeFieldNames(args.fieldNames, "fieldNames"),
|
|
810
|
+
args.fieldKeyword === void 0 || args.fieldKeyword === null || args.fieldKeyword === "" ? null : String(args.fieldKeyword)
|
|
811
|
+
);
|
|
812
|
+
return projectSuccess("project.form.fields", data, { table: value, groupId, sourceId });
|
|
813
|
+
}
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
name: "project.form.options",
|
|
817
|
+
resource: "project",
|
|
818
|
+
method: "metadata",
|
|
819
|
+
action: "project.form.options",
|
|
820
|
+
summary: "\u83B7\u53D6\u9009\u62E9\u7C7B\u5B57\u6BB5\u9009\u9879\uFF1B\u672A\u4F20 groupId/sourceId \u65F6\u81EA\u52A8\u89E3\u6790",
|
|
821
|
+
risk: "read",
|
|
822
|
+
inputSchema: schemaOf({
|
|
823
|
+
table: { type: "string", enum: ["task", "project"] },
|
|
824
|
+
fieldName: { type: "string", minLength: 1 },
|
|
825
|
+
groupId: { type: "string" },
|
|
826
|
+
sourceId: { type: "string" },
|
|
827
|
+
optionLevel: { type: "integer", minimum: 1, default: 1 }
|
|
828
|
+
}, { required: ["table", "fieldName"] }),
|
|
829
|
+
handler: async (args, { host }) => {
|
|
830
|
+
const value = table(args.table);
|
|
831
|
+
const groupId = args.groupId ? String(args.groupId) : await getAppId(host);
|
|
832
|
+
const sourceId = args.sourceId ? String(args.sourceId) : await getObject(host, value);
|
|
833
|
+
const response = await host.request({
|
|
834
|
+
method: "GET",
|
|
835
|
+
path: "/api/ebuilder/common/ds/options",
|
|
836
|
+
query: {
|
|
837
|
+
fieldName: args.fieldName,
|
|
838
|
+
objId: sourceId,
|
|
839
|
+
sourceType: "FORM",
|
|
840
|
+
groupId,
|
|
841
|
+
optionLevel: args.optionLevel ?? 1
|
|
842
|
+
},
|
|
843
|
+
operation: "project.form.options"
|
|
844
|
+
});
|
|
845
|
+
assertWeaverSuccess(response, "project.form.options");
|
|
846
|
+
return projectSuccess("project.form.options", response, { table: value, groupId, sourceId });
|
|
847
|
+
}
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
name: "project.form.data.page",
|
|
851
|
+
resource: "project",
|
|
852
|
+
method: "metadata",
|
|
853
|
+
action: "project.form.data.page",
|
|
854
|
+
summary: "\u5728\u5173\u8054\u8868\u5355\u4E2D\u6309\u6807\u9898\u5B57\u6BB5\u5206\u9875\u67E5\u8BE2\u8BB0\u5F55\uFF0C\u7528\u4E8E Ebuilder \u540D\u79F0\u5230 ID \u89E3\u6790",
|
|
855
|
+
risk: "read",
|
|
856
|
+
inputSchema: schemaOf({
|
|
857
|
+
refObjId: SCHEMA_ID_STRING,
|
|
858
|
+
fieldKey: { type: "string", minLength: 1 },
|
|
859
|
+
value: { type: "string", minLength: 1 },
|
|
860
|
+
pageNo: SCHEMA_PAGE_NO,
|
|
861
|
+
pageSize: SCHEMA_PAGE_SIZE
|
|
862
|
+
}, { required: ["refObjId", "fieldKey", "value"] }),
|
|
863
|
+
handler: async (args, { host }) => {
|
|
864
|
+
const pageNo = positiveInt(args.pageNo, "pageNo", 1);
|
|
865
|
+
const pageSize = positiveInt(args.pageSize, "pageSize", 10);
|
|
866
|
+
const response = await host.request({
|
|
867
|
+
method: "POST",
|
|
868
|
+
path: "/api/ebuilder/form/dataset/v2/getAllData",
|
|
869
|
+
body: {
|
|
870
|
+
datajson: {
|
|
871
|
+
header: { objId: idString(args.refObjId, "refObjId") },
|
|
872
|
+
mainTable: { [String(args.fieldKey)]: args.value },
|
|
873
|
+
pageInfo: { pageNo, pageSize },
|
|
874
|
+
operationinfo: { isReturnDetail: "n", fieldNoFindIgnore: "false" }
|
|
875
|
+
}
|
|
876
|
+
},
|
|
877
|
+
operation: "project.form.data.page"
|
|
878
|
+
});
|
|
879
|
+
assertDatajsonSuccess(response?.data, "project.form.data.page");
|
|
880
|
+
return projectSuccess("project.form.data.page", response?.data?.datajson ?? null, { pageNo, pageSize });
|
|
881
|
+
}
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
name: "project.version.check",
|
|
885
|
+
resource: "project",
|
|
886
|
+
method: "diagnose",
|
|
887
|
+
action: "project.version.check",
|
|
888
|
+
summary: "\u67E5\u8BE2\u4E8B\u4E95\u7136\u5E94\u7528\u7248\u672C\u5E76\u5224\u65AD\u662F\u5426\u6EE1\u8DB3 20.6.11\uFF1B\u4EC5\u7528\u4E8E\u5F02\u5E38\u8BCA\u65AD\u6216\u7528\u6237\u4E3B\u52A8\u8BE2\u95EE",
|
|
889
|
+
risk: "read",
|
|
890
|
+
inputSchema: schemaOf({ appId: { type: "string", description: "\u53EF\u9009\uFF1B\u7F3A\u7701\u65F6\u81EA\u52A8\u89E3\u6790" } }),
|
|
891
|
+
handler: async (args, { host }) => {
|
|
892
|
+
const appId = args.appId ? String(args.appId) : await getAppId(host);
|
|
893
|
+
const response = await host.request({
|
|
894
|
+
method: "GET",
|
|
895
|
+
path: "/api/installer/public/querySpAppVersionInfo",
|
|
896
|
+
query: { appId },
|
|
897
|
+
operation: "project.version.check"
|
|
898
|
+
});
|
|
899
|
+
assertWeaverSuccess(response, "project.version.check");
|
|
900
|
+
const version = String(response?.data?.commitVersion ?? "");
|
|
901
|
+
if (!version) throw new Error("\u63A5\u53E3\u672A\u8FD4\u56DE\u5E94\u7528\u7248\u672C");
|
|
902
|
+
return projectSuccess("project.version.check", {
|
|
903
|
+
appId,
|
|
904
|
+
version,
|
|
905
|
+
minimumVersion: MIN_VERSION.join("."),
|
|
906
|
+
supported: versionAtLeast(version)
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
},
|
|
910
|
+
listOperation(
|
|
911
|
+
"project.task.list",
|
|
912
|
+
"/api/ebuilder/form/formdata/v2/getFormDataList/queryTasks",
|
|
913
|
+
"task_name",
|
|
914
|
+
"task_desc",
|
|
915
|
+
"task_status"
|
|
916
|
+
),
|
|
917
|
+
detailOperation("project.task.detail", "/api/ebuilder/form/formdata/v2/getFormDataByPk/queryTaskDetail", "task_name"),
|
|
918
|
+
listOperation(
|
|
919
|
+
"project.project.list",
|
|
920
|
+
"/api/ebuilder/form/formdata/v2/getFormDataList/queryProjects",
|
|
921
|
+
"proj_name",
|
|
922
|
+
"proj_desc",
|
|
923
|
+
"proj_status"
|
|
924
|
+
),
|
|
925
|
+
detailOperation("project.project.detail", "/api/ebuilder/form/formdata/v2/getFormDataByPk/queryProjDetail", "proj_name"),
|
|
926
|
+
dictionaryOperation("project.dictionary.task-type", "/api/ebuilder/form/formdata/v2/getFormDataList/queryTaskTypes", "\u67E5\u8BE2\u4EFB\u52A1\u7C7B\u578B"),
|
|
927
|
+
dictionaryOperation("project.dictionary.task-priority", "/api/ebuilder/form/formdata/v2/getFormDataList/queryTaskPriorities", "\u67E5\u8BE2\u4EFB\u52A1\u7D27\u6025\u7A0B\u5EA6"),
|
|
928
|
+
dictionaryOperation("project.dictionary.task-status", "/api/ebuilder/form/formdata/v2/getFormDataList/queryTaskStatus", "\u67E5\u8BE2\u4EFB\u52A1\u72B6\u6001"),
|
|
929
|
+
dictionaryOperation("project.dictionary.project-type", "/api/ebuilder/form/formdata/v2/getFormDataList/queryProjTypes", "\u67E5\u8BE2\u9879\u76EE\u7C7B\u578B"),
|
|
930
|
+
dictionaryOperation("project.dictionary.project-priority", "/api/ebuilder/form/formdata/v2/getFormDataList/queryProjPriorities", "\u67E5\u8BE2\u9879\u76EE\u7D27\u6025\u7A0B\u5EA6"),
|
|
931
|
+
dictionaryOperation("project.dictionary.project-status", "/api/ebuilder/form/formdata/v2/getFormDataList/queryProjStatus", "\u67E5\u8BE2\u9879\u76EE\u72B6\u6001"),
|
|
932
|
+
hrmOperation("project.employee.resolve", "/api/hrm/common/browser/data/resource", "employee", "\u6309\u59D3\u540D\u7CBE\u786E\u6216\u6A21\u7CCA\u89E3\u6790\u5458\u5DE5 ID\uFF0C\u9ED8\u8BA4\u4EC5\u67E5\u5728\u804C\u5458\u5DE5"),
|
|
933
|
+
hrmOperation("project.department.resolve", "/api/hrm/common/browser/data/department", "organization", "\u6309\u540D\u79F0\u7CBE\u786E\u6216\u6A21\u7CCA\u89E3\u6790\u90E8\u95E8 ID"),
|
|
934
|
+
hrmOperation("project.subcompany.resolve", "/api/hrm/common/browser/data/subcompany", "organization", "\u6309\u540D\u79F0\u7CBE\u786E\u6216\u6A21\u7CCA\u89E3\u6790\u5206\u90E8 ID")
|
|
935
|
+
];
|
|
936
|
+
|
|
937
|
+
// src/shortcuts/project/operations/write.ts
|
|
938
|
+
var WRITE_TARGETS = {
|
|
939
|
+
taskCreate: { entity: "task", action: "create", listPath: "", detailPath: "/api/ebuilder/form/formdata/v2/getFormDataByPk/queryTaskDetail", writePath: "/api/ebuilder/form/formdata/v2/saveFormData/createTask" },
|
|
940
|
+
taskUpdate: { entity: "task", action: "update", listPath: "", detailPath: "/api/ebuilder/form/formdata/v2/getFormDataByPk/queryTaskDetail", writePath: "/api/ebuilder/form/formdata/v2/updateFormData/updateTask" },
|
|
941
|
+
taskDelete: { entity: "task", action: "delete", listPath: "", detailPath: "/api/ebuilder/form/formdata/v2/getFormDataByPk/queryTaskDetail", writePath: "/api/ebuilder/form/formdata/v2/deleteFormData/deleteTask" },
|
|
942
|
+
projectCreate: { entity: "project", action: "create", listPath: "", detailPath: "/api/ebuilder/form/formdata/v2/getFormDataByPk/queryProjDetail", writePath: "/api/ebuilder/form/formdata/v2/saveFormData/createProject" },
|
|
943
|
+
projectUpdate: { entity: "project", action: "update", listPath: "", detailPath: "/api/ebuilder/form/formdata/v2/getFormDataByPk/queryProjDetail", writePath: "/api/ebuilder/form/formdata/v2/updateFormData/updateProject" },
|
|
944
|
+
projectDelete: { entity: "project", action: "delete", listPath: "", detailPath: "/api/ebuilder/form/formdata/v2/getFormDataByPk/queryProjDetail", writePath: "/api/ebuilder/form/formdata/v2/deleteFormData/deleteProject" }
|
|
945
|
+
};
|
|
946
|
+
function resolveManager(value, operator) {
|
|
947
|
+
return value === void 0 || value === null || value === "" || value === "@me" ? operator : value;
|
|
948
|
+
}
|
|
949
|
+
function records(value) {
|
|
950
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > 100) {
|
|
951
|
+
throw projectValidationError("records_invalid", "records \u5FC5\u987B\u662F 1-100 \u6761\u8BB0\u5F55\u6570\u7EC4");
|
|
952
|
+
}
|
|
953
|
+
return value.map((item, index) => {
|
|
954
|
+
const record = asObject(item, `records[${index}]`);
|
|
955
|
+
if (Object.keys(record).length === 0) {
|
|
956
|
+
throw projectValidationError("records_invalid", `records[${index}] \u4E0D\u80FD\u4E3A\u7A7A\u5BF9\u8C61`);
|
|
957
|
+
}
|
|
958
|
+
return record;
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
async function detail(host, target, id, operation) {
|
|
962
|
+
const response = await host.request({
|
|
963
|
+
method: "POST",
|
|
964
|
+
path: target.detailPath,
|
|
965
|
+
body: {
|
|
966
|
+
datajson: JSON.stringify({
|
|
967
|
+
mainTable: { id },
|
|
968
|
+
header: { operator: await operatorId(host) }
|
|
969
|
+
})
|
|
970
|
+
},
|
|
971
|
+
operation
|
|
972
|
+
});
|
|
973
|
+
assertDatajsonSuccess(response, operation);
|
|
974
|
+
return response?.datajson ?? null;
|
|
975
|
+
}
|
|
976
|
+
async function sendWrite(host, operation, path, datajsonObject) {
|
|
977
|
+
let response;
|
|
978
|
+
try {
|
|
979
|
+
response = await host.request({
|
|
980
|
+
method: "POST",
|
|
981
|
+
path,
|
|
982
|
+
body: { datajson: datajsonObject },
|
|
983
|
+
operation
|
|
984
|
+
});
|
|
985
|
+
} catch (error) {
|
|
986
|
+
if (error?.type === "network") {
|
|
987
|
+
throw projectPartialError("\u5199\u5165\u8BF7\u6C42\u5DF2\u53D1\u51FA\u4F46\u7ED3\u679C\u4E0D\u786E\u5B9A\uFF0C\u8BF7\u52FF\u81EA\u52A8\u91CD\u8BD5\uFF1B\u5148\u6267\u884C\u53EA\u8BFB\u56DE\u67E5\u786E\u8BA4\u7ED3\u679C", {
|
|
988
|
+
operation,
|
|
989
|
+
path
|
|
990
|
+
}, error.details);
|
|
991
|
+
}
|
|
992
|
+
throw error;
|
|
993
|
+
}
|
|
994
|
+
assertDatajsonSuccess(response, operation);
|
|
995
|
+
return response?.datajson ?? null;
|
|
996
|
+
}
|
|
997
|
+
async function verifySession(env, continuation) {
|
|
998
|
+
if (continuation.userId !== await operatorId(env.host)) {
|
|
999
|
+
throw projectValidationError("continuation_mismatch", "continuation \u4E0E\u5F53\u524D\u767B\u5F55\u4F1A\u8BDD\u4E0D\u5339\u914D");
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
function createOperations(namePrefix, target) {
|
|
1003
|
+
const prepareName = `${namePrefix}.prepare`;
|
|
1004
|
+
const applyName = `${namePrefix}.apply`;
|
|
1005
|
+
return [
|
|
1006
|
+
{
|
|
1007
|
+
name: prepareName,
|
|
1008
|
+
resource: "project",
|
|
1009
|
+
method: "write.prepare",
|
|
1010
|
+
action: prepareName,
|
|
1011
|
+
summary: `\u9884\u89C8\u5E76\u751F\u6210${target.entity === "task" ? "\u4EFB\u52A1" : "\u9879\u76EE"}\u521B\u5EFA\u5199\u5165 continuation\uFF0C\u4E0D\u53D1\u751F\u5199\u5165`,
|
|
1012
|
+
risk: "read-before-write",
|
|
1013
|
+
inputSchema: schemaOf({ records: SCHEMA_RECORDS }, { required: ["records"] }),
|
|
1014
|
+
handler: async (args, env) => {
|
|
1015
|
+
const operator = await operatorId(env.host);
|
|
1016
|
+
const datajson = {
|
|
1017
|
+
header: { operator },
|
|
1018
|
+
operationinfo: {},
|
|
1019
|
+
datas: records(args.records).map((mainTable) => ({
|
|
1020
|
+
mainTable: { ...mainTable, manager: resolveManager(mainTable.manager, operator) }
|
|
1021
|
+
}))
|
|
1022
|
+
};
|
|
1023
|
+
const continuation = await env.continuation.issue({
|
|
1024
|
+
operation: applyName,
|
|
1025
|
+
userId: datajson.header.operator,
|
|
1026
|
+
datajson
|
|
1027
|
+
});
|
|
1028
|
+
return projectSuccess(prepareName, {
|
|
1029
|
+
continuation,
|
|
1030
|
+
request: { datajson },
|
|
1031
|
+
recordCount: datajson.datas.length
|
|
1032
|
+
}, { requiresConfirmation: true });
|
|
1033
|
+
}
|
|
1034
|
+
},
|
|
1035
|
+
{
|
|
1036
|
+
name: applyName,
|
|
1037
|
+
resource: "project",
|
|
1038
|
+
method: "write.apply",
|
|
1039
|
+
action: applyName,
|
|
1040
|
+
summary: `\u7ECF\u7528\u6237\u786E\u8BA4\u540E\u521B\u5EFA${target.entity === "task" ? "\u4EFB\u52A1" : "\u9879\u76EE"}`,
|
|
1041
|
+
risk: "high-risk-write",
|
|
1042
|
+
requiresConfirmation: true,
|
|
1043
|
+
inputSchema: schemaOf({
|
|
1044
|
+
continuation: SCHEMA_CONTINUATION,
|
|
1045
|
+
confirm: SCHEMA_CONFIRM
|
|
1046
|
+
}, { required: ["continuation", "confirm"] }),
|
|
1047
|
+
handler: async (args, env) => {
|
|
1048
|
+
if (args.confirm !== true) throw projectValidationError("confirm_required", "confirm \u5FC5\u987B\u4E3A true");
|
|
1049
|
+
const continuation = await env.continuation.verify(String(args.continuation), applyName);
|
|
1050
|
+
await verifySession(env, continuation);
|
|
1051
|
+
const datajson = asObject(continuation.datajson, "continuation.datajson");
|
|
1052
|
+
const response = await sendWrite(env.host, applyName, target.writePath, datajson);
|
|
1053
|
+
return projectSuccess(applyName, response, { targetType: target.entity, writeAction: "create" });
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
];
|
|
1057
|
+
}
|
|
1058
|
+
function updateOperations(namePrefix, target) {
|
|
1059
|
+
const prepareName = `${namePrefix}.prepare`;
|
|
1060
|
+
const applyName = `${namePrefix}.apply`;
|
|
1061
|
+
return [
|
|
1062
|
+
{
|
|
1063
|
+
name: prepareName,
|
|
1064
|
+
resource: "project",
|
|
1065
|
+
method: "write.prepare",
|
|
1066
|
+
action: prepareName,
|
|
1067
|
+
summary: `\u56DE\u67E5\u5E76\u9884\u89C8${target.entity === "task" ? "\u4EFB\u52A1" : "\u9879\u76EE"}\u66F4\u65B0\uFF0C\u751F\u6210 continuation\uFF0C\u4E0D\u53D1\u751F\u5199\u5165`,
|
|
1068
|
+
risk: "read-before-write",
|
|
1069
|
+
inputSchema: schemaOf({ id: SCHEMA_ID_STRING, fields: SCHEMA_FIELDS }, { required: ["id", "fields"] }),
|
|
1070
|
+
handler: async (args, env) => {
|
|
1071
|
+
const id = idString(args.id, "id");
|
|
1072
|
+
const fields = asObject(args.fields, "fields");
|
|
1073
|
+
if (Object.keys(fields).length === 0) {
|
|
1074
|
+
throw projectValidationError("fields_required", "fields \u81F3\u5C11\u5305\u542B\u4E00\u4E2A\u8981\u66F4\u65B0\u7684\u5B57\u6BB5");
|
|
1075
|
+
}
|
|
1076
|
+
const operator = await operatorId(env.host);
|
|
1077
|
+
if (fields.manager === "@me") fields.manager = operator;
|
|
1078
|
+
const current = await detail(env.host, target, id, `${namePrefix}.prepare`);
|
|
1079
|
+
const datajson = {
|
|
1080
|
+
header: { operator },
|
|
1081
|
+
operationinfo: {},
|
|
1082
|
+
datas: [{ mainTable: { id, ...fields } }]
|
|
1083
|
+
};
|
|
1084
|
+
const continuation = await env.continuation.issue({
|
|
1085
|
+
operation: applyName,
|
|
1086
|
+
userId: datajson.header.operator,
|
|
1087
|
+
id,
|
|
1088
|
+
fingerprint: stableFingerprint(current),
|
|
1089
|
+
datajson
|
|
1090
|
+
});
|
|
1091
|
+
return projectSuccess(prepareName, {
|
|
1092
|
+
continuation,
|
|
1093
|
+
request: { datajson },
|
|
1094
|
+
current
|
|
1095
|
+
}, { requiresConfirmation: true, id });
|
|
1096
|
+
}
|
|
1097
|
+
},
|
|
1098
|
+
{
|
|
1099
|
+
name: applyName,
|
|
1100
|
+
resource: "project",
|
|
1101
|
+
method: "write.apply",
|
|
1102
|
+
action: applyName,
|
|
1103
|
+
summary: `\u7ECF\u7528\u6237\u786E\u8BA4\u5E76\u786E\u8BA4\u76EE\u6807\u672A\u53D8\u5316\u540E\u66F4\u65B0${target.entity === "task" ? "\u4EFB\u52A1" : "\u9879\u76EE"}`,
|
|
1104
|
+
risk: "high-risk-write",
|
|
1105
|
+
requiresConfirmation: true,
|
|
1106
|
+
inputSchema: schemaOf({
|
|
1107
|
+
continuation: SCHEMA_CONTINUATION,
|
|
1108
|
+
confirm: SCHEMA_CONFIRM
|
|
1109
|
+
}, { required: ["continuation", "confirm"] }),
|
|
1110
|
+
handler: async (args, env) => {
|
|
1111
|
+
if (args.confirm !== true) throw projectValidationError("confirm_required", "confirm \u5FC5\u987B\u4E3A true");
|
|
1112
|
+
const continuation = await env.continuation.verify(String(args.continuation), applyName);
|
|
1113
|
+
await verifySession(env, continuation);
|
|
1114
|
+
const id = idString(continuation.id, "continuation.id");
|
|
1115
|
+
const current = await detail(env.host, target, id, applyName);
|
|
1116
|
+
if (stableFingerprint(current) !== continuation.fingerprint) {
|
|
1117
|
+
throw projectValidationError("target_changed", "\u76EE\u6807\u6570\u636E\u5728\u786E\u8BA4\u540E\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
1118
|
+
}
|
|
1119
|
+
const datajson = asObject(continuation.datajson, "continuation.datajson");
|
|
1120
|
+
const response = await sendWrite(env.host, applyName, target.writePath, datajson);
|
|
1121
|
+
return projectSuccess(applyName, response, { targetType: target.entity, writeAction: "update", id });
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
];
|
|
1125
|
+
}
|
|
1126
|
+
function deleteOperations(namePrefix, target) {
|
|
1127
|
+
const prepareName = `${namePrefix}.prepare`;
|
|
1128
|
+
const applyName = `${namePrefix}.apply`;
|
|
1129
|
+
return [
|
|
1130
|
+
{
|
|
1131
|
+
name: prepareName,
|
|
1132
|
+
resource: "project",
|
|
1133
|
+
method: "write.prepare",
|
|
1134
|
+
action: prepareName,
|
|
1135
|
+
summary: `\u56DE\u67E5${target.entity === "task" ? "\u4EFB\u52A1" : "\u9879\u76EE"}\u5E76\u751F\u6210\u4E0D\u53EF\u9006\u5220\u9664 continuation\uFF0C\u4E0D\u53D1\u751F\u5220\u9664`,
|
|
1136
|
+
risk: "read-before-write",
|
|
1137
|
+
inputSchema: schemaOf({ id: SCHEMA_ID_STRING }, { required: ["id"] }),
|
|
1138
|
+
handler: async (args, env) => {
|
|
1139
|
+
const id = idString(args.id, "id");
|
|
1140
|
+
const current = await detail(env.host, target, id, prepareName);
|
|
1141
|
+
const datajson = {
|
|
1142
|
+
header: { operator: await operatorId(env.host) },
|
|
1143
|
+
datas: [{ mainTable: { id } }]
|
|
1144
|
+
};
|
|
1145
|
+
const continuation = await env.continuation.issue({
|
|
1146
|
+
operation: applyName,
|
|
1147
|
+
userId: datajson.header.operator,
|
|
1148
|
+
id,
|
|
1149
|
+
fingerprint: stableFingerprint(current),
|
|
1150
|
+
datajson
|
|
1151
|
+
});
|
|
1152
|
+
return projectSuccess(prepareName, {
|
|
1153
|
+
continuation,
|
|
1154
|
+
request: { datajson },
|
|
1155
|
+
current
|
|
1156
|
+
}, { requiresConfirmation: true, id, irreversible: true });
|
|
1157
|
+
}
|
|
1158
|
+
},
|
|
1159
|
+
{
|
|
1160
|
+
name: applyName,
|
|
1161
|
+
resource: "project",
|
|
1162
|
+
method: "write.apply",
|
|
1163
|
+
action: applyName,
|
|
1164
|
+
summary: `\u7ECF\u7528\u6237\u786E\u8BA4\u5E76\u786E\u8BA4\u76EE\u6807\u672A\u53D8\u5316\u540E\u5220\u9664${target.entity === "task" ? "\u4EFB\u52A1" : "\u9879\u76EE"}\uFF0C\u4E0D\u53EF\u6062\u590D`,
|
|
1165
|
+
risk: "high-risk-write",
|
|
1166
|
+
requiresConfirmation: true,
|
|
1167
|
+
inputSchema: schemaOf({
|
|
1168
|
+
continuation: SCHEMA_CONTINUATION,
|
|
1169
|
+
confirm: SCHEMA_CONFIRM
|
|
1170
|
+
}, { required: ["continuation", "confirm"] }),
|
|
1171
|
+
handler: async (args, env) => {
|
|
1172
|
+
if (args.confirm !== true) throw projectValidationError("confirm_required", "confirm \u5FC5\u987B\u4E3A true");
|
|
1173
|
+
const continuation = await env.continuation.verify(String(args.continuation), applyName);
|
|
1174
|
+
await verifySession(env, continuation);
|
|
1175
|
+
const id = idString(continuation.id, "continuation.id");
|
|
1176
|
+
const current = await detail(env.host, target, id, applyName);
|
|
1177
|
+
if (stableFingerprint(current) !== continuation.fingerprint) {
|
|
1178
|
+
throw projectValidationError("target_changed", "\u76EE\u6807\u6570\u636E\u5728\u786E\u8BA4\u540E\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
1179
|
+
}
|
|
1180
|
+
const datajson = asObject(continuation.datajson, "continuation.datajson");
|
|
1181
|
+
const response = await sendWrite(env.host, applyName, target.writePath, datajson);
|
|
1182
|
+
return projectSuccess(applyName, response, { targetType: target.entity, writeAction: "delete", id });
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
];
|
|
1186
|
+
}
|
|
1187
|
+
var projectWriteOperations = [
|
|
1188
|
+
...createOperations("project.task.create", WRITE_TARGETS.taskCreate),
|
|
1189
|
+
...updateOperations("project.task.update", WRITE_TARGETS.taskUpdate),
|
|
1190
|
+
...deleteOperations("project.task.delete", WRITE_TARGETS.taskDelete),
|
|
1191
|
+
...createOperations("project.project.create", WRITE_TARGETS.projectCreate),
|
|
1192
|
+
...updateOperations("project.project.update", WRITE_TARGETS.projectUpdate),
|
|
1193
|
+
...deleteOperations("project.project.delete", WRITE_TARGETS.projectDelete)
|
|
1194
|
+
];
|
|
1195
|
+
|
|
1196
|
+
// src/shortcuts/project/operations/registry.ts
|
|
1197
|
+
function buildRegistry() {
|
|
1198
|
+
const registry = /* @__PURE__ */ new Map();
|
|
1199
|
+
const definitions = [
|
|
1200
|
+
...projectReadOperations,
|
|
1201
|
+
...projectWriteOperations
|
|
1202
|
+
];
|
|
1203
|
+
for (const definition of definitions) {
|
|
1204
|
+
if (registry.has(definition.name)) {
|
|
1205
|
+
throw new Error(`duplicate project operation: ${definition.name}`);
|
|
1206
|
+
}
|
|
1207
|
+
registry.set(definition.name, definition);
|
|
1208
|
+
}
|
|
1209
|
+
return registry;
|
|
1210
|
+
}
|
|
1211
|
+
var projectOperationRegistry = buildRegistry();
|
|
1212
|
+
function projectOperationDefinitions() {
|
|
1213
|
+
return [...projectOperationRegistry.values()];
|
|
1214
|
+
}
|
|
1215
|
+
function getProjectOperation(operation) {
|
|
1216
|
+
const definition = projectOperationRegistry.get(operation);
|
|
1217
|
+
if (!definition) {
|
|
1218
|
+
throw projectValidationError("operation_unknown", `\u4E8B\u4E95\u7136\u9879\u76EE\u6A21\u5757\u4E0D\u652F\u6301\u64CD\u4F5C\uFF1A${operation}`);
|
|
1219
|
+
}
|
|
1220
|
+
return definition;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
// src/shortcuts/project/manifest.ts
|
|
1224
|
+
function buildOperations() {
|
|
1225
|
+
return projectOperationDefinitions().map((definition) => ({
|
|
1226
|
+
name: definition.name,
|
|
1227
|
+
resource: definition.resource,
|
|
1228
|
+
summary: definition.summary,
|
|
1229
|
+
risk: definition.risk,
|
|
1230
|
+
...definition.requiresConfirmation ? { requiresConfirmation: true } : {},
|
|
1231
|
+
inputSchema: definition.inputSchema
|
|
1232
|
+
}));
|
|
1233
|
+
}
|
|
1234
|
+
var projectManifest = {
|
|
1235
|
+
schemaVersion: 1,
|
|
1236
|
+
name: "project",
|
|
1237
|
+
title: "\u6CDB\u5FAEE10\u4E8B\u4E95\u7136\u9879\u76EE\u7BA1\u7406",
|
|
1238
|
+
version: "0.1.0",
|
|
1239
|
+
host: "e10-project",
|
|
1240
|
+
status: "builtin",
|
|
1241
|
+
sourceSkill: "weaver-e10-shijingran",
|
|
1242
|
+
capabilities: ["project", "task"],
|
|
1243
|
+
fixed: {
|
|
1244
|
+
appTag: "weaver-project-eb",
|
|
1245
|
+
minimumAppVersion: "20.6.11"
|
|
1246
|
+
},
|
|
1247
|
+
operations: buildOperations(),
|
|
1248
|
+
withheldOperations: [
|
|
1249
|
+
{
|
|
1250
|
+
name: "project.attachment.upload",
|
|
1251
|
+
reason: "\u6E90\u8D44\u6599\u4EC5\u8BF4\u660E attachment \u5B57\u6BB5\u63A5\u53D7\u5DF2\u4E0A\u4F20\u6587\u4EF6 ID\uFF0C\u672A\u63D0\u4F9B\u4E8B\u4E95\u7136\u6A21\u5757\u81EA\u5DF1\u7684\u4E0A\u4F20\u63A5\u53E3\u4E0E\u6587\u4EF6\u5B89\u5168\u786E\u8BA4\u94FE\u3002"
|
|
1252
|
+
},
|
|
1253
|
+
{
|
|
1254
|
+
name: "project.field.auto-resolve",
|
|
1255
|
+
reason: "\u6E90\u8D44\u6599\u8981\u6C42\u6309\u5B57\u6BB5\u7C7B\u578B\u7EC4\u5408\u591A\u4E2A\u63A5\u53E3\u89E3\u6790\u540D\u79F0\u5230 ID\uFF1B\u5F53\u524D CLI \u66B4\u9732\u5206\u6B65\u89E3\u6790 operation\uFF0C\u7531 Agent \u6309\u5B57\u6BB5\u7C7B\u578B\u663E\u5F0F\u7F16\u6392\uFF0C\u907F\u514D\u66FF\u7528\u6237\u731C\u6D4B\u5173\u8054\u5BF9\u8C61\u3002"
|
|
1256
|
+
}
|
|
1257
|
+
]
|
|
1258
|
+
};
|
|
1259
|
+
|
|
1260
|
+
// src/shortcuts/project/operations.ts
|
|
1261
|
+
async function executeProjectOperation(operation, rawInput, context) {
|
|
1262
|
+
const definition = getProjectOperation(operation);
|
|
1263
|
+
const input = asObject(rawInput);
|
|
1264
|
+
assertNoForbiddenKeys(input);
|
|
1265
|
+
return definition.handler(input, context);
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
// src/shortcuts/project/index.ts
|
|
1269
|
+
function asOptions(value) {
|
|
1270
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1271
|
+
}
|
|
1272
|
+
async function readStdin() {
|
|
1273
|
+
const chunks = [];
|
|
1274
|
+
for await (const chunk of process.stdin) {
|
|
1275
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
1276
|
+
}
|
|
1277
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
1278
|
+
}
|
|
1279
|
+
function stripBom(value) {
|
|
1280
|
+
return value.replace(/^\uFEFF+/u, "");
|
|
1281
|
+
}
|
|
1282
|
+
async function inputFrom(options) {
|
|
1283
|
+
const opts = asOptions(options);
|
|
1284
|
+
let input = {};
|
|
1285
|
+
if (opts.input && opts.inputJson) {
|
|
1286
|
+
throw projectValidationError("input_conflict", "\u4E0D\u80FD\u540C\u65F6\u4F20 --input \u548C --input-json");
|
|
1287
|
+
}
|
|
1288
|
+
if (opts.inputJson) {
|
|
1289
|
+
input = parseJsonInput(String(opts.inputJson), "--input-json");
|
|
1290
|
+
}
|
|
1291
|
+
if (opts.input) {
|
|
1292
|
+
let raw;
|
|
1293
|
+
try {
|
|
1294
|
+
raw = opts.input === "-" ? await readStdin() : await readFile2(String(opts.input), "utf8");
|
|
1295
|
+
} catch {
|
|
1296
|
+
throw projectValidationError("input_unreadable", `\u65E0\u6CD5\u8BFB\u53D6 --input\uFF1A${String(opts.input)}`);
|
|
1297
|
+
}
|
|
1298
|
+
input = parseJsonInput(raw, "--input");
|
|
1299
|
+
}
|
|
1300
|
+
return input;
|
|
1301
|
+
}
|
|
1302
|
+
function parseJsonInput(raw, label) {
|
|
1303
|
+
try {
|
|
1304
|
+
const parsed = JSON.parse(stripBom(raw));
|
|
1305
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1306
|
+
throw new Error("input must be an object");
|
|
1307
|
+
}
|
|
1308
|
+
return parsed;
|
|
1309
|
+
} catch {
|
|
1310
|
+
throw projectValidationError("input_invalid", `${label} \u4E0D\u662F\u5408\u6CD5 JSON \u5BF9\u8C61`);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
function successEnvelope(operation, result) {
|
|
1314
|
+
return {
|
|
1315
|
+
schemaVersion: 1,
|
|
1316
|
+
ok: true,
|
|
1317
|
+
operation,
|
|
1318
|
+
data: result.data === void 0 ? null : result.data,
|
|
1319
|
+
...result.meta ? { meta: result.meta } : {},
|
|
1320
|
+
warnings: []
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
function failureEnvelope(error) {
|
|
1324
|
+
const structured = error;
|
|
1325
|
+
return {
|
|
1326
|
+
schemaVersion: 1,
|
|
1327
|
+
ok: false,
|
|
1328
|
+
...structured?.partialData === void 0 ? {} : { data: structured.partialData },
|
|
1329
|
+
error: toErrorEnvelope(error)
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
async function executeAndPrint(ctx, operation, input) {
|
|
1333
|
+
try {
|
|
1334
|
+
const result = await executeProjectOperation(operation, input, {
|
|
1335
|
+
host: createProjectHost(ctx),
|
|
1336
|
+
continuation: createProjectContinuationSigner(ctx)
|
|
1337
|
+
});
|
|
1338
|
+
ctx.output.write(successEnvelope(operation, result), { json: true });
|
|
1339
|
+
} catch (error) {
|
|
1340
|
+
console.error(JSON.stringify(failureEnvelope(error), null, 2));
|
|
1341
|
+
process.exitCode = isCliError(error) ? error.exitCode : 1 /* GeneralError */;
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
var projectShortcut = {
|
|
1345
|
+
name: "project",
|
|
1346
|
+
description: "\u6CDB\u5FAEE10\u4E8B\u4E95\u7136\u9879\u76EE\u7BA1\u7406 CLI\uFF08\u9879\u76EE/\u4EFB\u52A1\u67E5\u8BE2\u4E0E\u786E\u8BA4\u5199\u5165\uFF09",
|
|
1347
|
+
category: "shortcut",
|
|
1348
|
+
register({ program, action }) {
|
|
1349
|
+
const project = program.command("project").description("\u6CDB\u5FAEE10\u4E8B\u4E95\u7136\u9879\u76EE\u7BA1\u7406\uFF08\u9879\u76EE/\u4EFB\u52A1\u67E5\u8BE2\u4E0E\u786E\u8BA4\u5199\u5165\uFF09");
|
|
1350
|
+
project.command("schema").description("Print project operation manifest for agents").action(action((ctx) => {
|
|
1351
|
+
ctx.output.write(projectManifest, { json: true });
|
|
1352
|
+
}));
|
|
1353
|
+
project.command("run").description("Run a project operation with JSON input").argument("<operation>", "operation name, e.g. project.task.list").option("--input <path>", "JSON input file, or - for stdin").option("--input-json <json>", "inline JSON input object").action(action(async (ctx, operation, options) => {
|
|
1354
|
+
await executeAndPrint(ctx, String(operation), await inputFrom(options));
|
|
1355
|
+
}));
|
|
1356
|
+
}
|
|
1357
|
+
};
|
|
1358
|
+
export {
|
|
1359
|
+
inputFrom,
|
|
1360
|
+
projectShortcut
|
|
1361
|
+
};
|