vitepress-theme-async
Version:
<h1 align="center">vitepress-theme-async</h1>
630 lines (620 loc) • 21.4 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// utils/shared.ts
var EXTERNAL_URL_RE, withBase, joinPath, isString, isObject;
var init_shared = __esm({
"utils/shared.ts"() {
"use strict";
EXTERNAL_URL_RE = /^[a-z]+:/i;
withBase = (base, path2) => {
return EXTERNAL_URL_RE.test(path2) || !path2.startsWith("/") ? path2 : joinPath(base, path2);
};
joinPath = (base, ...paths) => `${base}/${paths.join("/")}`.replace(/\/+/g, "/");
isString = (value) => Object.prototype.toString.call(value) === "[object String]";
isObject = (val) => Object.prototype.toString.call(val) === "[object Object]";
}
});
// utils/node/index.ts
import { spawnSync } from "node:child_process";
function getFileBirthTime(url) {
try {
const infoStr = spawnSync("git", ["log", '--pretty="%ci"', url]).stdout?.toString().replace(/["']/g, "").trim();
const timeList = infoStr.split("\n").filter((item) => Boolean(item.trim()));
if (timeList.length > 0) {
return new Date(timeList.pop()).getTime();
}
} catch (error) {
return void 0;
}
}
var init_node = __esm({
"utils/node/index.ts"() {
"use strict";
}
});
// config/rss.ts
var rss_exports = {};
__export(rss_exports, {
genFeed: () => genFeed
});
import fs from "node:fs";
import matter from "gray-matter";
import path from "node:path";
import { Feed } from "feed";
import { normalizePath } from "vite";
var genFeed;
var init_rss = __esm({
"config/rss.ts"() {
"use strict";
init_node();
init_shared();
genFeed = async (config) => {
const { themeConfig, base, title, description } = config.site;
const { rss } = themeConfig;
const posts = [];
const postDir = ((themeConfig.postDir ?? "posts") + "/").replace(/\/+/, "/");
const files = config.pages.filter((item) => item.startsWith(postDir));
const { createMarkdownRenderer } = await import("vitepress");
const mdRender = await createMarkdownRenderer(config.srcDir, config.markdown, base, config.logger);
for (const file of files) {
const filePath = config.root + "/" + file;
const fileContent = fs.readFileSync(filePath, "utf-8");
let excerpt = "";
const { data: meta } = matter(fileContent, {
//@ts-ignore
excerpt: ({ content }) => {
const reg = /<!--\s*more\s*-->/gs;
const rpt = reg.exec(content);
excerpt = rpt ? content.substring(0, rpt.index) : "";
}
});
if (!meta.title) {
const title2 = /^#\s(.+)/gm.exec(fileContent);
if (title2) {
meta.title = title2[1].trim();
} else {
meta.title = path.basename(file).replace(new RegExp(`${path.extname(file)}$`), "");
}
}
const timeZone = themeConfig.timeZone ?? 8;
if (!meta.date) {
meta.date = getFileBirthTime(file);
if (!meta.date) {
const { birthtimeMs } = fs.statSync(filePath);
meta.date = birthtimeMs;
}
} else {
meta.date = (/* @__PURE__ */ new Date(`${new Date(meta.date).toUTCString()}+${timeZone}`)).getTime();
}
meta.description = meta.description ? meta.description : excerpt ? mdRender.render(excerpt) : void 0;
const cover = themeConfig.cover;
if (Array.isArray(meta.cover)) {
meta.cover = meta.cover[0];
}
if (!isString(meta.cover)) {
meta.cover = isString(cover?.default) ? cover?.default : "";
}
const html = mdRender.render(fileContent);
const url = config.site.base + normalizePath(path.relative(config.srcDir, filePath)).replace(/(^|\/)index\.md$/, "$1").replace(/\.md$/, config.cleanUrls ? "" : ".html");
posts.push({
url,
filepath: filePath,
html,
description: meta.description,
date: meta.date,
title: meta.title,
meta
});
}
posts.sort((a, b) => +new Date(b.date) - +new Date(a.date));
if (void 0 !== rss?.limit && rss?.limit > 0) {
posts.splice(rss.limit);
}
const feed = new Feed({
id: rss?.baseUrl ?? "",
link: rss?.baseUrl,
title,
description,
copyright: "",
...rss?.feedOptions ?? {}
});
for (const post of posts) {
const { title: title2, html, description: description2, date, meta, url } = post;
const author = meta?.author || themeConfig.author || "";
const link = `${themeConfig?.rss?.baseUrl}${url}`;
let cover = meta?.cover;
if (cover && !/^http|^\/\//.test(cover)) {
cover = `${rss?.baseUrl}${(config.site.base + cover).replace("//", "/")}`;
}
feed.addItem({
title: title2,
id: link,
link,
description: description2,
content: html,
author: [
{
name: author
}
],
image: cover,
date: new Date(date)
});
}
const RSSFilename = rss?.fileName || "feed.rss";
const RSSFilepath = path.join(config.outDir, RSSFilename);
fs.writeFileSync(RSSFilepath, /\.rss$/.test(RSSFilename) ? feed.rss2() : /\.xml$/.test(RSSFilename) ? feed.atom1() : /\.json$/.test(RSSFilename) ? feed.json1() : feed.rss2());
console.log();
console.log("\u{1F389} RSS generated", RSSFilename);
console.log("\u2705 rss filepath:", RSSFilepath);
console.log("\u2705 rss url:", `${rss?.baseUrl}${config.site.base + RSSFilename}`);
console.log("\u2705 include", posts.length, "posts");
console.log();
};
}
});
// config/index.ts
init_shared();
import { mergeConfig as mergeViteConfig } from "vite";
// package.json
var version = "0.0.23";
var homepage = "https://vitepress-theme-async.imalun.com";
// config/languages.ts
var languages_default = {
"zh-Hans": {
site: {
title: "\u672C\u7AD9\u4FE1\u606F",
webmaster: "\u7F51\u7AD9\u540D\u79F0",
domain: "\u7F51\u7AD9\u94FE\u63A5",
avatar: "\u7F51\u7AD9\u5934\u50CF",
describe: "\u7F51\u7AD9\u7B80\u4ECB",
ruleText: "\u53CB\u94FE\u8981\u6C42",
contactMe: "\u8054\u7CFB\u6211"
},
title: {
links: "\u53CB\u60C5\u94FE\u63A5",
newPublish: "\u6700\u8FD1\u53D1\u5E03",
comment: "\u7559\u8A00\u677F",
author: "\u4F5C\u8005",
blog: "\u535A\u5BA2",
privacy: "\u9690\u79C1\u6743\u53CA\u8BC4\u8BBA",
more: "\u67E5\u770B\u5206\u7C7B",
allArchives: "\u6240\u6709\u5F52\u6863",
yearArchives: "{0} \u5E74\u7684\u5F52\u6863",
otherArticles: "\u5176\u4ED6\u6587\u7AE0",
unclassified: "\u672A\u5206\u7C7B"
},
menu: {
home: "\u9996\u9875",
archives: "\u5F52\u6863",
categorys: "\u5206\u7C7B",
tags: "\u6807\u7B7E",
links: "\u53CB\u94FE",
about: "\u5173\u4E8E"
},
favicon: {
showText: "(/\u2267\u25BD\u2266/)\u54A6\uFF01\u53C8\u597D\u4E86\uFF01",
hideText: "(\u25CF\u2014\u25CF)\u5594\u54DF\uFF0C\u5D29\u6E83\u5566\uFF01"
},
post: {
sticky: "\u7F6E\u9876",
noticeOutdateMessage: "\u8DDD\u79BB\u4E0A\u6B21\u66F4\u65B0\u5DF2\u7ECF {0} \u5929\u4E86, \u6587\u7AE0\u5185\u5BB9\u53EF\u80FD\u5DF2\u7ECF\u8FC7\u65F6\u3002",
rewardComment: "\u6211\u5F88\u53EF\u7231\uFF0C\u8BF7\u7ED9\u6211\u94B1",
copyright: {
author: "\u672C\u6587\u4F5C\u8005",
link: "\u672C\u6587\u94FE\u63A5",
licenseTitle: "\u7248\u6743\u58F0\u660E",
licenseContent: "\u672C\u535A\u5BA2\u6240\u6709\u6587\u7AE0\u9664\u7279\u522B\u58F0\u660E\u5916\uFF0C\u5747\u9ED8\u8BA4\u91C7\u7528 {0} \u8BB8\u53EF\u534F\u8BAE\u3002"
}
},
rightside: {
search: "\u641C\u7D22",
backToTop: "\u8FD4\u56DE\u9876\u90E8",
toc: "\u6587\u7AE0\u76EE\u5F55",
theme: {
dark: "\u5207\u6362\u5230\u6697\u9ED1\u6A21\u5F0F",
light: "\u5207\u6362\u5230\u660E\u4EAE\u6A21\u5F0F"
},
aside: {
open: "\u5207\u6362\u5355\u680F\u6A21\u5F0F",
exit: "\u9000\u51FA\u5355\u680F\u6A21\u5F0F"
},
readMode: {
open: "\u8FDB\u5165\u9605\u8BFB\u6A21\u5F0F",
exit: "\u9000\u51FA\u9605\u8BFB\u6A21\u5F0F"
}
},
footer: {
powered: "\u7531 {0} \u9A71\u52A8",
theme: "\u4E3B\u9898",
tips: "\u535A\u5BA2\u5DF2\u840C\u840C\u54D2\u8FD0\u884C {0} \u5929",
day: "\u5929",
hour: "\u65F6",
minute: "\u5206",
seconds: "\u79D2"
},
symbol: {
comma: "\uFF0C",
period: "\u3002",
colon: "\uFF1A"
},
notFound: {
title: "404 \u672A\u627E\u5230\u9875\u9762",
text: "\u60A8\u6B63\u5728\u67E5\u627E\u7684\u9875\u9762\u4E0D\u5B58\u5728\u3002\u60A8\u662F\u600E\u4E48\u5230\u8FD9\u91CC\u6765\u7684\u662F\u4E2A\u8C1C,\u4F46\u662F\u60A8\u53EF\u4EE5\u70B9\u51FB\u4E0B\u9762\u7684\u6309\u94AE\u8FD4\u56DE\u4E3B\u9875\u3002",
name: "\u9996\u9875"
}
},
en: {
site: {
title: "Site Information",
webmaster: "Webmaster",
domain: "Domain",
avatar: "Avatar",
describe: "Describe",
ruleText: "Friend chain requirements",
contactMe: "Contact Me"
},
title: {
links: "Friendly Link",
newPublish: "Newest Publications",
comment: "Message",
author: "Author",
blog: "Blog Application",
privacy: "Privacy and Comments",
more: "Read More",
allArchives: "All Archives",
yearArchives: "Archive for {0}",
otherArticles: "Other Articles",
unclassified: "Unclassified"
},
menu: {
home: "Home",
archives: "Archives",
categorys: "Categorys",
tags: "Tags",
links: "Links",
about: "About"
},
favicon: {
showText: "(/\u2267\u25BD\u2266/)Hey! Good again!",
hideText: "(\u25CF\u2014\u25CF)Oh, crash!"
},
post: {
sticky: "TOP",
rewardComment: "I'm so cute. Please give me money.",
noticeOutdateMessage: "It has been {0} days since the last update, the content of the article may be outdated.",
copyright: {
author: "Post author",
link: "Post link",
licenseTitle: "Copyright notice",
licenseContent: "All articles in this blog are licensed under {0} unless otherwise stated."
}
},
rightside: {
search: "Search",
backToTop: "Back To Top",
toc: "Article table of contents",
theme: {
dark: "Switch to dark mode",
light: "Switch to light mode"
},
aside: {
open: "Enter single column mode",
exit: "Exit single column mode"
},
readMode: {
open: "Enter reading mode",
exit: "Exit reading mode"
}
},
footer: {
powered: "Powered by {0}",
theme: "Theme",
tips: "The blog has been lovely to run {0} day",
day: "day",
hour: "hour",
minute: "minute",
seconds: "seconds"
},
symbol: {
comma: ", ",
period: ". ",
colon: ": "
},
notFound: {
title: "404 Not Found",
text: "The requested page does not exist. The method of arrival is unknown, but you can click the button below to navigate back to the homepage.",
name: "Home"
}
}
};
// config/less.ts
var less_default = (config) => {
if (config.vite?.css?.preprocessorOptions?.less.globalVars) {
config.vite.css.preprocessorOptions.less.globalVars.isReadmode = Boolean(config.themeConfig?.rightside?.readmode);
config.vite.css.preprocessorOptions.less.globalVars.isAside = Boolean(config.themeConfig?.rightside?.aside);
config.vite.css.preprocessorOptions.less.globalVars.isReward = Boolean(config.themeConfig?.reward?.enable);
config.vite.css.preprocessorOptions.less.globalVars.isSearch = Boolean(config.themeConfig?.search?.provider === "local");
config.vite.css.preprocessorOptions.less.globalVars.isCustomMdStyle = Boolean(config.themeConfig?.customMdStyle);
config.vite.css.preprocessorOptions.less.globalVars.isFancybox = Boolean(config.themeConfig?.plugin?.plugins?.fancybox?.js);
}
};
// config/markdown.ts
var mdCustomAttrPugin = (md, type, mdOptions) => {
const defaultRenderer = md.renderer.rules[type];
if (defaultRenderer) {
md.renderer.rules[type] = function(tokens, idx, options, env, self) {
const token = tokens[idx];
if (mdOptions) {
for (const i in mdOptions) {
typeof mdOptions[i] === "function" ? mdOptions[i](token) : token.attrSet(i, mdOptions[i]);
}
}
return defaultRenderer(tokens, idx, options, env, self);
};
}
};
var markdown_default = (config) => {
const mdConfig = config.markdown?.config;
config.markdown.config = (md) => {
mdCustomAttrPugin(md, "image", {
"data-tag": "post-image",
loading: "lazy",
onload: "this.onload=null;this.style.opacity=1;"
});
mdConfig?.(md);
};
};
// config/index.ts
var defaultConfig = {
lang: "zh-Hans",
vite: {
css: {
preprocessorOptions: {
less: {
globalVars: {
isReadmode: true,
isAside: true,
isReward: true,
isSearch: true,
isNoticeOutdate: true,
isCustomMdStyle: false
}
}
}
}
},
markdown: {},
themeConfig: {
pageLoading: true,
themeLoading: true,
customMdStyle: false,
author: "async",
postDir: "posts",
indexGenerator: {
perPage: 10,
orderBy: "-date"
},
archiveGenerator: {
perPage: 10,
orderBy: "-date",
dateFmt: "YYYY-MM"
},
page: {
archives: "/archives",
categories: "/categories",
tags: "/tags",
index: "/"
},
user: {
name: "ThemeAsync",
firstName: "Theme",
lastName: "Async",
email: void 0,
domain: "\u7AD9\u70B9\u57DF\u540D",
describe: "\u7F51\u7AD9\u7B80\u4ECB\u3002",
ruleText: "\u6682\u4E0D\u63A5\u53D7\u4E2A\u4EBA\u535A\u5BA2\u4EE5\u5916\u7684\u53CB\u94FE\u7533\u8BF7\uFF0C\u786E\u4FDD\u60A8\u7684\u7F51\u7AD9\u5185\u5BB9\u79EF\u6781\u5411\u4E0A\uFF0C\u6587\u7AE0\u81F3\u5C1130\u7BC7\uFF0C\u539F\u521B70%\u4EE5\u4E0A\uFF0C\u90E8\u7F72HTTPS\u3002"
},
favicon: {
visibilitychange: true,
showText: "favicon.showText",
hideText: "favicon.hideText"
},
banner: {
type: "img",
bannerTitle: "\u6811\u6DF1\u65F6\u89C1\u9E7F\uFF0C<br>\u6EAA\u5348\u4E0D\u95FB\u949F\u3002",
bannerText: "Hi my new friend!",
position: "top",
fit: "cover"
},
sidebar: {
typedTextPrefix: "I`m",
typedText: void 0
},
footer: {
powered: {
enable: true
},
beian: {
enable: false,
icp: void 0
},
copyrightYear: void 0,
liveTime: {
enable: false,
prefix: "footer.tips",
startTime: "04/10/2022 17:00:00"
}
},
cover: {
type: "img"
},
about: {
title: "\u5982\u679C\u4E00\u5207\u90FD\u662F\u955C\u82B1\u6C34\u6708\uFF0C\u90A3\u5C31\u8BA9\u8FD9\u4E07\u7269\u8D70\u5411\u7EC8\u7ED3\u3002\u5982\u679C\u4E00\u5207\u7686\u662F\u547D\u4E2D\u6CE8\u5B9A\uFF0C\u90A3\u5C31\u8BA9\u8FD9\u4E16\u754C\u6D88\u5931\u6B86\u5C3D\u3002",
introduction: "\u5927\u5BB6\u597D\uFF0C\u6211\u662F <strong>Async</strong>\uFF0C\u5F88\u9AD8\u5174\u60A8\u80FD\u5728\u6D69\u701A\u5982\u70DF\u7684\u4E92\u8054\u7F51\u4E16\u754C\u91CC\u53D1\u73B0\u8FD9\u4E2A\u535A\u5BA2\uFF0C\u66F4\u611F\u8C22\u60A8\u80FD\u591F\u9976\u6709\u5174\u81F4\u5730\u6D4F\u89C8\u8FD9\u4E2A\u9875\u9762\u3002\u5EFA\u7ACB\u8FD9\u4E2A Blog \u662F\u51FA\u4E8E\u5174\u8DA3\u7231\u597D\uFF0C\u6211\u5C06\u5728\u6B64\u5206\u4F1A\u5206\u4EAB\u4E00\u4E9B\u5B66\u4E60\u7B14\u8BB0\uFF0C\u53EF\u80FD\u8FD8\u4F1A\u5206\u4EAB\u5C11\u8BB8\u56FE\u7247\u3001\u89C6\u9891\u4EE5\u53CA\u5176\u4ED6\u6709\u8DA3\u4E1C\u897F\u7684\u94FE\u63A5\u3002",
blog: `<ul class="trm-list">
<li>\u7A0B\u5E8F\uFF1AVitepress </li>
<li>\u4E3B\u9898\uFF1Avitepress-theme-async </li>
</ul>`,
privacy: "\u672C\u7F51\u7AD9\u4E0D\u4F1A\u8FFD\u8E2A\u8BBF\u5BA2\u884C\u4E3A\uFF0C\u4E14\u4E0D\u8981\u6C42\u8BBF\u5BA2\u63D0\u4F9B\u4EFB\u4F55\u654F\u611F\u4FE1\u606F\uFF08\u6BD4\u5982\u771F\u5B9E\u59D3\u540D\u3001\u8EAB\u4EFD\u8BC1\u53F7\u7801\u3001\u624B\u673A\u53F7\u7B49\uFF09\uFF0C\u56E0\u800C\u4E5F\u4E0D\u5B58\u5728\u4EFB\u4F55\u9690\u79C1\u6CC4\u6F0F\u95EE\u9898\u3002\u8BBF\u5BA2\u53C2\u4E0E\u8BC4\u8BBA\uFF0C\u5FC5\u987B\u9075\u5B88\u6CD5\u5F8B\u6CD5\u89C4\u548C\u57FA\u672C\u9053\u5FB7\u89C4\u8303\uFF0C\u6587\u660E\u793C\u8C8C\u3002\u4E25\u7981\u53D1\u5E03\u4EFB\u4F55\u6709\u5173\u6DEB\u79FD\u3001\u53CD\u52A8\u3001\u66B4\u529B\u3001\u535A\u5F69\u3001\u6050\u5413\u3001\u4F4E\u4FD7\u7684\u5185\u5BB9\u6216\u8FDD\u6CD5\u4FE1\u606F\uFF0C\u5728\u5C0A\u91CD\u8A00\u8BBA\u81EA\u7531\u7684\u540C\u65F6\u8BF7\u4FDD\u6301\u548C\u5E73\u4E0E\u7406\u6027\u3002\u8BF7\u52FF\u5BF9\u4ED6\u4EBA\u91C7\u53D6\u4E0D\u53CB\u597D\u7684\u8BC4\u8BBA\u6216\u5176\u5B83\u8FC7\u6FC0\u884C\u4E3A\u3002"
},
postPagination: {
enable: true,
type: "small"
},
creativeCommons: {
license: "by-nc-sa",
language: "deed.zh-hans",
post: true,
clipboard: false
},
outline: {
level: [2, 3],
label: "\u76EE\u5F55\u5217\u8868"
},
noticeOutdate: {
style: "simple",
limitDay: 365,
position: "top"
},
rss: {
baseUrl: "",
enable: false,
limit: 20
},
categorieCard: {
enable: true,
len: 2
},
notFound: {
title: "notFound.title",
text: "notFound.text",
path: "/",
name: "notFound.name"
},
languages: languages_default,
plugin: {
thirdPartyProvider: "https://npm.elemecdn.com",
plugins: {
fancybox: {
css: "/@fancyapps/ui@4.0/dist/fancybox.css",
js: "/@fancyapps/ui@4.0/dist/fancybox.umd.js"
},
flickrJustifiedGallery: "/flickr-justified-gallery@latest/dist/fjGallery.min.js"
}
}
}
};
var defineConfig = (config) => {
if (Array.isArray(config.themeConfig?.outline?.level)) {
defaultConfig.themeConfig.outline.level = [];
}
if (config.themeConfig?.page?.categorys && !config.themeConfig?.page?.categories) {
config.themeConfig.page.categories = config.themeConfig.page.categorys;
}
config = mergeConfig(defaultConfig, config);
config.head = config.head ?? [];
if (config.themeConfig?.favicon?.icon16) {
config.head.push([
"link",
{
href: withBase(config.base ?? "", config.themeConfig.favicon.icon16),
rel: "icon",
type: "image/png",
sizes: "16x16"
}
]);
}
if (config.themeConfig?.favicon?.icon32) {
config.head.push([
"link",
{
href: withBase(config.base ?? "", config.themeConfig.favicon.icon32),
rel: "icon",
type: "image/png",
sizes: "32x32"
}
]);
}
if (config.themeConfig?.favicon?.appleTouchIcon) {
config.head.push([
"link",
{
href: withBase(config.base ?? "", config.themeConfig.favicon.appleTouchIcon),
rel: "apple-touch-icon",
sizes: "180x180"
}
]);
}
if (config.themeConfig?.favicon?.webmanifest) {
config.head.push([
"link",
{
href: withBase(config.base ?? "", config.themeConfig.favicon.webmanifest),
rel: "manifest"
}
]);
}
if (config.themeConfig?.rewritePost) {
config.rewrites = {
...config.rewrites ?? {},
[`${config.themeConfig.postDir}/(.*)`]: "(.*)"
};
}
const selfBuildEnd = config.buildEnd;
config.buildEnd = async (siteConfig) => {
console.log();
console.log(`\u{1F496} Vitepress-Theme-Async. ${version} Guide: ${homepage}`);
console.log();
if (config?.themeConfig?.rss?.enable) {
await selfBuildEnd?.(siteConfig);
(await Promise.resolve().then(() => (init_rss(), rss_exports)))?.genFeed(siteConfig);
}
};
less_default(config);
setFancybox(config);
markdown_default(config);
return config;
};
var setFancybox = (config) => {
const { thirdPartyProvider, plugins } = config.themeConfig?.plugin ?? {};
if (plugins?.fancybox?.js) {
config.head = config.head ?? [];
config.head.push(["link", { rel: "stylesheet", href: `${thirdPartyProvider}${plugins.fancybox.css}` }]);
}
};
var mergeConfig = (a, b, isRoot = true) => {
const merged = { ...a };
for (const key in b) {
const value = b[key];
if (value == null) {
continue;
}
const existing = merged[key];
if (Array.isArray(existing) && Array.isArray(value)) {
merged[key] = [...existing, ...value];
continue;
}
if (isObject(existing) && isObject(value)) {
if (isRoot && key === "vite") {
merged[key] = mergeViteConfig(existing, value);
} else {
merged[key] = mergeConfig(existing, value, false);
}
continue;
}
merged[key] = value;
}
return merged;
};
export {
defaultConfig,
defineConfig
};