weaver-work-cli 0.1.33 → 0.1.38
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-FVFY6GZN.js → archive-PDV724YK.js} +5 -4
- package/dist/chunks/{archive-oa-NW3OD4UV.js → archive-oa-4XE4MNXQ.js} +4 -3
- package/dist/chunks/{asset-7QJKMIDV.js → asset-PDL2QE2N.js} +8 -7
- package/dist/chunks/{attachment-content-OSAVA6K3.js → attachment-content-MDDGOE5E.js} +3 -3
- package/dist/chunks/{blog-I7SDPNW4.js → blog-UYR3EUXW.js} +5 -4
- package/dist/chunks/{caizhilian-O37ZIQNY.js → caizhilian-LG2X5NMF.js} +5 -4
- package/dist/chunks/{calendar-7KXE4ED3.js → calendar-FG4BAZHE.js} +4 -3
- package/dist/chunks/{chunk-Q6LWB5HX.js → chunk-6FTTSA45.js} +4 -3
- package/dist/chunks/{chunk-MQ2I5AA3.js → chunk-6LTFIFLM.js} +3 -2
- package/dist/chunks/{chunk-WRRJ4GG2.js → chunk-CORFRD7Q.js} +4 -3
- package/dist/chunks/{chunk-WY74UBJ6.js → chunk-DMV2TOMH.js} +2194 -240
- package/dist/chunks/{chunk-MEEFGWTM.js → chunk-ELYDWBZJ.js} +135 -10
- package/dist/chunks/{chunk-EEWPQE3O.js → chunk-FUWVHMVV.js} +7 -6
- package/dist/chunks/{chunk-HEL5XTYI.js → chunk-GGJFMNJM.js} +26 -4
- package/dist/chunks/{chunk-KAS45KNR.js → chunk-IZUDA353.js} +1 -1
- package/dist/chunks/{chunk-2FLWXFVS.js → chunk-J7USS3ED.js} +4 -4
- package/dist/chunks/{chunk-IHUYP6LO.js → chunk-JSMFPO43.js} +1 -1
- package/dist/chunks/{chunk-RBGOMK4Y.js → chunk-KKRL3REV.js} +5 -4
- package/dist/chunks/{chunk-OCU4RLHC.js → chunk-NI6GIPIM.js} +195 -36
- package/dist/chunks/{chunk-PRHJGPMA.js → chunk-NR6RKXPA.js} +2 -2
- package/dist/chunks/{chunk-D223PTXU.js → chunk-OJQUJZQF.js} +33 -7
- package/dist/chunks/{chunk-ILMBNVSG.js → chunk-UJJD4QWF.js} +4 -3
- package/dist/chunks/{chunk-6ATGWRZM.js → chunk-UZZBA6PV.js} +177 -14
- package/dist/chunks/{chunk-GFPXQIY2.js → chunk-VRYHGG6O.js} +2 -2
- package/dist/chunks/{chunk-NHA62QD7.js → chunk-XJY7G4DD.js} +3 -3
- package/dist/chunks/{chunk-VBCFFFGT.js → chunk-Z32KWY6G.js} +4 -1
- package/dist/chunks/{conflict-SFNEVJY5.js → conflict-BQZEQ4SP.js} +2 -2
- package/dist/chunks/contract-XIRAFTEV.js +9111 -0
- package/dist/chunks/{cowork-CKWYHXYB.js → cowork-BLG62BL2.js} +46 -26
- package/dist/chunks/{ebuilder-form-KOLJRVZD.js → ebuilder-form-NUKG5QW4.js} +3 -3
- package/dist/chunks/{ehr-WFOC3B4D.js → ehr-2STW5ILH.js} +174 -10
- package/dist/chunks/{esb-LJZTN663.js → esb-UUDQUNKY.js} +4 -4
- package/dist/chunks/{fna-F7QRIIZC.js → fna-6RCY4NU5.js} +15 -9
- package/dist/chunks/{host-VQ6JJXGQ.js → host-7RXEDMAH.js} +3 -3
- package/dist/chunks/{host-KXPTEWFS.js → host-EJZFROU3.js} +3 -3
- package/dist/chunks/{host-BCGUVEWX.js → host-FWDOSRH5.js} +3 -3
- package/dist/chunks/{host-DGE2TZD4.js → host-RHM3NPXV.js} +3 -3
- package/dist/chunks/{host-BQBRHVR3.js → host-UFF33TWJ.js} +3 -3
- package/dist/chunks/{hrm-NI6XAKW5.js → hrm-PKJ6ELSH.js} +3 -3
- package/dist/chunks/{im-7TRTF3KT.js → im-YJAXS7CO.js} +3 -3
- package/dist/chunks/{invoice-AOXWJKYT.js → invoice-HWVSXGX6.js} +3 -3
- package/dist/chunks/{jiuchuanhui-7NQWEZAW.js → jiuchuanhui-L7VKILZB.js} +4 -3
- package/dist/chunks/{lazy-dispatch-RNS4EE4S.js → lazy-dispatch-NMYEIHRH.js} +4 -4
- package/dist/chunks/{mail-VDHJAB4O.js → mail-B42RRU7G.js} +46 -24
- package/dist/chunks/{meeting-GA7XCNNP.js → meeting-CFYVBJSS.js} +77 -12
- package/dist/chunks/{okr-TQIRERPQ.js → okr-GCLF6V7W.js} +4 -3
- package/dist/chunks/{plan-4RY4LN2P.js → plan-ZVL7GBRI.js} +4 -3
- package/dist/chunks/{project-D6XT2OC5.js → project-4YWAAE2K.js} +4 -3
- package/dist/chunks/{registry-QKMI43Q6.js → registry-EP4VTHZS.js} +8 -8
- package/dist/chunks/{registry-JHRIDQ3A.js → registry-FRJ6H7BT.js} +4 -4
- package/dist/chunks/{registry-VOGKFFTR.js → registry-SG2PGVCF.js} +2 -2
- package/dist/chunks/{room-recommend-D4EUOOWY.js → room-recommend-R3JVUUAC.js} +4 -4
- package/dist/chunks/{schedule-XPFBHPCV.js → schedule-NIJBTYDO.js} +4 -4
- package/dist/chunks/{workflow-HLBZRWIY.js → workflow-BB24DFBY.js} +11 -4
- package/dist/index.js +31 -26
- package/dist/internal/e10/auth-recovery.js +114 -1
- package/dist/internal/e10/client.js +16 -2
- package/dist/internal/e10/fetch-timing.js +31 -0
- package/dist/internal/e10/request-runtime.js +108 -7
- package/dist/shortcuts/archive/host.js +3 -2
- package/dist/shortcuts/archive-oa/host.js +2 -1
- package/dist/shortcuts/asset/host.js +6 -5
- package/dist/shortcuts/blog/host.js +3 -2
- package/dist/shortcuts/caizhilian/host.js +3 -2
- package/dist/shortcuts/calendar/host.js +2 -1
- package/dist/shortcuts/contract/host.js +2 -1
- package/dist/shortcuts/cowork/host.js +10 -1
- package/dist/shortcuts/cowork/operations/types.js +17 -2
- package/dist/shortcuts/ebuilder-form/host.js +3 -1
- package/dist/shortcuts/ehr/host.js +2 -1
- package/dist/shortcuts/ehr/operations/recruit-write.js +35 -0
- package/dist/shortcuts/ehr/operations/recruit.js +147 -0
- package/dist/shortcuts/esb/host.js +2 -1
- package/dist/shortcuts/fna/host.js +2 -1
- package/dist/shortcuts/fna/operations/expense-chart.js +19 -7
- package/dist/shortcuts/hrm/host.js +2 -1
- package/dist/shortcuts/im/host.js +3 -2
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/invoice/host.js +5 -4
- package/dist/shortcuts/jiuchuanhui/host.js +2 -1
- package/dist/shortcuts/mail/host.js +10 -1
- package/dist/shortcuts/mail/operations/types.js +17 -2
- package/dist/shortcuts/meeting/host.js +3 -2
- package/dist/shortcuts/meeting/index.js +79 -1
- package/dist/shortcuts/meeting/invitation/text.js +71 -0
- package/dist/shortcuts/meeting/manifest.js +10 -0
- package/dist/shortcuts/meeting/operations/eb/catalog.js +5 -0
- package/dist/shortcuts/meeting/operations/eb/conflict.js +6 -1
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +2105 -169
- package/dist/shortcuts/meeting/operations/eb/crm-search.js +478 -0
- package/dist/shortcuts/meeting/operations/eb/factory.js +161 -8
- package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +36 -2
- package/dist/shortcuts/meeting/operations/eb-fallback.js +4 -0
- package/dist/shortcuts/meeting/operations/env.js +6 -0
- package/dist/shortcuts/meeting/operations/invitation.js +200 -28
- package/dist/shortcuts/okr/host.js +2 -1
- package/dist/shortcuts/plan/host.js +2 -1
- package/dist/shortcuts/project/host.js +2 -1
- package/dist/shortcuts/workflow/endpoints.js +8 -3
- package/dist/shortcuts/workflow/operations/form.js +341 -36
- package/dist/shortcuts/workflow/operations.js +23 -1
- package/docs/ehr.md +1 -1
- package/docs/fna.md +2 -1
- package/package.json +1 -1
- package/skill-template/business-info.json +18 -0
- package/skill-template/domains/cowork.md +14 -0
- package/skills/weaver-e10-cowork/SKILL.md +101 -0
- package/skills/weaver-e10-cowork/references/cowork-read.md +90 -0
- package/skills/weaver-e10-cowork/references/cowork-write.md +131 -0
- package/skills/weaver-e10-cowork/references/safety-boundaries.md +45 -0
- package/skills/weaver-e10-jucailin/SKILL.md +21 -3
- package/skills/weaver-e10-jucailin/references/recruit-read.md +25 -0
- package/skills/weaver-e10-jucailin/references/recruit-write.md +13 -0
- package/skills/weaver-e10-jucailin/references/salary.md +15 -11
- package/skills/weaver-e10-mail/SKILL.md +12 -9
- package/skills/weaver-e10-meeting/SKILL.md +499 -300
- package/skills/weaver-e10-meeting/references/meeting-eb.md +334 -0
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +64 -6
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- package/skills/weaver-e10-qiyecheng/SKILL.md +5 -2
- package/skills/weaver-e10-qiyecheng/references/catalog.md +2 -2
- package/skills/weaver-e10-qiyecheng/references/expense-chart.md +15 -1
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +22 -21
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +3 -3
package/dist/index.js
CHANGED
|
@@ -7,12 +7,12 @@ import {
|
|
|
7
7
|
firstPositionalToken,
|
|
8
8
|
registerCommands,
|
|
9
9
|
toCommandMetadata
|
|
10
|
-
} from "./chunks/chunk-
|
|
10
|
+
} from "./chunks/chunk-VRYHGG6O.js";
|
|
11
11
|
import "./chunks/chunk-EG6ZU444.js";
|
|
12
12
|
import "./chunks/chunk-AJ62BGAW.js";
|
|
13
|
-
import "./chunks/chunk-
|
|
14
|
-
import "./chunks/chunk-
|
|
15
|
-
import "./chunks/chunk-
|
|
13
|
+
import "./chunks/chunk-FUWVHMVV.js";
|
|
14
|
+
import "./chunks/chunk-UZZBA6PV.js";
|
|
15
|
+
import "./chunks/chunk-OJQUJZQF.js";
|
|
16
16
|
import "./chunks/chunk-LUSPKZKY.js";
|
|
17
17
|
import "./chunks/chunk-BUSC6UAE.js";
|
|
18
18
|
|
|
@@ -29,7 +29,7 @@ function lazyShortcut(definition) {
|
|
|
29
29
|
placeholder.allowExcessArguments(true);
|
|
30
30
|
placeholder.helpOption(false);
|
|
31
31
|
placeholder.action(async () => {
|
|
32
|
-
const { dispatchLazyShortcut } = await import("./chunks/lazy-dispatch-
|
|
32
|
+
const { dispatchLazyShortcut } = await import("./chunks/lazy-dispatch-NMYEIHRH.js");
|
|
33
33
|
await dispatchLazyShortcut(definition, shortcutMetadata());
|
|
34
34
|
});
|
|
35
35
|
}
|
|
@@ -39,107 +39,112 @@ var builtinShortcuts = [
|
|
|
39
39
|
lazyShortcut({
|
|
40
40
|
name: "invoice",
|
|
41
41
|
description: "E10 \u4E1A\u7968\u901A\u53D1\u7968\u7BA1\u7406 CLI",
|
|
42
|
-
load: async () => (await import("./chunks/invoice-
|
|
42
|
+
load: async () => (await import("./chunks/invoice-HWVSXGX6.js")).invoiceShortcut
|
|
43
43
|
}),
|
|
44
44
|
lazyShortcut({
|
|
45
45
|
name: "ehr",
|
|
46
46
|
description: "\u6CDB\u5FAEE10\u805A\u624D\u6797\uFF08\u4EBA\u4E8B/\u51FA\u52E4/\u85AA\u916C\uFF09CLI",
|
|
47
|
-
load: async () => (await import("./chunks/ehr-
|
|
47
|
+
load: async () => (await import("./chunks/ehr-2STW5ILH.js")).ehrShortcut
|
|
48
48
|
}),
|
|
49
49
|
lazyShortcut({
|
|
50
50
|
name: "cowork",
|
|
51
51
|
description: "\u6CDB\u5FAEE10\u534F\u4F5C\u533A\uFF08\u534F\u4F5C\u4E8B\u9879/\u8BA8\u8BBA/\u5BA1\u6279/\u5171\u4EAB\u6743\u9650\uFF09CLI",
|
|
52
|
-
load: async () => (await import("./chunks/cowork-
|
|
52
|
+
load: async () => (await import("./chunks/cowork-BLG62BL2.js")).coworkShortcut
|
|
53
53
|
}),
|
|
54
54
|
lazyShortcut({
|
|
55
55
|
name: "archive",
|
|
56
56
|
description: "E10 \u6587\u4E66\u5B9A\u6863\u6848\u7BA1\u7406 CLI",
|
|
57
|
-
load: async () => (await import("./chunks/archive-
|
|
57
|
+
load: async () => (await import("./chunks/archive-PDV724YK.js")).archiveShortcut
|
|
58
58
|
}),
|
|
59
59
|
lazyShortcut({
|
|
60
60
|
name: "archive-oa",
|
|
61
61
|
description: "E10 \u6863\u6848\u5B9A\u4F4D\u4E0E OA \u5546\u52A1\u5408\u540C\u501F\u9605 CLI",
|
|
62
|
-
load: async () => (await import("./chunks/archive-oa-
|
|
62
|
+
load: async () => (await import("./chunks/archive-oa-4XE4MNXQ.js")).archiveOaShortcut
|
|
63
63
|
}),
|
|
64
64
|
lazyShortcut({
|
|
65
65
|
name: "calendar",
|
|
66
66
|
description: "\u6CDB\u5FAEE10\u65E5\u7A0B\u7BA1\u7406 CLI\uFF08\u521B\u5EFA/\u67E5\u8BE2/\u66F4\u65B0/\u5220\u9664/\u5B57\u5178\uFF09",
|
|
67
|
-
load: async () => (await import("./chunks/calendar-
|
|
67
|
+
load: async () => (await import("./chunks/calendar-FG4BAZHE.js")).calendarShortcut
|
|
68
68
|
}),
|
|
69
69
|
lazyShortcut({
|
|
70
70
|
name: "fna",
|
|
71
71
|
description: "\u6CDB\u5FAEE10\u9F50\u4E1A\u6210\u8D39\u63A7\u4E2D\u5FC3\uFF08\u9884\u7B97/\u8D39\u7528\u4E2D\u5FC3/\u501F\u6B3E\u7BA1\u7406/\u53D1\u7968\u6838\u9500\uFF09CLI",
|
|
72
|
-
load: async () => (await import("./chunks/fna-
|
|
72
|
+
load: async () => (await import("./chunks/fna-6RCY4NU5.js")).fnaShortcut
|
|
73
73
|
}),
|
|
74
74
|
lazyShortcut({
|
|
75
75
|
name: "hrm",
|
|
76
76
|
description: "\u6CDB\u5FAEE10\u7EC4\u7EC7\u7BA1\u7406\uFF08\u5458\u5DE5/\u7EC4\u7EC7/\u5C97\u4F4D\u67E5\u8BE2\uFF09CLI",
|
|
77
|
-
load: async () => (await import("./chunks/hrm-
|
|
77
|
+
load: async () => (await import("./chunks/hrm-PKJ6ELSH.js")).hrmShortcut
|
|
78
78
|
}),
|
|
79
79
|
lazyShortcut({
|
|
80
80
|
name: "mail",
|
|
81
81
|
description: "\u6CDB\u5FAEE10\u90AE\u4EF6\u7BA1\u7406 CLI",
|
|
82
|
-
load: async () => (await import("./chunks/mail-
|
|
82
|
+
load: async () => (await import("./chunks/mail-B42RRU7G.js")).mailShortcut
|
|
83
83
|
}),
|
|
84
84
|
lazyShortcut({
|
|
85
85
|
name: "meeting",
|
|
86
86
|
description: "\u6CDB\u5FAEE10\u4F1A\u8BAE\u7BA1\u7406 CLI\uFF08\u6807\u51C6\u7248\uFF1A\u67E5\u8BE2/\u51B2\u7A81/\u9884\u7EA6/\u56DE\u6267/\u7B7E\u5230\uFF09",
|
|
87
|
-
load: async () => (await import("./chunks/meeting-
|
|
87
|
+
load: async () => (await import("./chunks/meeting-CFYVBJSS.js")).meetingShortcut
|
|
88
88
|
}),
|
|
89
89
|
lazyShortcut({
|
|
90
90
|
name: "okr",
|
|
91
91
|
description: "\u6CDB\u5FAEE10 OKR \u76EE\u6807\u7BA1\u7406 CLI\uFF08\u76EE\u6807\u67E5\u8BE2/\u65B0\u5EFA/\u7F16\u8F91\u3001\u5173\u952E\u6210\u679C\u3001\u76EE\u6807\u5BF9\u9F50\u3001\u8BC4\u8BBA\uFF09",
|
|
92
|
-
load: async () => (await import("./chunks/okr-
|
|
92
|
+
load: async () => (await import("./chunks/okr-GCLF6V7W.js")).okrShortcut
|
|
93
93
|
}),
|
|
94
94
|
lazyShortcut({
|
|
95
95
|
name: "plan",
|
|
96
96
|
description: "\u6CDB\u5FAEE10\u8BA1\u5212\u62A5\u544A CLI\uFF08\u67E5\u8BE2/\u65B0\u5EFA/\u4FEE\u6539/\u53D1\u5E03/\u64A4\u56DE/\u63D0\u4EA4\u63D0\u9192/\u8BC4\u8BBA\uFF09",
|
|
97
|
-
load: async () => (await import("./chunks/plan-
|
|
97
|
+
load: async () => (await import("./chunks/plan-ZVL7GBRI.js")).planShortcut
|
|
98
98
|
}),
|
|
99
99
|
lazyShortcut({
|
|
100
100
|
name: "esb",
|
|
101
101
|
description: "\u6CDB\u5FAEE10 ESB \u4E2D\u5FC3\u81EA\u5B9A\u4E49\u89E6\u53D1\u52A8\u4F5C\u6D41 CLI",
|
|
102
|
-
load: async () => (await import("./chunks/esb-
|
|
102
|
+
load: async () => (await import("./chunks/esb-UUDQUNKY.js")).esbShortcut
|
|
103
103
|
}),
|
|
104
104
|
lazyShortcut({
|
|
105
105
|
name: "ebuilder-form",
|
|
106
106
|
description: "\u6CDB\u5FAEE10 eBuilder \u8868\u5355\u83DC\u5355\u3001\u5217\u8868\u548C\u8868\u5355\u6570\u636E CLI",
|
|
107
|
-
load: async () => (await import("./chunks/ebuilder-form-
|
|
107
|
+
load: async () => (await import("./chunks/ebuilder-form-NUKG5QW4.js")).ebuilderFormShortcut
|
|
108
108
|
}),
|
|
109
109
|
lazyShortcut({
|
|
110
110
|
name: "jiuchuanhui",
|
|
111
111
|
description: "\u6CDB\u5FAEE10\u4E5D\u6C1A\u6C47\u8425\u9500\u7BA1\u7406 CLI\uFF08\u5BA2\u6237/\u8054\u7CFB\u4EBA/\u5546\u673A/\u7EBF\u7D22/\u8054\u7CFB\u8BA1\u5212/\u516C\u6D77\uFF09",
|
|
112
|
-
load: async () => (await import("./chunks/jiuchuanhui-
|
|
112
|
+
load: async () => (await import("./chunks/jiuchuanhui-L7VKILZB.js")).jiuchuanhuiShortcut
|
|
113
113
|
}),
|
|
114
114
|
lazyShortcut({
|
|
115
115
|
name: "asset",
|
|
116
116
|
description: "E10 \u8D44\u4EA7\u7BA1\u7406\uFF08\u8D44\u7BA1\u5BB6\uFF09CLI",
|
|
117
|
-
load: async () => (await import("./chunks/asset-
|
|
117
|
+
load: async () => (await import("./chunks/asset-PDL2QE2N.js")).assetShortcut
|
|
118
118
|
}),
|
|
119
119
|
lazyShortcut({
|
|
120
120
|
name: "im",
|
|
121
121
|
description: "\u6CDB\u5FAEE10\u6613\u79D2\u529E\uFF08\u5373\u65F6\u901A\u8BAF\uFF09CLI",
|
|
122
|
-
load: async () => (await import("./chunks/im-
|
|
122
|
+
load: async () => (await import("./chunks/im-YJAXS7CO.js")).imShortcut
|
|
123
123
|
}),
|
|
124
124
|
lazyShortcut({
|
|
125
125
|
name: "project",
|
|
126
126
|
description: "\u6CDB\u5FAEE10\u4E8B\u4E95\u7136\u9879\u76EE\u7BA1\u7406 CLI\uFF08\u9879\u76EE/\u4EFB\u52A1\u67E5\u8BE2\u4E0E\u786E\u8BA4\u5199\u5165\uFF09",
|
|
127
|
-
load: async () => (await import("./chunks/project-
|
|
127
|
+
load: async () => (await import("./chunks/project-4YWAAE2K.js")).projectShortcut
|
|
128
128
|
}),
|
|
129
129
|
lazyShortcut({
|
|
130
130
|
name: "workflow",
|
|
131
131
|
description: "\u6CDB\u5FAEE10\u6D41\u7A0B\u667A\u80FD\u52A9\u624B CLI\uFF08\u67E5\u8BE2/\u67E5\u770B/\u64CD\u4F5C/\u6279\u91CF/\u53D1\u8D77/\u4FEE\u6539\uFF09",
|
|
132
|
-
load: async () => (await import("./chunks/workflow-
|
|
132
|
+
load: async () => (await import("./chunks/workflow-BB24DFBY.js")).workflowShortcut
|
|
133
133
|
}),
|
|
134
134
|
lazyShortcut({
|
|
135
135
|
name: "blog",
|
|
136
136
|
description: "\u6CDB\u5FAEE10\u5DE5\u4F5C\u65E5\u62A5 CLI\uFF08\u67E5\u8BE2/\u53D1\u5E03/\u7F16\u8F91/\u8BC4\u8BBA/\u70B9\u8D5E/\u63D0\u9192/\u5BFC\u51FA\uFF09",
|
|
137
|
-
load: async () => (await import("./chunks/blog-
|
|
137
|
+
load: async () => (await import("./chunks/blog-UYR3EUXW.js")).blogShortcut
|
|
138
138
|
}),
|
|
139
139
|
lazyShortcut({
|
|
140
140
|
name: "caizhilian",
|
|
141
141
|
description: "\u6CDB\u5FAEE10\u91C7\u77E5\u8FDE\uFF08\u6587\u6863\u4E2D\u5FC3\uFF09CLI",
|
|
142
|
-
load: async () => (await import("./chunks/caizhilian-
|
|
142
|
+
load: async () => (await import("./chunks/caizhilian-LG2X5NMF.js")).caizhilianShortcut
|
|
143
|
+
}),
|
|
144
|
+
lazyShortcut({
|
|
145
|
+
name: "contract",
|
|
146
|
+
description: "\u6CDB\u5FAEE10\u4ECA\u627F\u8FBE\u5408\u540C\u7BA1\u7406 CLI",
|
|
147
|
+
load: async () => (await import("./chunks/contract-XIRAFTEV.js")).contractShortcut
|
|
143
148
|
})
|
|
144
149
|
];
|
|
145
150
|
function shortcutMetadata() {
|
|
@@ -23,6 +23,116 @@ const AUTH_REQUIRED_MARKERS = [
|
|
|
23
23
|
'not logged in',
|
|
24
24
|
'not login',
|
|
25
25
|
];
|
|
26
|
+
const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
|
|
27
|
+
/** Location 命中这些特征即为登录类跳转。 */
|
|
28
|
+
const LOGIN_REDIRECT_MARKERS = [
|
|
29
|
+
'login',
|
|
30
|
+
'passport',
|
|
31
|
+
'sso',
|
|
32
|
+
'oauth',
|
|
33
|
+
'signin',
|
|
34
|
+
'sign-in',
|
|
35
|
+
'authorize',
|
|
36
|
+
'authn',
|
|
37
|
+
'atrust',
|
|
38
|
+
'checkticket',
|
|
39
|
+
];
|
|
40
|
+
/** Location 命中这些特征即为文件服务/对象存储交接。 */
|
|
41
|
+
const FILE_REDIRECT_MARKERS = [
|
|
42
|
+
'fileservice',
|
|
43
|
+
'/file/download',
|
|
44
|
+
'/file/remotedownload',
|
|
45
|
+
'/remotedownload/',
|
|
46
|
+
'/api/file/',
|
|
47
|
+
'/download/',
|
|
48
|
+
'aliyuncs.com',
|
|
49
|
+
'myqcloud.com',
|
|
50
|
+
'qiniucdn.com',
|
|
51
|
+
'qbox.me',
|
|
52
|
+
'jdcloud.com',
|
|
53
|
+
'amazonaws.com',
|
|
54
|
+
'blob.core.windows.net',
|
|
55
|
+
'ctyunapi.cn',
|
|
56
|
+
'hiclouds.com',
|
|
57
|
+
'minio',
|
|
58
|
+
's3.',
|
|
59
|
+
'obs.',
|
|
60
|
+
'ks3',
|
|
61
|
+
];
|
|
62
|
+
/** 这些请求路径本身就是取文件:其 3xx 只要不是登录页,就是文件服务交接。 */
|
|
63
|
+
const FILE_REQUEST_PATH_MARKERS = [
|
|
64
|
+
'/api/file/',
|
|
65
|
+
'/file/download',
|
|
66
|
+
'/remotedownload/',
|
|
67
|
+
'/fileservice',
|
|
68
|
+
'/download',
|
|
69
|
+
];
|
|
70
|
+
/** 跳转目标是前端页面骨架(如 wui/index.html#/main),不是文件直链。 */
|
|
71
|
+
const APP_SHELL_REDIRECT = /(?:\.html?(?:[?#]|$)|#\/|wui\/)/u;
|
|
72
|
+
export function isE10RedirectStatus(status) {
|
|
73
|
+
return REDIRECT_STATUSES.has(status);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 取跳转目标里「有语义」的部分:主机名 + 路径 + hash,**丢掉 query**。
|
|
77
|
+
* 对象存储的签名 query 是长随机串,拿去匹配关键词容易误伤(例如签名里恰好
|
|
78
|
+
* 出现 `sso`),所以只在主机与路径上判定。
|
|
79
|
+
*/
|
|
80
|
+
function redirectTarget(location) {
|
|
81
|
+
const raw = location.trim().toLowerCase();
|
|
82
|
+
if (!raw)
|
|
83
|
+
return '';
|
|
84
|
+
try {
|
|
85
|
+
const url = new URL(raw, 'https://e10.invalid');
|
|
86
|
+
return `${url.hostname}${url.pathname}${url.hash}`.toLowerCase();
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return raw.split('?')[0];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 识别 3xx 的真实语义。登录跳转优先判定,避免对象存储地址里的参数误伤;
|
|
94
|
+
* 若是下载类请求且目标不像登录页,则认为是文件服务交接(对象存储的签名地址
|
|
95
|
+
* 不一定带 `fileservice` 之类的特征,只能靠请求路径反推)。
|
|
96
|
+
*/
|
|
97
|
+
export function classifyE10Redirect(response) {
|
|
98
|
+
if (!isE10RedirectStatus(response.status))
|
|
99
|
+
return 'other';
|
|
100
|
+
const target = redirectTarget(response.headers?.get('location') || '');
|
|
101
|
+
if (!target)
|
|
102
|
+
return 'other';
|
|
103
|
+
if (LOGIN_REDIRECT_MARKERS.some((marker) => target.includes(marker)))
|
|
104
|
+
return 'login';
|
|
105
|
+
if (FILE_REDIRECT_MARKERS.some((marker) => target.includes(marker)))
|
|
106
|
+
return 'file';
|
|
107
|
+
const requestPath = (response.requestPath || '').toLowerCase();
|
|
108
|
+
if (requestPath
|
|
109
|
+
&& FILE_REQUEST_PATH_MARKERS.some((marker) => requestPath.includes(marker))
|
|
110
|
+
// 跳到前端页面骨架说明不是文件直链,继续按「无法判定」保守处理。
|
|
111
|
+
&& !APP_SHELL_REDIRECT.test(target)) {
|
|
112
|
+
return 'file';
|
|
113
|
+
}
|
|
114
|
+
return 'other';
|
|
115
|
+
}
|
|
116
|
+
/** 3xx 指向文件服务:属于下载直传,登录态有效,不得触发重新登录。 */
|
|
117
|
+
export function isE10FileRedirect(response) {
|
|
118
|
+
return classifyE10Redirect(response) === 'file';
|
|
119
|
+
}
|
|
120
|
+
/** 3xx 指向登录页:登录态确实失效。 */
|
|
121
|
+
export function isE10LoginRedirect(response) {
|
|
122
|
+
return classifyE10Redirect(response) === 'login';
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 业务层统一的「HTTP 层登录态失效」判定:401,或 3xx 且不是文件服务交接。
|
|
126
|
+
* 各 shortcut 用它替代原来的 `status === 401 || status === 302`,避免把下载
|
|
127
|
+
* 直传的 302 误报成登录失效。
|
|
128
|
+
*/
|
|
129
|
+
export function isE10SessionExpiredResponse(response) {
|
|
130
|
+
if (response.status === 401)
|
|
131
|
+
return true;
|
|
132
|
+
if (isE10RedirectStatus(response.status))
|
|
133
|
+
return !isE10FileRedirect(response);
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
26
136
|
const recoveryInFlight = new Map();
|
|
27
137
|
function asRecord(value) {
|
|
28
138
|
return value && typeof value === 'object' && !Array.isArray(value)
|
|
@@ -77,9 +187,12 @@ function responseText(response) {
|
|
|
77
187
|
* Detect only explicit authentication rejection signals. A bare HTTP 403 is
|
|
78
188
|
* deliberately excluded because E10 also uses it for ordinary permission
|
|
79
189
|
* denials, which must never trigger a credential refresh.
|
|
190
|
+
*
|
|
191
|
+
* 3xx 只在「跳到登录页」或「无法判定」时才算认证失败:下载接口把文件交接给
|
|
192
|
+
* 文件服务时同样返回 302,那不是登录失效,重新登录既无用也会白白换一次票据。
|
|
80
193
|
*/
|
|
81
194
|
export function isE10AuthenticationRequired(response) {
|
|
82
|
-
if (response
|
|
195
|
+
if (isE10SessionExpiredResponse(response))
|
|
83
196
|
return true;
|
|
84
197
|
if (responseCodes(response.value).some((code) => AUTH_REQUIRED_CODES.has(code)))
|
|
85
198
|
return true;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isE10AuthenticationRequired, sameE10SessionIdentity, } from './auth-recovery.js';
|
|
1
|
+
import { isE10AuthenticationRequired, isE10LoginRedirect, isE10RedirectStatus, sameE10SessionIdentity, } from './auth-recovery.js';
|
|
2
2
|
class E10AuthenticationContextChangedError extends Error {
|
|
3
3
|
}
|
|
4
4
|
export class E10ApiClient {
|
|
@@ -78,6 +78,7 @@ export class E10ApiClient {
|
|
|
78
78
|
if (!authenticationRecoveryAttempted && isE10AuthenticationRequired({
|
|
79
79
|
status: resp.status,
|
|
80
80
|
headers: resp.headers,
|
|
81
|
+
requestPath: safePathname(url),
|
|
81
82
|
text,
|
|
82
83
|
value,
|
|
83
84
|
})) {
|
|
@@ -94,7 +95,12 @@ export class E10ApiClient {
|
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
// Preserve the legacy password-based refresh for non-XiaoE callers.
|
|
97
|
-
|
|
98
|
+
// 只有真的跳到登录页才刷新;3xx 交给文件服务(下载直传)时登录态仍有效。
|
|
99
|
+
if (isE10LoginRedirect({
|
|
100
|
+
status: resp.status,
|
|
101
|
+
headers: resp.headers,
|
|
102
|
+
requestPath: safePathname(url),
|
|
103
|
+
}) || (isE10RedirectStatus(resp.status) && !resp.headers.get('location'))) {
|
|
98
104
|
const ok = await this.auth.ensureValid();
|
|
99
105
|
if (!ok)
|
|
100
106
|
throw new Error('E10 session expired; please login again');
|
|
@@ -134,3 +140,11 @@ function refreshAuthenticationHeaders(init, session) {
|
|
|
134
140
|
headers['user-agent'] = session.uaHeader();
|
|
135
141
|
init.headers = headers;
|
|
136
142
|
}
|
|
143
|
+
function safePathname(rawUrl) {
|
|
144
|
+
try {
|
|
145
|
+
return new URL(rawUrl).pathname;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return rawUrl.startsWith('/') ? rawUrl.split('?')[0] : '';
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
const storage = new AsyncLocalStorage();
|
|
3
|
+
export function createFetchTimingSink() {
|
|
4
|
+
return { fetchMs: 0, fetchCount: 0, fetchStart: null, fetchEnd: null };
|
|
5
|
+
}
|
|
6
|
+
/** 在 `sink` 的上下文里执行 `fn`:期间发生的 fetch 都会记到它上面。 */
|
|
7
|
+
export function runWithFetchTiming(sink, fn) {
|
|
8
|
+
return storage.run(sink, fn);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* fetch 前调一次,拿到的结束函数在 fetch 落定(成功或失败)时调一次。
|
|
12
|
+
* 返回 `null` 表示当前没有 sink(非计时路径)⇒ 调用方跳过全部计时动作。
|
|
13
|
+
*/
|
|
14
|
+
export function startFetchTiming() {
|
|
15
|
+
const sink = storage.getStore();
|
|
16
|
+
if (!sink)
|
|
17
|
+
return null;
|
|
18
|
+
const startedAt = Date.now();
|
|
19
|
+
let finished = false;
|
|
20
|
+
return () => {
|
|
21
|
+
if (finished)
|
|
22
|
+
return;
|
|
23
|
+
finished = true;
|
|
24
|
+
const endedAt = Date.now();
|
|
25
|
+
sink.fetchMs += Math.max(0, endedAt - startedAt);
|
|
26
|
+
sink.fetchCount += 1;
|
|
27
|
+
// 重试会有多次 fetch:起点取最早、终点取最晚,中间的空档(如换票据)不计入 fetchCost。
|
|
28
|
+
sink.fetchStart = sink.fetchStart === null ? startedAt : Math.min(sink.fetchStart, startedAt);
|
|
29
|
+
sink.fetchEnd = sink.fetchEnd === null ? endedAt : Math.max(sink.fetchEnd, endedAt);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { CliError, ExitCode } from '../../core/errors.js';
|
|
2
|
-
import { isE10AuthenticationRequired, recoverXiaoEAuthSession, sameE10SessionIdentity, } from './auth-recovery.js';
|
|
2
|
+
import { classifyE10Redirect, isE10AuthenticationRequired, recoverXiaoEAuthSession, sameE10SessionIdentity, } from './auth-recovery.js';
|
|
3
|
+
import { startFetchTiming } from './fetch-timing.js';
|
|
3
4
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
5
|
const DEFAULT_BIG_INT_STRINGS = true;
|
|
6
|
+
/** 下载直传最多跟几跳:E10 -> 对象存储通常 1 跳,留一点余量但不允许成环。 */
|
|
7
|
+
const MAX_DOWNLOAD_REDIRECTS = 3;
|
|
5
8
|
const RESERVED_HEADERS = [
|
|
6
9
|
'authorization',
|
|
7
10
|
'cookie',
|
|
@@ -62,16 +65,18 @@ export class E10RequestRuntime {
|
|
|
62
65
|
}
|
|
63
66
|
stripReservedHeaders(mutable.headers);
|
|
64
67
|
const requestEteamsId = this.session.eteamsId;
|
|
65
|
-
let
|
|
68
|
+
let attempt = await this.executeRequest(mutable, request.trustedHeaders);
|
|
66
69
|
if (!mutable.streamBody
|
|
67
|
-
|
|
70
|
+
// 已交接给文件服务的响应不是 E10 的接口回答,登录态不该由它判定。
|
|
71
|
+
&& !attempt.fromFileRedirect
|
|
72
|
+
&& isE10AuthenticationRequired(authenticationProbe(mutable, attempt.parsed))
|
|
68
73
|
&& await this.recoverExpiredSession(requestEteamsId)) {
|
|
69
74
|
// Authentication rejection is a definitive pre-business failure. Retry
|
|
70
75
|
// exactly once with the new session; never retry transport/partial errors.
|
|
71
|
-
|
|
76
|
+
attempt = await this.executeRequest(mutable, request.trustedHeaders);
|
|
72
77
|
}
|
|
73
|
-
await this.runAfterResponse(mutable, this.sessionContext(), parsed);
|
|
74
|
-
return parsed;
|
|
78
|
+
await this.runAfterResponse(mutable, this.sessionContext(), attempt.parsed);
|
|
79
|
+
return attempt.parsed;
|
|
75
80
|
}
|
|
76
81
|
catch (error) {
|
|
77
82
|
await this.runOnError(mutable, this.sessionContext(), error);
|
|
@@ -83,7 +88,74 @@ export class E10RequestRuntime {
|
|
|
83
88
|
const headers = this.composeHeaders(request, trustedHeaders);
|
|
84
89
|
const init = this.buildFetchInit(request, headers);
|
|
85
90
|
const response = await this.fetchWithTimeout(url, init, request.timeoutMs);
|
|
86
|
-
|
|
91
|
+
// 二进制下载:E10 常以 302 把文件交接给文件服务/对象存储。这里直接跟过去
|
|
92
|
+
// 取字节,既不会把「文件流」当成登录失效,也不会触发无谓的重新登录。
|
|
93
|
+
const followed = request.responseType === 'binary'
|
|
94
|
+
? await this.followDownloadRedirect(response, request, url)
|
|
95
|
+
: { response, followed: false };
|
|
96
|
+
if (followed.followed && (followed.response.status === 401 || followed.response.status === 403)) {
|
|
97
|
+
// 这是文件服务对直链的回答(签名过期/无权限),与 E10 登录态无关:
|
|
98
|
+
// 报清楚,别让调用方误以为要重新登录。
|
|
99
|
+
throw new E10ApiError('network', 'download_file_service_denied', `文件服务拒绝下载(HTTP ${followed.response.status}),直链可能已过期,请重试下载`, {
|
|
100
|
+
retryable: true,
|
|
101
|
+
exitCode: ExitCode.NetworkError,
|
|
102
|
+
details: { status: followed.response.status },
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
parsed: await this.readResponse(followed.response, request.responseType, request.bigIntStrings, request.maxResponseBytes, request.timeoutMs),
|
|
107
|
+
fromFileRedirect: followed.followed,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 跟随下载直传的 3xx。仅当跳转目标是文件服务(非登录页)时才跟随,最多
|
|
112
|
+
* `MAX_DOWNLOAD_REDIRECTS` 跳;登录类跳转原样返回,交给上层认证恢复处理。
|
|
113
|
+
* 凭证规则:同源才继续带 Cookie/eteamsid,跨域(对象存储)不带任何鉴权头。
|
|
114
|
+
*/
|
|
115
|
+
async followDownloadRedirect(response, request, requestUrl) {
|
|
116
|
+
const baseOrigin = safeOrigin(this.session.getBaseUrl());
|
|
117
|
+
let current = response;
|
|
118
|
+
let currentUrl = requestUrl;
|
|
119
|
+
let followed = false;
|
|
120
|
+
for (let hop = 0; hop < MAX_DOWNLOAD_REDIRECTS; hop += 1) {
|
|
121
|
+
const kind = classifyE10Redirect({
|
|
122
|
+
status: current.status,
|
|
123
|
+
headers: current.headers,
|
|
124
|
+
requestPath: request.path,
|
|
125
|
+
});
|
|
126
|
+
if (kind !== 'file')
|
|
127
|
+
return { response: current, followed };
|
|
128
|
+
const location = current.headers.get('location');
|
|
129
|
+
if (!location)
|
|
130
|
+
return { response: current, followed };
|
|
131
|
+
let next;
|
|
132
|
+
try {
|
|
133
|
+
next = new URL(location, currentUrl);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return { response: current, followed };
|
|
137
|
+
}
|
|
138
|
+
if (!/^https?:$/u.test(next.protocol))
|
|
139
|
+
return { response: current, followed };
|
|
140
|
+
const sameOrigin = baseOrigin !== '' && safeOrigin(next.toString()) === baseOrigin;
|
|
141
|
+
current = await this.fetchWithTimeout(next, this.buildDownloadRedirectInit(sameOrigin), request.timeoutMs);
|
|
142
|
+
currentUrl = next;
|
|
143
|
+
followed = true;
|
|
144
|
+
}
|
|
145
|
+
return { response: current, followed };
|
|
146
|
+
}
|
|
147
|
+
buildDownloadRedirectInit(sameOrigin) {
|
|
148
|
+
const headers = {
|
|
149
|
+
Accept: 'application/octet-stream, */*',
|
|
150
|
+
'User-Agent': this.session.uaHeader(),
|
|
151
|
+
};
|
|
152
|
+
if (sameOrigin) {
|
|
153
|
+
headers.Cookie = this.attachSessionTicket
|
|
154
|
+
? this.session.cookieHeaderWithSessionTicket()
|
|
155
|
+
: this.session.cookieHeader();
|
|
156
|
+
headers.eteamsid = this.session.eteamsId;
|
|
157
|
+
}
|
|
158
|
+
return { method: 'GET', headers, redirect: 'manual' };
|
|
87
159
|
}
|
|
88
160
|
async recoverExpiredSession(requestEteamsId) {
|
|
89
161
|
// Another concurrent request may already have refreshed the shared session
|
|
@@ -220,6 +292,9 @@ export class E10RequestRuntime {
|
|
|
220
292
|
async fetchWithTimeout(url, init, timeoutMs) {
|
|
221
293
|
const controller = new AbortController();
|
|
222
294
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
295
|
+
// 「纯 fetch」= 发出请求 → 收到响应头(`fetch` 落定那一刻,不含读响应体/解析)。没有计时上下文
|
|
296
|
+
// (`startFetchTiming()` 返回 `null`)时它什么都不做,非计时路径零开销。
|
|
297
|
+
const stopFetchTiming = startFetchTiming();
|
|
223
298
|
try {
|
|
224
299
|
return await this.fetchFn(url, { ...init, signal: controller.signal });
|
|
225
300
|
}
|
|
@@ -238,6 +313,7 @@ export class E10RequestRuntime {
|
|
|
238
313
|
}
|
|
239
314
|
finally {
|
|
240
315
|
clearTimeout(timer);
|
|
316
|
+
stopFetchTiming?.();
|
|
241
317
|
}
|
|
242
318
|
}
|
|
243
319
|
async readResponse(response, responseType, bigIntStrings = DEFAULT_BIG_INT_STRINGS, maxResponseBytes, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
@@ -271,6 +347,31 @@ export class E10RequestRuntime {
|
|
|
271
347
|
export function parseJsonPreservingBigInts(text) {
|
|
272
348
|
return JSON.parse(quoteLargeJsonIntegers(text));
|
|
273
349
|
}
|
|
350
|
+
/**
|
|
351
|
+
* 组装认证探测入参。二进制响应不能把文件字节交给关键词扫描(乱码里出现
|
|
352
|
+
* 「login」会误判成登录失效),只保留状态码与跳转目标;同时带上请求路径,
|
|
353
|
+
* 让「下载接口 -> 文件服务」的 3xx 能被识别为交接而不是失效。
|
|
354
|
+
*/
|
|
355
|
+
function authenticationProbe(request, response) {
|
|
356
|
+
if ('content' in response) {
|
|
357
|
+
return { status: response.status, headers: response.headers, requestPath: request.path };
|
|
358
|
+
}
|
|
359
|
+
return {
|
|
360
|
+
status: response.status,
|
|
361
|
+
headers: response.headers,
|
|
362
|
+
requestPath: request.path,
|
|
363
|
+
text: response.text,
|
|
364
|
+
value: response.value,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
function safeOrigin(rawUrl) {
|
|
368
|
+
try {
|
|
369
|
+
return new URL(rawUrl).origin.toLowerCase();
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
return '';
|
|
373
|
+
}
|
|
374
|
+
}
|
|
274
375
|
const LONG_INTEGER_MIN_DIGITS = 16;
|
|
275
376
|
// 一趟扫描把 JSON 拆成「字符串字面量」与「数字」两类 token:字符串整体跳过,
|
|
276
377
|
// 数字只在它是纯整数且位数够长时补引号。逐字符拼串在 MB 级响应上要 100 ms 以上,
|
|
@@ -2,6 +2,7 @@ import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js
|
|
|
2
2
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
3
3
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
4
4
|
import { E10ApiError, createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
5
|
+
import { isE10SessionExpiredResponse } from '../../internal/e10/auth-recovery.js';
|
|
5
6
|
import { ArchiveCliError, archiveAuthError, archiveNetworkError, archiveValidationError, } from './errors.js';
|
|
6
7
|
function inferProfile(ctx) {
|
|
7
8
|
const options = ctx.getGlobalOptions();
|
|
@@ -151,7 +152,7 @@ export function createArchiveHost(ctx, dependencies = {}) {
|
|
|
151
152
|
}
|
|
152
153
|
async function request(request) {
|
|
153
154
|
const response = await doRequest(request, false).catch((error) => mapRuntimeNetworkError(error));
|
|
154
|
-
if (response
|
|
155
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
155
156
|
throw archiveAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
156
157
|
}
|
|
157
158
|
if (response.parseError) {
|
|
@@ -182,7 +183,7 @@ export function createArchiveHost(ctx, dependencies = {}) {
|
|
|
182
183
|
}
|
|
183
184
|
async function requestBinary(request) {
|
|
184
185
|
const response = await doRequest(request, true).catch((error) => mapRuntimeNetworkError(error));
|
|
185
|
-
if (response
|
|
186
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
186
187
|
throw archiveAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
187
188
|
}
|
|
188
189
|
if (response.status < 200 || response.status >= 300) {
|
|
@@ -2,6 +2,7 @@ import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js
|
|
|
2
2
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
3
3
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
4
4
|
import { E10ApiError, createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
5
|
+
import { isE10SessionExpiredResponse } from '../../internal/e10/auth-recovery.js';
|
|
5
6
|
import { ArchiveOaCliError, archiveOaAuthError, archiveOaNetworkError, archiveOaValidationError, } from './errors.js';
|
|
6
7
|
/** 本模块允许调用的路径前缀:ebuilder 业务接口与 OpenESB 开放服务。 */
|
|
7
8
|
const ALLOWED_PATH_PREFIXES = ['/api/', '/openserver/'];
|
|
@@ -122,7 +123,7 @@ export function createArchiveOaHost(ctx, dependencies = {}) {
|
|
|
122
123
|
headers: { 'X-Requested-With': 'XMLHttpRequest', ...extraHeaders },
|
|
123
124
|
timeoutMs,
|
|
124
125
|
}).catch((error) => mapRuntimeNetworkError(error));
|
|
125
|
-
if (response
|
|
126
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
126
127
|
throw archiveOaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
127
128
|
}
|
|
128
129
|
if (response.parseError) {
|
|
@@ -2,6 +2,7 @@ import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js
|
|
|
2
2
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
3
3
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
4
4
|
import { createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
5
|
+
import { isE10SessionExpiredResponse } from '../../internal/e10/auth-recovery.js';
|
|
5
6
|
import { ziguanjiaAuthError, ziguanjiaBusinessError, ziguanjiaNetworkError, ziguanjiaValidationError, } from './errors.js';
|
|
6
7
|
const EBUILDER_PREFIX = process.env.WEAVER_EBUILDER_PREFIX || '/api/ebuilder';
|
|
7
8
|
const ESB_TRIGGER_PATH = '/api/esb/server/event/triggerActionFlow';
|
|
@@ -176,7 +177,7 @@ export function createZiguanjiaHost(ctx) {
|
|
|
176
177
|
query,
|
|
177
178
|
bigIntStrings: true,
|
|
178
179
|
});
|
|
179
|
-
if (response
|
|
180
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
180
181
|
throw ziguanjiaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
181
182
|
}
|
|
182
183
|
if (response.parseError) {
|
|
@@ -242,7 +243,7 @@ export function createZiguanjiaHost(ctx) {
|
|
|
242
243
|
formData: fd,
|
|
243
244
|
bigIntStrings: false,
|
|
244
245
|
});
|
|
245
|
-
if (response
|
|
246
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
246
247
|
throw ziguanjiaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
247
248
|
}
|
|
248
249
|
if (response.parseError) {
|
|
@@ -315,7 +316,7 @@ export function createZiguanjiaHost(ctx) {
|
|
|
315
316
|
},
|
|
316
317
|
bigIntStrings: true,
|
|
317
318
|
});
|
|
318
|
-
if (response
|
|
319
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
319
320
|
throw ziguanjiaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
320
321
|
}
|
|
321
322
|
if (response.parseError) {
|
|
@@ -363,7 +364,7 @@ export function createZiguanjiaHost(ctx) {
|
|
|
363
364
|
body: fullBody,
|
|
364
365
|
bigIntStrings: true,
|
|
365
366
|
});
|
|
366
|
-
if (response
|
|
367
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
367
368
|
throw ziguanjiaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
368
369
|
}
|
|
369
370
|
if (response.parseError) {
|
|
@@ -393,7 +394,7 @@ export function createZiguanjiaHost(ctx) {
|
|
|
393
394
|
body: payload,
|
|
394
395
|
bigIntStrings: true,
|
|
395
396
|
});
|
|
396
|
-
if (response
|
|
397
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
397
398
|
throw ziguanjiaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
398
399
|
}
|
|
399
400
|
if (response.parseError) {
|
|
@@ -3,6 +3,7 @@ import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js
|
|
|
3
3
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
4
4
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
5
5
|
import { createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
6
|
+
import { isE10SessionExpiredResponse } from '../../internal/e10/auth-recovery.js';
|
|
6
7
|
import { BlogCliError, blogAuthError, blogNetworkError, blogValidationError, } from './errors.js';
|
|
7
8
|
const MAX_EXPORT_BYTES = 50 * 1024 * 1024;
|
|
8
9
|
/** E10 登录失效在业务响应体里的 code(实测 -2 既可能是数字也可能是字符串) */
|
|
@@ -91,7 +92,7 @@ export function createBlogHost(ctx, dependencies = {}) {
|
|
|
91
92
|
body,
|
|
92
93
|
timeoutMs,
|
|
93
94
|
});
|
|
94
|
-
if (response
|
|
95
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
95
96
|
throw blogAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
96
97
|
}
|
|
97
98
|
if (response.parseError) {
|
|
@@ -134,7 +135,7 @@ export function createBlogHost(ctx, dependencies = {}) {
|
|
|
134
135
|
timeoutMs,
|
|
135
136
|
headers: { Accept: 'application/octet-stream, */*' },
|
|
136
137
|
});
|
|
137
|
-
if (response
|
|
138
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
138
139
|
throw blogAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
139
140
|
}
|
|
140
141
|
const contentType = response.contentType;
|