scripts/generate-picked-posts-info.mjs (93 lines of code) (raw):

import { stat, readFile, writeFile } from 'fs/promises'; import { join, dirname } from 'path'; import Listr from 'listr'; import matter from 'gray-matter'; import { remark } from 'remark'; import { visit } from 'unist-util-visit'; import { format } from 'date-fns'; const configs = ['../blog/en/config/picked-posts.json', '../blog/zh/config/picked-posts.json']; const parser = remark(); function createExcerpt(fileString) { const mdast = parser.parse(fileString); let excerpt = ''; visit(mdast, ['text', 'inlineCode'], (node) => { excerpt += node.value; }); return excerpt; } const tasks = new Listr([ { title: `Check picked blog config files exist`, task: () => Promise.all( configs.map((f) => stat(f).then((status) => (status.isFile() ? Promise.resolve() : Promise.reject(new Error(`${f} is not a file`))))), ), }, { title: `Generate picked blog info files`, task: () => new Listr( configs.map((config) => ({ title: `picking from ${config}`, task: () => readFile(config, 'utf8') .then((json) => JSON.parse(json)) .then((paths) => Promise.all( paths.map((path) => readFile(`../${path}`, 'utf8').then((content) => { const { data, excerpt } = matter(content, { excerpt: true, excerpt_separator: '<!--truncate-->', }); const summary = createExcerpt(excerpt); const locale = path.includes('/zh/blog') ? 'zh-CN' : 'en-US'; const rawDate = new Date( path.substring('blog/en/blog/'.length, 'blog/en/blog/2022/07/30'.length), ); const date = rawDate.toISOString(); const formattedDate = format( rawDate, locale === 'zh-CN' ? 'yyyy年MM月d日' : 'MMM dd, yyyy', ); return { ...data, authors: data?.authors?.map((v) => { if (v.image_url) { const res = v; res.imageURL = v.image_url; delete res.image_url; return res; } return v; }), tags: data?.tags?.map((v) => ({ label: v, permalink: locale === 'zh-CN' ? `/zh/blog/tags/${v}` : `/blog/tags/${v}`, })) || [], summary, permalink: path .substring(locale === 'zh-CN' ? 'blog'.length : 'blog/en'.length) .slice(0, -'.md'.length), date, formattedDate, }; })), ) .then( (matters) => `/*THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.*/\nconst config = ${JSON.stringify( matters, null, 2, )};\nmodule.exports = config;`, ) .then((content) => writeFile(join(dirname(config), 'picked-posts-info.js'), content, 'utf-8'))), })), { concurrent: configs.length }, ), }, ]); tasks .run() .then(() => { console.log(`[Finish] Generate picked blog info files`); }) .catch((err) => { console.error(err); process.exit(1); });