@tnotesjs/core 0.0.2 → 0.0.3
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/README.md +84 -84
- package/dist/{chunk-LZQDLU3S.js → chunk-NI5B4S3T.js} +12 -2
- package/dist/cli/index.js +1 -1
- package/dist/vitepress/config/index.js +60 -17
- package/package.json +1 -1
- package/types/config.ts +61 -61
- package/types/index.ts +11 -11
- package/types/note.ts +33 -33
- package/vitepress/assets/icons/icon__check.svg +3 -3
- package/vitepress/assets/icons/icon__clipboard.svg +7 -7
- package/vitepress/assets/icons/icon__close.svg +1 -1
- package/vitepress/assets/icons/icon__collapse.svg +1 -1
- package/vitepress/assets/icons/icon__confirm.svg +1 -1
- package/vitepress/assets/icons/icon__copy.svg +4 -4
- package/vitepress/assets/icons/icon__focus.svg +1 -1
- package/vitepress/assets/icons/icon__fold.svg +3 -3
- package/vitepress/assets/icons/icon__folder.svg +1 -1
- package/vitepress/assets/icons/icon__fullscreen.svg +1 -1
- package/vitepress/assets/icons/icon__fullscreen_exit.svg +1 -1
- package/vitepress/assets/icons/icon__github.svg +3 -3
- package/vitepress/assets/icons/icon__mindmap.svg +1 -1
- package/vitepress/assets/icons/icon__next.svg +1 -1
- package/vitepress/assets/icons/icon__number_gray.svg +1 -1
- package/vitepress/assets/icons/icon__number_purple.svg +1 -1
- package/vitepress/assets/icons/icon__prev.svg +1 -1
- package/vitepress/assets/icons/icon__restore.svg +1 -1
- package/vitepress/assets/icons/icon__rotate.svg +4 -4
- package/vitepress/assets/icons/icon__search.svg +1 -1
- package/vitepress/assets/icons/icon__sidebar_collapsed.svg +1 -1
- package/vitepress/assets/icons/icon__sidebar_opened.svg +1 -1
- package/vitepress/assets/icons/icon__totop.svg +5 -5
- package/vitepress/assets/icons/icon__vscode.svg +5 -5
- package/vitepress/assets/icons/icon__zoom_fit.svg +1 -1
- package/vitepress/assets/icons/icon__zoom_in.svg +1 -1
- package/vitepress/assets/icons/icon__zoom_out.svg +1 -1
- package/vitepress/assets/icons/icon__zoom_reset.svg +1 -1
- package/vitepress/assets/icons/index.ts +38 -38
- package/vitepress/components/BilibiliOutsidePlayer/BilibiliOutsidePlayer.vue +20 -20
- package/vitepress/components/CodeBlockFullscreen/CodeBlockFullscreen.vue +373 -373
- package/vitepress/components/CodeBlockFullscreen/index.ts +115 -115
- package/vitepress/components/CodeBlockFullscreen/styles.css +64 -64
- package/vitepress/components/Discussions/Discussions.module.scss +32 -32
- package/vitepress/components/Discussions/Discussions.vue +211 -211
- package/vitepress/components/EnWordList/EnWordList.module.scss +124 -124
- package/vitepress/components/EnWordList/EnWordList.vue +543 -543
- package/vitepress/components/EnWordList/RightClickMenu.module.scss +22 -22
- package/vitepress/components/EnWordList/RightClickMenu.vue +66 -66
- package/vitepress/components/Footprints/Footprints.module.scss +93 -93
- package/vitepress/components/Footprints/Footprints.vue +377 -377
- package/vitepress/components/Layout/AboutModal.module.scss +233 -233
- package/vitepress/components/Layout/AboutModal.vue +105 -105
- package/vitepress/components/Layout/AboutPanel.vue +266 -266
- package/vitepress/components/Layout/ContentCollapse.vue +603 -603
- package/vitepress/components/Layout/CustomSidebar.vue +605 -605
- package/vitepress/components/Layout/DocBeforeControls.vue +139 -139
- package/vitepress/components/Layout/DocFooter.vue +225 -225
- package/vitepress/components/Layout/ImagePreview.module.scss +201 -201
- package/vitepress/components/Layout/ImagePreview.vue +281 -281
- package/vitepress/components/Layout/Layout.module.scss +661 -661
- package/vitepress/components/Layout/Layout.vue +542 -542
- package/vitepress/components/Layout/NoteStatus.vue +140 -140
- package/vitepress/components/Layout/SidebarItems.vue +263 -263
- package/vitepress/components/Layout/SidebarNavBefore.vue +92 -92
- package/vitepress/components/Layout/Swiper.vue +167 -167
- package/vitepress/components/Layout/ToggleFullContent.module.scss +11 -11
- package/vitepress/components/Layout/ToggleFullContent.vue +34 -34
- package/vitepress/components/Layout/ToggleSidebar.module.scss +11 -11
- package/vitepress/components/Layout/ToggleSidebar.vue +35 -35
- package/vitepress/components/Layout/composables/useCollapseControl.ts +88 -88
- package/vitepress/components/Layout/composables/useNoteConfig.ts +121 -121
- package/vitepress/components/Layout/composables/useNoteSave.ts +173 -173
- package/vitepress/components/Layout/composables/useNoteValidation.ts +85 -85
- package/vitepress/components/Layout/composables/useRedirect.ts +110 -110
- package/vitepress/components/Layout/composables/useVSCodeIntegration.ts +85 -85
- package/vitepress/components/Layout/homeReadme.data.ts +124 -124
- package/vitepress/components/LoadingPage/LoadingPage.vue +192 -192
- package/vitepress/components/MarkMap/MarkMap.module.scss +159 -159
- package/vitepress/components/MarkMap/MarkMap.vue +404 -404
- package/vitepress/components/Mermaid/Mermaid.module.scss +275 -275
- package/vitepress/components/Mermaid/Mermaid.vue +364 -364
- package/vitepress/components/NotesTable/NotesTable.module.scss +77 -77
- package/vitepress/components/NotesTable/NotesTable.vue +98 -98
- package/vitepress/components/NotesTable/README.md +67 -67
- package/vitepress/components/Settings/Settings.module.scss +433 -433
- package/vitepress/components/Settings/Settings.vue +306 -306
- package/vitepress/components/SidebarCard/MindMapView.vue +483 -483
- package/vitepress/components/SidebarCard/NotesTrendChart.vue +108 -108
- package/vitepress/components/SidebarCard/SidebarCard.vue +948 -948
- package/vitepress/components/Tooltip/Tooltip.vue +70 -70
- package/vitepress/components/constants.ts +91 -91
- package/vitepress/components/notesConfig.data.ts +73 -73
- package/vitepress/components/sidebar.data.ts +59 -59
- package/vitepress/components/tnotes-config.data.ts +21 -21
- package/vitepress/components/utils.ts +26 -26
- package/vitepress/config/index.ts +141 -141
- package/vitepress/configs/constants.ts +26 -26
- package/vitepress/configs/head.config.ts +25 -25
- package/vitepress/configs/index.ts +9 -9
- package/vitepress/configs/markdown-it.d.ts +23 -23
- package/vitepress/configs/markdown.config.ts +366 -366
- package/vitepress/configs/theme.config.ts +108 -108
- package/vitepress/plugins/buildProgressPlugin.ts +466 -390
- package/vitepress/plugins/getNoteByConfigIdPlugin.ts +107 -107
- package/vitepress/plugins/renameNotePlugin.ts +60 -60
- package/vitepress/plugins/updateConfigPlugin.ts +63 -63
- package/vitepress/theme/index.ts +95 -95
- package/vitepress/theme/styles/base.scss +50 -50
- package/vitepress/theme/styles/components/404.scss +31 -31
- package/vitepress/theme/styles/components/collapse.scss +175 -175
- package/vitepress/theme/styles/components/markmap.scss +101 -101
- package/vitepress/theme/styles/components/swiper.scss +255 -255
- package/vitepress/theme/styles/index.scss +25 -25
- package/vitepress/theme/styles/layout.scss +62 -62
- package/vitepress/theme/styles/utilities.scss +39 -39
- package/vitepress/theme/styles/vitepress-override.scss +25 -25
|
@@ -1,107 +1,107 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* .vitepress/tnotes/vitepress/plugins/getNoteByConfigIdPlugin.ts
|
|
3
|
-
*
|
|
4
|
-
* VitePress 插件 - 根据 configId 查询笔记信息
|
|
5
|
-
*/
|
|
6
|
-
import type { PluginOption } from 'vite'
|
|
7
|
-
import { NoteIndexCache } from '../../core'
|
|
8
|
-
import { logger } from '../../utils'
|
|
9
|
-
|
|
10
|
-
export function getNoteByConfigIdPlugin(): PluginOption {
|
|
11
|
-
return {
|
|
12
|
-
name: 'tnotes-get-note-by-config-id',
|
|
13
|
-
|
|
14
|
-
configureServer(server) {
|
|
15
|
-
// 添加中间件处理查询请求
|
|
16
|
-
server.middlewares.use(async (req, res, next) => {
|
|
17
|
-
if (
|
|
18
|
-
req.url?.startsWith('/__tnotes_get_note?') &&
|
|
19
|
-
req.method === 'GET'
|
|
20
|
-
) {
|
|
21
|
-
try {
|
|
22
|
-
// 解析查询参数
|
|
23
|
-
const url = new URL(req.url, `http://${req.headers.host}`)
|
|
24
|
-
const configId = url.searchParams.get('configId')
|
|
25
|
-
|
|
26
|
-
if (!configId) {
|
|
27
|
-
res.statusCode = 400
|
|
28
|
-
res.setHeader('Content-Type', 'application/json')
|
|
29
|
-
res.end(
|
|
30
|
-
JSON.stringify({
|
|
31
|
-
success: false,
|
|
32
|
-
error: 'Missing configId parameter',
|
|
33
|
-
}),
|
|
34
|
-
)
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// 确保笔记索引缓存已初始化
|
|
39
|
-
const noteIndexCache = NoteIndexCache.getInstance()
|
|
40
|
-
if (!noteIndexCache.isInitialized()) {
|
|
41
|
-
res.statusCode = 503
|
|
42
|
-
res.setHeader('Content-Type', 'application/json')
|
|
43
|
-
res.end(
|
|
44
|
-
JSON.stringify({
|
|
45
|
-
success: false,
|
|
46
|
-
error: 'Service not initialized',
|
|
47
|
-
}),
|
|
48
|
-
)
|
|
49
|
-
return
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// 从索引缓存中查询笔记
|
|
53
|
-
const noteItem = noteIndexCache.getByConfigId(configId)
|
|
54
|
-
|
|
55
|
-
if (!noteItem) {
|
|
56
|
-
// 笔记不存在或已被删除
|
|
57
|
-
res.statusCode = 200
|
|
58
|
-
res.setHeader('Content-Type', 'application/json')
|
|
59
|
-
res.end(
|
|
60
|
-
JSON.stringify({
|
|
61
|
-
success: true,
|
|
62
|
-
found: false,
|
|
63
|
-
data: null,
|
|
64
|
-
}),
|
|
65
|
-
)
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// 返回笔记信息
|
|
70
|
-
res.statusCode = 200
|
|
71
|
-
res.setHeader('Content-Type', 'application/json')
|
|
72
|
-
res.end(
|
|
73
|
-
JSON.stringify({
|
|
74
|
-
success: true,
|
|
75
|
-
found: true,
|
|
76
|
-
data: {
|
|
77
|
-
noteIndex: noteItem.noteIndex,
|
|
78
|
-
folderName: noteItem.folderName,
|
|
79
|
-
// 构建笔记的完整 URL(包含 README)
|
|
80
|
-
url: `/notes/${encodeURIComponent(
|
|
81
|
-
noteItem.folderName,
|
|
82
|
-
)}/README`,
|
|
83
|
-
},
|
|
84
|
-
}),
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
logger.debug(
|
|
88
|
-
`查询笔记: configId=${configId}, noteIndex=${noteItem.noteIndex}`,
|
|
89
|
-
)
|
|
90
|
-
} catch (error) {
|
|
91
|
-
logger.error('查询笔记失败:', error)
|
|
92
|
-
res.statusCode = 500
|
|
93
|
-
res.setHeader('Content-Type', 'application/json')
|
|
94
|
-
res.end(
|
|
95
|
-
JSON.stringify({
|
|
96
|
-
success: false,
|
|
97
|
-
error: error instanceof Error ? error.message : String(error),
|
|
98
|
-
}),
|
|
99
|
-
)
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
next()
|
|
103
|
-
}
|
|
104
|
-
})
|
|
105
|
-
},
|
|
106
|
-
}
|
|
107
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* .vitepress/tnotes/vitepress/plugins/getNoteByConfigIdPlugin.ts
|
|
3
|
+
*
|
|
4
|
+
* VitePress 插件 - 根据 configId 查询笔记信息
|
|
5
|
+
*/
|
|
6
|
+
import type { PluginOption } from 'vite'
|
|
7
|
+
import { NoteIndexCache } from '../../core'
|
|
8
|
+
import { logger } from '../../utils'
|
|
9
|
+
|
|
10
|
+
export function getNoteByConfigIdPlugin(): PluginOption {
|
|
11
|
+
return {
|
|
12
|
+
name: 'tnotes-get-note-by-config-id',
|
|
13
|
+
|
|
14
|
+
configureServer(server) {
|
|
15
|
+
// 添加中间件处理查询请求
|
|
16
|
+
server.middlewares.use(async (req, res, next) => {
|
|
17
|
+
if (
|
|
18
|
+
req.url?.startsWith('/__tnotes_get_note?') &&
|
|
19
|
+
req.method === 'GET'
|
|
20
|
+
) {
|
|
21
|
+
try {
|
|
22
|
+
// 解析查询参数
|
|
23
|
+
const url = new URL(req.url, `http://${req.headers.host}`)
|
|
24
|
+
const configId = url.searchParams.get('configId')
|
|
25
|
+
|
|
26
|
+
if (!configId) {
|
|
27
|
+
res.statusCode = 400
|
|
28
|
+
res.setHeader('Content-Type', 'application/json')
|
|
29
|
+
res.end(
|
|
30
|
+
JSON.stringify({
|
|
31
|
+
success: false,
|
|
32
|
+
error: 'Missing configId parameter',
|
|
33
|
+
}),
|
|
34
|
+
)
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 确保笔记索引缓存已初始化
|
|
39
|
+
const noteIndexCache = NoteIndexCache.getInstance()
|
|
40
|
+
if (!noteIndexCache.isInitialized()) {
|
|
41
|
+
res.statusCode = 503
|
|
42
|
+
res.setHeader('Content-Type', 'application/json')
|
|
43
|
+
res.end(
|
|
44
|
+
JSON.stringify({
|
|
45
|
+
success: false,
|
|
46
|
+
error: 'Service not initialized',
|
|
47
|
+
}),
|
|
48
|
+
)
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 从索引缓存中查询笔记
|
|
53
|
+
const noteItem = noteIndexCache.getByConfigId(configId)
|
|
54
|
+
|
|
55
|
+
if (!noteItem) {
|
|
56
|
+
// 笔记不存在或已被删除
|
|
57
|
+
res.statusCode = 200
|
|
58
|
+
res.setHeader('Content-Type', 'application/json')
|
|
59
|
+
res.end(
|
|
60
|
+
JSON.stringify({
|
|
61
|
+
success: true,
|
|
62
|
+
found: false,
|
|
63
|
+
data: null,
|
|
64
|
+
}),
|
|
65
|
+
)
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 返回笔记信息
|
|
70
|
+
res.statusCode = 200
|
|
71
|
+
res.setHeader('Content-Type', 'application/json')
|
|
72
|
+
res.end(
|
|
73
|
+
JSON.stringify({
|
|
74
|
+
success: true,
|
|
75
|
+
found: true,
|
|
76
|
+
data: {
|
|
77
|
+
noteIndex: noteItem.noteIndex,
|
|
78
|
+
folderName: noteItem.folderName,
|
|
79
|
+
// 构建笔记的完整 URL(包含 README)
|
|
80
|
+
url: `/notes/${encodeURIComponent(
|
|
81
|
+
noteItem.folderName,
|
|
82
|
+
)}/README`,
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
logger.debug(
|
|
88
|
+
`查询笔记: configId=${configId}, noteIndex=${noteItem.noteIndex}`,
|
|
89
|
+
)
|
|
90
|
+
} catch (error) {
|
|
91
|
+
logger.error('查询笔记失败:', error)
|
|
92
|
+
res.statusCode = 500
|
|
93
|
+
res.setHeader('Content-Type', 'application/json')
|
|
94
|
+
res.end(
|
|
95
|
+
JSON.stringify({
|
|
96
|
+
success: false,
|
|
97
|
+
error: error instanceof Error ? error.message : String(error),
|
|
98
|
+
}),
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
next()
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* .vitepress/tnotes/vitepress/plugins/renameNotePlugin.ts
|
|
3
|
-
*
|
|
4
|
-
* Vite 插件 - 处理笔记重命名请求
|
|
5
|
-
*/
|
|
6
|
-
import type { PluginOption } from 'vite'
|
|
7
|
-
import { RenameNoteCommand } from '../../commands/note/RenameNoteCommand'
|
|
8
|
-
|
|
9
|
-
export function renameNotePlugin(): PluginOption {
|
|
10
|
-
const renameCommand = new RenameNoteCommand()
|
|
11
|
-
|
|
12
|
-
return {
|
|
13
|
-
name: 'tnotes-rename-note',
|
|
14
|
-
configureServer(server) {
|
|
15
|
-
server.middlewares.use(async (req, res, next) => {
|
|
16
|
-
// 只处理 POST 请求到 /__tnotes_rename_note
|
|
17
|
-
if (req.url === '/__tnotes_rename_note' && req.method === 'POST') {
|
|
18
|
-
let body = ''
|
|
19
|
-
|
|
20
|
-
req.on('data', (chunk) => {
|
|
21
|
-
body += chunk.toString()
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
req.on('end', async () => {
|
|
25
|
-
try {
|
|
26
|
-
const { noteIndex, newTitle } = JSON.parse(body)
|
|
27
|
-
|
|
28
|
-
if (!noteIndex || !newTitle) {
|
|
29
|
-
res.statusCode = 400
|
|
30
|
-
res.end('Missing noteIndex or newTitle')
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 执行重命名
|
|
35
|
-
const startTime = Date.now()
|
|
36
|
-
await renameCommand.renameNote({ noteIndex, newTitle })
|
|
37
|
-
const duration = Date.now() - startTime
|
|
38
|
-
|
|
39
|
-
res.statusCode = 200
|
|
40
|
-
res.setHeader('Content-Type', 'application/json')
|
|
41
|
-
res.end(
|
|
42
|
-
JSON.stringify({
|
|
43
|
-
success: true,
|
|
44
|
-
duration,
|
|
45
|
-
newTitle,
|
|
46
|
-
message: '重命名完成',
|
|
47
|
-
})
|
|
48
|
-
)
|
|
49
|
-
} catch (error) {
|
|
50
|
-
res.statusCode = 500
|
|
51
|
-
res.end(error instanceof Error ? error.message : 'Rename failed')
|
|
52
|
-
}
|
|
53
|
-
})
|
|
54
|
-
} else {
|
|
55
|
-
next()
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
|
-
},
|
|
59
|
-
}
|
|
60
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* .vitepress/tnotes/vitepress/plugins/renameNotePlugin.ts
|
|
3
|
+
*
|
|
4
|
+
* Vite 插件 - 处理笔记重命名请求
|
|
5
|
+
*/
|
|
6
|
+
import type { PluginOption } from 'vite'
|
|
7
|
+
import { RenameNoteCommand } from '../../commands/note/RenameNoteCommand'
|
|
8
|
+
|
|
9
|
+
export function renameNotePlugin(): PluginOption {
|
|
10
|
+
const renameCommand = new RenameNoteCommand()
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
name: 'tnotes-rename-note',
|
|
14
|
+
configureServer(server) {
|
|
15
|
+
server.middlewares.use(async (req, res, next) => {
|
|
16
|
+
// 只处理 POST 请求到 /__tnotes_rename_note
|
|
17
|
+
if (req.url === '/__tnotes_rename_note' && req.method === 'POST') {
|
|
18
|
+
let body = ''
|
|
19
|
+
|
|
20
|
+
req.on('data', (chunk) => {
|
|
21
|
+
body += chunk.toString()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
req.on('end', async () => {
|
|
25
|
+
try {
|
|
26
|
+
const { noteIndex, newTitle } = JSON.parse(body)
|
|
27
|
+
|
|
28
|
+
if (!noteIndex || !newTitle) {
|
|
29
|
+
res.statusCode = 400
|
|
30
|
+
res.end('Missing noteIndex or newTitle')
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 执行重命名
|
|
35
|
+
const startTime = Date.now()
|
|
36
|
+
await renameCommand.renameNote({ noteIndex, newTitle })
|
|
37
|
+
const duration = Date.now() - startTime
|
|
38
|
+
|
|
39
|
+
res.statusCode = 200
|
|
40
|
+
res.setHeader('Content-Type', 'application/json')
|
|
41
|
+
res.end(
|
|
42
|
+
JSON.stringify({
|
|
43
|
+
success: true,
|
|
44
|
+
duration,
|
|
45
|
+
newTitle,
|
|
46
|
+
message: '重命名完成',
|
|
47
|
+
})
|
|
48
|
+
)
|
|
49
|
+
} catch (error) {
|
|
50
|
+
res.statusCode = 500
|
|
51
|
+
res.end(error instanceof Error ? error.message : 'Rename failed')
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
} else {
|
|
55
|
+
next()
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* .vitepress/tnotes/vitepress/plugins/updateConfigPlugin.ts
|
|
3
|
-
*
|
|
4
|
-
* VitePress 插件 - 处理笔记配置更新请求
|
|
5
|
-
*/
|
|
6
|
-
import type { PluginOption } from 'vite'
|
|
7
|
-
import { UpdateNoteConfigCommand } from '../../commands/note/UpdateNoteConfigCommand'
|
|
8
|
-
|
|
9
|
-
export function updateConfigPlugin(): PluginOption {
|
|
10
|
-
let updateCommand: UpdateNoteConfigCommand
|
|
11
|
-
|
|
12
|
-
return {
|
|
13
|
-
name: 'tnotes-update-config',
|
|
14
|
-
|
|
15
|
-
configureServer(server) {
|
|
16
|
-
updateCommand = new UpdateNoteConfigCommand()
|
|
17
|
-
|
|
18
|
-
// 添加中间件处理配置更新请求
|
|
19
|
-
server.middlewares.use(async (req, res, next) => {
|
|
20
|
-
if (req.url === '/__tnotes_update_config' && req.method === 'POST') {
|
|
21
|
-
let body = ''
|
|
22
|
-
|
|
23
|
-
req.on('data', (chunk) => {
|
|
24
|
-
body += chunk.toString()
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
req.on('end', async () => {
|
|
28
|
-
try {
|
|
29
|
-
const data = JSON.parse(body)
|
|
30
|
-
const { noteIndex, config } = data
|
|
31
|
-
|
|
32
|
-
if (!noteIndex || !config) {
|
|
33
|
-
res.statusCode = 400
|
|
34
|
-
res.end('Missing noteIndex or config')
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// 调用命令更新配置
|
|
39
|
-
await updateCommand.updateConfig({
|
|
40
|
-
noteIndex,
|
|
41
|
-
config: {
|
|
42
|
-
done: config.done,
|
|
43
|
-
enableDiscussions: config.enableDiscussions,
|
|
44
|
-
description: config.description,
|
|
45
|
-
},
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
res.statusCode = 200
|
|
49
|
-
res.setHeader('Content-Type', 'application/json')
|
|
50
|
-
res.end(JSON.stringify({ success: true }))
|
|
51
|
-
} catch (error) {
|
|
52
|
-
console.error('更新配置失败:', error)
|
|
53
|
-
res.statusCode = 500
|
|
54
|
-
res.end(error instanceof Error ? error.message : String(error))
|
|
55
|
-
}
|
|
56
|
-
})
|
|
57
|
-
} else {
|
|
58
|
-
next()
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
},
|
|
62
|
-
}
|
|
63
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* .vitepress/tnotes/vitepress/plugins/updateConfigPlugin.ts
|
|
3
|
+
*
|
|
4
|
+
* VitePress 插件 - 处理笔记配置更新请求
|
|
5
|
+
*/
|
|
6
|
+
import type { PluginOption } from 'vite'
|
|
7
|
+
import { UpdateNoteConfigCommand } from '../../commands/note/UpdateNoteConfigCommand'
|
|
8
|
+
|
|
9
|
+
export function updateConfigPlugin(): PluginOption {
|
|
10
|
+
let updateCommand: UpdateNoteConfigCommand
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
name: 'tnotes-update-config',
|
|
14
|
+
|
|
15
|
+
configureServer(server) {
|
|
16
|
+
updateCommand = new UpdateNoteConfigCommand()
|
|
17
|
+
|
|
18
|
+
// 添加中间件处理配置更新请求
|
|
19
|
+
server.middlewares.use(async (req, res, next) => {
|
|
20
|
+
if (req.url === '/__tnotes_update_config' && req.method === 'POST') {
|
|
21
|
+
let body = ''
|
|
22
|
+
|
|
23
|
+
req.on('data', (chunk) => {
|
|
24
|
+
body += chunk.toString()
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
req.on('end', async () => {
|
|
28
|
+
try {
|
|
29
|
+
const data = JSON.parse(body)
|
|
30
|
+
const { noteIndex, config } = data
|
|
31
|
+
|
|
32
|
+
if (!noteIndex || !config) {
|
|
33
|
+
res.statusCode = 400
|
|
34
|
+
res.end('Missing noteIndex or config')
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 调用命令更新配置
|
|
39
|
+
await updateCommand.updateConfig({
|
|
40
|
+
noteIndex,
|
|
41
|
+
config: {
|
|
42
|
+
done: config.done,
|
|
43
|
+
enableDiscussions: config.enableDiscussions,
|
|
44
|
+
description: config.description,
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
res.statusCode = 200
|
|
49
|
+
res.setHeader('Content-Type', 'application/json')
|
|
50
|
+
res.end(JSON.stringify({ success: true }))
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error('更新配置失败:', error)
|
|
53
|
+
res.statusCode = 500
|
|
54
|
+
res.end(error instanceof Error ? error.message : String(error))
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
} else {
|
|
58
|
+
next()
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
}
|
package/vitepress/theme/index.ts
CHANGED
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* .vitepress/tnotes/theme/index.ts
|
|
3
|
-
*
|
|
4
|
-
* 自定义主题
|
|
5
|
-
*
|
|
6
|
-
* 提供两种使用方式:
|
|
7
|
-
* 1. defineNotesTheme() 工厂函数(推荐)
|
|
8
|
-
* 2. export default(向后兼容)
|
|
9
|
-
*
|
|
10
|
-
* doc:
|
|
11
|
-
* v1 - https://vuejs.github.io/vitepress/v1/zh/guide/custom-theme
|
|
12
|
-
* v2 - https://vitepress.dev/zh/guide/custom-theme
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import type { Theme, EnhanceAppContext } from 'vitepress'
|
|
16
|
-
import DefaultTheme from 'vitepress/theme'
|
|
17
|
-
import BilibiliOutsidePlayer from '../components/BilibiliOutsidePlayer/BilibiliOutsidePlayer.vue'
|
|
18
|
-
import Discussions from '../components/Discussions/Discussions.vue'
|
|
19
|
-
import EnWordList from '../components/EnWordList/EnWordList.vue'
|
|
20
|
-
import Footprints from '../components/Footprints/Footprints.vue'
|
|
21
|
-
import Layout from '../components/Layout/Layout.vue'
|
|
22
|
-
import LoadingPage from '../components/LoadingPage/LoadingPage.vue'
|
|
23
|
-
import MarkMap from '../components/MarkMap/MarkMap.vue'
|
|
24
|
-
import Mermaid from '../components/Mermaid/Mermaid.vue'
|
|
25
|
-
import NotesTable from '../components/NotesTable/NotesTable.vue'
|
|
26
|
-
import Settings from '../components/Settings/Settings.vue'
|
|
27
|
-
import SidebarCard from '../components/SidebarCard/SidebarCard.vue'
|
|
28
|
-
import Tooltip from '../components/Tooltip/Tooltip.vue'
|
|
29
|
-
import './styles/index.scss'
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* 注册 TNotes 核心全局组件
|
|
33
|
-
*/
|
|
34
|
-
function registerCoreComponents(ctx: EnhanceAppContext) {
|
|
35
|
-
const { app } = ctx
|
|
36
|
-
app.component('BilibiliOutsidePlayer', BilibiliOutsidePlayer)
|
|
37
|
-
app.component('B', BilibiliOutsidePlayer)
|
|
38
|
-
app.component('Discussions', Discussions)
|
|
39
|
-
app.component('EnWordList', EnWordList)
|
|
40
|
-
app.component('E', EnWordList)
|
|
41
|
-
app.component('Footprints', Footprints)
|
|
42
|
-
app.component('F', Footprints)
|
|
43
|
-
app.component('LoadingPage', LoadingPage)
|
|
44
|
-
app.component('Settings', Settings)
|
|
45
|
-
app.component('S', Settings)
|
|
46
|
-
app.component('SidebarCard', SidebarCard)
|
|
47
|
-
app.component('MarkMap', MarkMap)
|
|
48
|
-
app.component('Mermaid', Mermaid)
|
|
49
|
-
app.component('NotesTable', NotesTable)
|
|
50
|
-
app.component('N', NotesTable)
|
|
51
|
-
app.component('Tooltip', Tooltip)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* 覆盖选项
|
|
56
|
-
*/
|
|
57
|
-
interface NotesThemeOverrides {
|
|
58
|
-
/** 覆盖 Layout 组件 */
|
|
59
|
-
Layout?: Theme['Layout']
|
|
60
|
-
/** 追加的 enhanceApp 逻辑(在核心组件注册之后调用) */
|
|
61
|
-
enhanceApp?: Theme['enhanceApp']
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 创建 TNotes 主题配置
|
|
66
|
-
*
|
|
67
|
-
* @param overrides - 可选的覆盖选项
|
|
68
|
-
* @returns VitePress 主题对象
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* // .vitepress/theme/index.ts
|
|
72
|
-
* import { defineNotesTheme } from '../tnotes/vitepress/theme'
|
|
73
|
-
* export default defineNotesTheme()
|
|
74
|
-
*/
|
|
75
|
-
export function defineNotesTheme(overrides: NotesThemeOverrides = {}): Theme {
|
|
76
|
-
return {
|
|
77
|
-
extends: DefaultTheme,
|
|
78
|
-
Layout: overrides.Layout ?? Layout,
|
|
79
|
-
enhanceApp(ctx) {
|
|
80
|
-
registerCoreComponents(ctx)
|
|
81
|
-
overrides.enhanceApp?.(ctx)
|
|
82
|
-
},
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 默认导出(向后兼容旧版 re-export 方式)
|
|
88
|
-
*/
|
|
89
|
-
export default {
|
|
90
|
-
extends: DefaultTheme,
|
|
91
|
-
Layout,
|
|
92
|
-
enhanceApp(ctx: EnhanceAppContext) {
|
|
93
|
-
registerCoreComponents(ctx)
|
|
94
|
-
},
|
|
95
|
-
} satisfies Theme
|
|
1
|
+
/**
|
|
2
|
+
* .vitepress/tnotes/theme/index.ts
|
|
3
|
+
*
|
|
4
|
+
* 自定义主题
|
|
5
|
+
*
|
|
6
|
+
* 提供两种使用方式:
|
|
7
|
+
* 1. defineNotesTheme() 工厂函数(推荐)
|
|
8
|
+
* 2. export default(向后兼容)
|
|
9
|
+
*
|
|
10
|
+
* doc:
|
|
11
|
+
* v1 - https://vuejs.github.io/vitepress/v1/zh/guide/custom-theme
|
|
12
|
+
* v2 - https://vitepress.dev/zh/guide/custom-theme
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { Theme, EnhanceAppContext } from 'vitepress'
|
|
16
|
+
import DefaultTheme from 'vitepress/theme'
|
|
17
|
+
import BilibiliOutsidePlayer from '../components/BilibiliOutsidePlayer/BilibiliOutsidePlayer.vue'
|
|
18
|
+
import Discussions from '../components/Discussions/Discussions.vue'
|
|
19
|
+
import EnWordList from '../components/EnWordList/EnWordList.vue'
|
|
20
|
+
import Footprints from '../components/Footprints/Footprints.vue'
|
|
21
|
+
import Layout from '../components/Layout/Layout.vue'
|
|
22
|
+
import LoadingPage from '../components/LoadingPage/LoadingPage.vue'
|
|
23
|
+
import MarkMap from '../components/MarkMap/MarkMap.vue'
|
|
24
|
+
import Mermaid from '../components/Mermaid/Mermaid.vue'
|
|
25
|
+
import NotesTable from '../components/NotesTable/NotesTable.vue'
|
|
26
|
+
import Settings from '../components/Settings/Settings.vue'
|
|
27
|
+
import SidebarCard from '../components/SidebarCard/SidebarCard.vue'
|
|
28
|
+
import Tooltip from '../components/Tooltip/Tooltip.vue'
|
|
29
|
+
import './styles/index.scss'
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 注册 TNotes 核心全局组件
|
|
33
|
+
*/
|
|
34
|
+
function registerCoreComponents(ctx: EnhanceAppContext) {
|
|
35
|
+
const { app } = ctx
|
|
36
|
+
app.component('BilibiliOutsidePlayer', BilibiliOutsidePlayer)
|
|
37
|
+
app.component('B', BilibiliOutsidePlayer)
|
|
38
|
+
app.component('Discussions', Discussions)
|
|
39
|
+
app.component('EnWordList', EnWordList)
|
|
40
|
+
app.component('E', EnWordList)
|
|
41
|
+
app.component('Footprints', Footprints)
|
|
42
|
+
app.component('F', Footprints)
|
|
43
|
+
app.component('LoadingPage', LoadingPage)
|
|
44
|
+
app.component('Settings', Settings)
|
|
45
|
+
app.component('S', Settings)
|
|
46
|
+
app.component('SidebarCard', SidebarCard)
|
|
47
|
+
app.component('MarkMap', MarkMap)
|
|
48
|
+
app.component('Mermaid', Mermaid)
|
|
49
|
+
app.component('NotesTable', NotesTable)
|
|
50
|
+
app.component('N', NotesTable)
|
|
51
|
+
app.component('Tooltip', Tooltip)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 覆盖选项
|
|
56
|
+
*/
|
|
57
|
+
interface NotesThemeOverrides {
|
|
58
|
+
/** 覆盖 Layout 组件 */
|
|
59
|
+
Layout?: Theme['Layout']
|
|
60
|
+
/** 追加的 enhanceApp 逻辑(在核心组件注册之后调用) */
|
|
61
|
+
enhanceApp?: Theme['enhanceApp']
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 创建 TNotes 主题配置
|
|
66
|
+
*
|
|
67
|
+
* @param overrides - 可选的覆盖选项
|
|
68
|
+
* @returns VitePress 主题对象
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* // .vitepress/theme/index.ts
|
|
72
|
+
* import { defineNotesTheme } from '../tnotes/vitepress/theme'
|
|
73
|
+
* export default defineNotesTheme()
|
|
74
|
+
*/
|
|
75
|
+
export function defineNotesTheme(overrides: NotesThemeOverrides = {}): Theme {
|
|
76
|
+
return {
|
|
77
|
+
extends: DefaultTheme,
|
|
78
|
+
Layout: overrides.Layout ?? Layout,
|
|
79
|
+
enhanceApp(ctx) {
|
|
80
|
+
registerCoreComponents(ctx)
|
|
81
|
+
overrides.enhanceApp?.(ctx)
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 默认导出(向后兼容旧版 re-export 方式)
|
|
88
|
+
*/
|
|
89
|
+
export default {
|
|
90
|
+
extends: DefaultTheme,
|
|
91
|
+
Layout,
|
|
92
|
+
enhanceApp(ctx: EnhanceAppContext) {
|
|
93
|
+
registerCoreComponents(ctx)
|
|
94
|
+
},
|
|
95
|
+
} satisfies Theme
|