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,508 @@
|
|
|
1
|
+
import { createRequire as __esbuildCreateRequire } from 'node:module';
|
|
2
|
+
const require = __esbuildCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
E10AuthSession,
|
|
5
|
+
E10_AUTH_REQUIRED_MESSAGE,
|
|
6
|
+
getActiveProfile,
|
|
7
|
+
hasXiaoEEnv,
|
|
8
|
+
tryXiaoEUnifiedLogin
|
|
9
|
+
} from "./chunk-2GA5ZIQL.js";
|
|
10
|
+
import {
|
|
11
|
+
CliError
|
|
12
|
+
} from "./chunk-LUSPKZKY.js";
|
|
13
|
+
|
|
14
|
+
// src/internal/e10/auth-recovery.ts
|
|
15
|
+
var AUTH_REQUIRED_CODES = /* @__PURE__ */ new Set(["-2", "401"]);
|
|
16
|
+
var AUTH_REQUIRED_MARKERS = [
|
|
17
|
+
"\u672A\u767B\u5F55",
|
|
18
|
+
"\u8BF7\u767B\u5F55",
|
|
19
|
+
"\u91CD\u65B0\u767B\u5F55",
|
|
20
|
+
"\u767B\u5F55\u5931\u6548",
|
|
21
|
+
"\u767B\u5F55\u5DF2\u5931\u6548",
|
|
22
|
+
"\u767B\u5F55\u8FC7\u671F",
|
|
23
|
+
"\u767B\u5F55\u5DF2\u8FC7\u671F",
|
|
24
|
+
"\u767B\u5F55\u8D85\u65F6",
|
|
25
|
+
"\u4F1A\u8BDD\u5931\u6548",
|
|
26
|
+
"\u4F1A\u8BDD\u8FC7\u671F",
|
|
27
|
+
"\u8BA4\u8BC1\u5931\u8D25",
|
|
28
|
+
"\u8EAB\u4EFD\u8BA4\u8BC1\u5931\u8D25",
|
|
29
|
+
"token expired",
|
|
30
|
+
"token timeout",
|
|
31
|
+
"token invalid",
|
|
32
|
+
"session expired",
|
|
33
|
+
"login required",
|
|
34
|
+
"not logged in",
|
|
35
|
+
"not login"
|
|
36
|
+
];
|
|
37
|
+
var recoveryInFlight = /* @__PURE__ */ new Map();
|
|
38
|
+
function asRecord(value) {
|
|
39
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
40
|
+
}
|
|
41
|
+
function responseCodes(value) {
|
|
42
|
+
const root = asRecord(value);
|
|
43
|
+
if (!root) return [];
|
|
44
|
+
const data = asRecord(root.data);
|
|
45
|
+
const resBase = asRecord(root.res_base);
|
|
46
|
+
const nestedResBase = asRecord(data?.res_base);
|
|
47
|
+
return [root.code, data?.code, resBase?.ret, nestedResBase?.ret].filter((item) => item !== void 0 && item !== null).map(String);
|
|
48
|
+
}
|
|
49
|
+
function authenticationTextFields(value) {
|
|
50
|
+
if (typeof value === "string") return [value];
|
|
51
|
+
const root = asRecord(value);
|
|
52
|
+
if (!root) return [];
|
|
53
|
+
const data = asRecord(root.data);
|
|
54
|
+
const values = [];
|
|
55
|
+
for (const record of [root, data]) {
|
|
56
|
+
if (!record) continue;
|
|
57
|
+
for (const key of ["message", "msg", "error", "errorMsg", "rawText"]) values.push(record[key]);
|
|
58
|
+
}
|
|
59
|
+
return values.filter((item) => typeof item === "string" || typeof item === "number").map(String);
|
|
60
|
+
}
|
|
61
|
+
function responseText(response) {
|
|
62
|
+
const fields = authenticationTextFields(response.value);
|
|
63
|
+
if (fields.length) return fields.join("\n");
|
|
64
|
+
if (asRecord(response.value)) return "";
|
|
65
|
+
if (typeof response.text === "string" && response.text) return response.text;
|
|
66
|
+
if (response.content && response.content.length) {
|
|
67
|
+
return response.content.subarray(0, 8 * 1024).toString("utf8");
|
|
68
|
+
}
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
function isE10AuthenticationRequired(response) {
|
|
72
|
+
if (response.status === 401 || response.status === 302) return true;
|
|
73
|
+
if (responseCodes(response.value).some((code) => AUTH_REQUIRED_CODES.has(code))) return true;
|
|
74
|
+
const text = responseText(response).toLowerCase();
|
|
75
|
+
if (!text) return false;
|
|
76
|
+
if (text.includes("login.jsp")) return true;
|
|
77
|
+
if (text.includes("<input") && text.includes("password")) return true;
|
|
78
|
+
return AUTH_REQUIRED_MARKERS.some((marker) => text.includes(marker.toLowerCase()));
|
|
79
|
+
}
|
|
80
|
+
function globalOptions(ctx) {
|
|
81
|
+
return typeof ctx.getGlobalOptions === "function" ? ctx.getGlobalOptions() : {};
|
|
82
|
+
}
|
|
83
|
+
function canAutomaticallyRecoverXiaoE(ctx) {
|
|
84
|
+
const options = globalOptions(ctx);
|
|
85
|
+
return !options.auth && hasXiaoEEnv(ctx.env || process.env, options);
|
|
86
|
+
}
|
|
87
|
+
async function recoverXiaoEAuthSession(ctx, currentSession) {
|
|
88
|
+
if (!canAutomaticallyRecoverXiaoE(ctx)) return null;
|
|
89
|
+
const options = globalOptions(ctx);
|
|
90
|
+
const profile = options.profile || getActiveProfile();
|
|
91
|
+
const baseUrl = currentSession.getBaseUrl();
|
|
92
|
+
const key = `${profile}
|
|
93
|
+
${baseUrl}`;
|
|
94
|
+
const existing = recoveryInFlight.get(key);
|
|
95
|
+
if (existing) return existing;
|
|
96
|
+
const recovery = (async () => {
|
|
97
|
+
const login = await tryXiaoEUnifiedLogin({
|
|
98
|
+
env: ctx.env,
|
|
99
|
+
baseUrl,
|
|
100
|
+
profileBaseUrl: baseUrl,
|
|
101
|
+
allowBundledEnvScript: true,
|
|
102
|
+
allowTokenScript: true,
|
|
103
|
+
tenantKeyFallback: currentSession.tenantKey,
|
|
104
|
+
profileHint: profile
|
|
105
|
+
// Intentionally no logger: transparent recovery must not leak an
|
|
106
|
+
// intermediate "login" step into agent stdout/stderr or JSON output.
|
|
107
|
+
});
|
|
108
|
+
return login?.session || null;
|
|
109
|
+
})();
|
|
110
|
+
recoveryInFlight.set(key, recovery);
|
|
111
|
+
try {
|
|
112
|
+
return await recovery;
|
|
113
|
+
} finally {
|
|
114
|
+
if (recoveryInFlight.get(key) === recovery) recoveryInFlight.delete(key);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function sameE10SessionIdentity(current, recovered) {
|
|
118
|
+
const currentBaseUrl = current.getBaseUrl().replace(/\/+$/u, "").toLowerCase();
|
|
119
|
+
const recoveredBaseUrl = recovered.getBaseUrl().replace(/\/+$/u, "").toLowerCase();
|
|
120
|
+
if (currentBaseUrl !== recoveredBaseUrl) return false;
|
|
121
|
+
return !current.userId || !recovered.userId || current.userId === recovered.userId;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/internal/e10/context.ts
|
|
125
|
+
async function getE10Session(ctx, load = {}) {
|
|
126
|
+
const options = ctx.getGlobalOptions();
|
|
127
|
+
return E10AuthSession.fromOptions(options, ctx.cwd, load);
|
|
128
|
+
}
|
|
129
|
+
async function requireE10Session(ctx, load = {}) {
|
|
130
|
+
const session = await getE10Session(ctx, load);
|
|
131
|
+
if (!session) {
|
|
132
|
+
throw new CliError(E10_AUTH_REQUIRED_MESSAGE, 3 /* AuthError */);
|
|
133
|
+
}
|
|
134
|
+
return session;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// src/internal/e10/request-runtime.ts
|
|
138
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
139
|
+
var DEFAULT_BIG_INT_STRINGS = true;
|
|
140
|
+
var RESERVED_HEADERS = [
|
|
141
|
+
"authorization",
|
|
142
|
+
"cookie",
|
|
143
|
+
"eteamsid",
|
|
144
|
+
"token"
|
|
145
|
+
];
|
|
146
|
+
var E10ApiError = class extends CliError {
|
|
147
|
+
type;
|
|
148
|
+
subtype;
|
|
149
|
+
code;
|
|
150
|
+
retryable;
|
|
151
|
+
details;
|
|
152
|
+
constructor(type, subtype, message, options = {}) {
|
|
153
|
+
super(message, options.exitCode ?? 1 /* GeneralError */);
|
|
154
|
+
this.name = "E10ApiError";
|
|
155
|
+
this.type = type;
|
|
156
|
+
this.subtype = subtype;
|
|
157
|
+
this.code = options.code;
|
|
158
|
+
this.retryable = options.retryable ?? false;
|
|
159
|
+
this.details = options.details;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
var E10RequestRuntime = class {
|
|
163
|
+
constructor(ctx, session, dependencies = {}) {
|
|
164
|
+
this.ctx = ctx;
|
|
165
|
+
this.session = session;
|
|
166
|
+
this.fetchFn = dependencies.fetch || globalThis.fetch;
|
|
167
|
+
this.attachSessionTicket = dependencies.attachSessionTicket === true;
|
|
168
|
+
this.recoverAuthentication = dependencies.recoverAuthentication || ((current) => recoverXiaoEAuthSession(this.ctx, current));
|
|
169
|
+
this.interceptors = [
|
|
170
|
+
...this.ctx.hooks?.getE10RequestInterceptors?.() || [],
|
|
171
|
+
...dependencies.interceptors || []
|
|
172
|
+
];
|
|
173
|
+
}
|
|
174
|
+
ctx;
|
|
175
|
+
session;
|
|
176
|
+
interceptors;
|
|
177
|
+
fetchFn;
|
|
178
|
+
attachSessionTicket;
|
|
179
|
+
recoverAuthentication;
|
|
180
|
+
async requestJson(request) {
|
|
181
|
+
return this.request({ ...request, responseType: "json" });
|
|
182
|
+
}
|
|
183
|
+
async requestBinary(request) {
|
|
184
|
+
return this.request({ ...request, responseType: "binary" });
|
|
185
|
+
}
|
|
186
|
+
async request(request) {
|
|
187
|
+
const mutable = this.prepareRequest(request);
|
|
188
|
+
try {
|
|
189
|
+
await this.runBeforeRequest(mutable, this.sessionContext());
|
|
190
|
+
this.assertPath(mutable.path);
|
|
191
|
+
if (mutable.path !== request.path) {
|
|
192
|
+
throw new E10ApiError("policy", "path_rewrite_denied", "E10 API \u62E6\u622A\u5668\u4E0D\u80FD\u4FEE\u6539\u8BF7\u6C42\u8DEF\u5F84", {
|
|
193
|
+
exitCode: 6 /* PolicyError */,
|
|
194
|
+
details: { from: request.path, to: mutable.path }
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
stripReservedHeaders(mutable.headers);
|
|
198
|
+
const requestEteamsId = this.session.eteamsId;
|
|
199
|
+
let parsed = await this.executeRequest(mutable, request.trustedHeaders);
|
|
200
|
+
if (!mutable.streamBody && isE10AuthenticationRequired(parsed) && await this.recoverExpiredSession(requestEteamsId)) {
|
|
201
|
+
parsed = await this.executeRequest(mutable, request.trustedHeaders);
|
|
202
|
+
}
|
|
203
|
+
await this.runAfterResponse(mutable, this.sessionContext(), parsed);
|
|
204
|
+
return parsed;
|
|
205
|
+
} catch (error) {
|
|
206
|
+
await this.runOnError(mutable, this.sessionContext(), error);
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
async executeRequest(request, trustedHeaders = {}) {
|
|
211
|
+
const url = withQuery(this.session.getBaseUrl(), request.path, request.query);
|
|
212
|
+
const headers = this.composeHeaders(request, trustedHeaders);
|
|
213
|
+
const init = this.buildFetchInit(request, headers);
|
|
214
|
+
const response = await this.fetchWithTimeout(url, init, request.timeoutMs);
|
|
215
|
+
return this.readResponse(
|
|
216
|
+
response,
|
|
217
|
+
request.responseType,
|
|
218
|
+
request.bigIntStrings,
|
|
219
|
+
request.maxResponseBytes,
|
|
220
|
+
request.timeoutMs
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
async recoverExpiredSession(requestEteamsId) {
|
|
224
|
+
if (this.session.eteamsId && this.session.eteamsId !== requestEteamsId) return true;
|
|
225
|
+
let recovered;
|
|
226
|
+
try {
|
|
227
|
+
recovered = await this.recoverAuthentication(this.session);
|
|
228
|
+
} catch {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
if (!recovered) return false;
|
|
232
|
+
if (!sameE10SessionIdentity(this.session, recovered)) {
|
|
233
|
+
throw new E10ApiError(
|
|
234
|
+
"authentication",
|
|
235
|
+
"session_context_changed",
|
|
236
|
+
"XiaoE \u81EA\u52A8\u6062\u590D\u540E\u7684\u767B\u5F55\u8EAB\u4EFD\u6216 E10 \u73AF\u5883\u53D1\u751F\u53D8\u5316\uFF0C\u672C\u6B21\u8BF7\u6C42\u672A\u91CD\u8BD5",
|
|
237
|
+
{ exitCode: 3 /* AuthError */, retryable: false }
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
const original = this.session;
|
|
241
|
+
if (typeof original.replaceWith === "function") {
|
|
242
|
+
original.replaceWith(recovered);
|
|
243
|
+
this.session = original;
|
|
244
|
+
} else {
|
|
245
|
+
this.session = recovered;
|
|
246
|
+
}
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
prepareRequest(request) {
|
|
250
|
+
return {
|
|
251
|
+
module: request.module,
|
|
252
|
+
operation: request.operation,
|
|
253
|
+
method: (request.method || "POST").toUpperCase(),
|
|
254
|
+
path: request.path,
|
|
255
|
+
query: { ...request.query || {} },
|
|
256
|
+
headers: sanitizePublicHeaders(request.headers || {}),
|
|
257
|
+
body: request.body,
|
|
258
|
+
form: request.form,
|
|
259
|
+
formData: request.formData,
|
|
260
|
+
streamBody: request.streamBody,
|
|
261
|
+
maxResponseBytes: request.maxResponseBytes,
|
|
262
|
+
timeoutMs: request.timeoutMs || DEFAULT_TIMEOUT_MS,
|
|
263
|
+
responseType: request.responseType || "json",
|
|
264
|
+
bigIntStrings: request.bigIntStrings ?? DEFAULT_BIG_INT_STRINGS
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
sessionContext() {
|
|
268
|
+
return {
|
|
269
|
+
baseUrl: this.session.getBaseUrl(),
|
|
270
|
+
userId: this.session.userId,
|
|
271
|
+
agentType: this.session.agentType
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
async runBeforeRequest(request, session) {
|
|
275
|
+
for (const interceptor of this.interceptors) {
|
|
276
|
+
await interceptor.beforeRequest?.({ request, session });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
async runAfterResponse(request, session, response) {
|
|
280
|
+
for (const interceptor of this.interceptors) {
|
|
281
|
+
await interceptor.afterResponse?.({
|
|
282
|
+
request: requestForHook(request),
|
|
283
|
+
session,
|
|
284
|
+
response: responseForHook(response)
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async runOnError(request, session, error) {
|
|
289
|
+
for (const interceptor of this.interceptors) {
|
|
290
|
+
await interceptor.onError?.({ request, session, error });
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
assertPath(requestPath) {
|
|
294
|
+
if (typeof requestPath !== "string" || !requestPath.startsWith("/") || requestPath.startsWith("//")) {
|
|
295
|
+
throw new E10ApiError("validation", "path_invalid", "\u8BF7\u6C42\u8DEF\u5F84\u5FC5\u987B\u662F\u76F8\u5BF9\u7EDD\u5BF9\u8DEF\u5F84", {
|
|
296
|
+
exitCode: 2 /* UsageError */
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
if (/^https?:/i.test(requestPath) || /[\r\n]/.test(requestPath) || requestPath.includes("/../")) {
|
|
300
|
+
throw new E10ApiError("validation", "path_invalid", "\u8BF7\u6C42\u8DEF\u5F84\u4E0D\u5141\u8BB8\u8DE8\u57DF\u6216\u8DEF\u5F84\u9003\u9038", {
|
|
301
|
+
exitCode: 2 /* UsageError */
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
if (!requestPath.startsWith("/api/")) {
|
|
305
|
+
throw new E10ApiError("validation", "path_not_allowed", "E10 API \u53EA\u80FD\u8C03\u7528 /api/ \u8DEF\u5F84", {
|
|
306
|
+
exitCode: 2 /* UsageError */
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
composeHeaders(request, trustedHeaders = {}) {
|
|
311
|
+
return {
|
|
312
|
+
Accept: "application/json, text/plain, */*",
|
|
313
|
+
// E10 各端(含 eBuilder 表单运行态)依赖这两个头;缺失时 EB formdata 接口会直接返回
|
|
314
|
+
// 业务失败(CLI 侧表现为 business_error「泛微接口返回业务失败」,且响应无可读 message,
|
|
315
|
+
// 极易被误判为「EB 未配置/环境不对」)。standalone skill 的脚本一直带这两个头。
|
|
316
|
+
langType: "zh_CN",
|
|
317
|
+
timeZoneOffset: String((/* @__PURE__ */ new Date()).getTimezoneOffset()),
|
|
318
|
+
...request.headers,
|
|
319
|
+
Cookie: this.attachSessionTicket ? this.session.cookieHeaderWithSessionTicket() : this.session.cookieHeader(),
|
|
320
|
+
eteamsid: this.session.eteamsId,
|
|
321
|
+
"User-Agent": this.session.uaHeader(),
|
|
322
|
+
Origin: this.session.getBaseUrl(),
|
|
323
|
+
"X-Weaver-Cli-Source": "weaver-work-cli",
|
|
324
|
+
"X-Weaver-Cli-Version": this.ctx.packageInfo?.version || "unknown",
|
|
325
|
+
...request.module ? { "X-Weaver-Cli-Module": request.module } : {},
|
|
326
|
+
...request.operation ? { "X-Weaver-Cli-Operation": request.operation } : {},
|
|
327
|
+
...trustedHeaders
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
buildFetchInit(request, headers) {
|
|
331
|
+
const init = {
|
|
332
|
+
method: request.method,
|
|
333
|
+
headers,
|
|
334
|
+
redirect: "manual"
|
|
335
|
+
};
|
|
336
|
+
if (request.streamBody) {
|
|
337
|
+
init.body = request.streamBody;
|
|
338
|
+
init.duplex = "half";
|
|
339
|
+
} else if (request.formData) {
|
|
340
|
+
init.body = request.formData;
|
|
341
|
+
} else if (request.form !== void 0) {
|
|
342
|
+
headers["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8";
|
|
343
|
+
init.body = String(request.form);
|
|
344
|
+
} else if (request.body !== void 0) {
|
|
345
|
+
headers["Content-Type"] = "application/json;charset=UTF-8";
|
|
346
|
+
init.body = JSON.stringify(request.body);
|
|
347
|
+
}
|
|
348
|
+
return init;
|
|
349
|
+
}
|
|
350
|
+
async fetchWithTimeout(url, init, timeoutMs) {
|
|
351
|
+
const controller = new AbortController();
|
|
352
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
353
|
+
try {
|
|
354
|
+
return await this.fetchFn(url, { ...init, signal: controller.signal });
|
|
355
|
+
} catch (error) {
|
|
356
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
357
|
+
throw new E10ApiError("network", "timeout", `\u8BF7\u6C42\u8D85\u65F6\uFF08${timeoutMs}ms\uFF09`, {
|
|
358
|
+
retryable: false,
|
|
359
|
+
exitCode: 4 /* NetworkError */
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
363
|
+
throw new E10ApiError("network", "transport", `\u8BF7\u6C42\u5931\u8D25\uFF1A${message}`, {
|
|
364
|
+
retryable: true,
|
|
365
|
+
exitCode: 4 /* NetworkError */
|
|
366
|
+
});
|
|
367
|
+
} finally {
|
|
368
|
+
clearTimeout(timer);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
async readResponse(response, responseType, bigIntStrings = DEFAULT_BIG_INT_STRINGS, maxResponseBytes, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
372
|
+
if (responseType === "binary") {
|
|
373
|
+
return {
|
|
374
|
+
status: response.status,
|
|
375
|
+
headers: response.headers,
|
|
376
|
+
content: Buffer.from(await response.arrayBuffer()),
|
|
377
|
+
contentType: response.headers.get("content-type") || "application/octet-stream"
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
const text = maxResponseBytes === void 0 ? await response.text() : await readBoundedText(response, maxResponseBytes, timeoutMs);
|
|
381
|
+
let value = {};
|
|
382
|
+
let parseError;
|
|
383
|
+
try {
|
|
384
|
+
value = text ? bigIntStrings ? parseJsonPreservingBigInts(text) : JSON.parse(text) : {};
|
|
385
|
+
} catch (error) {
|
|
386
|
+
parseError = error instanceof Error ? error : new Error(String(error));
|
|
387
|
+
}
|
|
388
|
+
return {
|
|
389
|
+
status: response.status,
|
|
390
|
+
headers: response.headers,
|
|
391
|
+
text,
|
|
392
|
+
value,
|
|
393
|
+
...parseError ? { parseError } : {}
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
function parseJsonPreservingBigInts(text) {
|
|
398
|
+
return JSON.parse(quoteLargeJsonIntegers(text));
|
|
399
|
+
}
|
|
400
|
+
var LONG_INTEGER_MIN_DIGITS = 16;
|
|
401
|
+
var JSON_STRING_OR_NUMBER = /"(?:[^"\\]|\\.)*"|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/g;
|
|
402
|
+
var LONG_DIGIT_RUN = /\d{16}/;
|
|
403
|
+
function quoteLargeJsonIntegers(text) {
|
|
404
|
+
if (!LONG_DIGIT_RUN.test(text)) return text;
|
|
405
|
+
return text.replace(JSON_STRING_OR_NUMBER, (token) => {
|
|
406
|
+
if (token.charCodeAt(0) === 34) return token;
|
|
407
|
+
if (token.includes(".") || token.includes("e") || token.includes("E")) return token;
|
|
408
|
+
const digitCount = token.charCodeAt(0) === 45 ? token.length - 1 : token.length;
|
|
409
|
+
return digitCount >= LONG_INTEGER_MIN_DIGITS ? `"${token}"` : token;
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
function createE10RequestRuntime(ctx, session, dependencies = {}) {
|
|
413
|
+
return new E10RequestRuntime(ctx, session, dependencies);
|
|
414
|
+
}
|
|
415
|
+
function withQuery(baseUrl, requestPath, query = {}) {
|
|
416
|
+
const url = new URL(`${baseUrl}${requestPath}`);
|
|
417
|
+
for (const [key, value] of Object.entries(query)) {
|
|
418
|
+
if (value === void 0 || value === null) continue;
|
|
419
|
+
if (Array.isArray(value)) {
|
|
420
|
+
for (const item of value) url.searchParams.append(key, String(item));
|
|
421
|
+
} else {
|
|
422
|
+
url.searchParams.set(key, String(value));
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return url;
|
|
426
|
+
}
|
|
427
|
+
async function readBoundedText(response, limit, timeoutMs) {
|
|
428
|
+
if (!response.body) return "";
|
|
429
|
+
const reader = response.body.getReader();
|
|
430
|
+
const chunks = [];
|
|
431
|
+
let size = 0;
|
|
432
|
+
let expired = false;
|
|
433
|
+
const timer = setTimeout(() => {
|
|
434
|
+
expired = true;
|
|
435
|
+
void reader.cancel().catch(() => void 0);
|
|
436
|
+
}, timeoutMs);
|
|
437
|
+
try {
|
|
438
|
+
while (true) {
|
|
439
|
+
const next = await reader.read();
|
|
440
|
+
if (expired) throw new E10ApiError("network", "timeout", "\u6587\u4EF6\u670D\u52A1\u54CD\u5E94\u8BFB\u53D6\u8D85\u65F6", { retryable: false });
|
|
441
|
+
if (next.done) break;
|
|
442
|
+
size += next.value.byteLength;
|
|
443
|
+
if (size > limit) {
|
|
444
|
+
await reader.cancel().catch(() => void 0);
|
|
445
|
+
throw new E10ApiError("network", "response_too_large", "\u6587\u4EF6\u670D\u52A1\u54CD\u5E94\u8D85\u8FC7\u5927\u5C0F\u4E0A\u9650", { retryable: false });
|
|
446
|
+
}
|
|
447
|
+
chunks.push(next.value);
|
|
448
|
+
}
|
|
449
|
+
return Buffer.concat(chunks, size).toString("utf8");
|
|
450
|
+
} catch (error) {
|
|
451
|
+
if (error instanceof E10ApiError) throw error;
|
|
452
|
+
throw new E10ApiError("network", "response_read_failed", "\u6587\u4EF6\u670D\u52A1\u54CD\u5E94\u8BFB\u53D6\u5931\u8D25", { retryable: false });
|
|
453
|
+
} finally {
|
|
454
|
+
clearTimeout(timer);
|
|
455
|
+
reader.releaseLock();
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
function sanitizePublicHeaders(headers) {
|
|
459
|
+
const next = { ...headers };
|
|
460
|
+
stripReservedHeaders(next);
|
|
461
|
+
return next;
|
|
462
|
+
}
|
|
463
|
+
function stripReservedHeaders(headers) {
|
|
464
|
+
for (const key of Object.keys(headers)) {
|
|
465
|
+
if (RESERVED_HEADERS.includes(key.toLowerCase())) {
|
|
466
|
+
delete headers[key];
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
function responseForHook(response) {
|
|
471
|
+
if ("content" in response) {
|
|
472
|
+
return {
|
|
473
|
+
status: response.status,
|
|
474
|
+
headers: new Headers(response.headers),
|
|
475
|
+
contentType: response.contentType,
|
|
476
|
+
contentLength: response.content.length
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
return {
|
|
480
|
+
status: response.status,
|
|
481
|
+
headers: new Headers(response.headers),
|
|
482
|
+
value: cloneForHook(response.value),
|
|
483
|
+
text: response.text
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
function requestForHook(request) {
|
|
487
|
+
return {
|
|
488
|
+
...request,
|
|
489
|
+
query: { ...request.query },
|
|
490
|
+
headers: { ...request.headers },
|
|
491
|
+
body: cloneForHook(request.body),
|
|
492
|
+
streamBody: void 0
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
function cloneForHook(value) {
|
|
496
|
+
if (value === void 0 || value === null) return value;
|
|
497
|
+
try {
|
|
498
|
+
return structuredClone(value);
|
|
499
|
+
} catch {
|
|
500
|
+
return value;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
export {
|
|
505
|
+
requireE10Session,
|
|
506
|
+
E10ApiError,
|
|
507
|
+
createE10RequestRuntime
|
|
508
|
+
};
|