@moxn/kb-migrate 0.4.17 → 0.4.18
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/targets/notion.js +35 -9
- package/package.json +1 -1
package/dist/targets/notion.js
CHANGED
|
@@ -187,22 +187,50 @@ async function uploadFileToNotion(client, url, filename, contentType) {
|
|
|
187
187
|
/**
|
|
188
188
|
* Post-process martian output to reconstruct callout blocks.
|
|
189
189
|
*
|
|
190
|
-
* Callouts
|
|
191
|
-
*
|
|
192
|
-
* `
|
|
193
|
-
*
|
|
194
|
-
*
|
|
190
|
+
* Callouts may arrive as either:
|
|
191
|
+
* 1. `quote` blocks (when stored with `> ` prefix) — text in children[0].paragraph.rich_text
|
|
192
|
+
* 2. `paragraph` blocks (when stored as plain text) — text in paragraph.rich_text
|
|
193
|
+
*
|
|
194
|
+
* In both cases, if the first text segment starts with an emoji followed by a space,
|
|
195
|
+
* the block is converted to a native Notion `callout` with that emoji as the icon.
|
|
195
196
|
*/
|
|
196
197
|
function reconstructCallouts(blocks) {
|
|
197
198
|
const emojiPrefixRe = /^(\p{Emoji_Presentation}|\p{Emoji}\uFE0F?)\s/u;
|
|
198
199
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
199
200
|
return blocks.map((block) => {
|
|
201
|
+
// Case 1: paragraph with emoji prefix
|
|
202
|
+
if (block.type === 'paragraph') {
|
|
203
|
+
const richText = block.paragraph?.rich_text;
|
|
204
|
+
if (!richText?.length)
|
|
205
|
+
return block;
|
|
206
|
+
const firstSegment = richText[0];
|
|
207
|
+
if (firstSegment.type !== 'text' || !firstSegment.text?.content)
|
|
208
|
+
return block;
|
|
209
|
+
const match = firstSegment.text.content.match(emojiPrefixRe);
|
|
210
|
+
if (!match)
|
|
211
|
+
return block;
|
|
212
|
+
const emoji = match[1];
|
|
213
|
+
const strippedContent = firstSegment.text.content.slice(match[0].length);
|
|
214
|
+
const calloutRichText = [
|
|
215
|
+
{ ...firstSegment, text: { ...firstSegment.text, content: strippedContent } },
|
|
216
|
+
...richText.slice(1),
|
|
217
|
+
].filter((rt) => rt.text?.content);
|
|
218
|
+
return {
|
|
219
|
+
object: 'block',
|
|
220
|
+
type: 'callout',
|
|
221
|
+
callout: {
|
|
222
|
+
rich_text: calloutRichText,
|
|
223
|
+
icon: { type: 'emoji', emoji },
|
|
224
|
+
color: 'default',
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
// Case 2: quote with emoji prefix in first child paragraph
|
|
200
229
|
if (block.type !== 'quote')
|
|
201
230
|
return block;
|
|
202
231
|
const children = block.quote?.children;
|
|
203
232
|
if (!children?.length)
|
|
204
233
|
return block;
|
|
205
|
-
// Find the first child paragraph with text
|
|
206
234
|
const firstChild = children[0];
|
|
207
235
|
if (firstChild.type !== 'paragraph' || !firstChild.paragraph?.rich_text?.length)
|
|
208
236
|
return block;
|
|
@@ -211,15 +239,13 @@ function reconstructCallouts(blocks) {
|
|
|
211
239
|
return block;
|
|
212
240
|
const match = firstSegment.text.content.match(emojiPrefixRe);
|
|
213
241
|
if (!match)
|
|
214
|
-
return block;
|
|
242
|
+
return block;
|
|
215
243
|
const emoji = match[1];
|
|
216
244
|
const strippedContent = firstSegment.text.content.slice(match[0].length);
|
|
217
|
-
// Build the callout's rich_text from the first child paragraph (stripped of emoji)
|
|
218
245
|
const calloutRichText = [
|
|
219
246
|
{ ...firstSegment, text: { ...firstSegment.text, content: strippedContent } },
|
|
220
247
|
...firstChild.paragraph.rich_text.slice(1),
|
|
221
248
|
].filter((rt) => rt.text?.content);
|
|
222
|
-
// Remaining children become the callout's children
|
|
223
249
|
const remainingChildren = children.slice(1);
|
|
224
250
|
return {
|
|
225
251
|
object: 'block',
|
package/package.json
CHANGED