valaxy 0.12.9 → 0.13.0

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 (36) hide show
  1. package/client/App.vue +13 -13
  2. package/client/components/AppLink.vue +2 -2
  3. package/client/components/ValaxyCopyright.vue +8 -8
  4. package/client/components/ValaxyMd.vue +1 -1
  5. package/client/composables/body-scroll-lock.ts +17 -0
  6. package/client/composables/category.ts +1 -1
  7. package/client/composables/common.ts +3 -3
  8. package/client/composables/index.ts +1 -3
  9. package/client/composables/outline/anchor.ts +1 -1
  10. package/client/composables/post.ts +1 -1
  11. package/client/composables/sidebar.ts +1 -1
  12. package/client/composables/tag.ts +1 -1
  13. package/client/composables/widgets/aplayer.ts +3 -3
  14. package/client/config.ts +28 -13
  15. package/client/locales/en.yml +5 -4
  16. package/client/locales/zh-CN.yml +5 -4
  17. package/client/modules/valaxy.ts +4 -4
  18. package/client/styles/palette.scss +2 -0
  19. package/client/utils/helper.ts +0 -2
  20. package/client/utils/time.ts +1 -1
  21. package/dist/chunk-CIBEFRF5.cjs +114 -0
  22. package/dist/chunk-UQXOVWU2.mjs +114 -0
  23. package/dist/{config-e579a17c.d.ts → config-09cfcc92.d.ts} +45 -42
  24. package/dist/node/cli.cjs +1 -13
  25. package/dist/node/cli.d.ts +4 -1
  26. package/dist/node/cli.mjs +1 -13
  27. package/dist/node/index.cjs +1 -1
  28. package/dist/node/index.d.ts +109 -28
  29. package/dist/node/index.mjs +1 -1
  30. package/dist/types/index.d.ts +1 -1
  31. package/package.json +7 -2
  32. package/types/config.ts +48 -44
  33. package/client/composables/comments/index.ts +0 -1
  34. package/client/composables/comments/twikoo.ts +0 -55
  35. package/dist/chunk-MVEI4SJS.cjs +0 -102
  36. package/dist/chunk-R6CH55I6.mjs +0 -102
package/client/App.vue CHANGED
@@ -13,12 +13,12 @@ import { isDark, useFrontmatter } from './composables'
13
13
  // https://github.com/vueuse/head
14
14
  // you can use this to manipulate the document head in any components,
15
15
  // they will be rendered correctly in the html results with vite-ssg
16
- import { useConfig } from './config'
16
+ import { useSiteConfig } from './config'
17
17
 
18
18
  // <link rel="apple-touch-icon" href="/pwa-192x192.png">
19
19
  // <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#00aba9">
20
20
 
21
- const config = useConfig()
21
+ const siteConfig = useSiteConfig()
22
22
  // todo, allow user config
23
23
  const themeColor = computed(() => isDark.value ? '#000' : '#ffffff')
24
24
  const fm = useFrontmatter()
@@ -27,16 +27,16 @@ const { locale } = useI18n()
27
27
 
28
28
  useHead({
29
29
  title: computed(() => fm.value[`title_${locale.value}`] || fm.value.title),
30
- titleTemplate: computed(() => fm.value.titleTemplate || ((title: string) => title ? `${title} - ${config.value.title}` : config.value.title)),
30
+ titleTemplate: computed(() => fm.value.titleTemplate || ((title: string) => title ? `${title} - ${siteConfig.value.title}` : siteConfig.value.title)),
31
31
  link: [
32
32
  {
33
33
  rel: 'icon',
34
- href: config.value.favicon,
35
- type: config.value.favicon?.endsWith('svg') ? 'image/svg+xml' : 'image/png',
34
+ href: siteConfig.value.favicon,
35
+ type: siteConfig.value.favicon?.endsWith('svg') ? 'image/svg+xml' : 'image/png',
36
36
  },
37
37
  ],
38
38
  meta: [
39
- { name: 'description', content: computed(() => config.value.description) },
39
+ { name: 'description', content: computed(() => siteConfig.value.description) },
40
40
  {
41
41
  name: 'theme-color',
42
42
  content: themeColor,
@@ -55,13 +55,13 @@ useHead({
55
55
  // seo
56
56
  // todo: get first image url from markdown
57
57
  useSeoMeta({
58
- description: computed(() => fm.value.excerpt || config.value.description),
59
- ogDescription: computed(() => fm.value.excerpt || config.value.description),
60
- ogLocale: computed(() => fm.value.lang || config.value.lang),
61
- ogSiteName: computed(() => config.value.title),
62
- ogTitle: computed(() => fm.value.title || config.value.title),
63
- ogImage: computed(() => config.value.favicon),
64
- ogUrl: computed(() => fm.value.url || config.value.url),
58
+ description: computed(() => fm.value.excerpt || siteConfig.value.description),
59
+ ogDescription: computed(() => fm.value.excerpt || siteConfig.value.description),
60
+ ogLocale: computed(() => fm.value.lang || siteConfig.value.lang),
61
+ ogSiteName: computed(() => siteConfig.value.title),
62
+ ogTitle: computed(() => fm.value.title || siteConfig.value.title),
63
+ ogImage: computed(() => siteConfig.value.favicon),
64
+ ogUrl: computed(() => fm.value.url || siteConfig.value.url),
65
65
  })
66
66
 
67
67
  const onContentUpdated = ref()
@@ -14,11 +14,11 @@ const isExternalLink = computed(() => {
14
14
  </script>
15
15
 
16
16
  <template>
17
- <a v-if="isExternalLink || href" v-bind="$attrs" :href="href || to" target="_blank">
17
+ <a v-if="isExternalLink" v-bind="$attrs" :href="href || to" target="_blank">
18
18
  <slot />
19
19
  <div v-if="showExternalIcon" class="icon-link inline-block" i-ri-arrow-right-up-line />
20
20
  </a>
21
- <router-link v-else v-bind="$props as any">
21
+ <router-link v-else v-bind="$props" :to="href || to || '#'">
22
22
  <slot />
23
23
  </router-link>
24
24
  </template>
@@ -1,7 +1,7 @@
1
1
  <script lang="ts" setup>
2
2
  import { computed } from 'vue'
3
3
  import { useI18n } from 'vue-i18n'
4
- import { useConfig } from '../config'
4
+ import { useSiteConfig } from '../config'
5
5
 
6
6
  withDefaults(defineProps<{
7
7
  url?: string
@@ -11,17 +11,17 @@ withDefaults(defineProps<{
11
11
 
12
12
  const { t, locale } = useI18n()
13
13
 
14
- const config = useConfig()
14
+ const siteConfig = useSiteConfig()
15
15
 
16
- const ccVersion = (config.value.license.type === 'zero') ? '1.0' : '4.0'
17
- const ccPrefix = (config.value.license.type === 'zero') ? 'publicdomain' : 'licenses'
16
+ const ccVersion = (siteConfig.value.license.type === 'zero') ? '1.0' : '4.0'
17
+ const ccPrefix = (siteConfig.value.license.type === 'zero') ? 'publicdomain' : 'licenses'
18
18
  const ccURL = computed(() => {
19
- const ccLang = config.value.license.language ? config.value.license.language : (locale.value === 'zh-CN') ? 'zh' : 'en'
20
- return `https://creativecommons.org/${ccPrefix}/${config.value.license.type}/${ccVersion}/deed.${ccLang}`
19
+ const ccLang = siteConfig.value.license.language ? siteConfig.value.license.language : (locale.value === 'zh-CN') ? 'zh' : 'en'
20
+ return `https://creativecommons.org/${ccPrefix}/${siteConfig.value.license.type}/${ccVersion}/deed.${ccLang}`
21
21
  })
22
22
 
23
23
  const licenseHtml = computed(() => {
24
- return t('post.copyright.license_content', [`<a href="${ccURL.value}" target="_blank" rel="noopener" title="CC ${`${config.value.license.type.toUpperCase()} ${ccVersion}`} ">CC ${config.value.license.type.toUpperCase()}</a>`])
24
+ return t('post.copyright.license_content', [`<a href="${ccURL.value}" target="_blank" rel="noopener" title="CC ${`${siteConfig.value.license.type.toUpperCase()} ${ccVersion}`} ">CC ${siteConfig.value.license.type.toUpperCase()}</a>`])
25
25
  })
26
26
  </script>
27
27
 
@@ -31,7 +31,7 @@ const licenseHtml = computed(() => {
31
31
  <strong>
32
32
  {{ t('post.copyright.author') + t('symbol.colon') }}
33
33
  </strong>
34
- <span>{{ config.author.name }}</span>
34
+ <span>{{ siteConfig.author.name }}</span>
35
35
  </li>
36
36
  <li v-if="url" class="post-copyright-link">
37
37
  <strong>
@@ -3,7 +3,7 @@ import type { Ref } from 'vue'
3
3
  import { inject, onMounted, ref } from 'vue'
4
4
  import { useI18n } from 'vue-i18n'
5
5
  import { useAplayer, useCodePen, useCopyCode, wrapTable } from '..'
6
- import type { Post } from '../../types'
6
+ import type { Post } from '../..'
7
7
 
8
8
  const props = defineProps<{
9
9
  frontmatter: Post
@@ -0,0 +1,17 @@
1
+ import { clearAllBodyScrollLocks, disableBodyScroll } from 'body-scroll-lock'
2
+ import type { Ref } from 'vue'
3
+
4
+ export function useBodyScrollLock(screenRef: Ref<HTMLElement | undefined>) {
5
+ function lockBodyScroll() {
6
+ disableBodyScroll(screenRef.value! || document.body, { reserveScrollBarGap: true })
7
+ }
8
+
9
+ function unlockBodyScroll() {
10
+ clearAllBodyScrollLocks()
11
+ }
12
+
13
+ return {
14
+ lockBodyScroll,
15
+ unlockBodyScroll,
16
+ }
17
+ }
@@ -1,5 +1,5 @@
1
1
  import { unref } from 'vue'
2
- import type { Post } from '../../types'
2
+ import type { Post } from '../..'
3
3
  import { usePostList } from './post'
4
4
 
5
5
  export interface BaseCategory {
@@ -3,7 +3,7 @@ import { computed, inject } from 'vue'
3
3
  import { isClient } from '@vueuse/core'
4
4
 
5
5
  import type { PageData, Post } from '../../types'
6
- import { useConfig } from '../config'
6
+ import { useSiteConfig } from '../config'
7
7
 
8
8
  export function useFrontmatter() {
9
9
  const route = useRoute()
@@ -25,10 +25,10 @@ export function useData(): PageData {
25
25
  * get full url
26
26
  */
27
27
  export function useFullUrl() {
28
- const config = useConfig()
28
+ const siteConfig = useSiteConfig()
29
29
  const route = useRoute()
30
30
  const url = computed(() => {
31
- const siteUrl = config.value.url.endsWith('/') ? config.value.url.slice(0, -1) : config.value.url
31
+ const siteUrl = siteConfig.value.url.endsWith('/') ? siteConfig.value.url.slice(0, -1) : siteConfig.value.url
32
32
  const origin = siteUrl || (isClient && window.location.origin)
33
33
  return origin + route.path
34
34
  })
@@ -14,6 +14,4 @@ export * from './locale'
14
14
 
15
15
  export * from './sidebar'
16
16
  export * from './outline'
17
-
18
- // comment
19
- export * from './comments'
17
+ export * from './body-scroll-lock'
@@ -68,7 +68,7 @@ export function useActiveAnchor(
68
68
  const [isActive, hash] = isAnchorActive(i, anchor, nextAnchor)
69
69
 
70
70
  if (isActive) {
71
- history.replaceState(null, document.title, hash || ' ')
71
+ history.replaceState(history.state, document.title, hash || ' ')
72
72
  activateLink(hash)
73
73
  return
74
74
  }
@@ -2,7 +2,7 @@ import type { Ref } from 'vue'
2
2
  import { computed } from 'vue'
3
3
  import { useRoute, useRouter } from 'vue-router'
4
4
  import { useI18n } from 'vue-i18n'
5
- import type { Post } from '../../types'
5
+ import type { Post } from '../..'
6
6
  import { sortByDate } from '../utils'
7
7
 
8
8
  export const usePostTitle = (post: Ref<Post>) => {
@@ -24,7 +24,7 @@ export function useActiveSidebarLinks(container: Ref<HTMLElement>, marker: Ref<H
24
24
  const [isActive, hash] = isAnchorActive(i, anchor, nextAnchor)
25
25
 
26
26
  if (isActive) {
27
- history.replaceState(null, document.title, hash || ' ')
27
+ history.replaceState(history.state, document.title, hash || ' ')
28
28
  activateLink(hash)
29
29
  return
30
30
  }
@@ -1,5 +1,5 @@
1
1
  import { TinyColor } from '@ctrl/tinycolor'
2
- import type { Post } from '../../types'
2
+ import type { Post } from '../..'
3
3
  import { usePostList } from './post'
4
4
 
5
5
  export type Tags = Map<string, {
@@ -1,7 +1,7 @@
1
1
  import { useScriptTag } from '@vueuse/core'
2
2
  import { useHead } from '@vueuse/head'
3
3
  import { computed } from 'vue'
4
- import { useConfig } from '../..'
4
+ import { useSiteConfig } from '../..'
5
5
 
6
6
  /**
7
7
  * use MetingJS and Aplayer
@@ -9,8 +9,8 @@ import { useConfig } from '../..'
9
9
  * @see https://github.com/metowolf/MetingJS
10
10
  */
11
11
  export function useAplayer() {
12
- const config = useConfig()
13
- const cdnPrefix = computed(() => config.value.cdn.prefix)
12
+ const siteConfig = useSiteConfig()
13
+ const cdnPrefix = computed(() => siteConfig.value.cdn.prefix)
14
14
 
15
15
  useHead({
16
16
  link: [
package/client/config.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // @ts-expect-error virtual module @valaxyjs/config
2
- import valaxySiteConfig from '/@valaxyjs/site'
2
+ import valaxyConfig from '/@valaxyjs/config'
3
3
  // @ts-expect-error virtual module @valaxyjs/context
4
4
  import valaxyContext from '/@valaxyjs/context'
5
5
  import type { ComputedRef, InjectionKey } from 'vue'
@@ -8,7 +8,7 @@ import { computed, inject, readonly, shallowRef } from 'vue'
8
8
  // fix build caused by pnpm
9
9
  // This is likely not portable. A type annotation is necessary.
10
10
  // https://github.com/microsoft/TypeScript/issues/42873
11
- import type { DefaultThemeConfig, SiteConfig as ValaxySiteConfig } from 'valaxy/types'
11
+ import type { DefaultThemeConfig, ValaxyConfig } from 'valaxy/types'
12
12
 
13
13
  /**
14
14
  * parse valaxy config
@@ -24,16 +24,16 @@ interface ValaxyContext {
24
24
  userRoot: string
25
25
  }
26
26
 
27
- export const valaxySiteConfigSymbol: InjectionKey<ComputedRef<ValaxySiteConfig>> = Symbol('valaxy:site')
28
- export const valaxySiteConfigRef = shallowRef<ValaxySiteConfig>(parse<ValaxySiteConfig>(valaxySiteConfig))
27
+ export const valaxyConfigSymbol: InjectionKey<ComputedRef<ValaxyConfig>> = Symbol('valaxy:config')
28
+ export const valaxyConfigRef = shallowRef<ValaxyConfig>(parse<ValaxyConfig>(valaxyConfig))
29
29
 
30
30
  export const valaxyContextRef = shallowRef<ValaxyContext>(parse<ValaxyContext>(valaxyContext))
31
31
 
32
32
  // hmr
33
33
  if (import.meta.hot) {
34
- // /@valaxyjs/site must be static string
35
- import.meta.hot.accept('/@valaxyjs/site', (m) => {
36
- valaxySiteConfigRef.value = parse<ValaxySiteConfig>(m?.default)
34
+ // /@valaxyjs/config must be static string
35
+ import.meta.hot.accept('/@valaxyjs/config', (m) => {
36
+ valaxyConfigRef.value = parse<ValaxyConfig>(m?.default)
37
37
  })
38
38
 
39
39
  // context
@@ -42,8 +42,8 @@ if (import.meta.hot) {
42
42
  })
43
43
  }
44
44
 
45
- export function initSite() {
46
- return computed(() => valaxySiteConfigRef.value)
45
+ export function initValaxyConfig() {
46
+ return computed(() => valaxyConfigRef.value)
47
47
  }
48
48
 
49
49
  export function initContext() {
@@ -55,8 +55,8 @@ export function initContext() {
55
55
  * @public
56
56
  * @returns
57
57
  */
58
- export function useSite<ThemeConfig = DefaultThemeConfig>() {
59
- const config = inject<ComputedRef<ValaxySiteConfig<ThemeConfig>>>(valaxySiteConfigSymbol)
58
+ export function useValaxyConfig<ThemeConfig = DefaultThemeConfig>() {
59
+ const config = inject<ComputedRef<ValaxyConfig<ThemeConfig>>>(valaxyConfigSymbol)
60
60
  if (!config)
61
61
  throw new Error('[Valaxy] site config not properly injected in app')
62
62
  return config!
@@ -68,7 +68,17 @@ export function useSite<ThemeConfig = DefaultThemeConfig>() {
68
68
  * @returns
69
69
  */
70
70
  export function useConfig<ThemeConfig = DefaultThemeConfig>() {
71
- return useSite<ThemeConfig>()
71
+ return useValaxyConfig<ThemeConfig>()
72
+ }
73
+
74
+ /**
75
+ * get valaxy config
76
+ * @public
77
+ * @returns
78
+ */
79
+ export function useSiteConfig<ThemeConfig = DefaultThemeConfig>() {
80
+ const config = useValaxyConfig<ThemeConfig>()
81
+ return computed(() => config!.value.siteConfig)
72
82
  }
73
83
 
74
84
  /**
@@ -79,6 +89,11 @@ export function useConfig<ThemeConfig = DefaultThemeConfig>() {
79
89
  * @returns
80
90
  */
81
91
  export function useThemeConfig<ThemeConfig = DefaultThemeConfig>() {
82
- const config = useSite<ThemeConfig>()
92
+ const config = useValaxyConfig<ThemeConfig>()
83
93
  return computed(() => config!.value.themeConfig)
84
94
  }
95
+
96
+ export function useRuntimeConfig() {
97
+ const config = useValaxyConfig()
98
+ return computed(() => config!.value.runtimeConfig)
99
+ }
@@ -81,6 +81,7 @@ search:
81
81
  placeholder: Searching...
82
82
  empty: 'We could not find any results for the search: {query}.'
83
83
  hits_time: '{hits} results found in {time} ms'
84
+ hits: '{count} results found'
84
85
 
85
86
  symbol:
86
87
  comma: ', '
@@ -103,7 +104,7 @@ wordcount:
103
104
  time_total: Total reading time
104
105
 
105
106
  time:
106
- day: 1 Day | %d Days
107
- hour: 1 Hour | %d Hours
108
- minute: 1 Minute | %d Minutes
109
- second: 1 Second | %d Seconds
107
+ day: 1 Day | {count} Days
108
+ hour: 1 Hour | {count} Hours
109
+ minute: 1 Minute | {count} Minutes
110
+ second: 1 Second | {count} Seconds
@@ -80,6 +80,7 @@ search:
80
80
  placeholder: 搜索...
81
81
  empty: '找不到您查询的内容: {query}'
82
82
  hits_time: '找到 {hits} 条结果(用时 {time} 毫秒)'
83
+ hits: '找到 {count} 条结果'
83
84
 
84
85
  symbol:
85
86
  comma: ,
@@ -102,7 +103,7 @@ wordcount:
102
103
  time_total: 站点阅读时长
103
104
 
104
105
  time:
105
- day: 1 天 | %d
106
- hour: 1 小时 | %d 小时
107
- minute: 1 分 | %d
108
- second: 1 秒 | %d
106
+ day: 1 天 | {count}
107
+ hour: 1 小时 | {count} 小时
108
+ minute: 1 分 | {count}
109
+ second: 1 秒 | {count}
@@ -12,7 +12,7 @@ import { useStorage } from '@vueuse/core'
12
12
 
13
13
  import type { Router } from 'vue-router'
14
14
  import type { PageDataPayload } from '../../types'
15
- import { initSite, valaxySiteConfigSymbol } from '../config'
15
+ import { initValaxyConfig, valaxyConfigSymbol } from '../config'
16
16
  import { ensureSuffix } from '@antfu/utils'
17
17
 
18
18
  import type { UserModule } from 'valaxy/client/types'
@@ -45,10 +45,10 @@ function shouldHotReload(payload: PageDataPayload): boolean {
45
45
 
46
46
  export const install: UserModule = ({ app, router }) => {
47
47
  // inject valaxy config before modules
48
- const config = initSite()
49
- app.provide(valaxySiteConfigSymbol, config)
48
+ const config = initValaxyConfig()
49
+ app.provide(valaxyConfigSymbol, config)
50
50
 
51
- const locale = useStorage('valaxy-locale', config.value.lang || 'en')
51
+ const locale = useStorage('valaxy-locale', config.value.siteConfig.lang || 'en')
52
52
 
53
53
  // init i18n, by valaxy config
54
54
  const i18n = createI18n({
@@ -53,6 +53,7 @@ $light: map.merge(
53
53
  "c-bg": white,
54
54
  "c-bg-light": white,
55
55
  "c-bg-dark": #fafafa,
56
+ "c-bg-opacity": rgba(255, 255, 255, 0.8),
56
57
 
57
58
  "c-bg-soft": #f9f9f9,
58
59
  "c-bg-alt": #f9f9f9,
@@ -83,6 +84,7 @@ $dark: map.merge(
83
84
  "c-bg": #1a1a1a,
84
85
  "c-bg-light": #1d1e1f,
85
86
  "c-bg-dark": #1a1a1a,
87
+ "c-bg-opacity": rgba(0, 0, 0, 0.8),
86
88
 
87
89
  "c-bg-soft": #1d1e1f,
88
90
  "c-bg-mute": #2f2f2f,
@@ -1,5 +1,3 @@
1
- export const EXTERNAL_URL_RE = /^https?:/i
2
-
3
1
  /**
4
2
  * 生成介于 min 与 max 之间的随机数
5
3
  * @returns
@@ -1,5 +1,5 @@
1
1
  import dayjs from 'dayjs'
2
- import type { Post } from '../../types'
2
+ import type { Post } from '../..'
3
3
 
4
4
  /**
5
5
  * use dayjs format date