@jacobbubu/md-to-lark 1.0.0

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 (58) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +171 -0
  3. package/dist/btt/build-tree.js +79 -0
  4. package/dist/btt/index.js +1 -0
  5. package/dist/btt/types.js +1 -0
  6. package/dist/cli/publish-md-to-lark.js +15 -0
  7. package/dist/commands/publish-md/args.js +224 -0
  8. package/dist/commands/publish-md/command.js +97 -0
  9. package/dist/commands/publish-md/index.js +1 -0
  10. package/dist/commands/publish-md/input-resolver.js +48 -0
  11. package/dist/commands/publish-md/mermaid-render.js +17 -0
  12. package/dist/commands/publish-md/pipeline-transform.js +4 -0
  13. package/dist/commands/publish-md/preset-loader.js +113 -0
  14. package/dist/commands/publish-md/presets/medium.js +7 -0
  15. package/dist/commands/publish-md/presets/zh-format.js +8 -0
  16. package/dist/commands/publish-md/title-policy.js +93 -0
  17. package/dist/index.js +1 -0
  18. package/dist/interop/btt-to-last.js +79 -0
  19. package/dist/interop/codec-btt-to-last.js +435 -0
  20. package/dist/interop/codec-last-to-btt.js +383 -0
  21. package/dist/interop/codec-shared.js +722 -0
  22. package/dist/interop/index.js +2 -0
  23. package/dist/interop/last-to-btt.js +17 -0
  24. package/dist/lark/block-types.js +42 -0
  25. package/dist/lark/client.js +36 -0
  26. package/dist/lark/docx/ops.js +596 -0
  27. package/dist/lark/docx/render-btt.js +156 -0
  28. package/dist/lark/docx/render-models.js +1 -0
  29. package/dist/lark/docx/render-payload.js +338 -0
  30. package/dist/lark/docx/render-post-process.js +98 -0
  31. package/dist/lark/docx/render-table.js +87 -0
  32. package/dist/lark/docx/render-types.js +7 -0
  33. package/dist/lark/index.js +2 -0
  34. package/dist/lark/types.js +1 -0
  35. package/dist/last/api.js +1687 -0
  36. package/dist/last/index.js +3 -0
  37. package/dist/last/preview-terminal.js +296 -0
  38. package/dist/last/textual-block-types.js +19 -0
  39. package/dist/last/to-markdown.js +303 -0
  40. package/dist/last/types.js +11 -0
  41. package/dist/pipeline/hast-to-last.js +946 -0
  42. package/dist/pipeline/index.js +3 -0
  43. package/dist/pipeline/markdown/md-to-hast.js +34 -0
  44. package/dist/pipeline/markdown/prepare-markdown.js +1049 -0
  45. package/dist/preview/index.js +1 -0
  46. package/dist/preview/markdown-terminal.js +350 -0
  47. package/dist/publish/asset-adapter.js +123 -0
  48. package/dist/publish/btt-patch.js +65 -0
  49. package/dist/publish/common.js +139 -0
  50. package/dist/publish/ids.js +9 -0
  51. package/dist/publish/index.js +7 -0
  52. package/dist/publish/last-normalize.js +327 -0
  53. package/dist/publish/process-file.js +228 -0
  54. package/dist/publish/runtime.js +133 -0
  55. package/dist/publish/stage-cache.js +56 -0
  56. package/dist/shared/rate-limiter.js +18 -0
  57. package/dist/shared/retry.js +141 -0
  58. package/package.json +78 -0
@@ -0,0 +1,383 @@
1
+ import { CALLOUT_BG_TO_NUM, CALLOUT_BORDER_TO_NUM, IFRAME_TYPE_TO_NUM, LAST_TO_LARK_BLOCK_TYPE, deepClone, isTextualType, lastTextPayloadToLark, toAlignNumber, } from './codec-shared.js';
2
+ export function normalizeDocumentIdToLAST(value) {
3
+ return value.startsWith('doc_') ? value : `doc_${value}`;
4
+ }
5
+ export function isLASTFragment(doc) {
6
+ return doc.mode === 'fragment' || Array.isArray(doc.topLevel);
7
+ }
8
+ export function sortChildrenByTreeOrder(doc) {
9
+ if (isLASTFragment(doc)) {
10
+ return [...doc.topLevel];
11
+ }
12
+ const root = doc.blocks[doc.rootId];
13
+ if (!root)
14
+ return [];
15
+ return [...root.children];
16
+ }
17
+ export function buildLASTToBTTBlockIdMap(lastDoc) {
18
+ const map = {};
19
+ const used = new Set();
20
+ for (const block of Object.values(lastDoc.blocks)) {
21
+ const preferred = (block.bttId ?? '').trim();
22
+ const resolved = preferred || String(block.id);
23
+ if (used.has(resolved)) {
24
+ throw new Error(`Duplicate bttId "${resolved}" found in LAST blocks.`);
25
+ }
26
+ used.add(resolved);
27
+ map[block.id] = resolved;
28
+ }
29
+ return map;
30
+ }
31
+ export function collectBlocksRootFirst(lastDoc) {
32
+ const ordered = [];
33
+ const visited = new Set();
34
+ const visit = (blockId) => {
35
+ if (visited.has(blockId))
36
+ return;
37
+ const block = lastDoc.blocks[blockId];
38
+ if (!block)
39
+ return;
40
+ visited.add(blockId);
41
+ ordered.push(block);
42
+ for (const childId of block.children) {
43
+ visit(childId);
44
+ }
45
+ };
46
+ if (isLASTFragment(lastDoc)) {
47
+ for (const topLevelId of lastDoc.topLevel) {
48
+ visit(topLevelId);
49
+ }
50
+ }
51
+ else {
52
+ visit(lastDoc.rootId);
53
+ }
54
+ for (const block of Object.values(lastDoc.blocks)) {
55
+ if (!visited.has(block.id)) {
56
+ ordered.push(block);
57
+ }
58
+ }
59
+ return ordered;
60
+ }
61
+ export function toDocumentModelForBTT(lastDoc) {
62
+ if (!isLASTFragment(lastDoc)) {
63
+ return lastDoc;
64
+ }
65
+ const blocks = {};
66
+ for (const [blockId, block] of Object.entries(lastDoc.blocks)) {
67
+ blocks[blockId] = deepClone(block);
68
+ }
69
+ let rootId = 'b_root';
70
+ let suffix = 1;
71
+ while (blocks[rootId]) {
72
+ rootId = `b_root_${suffix}`;
73
+ suffix += 1;
74
+ }
75
+ for (const childId of lastDoc.topLevel) {
76
+ const child = blocks[childId];
77
+ if (child) {
78
+ child.parentId = rootId;
79
+ }
80
+ }
81
+ blocks[rootId] = {
82
+ id: rootId,
83
+ type: 'page',
84
+ parentId: null,
85
+ childrenDefined: true,
86
+ children: [...lastDoc.topLevel],
87
+ payload: {
88
+ style: {
89
+ align: 'left',
90
+ },
91
+ inlines: [],
92
+ },
93
+ };
94
+ return {
95
+ schema: lastDoc.schema,
96
+ version: lastDoc.version,
97
+ id: lastDoc.id,
98
+ rootId,
99
+ blocks,
100
+ indexes: {
101
+ byType: {},
102
+ textScopes: {},
103
+ textScopeByBlockId: {},
104
+ },
105
+ ...(lastDoc.meta ? { meta: deepClone(lastDoc.meta) } : {}),
106
+ };
107
+ }
108
+ export function toRawBlock(block, lastToBttBlockId) {
109
+ const blockType = LAST_TO_LARK_BLOCK_TYPE[block.type];
110
+ const blockBttId = lastToBttBlockId[block.id] ?? String(block.id);
111
+ const parentBttId = block.parentId ? (lastToBttBlockId[block.parentId] ?? String(block.parentId)) : '';
112
+ const childrenBttIds = block.children.map((childId) => lastToBttBlockId[childId] ?? String(childId));
113
+ const base = {
114
+ block_id: blockBttId,
115
+ parent_id: parentBttId,
116
+ block_type: blockType,
117
+ ...(block.childrenDefined === false ? {} : { children: childrenBttIds }),
118
+ };
119
+ if (isTextualType(block.type)) {
120
+ const textualBlock = block;
121
+ return {
122
+ ...base,
123
+ ...lastTextPayloadToLark(block.type, textualBlock.payload, lastToBttBlockId),
124
+ };
125
+ }
126
+ if (block.type === 'callout') {
127
+ const callout = {};
128
+ if (block.payload.backgroundColor !== undefined) {
129
+ if (typeof block.payload.backgroundColor === 'number') {
130
+ callout.background_color = block.payload.backgroundColor;
131
+ }
132
+ else {
133
+ callout.background_color = CALLOUT_BG_TO_NUM[block.payload.backgroundColor];
134
+ }
135
+ }
136
+ if (block.payload.borderColor !== undefined) {
137
+ if (typeof block.payload.borderColor === 'number') {
138
+ callout.border_color = block.payload.borderColor;
139
+ }
140
+ else {
141
+ callout.border_color = CALLOUT_BORDER_TO_NUM[block.payload.borderColor];
142
+ }
143
+ }
144
+ if (block.payload.textColor !== undefined) {
145
+ if (typeof block.payload.textColor === 'number') {
146
+ callout.text_color = block.payload.textColor;
147
+ }
148
+ else {
149
+ callout.text_color = CALLOUT_BORDER_TO_NUM[block.payload.textColor];
150
+ }
151
+ }
152
+ if (block.payload.emojiId !== undefined) {
153
+ callout.emoji_id = block.payload.emojiId;
154
+ }
155
+ return {
156
+ ...base,
157
+ callout,
158
+ };
159
+ }
160
+ if (block.type === 'divider') {
161
+ return {
162
+ ...base,
163
+ divider: {},
164
+ };
165
+ }
166
+ if (block.type === 'file') {
167
+ const file = {};
168
+ if (block.payload.name !== undefined) {
169
+ file.name = block.payload.name;
170
+ }
171
+ if (block.payload.token !== undefined) {
172
+ file.token = block.payload.token;
173
+ }
174
+ if (block.payload.viewType !== undefined) {
175
+ file.view_type = block.payload.viewType;
176
+ }
177
+ return {
178
+ ...base,
179
+ file,
180
+ };
181
+ }
182
+ if (block.type === 'bitable') {
183
+ const bitable = {};
184
+ if (block.payload.token !== undefined) {
185
+ bitable.token = block.payload.token;
186
+ }
187
+ if (block.payload.viewType !== undefined) {
188
+ bitable.view_type = block.payload.viewType;
189
+ }
190
+ return {
191
+ ...base,
192
+ bitable,
193
+ };
194
+ }
195
+ if (block.type === 'chat_card') {
196
+ const chatCard = {
197
+ chat_id: block.payload.chatId,
198
+ };
199
+ const align = toAlignNumber(block.payload.align);
200
+ if (align !== undefined) {
201
+ chatCard.align = align;
202
+ }
203
+ return {
204
+ ...base,
205
+ chat_card: chatCard,
206
+ };
207
+ }
208
+ if (block.type === 'diagram') {
209
+ const diagram = {};
210
+ if (block.payload.diagramType !== undefined) {
211
+ diagram.diagram_type = block.payload.diagramType;
212
+ }
213
+ return {
214
+ ...base,
215
+ diagram,
216
+ };
217
+ }
218
+ if (block.type === 'grid') {
219
+ const grid = {};
220
+ if (block.payload.columnSize !== undefined) {
221
+ grid.column_size = block.payload.columnSize;
222
+ }
223
+ return {
224
+ ...base,
225
+ grid,
226
+ };
227
+ }
228
+ if (block.type === 'grid_column') {
229
+ const gridColumn = {};
230
+ if (block.payload.widthRatio !== undefined) {
231
+ gridColumn.width_ratio = block.payload.widthRatio;
232
+ }
233
+ return {
234
+ ...base,
235
+ grid_column: gridColumn,
236
+ };
237
+ }
238
+ if (block.type === 'iframe') {
239
+ const component = {};
240
+ if (block.payload.component.iframeType !== undefined) {
241
+ if (typeof block.payload.component.iframeType === 'number') {
242
+ component.iframe_type = block.payload.component.iframeType;
243
+ }
244
+ else {
245
+ component.iframe_type = IFRAME_TYPE_TO_NUM[block.payload.component.iframeType];
246
+ }
247
+ }
248
+ if (block.payload.component.url !== undefined) {
249
+ component.url = block.payload.component.url;
250
+ }
251
+ return {
252
+ ...base,
253
+ iframe: {
254
+ component,
255
+ },
256
+ };
257
+ }
258
+ if (block.type === 'image' || block.type === 'board') {
259
+ const imageLike = {};
260
+ if (block.payload.width !== undefined) {
261
+ imageLike.width = block.payload.width;
262
+ }
263
+ if (block.payload.height !== undefined) {
264
+ imageLike.height = block.payload.height;
265
+ }
266
+ if (block.payload.token !== undefined) {
267
+ imageLike.token = block.payload.token;
268
+ }
269
+ const align = toAlignNumber(block.payload.align);
270
+ if (align !== undefined) {
271
+ imageLike.align = align;
272
+ }
273
+ if (block.payload.caption) {
274
+ imageLike.caption = {
275
+ content: block.payload.caption.content,
276
+ };
277
+ }
278
+ if (block.payload.scale !== undefined) {
279
+ imageLike.scale = block.payload.scale;
280
+ }
281
+ return {
282
+ ...base,
283
+ [block.type]: imageLike,
284
+ };
285
+ }
286
+ if (block.type === 'table') {
287
+ const property = {};
288
+ if (block.payload.rowSize !== undefined) {
289
+ property.row_size = block.payload.rowSize;
290
+ }
291
+ if (block.payload.columnSize !== undefined) {
292
+ property.column_size = block.payload.columnSize;
293
+ }
294
+ if (block.payload.mergeInfo !== undefined) {
295
+ property.merge_info = block.payload.mergeInfo.map((item) => ({
296
+ ...(item.rowSpan !== undefined ? { row_span: item.rowSpan } : {}),
297
+ ...(item.colSpan !== undefined ? { col_span: item.colSpan } : {}),
298
+ }));
299
+ }
300
+ if (block.payload.columnWidth !== undefined) {
301
+ property.column_width = block.payload.columnWidth;
302
+ }
303
+ if (block.payload.headerColumn !== undefined) {
304
+ property.header_column = block.payload.headerColumn;
305
+ }
306
+ if (block.payload.headerRow !== undefined) {
307
+ property.header_row = block.payload.headerRow;
308
+ }
309
+ return {
310
+ ...base,
311
+ table: {
312
+ ...(block.payload.cells !== undefined
313
+ ? {
314
+ cells: block.payload.cells.map((cellId) => lastToBttBlockId[cellId] ?? String(cellId)),
315
+ }
316
+ : {}),
317
+ ...(Object.keys(property).length > 0 ? { property } : {}),
318
+ },
319
+ };
320
+ }
321
+ if (block.type === 'table_cell') {
322
+ return {
323
+ ...base,
324
+ table_cell: {},
325
+ };
326
+ }
327
+ if (block.type === 'mindnote') {
328
+ const mindnote = {};
329
+ if (block.payload.token !== undefined) {
330
+ mindnote.token = block.payload.token;
331
+ }
332
+ return {
333
+ ...base,
334
+ mindnote,
335
+ };
336
+ }
337
+ if (block.type === 'sheet') {
338
+ const sheet = {};
339
+ if (block.payload.token !== undefined) {
340
+ sheet.token = block.payload.token;
341
+ }
342
+ if (block.payload.rowSize !== undefined) {
343
+ sheet.row_size = block.payload.rowSize;
344
+ }
345
+ if (block.payload.columnSize !== undefined) {
346
+ sheet.column_size = block.payload.columnSize;
347
+ }
348
+ return {
349
+ ...base,
350
+ sheet,
351
+ };
352
+ }
353
+ if (block.type === 'view') {
354
+ const view = {};
355
+ if (block.payload.viewType !== undefined) {
356
+ view.view_type = block.payload.viewType;
357
+ }
358
+ return {
359
+ ...base,
360
+ view,
361
+ };
362
+ }
363
+ if (block.type === 'quote_container') {
364
+ return {
365
+ ...base,
366
+ quote_container: {},
367
+ };
368
+ }
369
+ if (block.type === 'synced_block') {
370
+ const referenceSynced = {};
371
+ if (block.payload.sourceDocumentId !== undefined) {
372
+ referenceSynced.source_document_id = block.payload.sourceDocumentId;
373
+ }
374
+ if (block.payload.sourceBlockId !== undefined) {
375
+ referenceSynced.source_block_id = block.payload.sourceBlockId;
376
+ }
377
+ return {
378
+ ...base,
379
+ reference_synced: referenceSynced,
380
+ };
381
+ }
382
+ throw new Error(`Unsupported LAST block type in toRawBlock: ${block.type}`);
383
+ }