clarity-theme 0.1.0 → 0.1.2

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.
Files changed (154) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +70 -4
  3. package/README.zh-CN.md +67 -4
  4. package/nuxt.config.ts +217 -214
  5. package/package.json +35 -37
  6. package/{app → src}/app.config.ts +110 -110
  7. package/{app → src}/app.vue +5 -5
  8. package/{app → src}/components/blog/BlogAside.vue +25 -25
  9. package/{app → src}/components/blog/BlogFooter.vue +25 -25
  10. package/{app → src}/components/blog/BlogHeader.global.vue +48 -48
  11. package/{app → src}/components/blog/BlogPanel.vue +43 -43
  12. package/{app → src}/components/blog/BlogSidebar.vue +53 -53
  13. package/{app → src}/components/blog/BlogWidget.vue +42 -42
  14. package/{app → src}/components/blog/Mask.vue +25 -25
  15. package/{app → src}/components/blog/SkipToContent.vue +9 -9
  16. package/{app → src}/components/blog/ThemeToggle.vue +22 -22
  17. package/{app → src}/components/content/Badge.vue +45 -45
  18. package/{app → src}/components/content/Blur.vue +14 -14
  19. package/{app → src}/components/content/CardList.vue +8 -8
  20. package/{app → src}/components/content/Chat.vue +41 -41
  21. package/{app → src}/components/content/Copy.vue +71 -71
  22. package/{app → src}/components/content/EmojiClock.vue +49 -49
  23. package/{app → src}/components/content/FeedCard.vue +96 -96
  24. package/{app → src}/components/content/FeedGroup.vue +61 -61
  25. package/{app → src}/components/content/Folding.vue +19 -19
  26. package/{app → src}/components/content/Key.vue +143 -143
  27. package/{app → src}/components/content/LinkBanner.vue +27 -27
  28. package/{app → src}/components/content/LinkCard.vue +28 -28
  29. package/{app → src}/components/content/MdTitle.vue +8 -8
  30. package/{app → src}/components/content/Mermaid.vue +99 -99
  31. package/{app → src}/components/content/MusicScore.vue +63 -63
  32. package/{app → src}/components/content/Pic.vue +49 -49
  33. package/{app → src}/components/content/Poetry.vue +27 -27
  34. package/{app → src}/components/content/ProseA.vue +24 -24
  35. package/{app → src}/components/content/ProseCode.vue +16 -16
  36. package/{app → src}/components/content/ProsePre.vue +117 -117
  37. package/{app → src}/components/content/ProseTable.vue +23 -23
  38. package/{app → src}/components/content/Quote.vue +21 -21
  39. package/{app → src}/components/content/Tab.vue +32 -32
  40. package/{app → src}/components/content/Timeline.vue +33 -33
  41. package/{app → src}/components/content/Tip.vue +40 -40
  42. package/{app → src}/components/content/VideoEmbed.vue +112 -112
  43. package/{app → src}/components/partial/Button.vue +36 -36
  44. package/{app → src}/components/partial/DlGroup.vue +31 -31
  45. package/{app → src}/components/partial/Dropdown.vue +21 -21
  46. package/{app → src}/components/partial/Error.vue +39 -39
  47. package/{app → src}/components/partial/Expand.vue +26 -26
  48. package/{app → src}/components/partial/IconNavList.vue +24 -24
  49. package/{app → src}/components/partial/Pagination.vue +62 -62
  50. package/{app → src}/components/partial/RadioGroup.vue +30 -30
  51. package/{app → src}/components/partial/Secret.vue +11 -11
  52. package/{app → src}/components/partial/Slider.vue +48 -48
  53. package/{app → src}/components/partial/Toggle.vue +17 -17
  54. package/{app → src}/components/popover/Lightbox.vue +44 -44
  55. package/{app → src}/components/popover/Search.vue +143 -143
  56. package/{app → src}/components/popover/SearchItem.vue +28 -28
  57. package/{app → src}/components/post/Archive.vue +40 -40
  58. package/{app → src}/components/post/Article.vue +49 -49
  59. package/{app → src}/components/post/Comment.vue +119 -119
  60. package/{app → src}/components/post/Excerpt.vue +40 -40
  61. package/{app → src}/components/post/OrderToggle.vue +70 -70
  62. package/{app → src}/components/post/PostFooter.vue +52 -52
  63. package/{app → src}/components/post/PostHeader.vue +66 -66
  64. package/{app → src}/components/post/PostSurround.vue +51 -51
  65. package/{app → src}/components/post/Slide.vue +85 -85
  66. package/{app → src}/components/util/Date.vue +62 -62
  67. package/{app → src}/components/util/HydrateSafe.vue +10 -10
  68. package/{app → src}/components/util/Img.vue +38 -38
  69. package/{app → src}/components/util/Link.vue +11 -11
  70. package/{app → src}/components/widget/BlogLog.vue +23 -23
  71. package/{app → src}/components/widget/BlogStats.vue +38 -38
  72. package/{app → src}/components/widget/BlogTech.vue +57 -57
  73. package/{app → src}/components/widget/Empty.vue +3 -3
  74. package/{app → src}/components/widget/Toc.vue +67 -67
  75. package/{app → src}/composables/useArticle.ts +115 -115
  76. package/{app → src}/composables/useAvoid.ts +87 -87
  77. package/{app → src}/composables/useCopy.ts +21 -21
  78. package/{app → src}/composables/usePagination.ts +70 -70
  79. package/{app → src}/composables/useShiki.ts +129 -129
  80. package/{app → src}/composables/useToc.ts +57 -57
  81. package/{app → src}/composables/useWidgets.ts +56 -56
  82. package/{config → src/config}/app.ts +62 -62
  83. package/{config → src/config}/content.ts +75 -75
  84. package/{config → src/config}/define.ts +3 -3
  85. package/src/config/feeds.empty.ts +6 -0
  86. package/{config → src/config}/index.ts +1 -1
  87. package/{config → src/config}/schema.ts +89 -89
  88. package/{app → src}/error.vue +31 -31
  89. package/{img → src/img}/index.ts +2 -2
  90. package/{app → src}/layouts/default.vue +25 -25
  91. package/{modules → src/modules}/clarity-config/index.ts +168 -162
  92. package/src/modules/clarity-source-layout/index.ts +78 -0
  93. package/{app → src}/pages/[...slug].vue +59 -59
  94. package/{app → src}/pages/archive.vue +129 -129
  95. package/{app → src}/pages/index.vue +76 -76
  96. package/{app → src}/pages/link.vue +62 -62
  97. package/{app → src}/pages/preview.vue +46 -46
  98. package/{app → src}/plugins/easter-egg.ts +23 -23
  99. package/{app → src}/plugins/init.ts +6 -6
  100. package/{app → src}/plugins/tippy.ts +22 -22
  101. package/{public → src/public}/assets/atom.css +274 -274
  102. package/{public → src/public}/assets/atom.xsl +109 -109
  103. package/{remark-plugins → src/remark-plugins}/rehype-meta-slots.ts +58 -58
  104. package/{remark-plugins → src/remark-plugins}/remark-code-component.ts +41 -41
  105. package/{server → src/server}/api/stats.get.ts +84 -83
  106. package/{server → src/server}/routes/atom.xml.get.ts +85 -85
  107. package/{server → src/server}/routes/subscriptions.opml.get.ts +64 -64
  108. package/{shared → src/shared}/utils/clarity.ts +24 -24
  109. package/{shared → src/shared}/utils/icon.ts +218 -218
  110. package/{shared → src/shared}/utils/link.ts +52 -52
  111. package/{shared → src/shared}/utils/str.ts +88 -88
  112. package/{shared → src/shared}/utils/time.ts +115 -115
  113. package/{app → src}/shiki.config.ts +8 -8
  114. package/{app → src}/stores/layout.ts +34 -34
  115. package/{app → src}/stores/search.ts +37 -37
  116. package/{app → src}/types/article.ts +16 -16
  117. package/src/types/feed.ts +1 -0
  118. package/{app → src}/types/index.ts +14 -14
  119. package/{app → src}/types/nav.ts +11 -11
  120. package/{app → src}/utils/anim.ts +37 -37
  121. package/{app → src}/utils/img.ts +83 -83
  122. package/app/types/feed.ts +0 -1
  123. package/config/feeds.empty.ts +0 -4
  124. package/{app → src}/assets/css/_variable.scss +0 -0
  125. package/{app → src}/assets/css/animation.scss +0 -0
  126. package/{app → src}/assets/css/article.scss +0 -0
  127. package/{app → src}/assets/css/color.scss +0 -0
  128. package/{app → src}/assets/css/font.scss +0 -0
  129. package/{app → src}/assets/css/main.scss +0 -0
  130. package/{app → src}/assets/css/reusable.scss +0 -0
  131. package/{app → src}/assets/icons/solar-rewind-back-bold-duotone.svg +0 -0
  132. package/{app → src}/assets/icons/solar-rewind-forward-bold-duotone.svg +0 -0
  133. package/{app → src}/components/content/Alert.vue +0 -0
  134. package/{config → src/config}/content.d.mts +0 -0
  135. package/{config → src/config}/content.mjs +0 -0
  136. package/{config → src/config}/define.mjs +0 -0
  137. package/{config → src/config}/feed.ts +0 -0
  138. package/{config → src/config}/index.d.mts +0 -0
  139. package/{config → src/config}/index.mjs +0 -0
  140. package/{config → src/config}/public.ts +1 -1
  141. package/{config → src/config}/schema.d.mts +0 -0
  142. package/{config → src/config}/schema.mjs +0 -0
  143. package/{config → src/config}/server.ts +1 -1
  144. /package/{img → src/img}/index.d.mts +0 -0
  145. /package/{img → src/img}/index.mjs +0 -0
  146. /package/{modules → src/modules}/clarity-config/anti-mirror-client.ts +0 -0
  147. /package/{public → src/public}/fonts/AlimamaFangYuanTi.woff2 +0 -0
  148. /package/{remark-plugins → src/remark-plugins}/rehype-meta-slots.d.mts +0 -0
  149. /package/{remark-plugins → src/remark-plugins}/rehype-meta-slots.mjs +0 -0
  150. /package/{remark-plugins → src/remark-plugins}/remark-code-component.d.mts +0 -0
  151. /package/{remark-plugins → src/remark-plugins}/remark-code-component.mjs +0 -0
  152. /package/{server → src/server}/utils/clarity.ts +0 -0
  153. /package/{shared → src/shared}/types/content.ts +0 -0
  154. /package/{app → src}/types/modal.ts +0 -0
package/nuxt.config.ts CHANGED
@@ -1,225 +1,228 @@
1
- import { dirname, join } from 'node:path'
2
- import { arch, env, version as nodeVersion, platform } from 'node:process'
3
- import { fileURLToPath, pathToFileURL } from 'node:url'
4
- import { name as ciName, CLOUDFLARE_PAGES, GITHUB_ACTIONS, NETLIFY } from 'ci-info'
5
- import { Temporal } from 'temporal-polyfill'
6
- import { homepage, name as themeName, version as themeVersion } from './package.json'
7
-
8
- /** Theme 根目录(Layer 本地路径基准,兼容 npm 包 / git 包 / 本地目录安装) */
9
- const themeDir = dirname(fileURLToPath(import.meta.url))
10
- const toThemePath = (path: string) => join(themeDir, path).replaceAll('\\', '/')
11
-
1
+ import { dirname, join } from 'node:path'
2
+ import { arch, env, version as nodeVersion, platform } from 'node:process'
3
+ import { fileURLToPath, pathToFileURL } from 'node:url'
4
+ import { name as ciName, CLOUDFLARE_PAGES, GITHUB_ACTIONS, NETLIFY } from 'ci-info'
5
+ import { Temporal } from 'temporal-polyfill'
6
+ import { homepage, name as themeName, version as themeVersion } from './package.json'
7
+
8
+ /** Theme 根目录(Layer 本地路径基准,兼容 npm 包 / git 包 / 本地目录安装) */
9
+ const themeDir = dirname(fileURLToPath(import.meta.url))
10
+ const toThemePath = (path: string) => join(themeDir, path).replaceAll('\\', '/')
11
+
12
12
  function pluginPath(path: string) {
13
13
  // 插件必须是 .mjs:@nuxt/content 以 Node 原生方式加载,
14
14
  // 不允许 node_modules 内的 TS 文件(TS 剥离限制)
15
- return pathToFileURL(join(themeDir, 'remark-plugins', `${path}.mjs`)).href
15
+ return pathToFileURL(join(themeDir, 'src', 'remark-plugins', `${path}.mjs`)).href
16
16
  }
17
-
18
- /**
19
- * Clarity Theme Layer 配置
20
- *
21
- * 站点数据(SEO、favicon、scripts 等)由 modules/clarity-config
22
- * 读取消费项目的 clarity.config.ts 后统一注入,此处仅包含 Theme 自身能力。
23
- */
24
- export default defineNuxtConfig({
25
- app: {
26
- head: {
27
- meta: [
28
- { name: 'color-scheme', content: 'light dark' },
29
- { 'name': 'generator', 'content': `Clarity Theme ${themeVersion}`, 'data-github-repo': homepage },
30
- { name: 'mobile-web-app-capable', content: 'yes' },
31
- ],
32
- link: [
33
- { rel: 'stylesheet', href: 'https://s4.zstatic.net/npm/katex@0.16.44/dist/katex.min.css' },
34
- // "InterVariable", "Inter"
35
- { rel: 'stylesheet', href: 'https://s4.zstatic.net/npm/inter-ui@4.1.1/inter-variable.css' },
36
- { rel: 'stylesheet', href: 'https://s4.zstatic.net/npm/inter-ui@4.1.1/inter.css' },
37
- // "JetBrains Mono", 思源宋体 "Noto Serif SC"
38
- { rel: 'preconnect', href: 'https://fonts.gstatic.cn', crossorigin: '' },
39
- { rel: 'stylesheet', href: 'https://fonts.googleapis.cn/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&family=Noto+Serif+SC:wght@200..900&display=swap' },
40
- ],
41
- templateParams: {
42
- separator: '|',
43
- },
44
- },
45
- rootAttrs: {
46
- id: 'blog-root',
47
- },
48
- },
49
-
50
- compatibilityDate: '2024-08-03',
51
-
52
- components: [
53
- { path: toThemePath('app/components/partial'), prefix: 'Z' },
54
- toThemePath('app/components'),
55
- ],
56
-
57
- // @keep-sorted
58
- css: [
59
- toThemePath('app/assets/css/animation.scss'),
60
- toThemePath('app/assets/css/article.scss'),
61
- toThemePath('app/assets/css/color.scss'),
62
- toThemePath('app/assets/css/font.scss'),
63
- toThemePath('app/assets/css/main.scss'),
64
- toThemePath('app/assets/css/reusable.scss'),
65
- ],
66
-
67
- // @keep-sorted
68
- experimental: {
69
- extractAsyncDataHandlers: true,
70
- typescriptPlugin: true,
71
- },
72
-
73
- // @keep-sorted
74
- modules: [
75
- '@bikariya/image-viewer',
76
- '@bikariya/modals',
77
- '@bikariya/shiki',
78
- '@nuxt/content',
79
- '@nuxt/icon',
80
- '@nuxt/image',
81
- '@nuxtjs/color-mode',
17
+
18
+ /**
19
+ * Clarity Theme Layer 配置
20
+ *
21
+ * 站点数据(SEO、favicon、scripts 等)由 src/modules/clarity-config
22
+ * 读取消费项目的 clarity.config.ts 后统一注入,此处仅包含 Theme 自身能力。
23
+ */
24
+ export default defineNuxtConfig({
25
+ app: {
26
+ head: {
27
+ meta: [
28
+ { name: 'color-scheme', content: 'light dark' },
29
+ { 'name': 'generator', 'content': `Clarity Theme ${themeVersion}`, 'data-github-repo': homepage },
30
+ { name: 'mobile-web-app-capable', content: 'yes' },
31
+ ],
32
+ link: [
33
+ { rel: 'stylesheet', href: 'https://s4.zstatic.net/npm/katex@0.16.44/dist/katex.min.css' },
34
+ // "InterVariable", "Inter"
35
+ { rel: 'stylesheet', href: 'https://s4.zstatic.net/npm/inter-ui@4.1.1/inter-variable.css' },
36
+ { rel: 'stylesheet', href: 'https://s4.zstatic.net/npm/inter-ui@4.1.1/inter.css' },
37
+ // "JetBrains Mono", 思源宋体 "Noto Serif SC"
38
+ { rel: 'preconnect', href: 'https://fonts.gstatic.cn', crossorigin: '' },
39
+ { rel: 'stylesheet', href: 'https://fonts.googleapis.cn/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&family=Noto+Serif+SC:wght@200..900&display=swap' },
40
+ ],
41
+ templateParams: {
42
+ separator: '|',
43
+ },
44
+ },
45
+ rootAttrs: {
46
+ id: 'blog-root',
47
+ },
48
+ },
49
+
50
+ compatibilityDate: '2024-08-03',
51
+
52
+ components: [
53
+ { path: toThemePath('src/components/partial'), prefix: 'Z' },
54
+ toThemePath('src/components'),
55
+ ],
56
+
57
+ // @keep-sorted
58
+ css: [
59
+ toThemePath('src/assets/css/animation.scss'),
60
+ toThemePath('src/assets/css/article.scss'),
61
+ toThemePath('src/assets/css/color.scss'),
62
+ toThemePath('src/assets/css/font.scss'),
63
+ toThemePath('src/assets/css/main.scss'),
64
+ toThemePath('src/assets/css/reusable.scss'),
65
+ ],
66
+
67
+ // @keep-sorted
68
+ experimental: {
69
+ extractAsyncDataHandlers: true,
70
+ typescriptPlugin: true,
71
+ },
72
+
73
+ // @keep-sorted
74
+ modules: [
75
+ // 必须最先运行:把 src/ 仅应用到 Clarity 自身 layer,避免静态
76
+ // srcDir / serverDir / dir.* 经 c12 合并泄漏到 consumer root 配置。
77
+ toThemePath('src/modules/clarity-source-layout'),
78
+ '@bikariya/image-viewer',
79
+ '@bikariya/modals',
80
+ '@bikariya/shiki',
81
+ '@nuxt/content',
82
+ '@nuxt/icon',
83
+ '@nuxt/image',
84
+ '@nuxtjs/color-mode',
82
85
  '@nuxtjs/seo',
83
86
  '@pinia/nuxt',
84
87
  '@vueuse/nuxt',
85
88
  // Layer 配置中的相对 module 路径会以消费项目为基准解析,必须使用绝对路径;
86
89
  // 且 clarity-config 必须先于 nuxt-llms 运行:后者在 setup 时读取注入的 llms 站点配置
87
- toThemePath('modules/clarity-config'),
90
+ toThemePath('src/modules/clarity-config'),
88
91
  'nuxt-llms',
89
92
  ],
90
-
91
- nitro: {
92
- prerender: {
93
- // 修复部分平台会在文章路径后添加 `/`,导致闪现 404 错误
94
- // https://github.com/nuxt/content/issues/2378
95
- autoSubfolderIndex: CLOUDFLARE_PAGES || GITHUB_ACTIONS || NETLIFY ? false : undefined,
96
- },
97
- },
98
-
99
- runtimeConfig: {
100
- // @keep-sorted
101
- public: {
102
- arch,
103
- buildTime: Temporal.Now.zonedDateTimeISO().toString(),
104
- // EdgeOne 检测暂时不可用
105
- ci: env.TENCENTCLOUD_RUNENV === 'SCF' ? 'EdgeOne' : ciName || '',
106
- nodeVersion,
107
- platform,
108
- },
109
- },
110
-
111
- typescript: {
112
- nodeTsConfig: {
113
- // @keep-sorted
114
- include: [
115
- '../config/**/*.ts',
116
- '../remark-plugins/**/*.ts',
117
- ],
118
- },
119
- },
120
-
121
- vite: {
122
- css: {
123
- preprocessorOptions: {
124
- scss: {
125
- additionalData: `@use "${toThemePath('app/assets/css/_variable.scss')}" as *;`,
126
- },
127
- },
128
- },
129
- // @keep-sorted
130
- optimizeDeps: {
131
- include: ['@shikijs/colorized-brackets', '@shikijs/transformers', '@unhead/schema-org/vue', '@vue/devtools-core', '@vue/devtools-kit', 'embla-carousel-autoplay', 'embla-carousel-vue', 'embla-carousel-wheel-gestures', 'es-toolkit/array', 'es-toolkit/math', 'es-toolkit/object', 'es-toolkit/promise', 'es-toolkit/string', 'minisearch', 'parse-domain', 'plain-shiki', 'shiki/themes/catppuccin-latte.mjs', 'shiki/themes/one-dark-pro.mjs', 'temporal-polyfill', 'vue-tippy'],
132
- },
133
- server: {
134
- allowedHosts: true,
135
- },
136
- },
137
-
138
- colorMode: {
139
- preference: 'system',
140
- fallback: 'light',
141
- classSuffix: '',
142
- },
143
-
144
- content: {
145
- build: {
146
- markdown: {
147
- highlight: false,
148
- // @keep-sorted
149
- remarkPlugins: {
150
- [pluginPath('remark-code-component')]: {
151
- options: {
152
- 'mermaid': { component: 'mermaid', prop: 'code' },
153
- 'music-abc': { component: 'music-score', prop: 'abc' },
154
- },
155
- },
156
- 'remark-math': {},
157
- 'remark-reading-time': {},
158
- },
159
- // @keep-sorted
160
- rehypePlugins: {
161
- [pluginPath('rehype-meta-slots')]: {},
162
- 'rehype-katex': {},
163
- },
164
- toc: { depth: 4, searchDepth: 4 },
165
- },
166
- },
167
- experimental: {
168
- sqliteConnector: 'native',
169
- },
170
- },
171
-
172
- dxup: {
173
- features: {
174
- // 页面通过 <template #aside> 向布局具名插槽传参
175
- namedLayoutSlots: true,
176
- },
177
- },
178
-
179
- hooks: {
180
- ready: () => {
181
- console.info(`
182
- ================================
183
- ${themeName} ${themeVersion}
184
- ${homepage}
185
- ================================
186
- `)
187
- },
188
- },
189
-
190
- icon: {
191
- customCollections: [
192
- { prefix: 'clarity', dir: toThemePath('app/assets/icons') },
193
- ],
194
- clientBundle: {
195
- scan: {
196
- globInclude: ['**\/*.{vue,jsx,tsx,ts,md,mdc,mdx}'],
197
- },
198
- },
199
- },
200
-
201
- image: {
202
- densities: [1, 1.5, 2],
203
- format: ['avif', 'webp'],
204
- // Netlify 下 netlify 处理器无法显示站外图片,ipx 处理器无法显示站内图片,需彻底禁用
205
- // https://github.com/nuxt/image/issues/1353
206
- provider: NETLIFY ? 'none' : undefined,
207
- },
208
-
209
- linkChecker: {
210
- // @keep-sorted
211
- skipInspections: [
212
- 'no-baseless',
213
- 'no-non-ascii-chars',
214
- 'no-uppercase-chars',
215
- ],
216
- },
217
-
218
- ogImage: {
219
- enabled: false,
220
- },
221
-
222
- robots: {
223
- disableNuxtContentIntegration: true,
224
- },
225
- })
93
+
94
+ nitro: {
95
+ prerender: {
96
+ // 修复部分平台会在文章路径后添加 `/`,导致闪现 404 错误
97
+ // https://github.com/nuxt/content/issues/2378
98
+ autoSubfolderIndex: CLOUDFLARE_PAGES || GITHUB_ACTIONS || NETLIFY ? false : undefined,
99
+ },
100
+ },
101
+
102
+ runtimeConfig: {
103
+ // @keep-sorted
104
+ public: {
105
+ arch,
106
+ buildTime: Temporal.Now.zonedDateTimeISO().toString(),
107
+ // EdgeOne 检测暂时不可用
108
+ ci: env.TENCENTCLOUD_RUNENV === 'SCF' ? 'EdgeOne' : ciName || '',
109
+ nodeVersion,
110
+ platform,
111
+ },
112
+ },
113
+
114
+ typescript: {
115
+ nodeTsConfig: {
116
+ // @keep-sorted
117
+ include: [
118
+ '../src/config/**/*.ts',
119
+ '../src/remark-plugins/**/*.ts',
120
+ ],
121
+ },
122
+ },
123
+
124
+ vite: {
125
+ css: {
126
+ preprocessorOptions: {
127
+ scss: {
128
+ additionalData: `@use "${toThemePath('src/assets/css/_variable.scss')}" as *;`,
129
+ },
130
+ },
131
+ },
132
+ // @keep-sorted
133
+ optimizeDeps: {
134
+ include: ['@shikijs/colorized-brackets', '@shikijs/transformers', '@unhead/schema-org/vue', '@vue/devtools-core', '@vue/devtools-kit', 'embla-carousel-autoplay', 'embla-carousel-vue', 'embla-carousel-wheel-gestures', 'es-toolkit/array', 'es-toolkit/math', 'es-toolkit/object', 'es-toolkit/promise', 'es-toolkit/string', 'minisearch', 'parse-domain', 'plain-shiki', 'shiki/themes/catppuccin-latte.mjs', 'shiki/themes/one-dark-pro.mjs', 'temporal-polyfill', 'vue-tippy'],
135
+ },
136
+ server: {
137
+ allowedHosts: true,
138
+ },
139
+ },
140
+
141
+ colorMode: {
142
+ preference: 'system',
143
+ fallback: 'light',
144
+ classSuffix: '',
145
+ },
146
+
147
+ content: {
148
+ build: {
149
+ markdown: {
150
+ highlight: false,
151
+ // @keep-sorted
152
+ remarkPlugins: {
153
+ [pluginPath('remark-code-component')]: {
154
+ options: {
155
+ 'mermaid': { component: 'mermaid', prop: 'code' },
156
+ 'music-abc': { component: 'music-score', prop: 'abc' },
157
+ },
158
+ },
159
+ 'remark-math': {},
160
+ 'remark-reading-time': {},
161
+ },
162
+ // @keep-sorted
163
+ rehypePlugins: {
164
+ [pluginPath('rehype-meta-slots')]: {},
165
+ 'rehype-katex': {},
166
+ },
167
+ toc: { depth: 4, searchDepth: 4 },
168
+ },
169
+ },
170
+ experimental: {
171
+ sqliteConnector: 'native',
172
+ },
173
+ },
174
+
175
+ dxup: {
176
+ features: {
177
+ // 页面通过 <template #aside> 向布局具名插槽传参
178
+ namedLayoutSlots: true,
179
+ },
180
+ },
181
+
182
+ hooks: {
183
+ ready: () => {
184
+ console.info(`
185
+ ================================
186
+ ${themeName} ${themeVersion}
187
+ ${homepage}
188
+ ================================
189
+ `)
190
+ },
191
+ },
192
+
193
+ icon: {
194
+ customCollections: [
195
+ { prefix: 'clarity', dir: toThemePath('src/assets/icons') },
196
+ ],
197
+ clientBundle: {
198
+ scan: {
199
+ globInclude: ['**\/*.{vue,jsx,tsx,ts,md,mdc,mdx}'],
200
+ },
201
+ },
202
+ },
203
+
204
+ image: {
205
+ densities: [1, 1.5, 2],
206
+ format: ['avif', 'webp'],
207
+ // Netlify 下 netlify 处理器无法显示站外图片,ipx 处理器无法显示站内图片,需彻底禁用
208
+ // https://github.com/nuxt/image/issues/1353
209
+ provider: NETLIFY ? 'none' : undefined,
210
+ },
211
+
212
+ linkChecker: {
213
+ // @keep-sorted
214
+ skipInspections: [
215
+ 'no-baseless',
216
+ 'no-non-ascii-chars',
217
+ 'no-uppercase-chars',
218
+ ],
219
+ },
220
+
221
+ ogImage: {
222
+ enabled: false,
223
+ },
224
+
225
+ robots: {
226
+ disableNuxtContentIntegration: true,
227
+ },
228
+ })
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "clarity-theme",
3
3
  "type": "module",
4
- "version": "0.1.0",
5
- "packageManager": "pnpm@12.4.1",
4
+ "version": "0.1.2",
6
5
  "description": "Clarity Theme — 从 blog-v3 提取的可复用 Nuxt 4 Layer 博客主题",
7
6
  "license": "MIT",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
8
10
  "homepage": "https://github.com/iicemeta/clarity-theme",
9
11
  "repository": {
10
12
  "type": "git",
@@ -16,59 +18,33 @@
16
18
  "exports": {
17
19
  ".": "./nuxt.config.ts",
18
20
  "./config": {
19
- "types": "./config/index.d.mts",
20
- "default": "./config/index.mjs"
21
+ "types": "./src/config/index.d.mts",
22
+ "default": "./src/config/index.mjs"
21
23
  },
22
24
  "./content": {
23
- "types": "./config/content.d.mts",
24
- "default": "./config/content.mjs"
25
+ "types": "./src/config/content.d.mts",
26
+ "default": "./src/config/content.mjs"
25
27
  },
26
28
  "./img": {
27
- "types": "./img/index.d.mts",
28
- "default": "./img/index.mjs"
29
+ "types": "./src/img/index.d.mts",
30
+ "default": "./src/img/index.mjs"
29
31
  },
30
32
  "./schema": {
31
- "types": "./config/schema.d.mts",
32
- "default": "./config/schema.mjs"
33
+ "types": "./src/config/schema.d.mts",
34
+ "default": "./src/config/schema.mjs"
33
35
  }
34
36
  },
35
37
  "main": "./nuxt.config.ts",
36
38
  "files": [
37
39
  "LICENSE",
38
40
  "README.md",
39
- "app",
40
- "config",
41
- "img",
42
- "modules",
43
41
  "nuxt.config.ts",
44
42
  "package.json",
45
- "public",
46
- "remark-plugins",
47
- "server",
48
- "shared"
43
+ "src"
49
44
  ],
50
45
  "engines": {
51
46
  "node": "^22.19 || ^24.11 || >=26"
52
47
  },
53
- "scripts": {
54
- "dev": "pnpm --dir playground dev",
55
- "build": "pnpm --dir playground build",
56
- "generate": "pnpm --dir playground generate",
57
- "lint": "eslint && stylelint \"app/**/*.{vue,scss}\" \"playground/app/**/*.vue\"",
58
- "lint:fix": "eslint --fix && stylelint \"app/**/*.{vue,scss}\" \"playground/app/**/*.vue\" --fix",
59
- "typecheck": "pnpm --dir playground typecheck",
60
- "verify": "node scripts/verify-theme.mjs",
61
- "test:sync": "node --test tests/sync-upstream.test.mjs",
62
- "test:migration": "node --test tests/migration-skill.test.mjs",
63
- "test:contract": "node scripts/test-compatibility.mjs --contract-only",
64
- "test:release": "pnpm verify && pnpm test:consumer && pnpm test:compatibility",
65
- "test:consumer": "node scripts/test-consumer.mjs",
66
- "test:compatibility": "node scripts/test-compatibility.mjs",
67
- "sync:check": "node scripts/sync-upstream.mjs check",
68
- "sync:diff": "node scripts/sync-upstream.mjs diff",
69
- "sync:apply": "node scripts/sync-upstream.mjs apply",
70
- "sync:verify": "node scripts/sync-upstream.mjs verify"
71
- },
72
48
  "peerDependencies": {
73
49
  "nuxt": "^4.5.2",
74
50
  "vue": "^3.5.42"
@@ -129,6 +105,7 @@
129
105
  "@nuxt/hints": "^1.1.4",
130
106
  "@stylistic/stylelint-plugin": "^5.2.1",
131
107
  "@types/hast": "^3.0.5",
108
+ "@types/mdast": "^4.0.4",
132
109
  "@zinkawaii/stylelint-config": "^0.5.2",
133
110
  "cspell": "^10.2.2",
134
111
  "eslint": "^10.10.0",
@@ -144,5 +121,26 @@
144
121
  "typescript": "^6.0.3",
145
122
  "vue": "^3.5.42",
146
123
  "vue-router": "^5.3.1"
124
+ },
125
+ "scripts": {
126
+ "dev": "pnpm --dir playground dev",
127
+ "build": "pnpm --dir playground build",
128
+ "generate": "pnpm --dir playground generate",
129
+ "lint": "eslint && stylelint \"src/**/*.{vue,scss}\" \"playground/app/**/*.vue\"",
130
+ "lint:fix": "eslint --fix && stylelint \"src/**/*.{vue,scss}\" \"playground/app/**/*.vue\" --fix",
131
+ "typecheck": "pnpm --dir playground typecheck",
132
+ "verify": "node scripts/verify-theme.mjs",
133
+ "test:sync": "node --test tests/sync-upstream.test.mjs",
134
+ "test:migration": "node --test tests/migration-skill.test.mjs",
135
+ "test:contract": "node scripts/test-compatibility.mjs --contract-only",
136
+ "test:release": "pnpm verify && pnpm test:consumer && pnpm test:compatibility",
137
+ "test:consumer": "node scripts/test-consumer.mjs",
138
+ "test:compatibility": "node scripts/test-compatibility.mjs",
139
+ "test:registry-consumer": "node scripts/test-registry-consumer.mjs",
140
+ "release:check": "node scripts/release-check.mjs",
141
+ "sync:check": "node scripts/sync-upstream.mjs check",
142
+ "sync:diff": "node scripts/sync-upstream.mjs diff",
143
+ "sync:apply": "node scripts/sync-upstream.mjs apply",
144
+ "sync:verify": "node scripts/sync-upstream.mjs verify"
147
145
  }
148
146
  }