noblog 0.0.9 → 0.0.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/dist/generate.cjs CHANGED
@@ -3,9 +3,8 @@
3
3
 
4
4
  var path = require('path');
5
5
  var fs = require('fs/promises');
6
- var notionToMd = require('notion-to-md');
7
- require('node-fetch');
8
- require('markdown-table');
6
+ var fetch = require('node-fetch');
7
+ var markdownTable = require('markdown-table');
9
8
  require('dotenv/config');
10
9
  var retry = require('async-retry');
11
10
  var client$1 = require('@notionhq/client');
@@ -30,6 +29,73 @@ function _interopNamespaceDefault(e) {
30
29
  var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
31
30
  var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
32
31
 
32
+ const inlineEquation = (text) => {
33
+ return `$${text}$`;
34
+ };
35
+ const link = (text, href) => {
36
+ return `[${text}](${href})`;
37
+ };
38
+ const codeBlock = (text, language) => {
39
+ if (language === "plain text")
40
+ language = "text";
41
+ return `\`\`\`${language}
42
+ ${text}
43
+ \`\`\``;
44
+ };
45
+ const equation = (text) => {
46
+ return `$$
47
+ ${text}
48
+ $$`;
49
+ };
50
+ const heading1 = (text) => {
51
+ return `# ${text}`;
52
+ };
53
+ const heading2 = (text) => {
54
+ return `## ${text}`;
55
+ };
56
+ const heading3 = (text) => {
57
+ return `### ${text}`;
58
+ };
59
+ const quote = (text) => {
60
+ // the replace is done to handle multiple lines
61
+ return `> ${text.replace(/\n/g, " \n> ")}`;
62
+ };
63
+ const callout = (text, icon) => {
64
+ let emoji;
65
+ if (icon?.type === "emoji") {
66
+ emoji = icon.emoji;
67
+ }
68
+ // the replace is done to handle multiple lines
69
+ return `> ${emoji ? emoji + " " : ""}${text.replace(/\n/g, " \n> ")}`;
70
+ };
71
+ const bullet = (text, count) => {
72
+ let renderText = text.trim();
73
+ return count ? `${count}. ${renderText}` : `- ${renderText}`;
74
+ };
75
+ const todo = (text, checked) => {
76
+ return checked ? `- [x] ${text}` : `- [ ] ${text}`;
77
+ };
78
+ const image = async (alt, href, convertToBase64 = false) => {
79
+ // In case the user does not want to convert the images to Base64
80
+ // or the image is already base64
81
+ if (!convertToBase64 || href.startsWith("data:")) {
82
+ if (href.startsWith("data:")) {
83
+ // Extract base64 data, i.e. the string after 'data:mime/type;base64,'
84
+ const base64 = href.split(",").pop();
85
+ // This overrides incorrect data: string format to png
86
+ // so that browsers can correctly render the data
87
+ return `![${alt}](data:image/png;base64,${base64})`;
88
+ }
89
+ return `![${alt}](${href})`;
90
+ }
91
+ else {
92
+ // Otherwise, download the image and convert it to base64
93
+ const res = await fetch(href);
94
+ const buf = await res.arrayBuffer();
95
+ const base64 = Buffer.from(buf).toString("base64");
96
+ return `![${alt}](data:image/png;base64,${base64})`;
97
+ }
98
+ };
33
99
  const addTabSpace = (text, n = 0) => {
34
100
  const tab = " ";
35
101
  for (let i = 0; i < n; i++) {
@@ -42,6 +108,9 @@ const addTabSpace = (text, n = 0) => {
42
108
  }
43
109
  return text;
44
110
  };
111
+ const divider = () => {
112
+ return "---";
113
+ };
45
114
  const toggle = (summary, children) => {
46
115
  if (!summary)
47
116
  return children || "";
@@ -50,9 +119,12 @@ const toggle = (summary, children) => {
50
119
  ${children || ""}
51
120
  </details>\n\n`;
52
121
  };
122
+ const table = (cells) => {
123
+ return markdownTable.markdownTable(cells);
124
+ };
53
125
 
54
- const NOTION_API_SECRET = process.env.NOTION_API_SECRET ?? '';
55
- const NOBLOG_DATABASE_ID = process.env.NOBLOG_DATABASE_ID ?? '';
126
+ const NOTION_API_SECRET = process.env.NOTION_API_SECRET ?? "";
127
+ const NOBLOG_DATABASE_ID = process.env.NOBLOG_DATABASE_ID ?? "";
56
128
  const client = new client$1.Client({
57
129
  auth: NOTION_API_SECRET,
58
130
  });
@@ -61,15 +133,19 @@ async function GetAllPosts() {
61
133
  const params = {
62
134
  database_id: NOBLOG_DATABASE_ID,
63
135
  filter: {
64
- and: [{
65
- property: 'publish',
66
- checkbox: { equals: true, },
67
- }]
136
+ and: [
137
+ {
138
+ property: "publish",
139
+ checkbox: { equals: true },
140
+ },
141
+ ],
68
142
  },
69
- sorts: [{
70
- property: 'date',
71
- direction: 'descending',
72
- }],
143
+ sorts: [
144
+ {
145
+ property: "date",
146
+ direction: "descending",
147
+ },
148
+ ],
73
149
  page_size: 100,
74
150
  };
75
151
  let results = [];
@@ -86,12 +162,12 @@ async function GetAllPosts() {
86
162
  }
87
163
  throw error;
88
164
  }
89
- }, { retries: numberOfRetry, });
165
+ }, { retries: numberOfRetry });
90
166
  results = results.concat(res.results);
91
167
  if (!res.has_more) {
92
168
  break;
93
169
  }
94
- params['start_cursor'] = res.next_cursor;
170
+ params["start_cursor"] = res.next_cursor;
95
171
  }
96
172
  return results;
97
173
  }
@@ -108,17 +184,48 @@ async function GetPageMeta(page_id) {
108
184
  }
109
185
  throw error;
110
186
  }
111
- }, { retries: numberOfRetry, });
187
+ }, { retries: numberOfRetry });
188
+ return result;
189
+ }
190
+ async function GetBlockChildren(block_id, totalPage) {
191
+ let result = [];
192
+ let pageCount = 0;
193
+ let start_cursor = undefined;
194
+ do {
195
+ const response = (await client.blocks.children.list({
196
+ start_cursor: start_cursor,
197
+ block_id: block_id,
198
+ }));
199
+ result.push(...response.results);
200
+ start_cursor = response?.next_cursor;
201
+ pageCount += 1;
202
+ } while (start_cursor != null &&
203
+ (totalPage == null || pageCount < totalPage));
204
+ ModifyNumberedListObject(result);
112
205
  return result;
113
206
  }
207
+ function ModifyNumberedListObject(blocks) {
208
+ let numberedListIndex = 0;
209
+ for (const block of blocks) {
210
+ if ("type" in block && block.type === "numbered_list_item") {
211
+ // add numbers
212
+ // @ts-ignore
213
+ block.numbered_list_item.number = ++numberedListIndex;
214
+ }
215
+ else {
216
+ numberedListIndex = 0;
217
+ }
218
+ }
219
+ }
114
220
 
115
- class Noblog extends notionToMd.NotionToMarkdown {
221
+ class Noblog {
116
222
  Posts = [];
223
+ CurrPage = "";
117
224
  SavePath = "./src/pages/posts/";
118
225
  ChildPath = "nob_children/";
119
226
  MdCollection = {};
227
+ CustomTransformers = {};
120
228
  constructor(posts, save_path, child_path) {
121
- super({ notionClient: client });
122
229
  this.Posts = posts;
123
230
  if (child_path != undefined) {
124
231
  this.ChildPath = child_path;
@@ -126,29 +233,44 @@ class Noblog extends notionToMd.NotionToMarkdown {
126
233
  if (save_path != undefined) {
127
234
  this.SavePath = save_path;
128
235
  }
129
- this.setCustomTransformer("child_page", async (block) => {
130
- let path = this.ChildPath;
236
+ this.CustomTransformers["child_page"] = async (block) => {
131
237
  const page = block;
132
238
  if (!page?.id) {
133
239
  return false;
134
240
  }
135
- if (this.Posts.filter(post => post.id === page.child_page.title).length > 0) {
136
- path = "";
241
+ let sub_path;
242
+ // if (curr_page.id in this.Post) and (page.id in this.Post) ||
243
+ // (curr_page.id not in this.Post) and (page.id not in this.Post)
244
+ // * path should be "../pageid"
245
+ // if (curr_page.id in this.Post) and (page.id not in this.Post)
246
+ // * path should be "../save_path/pageid"
247
+ // if (curr_page.id not in this.Post) and (page.id in this.Post)
248
+ // * path should be "../../pageid"
249
+ const parent_surface = this.Posts.filter((post) => post.id === this.CurrPage).length > 0;
250
+ const child_surface = this.Posts.filter((post) => post.id === page.id).length > 0;
251
+ if (parent_surface === child_surface) {
252
+ sub_path = "";
137
253
  }
138
- return `[${page.child_page.title}](../${path}${page.id})`;
139
- });
254
+ else if (parent_surface) {
255
+ sub_path = this.ChildPath;
256
+ }
257
+ else {
258
+ sub_path = "..";
259
+ }
260
+ const full_path = path__namespace.join("../", sub_path, page.id);
261
+ return `&[${page.child_page.title}](${full_path})`;
262
+ };
140
263
  }
141
264
  async Collect(recur = true) {
142
265
  const save_dir = this.SavePath;
143
266
  const sub_dir = path__namespace.join(save_dir, this.ChildPath);
144
- const futs = this.Posts.map(page => {
145
- return this.FromPageid(page.id, recur);
146
- });
267
+ for (let page of this.Posts) {
268
+ await this.FromPageid(page.id, recur);
269
+ }
147
270
  try {
148
- await Promise.all(futs);
149
271
  for (const pageid of Object.keys(this.MdCollection)) {
150
272
  let fpath = sub_dir;
151
- if (this.Posts.find(page => page.id === pageid))
273
+ if (this.Posts.find((page) => page.id === pageid))
152
274
  fpath = save_dir;
153
275
  await this.SaveJelly(pageid + ".md", fpath, this.MdCollection[pageid]);
154
276
  }
@@ -159,7 +281,7 @@ class Noblog extends notionToMd.NotionToMarkdown {
159
281
  console.log(`failed: consider run verbose with v=true - ${error.message}`);
160
282
  }
161
283
  else {
162
- console.log('failed: an unknown error occurred');
284
+ console.log("failed: an unknown error occurred");
163
285
  }
164
286
  }
165
287
  }
@@ -178,7 +300,8 @@ class Noblog extends notionToMd.NotionToMarkdown {
178
300
  block.type !== "numbered_list_item") {
179
301
  line_wrap = "\n";
180
302
  }
181
- jelly.content += (line_wrap + `${addTabSpace(block.parent, 0)}\n` + line_wrap);
303
+ jelly.content +=
304
+ line_wrap + `${addTabSpace(block.parent, 0)}\n` + line_wrap;
182
305
  if (block.type === "child_page") {
183
306
  jelly.children = [...jelly.children, block.blockId];
184
307
  if (recursive)
@@ -192,24 +315,332 @@ class Noblog extends notionToMd.NotionToMarkdown {
192
315
  return jelly;
193
316
  }
194
317
  async FromPageid(page_id, recursive = true) {
318
+ // preserve the curr page info
319
+ const prev_page = this.CurrPage;
320
+ this.CurrPage = page_id;
195
321
  if (this.MdCollection.hasOwnProperty(page_id)) {
196
322
  return this.MdCollection[page_id];
197
323
  }
198
- const blocks = await this.pageToMarkdown(page_id);
324
+ const blocks = await this.PageToMarkdown(page_id);
199
325
  const jelly = await this.FromBlocks(blocks, recursive);
200
326
  const meta = await GetPageMeta(page_id);
201
327
  const astro_meta = await this.AssembleAstroFrontmatter(meta);
202
328
  jelly.content = astro_meta + jelly.content;
203
329
  this.MdCollection[page_id] = jelly;
330
+ // restore the prev page info
331
+ this.CurrPage = prev_page;
204
332
  return jelly;
205
333
  }
334
+ async PageToMarkdown(id, totalPage) {
335
+ if (!client) {
336
+ throw new Error("notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md");
337
+ }
338
+ const blocks = await GetBlockChildren(id, totalPage);
339
+ const parsedData = await this.BlocksToMarkdown(blocks);
340
+ return parsedData;
341
+ }
342
+ async BlocksToMarkdown(blocks, totalPage, mdBlocks) {
343
+ if (!client) {
344
+ throw new Error("notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md");
345
+ }
346
+ if (!blocks)
347
+ return mdBlocks;
348
+ for (let i = 0; i < blocks.length; i++) {
349
+ let block = blocks[i];
350
+ if (
351
+ // @ts-ignore
352
+ block.type === "unsupported" ||
353
+ // @ts-ignore
354
+ (block.type === "child_page" && !this.config.parseChildPages)) {
355
+ continue;
356
+ }
357
+ if ("has_children" in block && block.has_children) {
358
+ const block_id = block.type == "synced_block" &&
359
+ block.synced_block?.synced_from?.block_id
360
+ ? block.synced_block.synced_from.block_id
361
+ : block.id;
362
+ // Get children of this block.
363
+ let child_blocks = await GetBlockChildren(block_id, totalPage);
364
+ // Recursively call BlocksToMarkdown to get children of this block.
365
+ // check for custom transformer before parsing child
366
+ if (!(block.type in this.CustomTransformers) &&
367
+ !this.CustomTransformers[block.type]) {
368
+ let l = mdBlocks.length;
369
+ if (mdBlocks !== undefined) {
370
+ await this.BlocksToMarkdown(child_blocks, totalPage, mdBlocks[l - 1]?.children);
371
+ }
372
+ }
373
+ // Push this block to mdBlocks.
374
+ mdBlocks.push({
375
+ type: block.type,
376
+ blockId: block.id,
377
+ parent: await this.BlockToMarkdown(block),
378
+ children: [],
379
+ });
380
+ continue;
381
+ }
382
+ let tmp = await this.BlockToMarkdown(block);
383
+ mdBlocks.push({
384
+ // @ts-ignore
385
+ type: block.type,
386
+ blockId: block.id,
387
+ parent: tmp,
388
+ children: [],
389
+ });
390
+ }
391
+ return mdBlocks;
392
+ }
393
+ async BlockToMarkdown(block) {
394
+ if (typeof block !== "object" || !("type" in block))
395
+ return "";
396
+ let parsedData = "";
397
+ const { type } = block;
398
+ if (type in this.CustomTransformers && !!this.CustomTransformers[type]) {
399
+ const transformer = this.CustomTransformers[type];
400
+ const customTransformerValue = transformer(block);
401
+ if (typeof customTransformerValue === "string")
402
+ return customTransformerValue;
403
+ }
404
+ switch (type) {
405
+ case "image":
406
+ let blockContent = block.image;
407
+ let image_title = "image";
408
+ const image_caption_plain = blockContent.caption
409
+ .map((item) => item.plain_text)
410
+ .join("");
411
+ const image_type = blockContent.type;
412
+ let link$1 = "";
413
+ if (image_type === "external") {
414
+ link$1 = blockContent.external.url;
415
+ }
416
+ if (image_type === "file") {
417
+ link$1 = blockContent.file.url;
418
+ }
419
+ // image caption with high priority
420
+ if (image_caption_plain.trim().length > 0) {
421
+ image_title = image_caption_plain;
422
+ }
423
+ else if (image_type === "file" || image_type === "external") {
424
+ const matches = link$1.match(/[^\/\\&\?]+\.\w{3,4}(?=([\?&].*$|$))/);
425
+ image_title = matches ? matches[0] : image_title;
426
+ }
427
+ return await image(image_title, link$1, false);
428
+ case "divider":
429
+ return divider();
430
+ case "equation":
431
+ return equation(block.equation.expression);
432
+ case "video":
433
+ case "file":
434
+ case "pdf":
435
+ {
436
+ let blockContent;
437
+ let title = type;
438
+ if (type === "video")
439
+ blockContent = block.video;
440
+ if (type === "file")
441
+ blockContent = block.file;
442
+ if (type === "pdf")
443
+ blockContent = block.pdf;
444
+ const caption = blockContent?.caption
445
+ .map((item) => item.plain_text)
446
+ .join("");
447
+ if (blockContent) {
448
+ const file_type = blockContent.type;
449
+ let link$1 = "";
450
+ if (file_type === "external")
451
+ link$1 = blockContent.external.url;
452
+ if (file_type === "file")
453
+ link$1 = blockContent.file.url;
454
+ if (caption && caption.trim().length > 0) {
455
+ title = caption;
456
+ }
457
+ else if (link$1) {
458
+ const matches = link$1.match(/[^\/\\&\?]+\.\w{3,4}(?=([\?&].*$|$))/);
459
+ title = matches ? matches[0] : type;
460
+ }
461
+ return link(title, link$1);
462
+ }
463
+ }
464
+ break;
465
+ case "bookmark":
466
+ case "embed":
467
+ case "link_preview":
468
+ case "link_to_page":
469
+ {
470
+ let blockContent;
471
+ let title = type;
472
+ if (type === "bookmark")
473
+ blockContent = block.bookmark;
474
+ if (type === "embed")
475
+ blockContent = block.embed;
476
+ if (type === "link_preview")
477
+ blockContent = block.link_preview;
478
+ if (type === "link_to_page" &&
479
+ block.link_to_page.type === "page_id") {
480
+ blockContent = {
481
+ url: `https://www.notion.so/${block.link_to_page.page_id}`,
482
+ };
483
+ }
484
+ if (blockContent)
485
+ return link(title, blockContent.url);
486
+ }
487
+ break;
488
+ case "child_page": {
489
+ let pageTitle = block.child_page.title;
490
+ return heading2(pageTitle);
491
+ }
492
+ case "child_database": {
493
+ let pageTitle = block.child_database.title || `child_database`;
494
+ return heading2(pageTitle);
495
+ }
496
+ case "table": {
497
+ const { id, has_children } = block;
498
+ let tableArr = [];
499
+ if (has_children) {
500
+ const tableRows = await GetBlockChildren(id, 100);
501
+ let rowsPromise = tableRows?.map(async (row) => {
502
+ const { type } = row;
503
+ const cells = row[type]["cells"];
504
+ /**
505
+ * this is more like a hack since matching the type text was
506
+ * difficult. So converting each cell to paragraph type to
507
+ * reuse the BlockToMarkdown function
508
+ */
509
+ let cellStringPromise = cells.map(async (cell) => await this.BlockToMarkdown({
510
+ type: "paragraph",
511
+ paragraph: { rich_text: cell },
512
+ }));
513
+ const cellStringArr = await Promise.all(cellStringPromise);
514
+ tableArr.push(cellStringArr);
515
+ });
516
+ await Promise.all(rowsPromise || []);
517
+ }
518
+ return table(tableArr);
519
+ }
520
+ // Rest of the types:
521
+ // "paragraph" "heading_1" "heading_2" "heading_3"
522
+ // "bulleted_list_item" "numbered_list_item"
523
+ // "quote" "to_do" "template" "synced_block"
524
+ // "child_page" "child_database" "code" "callout" "breadcrumb"
525
+ // "table_of_contents" "link_to_page" "audio" "unsupported"
526
+ default: {
527
+ // @ts-ignore
528
+ let blockContent = block[type].text || block[type].rich_text || [];
529
+ let bucket = [];
530
+ let code_range = [];
531
+ let bold_range = [];
532
+ let italic_range = [];
533
+ let underline_range = [];
534
+ let strikethrough_range = [];
535
+ const push_or_merge = (arr, idx) => {
536
+ if (arr.length == 0) {
537
+ return;
538
+ }
539
+ // @ts-ignore
540
+ if (idx === arr[arr.length - 1][1]) {
541
+ // @ts-ignore
542
+ arr[arr.length - 1][1] += 1;
543
+ }
544
+ else {
545
+ arr.push([idx, idx + 1]);
546
+ }
547
+ };
548
+ for (let i = 0; i < blockContent.length; i++) {
549
+ let content = blockContent[i];
550
+ if (content.type === "equation") {
551
+ bucket.push(inlineEquation(content.equation.expression));
552
+ continue;
553
+ }
554
+ let plain_text = content.plain_text;
555
+ if (content["href"])
556
+ plain_text = link(plain_text, content["href"]);
557
+ bucket.push(plain_text);
558
+ const annotations = content.annotations;
559
+ if (annotations.code)
560
+ push_or_merge(code_range, i);
561
+ if (annotations.bold)
562
+ push_or_merge(bold_range, i);
563
+ if (annotations.italic)
564
+ push_or_merge(italic_range, i);
565
+ if (annotations.underline)
566
+ push_or_merge(underline_range, i);
567
+ if (annotations.strikethrough)
568
+ push_or_merge(strikethrough_range, i);
569
+ }
570
+ let annoed_bucket = [];
571
+ for (let range of code_range)
572
+ annoed_bucket.push({ range: range, type: "code" });
573
+ for (let range of bold_range)
574
+ annoed_bucket.push({ range: range, type: "bold" });
575
+ for (let range of italic_range)
576
+ annoed_bucket.push({ range: range, type: "italic" });
577
+ for (let range of underline_range)
578
+ annoed_bucket.push({ range: range, type: "underline" });
579
+ for (let range of strikethrough_range)
580
+ annoed_bucket.push({ range: range, type: "strikethrough" });
581
+ annoed_bucket.sort(
582
+ // @ts-ignore
583
+ (a, b) => a.range[1] - a.range[0] - (b.range[1] - b.range[0]));
584
+ for (let annoed of annoed_bucket) {
585
+ annoed.type;
586
+ let [from, to] = annoed.range;
587
+ // @ts-ignore
588
+ bucket[from] = annotation + bucket[from];
589
+ // @ts-ignore
590
+ bucket[to - 1] = bucket[to - 1] + annotation;
591
+ }
592
+ bucket.forEach((x) => (parsedData += x));
593
+ }
594
+ }
595
+ switch (type) {
596
+ case "code":
597
+ parsedData = codeBlock(parsedData, block[type].language);
598
+ break;
599
+ case "heading_1":
600
+ parsedData = heading1(parsedData);
601
+ break;
602
+ case "heading_2":
603
+ parsedData = heading2(parsedData);
604
+ break;
605
+ case "heading_3":
606
+ parsedData = heading3(parsedData);
607
+ break;
608
+ case "quote":
609
+ parsedData = quote(parsedData);
610
+ break;
611
+ case "callout":
612
+ const { id, has_children } = block;
613
+ let callout_string = "";
614
+ if (!has_children) {
615
+ return callout(parsedData, block[type].icon);
616
+ }
617
+ const callout_children_object = await GetBlockChildren(id, 100);
618
+ const callout_children = await this.BlocksToMarkdown(callout_children_object);
619
+ callout_string += `${parsedData}\n`;
620
+ callout_children.map((child) => {
621
+ callout_string += `${child.parent}\n\n`;
622
+ });
623
+ parsedData = callout(callout_string.trim(), block[type].icon);
624
+ break;
625
+ case "bulleted_list_item":
626
+ parsedData = bullet(parsedData);
627
+ break;
628
+ case "numbered_list_item":
629
+ parsedData = bullet(parsedData, block.numbered_list_item.number);
630
+ break;
631
+ case "to_do":
632
+ parsedData = todo(parsedData, block.to_do.checked);
633
+ break;
634
+ }
635
+ return parsedData;
636
+ }
206
637
  async SaveJelly(fname, dir, jelly) {
207
638
  if (jelly === undefined)
208
639
  return `failed: ${fname} has empty jelly: `;
209
640
  try {
210
641
  await fs__namespace.mkdir(dir, { recursive: true });
211
642
  const filePath = path__namespace.join(dir, fname);
212
- await fs__namespace.writeFile(filePath, jelly.content, 'utf-8');
643
+ await fs__namespace.writeFile(filePath, jelly.content, "utf-8");
213
644
  return `success: ${fname} saved to ${filePath}`;
214
645
  }
215
646
  catch (error) {
@@ -217,25 +648,40 @@ class Noblog extends notionToMd.NotionToMarkdown {
217
648
  return `failed: ${fname} - ${error.message}`;
218
649
  }
219
650
  else {
220
- return 'failed: an unknown error occurred';
651
+ return "failed: an unknown error occurred";
221
652
  }
222
653
  }
223
654
  }
224
655
  async AssembleAstroFrontmatter(page) {
225
656
  let frontmatter = "";
226
657
  // default layout
227
- const ischild = this.Posts.filter(post => post.id === page.id).length > 0 ? "" : "../";
228
- frontmatter += "layout: " + ischild + "../../layouts/MarkdownPostLayout.astro" + "\n";
658
+ const ischild = this.Posts.filter((post) => post.id === page.id).length > 0 ? "" : "../";
659
+ frontmatter +=
660
+ "layout: " + ischild + "../../layouts/MarkdownPostLayout.astro" + "\n";
229
661
  // get title
230
- frontmatter += "title: " + JSON.stringify(page.properties.title?.title?.[0]?.plain_text ?? "") + "\n";
662
+ frontmatter +=
663
+ "title: " +
664
+ JSON.stringify(page.properties.title?.title?.[0]?.plain_text ?? "") +
665
+ "\n";
231
666
  // get tags
232
- frontmatter += "tags: " + JSON.stringify((page.properties.tags?.multi_select ?? []).map(tag => tag.name)) + "\n";
667
+ frontmatter +=
668
+ "tags: " +
669
+ JSON.stringify((page.properties.tags?.multi_select ?? []).map((tag) => tag.name)) +
670
+ "\n";
233
671
  // get date
234
- frontmatter += "pubDate: " + (page.properties.date?.date?.start ?? new Date().toISOString().split("T")[0]) + "\n";
672
+ frontmatter +=
673
+ "pubDate: " +
674
+ (page.properties.date?.date?.start ??
675
+ new Date().toISOString().split("T")[0]) +
676
+ "\n";
235
677
  // get archived
236
- frontmatter += "archived: " + (page.properties.archived ? "true" : "false") + "\n";
678
+ frontmatter +=
679
+ "archived: " + (page.properties.archived ? "true" : "false") + "\n";
237
680
  // get description
238
- frontmatter += "description: " + JSON.stringify(page.properties.description?.rich_text?.[0]?.plain_text ?? "") + "\n";
681
+ frontmatter +=
682
+ "description: " +
683
+ JSON.stringify(page.properties.description?.rich_text?.[0]?.plain_text ?? "") +
684
+ "\n";
239
685
  return "---\n" + frontmatter + "---\n";
240
686
  }
241
687
  }