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);
});