Skip to content

Commit d32f473

Browse files
authored
Merge pull request #247 from ATQQ/feature/pagefind-filter-and-sort
feat: add shared lib
2 parents fe63db1 + 67f9954 commit d32f473

File tree

39 files changed

+736
-765
lines changed

39 files changed

+736
-765
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121
"build": "pnpm --filter blogpress build",
2222
"buildTheme": "pnpm --filter @sugarat/theme build",
2323
"buildlib": "pnpm run /^build:.*/",
24-
"build:pagefind": "pnpm --filter vitepress-plugin-pagefind build",
25-
"build:rss": "pnpm --filter vitepress-plugin-rss build",
24+
"build:shared": "pnpm --filter @sugarat/theme-shared build",
25+
"build:pagefind": "wait-on packages/shared/dist && pnpm --filter vitepress-plugin-pagefind build",
26+
"build:rss": "wait-on packages/shared/dist && pnpm --filter vitepress-plugin-rss build",
2627
"build:create": "pnpm --filter @sugarat/create-theme build",
2728
"build:theme-only": "wait-on packages/vitepress-plugin-rss/dist packages/vitepress-plugin-pagefind/dist && pnpm --filter @sugarat/theme build:node",
2829
"serve": "pnpm --filter blogpress serve",

packages/blogpress/.vitepress/config.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import process from 'node:process'
22
import { getThemeConfig } from '@sugarat/theme/node'
33
import type { Theme } from '@sugarat/theme'
4-
import type { RSSOptions } from 'vitepress-plugin-rss'
5-
import { RssPlugin } from 'vitepress-plugin-rss'
64
import { defineConfig } from 'vitepress'
75

86
const baseUrl = 'https://sugarat.top'
97
const weekly = `${baseUrl}/weekly`
10-
const RSSWeekly: RSSOptions = {
8+
const RSSWeekly: Theme.RSSOptions = {
119
title: '视野修炼 - 技术周刊',
1210
baseUrl,
1311
description: '每周会精选出一些 优质&有趣 的内容做推送(大前端为主),包含但不限于 优质文章,开源库,工具网站,有意思的知识',
@@ -58,7 +56,7 @@ const blogTheme = getThemeConfig({
5856
]
5957
},
6058
themeColor: 'el-blue',
61-
RSS,
59+
RSS: [RSS, RSSWeekly],
6260
author: '粥里有勺糖',
6361
comment: {
6462
repo: 'ATQQ/sugar-blog',
@@ -194,7 +192,9 @@ const blogTheme = getThemeConfig({
194192
random: true,
195193
limit: 6,
196194
},
197-
// search: false,
195+
search: {
196+
showDate: true,
197+
},
198198
recommend: {
199199
showSelf: true,
200200
nextText: '下一页',
@@ -288,10 +288,7 @@ export default defineConfig({
288288
server: {
289289
port: 4000,
290290
host: '0.0.0.0'
291-
},
292-
plugins: [
293-
RssPlugin(RSSWeekly)
294-
]
291+
}
295292
},
296293
vue: {
297294
template: {

packages/blogpress/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ publish: false
44

55
# CHANGELOG
66

7+
## 2.0.52
8+
### Patch Changes
9+
- @sugarat/theme@0.4.4
10+
711
## 2.0.51
12+
813
### Patch Changes
914

1015
- Updated dependencies

packages/blogpress/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "blogpress",
33
"type": "module",
4-
"version": "2.0.51",
4+
"version": "2.0.52",
55
"private": true,
66
"license": "MIT",
77
"scripts": {
@@ -14,7 +14,6 @@
1414
"@sugarat/theme": "workspace:*",
1515
"element-plus": "^2.7.2",
1616
"vitepress": "1.2.3",
17-
"vitepress-plugin-rss": "workspace:*",
1817
"vue": "^3.4.26"
1918
},
2019
"devDependencies": {

packages/create-theme/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# @sugarat/create-theme
22

3+
## 0.0.67
4+
5+
### Patch Changes
6+
7+
- chore: update deps
8+
39
## 0.0.66
410

511
### Patch Changes

packages/create-theme/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sugarat/create-theme",
3-
"version": "0.0.66",
3+
"version": "0.0.67",
44
"description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
55
"author": "粥里有勺糖",
66
"license": "MIT",

packages/create-theme/public/template/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
},
1212
"dependencies": {
1313
"@element-plus/icons-vue": "^2.3.1",
14-
"@sugarat/theme": "^0.4.3",
14+
"@sugarat/theme": "^0.4.4",
1515
"element-plus": "^2.7.2",
1616
"vue": "3.4.26"
1717
},

packages/shared/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# @sugarat/theme-shared
2+
3+
## 0.0.1
4+
5+
### Patch Changes
6+
7+
- feat: init shared package

packages/shared/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# @sugarat/theme-shared
2+
3+
Internal utility functions and constants shared across VitePress sources: [@sugarat/theme](https://www.npmjs.com/package/@sugarat/theme), [vitepress-plugin-rss](https://www.npmjs.com/package/vitepress-plugin-rss), [vitepress-plugin-pagefind](https://www.npmjs.com/package/vitepress-plugin-pagefind).

packages/shared/package.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "@sugarat/theme-shared",
3+
"version": "0.0.1",
4+
"description": "@sugarat/theme-shared",
5+
"author": "sugar",
6+
"license": "MIT",
7+
"homepage": "https://github.com/ATQQ/sugar-blog/tree/master/packages/shared",
8+
"repository": {
9+
"type": "git",
10+
"url": "git+https://github.com/ATQQ/sugar-blog.git"
11+
},
12+
"bugs": {
13+
"url": "https://github.com/ATQQ/sugar-blog/issues"
14+
},
15+
"keywords": [
16+
"shared",
17+
"utils",
18+
"vitepress"
19+
],
20+
"exports": {
21+
".": {
22+
"import": "./dist/index.mjs",
23+
"require": "./dist/index.js"
24+
}
25+
},
26+
"main": "dist/index.js",
27+
"module": "dist/index.mjs",
28+
"types": "dist/index.d.ts",
29+
"files": [
30+
"dist"
31+
],
32+
"scripts": {
33+
"dev": "npx tsup src/index.ts --dts --watch --format esm,cjs",
34+
"build": "npx tsup src/index.ts --dts --format esm,cjs --silent"
35+
},
36+
"dependencies": {
37+
"cross-spawn": "^7.0.3",
38+
"gray-matter": "^4.0.3"
39+
},
40+
"devDependencies": {
41+
"@types/cross-spawn": "^6.0.6",
42+
"p-limit": "4"
43+
}
44+
}

packages/shared/src/date.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
export function formatDate(d: any, fmt = 'yyyy-MM-dd hh:mm:ss') {
2+
if (!(d instanceof Date)) {
3+
d = new Date(d)
4+
}
5+
const o: any = {
6+
'M+': d.getMonth() + 1, // 月份
7+
'd+': d.getDate(), // 日
8+
'h+': d.getHours(), // 小时
9+
'm+': d.getMinutes(), // 分
10+
's+': d.getSeconds(), // 秒
11+
'q+': Math.floor((d.getMonth() + 3) / 3), // 季度
12+
'S': d.getMilliseconds() // 毫秒
13+
}
14+
if (/(y+)/.test(fmt)) {
15+
fmt = fmt.replace(
16+
RegExp.$1,
17+
`${d.getFullYear()}`.substr(4 - RegExp.$1.length)
18+
)
19+
}
20+
// eslint-disable-next-line no-restricted-syntax
21+
for (const k in o) {
22+
if (new RegExp(`(${k})`).test(fmt))
23+
fmt = fmt.replace(
24+
RegExp.$1,
25+
RegExp.$1.length === 1 ? o[k] : `00${o[k]}`.substr(`${o[k]}`.length)
26+
)
27+
}
28+
return fmt
29+
}
30+
31+
export function formatShowDate(date: Date | string) {
32+
const source = +new Date(date)
33+
const now = +new Date()
34+
const diff = now - source
35+
const oneSeconds = 1000
36+
const oneMinute = oneSeconds * 60
37+
const oneHour = oneMinute * 60
38+
const oneDay = oneHour * 24
39+
const oneWeek = oneDay * 7
40+
if (diff < oneMinute) {
41+
return `${Math.floor(diff / oneSeconds)}秒前`
42+
}
43+
if (diff < oneHour) {
44+
return `${Math.floor(diff / oneMinute)}分钟前`
45+
}
46+
if (diff < oneDay) {
47+
return `${Math.floor(diff / oneHour)}小时前`
48+
}
49+
if (diff < oneWeek) {
50+
return `${Math.floor(diff / oneDay)}天前`
51+
}
52+
53+
return formatDate(new Date(date), 'yyyy-MM-dd')
54+
}

packages/shared/src/fs.ts

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import fs from 'node:fs'
2+
import os from 'node:os'
3+
import path from 'node:path'
4+
import process from 'node:process'
5+
import { spawn } from 'cross-spawn'
6+
import matter from 'gray-matter'
7+
import pLimit from 'p-limit'
8+
9+
const timeLimit = pLimit(+(process.env.P_LIMT_MAX || os.cpus().length))
10+
11+
/**
12+
* 获取 markdown 内容中的标题
13+
*/
14+
export function getDefaultTitle(content: string) {
15+
const match = content.match(/^(#+)\s+(.+)/m)
16+
return match?.[2] || ''
17+
}
18+
19+
const cache = new Map<string, Date | undefined>()
20+
/**
21+
* 获取文件最后修改时间
22+
* 优先使用 git 命令获取,如果失败则使用 fs.stat 获取
23+
*/
24+
export async function getFileLastModifyTime(url: string) {
25+
const cached = cache.get(url)
26+
if (cached) {
27+
return cached
28+
}
29+
let date = await timeLimit(() => getFileLastModifyTimeByGit(url))
30+
if (!date) {
31+
date = await getFileLastModifyTimeByFs(url)
32+
}
33+
if (date) {
34+
cache.set(url, date)
35+
}
36+
return date
37+
}
38+
39+
export function getFileLastModifyTimeByGit(url: string): Promise<Date | undefined> {
40+
return new Promise((resolve) => {
41+
// 使用异步回调
42+
const child = spawn('git', ['log', '-1', '--pretty="%ai"', url])
43+
let output = ''
44+
child.stdout.on('data', d => (output += String(d)))
45+
child.on('close', async () => {
46+
let date: Date | undefined
47+
if (output.trim()) {
48+
date = new Date(output)
49+
}
50+
resolve(date)
51+
})
52+
child.on('error', async () => {
53+
resolve(undefined)
54+
})
55+
})
56+
}
57+
58+
export async function getFileBirthTimeByFs(url: string) {
59+
try {
60+
const fsStat = await fs.promises.stat(url)
61+
return fsStat.birthtime
62+
}
63+
catch {
64+
return undefined
65+
}
66+
}
67+
68+
export async function getFileLastModifyTimeByFs(url: string) {
69+
try {
70+
const fsStat = await fs.promises.stat(url)
71+
return fsStat.mtime
72+
}
73+
catch {
74+
return undefined
75+
}
76+
}
77+
78+
export const EXTERNAL_URL_RE = /^[a-z]+:/i
79+
80+
/**
81+
* Join two paths by resolving the slash collision.
82+
*/
83+
export function joinPath(base: string, path: string): string {
84+
return `${base}${path}`.replace(/\/+/g, '/')
85+
}
86+
87+
export function withBase(base: string, path: string) {
88+
return EXTERNAL_URL_RE.test(path) || path.startsWith('.')
89+
? path
90+
: joinPath(base, path)
91+
}
92+
93+
export const grayMatter = matter
94+
95+
export function getTextSummary(text: string, count = 100) {
96+
return (
97+
text
98+
// 首个标题
99+
?.replace(/^#+\s+.*/, '')
100+
// 除去标题
101+
?.replace(/#/g, '')
102+
// 除去图片
103+
?.replace(/!\[.*?\]\(.*?\)/g, '')
104+
// 除去链接
105+
?.replace(/\[(.*?)\]\(.*?\)/g, '$1')
106+
// 除去加粗
107+
?.replace(/\*\*(.*?)\*\*/g, '$1')
108+
?.split('\n')
109+
?.filter(v => !!v)
110+
?.join('\n')
111+
?.replace(/>(.*)/, '')
112+
?.replace(/</g, '&lt;').replace(/>/g, '&gt;')
113+
?.trim()
114+
?.slice(0, count)
115+
)
116+
}
117+
118+
const windowsSlashRE = /\\/g
119+
export const isWindows = os.platform() === 'win32'
120+
121+
export function slash(p: string): string {
122+
return p.replace(windowsSlashRE, '/')
123+
}
124+
125+
export function normalizePath(id: string): string {
126+
return path.posix.normalize(isWindows ? slash(id) : id)
127+
}

packages/shared/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './fs'
2+
export * from './date'

packages/shared/tsconfig.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"compilerOptions": {
3+
"target": "esnext",
4+
"lib": ["ESNext", "DOM"],
5+
"jsx": "preserve",
6+
"module": "esnext",
7+
"moduleResolution": "node",
8+
"baseUrl": ".",
9+
"resolveJsonModule": true,
10+
"allowJs": true,
11+
"outDir": "dist",
12+
"esModuleInterop": true,
13+
"strict": true,
14+
"noUnusedLocals": true,
15+
"skipLibCheck": true
16+
}
17+
}

packages/theme/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# @sugarat/theme
22

3+
## 0.4.4
4+
5+
### Patch Changes
6+
7+
- feat: RSS 生成支持配置多个
8+
- feat: pagefind 配置复用插件配置
9+
- chore: 分离 shared 方法库
10+
- Updated dependencies
11+
12+
13+
314
## 0.4.3
415

516
### Patch Changes

0 commit comments

Comments
 (0)