weaver-work-cli 0.1.29 → 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.
Files changed (185) hide show
  1. package/dist/chunks/archive-U766FTFH.js +2537 -0
  2. package/dist/chunks/archive-oa-DMWEKX3L.js +1317 -0
  3. package/dist/chunks/asset-TCR7VDEV.js +2109 -0
  4. package/dist/chunks/attachment-content-AQNX5N3S.js +23 -0
  5. package/dist/chunks/blog-EVZWGDVM.js +2157 -0
  6. package/dist/chunks/caizhilian-JOWS6SL5.js +10087 -0
  7. package/dist/chunks/calendar-5WNCV66Q.js +1195 -0
  8. package/dist/chunks/chunk-2DUV44UX.js +15606 -0
  9. package/dist/chunks/chunk-324YPTC2.js +1607 -0
  10. package/dist/chunks/chunk-65QMVWHS.js +231 -0
  11. package/dist/chunks/chunk-6V7ZLF34.js +387 -0
  12. package/dist/chunks/chunk-AC7KJWC5.js +358 -0
  13. package/dist/chunks/chunk-AJ62BGAW.js +29 -0
  14. package/dist/chunks/chunk-BUSC6UAE.js +43 -0
  15. package/dist/chunks/chunk-CVZ2JOSW.js +62 -0
  16. package/dist/chunks/chunk-D4LTJSJD.js +477 -0
  17. package/dist/chunks/chunk-EG6ZU444.js +654 -0
  18. package/dist/chunks/chunk-EZALDOQH.js +383 -0
  19. package/dist/chunks/chunk-FMPJJYYI.js +106 -0
  20. package/dist/chunks/chunk-G2JSIUWF.js +769 -0
  21. package/dist/chunks/chunk-GCG2NMWR.js +703 -0
  22. package/dist/chunks/chunk-GPMFD4RD.js +75 -0
  23. package/dist/chunks/chunk-H3WDBYJW.js +508 -0
  24. package/dist/chunks/chunk-H6XSTSLM.js +2357 -0
  25. package/dist/chunks/chunk-J7RJTZSV.js +5556 -0
  26. package/dist/chunks/chunk-LUSPKZKY.js +53 -0
  27. package/dist/chunks/chunk-NIAJ5ZCG.js +73 -0
  28. package/dist/chunks/chunk-NOODWMCL.js +584 -0
  29. package/dist/chunks/chunk-OOUTBLZ4.js +51 -0
  30. package/dist/chunks/chunk-P26ZWSKU.js +73 -0
  31. package/dist/chunks/chunk-QWY6PGL6.js +3472 -0
  32. package/dist/chunks/chunk-R2IJAK7T.js +464 -0
  33. package/dist/chunks/chunk-R7O5PUWO.js +205 -0
  34. package/dist/chunks/chunk-RCGYCOMG.js +6962 -0
  35. package/dist/chunks/chunk-VZTXRG6X.js +403 -0
  36. package/dist/chunks/chunk-WHD4XMRP.js +161 -0
  37. package/dist/chunks/chunk-YLCYX7LE.js +371 -0
  38. package/dist/chunks/chunk-ZEDWSH32.js +68 -0
  39. package/dist/chunks/continuation-2CKSBLA6.js +11 -0
  40. package/dist/chunks/continuation-HZIZRZBX.js +13 -0
  41. package/dist/chunks/continuation-NLECEJPX.js +11 -0
  42. package/dist/chunks/ebuilder-form-NJ4YK6CC.js +2276 -0
  43. package/dist/chunks/ehr-MMYN36VA.js +5241 -0
  44. package/dist/chunks/employee-SAK2QYXX.js +11 -0
  45. package/dist/chunks/esb-HIWHOU7Q.js +141 -0
  46. package/dist/chunks/fna-KBACQTA5.js +1444 -0
  47. package/dist/chunks/host-3OHS5QUX.js +21 -0
  48. package/dist/chunks/host-IG6KEH5Q.js +19 -0
  49. package/dist/chunks/host-KQL5N4HO.js +23 -0
  50. package/dist/chunks/host-LLSZQCWR.js +17 -0
  51. package/dist/chunks/hrm-LYEC67ZQ.js +244 -0
  52. package/dist/chunks/im-RN2UKAEU.js +252 -0
  53. package/dist/chunks/invoice-EEPHLAF6.js +5179 -0
  54. package/dist/chunks/jiuchuanhui-WVVZYSJE.js +1940 -0
  55. package/dist/chunks/lazy-dispatch-MDOFFL2S.js +28 -0
  56. package/dist/chunks/mail-LNQLTF6L.js +2695 -0
  57. package/dist/chunks/meeting-XSD3BDVQ.js +504 -0
  58. package/dist/chunks/msg-parse-4GSQ2WTO.js +41 -0
  59. package/dist/chunks/okr-TMWTIU2K.js +2482 -0
  60. package/dist/chunks/plan-A2FSFA7T.js +2025 -0
  61. package/dist/chunks/project-T26QLBQF.js +1361 -0
  62. package/dist/chunks/registry-2VLUAESA.js +14 -0
  63. package/dist/chunks/registry-JCFEYXOE.js +18 -0
  64. package/dist/chunks/registry-NYPYMZXG.js +16 -0
  65. package/dist/chunks/registry-Q7OQJ3SU.js +19 -0
  66. package/dist/chunks/registry-ZJMJVWFA.js +19 -0
  67. package/dist/chunks/room-recommend-UR4ZDZS6.js +20 -0
  68. package/dist/chunks/schedule-5L2PM4M6.js +24 -0
  69. package/dist/chunks/state-Y2XBP6YE.js +15 -0
  70. package/dist/chunks/workflow-TR6PG2SL.js +245 -0
  71. package/dist/cmd/argv.js +45 -0
  72. package/dist/cmd/docs/index.js +3 -3
  73. package/dist/cmd/lazy-dispatch.js +20 -0
  74. package/dist/cmd/root.js +2 -4
  75. package/dist/cmd/setup/index.js +2 -2
  76. package/dist/cmd/skills/index.js +2 -2
  77. package/dist/core/package-paths.js +47 -0
  78. package/dist/index.js +163 -7
  79. package/dist/internal/e10/auth/xiaoe.js +3 -3
  80. package/dist/internal/e10/request-runtime.js +18 -62
  81. package/dist/internal/skills/detector.js +2 -2
  82. package/dist/shortcuts/contract/data/performance-catalog.js +1306 -0
  83. package/dist/shortcuts/contract/host.js +91 -35
  84. package/dist/shortcuts/contract/index.js +213 -0
  85. package/dist/shortcuts/contract/manifest.js +928 -0
  86. package/dist/shortcuts/contract/ooxml/docx.js +295 -0
  87. package/dist/shortcuts/contract/ooxml/xlsx.js +221 -0
  88. package/dist/shortcuts/contract/ooxml/zip.js +158 -0
  89. package/dist/shortcuts/contract/operations/assistant.js +1156 -0
  90. package/dist/shortcuts/contract/operations/clause-library.js +522 -0
  91. package/dist/shortcuts/contract/operations/compare.js +193 -0
  92. package/dist/shortcuts/contract/operations/credit-page.js +34 -0
  93. package/dist/shortcuts/contract/operations/flow.js +98 -0
  94. package/dist/shortcuts/contract/operations/page.js +66 -0
  95. package/dist/shortcuts/contract/operations/performance.js +733 -0
  96. package/dist/shortcuts/contract/operations/quote.js +557 -0
  97. package/dist/shortcuts/contract/operations/recommend.js +78 -0
  98. package/dist/shortcuts/contract/operations/registry.js +18 -0
  99. package/dist/shortcuts/contract/operations/review.js +83 -0
  100. package/dist/shortcuts/contract/operations/shared.js +37 -0
  101. package/dist/shortcuts/contract/operations/upload.js +108 -0
  102. package/dist/shortcuts/contract/operations/write.js +3 -2
  103. package/dist/shortcuts/index.js +140 -40
  104. package/dist/shortcuts/invoice/manifest.js +34 -11
  105. package/dist/shortcuts/invoice/operations/reim-auto.js +9 -0
  106. package/dist/shortcuts/invoice/operations/reim.js +81 -5
  107. package/dist/shortcuts/invoice/operations/shared.js +12 -5
  108. package/dist/shortcuts/meeting/host.js +45 -3
  109. package/dist/shortcuts/meeting/invitation/docx.js +442 -0
  110. package/dist/shortcuts/meeting/operations/attachment-content.js +418 -0
  111. package/dist/shortcuts/meeting/operations/attachment.js +442 -0
  112. package/dist/shortcuts/meeting/operations/eb/cache.js +57 -0
  113. package/dist/shortcuts/meeting/operations/eb/catalog.js +343 -28
  114. package/dist/shortcuts/meeting/operations/eb/conflict.js +372 -11
  115. package/dist/shortcuts/meeting/operations/eb/create-flow.js +710 -0
  116. package/dist/shortcuts/meeting/operations/eb/decision.js +47 -1
  117. package/dist/shortcuts/meeting/operations/eb/factory.js +129 -11
  118. package/dist/shortcuts/meeting/operations/eb/index.js +122 -2
  119. package/dist/shortcuts/meeting/operations/eb/room-recommend.js +378 -0
  120. package/dist/shortcuts/meeting/operations/eb/room-summary.js +84 -0
  121. package/dist/shortcuts/meeting/operations/eb/schedule.js +450 -0
  122. package/dist/shortcuts/meeting/operations/from-group-chat.js +576 -0
  123. package/dist/shortcuts/meeting/operations/invitation.js +458 -0
  124. package/dist/shortcuts/meeting/operations/minute-content.js +266 -0
  125. package/dist/shortcuts/meeting/operations/pipeline.js +489 -0
  126. package/dist/shortcuts/meeting/operations/qrcode.js +131 -0
  127. package/dist/shortcuts/meeting/operations/receipts.js +1 -1
  128. package/dist/shortcuts/meeting/operations/registry.js +18 -0
  129. package/dist/shortcuts/meeting/operations/summary.js +276 -0
  130. package/dist/shortcuts/meeting/operations/task-notify.js +325 -0
  131. package/dist/shortcuts/meeting/operations.js +42 -1
  132. package/dist/shortcuts/meeting/qr/encoder.js +427 -0
  133. package/dist/shortcuts/meeting/qr/render.js +103 -0
  134. package/dist/shortcuts/workflow/operations/form.js +17 -5
  135. package/docs/contract.md +39 -4
  136. package/docs/invoice.md +5 -5
  137. package/package.json +3 -2
  138. package/scripts/bundle.mjs +63 -0
  139. package/skill-template/business-info.json +25 -4
  140. package/skill-template/domains/jinchengda.md +16 -3
  141. package/skill-template/domains/yepiaotong.md +1 -1
  142. package/skills/weaver-e10-jinchengda/SKILL.md +111 -31
  143. package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +7 -13
  144. package/skills/weaver-e10-jinchengda/references/contract-ai-assistant.md +150 -0
  145. package/skills/weaver-e10-jinchengda/references/contract-ai-review.md +87 -0
  146. package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +111 -0
  147. package/skills/weaver-e10-jinchengda/references/contract-clause-recommender.md +0 -15
  148. package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +0 -13
  149. package/skills/weaver-e10-jinchengda/references/contract-credit-page.md +50 -0
  150. package/skills/weaver-e10-jinchengda/references/contract-disabled-capabilities.md +4 -2
  151. package/skills/weaver-e10-jinchengda/references/contract-doc-compare.md +74 -0
  152. package/skills/weaver-e10-jinchengda/references/contract-flow-launch.md +84 -0
  153. package/skills/weaver-e10-jinchengda/references/contract-performance-query.md +29 -0
  154. package/skills/weaver-e10-jinchengda/references/contract-quote-to-contract.md +28 -0
  155. package/skills/weaver-e10-jinchengda/references/contract-request-status.md +2 -21
  156. package/skills/weaver-e10-jinchengda/references/contract-request-write.md +0 -24
  157. package/skills/weaver-e10-jinchengda/references/contract-signing-subjects.md +0 -15
  158. package/skills/weaver-e10-jinchengda/references/contract-subject-create.md +0 -17
  159. package/skills/weaver-e10-jinchengda/references/contract-template-recommend.md +70 -0
  160. package/skills/weaver-e10-jinchengda/references/contract-template-selector.md +0 -15
  161. package/skills/weaver-e10-jinchengda/references/contract-workflow-discovery.md +0 -15
  162. package/skills/weaver-e10-jinchengda/references/source-manifest.json +1168 -152
  163. package/skills/weaver-e10-meeting/SKILL.md +493 -17
  164. package/skills/weaver-e10-meeting/references/meeting-change.md +4 -4
  165. package/skills/weaver-e10-meeting/references/meeting-create.md +6 -6
  166. package/skills/weaver-e10-meeting/references/meeting-eb.md +503 -27
  167. package/skills/weaver-e10-meeting/references/meeting-invitation.md +113 -0
  168. package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +6 -6
  169. package/skills/weaver-e10-meeting/references/meeting-minute-file.md +425 -0
  170. package/skills/weaver-e10-meeting/references/meeting-queries.md +4 -4
  171. package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +15 -15
  172. package/skills/weaver-e10-meeting/references/meeting-verification.md +19 -11
  173. package/skills/weaver-e10-meeting.zip +0 -0
  174. package/skills/weaver-e10-yepiaotong/SKILL.md +9 -5
  175. package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +1 -1
  176. package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +6 -5
  177. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +14 -11
  178. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +97 -56
  179. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +84 -60
  180. package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +142 -105
  181. package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +53 -194
  182. package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -7
  183. package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +164 -72
  184. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +6 -0
  185. package/templates/meeting/invitation.docx +0 -0
@@ -24,6 +24,26 @@ function optionalDate(value, name) {
24
24
  }
25
25
  return text;
26
26
  }
27
+ function formatUtcDate(date) {
28
+ const y = date.getUTCFullYear();
29
+ const m = String(date.getUTCMonth() + 1).padStart(2, '0');
30
+ const d = String(date.getUTCDate()).padStart(2, '0');
31
+ return `${y}-${m}-${d}`;
32
+ }
33
+ /** 按日历日加减,跨月、跨年按公历进位。 */
34
+ export function addCalendarDays(isoDate, offsetDays) {
35
+ const [year, month, day] = isoDate.split('-').map(Number);
36
+ return formatUtcDate(new Date(Date.UTC(year, (month ?? 1) - 1, (day ?? 1) + offsetDays)));
37
+ }
38
+ /** 东八区日历日。 */
39
+ export function shanghaiCalendarDate(offsetDays = 0, now = new Date()) {
40
+ const today = new Intl.DateTimeFormat('en-CA', { timeZone: 'Asia/Shanghai' }).format(now);
41
+ return offsetDays === 0 ? today : addCalendarDays(today, offsetDays);
42
+ }
43
+ /** 不传结束日用东八区当天;无论是否传入,发给接口前都再加 1 天。 */
44
+ function requestCreateDateEnd(value) {
45
+ return addCalendarDays(optionalDate(value, 'cusCreateDateEnd') ?? shanghaiCalendarDate(0), 1);
46
+ }
27
47
  function responseData(value) {
28
48
  return value && typeof value === 'object' && 'data' in value ? value.data : value;
29
49
  }
@@ -38,6 +58,32 @@ function resultEnvelope(value, workflowName) {
38
58
  },
39
59
  };
40
60
  }
61
+ const REQUEST_LIST_ITEM_FIELDS = [
62
+ 'requestid',
63
+ 'workflowid',
64
+ 'requestname',
65
+ 'flowStatus',
66
+ 'creatorId',
67
+ 'creatorName',
68
+ 'createTime',
69
+ ];
70
+ function projectRequestListItem(item) {
71
+ const source = item && typeof item === 'object' && !Array.isArray(item) ? item : {};
72
+ const projected = {};
73
+ for (const key of REQUEST_LIST_ITEM_FIELDS) {
74
+ if (source[key] !== undefined)
75
+ projected[key] = source[key];
76
+ }
77
+ return projected;
78
+ }
79
+ function projectRequestListResult(value) {
80
+ if (!value || typeof value !== 'object' || Array.isArray(value))
81
+ return value;
82
+ const record = value;
83
+ if (!Array.isArray(record.data))
84
+ return value;
85
+ return { ...record, data: record.data.map(projectRequestListItem) };
86
+ }
41
87
  const UNSAFE_JSON_INTEGER_ID = /("id"\s*:\s*)(-?\d{16,})(?=\s*[,}\]])/g;
42
88
  export function quoteEmployeeIdsInJsonText(text) {
43
89
  return text.replace(UNSAFE_JSON_INTEGER_ID, '$1"$2"');
@@ -177,18 +223,18 @@ export class InvoiceReimRequestsListOperation {
177
223
  async execute(input, { host }) {
178
224
  const body = {
179
225
  pageNo: integerInput(input.pageNo, 'pageNo', { min: 1, max: 10000 }),
180
- pageSize: integerInput(input.pageSize, 'pageSize', { min: 1, max: 200, defaultValue: 20 }),
226
+ pageSize: integerInput(input.pageSize, 'pageSize', { min: 1, max: 200, defaultValue: 100 }),
181
227
  };
182
228
  for (const [key, value] of Object.entries({
183
229
  requestname: optionalString(input.requestname, 'requestname'),
184
230
  cusCreateDateStart: optionalDate(input.cusCreateDateStart, 'cusCreateDateStart'),
185
- cusCreateDateEnd: optionalDate(input.cusCreateDateEnd, 'cusCreateDateEnd'),
231
+ cusCreateDateEnd: requestCreateDateEnd(input.cusCreateDateEnd),
186
232
  })) {
187
233
  if (value !== undefined)
188
234
  body[key] = value;
189
235
  }
190
236
  const result = await host.invoiceRequest({ path: '/api/inc/book/getRequestListByTabId', method: 'POST', body, operation: this.name });
191
- return resultEnvelope(result, 'invoice.reim.requests.list');
237
+ return resultEnvelope(projectRequestListResult(result), 'invoice.reim.requests.list');
192
238
  }
193
239
  }
194
240
  export class InvoiceReimWorkflowResolveOperation {
@@ -304,14 +350,30 @@ export class InvoiceReimEmployeeSuperiorsOperation {
304
350
  return employeeSuperiorsEnvelope(result);
305
351
  }
306
352
  }
353
+ function projectFieldSearchItems(value) {
354
+ const raw = Array.isArray(value) ? value : [];
355
+ const items = [];
356
+ const seen = new Set();
357
+ for (const item of raw) {
358
+ const record = item && typeof item === 'object' && !Array.isArray(item) ? item : {};
359
+ const id = String(record.id ?? record.value ?? '').trim();
360
+ const name = String(record.name ?? '').trim();
361
+ if (!id || !name || seen.has(id))
362
+ continue;
363
+ seen.add(id);
364
+ items.push({ id, name, value: id });
365
+ }
366
+ return items;
367
+ }
307
368
  export class InvoiceReimFieldSearchOperation {
308
369
  name = 'invoice.reim.field.search';
309
370
  async execute(input, { host }) {
371
+ const keywords = asNonEmptyString(input.keywords, 'keywords');
310
372
  const result = await host.invoiceRequest({
311
373
  path: '/api/government/formStructure/fieldRelateSearch',
312
374
  method: 'GET',
313
375
  query: {
314
- keywords: asNonEmptyString(input.keywords, 'keywords'),
376
+ keywords,
315
377
  fieldId: asNonEmptyString(input.fieldId, 'fieldId'),
316
378
  formModeType: 'wf',
317
379
  workflowId: asNonEmptyString(input.workflowId, 'workflowId'),
@@ -319,7 +381,21 @@ export class InvoiceReimFieldSearchOperation {
319
381
  },
320
382
  operation: this.name,
321
383
  });
322
- return resultEnvelope(result, 'invoice.reim.field.search');
384
+ assertBusinessSuccess(result, 'invoice.reim.field.search_failed', '搜索关联字段失败');
385
+ const items = projectFieldSearchItems(responseData(result));
386
+ const match = items.length === 0 ? 'none' : items.length === 1 ? 'unique' : 'multiple';
387
+ return {
388
+ status: 'COMPLETE',
389
+ data: {
390
+ result,
391
+ data: items,
392
+ keywords,
393
+ match,
394
+ items,
395
+ selected: match === 'unique' ? items[0] : null,
396
+ workflow: workflow(this.name, 'COMPLETE'),
397
+ },
398
+ };
323
399
  }
324
400
  }
325
401
  export class InvoiceReimFlowCreatePrepareOperation {
@@ -15,6 +15,8 @@ const LIST_FIELDS = new Set([
15
15
  'date_end',
16
16
  'create_tm_begin',
17
17
  'create_tm_end',
18
+ 'consumption_tm_begin',
19
+ 'consumption_tm_end',
18
20
  'payer_company',
19
21
  'buyer_company',
20
22
  'payer_taxno',
@@ -780,7 +782,9 @@ export async function listInvoices(input, host, flag) {
780
782
  };
781
783
  }
782
784
  /** 列表查询里 E10 只接受秒级 epoch 的时间字段(契约声明为 integer)。 */
783
- const EPOCH_FIELDS = new Set(['date_begin', 'date_end', 'create_tm_begin', 'create_tm_end']);
785
+ const EPOCH_FIELDS = new Set(['date_begin', 'date_end', 'create_tm_begin', 'create_tm_end', 'consumption_tm_begin']);
786
+ /** 日期字符串按当天 23:59:59(东八区)换算,已是秒级时间戳则原样透传。 */
787
+ const EPOCH_END_OF_DAY_FIELDS = new Set(['consumption_tm_end']);
784
788
  /** 列表查询里契约声明为 integer 的标量字段。 */
785
789
  const INTEGER_FIELDS = new Set(['page_size', 'start_pos', 'req_type', 'mask', 'mext']);
786
790
  /**
@@ -788,7 +792,7 @@ const INTEGER_FIELDS = new Set(['page_size', 'start_pos', 'req_type', 'mask', 'm
788
792
  * 同时接受 `YYYY-MM-DD`(按东八区零点换算,与 `invoice.reim.candidates.list` 一致)和已是秒级 epoch 的数字/数字串,
789
793
  * 避免把字符串日期原样透传给 `/api/inc/sync` 后被打成不透明的 400 系统错误。
790
794
  */
791
- export function epochSeconds(value, name) {
795
+ export function epochSeconds(value, name, options = {}) {
792
796
  if (typeof value === 'number') {
793
797
  if (Number.isInteger(value) && value >= 0)
794
798
  return value;
@@ -796,7 +800,8 @@ export function epochSeconds(value, name) {
796
800
  }
797
801
  const text = typeof value === 'string' ? value.trim() : '';
798
802
  if (DATE_PATTERN.test(text)) {
799
- const seconds = Math.floor(Date.parse(`${text}T00:00:00+08:00`) / 1000);
803
+ const clock = options.endOfDay ? 'T23:59:59+08:00' : 'T00:00:00+08:00';
804
+ const seconds = Math.floor(Date.parse(`${text}${clock}`) / 1000);
800
805
  if (!Number.isFinite(seconds))
801
806
  throw invoiceValidationError('input_invalid', `${name} 不是有效日期`);
802
807
  return seconds;
@@ -809,10 +814,10 @@ export function epochSeconds(value, name) {
809
814
  throw invoiceValidationError('input_invalid', `${name} 必须是 YYYY-MM-DD 或秒级时间戳`);
810
815
  }
811
816
  /** `epochSeconds` 的可选版本:undefined / null / 空串 一律视为未传。 */
812
- export function optionalEpochSeconds(value, name) {
817
+ export function optionalEpochSeconds(value, name, options = {}) {
813
818
  if (value === undefined || value === null || value === '')
814
819
  return undefined;
815
- return epochSeconds(value, name);
820
+ return epochSeconds(value, name, options);
816
821
  }
817
822
  /** 列表查询的整数标量归一:数字串转数字,非法值就地报 input_invalid 而不是透传到 E10 变成 400。 */
818
823
  function listInteger(key, value) {
@@ -827,6 +832,8 @@ function listInteger(key, value) {
827
832
  function normalizeListField(key, value) {
828
833
  if (key === 'sreim')
829
834
  return normalizeSreim(value);
835
+ if (EPOCH_END_OF_DAY_FIELDS.has(key))
836
+ return epochSeconds(value, key, { endOfDay: true });
830
837
  if (EPOCH_FIELDS.has(key))
831
838
  return epochSeconds(value, key);
832
839
  if (INTEGER_FIELDS.has(key))
@@ -110,6 +110,46 @@ export function createMeetingHost(ctx, dependencies = {}) {
110
110
  await ensureSession();
111
111
  return sessionContext;
112
112
  }
113
+ async function download(request) {
114
+ const session = await ensureSession();
115
+ const url = new URL(request.path, session.getBaseUrl());
116
+ for (const [key, value] of Object.entries(request.query ?? {})) {
117
+ if (value !== undefined && value !== null && String(value) !== '')
118
+ url.searchParams.set(key, String(value));
119
+ }
120
+ const controller = new AbortController();
121
+ const timer = setTimeout(() => controller.abort(), request.timeoutMs ?? 60_000);
122
+ try {
123
+ const response = await (dependencies.fetch || globalThis.fetch)(url.toString(), {
124
+ headers: {
125
+ accept: '*/*',
126
+ cookie: session.cookieHeader(),
127
+ eteamsid: session.eteamsId,
128
+ 'user-agent': session.uaHeader(),
129
+ origin: session.getBaseUrl(),
130
+ },
131
+ redirect: 'manual',
132
+ signal: controller.signal,
133
+ });
134
+ if (response.status === 401 || response.status === 302) {
135
+ throw meetingAuthError('session_expired', '登录态已失效:下载需有效登录态,请重新登录后重试', { httpStatus: response.status });
136
+ }
137
+ if (response.status !== 200) {
138
+ throw new MeetingCliError('api', 'download_failed', `下载失败 HTTP ${response.status}`, {
139
+ code: response.status,
140
+ exitCode: 1,
141
+ });
142
+ }
143
+ return {
144
+ buffer: Buffer.from(await response.arrayBuffer()),
145
+ contentType: response.headers.get('content-type') ?? '',
146
+ contentDisposition: response.headers.get('content-disposition') ?? '',
147
+ };
148
+ }
149
+ finally {
150
+ clearTimeout(timer);
151
+ }
152
+ }
113
153
  async function runtime() {
114
154
  return createE10RequestRuntime(ctx, await ensureSession(), {
115
155
  interceptors: dependencies.interceptors,
@@ -117,12 +157,12 @@ export function createMeetingHost(ctx, dependencies = {}) {
117
157
  });
118
158
  }
119
159
  async function request(request) {
120
- const { method, path, query, body, operation, headers: extraHeaders = {}, timeoutMs = 30_000 } = request;
160
+ const { method, path, query, body, formData, operation, headers: extraHeaders = {}, timeoutMs = 30_000 } = request;
121
161
  assertPath(path);
122
162
  // 标准版会议接口硬性约定(standalone skill 实测):不能带 workflow 专用头
123
163
  // (Referer: /workflow/newflow 等),否则 400 系统错误;等价于 standalone
124
164
  // 执行器的 --simple-header(仅 Content-Type + Cookie,由 runtime 托管)。
125
- const resolvedMethod = method || (body === undefined ? 'GET' : 'POST');
165
+ const resolvedMethod = method || (body === undefined && formData === undefined ? 'GET' : 'POST');
126
166
  let response;
127
167
  try {
128
168
  response = await (await runtime()).requestJson({
@@ -132,6 +172,8 @@ export function createMeetingHost(ctx, dependencies = {}) {
132
172
  path,
133
173
  query: omitEmptyQueryValues(query),
134
174
  body,
175
+ // 文件上传:multipart 体由 runtime 直接交给 fetch(不设 Content-Type,交给 fetch 生成 boundary)
176
+ ...(formData ? { formData } : {}),
135
177
  headers: { ...extraHeaders },
136
178
  // 会议接口存在裸数字长 ID(如 meetingExtend.mtId / creater),超 2^53 会被
137
179
  // JSON.parse 舍入;开启大整数保护后按字符串保留,保证 ID 回查不失真。
@@ -181,5 +223,5 @@ export function createMeetingHost(ctx, dependencies = {}) {
181
223
  }
182
224
  return response.value;
183
225
  }
184
- return { request, getSession };
226
+ return { request, getSession, download };
185
227
  }