@xopcai/xopc 0.0.14 → 0.0.16
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/extensions/feishu/src/adapters/onboard-cli.d.ts +7 -0
- package/dist/extensions/feishu/src/adapters/onboard-cli.js +432 -0
- package/dist/extensions/feishu/src/adapters/onboard-cli.js.map +1 -0
- package/dist/extensions/feishu/src/auth/pairing.d.ts +7 -0
- package/dist/extensions/feishu/src/auth/pairing.js +45 -0
- package/dist/extensions/feishu/src/auth/pairing.js.map +1 -0
- package/dist/extensions/feishu/src/auth/paths.d.ts +2 -0
- package/dist/extensions/feishu/src/auth/paths.js +18 -0
- package/dist/extensions/feishu/src/auth/paths.js.map +1 -0
- package/dist/extensions/feishu/src/directory/directory-adapter.d.ts +2 -0
- package/dist/extensions/feishu/src/directory/directory-adapter.js +27 -0
- package/dist/extensions/feishu/src/directory/directory-adapter.js.map +1 -0
- package/dist/extensions/feishu/src/format.d.ts +21 -0
- package/dist/extensions/feishu/src/format.js +99 -0
- package/dist/extensions/feishu/src/format.js.map +1 -0
- package/dist/extensions/feishu/src/index.d.ts +5 -0
- package/dist/extensions/feishu/src/index.js +3 -0
- package/dist/extensions/feishu/src/outbound/actions.d.ts +51 -0
- package/dist/extensions/feishu/src/outbound/actions.js +62 -0
- package/dist/extensions/feishu/src/outbound/actions.js.map +1 -0
- package/dist/extensions/feishu/src/outbound/media-load.d.ts +12 -0
- package/dist/extensions/feishu/src/outbound/media-load.js +125 -0
- package/dist/extensions/feishu/src/outbound/media-load.js.map +1 -0
- package/dist/extensions/feishu/src/outbound/outbound-adapter.d.ts +2 -0
- package/dist/extensions/feishu/src/outbound/outbound-adapter.js +201 -0
- package/dist/extensions/feishu/src/outbound/outbound-adapter.js.map +1 -0
- package/dist/extensions/feishu/src/plugin.d.ts +70 -0
- package/dist/extensions/feishu/src/plugin.js +313 -0
- package/dist/extensions/feishu/src/plugin.js.map +1 -0
- package/dist/extensions/feishu/src/schema/config-schema.d.ts +215 -0
- package/dist/extensions/feishu/src/schema/config-schema.js +198 -0
- package/dist/extensions/feishu/src/schema/config-schema.js.map +1 -0
- package/dist/extensions/feishu/src/state/accounts.d.ts +38 -0
- package/dist/extensions/feishu/src/state/accounts.js +96 -0
- package/dist/extensions/feishu/src/state/accounts.js.map +1 -0
- package/dist/extensions/feishu/src/state/message-bindings.d.ts +11 -0
- package/dist/extensions/feishu/src/state/message-bindings.js +41 -0
- package/dist/extensions/feishu/src/state/message-bindings.js.map +1 -0
- package/dist/extensions/feishu/src/state/thread-bindings.js +46 -0
- package/dist/extensions/feishu/src/state/thread-bindings.js.map +1 -0
- package/dist/extensions/feishu/src/status/doctor.d.ts +2 -0
- package/dist/extensions/feishu/src/status/doctor.js +38 -0
- package/dist/extensions/feishu/src/status/doctor.js.map +1 -0
- package/dist/extensions/feishu/src/status/status-adapter.d.ts +3 -0
- package/dist/extensions/feishu/src/status/status-adapter.js +45 -0
- package/dist/extensions/feishu/src/status/status-adapter.js.map +1 -0
- package/dist/extensions/feishu/src/streaming/streaming-adapter.d.ts +3 -0
- package/dist/extensions/feishu/src/streaming/streaming-adapter.js +242 -0
- package/dist/extensions/feishu/src/streaming/streaming-adapter.js.map +1 -0
- package/dist/extensions/feishu/src/subagent-hooks.js +52 -0
- package/dist/extensions/feishu/src/subagent-hooks.js.map +1 -0
- package/dist/extensions/feishu/src/tools/docx/docx-batch-insert.js +95 -0
- package/dist/extensions/feishu/src/tools/docx/docx-batch-insert.js.map +1 -0
- package/dist/extensions/feishu/src/tools/docx/docx-color-text.js +75 -0
- package/dist/extensions/feishu/src/tools/docx/docx-color-text.js.map +1 -0
- package/dist/extensions/feishu/src/tools/docx/docx-table-ops.js +173 -0
- package/dist/extensions/feishu/src/tools/docx/docx-table-ops.js.map +1 -0
- package/dist/extensions/feishu/src/tools/docx/docx-types.js +1 -0
- package/dist/extensions/feishu/src/tools/tools.d.ts +5 -0
- package/dist/extensions/feishu/src/tools/tools.js +46 -0
- package/dist/extensions/feishu/src/tools/tools.js.map +1 -0
- package/dist/extensions/feishu/src/transport/client/client.d.ts +6 -0
- package/dist/extensions/feishu/src/transport/client/client.js +41 -0
- package/dist/extensions/feishu/src/transport/client/client.js.map +1 -0
- package/dist/extensions/feishu/src/transport/client/lark-sdk-logger.d.ts +13 -0
- package/dist/extensions/feishu/src/transport/client/lark-sdk-logger.js +104 -0
- package/dist/extensions/feishu/src/transport/client/lark-sdk-logger.js.map +1 -0
- package/dist/extensions/feishu/src/transport/reliability/dedupe.d.ts +7 -0
- package/dist/extensions/feishu/src/transport/reliability/dedupe.js +30 -0
- package/dist/extensions/feishu/src/transport/reliability/dedupe.js.map +1 -0
- package/dist/extensions/feishu/src/transport/socket-mode/monitor.d.ts +19 -0
- package/dist/extensions/feishu/src/transport/socket-mode/monitor.js +326 -0
- package/dist/extensions/feishu/src/transport/socket-mode/monitor.js.map +1 -0
- package/dist/extensions/feishu/src/transport/socket-mode/retry.d.ts +1 -0
- package/dist/extensions/feishu/src/transport/socket-mode/retry.js +10 -0
- package/dist/extensions/feishu/src/transport/socket-mode/retry.js.map +1 -0
- package/dist/extensions/feishu/src/transport/text/mentions.d.ts +1 -0
- package/dist/extensions/feishu/src/transport/text/mentions.js +9 -0
- package/dist/extensions/feishu/src/transport/text/mentions.js.map +1 -0
- package/dist/extensions/feishu/src/transport/webhook/monitor.d.ts +19 -0
- package/dist/extensions/feishu/src/transport/webhook/monitor.js +271 -0
- package/dist/extensions/feishu/src/transport/webhook/monitor.js.map +1 -0
- package/dist/extensions/feishu/src/ui/config-surface.d.ts +2 -0
- package/dist/extensions/feishu/src/ui/config-surface.js +6 -0
- package/dist/extensions/feishu/src/ui/config-surface.js.map +1 -0
- package/dist/extensions/feishu/xopc.extension.json +18 -0
- package/dist/extensions/telegram/xopc.extension.json +20 -0
- package/dist/extensions/weixin/xopc.extension.json +17 -0
- package/dist/gateway/static/root/assets/{agents-C2blSFQk.js → agents-Dy5cGVVQ.js} +2 -2
- package/dist/gateway/static/root/assets/{agents-C2blSFQk.js.map → agents-Dy5cGVVQ.js.map} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-Dg7InQ41.js → apps-page-BOpDR0Lz.js} +2 -2
- package/dist/gateway/static/root/assets/{apps-page-Dg7InQ41.js.map → apps-page-BOpDR0Lz.js.map} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-CrCesccB.js +9 -0
- package/dist/gateway/static/root/assets/channels-settings-CrCesccB.js.map +1 -0
- package/dist/gateway/static/root/assets/{cron-page-B-7O4_QQ.js → cron-page-B_XY0gPt.js} +2 -2
- package/dist/gateway/static/root/assets/{cron-page-B-7O4_QQ.js.map → cron-page-B_XY0gPt.js.map} +1 -1
- package/dist/gateway/static/root/assets/{cron-utils-DvRPM814.js → cron-utils-BYdnLwhl.js} +2 -2
- package/dist/gateway/static/root/assets/{cron-utils-DvRPM814.js.map → cron-utils-BYdnLwhl.js.map} +1 -1
- package/dist/gateway/static/root/assets/{dist-DYzyRkRh.js → dist-DvaA5uNp.js} +2 -2
- package/dist/gateway/static/root/assets/{dist-DYzyRkRh.js.map → dist-DvaA5uNp.js.map} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DV-NwlaY.js → extension-debug-page-CPSk7gFW.js} +2 -2
- package/dist/gateway/static/root/assets/{extension-debug-page-DV-NwlaY.js.map → extension-debug-page-CPSk7gFW.js.map} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-UUKLJwpo.js → extension-page-COdbk9I6.js} +2 -2
- package/dist/gateway/static/root/assets/{extension-page-UUKLJwpo.js.map → extension-page-COdbk9I6.js.map} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-R4VlbZOj.js → extension-settings-page-BlEz2Ily.js} +2 -2
- package/dist/gateway/static/root/assets/{extension-settings-page-R4VlbZOj.js.map → extension-settings-page-BlEz2Ily.js.map} +1 -1
- package/dist/gateway/static/root/assets/index-BQNdJlkw.css +1 -0
- package/dist/gateway/static/root/assets/index-tm9ZY35l.js +144 -0
- package/dist/gateway/static/root/assets/{index-BCVqNi5T.js.map → index-tm9ZY35l.js.map} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-BgUDjMge.js → logs-page-LSa0jmLO.js} +2 -2
- package/dist/gateway/static/root/assets/{logs-page-BgUDjMge.js.map → logs-page-LSa0jmLO.js.map} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-cn2fi_V3.js +2 -0
- package/dist/gateway/static/root/assets/sessions-page-cn2fi_V3.js.map +1 -0
- package/dist/gateway/static/root/assets/{settings-page-Doa_lzdW.js → settings-page-CyHd5szQ.js} +2 -2
- package/dist/gateway/static/root/assets/{settings-page-Doa_lzdW.js.map → settings-page-CyHd5szQ.js.map} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-BdNqg2NG.js → skills-page-irjxwW9u.js} +2 -2
- package/dist/gateway/static/root/assets/{skills-page-BdNqg2NG.js.map → skills-page-irjxwW9u.js.map} +1 -1
- package/dist/gateway/static/root/channel-icons/feishu.svg +12 -0
- package/dist/gateway/static/root/channel-icons/lark.svg +12 -0
- package/dist/gateway/static/root/channel-icons/telegram.svg +1 -0
- package/dist/gateway/static/root/channel-icons/wechat.svg +1 -0
- package/dist/gateway/static/root/channel-icons/weixin.svg +1 -0
- package/dist/gateway/static/root/index.html +2 -2
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +1 -0
- package/dist/src/agent/agent-manager.js +1 -0
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/service.js +3 -0
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/tools/delegate-tool.d.ts +8 -0
- package/dist/src/agent/tools/delegate-tool.js +60 -2
- package/dist/src/agent/tools/delegate-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.d.ts +1 -0
- package/dist/src/agent/tools/factory.js +2 -0
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/channels/envelope-timestamp.d.ts +5 -0
- package/dist/src/channels/envelope-timestamp.js +10 -1
- package/dist/src/channels/envelope-timestamp.js.map +1 -1
- package/dist/src/channels/feishu/index.d.ts +5 -0
- package/dist/src/channels/feishu/index.js +4 -0
- package/dist/src/chat-commands/types.d.ts +1 -1
- package/dist/src/extensions/types/hooks.d.ts +46 -1
- package/dist/src/extensions/types/hooks.js +3 -0
- package/dist/src/extensions/types/hooks.js.map +1 -1
- package/dist/src/gateway/service.js +1 -1
- package/dist/src/generated/bundled-channel-plugins.d.ts +2 -1
- package/dist/src/generated/bundled-channel-plugins.js +8 -2
- package/dist/src/generated/bundled-channel-plugins.js.map +1 -1
- package/dist/src/providers/env-keys.js +1 -0
- package/dist/src/providers/env-keys.js.map +1 -1
- package/dist/src/providers/index.js +5 -0
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/session/session-title.js +2 -1
- package/dist/src/session/session-title.js.map +1 -1
- package/package.json +2 -2
- package/dist/gateway/static/root/assets/channels-settings-CHOL7G_P.js +0 -9
- package/dist/gateway/static/root/assets/channels-settings-CHOL7G_P.js.map +0 -1
- package/dist/gateway/static/root/assets/index-BCVqNi5T.js +0 -144
- package/dist/gateway/static/root/assets/index-XbYityMf.css +0 -1
- package/dist/gateway/static/root/assets/sessions-page-L2VUocA4.js +0 -2
- package/dist/gateway/static/root/assets/sessions-page-L2VUocA4.js.map +0 -1
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
//#region extensions/feishu/src/tools/docx/docx-table-ops.ts
|
|
2
|
+
const MIN_COLUMN_WIDTH = 50;
|
|
3
|
+
const MAX_COLUMN_WIDTH = 400;
|
|
4
|
+
const DEFAULT_TABLE_WIDTH = 730;
|
|
5
|
+
function normalizeChildBlockIds(children) {
|
|
6
|
+
if (Array.isArray(children)) return children;
|
|
7
|
+
return typeof children === "string" ? [children] : [];
|
|
8
|
+
}
|
|
9
|
+
function omitParentId(block) {
|
|
10
|
+
const cleanBlock = { ...block };
|
|
11
|
+
delete cleanBlock.parent_id;
|
|
12
|
+
return cleanBlock;
|
|
13
|
+
}
|
|
14
|
+
function createDescendantTable(table, adaptiveWidths) {
|
|
15
|
+
const { row_size, column_size } = table.property || {};
|
|
16
|
+
return { property: {
|
|
17
|
+
row_size,
|
|
18
|
+
column_size,
|
|
19
|
+
...adaptiveWidths?.length ? { column_width: adaptiveWidths } : {}
|
|
20
|
+
} };
|
|
21
|
+
}
|
|
22
|
+
function calculateAdaptiveColumnWidths(blocks, tableBlockId) {
|
|
23
|
+
const tableBlock = blocks.find((b) => b.block_id === tableBlockId && b.block_type === 31);
|
|
24
|
+
if (!tableBlock?.table?.property) return [];
|
|
25
|
+
const { row_size, column_size, column_width: originalWidths } = tableBlock.table.property;
|
|
26
|
+
if (!row_size || !column_size) return [];
|
|
27
|
+
const totalWidth = originalWidths && originalWidths.length > 0 ? originalWidths.reduce((a, b) => a + b, 0) : DEFAULT_TABLE_WIDTH;
|
|
28
|
+
const cellIds = normalizeChildBlockIds(tableBlock.children);
|
|
29
|
+
const blockMap = /* @__PURE__ */ new Map();
|
|
30
|
+
for (const block of blocks) if (block.block_id) blockMap.set(block.block_id, block);
|
|
31
|
+
function getCellText(cellId) {
|
|
32
|
+
const cell = blockMap.get(cellId);
|
|
33
|
+
let text = "";
|
|
34
|
+
const childIds = normalizeChildBlockIds(cell?.children);
|
|
35
|
+
for (const childId of childIds) {
|
|
36
|
+
const child = blockMap.get(childId);
|
|
37
|
+
if (child?.text?.elements) {
|
|
38
|
+
for (const elem of child.text.elements) if (elem.text_run?.content) text += elem.text_run.content;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return text;
|
|
42
|
+
}
|
|
43
|
+
function getWeightedLength(text) {
|
|
44
|
+
return Array.from(text).reduce((sum, char) => sum + (char.charCodeAt(0) > 255 ? 2 : 1), 0);
|
|
45
|
+
}
|
|
46
|
+
const maxLengths = Array.from({ length: column_size }, () => 0);
|
|
47
|
+
for (let row = 0; row < row_size; row++) for (let col = 0; col < column_size; col++) {
|
|
48
|
+
const cellId = cellIds[row * column_size + col];
|
|
49
|
+
if (!cellId) continue;
|
|
50
|
+
const length = getWeightedLength(getCellText(cellId));
|
|
51
|
+
maxLengths[col] = Math.max(maxLengths[col], length);
|
|
52
|
+
}
|
|
53
|
+
const totalLength = maxLengths.reduce((a, b) => a + b, 0);
|
|
54
|
+
if (totalLength === 0) {
|
|
55
|
+
const equalWidth = Math.max(MIN_COLUMN_WIDTH, Math.min(MAX_COLUMN_WIDTH, Math.floor(totalWidth / column_size)));
|
|
56
|
+
return Array.from({ length: column_size }, () => equalWidth);
|
|
57
|
+
}
|
|
58
|
+
let widths = maxLengths.map((len) => Math.round(len / totalLength * totalWidth));
|
|
59
|
+
widths = widths.map((w) => Math.max(MIN_COLUMN_WIDTH, Math.min(MAX_COLUMN_WIDTH, w)));
|
|
60
|
+
let remaining = totalWidth - widths.reduce((a, b) => a + b, 0);
|
|
61
|
+
while (remaining > 0) {
|
|
62
|
+
const growable = widths.map((w, i) => w < MAX_COLUMN_WIDTH ? i : -1).filter((i) => i >= 0);
|
|
63
|
+
if (growable.length === 0) break;
|
|
64
|
+
const perColumn = Math.floor(remaining / growable.length);
|
|
65
|
+
if (perColumn === 0) break;
|
|
66
|
+
for (const i of growable) {
|
|
67
|
+
const add = Math.min(perColumn, MAX_COLUMN_WIDTH - widths[i]);
|
|
68
|
+
widths[i] += add;
|
|
69
|
+
remaining -= add;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return widths;
|
|
73
|
+
}
|
|
74
|
+
function cleanBlocksForDescendant(blocks) {
|
|
75
|
+
const tableWidths = /* @__PURE__ */ new Map();
|
|
76
|
+
for (const block of blocks) if (block.block_type === 31 && block.block_id) tableWidths.set(block.block_id, calculateAdaptiveColumnWidths(blocks, block.block_id));
|
|
77
|
+
return blocks.map((block) => {
|
|
78
|
+
const cleanBlock = omitParentId(block);
|
|
79
|
+
if (cleanBlock.block_type === 32 && typeof cleanBlock.children === "string") cleanBlock.children = [cleanBlock.children];
|
|
80
|
+
if (cleanBlock.block_type === 31 && cleanBlock.table) {
|
|
81
|
+
const adaptive = block.block_id ? tableWidths.get(block.block_id) : void 0;
|
|
82
|
+
cleanBlock.table = createDescendantTable(cleanBlock.table, adaptive);
|
|
83
|
+
}
|
|
84
|
+
return cleanBlock;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
async function insertTableRow(client, docToken, blockId, rowIndex = -1) {
|
|
88
|
+
const res = await client.docx.documentBlock.patch({
|
|
89
|
+
path: {
|
|
90
|
+
document_id: docToken,
|
|
91
|
+
block_id: blockId
|
|
92
|
+
},
|
|
93
|
+
data: { insert_table_row: { row_index: rowIndex } }
|
|
94
|
+
});
|
|
95
|
+
if (res.code !== 0) throw new Error(res.msg);
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
block: res.data?.block
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function insertTableColumn(client, docToken, blockId, columnIndex = -1) {
|
|
102
|
+
const res = await client.docx.documentBlock.patch({
|
|
103
|
+
path: {
|
|
104
|
+
document_id: docToken,
|
|
105
|
+
block_id: blockId
|
|
106
|
+
},
|
|
107
|
+
data: { insert_table_column: { column_index: columnIndex } }
|
|
108
|
+
});
|
|
109
|
+
if (res.code !== 0) throw new Error(res.msg);
|
|
110
|
+
return {
|
|
111
|
+
success: true,
|
|
112
|
+
block: res.data?.block
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async function deleteTableRows(client, docToken, blockId, rowStart, rowCount = 1) {
|
|
116
|
+
const res = await client.docx.documentBlock.patch({
|
|
117
|
+
path: {
|
|
118
|
+
document_id: docToken,
|
|
119
|
+
block_id: blockId
|
|
120
|
+
},
|
|
121
|
+
data: { delete_table_rows: {
|
|
122
|
+
row_start_index: rowStart,
|
|
123
|
+
row_end_index: rowStart + rowCount
|
|
124
|
+
} }
|
|
125
|
+
});
|
|
126
|
+
if (res.code !== 0) throw new Error(res.msg);
|
|
127
|
+
return {
|
|
128
|
+
success: true,
|
|
129
|
+
rows_deleted: rowCount,
|
|
130
|
+
block: res.data?.block
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
async function deleteTableColumns(client, docToken, blockId, columnStart, columnCount = 1) {
|
|
134
|
+
const res = await client.docx.documentBlock.patch({
|
|
135
|
+
path: {
|
|
136
|
+
document_id: docToken,
|
|
137
|
+
block_id: blockId
|
|
138
|
+
},
|
|
139
|
+
data: { delete_table_columns: {
|
|
140
|
+
column_start_index: columnStart,
|
|
141
|
+
column_end_index: columnStart + columnCount
|
|
142
|
+
} }
|
|
143
|
+
});
|
|
144
|
+
if (res.code !== 0) throw new Error(res.msg);
|
|
145
|
+
return {
|
|
146
|
+
success: true,
|
|
147
|
+
columns_deleted: columnCount,
|
|
148
|
+
block: res.data?.block
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
async function mergeTableCells(client, docToken, blockId, rowStart, rowEnd, columnStart, columnEnd) {
|
|
152
|
+
const res = await client.docx.documentBlock.patch({
|
|
153
|
+
path: {
|
|
154
|
+
document_id: docToken,
|
|
155
|
+
block_id: blockId
|
|
156
|
+
},
|
|
157
|
+
data: { merge_table_cells: {
|
|
158
|
+
row_start_index: rowStart,
|
|
159
|
+
row_end_index: rowEnd,
|
|
160
|
+
column_start_index: columnStart,
|
|
161
|
+
column_end_index: columnEnd
|
|
162
|
+
} }
|
|
163
|
+
});
|
|
164
|
+
if (res.code !== 0) throw new Error(res.msg);
|
|
165
|
+
return {
|
|
166
|
+
success: true,
|
|
167
|
+
block: res.data?.block
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
//#endregion
|
|
171
|
+
export { calculateAdaptiveColumnWidths, cleanBlocksForDescendant, deleteTableColumns, deleteTableRows, insertTableColumn, insertTableRow, mergeTableCells };
|
|
172
|
+
|
|
173
|
+
//# sourceMappingURL=docx-table-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docx-table-ops.js","names":[],"sources":["../../../../../../extensions/feishu/src/tools/docx/docx-table-ops.ts"],"sourcesContent":["import type * as Lark from '@larksuiteoapi/node-sdk';\n\nimport type { FeishuBlockTable, FeishuDocxBlock } from './docx-types.js';\n\nconst MIN_COLUMN_WIDTH = 50;\nconst MAX_COLUMN_WIDTH = 400;\nconst DEFAULT_TABLE_WIDTH = 730;\n\nfunction normalizeChildBlockIds(children: string[] | string | undefined): string[] {\n if (Array.isArray(children)) return children;\n return typeof children === 'string' ? [children] : [];\n}\n\nfunction omitParentId(block: FeishuDocxBlock): FeishuDocxBlock {\n const cleanBlock = { ...block };\n delete cleanBlock.parent_id;\n return cleanBlock;\n}\n\nfunction createDescendantTable(table: FeishuBlockTable, adaptiveWidths: number[] | undefined): FeishuBlockTable {\n const { row_size, column_size } = table.property || {};\n return {\n property: {\n row_size,\n column_size,\n ...(adaptiveWidths?.length ? { column_width: adaptiveWidths } : {}),\n },\n };\n}\n\nexport function calculateAdaptiveColumnWidths(blocks: FeishuDocxBlock[], tableBlockId: string): number[] {\n const tableBlock = blocks.find((b) => b.block_id === tableBlockId && b.block_type === 31);\n if (!tableBlock?.table?.property) return [];\n\n const { row_size, column_size, column_width: originalWidths } = tableBlock.table.property;\n if (!row_size || !column_size) return [];\n\n const totalWidth =\n originalWidths && originalWidths.length > 0\n ? originalWidths.reduce((a: number, b: number) => a + b, 0)\n : DEFAULT_TABLE_WIDTH;\n\n const cellIds = normalizeChildBlockIds(tableBlock.children);\n const blockMap = new Map<string, FeishuDocxBlock>();\n for (const block of blocks) {\n if (block.block_id) blockMap.set(block.block_id, block);\n }\n\n function getCellText(cellId: string): string {\n const cell = blockMap.get(cellId);\n let text = '';\n const childIds = normalizeChildBlockIds(cell?.children as any);\n for (const childId of childIds) {\n const child = blockMap.get(childId);\n if (child?.text?.elements) {\n for (const elem of child.text.elements) {\n if (elem.text_run?.content) {\n text += elem.text_run.content;\n }\n }\n }\n }\n return text;\n }\n\n function getWeightedLength(text: string): number {\n return Array.from(text).reduce((sum, char) => sum + (char.charCodeAt(0) > 255 ? 2 : 1), 0);\n }\n\n const maxLengths = Array.from({ length: column_size }, () => 0);\n for (let row = 0; row < row_size; row++) {\n for (let col = 0; col < column_size; col++) {\n const cellIndex = row * column_size + col;\n const cellId = cellIds[cellIndex];\n if (!cellId) continue;\n const content = getCellText(cellId);\n const length = getWeightedLength(content);\n maxLengths[col] = Math.max(maxLengths[col], length);\n }\n }\n\n const totalLength = maxLengths.reduce((a, b) => a + b, 0);\n if (totalLength === 0) {\n const equalWidth = Math.max(\n MIN_COLUMN_WIDTH,\n Math.min(MAX_COLUMN_WIDTH, Math.floor(totalWidth / column_size)),\n );\n return Array.from({ length: column_size }, () => equalWidth);\n }\n\n let widths = maxLengths.map((len) => Math.round((len / totalLength) * totalWidth));\n widths = widths.map((w) => Math.max(MIN_COLUMN_WIDTH, Math.min(MAX_COLUMN_WIDTH, w)));\n\n let remaining = totalWidth - widths.reduce((a, b) => a + b, 0);\n while (remaining > 0) {\n const growable = widths.map((w, i) => (w < MAX_COLUMN_WIDTH ? i : -1)).filter((i) => i >= 0);\n if (growable.length === 0) break;\n const perColumn = Math.floor(remaining / growable.length);\n if (perColumn === 0) break;\n for (const i of growable) {\n const add = Math.min(perColumn, MAX_COLUMN_WIDTH - widths[i]!);\n widths[i]! += add;\n remaining -= add;\n }\n }\n\n return widths;\n}\n\nexport function cleanBlocksForDescendant(blocks: FeishuDocxBlock[]): FeishuDocxBlock[] {\n const tableWidths = new Map<string, number[]>();\n for (const block of blocks) {\n if (block.block_type === 31 && block.block_id) {\n tableWidths.set(block.block_id, calculateAdaptiveColumnWidths(blocks, block.block_id));\n }\n }\n\n return blocks.map((block) => {\n const cleanBlock = omitParentId(block);\n if (cleanBlock.block_type === 32 && typeof cleanBlock.children === 'string') {\n cleanBlock.children = [cleanBlock.children];\n }\n if (cleanBlock.block_type === 31 && cleanBlock.table) {\n const adaptive = block.block_id ? tableWidths.get(block.block_id) : undefined;\n cleanBlock.table = createDescendantTable(cleanBlock.table, adaptive);\n }\n return cleanBlock;\n });\n}\n\nexport async function insertTableRow(client: Lark.Client, docToken: string, blockId: string, rowIndex: number = -1) {\n const res = await client.docx.documentBlock.patch({\n path: { document_id: docToken, block_id: blockId },\n data: { insert_table_row: { row_index: rowIndex } },\n });\n if (res.code !== 0) throw new Error(res.msg);\n return { success: true, block: res.data?.block };\n}\n\nexport async function insertTableColumn(\n client: Lark.Client,\n docToken: string,\n blockId: string,\n columnIndex: number = -1,\n) {\n const res = await client.docx.documentBlock.patch({\n path: { document_id: docToken, block_id: blockId },\n data: { insert_table_column: { column_index: columnIndex } },\n });\n if (res.code !== 0) throw new Error(res.msg);\n return { success: true, block: res.data?.block };\n}\n\nexport async function deleteTableRows(\n client: Lark.Client,\n docToken: string,\n blockId: string,\n rowStart: number,\n rowCount: number = 1,\n) {\n const res = await client.docx.documentBlock.patch({\n path: { document_id: docToken, block_id: blockId },\n data: { delete_table_rows: { row_start_index: rowStart, row_end_index: rowStart + rowCount } },\n });\n if (res.code !== 0) throw new Error(res.msg);\n return { success: true, rows_deleted: rowCount, block: res.data?.block };\n}\n\nexport async function deleteTableColumns(\n client: Lark.Client,\n docToken: string,\n blockId: string,\n columnStart: number,\n columnCount: number = 1,\n) {\n const res = await client.docx.documentBlock.patch({\n path: { document_id: docToken, block_id: blockId },\n data: { delete_table_columns: { column_start_index: columnStart, column_end_index: columnStart + columnCount } },\n });\n if (res.code !== 0) throw new Error(res.msg);\n return { success: true, columns_deleted: columnCount, block: res.data?.block };\n}\n\nexport async function mergeTableCells(\n client: Lark.Client,\n docToken: string,\n blockId: string,\n rowStart: number,\n rowEnd: number,\n columnStart: number,\n columnEnd: number,\n) {\n const res = await client.docx.documentBlock.patch({\n path: { document_id: docToken, block_id: blockId },\n data: {\n merge_table_cells: {\n row_start_index: rowStart,\n row_end_index: rowEnd,\n column_start_index: columnStart,\n column_end_index: columnEnd,\n },\n },\n });\n if (res.code !== 0) throw new Error(res.msg);\n return { success: true, block: res.data?.block };\n}\n\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { resolveFeishuAccount } from "../state/accounts.js";
|
|
2
|
+
import { createFeishuClient } from "../transport/client/client.js";
|
|
3
|
+
//#region extensions/feishu/src/tools/tools.ts
|
|
4
|
+
async function feishuWhoAmI(params) {
|
|
5
|
+
const account = resolveFeishuAccount(params.cfg, params.accountId ?? "default");
|
|
6
|
+
if (!account.configured) throw new Error("Feishu account not configured");
|
|
7
|
+
const { api } = createFeishuClient(account);
|
|
8
|
+
const res = await api.auth.tenantAccessToken.internal({ data: {
|
|
9
|
+
app_id: account.appId,
|
|
10
|
+
app_secret: account.appSecret
|
|
11
|
+
} });
|
|
12
|
+
const token = res?.tenant_access_token || res?.data?.tenant_access_token || "";
|
|
13
|
+
const probes = {};
|
|
14
|
+
const tryProbe = async (name, fn) => {
|
|
15
|
+
try {
|
|
16
|
+
await fn();
|
|
17
|
+
probes[name] = { ok: true };
|
|
18
|
+
} catch (err) {
|
|
19
|
+
probes[name] = {
|
|
20
|
+
ok: false,
|
|
21
|
+
error: err instanceof Error ? err.message : String(err)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
await tryProbe("im.message.read", async () => {
|
|
26
|
+
await api.im.v1.chat.list({ params: { page_size: 1 } });
|
|
27
|
+
});
|
|
28
|
+
await tryProbe("drive.files.list", async () => {
|
|
29
|
+
await api.drive.v1.file.list({ params: { page_size: 1 } });
|
|
30
|
+
});
|
|
31
|
+
await tryProbe("wiki.spaces.list", async () => {
|
|
32
|
+
await api.wiki.v2.space.list({ params: { page_size: 1 } });
|
|
33
|
+
});
|
|
34
|
+
await tryProbe("bitable.apps.list", async () => {
|
|
35
|
+
await api.bitable.v1.app.list({ params: { page_size: 1 } });
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
ok: true,
|
|
39
|
+
tenantAccessToken: Boolean(token),
|
|
40
|
+
probes
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { feishuWhoAmI };
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","names":[],"sources":["../../../../../extensions/feishu/src/tools/tools.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/schema.js';\n\nimport { resolveFeishuAccount } from '../state/accounts.js';\nimport { createFeishuClient } from '../transport/client/client.js';\n\nexport async function feishuWhoAmI(params: { cfg: Config; accountId?: string }): Promise<any> {\n const account = resolveFeishuAccount(params.cfg, params.accountId ?? 'default');\n if (!account.configured) {\n throw new Error('Feishu account not configured');\n }\n const { api } = createFeishuClient(account);\n const res = await (api as any).auth.tenantAccessToken.internal({\n data: {\n app_id: account.appId,\n app_secret: account.appSecret,\n },\n });\n const token = res?.tenant_access_token || res?.data?.tenant_access_token || '';\n\n // Probe a few representative APIs to surface which permission buckets are working.\n // Keep it cheap: one lightweight call per area, each isolated so partial failures still return signal.\n const probes: Record<string, { ok: boolean; error?: string }> = {};\n\n const tryProbe = async (name: string, fn: () => Promise<void>) => {\n try {\n await fn();\n probes[name] = { ok: true };\n } catch (err) {\n probes[name] = { ok: false, error: err instanceof Error ? err.message : String(err) };\n }\n };\n\n await tryProbe('im.message.read', async () => {\n // A harmless endpoint that validates the token; will still fail if permissions missing.\n await (api as any).im.v1.chat.list({ params: { page_size: 1 } });\n });\n\n await tryProbe('drive.files.list', async () => {\n await (api as any).drive.v1.file.list({ params: { page_size: 1 } });\n });\n\n await tryProbe('wiki.spaces.list', async () => {\n await (api as any).wiki.v2.space.list({ params: { page_size: 1 } });\n });\n\n await tryProbe('bitable.apps.list', async () => {\n await (api as any).bitable.v1.app.list({ params: { page_size: 1 } });\n });\n\n return {\n ok: true,\n tenantAccessToken: Boolean(token),\n probes,\n };\n}\n\n"],"mappings":";;;AAKA,eAAsB,aAAa,QAA2D;CAC5F,MAAM,UAAU,qBAAqB,OAAO,KAAK,OAAO,aAAa,UAAU;AAC/E,KAAI,CAAC,QAAQ,WACX,OAAM,IAAI,MAAM,gCAAgC;CAElD,MAAM,EAAE,QAAQ,mBAAmB,QAAQ;CAC3C,MAAM,MAAM,MAAO,IAAY,KAAK,kBAAkB,SAAS,EAC7D,MAAM;EACJ,QAAQ,QAAQ;EAChB,YAAY,QAAQ;EACrB,EACF,CAAC;CACF,MAAM,QAAQ,KAAK,uBAAuB,KAAK,MAAM,uBAAuB;CAI5E,MAAM,SAA0D,EAAE;CAElE,MAAM,WAAW,OAAO,MAAc,OAA4B;AAChE,MAAI;AACF,SAAM,IAAI;AACV,UAAO,QAAQ,EAAE,IAAI,MAAM;WACpB,KAAK;AACZ,UAAO,QAAQ;IAAE,IAAI;IAAO,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;IAAE;;;AAIzF,OAAM,SAAS,mBAAmB,YAAY;AAE5C,QAAO,IAAY,GAAG,GAAG,KAAK,KAAK,EAAE,QAAQ,EAAE,WAAW,GAAG,EAAE,CAAC;GAChE;AAEF,OAAM,SAAS,oBAAoB,YAAY;AAC7C,QAAO,IAAY,MAAM,GAAG,KAAK,KAAK,EAAE,QAAQ,EAAE,WAAW,GAAG,EAAE,CAAC;GACnE;AAEF,OAAM,SAAS,oBAAoB,YAAY;AAC7C,QAAO,IAAY,KAAK,GAAG,MAAM,KAAK,EAAE,QAAQ,EAAE,WAAW,GAAG,EAAE,CAAC;GACnE;AAEF,OAAM,SAAS,qBAAqB,YAAY;AAC9C,QAAO,IAAY,QAAQ,GAAG,IAAI,KAAK,EAAE,QAAQ,EAAE,WAAW,GAAG,EAAE,CAAC;GACpE;AAEF,QAAO;EACL,IAAI;EACJ,mBAAmB,QAAQ,MAAM;EACjC;EACD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createFeishuLarkSdkPinoLogger } from "./lark-sdk-logger.js";
|
|
2
|
+
import lark from "@larksuiteoapi/node-sdk";
|
|
3
|
+
//#region extensions/feishu/src/transport/client/client.ts
|
|
4
|
+
function createFeishuClient(account) {
|
|
5
|
+
const l = lark;
|
|
6
|
+
const sdkLogger = createFeishuLarkSdkPinoLogger(account.accountId);
|
|
7
|
+
const apiBaseUrl = resolveFeishuBaseUrl(account.domain);
|
|
8
|
+
const api = new l.Client({
|
|
9
|
+
appId: account.appId,
|
|
10
|
+
appSecret: account.appSecret,
|
|
11
|
+
logger: sdkLogger,
|
|
12
|
+
loggerLevel: l.LoggerLevel.info,
|
|
13
|
+
...apiBaseUrl ? { baseURL: apiBaseUrl } : {}
|
|
14
|
+
});
|
|
15
|
+
const dispatcher = new l.EventDispatcher({
|
|
16
|
+
verifyChallenge: false,
|
|
17
|
+
logger: sdkLogger,
|
|
18
|
+
loggerLevel: l.LoggerLevel.info
|
|
19
|
+
});
|
|
20
|
+
return {
|
|
21
|
+
wsClient: new l.WSClient({
|
|
22
|
+
appId: account.appId,
|
|
23
|
+
appSecret: account.appSecret,
|
|
24
|
+
eventDispatcher: dispatcher,
|
|
25
|
+
logger: sdkLogger,
|
|
26
|
+
loggerLevel: l.LoggerLevel.info,
|
|
27
|
+
...apiBaseUrl ? { baseURL: apiBaseUrl } : {}
|
|
28
|
+
}),
|
|
29
|
+
dispatcher,
|
|
30
|
+
api
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function resolveFeishuBaseUrl(domain) {
|
|
34
|
+
if (domain === "feishu") return "https://open.feishu.cn";
|
|
35
|
+
if (domain === "lark") return "https://open.larksuite.com";
|
|
36
|
+
if (domain && domain.startsWith("https://")) return domain;
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
export { createFeishuClient };
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../../../../../../extensions/feishu/src/transport/client/client.ts"],"sourcesContent":["import lark from '@larksuiteoapi/node-sdk';\n\nimport type { ResolvedFeishuAccount } from '../../state/accounts.js';\nimport { createFeishuLarkSdkPinoLogger } from './lark-sdk-logger.js';\n\nexport function createFeishuClient(account: ResolvedFeishuAccount): {\n wsClient: any;\n dispatcher: any;\n api: any;\n} {\n const l = lark as any;\n const sdkLogger = createFeishuLarkSdkPinoLogger(account.accountId);\n\n const apiBaseUrl = resolveFeishuBaseUrl(account.domain);\n\n const api = new l.Client({\n appId: account.appId,\n appSecret: account.appSecret,\n logger: sdkLogger,\n loggerLevel: l.LoggerLevel.info,\n ...(apiBaseUrl ? { baseURL: apiBaseUrl } : {}),\n });\n\n const dispatcher = new l.EventDispatcher({ verifyChallenge: false, logger: sdkLogger, loggerLevel: l.LoggerLevel.info } as any);\n const wsClient = new l.WSClient({\n appId: account.appId,\n appSecret: account.appSecret,\n eventDispatcher: dispatcher,\n logger: sdkLogger,\n loggerLevel: l.LoggerLevel.info,\n ...(apiBaseUrl ? { baseURL: apiBaseUrl } : {}),\n });\n\n return { wsClient, dispatcher, api };\n}\n\nfunction resolveFeishuBaseUrl(domain: string): string | undefined {\n if (domain === 'feishu') {\n return 'https://open.feishu.cn';\n }\n if (domain === 'lark') {\n return 'https://open.larksuite.com';\n }\n if (domain && domain.startsWith('https://')) {\n return domain;\n }\n return undefined;\n}\n\n"],"mappings":";;;AAKA,SAAgB,mBAAmB,SAIjC;CACA,MAAM,IAAI;CACV,MAAM,YAAY,8BAA8B,QAAQ,UAAU;CAElE,MAAM,aAAa,qBAAqB,QAAQ,OAAO;CAEvD,MAAM,MAAM,IAAI,EAAE,OAAO;EACvB,OAAO,QAAQ;EACf,WAAW,QAAQ;EACnB,QAAQ;EACR,aAAa,EAAE,YAAY;EAC3B,GAAI,aAAa,EAAE,SAAS,YAAY,GAAG,EAAE;EAC9C,CAAC;CAEF,MAAM,aAAa,IAAI,EAAE,gBAAgB;EAAE,iBAAiB;EAAO,QAAQ;EAAW,aAAa,EAAE,YAAY;EAAM,CAAQ;AAU/H,QAAO;EAAE,UAAA,IATY,EAAE,SAAS;GAC9B,OAAO,QAAQ;GACf,WAAW,QAAQ;GACnB,iBAAiB;GACjB,QAAQ;GACR,aAAa,EAAE,YAAY;GAC3B,GAAI,aAAa,EAAE,SAAS,YAAY,GAAG,EAAE;GAC9C,CAEgB;EAAE;EAAY;EAAK;;AAGtC,SAAS,qBAAqB,QAAoC;AAChE,KAAI,WAAW,SACb,QAAO;AAET,KAAI,WAAW,OACb,QAAO;AAET,KAAI,UAAU,OAAO,WAAW,WAAW,CACzC,QAAO"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapts `@larksuiteoapi/node-sdk`'s `Logger` interface to xopc's pino-based logger.
|
|
3
|
+
*
|
|
4
|
+
* The SDK wraps calls like `this.logger.info('a', 'b')` into `LoggerProxy.info` which forwards a *single* array
|
|
5
|
+
* argument to the underlying logger — which is why the default output looks like: `[info]: [ 'a', 'b' ]`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createFeishuLarkSdkPinoLogger(accountId: string): {
|
|
8
|
+
error: (...msg: any[]) => void;
|
|
9
|
+
warn: (...msg: any[]) => void;
|
|
10
|
+
info: (...msg: any[]) => void;
|
|
11
|
+
debug: (...msg: any[]) => void;
|
|
12
|
+
trace: (...msg: any[]) => void;
|
|
13
|
+
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createLogger } from "../../../../../src/utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../../../../../src/utils/logger.js";
|
|
3
|
+
//#region extensions/feishu/src/transport/client/lark-sdk-logger.ts
|
|
4
|
+
init_logger();
|
|
5
|
+
function normalizeLarkLogArgs(args) {
|
|
6
|
+
const raw = args.length === 1 ? args[0] : args;
|
|
7
|
+
if (Array.isArray(raw)) {
|
|
8
|
+
const errIdx = raw.findIndex((x) => x instanceof Error);
|
|
9
|
+
if (errIdx >= 0) {
|
|
10
|
+
const err = raw[errIdx];
|
|
11
|
+
return {
|
|
12
|
+
parts: raw.filter((_, i) => i !== errIdx),
|
|
13
|
+
err
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return { parts: raw };
|
|
17
|
+
}
|
|
18
|
+
return { parts: [raw] };
|
|
19
|
+
}
|
|
20
|
+
function stringifyParts(parts) {
|
|
21
|
+
const text = parts.map((p) => {
|
|
22
|
+
if (typeof p === "string") return p;
|
|
23
|
+
if (p instanceof Error) return p.message;
|
|
24
|
+
if (p === null || p === void 0) return "";
|
|
25
|
+
try {
|
|
26
|
+
return JSON.stringify(p);
|
|
27
|
+
} catch {
|
|
28
|
+
return String(p);
|
|
29
|
+
}
|
|
30
|
+
}).join(" ").replace(/\r\n/g, "\n").replace(/\r/g, "\n").trim();
|
|
31
|
+
return {
|
|
32
|
+
text,
|
|
33
|
+
hasLongLines: text.includes("\n") || text.length > 240
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function linePreview(text, max = 240) {
|
|
37
|
+
const oneLine = text.replace(/\s+/g, " ").trim();
|
|
38
|
+
if (oneLine.length <= max) return oneLine;
|
|
39
|
+
return oneLine.slice(0, max - 1) + "…";
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Adapts `@larksuiteoapi/node-sdk`'s `Logger` interface to xopc's pino-based logger.
|
|
43
|
+
*
|
|
44
|
+
* The SDK wraps calls like `this.logger.info('a', 'b')` into `LoggerProxy.info` which forwards a *single* array
|
|
45
|
+
* argument to the underlying logger — which is why the default output looks like: `[info]: [ 'a', 'b' ]`.
|
|
46
|
+
*/
|
|
47
|
+
function createFeishuLarkSdkPinoLogger(accountId) {
|
|
48
|
+
const log = createLogger("FeishuLarkSDK");
|
|
49
|
+
const write = (level, args) => {
|
|
50
|
+
const { parts, err } = normalizeLarkLogArgs(args);
|
|
51
|
+
const { text, hasLongLines } = stringifyParts(parts);
|
|
52
|
+
if (!text && !err) return;
|
|
53
|
+
if (err) {
|
|
54
|
+
log[level]({
|
|
55
|
+
err,
|
|
56
|
+
accountId,
|
|
57
|
+
linePreview: text ? linePreview(text) : void 0,
|
|
58
|
+
component: "lark-sdk"
|
|
59
|
+
}, text || err.message);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (level === "info" && (text === "client ready" || /^\[ws\]\s*ws client ready$/.test(text))) {
|
|
63
|
+
log.info({
|
|
64
|
+
accountId,
|
|
65
|
+
component: "lark-sdk",
|
|
66
|
+
lark: "api+ws"
|
|
67
|
+
}, "Lark SDK is ready (HTTP client + websocket)");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (level === "info" && text === "event-dispatch is ready") {
|
|
71
|
+
log.info({
|
|
72
|
+
accountId,
|
|
73
|
+
component: "lark-sdk",
|
|
74
|
+
lark: "event-dispatch"
|
|
75
|
+
}, "Lark event dispatcher is ready");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (level === "info" && hasLongLines) {
|
|
79
|
+
log.info({
|
|
80
|
+
accountId,
|
|
81
|
+
component: "lark-sdk",
|
|
82
|
+
lark: "event-subscription",
|
|
83
|
+
linePreview: linePreview(text)
|
|
84
|
+
}, "Lark subscription guidance: enable persistent connection mode in Developer Console (self-build + Feishu app)");
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
log[level]({
|
|
88
|
+
accountId,
|
|
89
|
+
component: "lark-sdk",
|
|
90
|
+
linePreview: linePreview(text)
|
|
91
|
+
}, text);
|
|
92
|
+
};
|
|
93
|
+
return {
|
|
94
|
+
error: (...args) => write("error", args),
|
|
95
|
+
warn: (...args) => write("warn", args),
|
|
96
|
+
info: (...args) => write("info", args),
|
|
97
|
+
debug: (...args) => write("debug", args),
|
|
98
|
+
trace: (...args) => write("trace", args)
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
102
|
+
export { createFeishuLarkSdkPinoLogger };
|
|
103
|
+
|
|
104
|
+
//# sourceMappingURL=lark-sdk-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lark-sdk-logger.js","names":[],"sources":["../../../../../../extensions/feishu/src/transport/client/lark-sdk-logger.ts"],"sourcesContent":["import { createLogger } from '@xopcai/xopc/utils/logger.js';\nimport type { Logger } from 'pino';\n\nfunction normalizeLarkLogArgs(args: any[]): { parts: any[]; err?: Error } {\n const raw: any = args.length === 1 ? args[0] : args;\n if (Array.isArray(raw)) {\n const errIdx = raw.findIndex((x) => x instanceof Error);\n if (errIdx >= 0) {\n const err = raw[errIdx] as Error;\n const parts = raw.filter((_, i) => i !== errIdx);\n return { parts, err };\n }\n return { parts: raw };\n }\n return { parts: [raw] };\n}\n\nfunction stringifyParts(parts: any[]): { text: string; hasLongLines: boolean } {\n const mapped = parts.map((p) => {\n if (typeof p === 'string') return p;\n if (p instanceof Error) return p.message;\n if (p === null || p === undefined) return '';\n try {\n return JSON.stringify(p);\n } catch {\n return String(p);\n }\n });\n const text = mapped.join(' ').replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n').trim();\n const hasLongLines = text.includes('\\n') || text.length > 240;\n return { text, hasLongLines };\n}\n\nfunction linePreview(text: string, max = 240): string {\n const oneLine = text.replace(/\\s+/g, ' ').trim();\n if (oneLine.length <= max) return oneLine;\n return oneLine.slice(0, max - 1) + '…';\n}\n\n/**\n * Adapts `@larksuiteoapi/node-sdk`'s `Logger` interface to xopc's pino-based logger.\n *\n * The SDK wraps calls like `this.logger.info('a', 'b')` into `LoggerProxy.info` which forwards a *single* array\n * argument to the underlying logger — which is why the default output looks like: `[info]: [ 'a', 'b' ]`.\n */\nexport function createFeishuLarkSdkPinoLogger(accountId: string): {\n error: (...msg: any[]) => void;\n warn: (...msg: any[]) => void;\n info: (...msg: any[]) => void;\n debug: (...msg: any[]) => void;\n trace: (...msg: any[]) => void;\n} {\n const log: Logger = createLogger('FeishuLarkSDK') as unknown as Logger;\n\n const write = (level: 'error' | 'warn' | 'info' | 'debug' | 'trace', args: any[]) => {\n const { parts, err } = normalizeLarkLogArgs(args);\n const { text, hasLongLines } = stringifyParts(parts);\n if (!text && !err) return;\n\n if (err) {\n (log as any)[level](\n { err, accountId, linePreview: text ? linePreview(text) : undefined, component: 'lark-sdk' },\n text || err.message,\n );\n return;\n }\n\n if (level === 'info' && (text === 'client ready' || /^\\[ws\\]\\s*ws client ready$/.test(text))) {\n // `Client` logs \"client ready\" and WSClient logs \"[ws] ws client ready\" — both mean the client stack is up.\n log.info({ accountId, component: 'lark-sdk', lark: 'api+ws' }, 'Lark SDK is ready (HTTP client + websocket)');\n return;\n }\n if (level === 'info' && text === 'event-dispatch is ready') {\n log.info({ accountId, component: 'lark-sdk', lark: 'event-dispatch' }, 'Lark event dispatcher is ready');\n return;\n }\n if (level === 'info' && hasLongLines) {\n log.info(\n { accountId, component: 'lark-sdk', lark: 'event-subscription', linePreview: linePreview(text) },\n 'Lark subscription guidance: enable persistent connection mode in Developer Console (self-build + Feishu app)',\n );\n return;\n }\n\n (log as any)[level]({ accountId, component: 'lark-sdk', linePreview: linePreview(text) }, text);\n };\n\n return {\n error: (...args) => write('error', args),\n warn: (...args) => write('warn', args),\n info: (...args) => write('info', args),\n debug: (...args) => write('debug', args),\n trace: (...args) => write('trace', args),\n };\n}\n"],"mappings":";;;aAA4D;AAG5D,SAAS,qBAAqB,MAA4C;CACxE,MAAM,MAAW,KAAK,WAAW,IAAI,KAAK,KAAK;AAC/C,KAAI,MAAM,QAAQ,IAAI,EAAE;EACtB,MAAM,SAAS,IAAI,WAAW,MAAM,aAAa,MAAM;AACvD,MAAI,UAAU,GAAG;GACf,MAAM,MAAM,IAAI;AAEhB,UAAO;IAAE,OADK,IAAI,QAAQ,GAAG,MAAM,MAAM,OAC3B;IAAE;IAAK;;AAEvB,SAAO,EAAE,OAAO,KAAK;;AAEvB,QAAO,EAAE,OAAO,CAAC,IAAI,EAAE;;AAGzB,SAAS,eAAe,OAAuD;CAW7E,MAAM,OAVS,MAAM,KAAK,MAAM;AAC9B,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,MAAI,aAAa,MAAO,QAAO,EAAE;AACjC,MAAI,MAAM,QAAQ,MAAM,KAAA,EAAW,QAAO;AAC1C,MAAI;AACF,UAAO,KAAK,UAAU,EAAE;UAClB;AACN,UAAO,OAAO,EAAE;;GAGD,CAAC,KAAK,IAAI,CAAC,QAAQ,SAAS,KAAK,CAAC,QAAQ,OAAO,KAAK,CAAC,MAAM;AAEhF,QAAO;EAAE;EAAM,cADM,KAAK,SAAS,KAAK,IAAI,KAAK,SAAS;EAC7B;;AAG/B,SAAS,YAAY,MAAc,MAAM,KAAa;CACpD,MAAM,UAAU,KAAK,QAAQ,QAAQ,IAAI,CAAC,MAAM;AAChD,KAAI,QAAQ,UAAU,IAAK,QAAO;AAClC,QAAO,QAAQ,MAAM,GAAG,MAAM,EAAE,GAAG;;;;;;;;AASrC,SAAgB,8BAA8B,WAM5C;CACA,MAAM,MAAc,aAAa,gBAAgB;CAEjD,MAAM,SAAS,OAAsD,SAAgB;EACnF,MAAM,EAAE,OAAO,QAAQ,qBAAqB,KAAK;EACjD,MAAM,EAAE,MAAM,iBAAiB,eAAe,MAAM;AACpD,MAAI,CAAC,QAAQ,CAAC,IAAK;AAEnB,MAAI,KAAK;AACN,OAAY,OACX;IAAE;IAAK;IAAW,aAAa,OAAO,YAAY,KAAK,GAAG,KAAA;IAAW,WAAW;IAAY,EAC5F,QAAQ,IAAI,QACb;AACD;;AAGF,MAAI,UAAU,WAAW,SAAS,kBAAkB,6BAA6B,KAAK,KAAK,GAAG;AAE5F,OAAI,KAAK;IAAE;IAAW,WAAW;IAAY,MAAM;IAAU,EAAE,8CAA8C;AAC7G;;AAEF,MAAI,UAAU,UAAU,SAAS,2BAA2B;AAC1D,OAAI,KAAK;IAAE;IAAW,WAAW;IAAY,MAAM;IAAkB,EAAE,iCAAiC;AACxG;;AAEF,MAAI,UAAU,UAAU,cAAc;AACpC,OAAI,KACF;IAAE;IAAW,WAAW;IAAY,MAAM;IAAsB,aAAa,YAAY,KAAK;IAAE,EAChG,+GACD;AACD;;AAGD,MAAY,OAAO;GAAE;GAAW,WAAW;GAAY,aAAa,YAAY,KAAK;GAAE,EAAE,KAAK;;AAGjG,QAAO;EACL,QAAQ,GAAG,SAAS,MAAM,SAAS,KAAK;EACxC,OAAO,GAAG,SAAS,MAAM,QAAQ,KAAK;EACtC,OAAO,GAAG,SAAS,MAAM,QAAQ,KAAK;EACtC,QAAQ,GAAG,SAAS,MAAM,SAAS,KAAK;EACxC,QAAQ,GAAG,SAAS,MAAM,SAAS,KAAK;EACzC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region extensions/feishu/src/transport/reliability/dedupe.ts
|
|
2
|
+
function createFeishuDedupe(options) {
|
|
3
|
+
const max = options?.max ?? 1e4;
|
|
4
|
+
const ttlMs = options?.ttlMs ?? 10 * 6e4;
|
|
5
|
+
const seen = /* @__PURE__ */ new Map();
|
|
6
|
+
function prune(now) {
|
|
7
|
+
for (const [k, t] of seen) if (now - t > ttlMs) seen.delete(k);
|
|
8
|
+
if (seen.size <= max) return;
|
|
9
|
+
const extra = seen.size - max;
|
|
10
|
+
let i = 0;
|
|
11
|
+
for (const k of seen.keys()) {
|
|
12
|
+
seen.delete(k);
|
|
13
|
+
i++;
|
|
14
|
+
if (i >= extra) break;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return { claim(id) {
|
|
18
|
+
const key = id.trim();
|
|
19
|
+
if (!key) return false;
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
prune(now);
|
|
22
|
+
if (seen.has(key)) return false;
|
|
23
|
+
seen.set(key, now);
|
|
24
|
+
return true;
|
|
25
|
+
} };
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { createFeishuDedupe };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=dedupe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dedupe.js","names":[],"sources":["../../../../../../extensions/feishu/src/transport/reliability/dedupe.ts"],"sourcesContent":["export interface FeishuDedupe {\n claim(id: string): boolean;\n}\n\nexport function createFeishuDedupe(options?: { max?: number; ttlMs?: number }): FeishuDedupe {\n const max = options?.max ?? 10_000;\n const ttlMs = options?.ttlMs ?? 10 * 60_000;\n const seen = new Map<string, number>();\n\n function prune(now: number) {\n for (const [k, t] of seen) {\n if (now - t > ttlMs) {\n seen.delete(k);\n }\n }\n if (seen.size <= max) return;\n const extra = seen.size - max;\n let i = 0;\n for (const k of seen.keys()) {\n seen.delete(k);\n i++;\n if (i >= extra) break;\n }\n }\n\n return {\n claim(id: string): boolean {\n const key = id.trim();\n if (!key) return false;\n const now = Date.now();\n prune(now);\n if (seen.has(key)) return false;\n seen.set(key, now);\n return true;\n },\n };\n}\n\n"],"mappings":";AAIA,SAAgB,mBAAmB,SAA0D;CAC3F,MAAM,MAAM,SAAS,OAAO;CAC5B,MAAM,QAAQ,SAAS,SAAS,KAAK;CACrC,MAAM,uBAAO,IAAI,KAAqB;CAEtC,SAAS,MAAM,KAAa;AAC1B,OAAK,MAAM,CAAC,GAAG,MAAM,KACnB,KAAI,MAAM,IAAI,MACZ,MAAK,OAAO,EAAE;AAGlB,MAAI,KAAK,QAAQ,IAAK;EACtB,MAAM,QAAQ,KAAK,OAAO;EAC1B,IAAI,IAAI;AACR,OAAK,MAAM,KAAK,KAAK,MAAM,EAAE;AAC3B,QAAK,OAAO,EAAE;AACd;AACA,OAAI,KAAK,MAAO;;;AAIpB,QAAO,EACL,MAAM,IAAqB;EACzB,MAAM,MAAM,GAAG,MAAM;AACrB,MAAI,CAAC,IAAK,QAAO;EACjB,MAAM,MAAM,KAAK,KAAK;AACtB,QAAM,IAAI;AACV,MAAI,KAAK,IAAI,IAAI,CAAE,QAAO;AAC1B,OAAK,IAAI,KAAK,IAAI;AAClB,SAAO;IAEV"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { MessageBus } from '@xopcai/xopc/infra/bus/index.js';
|
|
2
|
+
import type { Config } from '@xopcai/xopc/config/schema.js';
|
|
3
|
+
import type { ChannelSecurityContext } from '@xopcai/xopc/channels/plugin-types.js';
|
|
4
|
+
import type { ResolvedFeishuAccount } from '../../state/accounts.js';
|
|
5
|
+
export interface FeishuSocketModeMonitorDeps {
|
|
6
|
+
account: ResolvedFeishuAccount;
|
|
7
|
+
config: Config;
|
|
8
|
+
bus: MessageBus;
|
|
9
|
+
abortSignal: AbortSignal;
|
|
10
|
+
security: {
|
|
11
|
+
checkAccess: (ctx: ChannelSecurityContext) => {
|
|
12
|
+
allowed: boolean;
|
|
13
|
+
reason?: string;
|
|
14
|
+
} | undefined;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare function createFeishuSocketModeMonitor(deps: FeishuSocketModeMonitorDeps): {
|
|
18
|
+
run: () => Promise<void>;
|
|
19
|
+
};
|