@max1874/feishu 0.2.10 → 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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/docx.ts +62 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@max1874/feishu",
3
- "version": "0.2.10",
3
+ "version": "0.2.11",
4
4
  "type": "module",
5
5
  "description": "OpenClaw Feishu/Lark channel plugin",
6
6
  "license": "MIT",
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
- return {
187
- blocks: res.data?.blocks ?? [],
188
- firstLevelBlockIds: res.data?.first_level_block_ids ?? [],
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) */