@movk/nuxt-docs 1.3.7 → 1.3.9

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 CHANGED
@@ -19,6 +19,7 @@
19
19
  - 🎨 **采用 Nuxt UI** - 集成全面的 UI 组件库,开箱即用
20
20
  - 📝 **MDC 语法增强** - 支持 Markdown 与 Vue 组件的无缝集成,实现动态内容
21
21
  - 🧩 **组件文档自动生成** - 自动生成 Props、Slots、Emits 文档及交互式示例
22
+ - 📦 **Git 提交历史集成** - 通过 CommitChangelog 组件自动展示文件的提交历史记录
22
23
  - 📚 **智能侧边栏导航** - 根据内容结构自动生成导航
23
24
  - 🔍 **全文搜索** - 内置强大的全文搜索功能
24
25
  - 🌙 **暗黑模式** - 支持亮色/暗色主题切换
@@ -31,14 +32,30 @@
31
32
 
32
33
  ### 使用模板创建项目
33
34
 
34
- ```bash [Terminal]
35
- # 使用此模板创建新项目
35
+ 根据您的需求选择合适的模板:
36
+
37
+ #### 📚 完整文档站点(推荐)
38
+
39
+ 适合构建完整的文档网站,包含 ESLint、TypeScript 检查等开发工具。
40
+
41
+ ```bash
42
+ # 使用完整模板创建新项目
36
43
  npx nuxi init -t gh:mhaibaraai/movk-nuxt-docs/templates/default my-docs
37
- # 进入项目目录
38
44
  cd my-docs
39
- # 启动开发服务器
40
45
  pnpm dev
41
46
  ```
47
+
48
+ #### 📦 模块文档站点(精简)
49
+
50
+ 适合为 npm 包或库快速创建文档,内置 Release 页面展示版本发布历史,无额外开发工具。
51
+
52
+ ```bash
53
+ # 使用模块模板创建新项目
54
+ npx nuxi init -t gh:mhaibaraai/movk-nuxt-docs/templates/module my-module-docs
55
+ cd my-module-docs
56
+ pnpm dev
57
+ ```
58
+
42
59
  访问 `http://localhost:3000` 查看你的文档网站。
43
60
 
44
61
  ### 作为 Layer 使用
@@ -73,9 +90,9 @@ export default defineNuxtConfig({
73
90
 
74
91
  ## 📁 项目结构
75
92
 
76
- ### 完整项目结构
93
+ ### 模板项目结构
77
94
 
78
- 使用模板创建的项目结构:
95
+ 使用模板创建的项目结构(以 `default` 模板为例):
79
96
 
80
97
  ```bash
81
98
  my-docs/
@@ -86,22 +103,27 @@ my-docs/
86
103
  │ ├── index.md # 首页
87
104
  │ └── docs/ # 文档页面
88
105
  ├── public/ # 静态资源
89
- ├── scripts/ # 脚本
90
106
  ├── nuxt.config.ts # Nuxt 配置
107
+ ├── app.config.ts # 应用配置
108
+ ├── content.config.ts # 内容配置
91
109
  ├── tsconfig.json # TypeScript 配置
92
110
  ├── package.json # 依赖与脚本
93
- ├── pnpm-workspace.yaml # pnpm 工作区配置
94
111
  └── README.md # 项目说明
95
112
  ```
96
113
 
97
114
  ### Monorepo 结构
98
115
 
99
- 本项目采用 monorepo 结构:
116
+ 本仓库采用 monorepo 结构:
100
117
 
101
- - `/docs` - 官方文档站点
102
- - `/layer` - Movk Nuxt Docs 主题 layer(`@movk/nuxt-docs`)
103
- - `/template` - 项目模板
104
- - `/scripts` - 构建脚本
118
+ ```bash
119
+ movk-nuxt-docs/
120
+ ├── docs/ # 官方文档站点
121
+ ├── layer/ # @movk/nuxt-docs layer 包
122
+ ├── templates/
123
+ │ ├── default/ # 完整文档站点模板
124
+ │ └── module/ # 模块文档站点模板(精简)
125
+ └── scripts/ # 构建脚本
126
+ ```
105
127
 
106
128
  ## 📝 内容编写
107
129
 
@@ -0,0 +1,95 @@
1
+ <script setup lang="ts">
2
+ import { camelCase, upperFirst } from '@movk/core'
3
+
4
+ interface Commit {
5
+ sha: string
6
+ message: string
7
+ }
8
+
9
+ const props = defineProps<{
10
+ /**
11
+ * The path to the file in the repository.
12
+ * @defaultValue 'src'
13
+ */
14
+ commitPath?: string
15
+ /**
16
+ * The prefix for the file path.
17
+ */
18
+ prefix?: string
19
+ /**
20
+ * The file extension.
21
+ * @defaultValue 'vue'
22
+ */
23
+ suffix?: string
24
+ /**
25
+ * The name of the component or file to get the changelog for.
26
+ */
27
+ name?: string
28
+ }>()
29
+
30
+ const SHA_SHORT_LENGTH = 5
31
+
32
+ const { github } = useAppConfig()
33
+ const route = useRoute()
34
+
35
+ // 计算文件路径相关的值
36
+ const routeName = computed(() => route.path.split('/').pop() ?? '')
37
+ const githubUrl = computed(() => (github && typeof github === 'object' ? github.url : ''))
38
+
39
+ const filePath = computed(() => {
40
+ const basePath = props.commitPath ?? (github && typeof github === 'object' ? github.commitPath : 'src')
41
+ const filePrefix = props.prefix ? `${props.prefix}/` : ''
42
+ const fileExtension = props.suffix ?? (github && typeof github === 'object' ? github.suffix : 'vue')
43
+ const fileName = props.name ?? routeName.value
44
+
45
+ const camelName = fileExtension === 'vue'
46
+ ? upperFirst(camelCase(fileName))
47
+ : camelCase(fileName)
48
+
49
+ return `${basePath}/${filePrefix}${camelName}.${fileExtension}`
50
+ })
51
+
52
+ const { data: commits } = await useLazyFetch<Commit[]>('/api/github/commits', {
53
+ key: `commit-changelog-${props.name ?? routeName.value}`,
54
+ query: { path: filePath.value }
55
+ })
56
+
57
+ // 格式化提交消息
58
+ const formattedCommits = computed(() => {
59
+ if (!commits.value?.length) return []
60
+
61
+ return commits.value.map((commit) => {
62
+ const shortSha = commit.sha.slice(0, SHA_SHORT_LENGTH)
63
+ const commitLink = `[\`${shortSha}\`](${githubUrl.value}/commit/${commit.sha})`
64
+
65
+ const content = commit.message
66
+ .replace(/\(.*?\)/, '')
67
+ .replace(/#(\d+)/g, `<a href='${githubUrl.value}/issues/$1'>#$1</a>`)
68
+ .replace(/`(.*?)`/g, '<code class="text-xs">$1</code>')
69
+
70
+ return {
71
+ sha: commit.sha,
72
+ formatted: `${commitLink} — ${content}`
73
+ }
74
+ })
75
+ })
76
+ </script>
77
+
78
+ <template>
79
+ <div v-if="!formattedCommits.length">
80
+ No recent changes
81
+ </div>
82
+
83
+ <div v-else class="flex flex-col gap-1.5 relative">
84
+ <div class="bg-accented w-px h-full absolute left-[11px] z-[-1]" />
85
+
86
+ <div
87
+ v-for="commit of formattedCommits"
88
+ :key="commit.sha"
89
+ class="flex gap-1.5 items-center"
90
+ >
91
+ <div class="bg-accented ring-2 ring-bg size-1.5 mx-[8.5px] rounded-full" />
92
+ <MDC :value="commit.formatted" class="text-sm *:py-0 *:my-0 [&_code]:text-xs" tag="div" />
93
+ </div>
94
+ </div>
95
+ </template>
@@ -5,7 +5,7 @@ import { hash } from 'ohash'
5
5
  import { useElementSize } from '@vueuse/core'
6
6
  import { get, set } from '#ui/utils'
7
7
 
8
- const { preview = true, source = true, prettier = true, ...props } = defineProps<{
8
+ const { preview = true, source = true, prettier = false, ...props } = defineProps<{
9
9
  name: string
10
10
  class?: any
11
11
  /**
@@ -29,6 +29,9 @@ declare module 'nuxt/schema' {
29
29
  url: string
30
30
  branch: string
31
31
  rootDir: string
32
+ commitPath: string
33
+ since: string
34
+ suffix: string
32
35
  } | false
33
36
  }
34
37
  }
package/modules/config.ts CHANGED
@@ -49,6 +49,9 @@ export default defineNuxtModule({
49
49
  owner: gitInfo?.owner,
50
50
  name: gitInfo?.name,
51
51
  url: gitInfo?.url,
52
+ commitPath: 'src',
53
+ suffix: 'vue',
54
+ since: '2025-01-31T04:00:00Z',
52
55
  branch: getGitBranch()
53
56
  })
54
57
 
@@ -65,7 +68,7 @@ export default defineNuxtModule({
65
68
  'nuxt-og-image',
66
69
  '@nuxtjs/plausible',
67
70
  '@nuxt/ui',
68
- new RegExp(`${componentsPath.replace(/[/\\]/g, '[/\\\\]')}/(?!content/(ComponentEmits|ComponentProps|ComponentSlots|ComponentExample)\\.vue$)`)
71
+ new RegExp(`${componentsPath.replace(/[/\\]/g, '[/\\\\]')}/(?!content/(ComponentEmits|ComponentProps|ComponentSlots|ComponentExample|CommitChangelog)\\.vue$)`)
69
72
  ],
70
73
  metaFields: {
71
74
  type: false,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@movk/nuxt-docs",
3
3
  "type": "module",
4
- "version": "1.3.7",
4
+ "version": "1.3.9",
5
5
  "private": false,
6
6
  "description": "An elegant documentation theme for Nuxt, powered by Nuxt UI and Nuxt Content.",
7
7
  "author": "YiXuan <mhaibaraai@gmail.com>",
@@ -30,12 +30,13 @@
30
30
  "@iconify-json/lucide": "^1.2.75",
31
31
  "@iconify-json/simple-icons": "^1.2.60",
32
32
  "@iconify-json/vscode-icons": "^1.2.36",
33
- "@movk/core": "^1.0.1",
33
+ "@movk/core": "^1.0.2",
34
34
  "@nuxt/content": "^3.8.2",
35
35
  "@nuxt/image": "^2.0.0",
36
36
  "@nuxt/kit": "^4.2.1",
37
37
  "@nuxt/ui": "^4.2.1",
38
38
  "@nuxtjs/seo": "^3.2.2",
39
+ "@octokit/rest": "^22.0.1",
39
40
  "@vueuse/core": "^14.0.0",
40
41
  "@vueuse/nuxt": "^14.0.0",
41
42
  "defu": "^6.1.4",
@@ -0,0 +1,33 @@
1
+ import { Octokit } from '@octokit/rest'
2
+
3
+ export default defineCachedEventHandler(async (event) => {
4
+ if (!process.env.NUXT_GITHUB_TOKEN) {
5
+ return []
6
+ }
7
+
8
+ const { path } = getQuery(event) as { path: string }
9
+ if (!path) {
10
+ throw createError({
11
+ statusCode: 400,
12
+ statusMessage: 'Path is required'
13
+ })
14
+ }
15
+
16
+ const { github } = useAppConfig()
17
+ const octokit = new Octokit({ auth: process.env.NUXT_GITHUB_TOKEN })
18
+ const commits = await octokit.paginate(octokit.rest.repos.listCommits, {
19
+ owner: github.owner,
20
+ repo: github.name,
21
+ path,
22
+ since: github.since
23
+ })
24
+
25
+ return commits.map(commit => ({
26
+ sha: commit.sha,
27
+ date: commit.commit.author?.date ?? '',
28
+ message: (commit.commit.message?.split('\n')[0] ?? '')
29
+ }))
30
+ }, {
31
+ maxAge: 60 * 60,
32
+ getKey: event => `commits-${getQuery(event).path}`
33
+ })