@max1874/feishu 0.2.9 → 0.2.11
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/package.json +1 -1
- package/src/docx.ts +75 -6
package/package.json
CHANGED
package/src/docx.ts
CHANGED
|
@@ -43,6 +43,60 @@ function extractImageUrls(markdown: string): string[] {
|
|
|
43
43
|
return urls;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/** Extract text content from a block for sorting */
|
|
47
|
+
function extractBlockText(block: any): string {
|
|
48
|
+
const elements =
|
|
49
|
+
block.text?.elements ??
|
|
50
|
+
block.heading1?.elements ??
|
|
51
|
+
block.heading2?.elements ??
|
|
52
|
+
block.heading3?.elements ??
|
|
53
|
+
block.bullet?.elements ??
|
|
54
|
+
block.ordered?.elements ??
|
|
55
|
+
block.quote?.elements ??
|
|
56
|
+
block.todo?.elements ??
|
|
57
|
+
[];
|
|
58
|
+
return elements
|
|
59
|
+
.filter((e: any) => e.text_run)
|
|
60
|
+
.map((e: any) => e.text_run.content)
|
|
61
|
+
.join("");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Sort blocks by their position in firstLevelBlockIds.
|
|
66
|
+
* The Convert API returns blocks in arbitrary order, but provides
|
|
67
|
+
* first_level_block_ids in the correct document order.
|
|
68
|
+
*/
|
|
69
|
+
function sortBlocksByFirstLevelIds(blocks: any[], firstLevelBlockIds: string[]): any[] {
|
|
70
|
+
// Build a map of block_id -> block
|
|
71
|
+
const blockMap = new Map<string, any>();
|
|
72
|
+
for (const block of blocks) {
|
|
73
|
+
if (block.block_id) {
|
|
74
|
+
blockMap.set(block.block_id, block);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Reorder blocks according to firstLevelBlockIds
|
|
79
|
+
const sortedBlocks: any[] = [];
|
|
80
|
+
const usedIds = new Set<string>();
|
|
81
|
+
|
|
82
|
+
for (const id of firstLevelBlockIds) {
|
|
83
|
+
const block = blockMap.get(id);
|
|
84
|
+
if (block) {
|
|
85
|
+
sortedBlocks.push(block);
|
|
86
|
+
usedIds.add(id);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Append any remaining blocks (e.g., child blocks like TableCell)
|
|
91
|
+
for (const block of blocks) {
|
|
92
|
+
if (block.block_id && !usedIds.has(block.block_id)) {
|
|
93
|
+
sortedBlocks.push(block);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return sortedBlocks;
|
|
98
|
+
}
|
|
99
|
+
|
|
46
100
|
const BLOCK_TYPE_NAMES: Record<number, string> = {
|
|
47
101
|
1: "Page",
|
|
48
102
|
2: "Text",
|
|
@@ -183,10 +237,14 @@ async function convertMarkdown(client: Lark.Client, markdown: string) {
|
|
|
183
237
|
data: { content_type: "markdown", content: markdown },
|
|
184
238
|
});
|
|
185
239
|
if (res.code !== 0) throw new Error(res.msg);
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
240
|
+
|
|
241
|
+
const rawBlocks = res.data?.blocks ?? [];
|
|
242
|
+
const firstLevelBlockIds = res.data?.first_level_block_ids ?? [];
|
|
243
|
+
|
|
244
|
+
// Sort blocks according to first_level_block_ids (Convert API returns blocks in arbitrary order)
|
|
245
|
+
const blocks = sortBlocksByFirstLevelIds(rawBlocks, firstLevelBlockIds);
|
|
246
|
+
|
|
247
|
+
return { blocks, firstLevelBlockIds };
|
|
190
248
|
}
|
|
191
249
|
|
|
192
250
|
/** Insert blocks as children of a parent block (with batching for >50 blocks) */
|
|
@@ -207,14 +265,25 @@ async function insertBlocks(
|
|
|
207
265
|
const BATCH_SIZE = 50;
|
|
208
266
|
const allChildren: any[] = [];
|
|
209
267
|
|
|
268
|
+
// Get current children count to determine insert index
|
|
269
|
+
let insertIndex = 0;
|
|
270
|
+
const existing = await client.docx.documentBlockChildren.get({
|
|
271
|
+
path: { document_id: docToken, block_id: blockId },
|
|
272
|
+
});
|
|
273
|
+
if (existing.code === 0) {
|
|
274
|
+
insertIndex = existing.data?.items?.length ?? 0;
|
|
275
|
+
}
|
|
276
|
+
|
|
210
277
|
for (let i = 0; i < cleaned.length; i += BATCH_SIZE) {
|
|
211
278
|
const batch = cleaned.slice(i, i + BATCH_SIZE);
|
|
212
279
|
const res = await client.docx.documentBlockChildren.create({
|
|
213
280
|
path: { document_id: docToken, block_id: blockId },
|
|
214
|
-
data: { children: batch },
|
|
281
|
+
data: { children: batch, index: insertIndex },
|
|
215
282
|
});
|
|
216
283
|
if (res.code !== 0) throw new Error(res.msg);
|
|
217
|
-
|
|
284
|
+
const inserted = res.data?.children ?? [];
|
|
285
|
+
allChildren.push(...inserted);
|
|
286
|
+
insertIndex += inserted.length;
|
|
218
287
|
}
|
|
219
288
|
|
|
220
289
|
return { children: allChildren, skipped };
|