weaver-work-cli 0.1.28 → 0.1.31
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-U766FTFH.js +2537 -0
- package/dist/chunks/archive-oa-DMWEKX3L.js +1317 -0
- package/dist/chunks/asset-TCR7VDEV.js +2109 -0
- package/dist/chunks/attachment-content-AQNX5N3S.js +23 -0
- package/dist/chunks/blog-EVZWGDVM.js +2157 -0
- package/dist/chunks/caizhilian-JOWS6SL5.js +10087 -0
- package/dist/chunks/calendar-5WNCV66Q.js +1195 -0
- package/dist/chunks/chunk-2DUV44UX.js +15606 -0
- package/dist/chunks/chunk-324YPTC2.js +1607 -0
- package/dist/chunks/chunk-65QMVWHS.js +231 -0
- package/dist/chunks/chunk-6V7ZLF34.js +387 -0
- package/dist/chunks/chunk-AC7KJWC5.js +358 -0
- package/dist/chunks/chunk-AJ62BGAW.js +29 -0
- package/dist/chunks/chunk-BUSC6UAE.js +43 -0
- package/dist/chunks/chunk-CVZ2JOSW.js +62 -0
- package/dist/chunks/chunk-D4LTJSJD.js +477 -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-GCG2NMWR.js +703 -0
- package/dist/chunks/chunk-GPMFD4RD.js +75 -0
- package/dist/chunks/chunk-H3WDBYJW.js +508 -0
- package/dist/chunks/chunk-H6XSTSLM.js +2357 -0
- package/dist/chunks/chunk-J7RJTZSV.js +5556 -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-R2IJAK7T.js +464 -0
- package/dist/chunks/chunk-R7O5PUWO.js +205 -0
- package/dist/chunks/chunk-RCGYCOMG.js +6962 -0
- package/dist/chunks/chunk-VZTXRG6X.js +403 -0
- package/dist/chunks/chunk-WHD4XMRP.js +161 -0
- package/dist/chunks/chunk-YLCYX7LE.js +371 -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-NJ4YK6CC.js +2276 -0
- package/dist/chunks/ehr-MMYN36VA.js +5241 -0
- package/dist/chunks/employee-SAK2QYXX.js +11 -0
- package/dist/chunks/esb-HIWHOU7Q.js +141 -0
- package/dist/chunks/fna-KBACQTA5.js +1444 -0
- package/dist/chunks/host-3OHS5QUX.js +21 -0
- package/dist/chunks/host-IG6KEH5Q.js +19 -0
- package/dist/chunks/host-KQL5N4HO.js +23 -0
- package/dist/chunks/host-LLSZQCWR.js +17 -0
- package/dist/chunks/hrm-LYEC67ZQ.js +244 -0
- package/dist/chunks/im-RN2UKAEU.js +252 -0
- package/dist/chunks/invoice-EEPHLAF6.js +5179 -0
- package/dist/chunks/jiuchuanhui-WVVZYSJE.js +1940 -0
- package/dist/chunks/lazy-dispatch-MDOFFL2S.js +28 -0
- package/dist/chunks/mail-LNQLTF6L.js +2695 -0
- package/dist/chunks/meeting-XSD3BDVQ.js +504 -0
- package/dist/chunks/msg-parse-4GSQ2WTO.js +41 -0
- package/dist/chunks/okr-TMWTIU2K.js +2482 -0
- package/dist/chunks/plan-A2FSFA7T.js +2025 -0
- package/dist/chunks/project-T26QLBQF.js +1361 -0
- package/dist/chunks/registry-2VLUAESA.js +14 -0
- package/dist/chunks/registry-JCFEYXOE.js +18 -0
- package/dist/chunks/registry-NYPYMZXG.js +16 -0
- package/dist/chunks/registry-Q7OQJ3SU.js +19 -0
- package/dist/chunks/registry-ZJMJVWFA.js +19 -0
- package/dist/chunks/room-recommend-UR4ZDZS6.js +20 -0
- package/dist/chunks/schedule-5L2PM4M6.js +24 -0
- package/dist/chunks/state-Y2XBP6YE.js +15 -0
- package/dist/chunks/workflow-TR6PG2SL.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 +47 -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/host.js +2 -1
- package/dist/shortcuts/invoice/manifest.js +36 -12
- package/dist/shortcuts/invoice/operations/issuing-qys.js +132 -36
- 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/index.js +3 -0
- package/dist/shortcuts/workflow/operations/form.js +17 -5
- package/dist/shortcuts/workflow/operations/read.js +13 -6
- package/dist/shortcuts/workflow/operations/registry.js +2 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/businessRules.js +331 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.js +133 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +326 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +113 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +259 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoListRows.js +64 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoOutputPlanner.js +28 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.aggregate.js +70 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +267 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +392 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +165 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +448 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +348 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +222 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.pipeline.js +66 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +502 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +540 -0
- package/docs/_catalog.md +1 -0
- package/docs/contract.md +39 -4
- package/docs/invoice.md +7 -7
- package/docs/todo-smart-convert/README.md +171 -0
- package/docs/todo-smart-convert/data-contract.md +236 -0
- package/docs/todo-smart-convert/mock/ai-todo-query-target.json +209 -0
- package/docs/todo-smart-convert/subgroup-rules.md +245 -0
- package/package.json +3 -2
- package/scripts/bundle.mjs +63 -0
- package/scripts/package-skill.mjs +1 -1
- package/skill-template/business-info.json +25 -4
- package/skill-template/domains/jinchengda.md +16 -3
- package/skill-template/domains/yepiaotong.md +3 -3
- 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-workflow/SKILL.md +23 -1
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +282 -0
- package/skills/weaver-e10-workflow/scripts/todo-summary.cjs +695 -0
- package/skills/weaver-e10-yepiaotong/SKILL.md +15 -11
- package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +1 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +10 -7
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-form-fill-rules.md +41 -14
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-workflow.md +54 -26
- 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 +8 -2
- package/templates/meeting/invitation.docx +0 -0
|
@@ -0,0 +1,1195 @@
|
|
|
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-H3WDBYJW.js";
|
|
8
|
+
import {
|
|
9
|
+
E10_SESSION_EXPIRED_MESSAGE,
|
|
10
|
+
getActiveProfile
|
|
11
|
+
} from "./chunk-324YPTC2.js";
|
|
12
|
+
import {
|
|
13
|
+
CliError,
|
|
14
|
+
isCliError,
|
|
15
|
+
toErrorEnvelope
|
|
16
|
+
} from "./chunk-LUSPKZKY.js";
|
|
17
|
+
import "./chunk-BUSC6UAE.js";
|
|
18
|
+
|
|
19
|
+
// src/shortcuts/calendar/index.ts
|
|
20
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
21
|
+
|
|
22
|
+
// src/shortcuts/calendar/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/calendar/errors.ts
|
|
30
|
+
var CalendarCliError = 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 = "CalendarCliError";
|
|
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 calendarValidationError(subtype, message, details) {
|
|
51
|
+
return new CalendarCliError("validation", subtype, message, {
|
|
52
|
+
details,
|
|
53
|
+
exitCode: 2 /* UsageError */
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function calendarAuthError(subtype, message, details) {
|
|
57
|
+
return new CalendarCliError("authentication", subtype, message, {
|
|
58
|
+
details,
|
|
59
|
+
exitCode: 3 /* AuthError */
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function calendarNetworkError(subtype, message, options = {}) {
|
|
63
|
+
return new CalendarCliError("network", subtype, message, {
|
|
64
|
+
...options,
|
|
65
|
+
retryable: options.retryable ?? true,
|
|
66
|
+
exitCode: 4 /* NetworkError */
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function calendarConfirmationError(action, details) {
|
|
70
|
+
return new CalendarCliError("confirmation", "required", "\u8BE5\u64CD\u4F5C\u9700\u8981\u660E\u786E\u786E\u8BA4", {
|
|
71
|
+
details: { action, ...details },
|
|
72
|
+
exitCode: 10 /* ConfirmationRequired */
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function calendarPartialError(message, partialData, details) {
|
|
76
|
+
return new CalendarCliError("partial", "write_uncertain", message, {
|
|
77
|
+
details,
|
|
78
|
+
partialData,
|
|
79
|
+
exitCode: 11 /* Partial */
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/shortcuts/calendar/continuation.ts
|
|
84
|
+
function stateRoot(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(stateRoot(ctx), "keys");
|
|
91
|
+
const filename = resolve(keysDir, "calendar-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 createCalendarContinuationSigner(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 calendarValidationError("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 calendarValidationError("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 calendarValidationError("continuation_invalid", "continuation \u5185\u5BB9\u65E0\u6CD5\u89E3\u6790");
|
|
130
|
+
}
|
|
131
|
+
if (value.operation !== expectedOperation) {
|
|
132
|
+
throw calendarValidationError("continuation_mismatch", "continuation \u4E0D\u5C5E\u4E8E\u5F53\u524D\u64CD\u4F5C");
|
|
133
|
+
}
|
|
134
|
+
if (!Number.isSafeInteger(value.expiresAt) || value.expiresAt < Date.now()) {
|
|
135
|
+
throw calendarValidationError("continuation_expired", "continuation \u5DF2\u8FC7\u671F");
|
|
136
|
+
}
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/shortcuts/calendar/host.ts
|
|
143
|
+
function inferProfile(ctx) {
|
|
144
|
+
const options = ctx.getGlobalOptions();
|
|
145
|
+
return options.profile || getActiveProfile();
|
|
146
|
+
}
|
|
147
|
+
function isBusinessSuccess(value) {
|
|
148
|
+
if (!value || typeof value !== "object") return false;
|
|
149
|
+
const datajson = value.datajson;
|
|
150
|
+
if (datajson && typeof datajson === "object") {
|
|
151
|
+
return datajson.status === true;
|
|
152
|
+
}
|
|
153
|
+
if (value.resultCode !== void 0 && value.resultCode !== null) {
|
|
154
|
+
return Number(value.resultCode) === 200;
|
|
155
|
+
}
|
|
156
|
+
if ("data" in value) return true;
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
function businessMessage(value) {
|
|
160
|
+
if (!value || typeof value !== "object") return "\u6CDB\u5FAE\u63A5\u53E3\u8FD4\u56DE\u4E1A\u52A1\u5931\u8D25";
|
|
161
|
+
const candidates = [value.resultMsg, value.msg, value.message, value.datajson?.message];
|
|
162
|
+
for (const item of candidates) {
|
|
163
|
+
if (typeof item === "string" && item.trim()) return item;
|
|
164
|
+
}
|
|
165
|
+
return "\u6CDB\u5FAE\u63A5\u53E3\u8FD4\u56DE\u4E1A\u52A1\u5931\u8D25";
|
|
166
|
+
}
|
|
167
|
+
function assertPath(requestPath) {
|
|
168
|
+
if (typeof requestPath !== "string" || !requestPath.startsWith("/") || requestPath.startsWith("//")) {
|
|
169
|
+
throw calendarValidationError("path_invalid", "\u8BF7\u6C42\u8DEF\u5F84\u5FC5\u987B\u662F\u76F8\u5BF9\u7EDD\u5BF9\u8DEF\u5F84");
|
|
170
|
+
}
|
|
171
|
+
if (/^https?:/i.test(requestPath) || /[\r\n]/.test(requestPath) || requestPath.includes("/../")) {
|
|
172
|
+
throw calendarValidationError("path_invalid", "\u8BF7\u6C42\u8DEF\u5F84\u4E0D\u5141\u8BB8\u8DE8\u57DF\u6216\u8DEF\u5F84\u9003\u9038");
|
|
173
|
+
}
|
|
174
|
+
if (!requestPath.startsWith("/api/")) {
|
|
175
|
+
throw calendarValidationError("path_not_allowed", "\u65E5\u7A0B\u6A21\u5757\u53EA\u80FD\u8C03\u7528 /api/ \u8DEF\u5F84");
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function omitEmptyQueryValues(query) {
|
|
179
|
+
if (!query) return void 0;
|
|
180
|
+
return Object.fromEntries(Object.entries(query).filter(([, value]) => value !== "" && value !== void 0 && value !== null));
|
|
181
|
+
}
|
|
182
|
+
function mapRuntimeNetworkError(error) {
|
|
183
|
+
if (error instanceof E10ApiError && error.type === "network") {
|
|
184
|
+
throw calendarNetworkError(error.subtype, error.message, {
|
|
185
|
+
retryable: error.retryable,
|
|
186
|
+
details: error.details
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
function createCalendarHost(ctx, dependencies = {}) {
|
|
192
|
+
let e10Session = null;
|
|
193
|
+
let sessionContext = null;
|
|
194
|
+
const requireSession = dependencies.requireSession || requireE10Session;
|
|
195
|
+
async function ensureSession() {
|
|
196
|
+
if (!e10Session) {
|
|
197
|
+
e10Session = await requireSession(ctx);
|
|
198
|
+
sessionContext = {
|
|
199
|
+
baseUrl: e10Session.getBaseUrl(),
|
|
200
|
+
profile: inferProfile(ctx),
|
|
201
|
+
userId: e10Session.userId,
|
|
202
|
+
tenantKey: e10Session.tenantKey,
|
|
203
|
+
eteamsId: e10Session.eteamsId
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
return e10Session;
|
|
207
|
+
}
|
|
208
|
+
async function getSession() {
|
|
209
|
+
await ensureSession();
|
|
210
|
+
return sessionContext;
|
|
211
|
+
}
|
|
212
|
+
async function runtime() {
|
|
213
|
+
return createE10RequestRuntime(ctx, await ensureSession(), {
|
|
214
|
+
interceptors: dependencies.interceptors,
|
|
215
|
+
fetch: dependencies.fetch
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
async function request(request2) {
|
|
219
|
+
const { method, path, query, body, operation, timeoutMs = 3e4 } = request2;
|
|
220
|
+
assertPath(path);
|
|
221
|
+
const resolvedMethod = method || "POST";
|
|
222
|
+
let response;
|
|
223
|
+
try {
|
|
224
|
+
response = await (await runtime()).requestJson({
|
|
225
|
+
module: "calendar",
|
|
226
|
+
operation,
|
|
227
|
+
method: resolvedMethod,
|
|
228
|
+
path,
|
|
229
|
+
query: omitEmptyQueryValues(query),
|
|
230
|
+
body,
|
|
231
|
+
headers: { "X-Requested-With": "XMLHttpRequest" },
|
|
232
|
+
timeoutMs
|
|
233
|
+
});
|
|
234
|
+
} catch (error) {
|
|
235
|
+
mapRuntimeNetworkError(error);
|
|
236
|
+
}
|
|
237
|
+
if (response.status === 401 || response.status === 302) {
|
|
238
|
+
throw calendarAuthError("session_expired", E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
239
|
+
}
|
|
240
|
+
if (response.parseError) {
|
|
241
|
+
if (response.status < 200 || response.status >= 300) {
|
|
242
|
+
throw new CalendarCliError("api", "http_error", `\u6CDB\u5FAE\u63A5\u53E3 HTTP ${response.status}`, {
|
|
243
|
+
code: response.status,
|
|
244
|
+
details: { status: response.status },
|
|
245
|
+
exitCode: 1
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
throw calendarNetworkError("protocol", `\u63A5\u53E3\u8FD4\u56DE\u4E0D\u662F\u5408\u6CD5 JSON\uFF08HTTP ${response.status}\uFF09`, { retryable: false });
|
|
249
|
+
}
|
|
250
|
+
if (response.status < 200 || response.status >= 300) {
|
|
251
|
+
throw new CalendarCliError("api", "http_error", `\u6CDB\u5FAE\u63A5\u53E3 HTTP ${response.status}`, {
|
|
252
|
+
code: response.status,
|
|
253
|
+
details: { status: response.status, message: businessMessage(response.value) },
|
|
254
|
+
exitCode: 1
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
if (response.status === 404) {
|
|
258
|
+
throw new CalendarCliError("api", "app_not_installed", "\u63A5\u53E3\u8FD4\u56DE 404\uFF0C\u5F53\u524D\u73AF\u5883\u53EF\u80FD\u672A\u5B89\u88C5\u300C\u65E5\u7A0B\u300D\u5E94\u7528\uFF0C\u8BF7\u5148\u5B89\u88C5/\u90E8\u7F72\u5E94\u7528\u540E\u518D\u8BD5", {
|
|
259
|
+
code: response.status,
|
|
260
|
+
exitCode: 1
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
if (!isBusinessSuccess(response.value)) {
|
|
264
|
+
throw new CalendarCliError("api", "business_error", businessMessage(response.value), {
|
|
265
|
+
details: { message: businessMessage(response.value) },
|
|
266
|
+
exitCode: 1
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return response.value;
|
|
270
|
+
}
|
|
271
|
+
return { request, getSession };
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// src/shortcuts/calendar/operations/types.ts
|
|
275
|
+
function calendarSuccess(action, data, meta) {
|
|
276
|
+
const payload = { ok: true, action, data };
|
|
277
|
+
if (meta && Object.keys(meta).length > 0) payload.meta = meta;
|
|
278
|
+
return payload;
|
|
279
|
+
}
|
|
280
|
+
function schemaOf(properties, options = {}) {
|
|
281
|
+
return {
|
|
282
|
+
type: "object",
|
|
283
|
+
additionalProperties: false,
|
|
284
|
+
properties,
|
|
285
|
+
...options.required?.length ? { required: options.required } : {},
|
|
286
|
+
...options.description ? { description: options.description } : {}
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
var SCHEMA_ID = { oneOf: [{ type: "integer" }, { type: "string", pattern: "^\\d+$" }] };
|
|
290
|
+
var SCHEMA_DATETIME_MINUTE = { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$" };
|
|
291
|
+
var SCHEMA_DATE = { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2}$" };
|
|
292
|
+
var SCHEMA_SWITCH = { type: "integer", enum: [0, 1] };
|
|
293
|
+
|
|
294
|
+
// src/shortcuts/calendar/operations/read.ts
|
|
295
|
+
var LIST_UNIQUE_INDENT = "E49255BD213B480CB13DFB8E1B4159ED";
|
|
296
|
+
var AGENDA_APP_TAG = "weaver-calendar-eb";
|
|
297
|
+
var AGENDA_FORM_TAG = "uf_agn_agenda";
|
|
298
|
+
var MIN_APP_VERSION = "4.1.4";
|
|
299
|
+
async function buildDatajson(host, mainTable, extra = {}) {
|
|
300
|
+
const session = await host.getSession();
|
|
301
|
+
const datajson = {
|
|
302
|
+
mainTable,
|
|
303
|
+
header: { operator: session.userId },
|
|
304
|
+
...extra
|
|
305
|
+
};
|
|
306
|
+
return { datajson };
|
|
307
|
+
}
|
|
308
|
+
function pageInfo(args) {
|
|
309
|
+
const pageNo = args.pageNo !== void 0 ? String(args.pageNo) : void 0;
|
|
310
|
+
const pageSize = args.pageSize !== void 0 ? String(args.pageSize) : void 0;
|
|
311
|
+
if (pageNo === void 0 && pageSize === void 0) return void 0;
|
|
312
|
+
return {
|
|
313
|
+
pageNo: pageNo ?? "1",
|
|
314
|
+
pageSize: pageSize ?? "10"
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
var calendarList = {
|
|
318
|
+
name: "calendar.list",
|
|
319
|
+
resource: "calendar",
|
|
320
|
+
method: "list",
|
|
321
|
+
action: "calendar.list",
|
|
322
|
+
summary: "\u5206\u9875\u67E5\u8BE2\u65E5\u7A0B\u5217\u8868\uFF0C\u652F\u6301\u6309\u65F6\u95F4\u8303\u56F4\u548C\u5173\u952E\u5B57\u7B5B\u9009\uFF1B\u4E5F\u7528\u4E8E\u66F4\u65B0/\u5220\u9664\u524D\u6309\u540D\u79F0\u83B7\u53D6\u65E5\u7A0B ID",
|
|
323
|
+
capability: "calendar",
|
|
324
|
+
risk: "read",
|
|
325
|
+
inputSchema: schemaOf({
|
|
326
|
+
start_time: { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$", description: "\u5F00\u59CB\u65F6\u95F4\u7B5B\u9009\uFF08yyyy-MM-dd HH:mm\uFF09" },
|
|
327
|
+
end_time: { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$", description: "\u7ED3\u675F\u65F6\u95F4\u7B5B\u9009\uFF08yyyy-MM-dd HH:mm\uFF09" },
|
|
328
|
+
keywork: { type: "string", description: "\u5173\u952E\u5B57\u68C0\u7D22\uFF08\u6309\u65E5\u7A0B\u540D\u79F0\u6A21\u7CCA\u5339\u914D\uFF0C\u5B57\u6BB5\u540D\u62FC\u5199\u4E3A keywork\uFF09" },
|
|
329
|
+
page_no: { type: "integer", minimum: 1, default: 1, description: "\u9875\u7801" },
|
|
330
|
+
page_size: { type: "integer", minimum: 1, maximum: 100, default: 10, description: "\u6BCF\u9875\u6761\u6570" }
|
|
331
|
+
}),
|
|
332
|
+
handler: async (args, { host }) => {
|
|
333
|
+
const mainTable = {};
|
|
334
|
+
if (args.start_time !== void 0) mainTable.start_time = args.start_time;
|
|
335
|
+
if (args.end_time !== void 0) mainTable.end_time = args.end_time;
|
|
336
|
+
if (args.keywork !== void 0) mainTable.keywork = args.keywork;
|
|
337
|
+
if (args.page_no !== void 0) mainTable.page_no = args.page_no;
|
|
338
|
+
if (args.page_size !== void 0) mainTable.page_size = args.page_size;
|
|
339
|
+
const response = await host.request({
|
|
340
|
+
method: "POST",
|
|
341
|
+
path: "/api/esb/server/event/triggerActionFlow",
|
|
342
|
+
operation: "calendar.list",
|
|
343
|
+
body: {
|
|
344
|
+
customParams: { mainTable },
|
|
345
|
+
moduleSource: "",
|
|
346
|
+
uniqueIndent: LIST_UNIQUE_INDENT
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
return calendarSuccess("calendar.list", response);
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
var calendarGet = {
|
|
353
|
+
name: "calendar.get",
|
|
354
|
+
resource: "calendar",
|
|
355
|
+
method: "get",
|
|
356
|
+
action: "calendar.get",
|
|
357
|
+
summary: "\u6309\u65E5\u7A0B\u6570\u636E ID \u67E5\u8BE2\u5355\u6761\u65E5\u7A0B\u5B8C\u6574\u4FE1\u606F\uFF1B\u4E5F\u4F5C\u4E3A\u66F4\u65B0\u3001\u5220\u9664\u524D\u7684\u8F85\u52A9\u67E5\u8BE2",
|
|
358
|
+
capability: "calendar",
|
|
359
|
+
risk: "read",
|
|
360
|
+
inputSchema: schemaOf({ id: SCHEMA_ID }, { required: ["id"] }),
|
|
361
|
+
handler: async (args, { host }) => {
|
|
362
|
+
const id = String(args.id);
|
|
363
|
+
const body = await buildDatajson(host, { id });
|
|
364
|
+
const response = await host.request({
|
|
365
|
+
method: "POST",
|
|
366
|
+
path: "/api/ebuilder/form/formdata/v2/getFormDataByPk/queryAgenda",
|
|
367
|
+
operation: "calendar.get",
|
|
368
|
+
body
|
|
369
|
+
});
|
|
370
|
+
return calendarSuccess("calendar.get", response);
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
var calendarCount = {
|
|
374
|
+
name: "calendar.count",
|
|
375
|
+
resource: "calendar",
|
|
376
|
+
method: "count",
|
|
377
|
+
action: "calendar.count",
|
|
378
|
+
summary: "\u67E5\u8BE2\u65E5\u7A0B\u6570\u636E\u603B\u6570\u91CF",
|
|
379
|
+
capability: "calendar",
|
|
380
|
+
risk: "read",
|
|
381
|
+
inputSchema: schemaOf({}),
|
|
382
|
+
handler: async (_args, { host }) => {
|
|
383
|
+
const body = await buildDatajson(host, {});
|
|
384
|
+
const response = await host.request({
|
|
385
|
+
method: "POST",
|
|
386
|
+
path: "/api/ebuilder/form/formdata/v2/getFormDataCount/queryAgendaCount",
|
|
387
|
+
operation: "calendar.count",
|
|
388
|
+
body
|
|
389
|
+
});
|
|
390
|
+
return calendarSuccess("calendar.count", response);
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
function dictOperation(name, method, summary, path, filterField) {
|
|
394
|
+
return {
|
|
395
|
+
name,
|
|
396
|
+
resource: "calendar",
|
|
397
|
+
method,
|
|
398
|
+
action: name,
|
|
399
|
+
summary,
|
|
400
|
+
capability: "calendar",
|
|
401
|
+
risk: "read",
|
|
402
|
+
inputSchema: schemaOf({
|
|
403
|
+
...filterField ? { [filterField]: { type: "string", description: "\u6309\u540D\u79F0\u7B5B\u9009\uFF1B\u4E0D\u4F20\u5219\u67E5\u8BE2\u5168\u90E8\uFF08\u6CE8\u610F\u4E0D\u53EF\u4F20\u7A7A\u5B57\u7B26\u4E32\uFF09" } } : {},
|
|
404
|
+
pageNo: { type: "integer", minimum: 1, default: 1 },
|
|
405
|
+
pageSize: { type: "integer", minimum: 1, maximum: 100, default: 10 }
|
|
406
|
+
}),
|
|
407
|
+
handler: async (args, { host }) => {
|
|
408
|
+
const mainTable = {};
|
|
409
|
+
if (filterField && args[filterField] !== void 0) {
|
|
410
|
+
mainTable[filterField] = args[filterField];
|
|
411
|
+
}
|
|
412
|
+
const page = pageInfo(args);
|
|
413
|
+
const body = await buildDatajson(host, mainTable, page ? { pageInfo: page } : {});
|
|
414
|
+
const response = await host.request({
|
|
415
|
+
method: "POST",
|
|
416
|
+
path,
|
|
417
|
+
operation: name,
|
|
418
|
+
body
|
|
419
|
+
});
|
|
420
|
+
return calendarSuccess(name, response);
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
var calendarPriorityList = dictOperation(
|
|
425
|
+
"calendar.priority.list",
|
|
426
|
+
"priority.list",
|
|
427
|
+
"\u67E5\u8BE2\u65E5\u7A0B\u7D27\u6025\u7A0B\u5EA6\u9009\u9879\u5217\u8868\uFF08priority \u5B57\u6BB5\u53EF\u9009\u503C\uFF09",
|
|
428
|
+
"/api/ebuilder/form/formdata/v2/getFormDataList/queryAgendaPriority",
|
|
429
|
+
"priority_name"
|
|
430
|
+
);
|
|
431
|
+
var calendarTypeList = dictOperation(
|
|
432
|
+
"calendar.type.list",
|
|
433
|
+
"type.list",
|
|
434
|
+
"\u67E5\u8BE2\u65E5\u7A0B\u7C7B\u578B\u9009\u9879\u5217\u8868\uFF08agn_type \u5B57\u6BB5\u53EF\u9009\u503C\uFF09",
|
|
435
|
+
"/api/ebuilder/form/formdata/v2/getFormDataList/queryAgendaType",
|
|
436
|
+
"type_name"
|
|
437
|
+
);
|
|
438
|
+
function compareVersion(a, b) {
|
|
439
|
+
const pa = a.split(".").map((part) => Number(part) || 0);
|
|
440
|
+
const pb = b.split(".").map((part) => Number(part) || 0);
|
|
441
|
+
const length = Math.max(pa.length, pb.length);
|
|
442
|
+
for (let i = 0; i < length; i++) {
|
|
443
|
+
const x = pa[i] ?? 0;
|
|
444
|
+
const y = pb[i] ?? 0;
|
|
445
|
+
if (x !== y) return x > y ? 1 : -1;
|
|
446
|
+
}
|
|
447
|
+
return 0;
|
|
448
|
+
}
|
|
449
|
+
function firstId(value) {
|
|
450
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
451
|
+
const first = value[0];
|
|
452
|
+
if (typeof first === "string" || typeof first === "number") return String(first);
|
|
453
|
+
if (first && typeof first === "object") {
|
|
454
|
+
const record = first;
|
|
455
|
+
const id = record.id ?? record.appId ?? record.app_id;
|
|
456
|
+
if (id !== void 0 && id !== null && id !== "") return String(id);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
460
|
+
return void 0;
|
|
461
|
+
}
|
|
462
|
+
var calendarAppCheck = {
|
|
463
|
+
name: "calendar.app.check",
|
|
464
|
+
resource: "calendar",
|
|
465
|
+
method: "app.check",
|
|
466
|
+
action: "calendar.app.check",
|
|
467
|
+
summary: "\u68C0\u6D4B\u300C\u65E5\u7A0B\u300D\u5E94\u7528\u662F\u5426\u5B89\u88C5\u53CA\u7248\u672C\uFF08\u8981\u6C42 >= 4.1.4\uFF09\uFF0C\u5E76\u8FD4\u56DE\u65E5\u7A0B\u8868\u5355 ID\uFF08\u7528\u4E8E\u8BE6\u60C5\u5361\u7247\u9875\u94FE\u63A5\uFF09",
|
|
468
|
+
capability: "calendar",
|
|
469
|
+
risk: "read",
|
|
470
|
+
inputSchema: schemaOf({}),
|
|
471
|
+
handler: async (_args, { host }) => {
|
|
472
|
+
const appIdsResponse = await host.request({
|
|
473
|
+
method: "GET",
|
|
474
|
+
path: "/api/bs/ebuilder/app/tags/getAppIds",
|
|
475
|
+
operation: "calendar.app.check",
|
|
476
|
+
query: { tag: AGENDA_APP_TAG }
|
|
477
|
+
}).catch(() => void 0);
|
|
478
|
+
const appId = firstId(appIdsResponse?.data);
|
|
479
|
+
if (!appId) {
|
|
480
|
+
return calendarSuccess("calendar.app.check", {
|
|
481
|
+
installed: false,
|
|
482
|
+
reason: "app_not_found",
|
|
483
|
+
message: "\u672A\u68C0\u6D4B\u5230\u300C\u65E5\u7A0B\u300D\u5E94\u7528\uFF08getAppIds \u672A\u8FD4\u56DE appId\uFF09\uFF0C\u8BF7\u5148\u5B89\u88C5\u5E94\u7528"
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
const versionResponse = await host.request({
|
|
487
|
+
method: "GET",
|
|
488
|
+
path: "/api/installer/public/querySpAppVersionInfo",
|
|
489
|
+
operation: "calendar.app.check",
|
|
490
|
+
query: { appId }
|
|
491
|
+
}).catch(() => void 0);
|
|
492
|
+
const commitVersion = versionResponse?.data?.commitVersion ?? versionResponse?.commitVersion;
|
|
493
|
+
let formId;
|
|
494
|
+
for (let attempt = 0; attempt < 3 && !formId; attempt++) {
|
|
495
|
+
const formResponse = await host.request({
|
|
496
|
+
method: "GET",
|
|
497
|
+
path: "/api/ebuilder/form/obj/getObjsByTag",
|
|
498
|
+
operation: "calendar.app.check",
|
|
499
|
+
query: { tag: AGENDA_FORM_TAG, appId }
|
|
500
|
+
}).catch(() => void 0);
|
|
501
|
+
formId = firstId(formResponse?.data);
|
|
502
|
+
if (!formId && attempt < 2) {
|
|
503
|
+
await new Promise((resolve2) => setTimeout(resolve2, 800));
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
const hasVersion = typeof commitVersion === "string" && commitVersion.trim() !== "";
|
|
507
|
+
const installed = hasVersion && commitVersion !== null && commitVersion !== void 0;
|
|
508
|
+
const versionOk = installed && compareVersion(commitVersion, MIN_APP_VERSION) >= 0;
|
|
509
|
+
return calendarSuccess("calendar.app.check", {
|
|
510
|
+
installed,
|
|
511
|
+
appId,
|
|
512
|
+
commitVersion: installed ? commitVersion : null,
|
|
513
|
+
versionOk,
|
|
514
|
+
minRequiredVersion: MIN_APP_VERSION,
|
|
515
|
+
formId: formId ?? null,
|
|
516
|
+
status: !installed ? "NOT_INSTALLED" : versionOk ? "OK" : "VERSION_TOO_LOW"
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
var calendarReadOperations = [
|
|
521
|
+
calendarList,
|
|
522
|
+
calendarGet,
|
|
523
|
+
calendarCount,
|
|
524
|
+
calendarPriorityList,
|
|
525
|
+
calendarTypeList,
|
|
526
|
+
calendarAppCheck
|
|
527
|
+
];
|
|
528
|
+
|
|
529
|
+
// src/shortcuts/calendar/operations/write.ts
|
|
530
|
+
import { createHash } from "node:crypto";
|
|
531
|
+
|
|
532
|
+
// src/shortcuts/calendar/operations/shared.ts
|
|
533
|
+
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
534
|
+
function asObject(value) {
|
|
535
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
536
|
+
throw calendarValidationError("input_not_object", "\u8F93\u5165\u5FC5\u987B\u662F JSON \u5BF9\u8C61");
|
|
537
|
+
}
|
|
538
|
+
return value;
|
|
539
|
+
}
|
|
540
|
+
function assertNoForbiddenKeys(input) {
|
|
541
|
+
for (const key of Object.keys(input)) {
|
|
542
|
+
if (FORBIDDEN_KEYS.has(key)) {
|
|
543
|
+
throw calendarValidationError("forbidden_key", `\u8F93\u5165\u5305\u542B\u975E\u6CD5\u5B57\u6BB5\uFF1A${key}`);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
function assertDateTimeMinute(value, field) {
|
|
548
|
+
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(value)) {
|
|
549
|
+
throw calendarValidationError("datetime_invalid", `${field} \u5FC5\u987B\u662F yyyy-MM-dd HH:mm \u683C\u5F0F`);
|
|
550
|
+
}
|
|
551
|
+
return value;
|
|
552
|
+
}
|
|
553
|
+
function pickDefined(value, keys) {
|
|
554
|
+
const result = {};
|
|
555
|
+
for (const key of keys) {
|
|
556
|
+
if (value[key] !== void 0) result[key] = value[key];
|
|
557
|
+
}
|
|
558
|
+
return result;
|
|
559
|
+
}
|
|
560
|
+
function optionId(value) {
|
|
561
|
+
if (Array.isArray(value) && value.length > 0 && typeof value[0] === "object" && value[0] !== null) {
|
|
562
|
+
const id = value[0].id;
|
|
563
|
+
if (id !== void 0 && id !== null && id !== "") return String(id);
|
|
564
|
+
return void 0;
|
|
565
|
+
}
|
|
566
|
+
if (typeof value === "string" && value) return value;
|
|
567
|
+
if (typeof value === "number") return String(value);
|
|
568
|
+
return void 0;
|
|
569
|
+
}
|
|
570
|
+
function participantIds(value) {
|
|
571
|
+
if (typeof value === "string" && value) return value;
|
|
572
|
+
if (Array.isArray(value)) return value.map((item) => String(item)).join(",");
|
|
573
|
+
return void 0;
|
|
574
|
+
}
|
|
575
|
+
function defaultEndTime(startTime) {
|
|
576
|
+
const match = /^(\d{4}-\d{2}-\d{2}) (\d{2}):(\d{2})$/.exec(startTime);
|
|
577
|
+
if (!match) return startTime;
|
|
578
|
+
const [, date, hour, minute] = match;
|
|
579
|
+
let nextHour = Number(hour) + 1;
|
|
580
|
+
let nextDay = date;
|
|
581
|
+
if (nextHour >= 24) {
|
|
582
|
+
nextHour -= 24;
|
|
583
|
+
const [y, m, d] = date.split("-").map(Number);
|
|
584
|
+
const tomorrow = new Date(Date.UTC(y, m - 1, d + 1));
|
|
585
|
+
nextDay = `${tomorrow.getUTCFullYear()}-${String(tomorrow.getUTCMonth() + 1).padStart(2, "0")}-${String(tomorrow.getUTCDate()).padStart(2, "0")}`;
|
|
586
|
+
}
|
|
587
|
+
return `${nextDay} ${String(nextHour).padStart(2, "0")}:${minute}`;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// src/shortcuts/calendar/operations/write.ts
|
|
591
|
+
var CONTINUATION_TTL_SECONDS = 600;
|
|
592
|
+
var OPTIONAL_FIELDS = [
|
|
593
|
+
"next_start_remind",
|
|
594
|
+
"next_end_remind",
|
|
595
|
+
"all_day",
|
|
596
|
+
"agn_desc",
|
|
597
|
+
"location",
|
|
598
|
+
"place",
|
|
599
|
+
"part_receipt",
|
|
600
|
+
"remind",
|
|
601
|
+
"start_reminder",
|
|
602
|
+
"remind_type",
|
|
603
|
+
"start_hours",
|
|
604
|
+
"start_mins",
|
|
605
|
+
"end_reminder",
|
|
606
|
+
"end_hours",
|
|
607
|
+
"end_mins",
|
|
608
|
+
"repeat_type",
|
|
609
|
+
"repeat_custom_type",
|
|
610
|
+
"repeat_custom_cycle",
|
|
611
|
+
"repeat_week_unit",
|
|
612
|
+
"repeat_month_unit",
|
|
613
|
+
"repeat_end_date",
|
|
614
|
+
"repeat_end_type",
|
|
615
|
+
"repeat_end_num",
|
|
616
|
+
"repeat_desc"
|
|
617
|
+
];
|
|
618
|
+
var MAIN_TABLE_SCHEMA = {
|
|
619
|
+
agn_name: { type: "string", minLength: 1, description: "\u65E5\u7A0B\u540D\u79F0" },
|
|
620
|
+
start_time: SCHEMA_DATETIME_MINUTE,
|
|
621
|
+
end_time: SCHEMA_DATETIME_MINUTE,
|
|
622
|
+
participants: { type: "string", description: "\u53C2\u4E0E\u4EBA\u4EBA\u5458 ID\uFF08\u591A\u4E2A\u9017\u53F7\u5206\u9694\uFF09\uFF1B\u7F3A\u7701\u65F6\u81EA\u52A8\u5E26\u5F53\u524D\u64CD\u4F5C\u4EBA" },
|
|
623
|
+
agn_type: { type: "string", description: "\u65E5\u7A0B\u7C7B\u578B\u9009\u9879 ID\uFF08\u5148\u901A\u8FC7 calendar.type.list \u83B7\u53D6\uFF09" },
|
|
624
|
+
priority: { type: "string", description: "\u7D27\u6025\u7A0B\u5EA6\u9009\u9879 ID\uFF08\u5148\u901A\u8FC7 calendar.priority.list \u83B7\u53D6\uFF09" },
|
|
625
|
+
next_start_remind: { type: "string", description: "\u4E0B\u6B21\u63D0\u9192\u65F6\u95F4\uFF08\u5F00\u59CB\u524D\uFF09yyyy-MM-dd HH:mm:ss" },
|
|
626
|
+
next_end_remind: { type: "string", description: "\u4E0B\u6B21\u63D0\u9192\u65F6\u95F4\uFF08\u7ED3\u675F\u524D\uFF09yyyy-MM-dd HH:mm:ss" },
|
|
627
|
+
all_day: SCHEMA_SWITCH,
|
|
628
|
+
agn_desc: { type: "string", description: "\u65E5\u7A0B\u8BE6\u60C5" },
|
|
629
|
+
location: { type: "string", description: "\u4F4D\u7F6E" },
|
|
630
|
+
place: { type: "string", description: "\u5730\u70B9" },
|
|
631
|
+
part_receipt: SCHEMA_SWITCH,
|
|
632
|
+
remind: SCHEMA_SWITCH,
|
|
633
|
+
start_reminder: { type: "string", enum: ["NOW", "M5", "M15", "H1", "D1", "CUSTOM"], description: "\u5F00\u59CB\u524D\u63D0\u9192" },
|
|
634
|
+
remind_type: { type: "string", enum: ["system", "message", "email"], description: "\u63D0\u9192\u65B9\u5F0F" },
|
|
635
|
+
start_hours: { type: "integer", description: "\u63D0\u524D\u5C0F\u65F6\uFF08start_reminder=CUSTOM \u65F6\uFF09" },
|
|
636
|
+
start_mins: { type: "integer", description: "\u63D0\u524D\u5206\u949F\uFF08start_reminder=CUSTOM \u65F6\uFF09" },
|
|
637
|
+
end_reminder: { type: "string", enum: ["NOW", "M5", "M15", "H1", "D1", "CUSTOM"], description: "\u7ED3\u675F\u524D\u63D0\u9192" },
|
|
638
|
+
end_hours: { type: "integer", description: "\u7ED3\u675F\u5C0F\u65F6\uFF08end_reminder=CUSTOM \u65F6\uFF09" },
|
|
639
|
+
end_mins: { type: "integer", description: "\u7ED3\u675F\u5206\u949F\uFF08end_reminder=CUSTOM \u65F6\uFF09" },
|
|
640
|
+
repeat_type: { type: "string", enum: ["NONE", "D1", "W1", "W2", "M1", "CUSTOM"], description: "\u91CD\u590D\u7C7B\u578B" },
|
|
641
|
+
repeat_custom_type: { type: "string", enum: ["D", "W", "M"], description: "\u91CD\u590D\u9891\u7387\uFF08repeat_type=CUSTOM \u65F6\uFF09" },
|
|
642
|
+
repeat_custom_cycle: { type: "integer", description: "\u91CD\u590D\u95F4\u9694" },
|
|
643
|
+
repeat_week_unit: { type: "string", enum: ["MO", "TU", "WE", "TH", "FR", "SA", "SU"], description: "\u6BCF\u5468\u7684" },
|
|
644
|
+
repeat_month_unit: { type: "string", description: "\u6BCF\u6708\u7684\uFF081~31\uFF09" },
|
|
645
|
+
repeat_end_date: SCHEMA_DATE,
|
|
646
|
+
repeat_end_type: { type: "string", enum: ["0", "1", "2"], description: "\u7ED3\u675F\u7C7B\u578B\uFF1A0 \u6307\u5B9A\u65F6\u95F4 / 1 \u6307\u5B9A\u6B21\u6570 / 2 \u6C38\u4E0D\u7ED3\u675F" },
|
|
647
|
+
repeat_end_num: { type: "integer", description: "\u6B21\u6570\uFF08repeat_end_type=1 \u65F6\uFF09" },
|
|
648
|
+
repeat_desc: { type: "string", description: "\u91CD\u590D\u89C4\u5219\u63CF\u8FF0" }
|
|
649
|
+
};
|
|
650
|
+
function fingerprint(value) {
|
|
651
|
+
return createHash("sha256").update(JSON.stringify(value ?? null)).digest("hex").slice(0, 32);
|
|
652
|
+
}
|
|
653
|
+
function requireConfirm(args, action) {
|
|
654
|
+
if (args.confirm !== true) {
|
|
655
|
+
throw calendarConfirmationError(action, { hint: "\u91CD\u65B0\u8C03\u7528\u65F6\u4F20\u5165 confirm=true \u4E0E prepare \u8FD4\u56DE\u7684 continuation" });
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
async function verifyLease(args, action, env) {
|
|
659
|
+
const lease = await env.continuation.verify(args.continuation, action);
|
|
660
|
+
const session = await env.host.getSession();
|
|
661
|
+
if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
|
|
662
|
+
throw calendarValidationError("context_mismatch", "\u786E\u8BA4\u4E0A\u4E0B\u6587\u5DF2\u53D8\u5316\uFF08\u79DF\u6237\u6216\u767B\u5F55\u8D26\u53F7\u4E0D\u540C\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
663
|
+
}
|
|
664
|
+
return lease;
|
|
665
|
+
}
|
|
666
|
+
function isNetworkError(error) {
|
|
667
|
+
return error instanceof CalendarCliError && error.type === "network";
|
|
668
|
+
}
|
|
669
|
+
async function buildWriteDatajson(host, mainTableList) {
|
|
670
|
+
const session = await host.getSession();
|
|
671
|
+
return {
|
|
672
|
+
datajson: {
|
|
673
|
+
operationinfo: { printCost: false },
|
|
674
|
+
datas: mainTableList.map((mainTable) => ({ mainTable })),
|
|
675
|
+
header: { operator: session.userId }
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
async function normalizeMainTable(args, host) {
|
|
680
|
+
const session = await host.getSession();
|
|
681
|
+
const agnName = args.agn_name;
|
|
682
|
+
if (typeof agnName !== "string" || !agnName.trim()) {
|
|
683
|
+
throw calendarValidationError("agn_name_required", "agn_name\uFF08\u65E5\u7A0B\u540D\u79F0\uFF09\u5FC5\u586B");
|
|
684
|
+
}
|
|
685
|
+
const startTime = assertDateTimeMinute(args.start_time, "start_time");
|
|
686
|
+
const endTime = args.end_time !== void 0 ? assertDateTimeMinute(args.end_time, "end_time") : defaultEndTime(startTime);
|
|
687
|
+
const participants = args.participants !== void 0 && args.participants !== "" ? args.participants : session.userId;
|
|
688
|
+
const mainTable = {
|
|
689
|
+
agn_name: agnName.trim(),
|
|
690
|
+
start_time: startTime,
|
|
691
|
+
end_time: endTime,
|
|
692
|
+
participants,
|
|
693
|
+
...pickDefined(args, [...OPTIONAL_FIELDS])
|
|
694
|
+
};
|
|
695
|
+
if (args.agn_type !== void 0) mainTable.agn_type = args.agn_type;
|
|
696
|
+
if (args.priority !== void 0) mainTable.priority = args.priority;
|
|
697
|
+
return mainTable;
|
|
698
|
+
}
|
|
699
|
+
var calendarCreatePrepare = {
|
|
700
|
+
name: "calendar.create.prepare",
|
|
701
|
+
resource: "calendar",
|
|
702
|
+
method: "create.prepare",
|
|
703
|
+
action: "calendar.create.prepare",
|
|
704
|
+
summary: "\u51C6\u5907\u521B\u5EFA\u65E5\u7A0B\uFF1A\u6821\u9A8C\u5B57\u6BB5\u3001\u8865\u9ED8\u8BA4\u503C\uFF08\u53C2\u4E0E\u4EBA\u9ED8\u8BA4\u5F53\u524D\u4EBA\u3001\u65F6\u957F\u9ED8\u8BA4 1 \u5C0F\u65F6\uFF09\u5E76\u751F\u6210\u786E\u8BA4\u9884\u89C8\uFF0C\u4E0D\u5199\u5165",
|
|
705
|
+
capability: "calendar",
|
|
706
|
+
risk: "high-risk-write",
|
|
707
|
+
requiresConfirmation: true,
|
|
708
|
+
inputSchema: schemaOf({ ...MAIN_TABLE_SCHEMA }, { required: ["agn_name", "start_time"] }),
|
|
709
|
+
handler: async (args, { host, continuation }) => {
|
|
710
|
+
if (args.agn_type === void 0) {
|
|
711
|
+
throw calendarValidationError("agn_type_required", "agn_type\uFF08\u65E5\u7A0B\u7C7B\u578B\uFF09\u5FC5\u586B\uFF0C\u8BF7\u5148\u901A\u8FC7 calendar.type.list \u83B7\u53D6\u9009\u9879 ID");
|
|
712
|
+
}
|
|
713
|
+
if (args.priority === void 0) {
|
|
714
|
+
throw calendarValidationError("priority_required", "priority\uFF08\u7D27\u6025\u7A0B\u5EA6\uFF09\u5FC5\u586B\uFF0C\u8BF7\u5148\u901A\u8FC7 calendar.priority.list \u83B7\u53D6\u9009\u9879 ID");
|
|
715
|
+
}
|
|
716
|
+
const mainTable = await normalizeMainTable(args, host);
|
|
717
|
+
const session = await host.getSession();
|
|
718
|
+
const preview = { ...mainTable };
|
|
719
|
+
const token = await continuation.issue(
|
|
720
|
+
{
|
|
721
|
+
operation: "calendar.create.apply",
|
|
722
|
+
baseUrl: session.baseUrl,
|
|
723
|
+
profile: session.profile,
|
|
724
|
+
userId: session.userId,
|
|
725
|
+
payload: mainTable,
|
|
726
|
+
fingerprint: fingerprint(mainTable)
|
|
727
|
+
},
|
|
728
|
+
CONTINUATION_TTL_SECONDS * 1e3
|
|
729
|
+
);
|
|
730
|
+
return calendarSuccess("calendar.create.prepare", {
|
|
731
|
+
status: "AWAITING_CONFIRMATION",
|
|
732
|
+
preview,
|
|
733
|
+
continuation: token,
|
|
734
|
+
expiresInSeconds: CONTINUATION_TTL_SECONDS
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
var calendarCreateApply = {
|
|
739
|
+
name: "calendar.create.apply",
|
|
740
|
+
resource: "calendar",
|
|
741
|
+
method: "create.apply",
|
|
742
|
+
action: "calendar.create.apply",
|
|
743
|
+
summary: "\u63D0\u4EA4\u521B\u5EFA\u65E5\u7A0B\uFF1B\u5FC5\u987B\u5728\u7528\u6237\u660E\u786E\u786E\u8BA4\u540E\u8C03\u7528\uFF0C\u4E14\u8981\u6C42 prepare \u8FD4\u56DE\u7684 continuation",
|
|
744
|
+
capability: "calendar",
|
|
745
|
+
risk: "high-risk-write",
|
|
746
|
+
requiresConfirmation: true,
|
|
747
|
+
inputSchema: schemaOf(
|
|
748
|
+
{ ...MAIN_TABLE_SCHEMA, confirm: { const: true }, continuation: { type: "string", minLength: 1 } },
|
|
749
|
+
{ required: ["agn_name", "start_time", "confirm", "continuation"] }
|
|
750
|
+
),
|
|
751
|
+
handler: async (args, env) => {
|
|
752
|
+
requireConfirm(args, "calendar.create.apply");
|
|
753
|
+
const lease = await verifyLease(args, "calendar.create.apply", env);
|
|
754
|
+
const mainTable = await normalizeMainTable(args, env.host);
|
|
755
|
+
if (lease.fingerprint !== fingerprint(mainTable)) {
|
|
756
|
+
throw calendarValidationError("target_changed", "\u65E5\u7A0B\u5185\u5BB9\u4E0E prepare \u65F6\u7684\u5FEB\u7167\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
757
|
+
}
|
|
758
|
+
const body = await buildWriteDatajson(env.host, [mainTable]);
|
|
759
|
+
let response;
|
|
760
|
+
try {
|
|
761
|
+
response = await env.host.request({
|
|
762
|
+
method: "POST",
|
|
763
|
+
path: "/api/ebuilder/form/formdata/v2/saveFormData/createAgenda",
|
|
764
|
+
operation: "calendar.create.apply",
|
|
765
|
+
body
|
|
766
|
+
});
|
|
767
|
+
} catch (error) {
|
|
768
|
+
if (isNetworkError(error)) {
|
|
769
|
+
throw calendarPartialError(
|
|
770
|
+
"\u521B\u5EFA\u8BF7\u6C42\u53D1\u9001\u540E\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u662F\u5426\u5DF2\u521B\u5EFA\u4E0D\u786E\u5B9A\uFF0C\u7981\u6B62\u81EA\u52A8\u91CD\u8BD5\uFF0C\u8BF7\u901A\u8FC7 calendar.list \u590D\u6838",
|
|
771
|
+
{ attempted: { agn_name: mainTable.agn_name } },
|
|
772
|
+
{ stage: "create" }
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
throw error;
|
|
776
|
+
}
|
|
777
|
+
return calendarSuccess("calendar.create.apply", {
|
|
778
|
+
status: "COMPLETE",
|
|
779
|
+
result: response
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
};
|
|
783
|
+
async function fetchCurrentMainTable(id, host) {
|
|
784
|
+
const session = await host.getSession();
|
|
785
|
+
const response = await host.request({
|
|
786
|
+
method: "POST",
|
|
787
|
+
path: "/api/ebuilder/form/formdata/v2/getFormDataByPk/queryAgenda",
|
|
788
|
+
operation: "calendar.update.prepare",
|
|
789
|
+
body: {
|
|
790
|
+
datajson: {
|
|
791
|
+
mainTable: { id },
|
|
792
|
+
header: { operator: session.userId }
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
});
|
|
796
|
+
const datas = response?.datajson?.datas;
|
|
797
|
+
const mainTable = Array.isArray(datas) && datas[0]?.mainTable ? datas[0].mainTable : void 0;
|
|
798
|
+
if (!mainTable) {
|
|
799
|
+
throw calendarValidationError("not_found", `\u65E5\u7A0B ${id} \u4E0D\u5B58\u5728\u6216\u65E0\u6743\u67E5\u770B\uFF0C\u65E0\u6CD5\u66F4\u65B0`);
|
|
800
|
+
}
|
|
801
|
+
return mainTable;
|
|
802
|
+
}
|
|
803
|
+
function mainTableToUpdateFields(mainTable) {
|
|
804
|
+
const result = { id: mainTable.id };
|
|
805
|
+
const scalarKeys = [
|
|
806
|
+
"agn_name",
|
|
807
|
+
"start_time",
|
|
808
|
+
"end_time",
|
|
809
|
+
"agn_desc",
|
|
810
|
+
"place",
|
|
811
|
+
"location",
|
|
812
|
+
"next_start_remind",
|
|
813
|
+
"next_end_remind",
|
|
814
|
+
"all_day",
|
|
815
|
+
"part_receipt",
|
|
816
|
+
"remind",
|
|
817
|
+
"start_hours",
|
|
818
|
+
"start_mins",
|
|
819
|
+
"end_hours",
|
|
820
|
+
"end_mins",
|
|
821
|
+
"repeat_custom_cycle",
|
|
822
|
+
"repeat_end_date",
|
|
823
|
+
"repeat_end_num",
|
|
824
|
+
"repeat_desc"
|
|
825
|
+
];
|
|
826
|
+
for (const key of scalarKeys) {
|
|
827
|
+
if (mainTable[key] !== void 0) result[key] = mainTable[key];
|
|
828
|
+
}
|
|
829
|
+
const optionKeys = ["agn_type", "priority", "start_reminder", "remind_type", "end_reminder", "repeat_type", "repeat_custom_type", "repeat_week_unit", "repeat_month_unit", "repeat_end_type"];
|
|
830
|
+
for (const key of optionKeys) {
|
|
831
|
+
const id = optionId(mainTable[key]);
|
|
832
|
+
if (id !== void 0) result[key] = id;
|
|
833
|
+
}
|
|
834
|
+
const participants = participantIds(mainTable.participants);
|
|
835
|
+
if (participants !== void 0) result.participants = participants;
|
|
836
|
+
return result;
|
|
837
|
+
}
|
|
838
|
+
var calendarUpdatePrepare = {
|
|
839
|
+
name: "calendar.update.prepare",
|
|
840
|
+
resource: "calendar",
|
|
841
|
+
method: "update.prepare",
|
|
842
|
+
action: "calendar.update.prepare",
|
|
843
|
+
summary: "\u51C6\u5907\u66F4\u65B0\u65E5\u7A0B\uFF08\u5168\u91CF\u8986\u76D6\uFF09\uFF1A\u5148\u67E5\u5F53\u524D\u8BE6\u60C5\uFF0C\u5408\u5E76\u7528\u6237\u4FEE\u6539\u5E76\u751F\u6210\u786E\u8BA4\u9884\u89C8\uFF0C\u4E0D\u5199\u5165",
|
|
844
|
+
capability: "calendar",
|
|
845
|
+
risk: "high-risk-write",
|
|
846
|
+
requiresConfirmation: true,
|
|
847
|
+
inputSchema: schemaOf({
|
|
848
|
+
id: SCHEMA_ID,
|
|
849
|
+
...MAIN_TABLE_SCHEMA
|
|
850
|
+
}, { required: ["id"] }),
|
|
851
|
+
handler: async (args, { host, continuation }) => {
|
|
852
|
+
const id = String(args.id);
|
|
853
|
+
const current = await fetchCurrentMainTable(id, host);
|
|
854
|
+
const base = mainTableToUpdateFields(current);
|
|
855
|
+
const overrides = {};
|
|
856
|
+
for (const key of ["agn_name", "start_time", "end_time", "participants", "agn_type", "priority", ...OPTIONAL_FIELDS]) {
|
|
857
|
+
if (args[key] !== void 0) overrides[key] = args[key];
|
|
858
|
+
}
|
|
859
|
+
if (overrides.start_time !== void 0 && overrides.end_time === void 0) {
|
|
860
|
+
overrides.end_time = defaultEndTime(String(overrides.start_time));
|
|
861
|
+
}
|
|
862
|
+
const merged = { ...base, ...overrides };
|
|
863
|
+
const session = await host.getSession();
|
|
864
|
+
const token = await continuation.issue(
|
|
865
|
+
{
|
|
866
|
+
operation: "calendar.update.apply",
|
|
867
|
+
baseUrl: session.baseUrl,
|
|
868
|
+
profile: session.profile,
|
|
869
|
+
userId: session.userId,
|
|
870
|
+
payload: merged,
|
|
871
|
+
fingerprint: fingerprint(merged)
|
|
872
|
+
},
|
|
873
|
+
CONTINUATION_TTL_SECONDS * 1e3
|
|
874
|
+
);
|
|
875
|
+
return calendarSuccess("calendar.update.prepare", {
|
|
876
|
+
status: "AWAITING_CONFIRMATION",
|
|
877
|
+
preview: {
|
|
878
|
+
before: base,
|
|
879
|
+
after: merged,
|
|
880
|
+
changedFields: Object.keys(overrides)
|
|
881
|
+
},
|
|
882
|
+
continuation: token,
|
|
883
|
+
expiresInSeconds: CONTINUATION_TTL_SECONDS
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
};
|
|
887
|
+
var calendarUpdateApply = {
|
|
888
|
+
name: "calendar.update.apply",
|
|
889
|
+
resource: "calendar",
|
|
890
|
+
method: "update.apply",
|
|
891
|
+
action: "calendar.update.apply",
|
|
892
|
+
summary: "\u63D0\u4EA4\u66F4\u65B0\u65E5\u7A0B\uFF1B\u5FC5\u987B\u5728\u7528\u6237\u660E\u786E\u786E\u8BA4\u540E\u8C03\u7528\uFF0C\u4E14\u8981\u6C42 prepare \u8FD4\u56DE\u7684 continuation",
|
|
893
|
+
capability: "calendar",
|
|
894
|
+
risk: "high-risk-write",
|
|
895
|
+
requiresConfirmation: true,
|
|
896
|
+
inputSchema: schemaOf({
|
|
897
|
+
id: SCHEMA_ID,
|
|
898
|
+
...MAIN_TABLE_SCHEMA,
|
|
899
|
+
confirm: { const: true },
|
|
900
|
+
continuation: { type: "string", minLength: 1 }
|
|
901
|
+
}, { required: ["id", "confirm", "continuation"] }),
|
|
902
|
+
handler: async (args, env) => {
|
|
903
|
+
requireConfirm(args, "calendar.update.apply");
|
|
904
|
+
const lease = await verifyLease(args, "calendar.update.apply", env);
|
|
905
|
+
const id = String(args.id);
|
|
906
|
+
const payload = lease.payload || {};
|
|
907
|
+
if (String(payload.id ?? "") !== id) {
|
|
908
|
+
throw calendarValidationError("target_changed", "\u65E5\u7A0B ID \u4E0E prepare \u65F6\u7684\u5FEB\u7167\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
909
|
+
}
|
|
910
|
+
const body = await buildWriteDatajson(env.host, [payload]);
|
|
911
|
+
let response;
|
|
912
|
+
try {
|
|
913
|
+
response = await env.host.request({
|
|
914
|
+
method: "POST",
|
|
915
|
+
path: "/api/ebuilder/form/formdata/v2/updateFormData/updateAgenda",
|
|
916
|
+
operation: "calendar.update.apply",
|
|
917
|
+
body
|
|
918
|
+
});
|
|
919
|
+
} catch (error) {
|
|
920
|
+
if (isNetworkError(error)) {
|
|
921
|
+
throw calendarPartialError(
|
|
922
|
+
"\u66F4\u65B0\u8BF7\u6C42\u53D1\u9001\u540E\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u662F\u5426\u5DF2\u66F4\u65B0\u4E0D\u786E\u5B9A\uFF0C\u7981\u6B62\u81EA\u52A8\u91CD\u8BD5\uFF0C\u8BF7\u901A\u8FC7 calendar.get \u590D\u6838",
|
|
923
|
+
{ attempted: { id } },
|
|
924
|
+
{ stage: "update" }
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
throw error;
|
|
928
|
+
}
|
|
929
|
+
return calendarSuccess("calendar.update.apply", {
|
|
930
|
+
status: "COMPLETE",
|
|
931
|
+
result: response
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
var calendarDeletePrepare = {
|
|
936
|
+
name: "calendar.delete.prepare",
|
|
937
|
+
resource: "calendar",
|
|
938
|
+
method: "delete.prepare",
|
|
939
|
+
action: "calendar.delete.prepare",
|
|
940
|
+
summary: "\u51C6\u5907\u5220\u9664\u65E5\u7A0B\uFF1A\u67E5\u5F53\u524D\u8BE6\u60C5\u5E76\u751F\u6210\u786E\u8BA4\u9884\u89C8\uFF0C\u4E0D\u5220\u9664",
|
|
941
|
+
capability: "calendar",
|
|
942
|
+
risk: "high-risk-write",
|
|
943
|
+
requiresConfirmation: true,
|
|
944
|
+
inputSchema: schemaOf({ id: SCHEMA_ID }, { required: ["id"] }),
|
|
945
|
+
handler: async (args, { host, continuation }) => {
|
|
946
|
+
const id = String(args.id);
|
|
947
|
+
const current = await fetchCurrentMainTable(id, host);
|
|
948
|
+
const session = await host.getSession();
|
|
949
|
+
const preview = {
|
|
950
|
+
id,
|
|
951
|
+
agn_name: current.agn_name,
|
|
952
|
+
start_time: current.start_time,
|
|
953
|
+
end_time: current.end_time
|
|
954
|
+
};
|
|
955
|
+
const token = await continuation.issue(
|
|
956
|
+
{
|
|
957
|
+
operation: "calendar.delete.apply",
|
|
958
|
+
baseUrl: session.baseUrl,
|
|
959
|
+
profile: session.profile,
|
|
960
|
+
userId: session.userId,
|
|
961
|
+
payload: { id },
|
|
962
|
+
fingerprint: fingerprint({ id })
|
|
963
|
+
},
|
|
964
|
+
CONTINUATION_TTL_SECONDS * 1e3
|
|
965
|
+
);
|
|
966
|
+
return calendarSuccess("calendar.delete.prepare", {
|
|
967
|
+
status: "AWAITING_CONFIRMATION",
|
|
968
|
+
preview,
|
|
969
|
+
continuation: token,
|
|
970
|
+
expiresInSeconds: CONTINUATION_TTL_SECONDS
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
var calendarDeleteApply = {
|
|
975
|
+
name: "calendar.delete.apply",
|
|
976
|
+
resource: "calendar",
|
|
977
|
+
method: "delete.apply",
|
|
978
|
+
action: "calendar.delete.apply",
|
|
979
|
+
summary: "\u63D0\u4EA4\u5220\u9664\u65E5\u7A0B\uFF1B\u4E0D\u53EF\u9006\uFF0C\u5FC5\u987B\u5728\u7528\u6237\u660E\u786E\u786E\u8BA4\u540E\u8C03\u7528",
|
|
980
|
+
capability: "calendar",
|
|
981
|
+
risk: "high-risk-write",
|
|
982
|
+
requiresConfirmation: true,
|
|
983
|
+
inputSchema: schemaOf({
|
|
984
|
+
id: SCHEMA_ID,
|
|
985
|
+
confirm: { const: true },
|
|
986
|
+
continuation: { type: "string", minLength: 1 }
|
|
987
|
+
}, { required: ["id", "confirm", "continuation"] }),
|
|
988
|
+
handler: async (args, env) => {
|
|
989
|
+
requireConfirm(args, "calendar.delete.apply");
|
|
990
|
+
const lease = await verifyLease(args, "calendar.delete.apply", env);
|
|
991
|
+
const id = String(args.id);
|
|
992
|
+
if (lease.fingerprint !== fingerprint({ id })) {
|
|
993
|
+
throw calendarValidationError("target_changed", "\u65E5\u7A0B ID \u4E0E prepare \u65F6\u7684\u5FEB\u7167\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
994
|
+
}
|
|
995
|
+
const body = await buildWriteDatajson(env.host, [{ id }]);
|
|
996
|
+
let response;
|
|
997
|
+
try {
|
|
998
|
+
response = await env.host.request({
|
|
999
|
+
method: "POST",
|
|
1000
|
+
path: "/api/ebuilder/form/formdata/v2/deleteFormData/deleteAgenda",
|
|
1001
|
+
operation: "calendar.delete.apply",
|
|
1002
|
+
body
|
|
1003
|
+
});
|
|
1004
|
+
} catch (error) {
|
|
1005
|
+
if (isNetworkError(error)) {
|
|
1006
|
+
throw calendarPartialError(
|
|
1007
|
+
"\u5220\u9664\u8BF7\u6C42\u53D1\u9001\u540E\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u662F\u5426\u5DF2\u5220\u9664\u4E0D\u786E\u5B9A\uFF0C\u7981\u6B62\u81EA\u52A8\u91CD\u8BD5\uFF0C\u8BF7\u901A\u8FC7 calendar.get \u590D\u6838",
|
|
1008
|
+
{ attempted: { id } },
|
|
1009
|
+
{ stage: "delete" }
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
1012
|
+
throw error;
|
|
1013
|
+
}
|
|
1014
|
+
return calendarSuccess("calendar.delete.apply", {
|
|
1015
|
+
status: "COMPLETE",
|
|
1016
|
+
result: response
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
};
|
|
1020
|
+
var calendarWriteOperations = [
|
|
1021
|
+
calendarCreatePrepare,
|
|
1022
|
+
calendarCreateApply,
|
|
1023
|
+
calendarUpdatePrepare,
|
|
1024
|
+
calendarUpdateApply,
|
|
1025
|
+
calendarDeletePrepare,
|
|
1026
|
+
calendarDeleteApply
|
|
1027
|
+
];
|
|
1028
|
+
|
|
1029
|
+
// src/shortcuts/calendar/operations/registry.ts
|
|
1030
|
+
function buildRegistry() {
|
|
1031
|
+
const registry = /* @__PURE__ */ new Map();
|
|
1032
|
+
const definitions = [
|
|
1033
|
+
...calendarReadOperations,
|
|
1034
|
+
...calendarWriteOperations
|
|
1035
|
+
];
|
|
1036
|
+
for (const definition of definitions) {
|
|
1037
|
+
if (registry.has(definition.name)) {
|
|
1038
|
+
throw new Error(`duplicate calendar operation: ${definition.name}`);
|
|
1039
|
+
}
|
|
1040
|
+
registry.set(definition.name, definition);
|
|
1041
|
+
}
|
|
1042
|
+
return registry;
|
|
1043
|
+
}
|
|
1044
|
+
var calendarOperationRegistry = buildRegistry();
|
|
1045
|
+
function calendarOperationDefinitions() {
|
|
1046
|
+
return [...calendarOperationRegistry.values()];
|
|
1047
|
+
}
|
|
1048
|
+
function getCalendarOperation(operation) {
|
|
1049
|
+
const definition = calendarOperationRegistry.get(operation);
|
|
1050
|
+
if (!definition) {
|
|
1051
|
+
throw calendarValidationError("operation_unknown", `\u65E5\u7A0B\u6A21\u5757\u4E0D\u652F\u6301\u64CD\u4F5C\uFF1A${operation}`);
|
|
1052
|
+
}
|
|
1053
|
+
return definition;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
// src/shortcuts/calendar/manifest.ts
|
|
1057
|
+
var WITHHELD = [];
|
|
1058
|
+
function buildOperations() {
|
|
1059
|
+
return calendarOperationDefinitions().map((definition) => ({
|
|
1060
|
+
name: definition.name,
|
|
1061
|
+
resource: definition.resource,
|
|
1062
|
+
summary: definition.summary,
|
|
1063
|
+
...definition.capability ? { capability: definition.capability } : {},
|
|
1064
|
+
risk: definition.risk,
|
|
1065
|
+
...definition.requiresConfirmation ? { requiresConfirmation: true } : {},
|
|
1066
|
+
inputSchema: definition.inputSchema
|
|
1067
|
+
}));
|
|
1068
|
+
}
|
|
1069
|
+
var calendarManifest = {
|
|
1070
|
+
schemaVersion: 1,
|
|
1071
|
+
name: "calendar",
|
|
1072
|
+
title: "\u6CDB\u5FAEE10\u65E5\u7A0B\u7BA1\u7406\uFF08\u521B\u5EFA/\u67E5\u8BE2/\u66F4\u65B0/\u5220\u9664/\u5B57\u5178\uFF09",
|
|
1073
|
+
version: "0.1.0",
|
|
1074
|
+
host: "e10-calendar",
|
|
1075
|
+
status: "builtin",
|
|
1076
|
+
sourceSkill: "weaver-e10-calendar",
|
|
1077
|
+
capabilities: ["calendar"],
|
|
1078
|
+
operations: buildOperations(),
|
|
1079
|
+
withheldOperations: WITHHELD
|
|
1080
|
+
};
|
|
1081
|
+
|
|
1082
|
+
// src/shortcuts/calendar/operations.ts
|
|
1083
|
+
async function executeCalendarOperation(operation, rawInput, context) {
|
|
1084
|
+
const definition = getCalendarOperation(operation);
|
|
1085
|
+
const input = asObject(rawInput);
|
|
1086
|
+
assertNoForbiddenKeys(input);
|
|
1087
|
+
return definition.handler(input, context);
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
// src/shortcuts/calendar/index.ts
|
|
1091
|
+
function asOptions(value) {
|
|
1092
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1093
|
+
}
|
|
1094
|
+
async function readStdin() {
|
|
1095
|
+
const chunks = [];
|
|
1096
|
+
for await (const chunk of process.stdin) {
|
|
1097
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
1098
|
+
}
|
|
1099
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
1100
|
+
}
|
|
1101
|
+
function stripBom(value) {
|
|
1102
|
+
return value.replace(/^\uFEFF+/, "");
|
|
1103
|
+
}
|
|
1104
|
+
async function inputFrom(options, extra = {}) {
|
|
1105
|
+
const opts = asOptions(options);
|
|
1106
|
+
let input = {};
|
|
1107
|
+
if (opts.input && opts.inputJson) {
|
|
1108
|
+
throw calendarValidationError("input_conflict", "\u4E0D\u80FD\u540C\u65F6\u4F20 --input \u548C --input-json");
|
|
1109
|
+
}
|
|
1110
|
+
if (opts.inputJson) {
|
|
1111
|
+
input = parseJsonInput(String(opts.inputJson), "--input-json");
|
|
1112
|
+
}
|
|
1113
|
+
if (opts.input) {
|
|
1114
|
+
let raw;
|
|
1115
|
+
try {
|
|
1116
|
+
raw = stripBom(opts.input === "-" ? await readStdin() : await readFile2(String(opts.input), "utf8"));
|
|
1117
|
+
} catch {
|
|
1118
|
+
throw calendarValidationError("input_unreadable", `\u65E0\u6CD5\u8BFB\u53D6 --input\uFF1A${String(opts.input)}`);
|
|
1119
|
+
}
|
|
1120
|
+
input = parseJsonInput(raw, "--input");
|
|
1121
|
+
}
|
|
1122
|
+
return {
|
|
1123
|
+
...input,
|
|
1124
|
+
...Object.fromEntries(Object.entries(extra).filter(([, value]) => value !== void 0 && value !== ""))
|
|
1125
|
+
};
|
|
1126
|
+
}
|
|
1127
|
+
function parseJsonInput(raw, label) {
|
|
1128
|
+
try {
|
|
1129
|
+
const parsed = JSON.parse(stripBom(raw));
|
|
1130
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1131
|
+
throw new Error("input must be an object");
|
|
1132
|
+
}
|
|
1133
|
+
return parsed;
|
|
1134
|
+
} catch {
|
|
1135
|
+
throw calendarValidationError("input_invalid", `${label} \u4E0D\u662F\u5408\u6CD5 JSON \u5BF9\u8C61`);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
function successEnvelope(operation, result) {
|
|
1139
|
+
return {
|
|
1140
|
+
schemaVersion: 1,
|
|
1141
|
+
ok: true,
|
|
1142
|
+
operation,
|
|
1143
|
+
data: result.data === void 0 ? null : result.data,
|
|
1144
|
+
...result.meta ? { meta: result.meta } : {},
|
|
1145
|
+
warnings: []
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
function failureEnvelope(error) {
|
|
1149
|
+
const structured = error;
|
|
1150
|
+
return {
|
|
1151
|
+
schemaVersion: 1,
|
|
1152
|
+
ok: false,
|
|
1153
|
+
...structured?.partialData === void 0 ? {} : { data: structured.partialData },
|
|
1154
|
+
error: toErrorEnvelope(error)
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
async function executeAndPrint(ctx, operation, input) {
|
|
1158
|
+
try {
|
|
1159
|
+
const result = await executeCalendarOperation(operation, input, {
|
|
1160
|
+
ctx,
|
|
1161
|
+
host: createCalendarHost(ctx),
|
|
1162
|
+
continuation: createCalendarContinuationSigner(ctx)
|
|
1163
|
+
});
|
|
1164
|
+
ctx.output.write(successEnvelope(operation, result), { json: true });
|
|
1165
|
+
} catch (error) {
|
|
1166
|
+
console.error(JSON.stringify(failureEnvelope(error), null, 2));
|
|
1167
|
+
process.exitCode = isCliError(error) ? error.exitCode : 1 /* GeneralError */;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
var calendarShortcut = {
|
|
1171
|
+
name: "calendar",
|
|
1172
|
+
description: "\u6CDB\u5FAEE10\u65E5\u7A0B\u7BA1\u7406 CLI\uFF08\u521B\u5EFA/\u67E5\u8BE2/\u66F4\u65B0/\u5220\u9664/\u5B57\u5178\uFF09",
|
|
1173
|
+
category: "shortcut",
|
|
1174
|
+
register({ program, action }) {
|
|
1175
|
+
const calendar = program.command("calendar").description("\u6CDB\u5FAEE10\u65E5\u7A0B\u7BA1\u7406\uFF08\u521B\u5EFA/\u67E5\u8BE2\u5217\u8868/\u8BE6\u60C5/\u603B\u6570/\u66F4\u65B0/\u5220\u9664/\u7C7B\u578B/\u7D27\u6025\u7A0B\u5EA6\uFF09");
|
|
1176
|
+
calendar.command("schema").description("Print calendar operation manifest for agents").action(action((ctx) => {
|
|
1177
|
+
ctx.output.write(calendarManifest, { json: true });
|
|
1178
|
+
}));
|
|
1179
|
+
calendar.command("run").description("Run a calendar operation with JSON input").argument("<operation>", "operation name, e.g. calendar.list").option("--input <path>", "JSON input file, or - for stdin").option("--input-json <json>", "inline JSON input object").action(action(async (ctx, operation, options) => {
|
|
1180
|
+
await executeAndPrint(ctx, String(operation), await inputFrom(options));
|
|
1181
|
+
}));
|
|
1182
|
+
calendar.command("get").description("\u67E5\u8BE2\u5355\u6761\u65E5\u7A0B\u8BE6\u60C5\uFF08calendar.get \u8584\u5305\u88C5\uFF09").option("--input <path>", "JSON input file, or - for stdin").option("--input-json <json>", "inline JSON input object").option("--id <id>", "\u65E5\u7A0B\u6570\u636E ID").action(action(async (ctx, options) => {
|
|
1183
|
+
const opts = asOptions(options);
|
|
1184
|
+
await executeAndPrint(ctx, "calendar.get", await inputFrom(options, { id: opts.id }));
|
|
1185
|
+
}));
|
|
1186
|
+
calendar.command("count").description("\u67E5\u8BE2\u65E5\u7A0B\u603B\u6570\uFF08calendar.count \u8584\u5305\u88C5\uFF09").action(action(async (ctx) => {
|
|
1187
|
+
await executeAndPrint(ctx, "calendar.count", {});
|
|
1188
|
+
}));
|
|
1189
|
+
}
|
|
1190
|
+
};
|
|
1191
|
+
export {
|
|
1192
|
+
calendarShortcut,
|
|
1193
|
+
inputFrom,
|
|
1194
|
+
successEnvelope
|
|
1195
|
+
};
|