retypeset-odyssey 0.1.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.
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/astro.config.ts +18 -0
- package/default-config.yaml +136 -0
- package/discover-collections.ts +160 -0
- package/integration.ts +394 -0
- package/package.json +105 -0
- package/patches/@qwik.dev__partytown@0.11.2.patch +98 -0
- package/public/_redirects +819 -0
- package/public/feeds/atom-style.xsl +105 -0
- package/public/feeds/rss-style.xsl +105 -0
- package/public/fonts/EarlySummer-VF-Split/00785494587e3487ac63a0e7e4fa30f0.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/08e5d941a4c76fad7b68e7a937ebb21f.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/1268e5072156188d601f1eeb4473655d.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/12a385475353c815d7a5add53ee51e37.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/12b11ca08223c65a21fc731d59dcfc11.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/16d6676d3cb645c520ee6df8a1f89afd.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/2912a75ffef95e7a5ae9e2b2311ad61d.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/298d96ea561e419a4104bc9fc18499ce.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/2a2c71acc17ec39f6780835899e53096.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/2a7e2d0e59d3f638074c50fab39fdef1.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/36931fc4370e1670ed76af5d3feccba2.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/3a68fdc792e4a9e0399a04e32d0cc2e3.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/4054d6a4d6b37719b51e0f71da6e7cd9.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/429cb25f825c3cbde6bfac5b36ae9675.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/42a9efc11298368ecdc1b85ab46f0b4f.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/432018d2bdc9df92a7662056eb2b1261.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/44a6fb782f2a01560faa0f95248b60ef.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/45367b060e8ba0aa2507e6b91b86620b.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/571db7564bda7c1a93542881b8976f4b.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/58d55eeef4cf455e86a1142b1f3110d3.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/59ea41e77309160a0f63cdc76a010202.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/5d19d9174e568db4755981aa2e4ab380.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/5e811eb3b4175ee93d7ec000bf4631c2.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/6268e0cd5d66d6fe05b331f259e7b9e4.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/6549844aa3d833ca06a68a8e839db465.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/714b459658a7321ceeb1e1386ce165c2.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/7511d97a469915013683eae06cb21cd9.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/7784b4ebe543d13f62f6f6e05beb0b2e.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/77c9bea70b3c6ab24e1497d5468c825b.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/789ebea9e81df623e930b86de98fbfab.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/885bb7ab0717e8a47fc17f953adcdbf1.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/896c58aff69a9a857764cee0663bc56d.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/8fb6fc01c59d1e3ad1910b58dec7f5e7.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/95be5462b91b9a0458797cdc89d94cb5.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/9a5b2724f983ca0fc0d5ff8d10c41396.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/9ffe17f9c0e4cc4356cb3f08ffdb9c6d.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/EarlySummer-VF-Subset.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/EarlySummerSerif License.txt +91 -0
- package/public/fonts/EarlySummer-VF-Split/a097ef49be62cd2565aca45600e1e3ac.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/a17a1ae6063088e5b3a48c06b816929a.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/a83fdcfc5ecf2f6996704b0c02758689.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/a8cf15ff9b71e59407d8406866ff6f99.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/af530ed51dd519e4456f8a5e259e908b.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/b195a8924915deec4aa9c3ec777cc93f.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/b4b6bb5df9239dd67b52ca858fd2a506.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/b7592e1e027923f19e0e55dfdac69668.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/b965859f69d8ccceaf0e2d6292afbcfb.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/bbe9333f1ff242bd96ecb23ff9e723b1.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/be758580e295339ea98f0240b9869f24.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/c07099e1d025617f6d40966986e1941b.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/c1b593dda62fdeb7dde3af02016da282.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/c89f0335910a68a0958f2846108370e8.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/ca49aa409fdedd3f2f894cd20a16640a.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/ccd4a28d2f63797e0183c87792e20b75.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/d2718da923fce8e7ea229d65e306e92c.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/d893e9b307d96041e9cfcbd03761b9f4.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/dafaedaee41b75e21479d4ff324b6a34.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/db392af65f1867e5fd580eed2195df99.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/dc7c73a9e5577143ccd11e05ab55cb39.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/de396881189f747eba67685298363242.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/df625b213228bba22a7733d4eff8f148.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/e6e60b384f220b893ef31a926ece829a.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/e6e8ce2c5972ab665630bb705383d0fb.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/e963c7ed7104c2d6d68fcb5f952fe2f5.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/e966b23b4cd7783f43e31032d41784f4.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/edaac57c3856ec13128f4c6c3e00975c.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/ee54e0d86edf068c6c9cbddb76a856fe.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/f612c78a5544ff2dd3e8296ac3e58344.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/f9e539bd9b7bf999c3da82f5403ec3b6.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/fa5863b923ac15993c52a619f699ee63.woff2 +0 -0
- package/public/fonts/EarlySummer-VF-Split/fc759e56ec6f6e6d3d4cb163d62fb557.woff2 +0 -0
- package/public/fonts/Font Subset List/CJK Common Characters.txt +7534 -0
- package/public/fonts/Font Subset List/EarlySummer Subset.txt +3 -0
- package/public/fonts/Font Subset List/Japanese Kana + Korean Letters.txt +6123 -0
- package/public/fonts/Font Subset List/Latin + Cyrillic + Greek + Arabic Glyphs.txt +121 -0
- package/public/fonts/Font Subset List/unicode_range.py +49 -0
- package/public/fonts/NotoSansSC-Bold.otf +0 -0
- package/public/fonts/NotoSansSC-Regular.otf +0 -0
- package/public/fonts/STIX-Italic-VF.woff2 +0 -0
- package/public/fonts/STIX-VF.woff2 +0 -0
- package/public/fonts/Snell-Black-SF.woff2 +0 -0
- package/public/fonts/Snell-Bold-SF.woff2 +0 -0
- package/public/giscus/theme-dark.css +208 -0
- package/public/giscus/theme-light.css +208 -0
- package/public/icons/favicon.svg +4 -0
- package/public/icons/og-logo.png +0 -0
- package/public/robots.txt +4 -0
- package/public/sounds/tap_01.wav +0 -0
- package/public/sounds/tap_02.wav +0 -0
- package/public/sounds/tap_03.wav +0 -0
- package/public/sounds/tap_04.wav +0 -0
- package/public/sounds/tap_05.wav +0 -0
- package/public/sounds/type_01.wav +0 -0
- package/public/sounds/type_02.wav +0 -0
- package/public/sounds/type_03.wav +0 -0
- package/public/sounds/type_04.wav +0 -0
- package/public/sounds/type_05.wav +0 -0
- package/scripts/apply-lqip.ts +276 -0
- package/scripts/format-posts.ts +105 -0
- package/scripts/migration/README.md +52 -0
- package/scripts/migration/migrate-hexo.ts +185 -0
- package/scripts/migration/validate-abbrlinks.ts +161 -0
- package/scripts/new-post.ts +52 -0
- package/scripts/seo/generate-legacy-redirects.ts +407 -0
- package/scripts/update-theme.ts +46 -0
- package/src/assets/icons/copy-check.svg +3 -0
- package/src/assets/icons/copy-icon.svg +4 -0
- package/src/assets/icons/go-back.svg +3 -0
- package/src/assets/icons/heading-anchor.svg +4 -0
- package/src/assets/icons/lang-en.svg +3 -0
- package/src/assets/icons/lang-ja.svg +5 -0
- package/src/assets/icons/lang-zh.svg +5 -0
- package/src/assets/icons/language-switcher.svg +3 -0
- package/src/assets/icons/pin-icon.svg +3 -0
- package/src/assets/icons/search-icon.svg +3 -0
- package/src/assets/icons/theme-toggle.svg +3 -0
- package/src/assets/icons/toc-icon.svg +3 -0
- package/src/assets/icons/top-icon.svg +3 -0
- package/src/assets/lqip-map.json +10 -0
- package/src/components/Button.astro +152 -0
- package/src/components/CategoryList.astro +66 -0
- package/src/components/Comment/Giscus.astro +119 -0
- package/src/components/Comment/Index.astro +30 -0
- package/src/components/Comment/Twikoo.astro +114 -0
- package/src/components/Comment/Waline.astro +149 -0
- package/src/components/FloatingButtons.astro +101 -0
- package/src/components/Footer.astro +74 -0
- package/src/components/Header.astro +62 -0
- package/src/components/JournalList.astro +56 -0
- package/src/components/Navbar.astro +69 -0
- package/src/components/NoteList.astro +56 -0
- package/src/components/Pagination.astro +267 -0
- package/src/components/PostDate.astro +80 -0
- package/src/components/PostList.astro +87 -0
- package/src/components/SearchModal.astro +340 -0
- package/src/components/TagList.astro +135 -0
- package/src/components/Widgets/BackButton.astro +43 -0
- package/src/components/Widgets/CodeCopyButton.astro +47 -0
- package/src/components/Widgets/GithubCard.astro +110 -0
- package/src/components/Widgets/ImageZoom.astro +135 -0
- package/src/components/Widgets/MediaEmbed.astro +127 -0
- package/src/components/Widgets/SoundEffect.astro +179 -0
- package/src/components/Widgets/TOC.astro +198 -0
- package/src/config-schema.ts +164 -0
- package/src/config.ts +127 -0
- package/src/config.ts.example +205 -0
- package/src/content/about/_example-about-en.md +6 -0
- package/src/content/about/about-en.md +21 -0
- package/src/content/about/about-ja.md +21 -0
- package/src/content/about/about-zh.md +24 -0
- package/src/content.config.ts +247 -0
- package/src/env.d.ts +25 -0
- package/src/i18n/config.ts +65 -0
- package/src/i18n/lang.ts +70 -0
- package/src/i18n/path.ts +160 -0
- package/src/i18n/ui.ts +214 -0
- package/src/layouts/Head.astro +203 -0
- package/src/layouts/Layout.astro +69 -0
- package/src/pages/404.astro +20 -0
- package/src/pages/[...lang]/[...page].astro +48 -0
- package/src/pages/[...lang]/about.astro +28 -0
- package/src/pages/[...lang]/atom.xml.ts +14 -0
- package/src/pages/[...lang]/categories/index.astro +35 -0
- package/src/pages/[...lang]/journals/[slug].astro +89 -0
- package/src/pages/[...lang]/journals/index.astro +55 -0
- package/src/pages/[...lang]/journals/page/[page].astro +66 -0
- package/src/pages/[...lang]/notes/[slug].astro +88 -0
- package/src/pages/[...lang]/notes/index.astro +55 -0
- package/src/pages/[...lang]/notes/page/[page].astro +66 -0
- package/src/pages/[...lang]/posts/[slug].astro +101 -0
- package/src/pages/[...lang]/rss.xml.ts +14 -0
- package/src/pages/[...lang]/search.astro +65 -0
- package/src/pages/[...lang]/tags/[tag].astro +53 -0
- package/src/pages/[...lang]/tags/index.astro +36 -0
- package/src/pages/_dynamic/list.astro +101 -0
- package/src/pages/_dynamic/slug.astro +100 -0
- package/src/pages/og/[...image].ts +114 -0
- package/src/pages/robots.txt.ts +20 -0
- package/src/plugins/rehype-code-copy-button.mjs +82 -0
- package/src/plugins/rehype-external-links.mjs +18 -0
- package/src/plugins/rehype-heading-anchor.mjs +55 -0
- package/src/plugins/rehype-image-processor.mjs +77 -0
- package/src/plugins/remark-container-directives.mjs +135 -0
- package/src/plugins/remark-leaf-directives.mjs +184 -0
- package/src/plugins/remark-reading-time.mjs +11 -0
- package/src/styles/comment.css +205 -0
- package/src/styles/extension.css +180 -0
- package/src/styles/font.css +111 -0
- package/src/styles/global.css +91 -0
- package/src/styles/lqip.css +71 -0
- package/src/styles/markdown.css +276 -0
- package/src/styles/transition.css +173 -0
- package/src/types/global.d.ts +22 -0
- package/src/types/index.d.ts +111 -0
- package/src/utils/cache.ts +32 -0
- package/src/utils/content.ts +819 -0
- package/src/utils/description.ts +147 -0
- package/src/utils/dynamic-collections.ts +155 -0
- package/src/utils/feed.ts +238 -0
- package/src/utils/page.ts +107 -0
- package/tsconfig.json +13 -0
- package/uno.config.ts +75 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type { ThemeConfig } from '@/types'
|
|
2
|
+
|
|
3
|
+
export const themeConfig: ThemeConfig = {
|
|
4
|
+
// SITE INFORMATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
|
|
5
|
+
site: {
|
|
6
|
+
// site title
|
|
7
|
+
title: 'Your Blog Title',
|
|
8
|
+
// site subtitle
|
|
9
|
+
subtitle: 'Your Blog Subtitle',
|
|
10
|
+
// site description
|
|
11
|
+
description: 'A personal blog about...',
|
|
12
|
+
// use i18n title/subtitle/description from src/i18n/ui.ts instead of static ones above
|
|
13
|
+
i18nTitle: true, // true | false
|
|
14
|
+
// author name
|
|
15
|
+
author: 'Your Name',
|
|
16
|
+
// site url
|
|
17
|
+
url: 'https://yourdomain.com',
|
|
18
|
+
// base path
|
|
19
|
+
// root directory for all pages and assets
|
|
20
|
+
base: '/', // e.g., '/blog', '/docs'
|
|
21
|
+
// favicon url
|
|
22
|
+
// recommended formats: svg, png or ico
|
|
23
|
+
favicon: '/icons/favicon.svg', // or https://example.com/favicon.svg
|
|
24
|
+
},
|
|
25
|
+
// SITE INFORMATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
|
26
|
+
|
|
27
|
+
// COLOR SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
|
|
28
|
+
color: {
|
|
29
|
+
// default theme mode
|
|
30
|
+
mode: 'light', // light | dark | auto
|
|
31
|
+
light: {
|
|
32
|
+
// primary color
|
|
33
|
+
// used for title, hover, etc
|
|
34
|
+
// oklch color picker: https://oklch.com/
|
|
35
|
+
primary: 'oklch(25% 0.005 298)',
|
|
36
|
+
// secondary color
|
|
37
|
+
// used for post text
|
|
38
|
+
secondary: 'oklch(40% 0.005 298)',
|
|
39
|
+
// background color
|
|
40
|
+
background: 'oklch(96% 0.005 298)',
|
|
41
|
+
// highlight color
|
|
42
|
+
// used for navbar, selected text, etc
|
|
43
|
+
highlight: 'oklch(0.93 0.195089 103.2532 / 0.5)', // rgba(255,235,0,0.5)
|
|
44
|
+
},
|
|
45
|
+
dark: {
|
|
46
|
+
// primary color
|
|
47
|
+
primary: 'oklch(92% 0.005 298)',
|
|
48
|
+
// secondary color
|
|
49
|
+
secondary: 'oklch(77% 0.005 298)',
|
|
50
|
+
// background color
|
|
51
|
+
background: 'oklch(22% 0.005 298)',
|
|
52
|
+
// highlight color
|
|
53
|
+
highlight: 'oklch(0.93 0.195089 103.2532 / 0.2)', // rgba(255,235,0,0.2)
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
// COLOR SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
|
57
|
+
|
|
58
|
+
// GLOBAL SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
|
|
59
|
+
global: {
|
|
60
|
+
// default language
|
|
61
|
+
locale: 'zh', // de | en | es | fr | ja | ko | pl | pt | ru | zh | zh-tw
|
|
62
|
+
// more languages
|
|
63
|
+
// not fill in the locale code above again, can be an empty array []
|
|
64
|
+
moreLocales: ['en', 'ja'], // Only zh (default), en, ja
|
|
65
|
+
// post font style
|
|
66
|
+
fontStyle: 'sans', // sans | serif
|
|
67
|
+
// post date format
|
|
68
|
+
dateFormat: 'YYYY-MM-DD', // YYYY-MM-DD | MM-DD-YYYY | DD-MM-YYYY | MMM D YYYY | D MMM YYYY
|
|
69
|
+
// enable table of contents
|
|
70
|
+
toc: true, // true | false
|
|
71
|
+
// enable katex math rendering
|
|
72
|
+
katex: true, // true | false
|
|
73
|
+
// reduce motion
|
|
74
|
+
reduceMotion: false, // true | false
|
|
75
|
+
},
|
|
76
|
+
// GLOBAL SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
|
77
|
+
|
|
78
|
+
// COMMENT SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
|
|
79
|
+
comment: {
|
|
80
|
+
// enable comment system
|
|
81
|
+
enabled: false, // Disabled for now
|
|
82
|
+
// giscus
|
|
83
|
+
// https://giscus.app/
|
|
84
|
+
giscus: {
|
|
85
|
+
repo: '',
|
|
86
|
+
repoId: '',
|
|
87
|
+
category: '',
|
|
88
|
+
categoryId: '',
|
|
89
|
+
mapping: 'pathname',
|
|
90
|
+
strict: '0',
|
|
91
|
+
reactionsEnabled: '1',
|
|
92
|
+
emitMetadata: '0',
|
|
93
|
+
inputPosition: 'bottom',
|
|
94
|
+
},
|
|
95
|
+
// twikoo
|
|
96
|
+
// https://twikoo.js.org/
|
|
97
|
+
twikoo: {
|
|
98
|
+
envId: '',
|
|
99
|
+
// version: frontend version can be changed in package.json
|
|
100
|
+
},
|
|
101
|
+
// waline
|
|
102
|
+
// https://waline.js.org/en/
|
|
103
|
+
waline: {
|
|
104
|
+
// server url
|
|
105
|
+
serverURL: 'https://retypeset-comment.radishzz.cc',
|
|
106
|
+
// emoji url
|
|
107
|
+
emoji: [
|
|
108
|
+
'https://unpkg.com/@waline/emojis@1.2.0/tw-emoji',
|
|
109
|
+
// 'https://unpkg.com/@waline/emojis@1.2.0/bmoji',
|
|
110
|
+
// more emojis: https://waline.js.org/en/guide/features/emoji.html
|
|
111
|
+
],
|
|
112
|
+
// gif search
|
|
113
|
+
search: false, // true | false
|
|
114
|
+
// image uploader
|
|
115
|
+
imageUploader: false, // true | false
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
// COMMENT SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
|
119
|
+
|
|
120
|
+
// SEO SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
|
|
121
|
+
seo: {
|
|
122
|
+
// @twitter ID
|
|
123
|
+
twitterID: '',
|
|
124
|
+
// site verification
|
|
125
|
+
verification: {
|
|
126
|
+
// google search console
|
|
127
|
+
// https://search.google.com/search-console
|
|
128
|
+
google: '',
|
|
129
|
+
// bing webmaster tools
|
|
130
|
+
// https://www.bing.com/webmasters
|
|
131
|
+
bing: '',
|
|
132
|
+
// yandex webmaster
|
|
133
|
+
// https://webmaster.yandex.com
|
|
134
|
+
yandex: '',
|
|
135
|
+
// baidu search
|
|
136
|
+
// https://ziyuan.baidu.com
|
|
137
|
+
baidu: '',
|
|
138
|
+
},
|
|
139
|
+
// google analytics — GA4 measurement ID (format: G-XXXXXXXXXX)
|
|
140
|
+
// NOT the old UA-XXXXXXXX-X format (deprecated July 2023)
|
|
141
|
+
// Get yours at: https://analytics.google.com → Admin → Data Streams → Measurement ID
|
|
142
|
+
googleAnalyticsID: '',
|
|
143
|
+
// umami analytics
|
|
144
|
+
// https://cloud.umami.is
|
|
145
|
+
umamiAnalyticsID: '',
|
|
146
|
+
// follow verification
|
|
147
|
+
// https://follow.is/
|
|
148
|
+
follow: {
|
|
149
|
+
// feed ID
|
|
150
|
+
feedID: '',
|
|
151
|
+
// user ID
|
|
152
|
+
userID: '',
|
|
153
|
+
},
|
|
154
|
+
// apiflash access key
|
|
155
|
+
// generate website screenshots for open graph images
|
|
156
|
+
// get your access key at: https://apiflash.com/
|
|
157
|
+
apiflashKey: '',
|
|
158
|
+
},
|
|
159
|
+
// SEO SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
|
160
|
+
|
|
161
|
+
// FOOTER SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
|
|
162
|
+
footer: {
|
|
163
|
+
// social links
|
|
164
|
+
links: [
|
|
165
|
+
{
|
|
166
|
+
name: 'RSS',
|
|
167
|
+
url: '/atom.xml', // or /rss.xml
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: 'GitHub',
|
|
171
|
+
url: 'https://github.com/yourusername',
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
// year of website start
|
|
175
|
+
startYear: 2024,
|
|
176
|
+
},
|
|
177
|
+
// FOOTER SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
|
178
|
+
|
|
179
|
+
// PRELOAD SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
|
|
180
|
+
preload: {
|
|
181
|
+
// image hosting url
|
|
182
|
+
// optimize remote images and generate low-quality placeholders
|
|
183
|
+
imageHostURL: '',
|
|
184
|
+
// custom google analytics js
|
|
185
|
+
// for users who proxy tracking scripts to a custom domain
|
|
186
|
+
// see https://gist.github.com/xiaopc/0602f06ca465d76bd9efd3dda9393738
|
|
187
|
+
customGoogleAnalyticsJS: '',
|
|
188
|
+
// custom umami analytics js
|
|
189
|
+
// for users who self-deploy umami or proxy tracking scripts to a custom domain
|
|
190
|
+
// see https://umami.is/docs/bypass-ad-blockers
|
|
191
|
+
customUmamiAnalyticsJS: '',
|
|
192
|
+
},
|
|
193
|
+
// PRELOAD SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export const base = themeConfig.site.base === '/' ? '' : themeConfig.site.base.replace(/\/$/, '')
|
|
197
|
+
export const defaultLocale = themeConfig.global.locale
|
|
198
|
+
export const moreLocales = themeConfig.global.moreLocales
|
|
199
|
+
export const allLocales = [defaultLocale, ...moreLocales]
|
|
200
|
+
|
|
201
|
+
// Pagination
|
|
202
|
+
// Used by posts/notes/journals list pages.
|
|
203
|
+
export const POSTS_PER_PAGE = 7
|
|
204
|
+
export const NOTES_PER_PAGE = 7
|
|
205
|
+
export const JOURNALS_PER_PAGE = 7
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
lang: en
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# About Me
|
|
6
|
+
|
|
7
|
+
Thank you for visiting my blog.
|
|
8
|
+
|
|
9
|
+
I'm working as a software engineer.
|
|
10
|
+
|
|
11
|
+
Please feel free to contact me: zhenjiazhou0127@outlook.com
|
|
12
|
+
|
|
13
|
+
# Privacy & Analytics
|
|
14
|
+
|
|
15
|
+
I use Google Analytics to better understand my visitors. The data collection is based on Google's standard practices. Thank you for your understanding.
|
|
16
|
+
|
|
17
|
+
I'm very happy to receive any type of message. Please feel free to reach out.
|
|
18
|
+
|
|
19
|
+
# The End
|
|
20
|
+
|
|
21
|
+
Sometimes, this ocean of starlight seems to have reached the edge of darkness; I thought beyond it lay only endless void. Yet, with just a glance upward, there are still stars everywhere.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
lang: ja
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# 私について
|
|
6
|
+
|
|
7
|
+
ブログをご覧いただきありがとうございます。
|
|
8
|
+
|
|
9
|
+
私はSoftware Engineerで働いています。
|
|
10
|
+
|
|
11
|
+
お気軽にご連絡ください:zhenjiazhou0127@outlook.com
|
|
12
|
+
|
|
13
|
+
# プライバシーと分析
|
|
14
|
+
|
|
15
|
+
訪問者をより理解するために、Google Analyticsを使用しています。データ収集はGoogleの標準的な方法に基づいています。ご理解いただきありがとうございます。
|
|
16
|
+
|
|
17
|
+
どんなメッセージでも大歓迎です。
|
|
18
|
+
|
|
19
|
+
# 終わりに
|
|
20
|
+
|
|
21
|
+
時々、この星の海は闇の果てに達したように見える。その先には無限の暗黒しかないと思っていた。しかし、ふと見上げれば、そこにはまだ星々が輝いている。
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
lang: zh
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# 关于我
|
|
6
|
+
|
|
7
|
+
欢迎你来我的博客,希望我写的东西能够帮到你。
|
|
8
|
+
|
|
9
|
+
我目前是一名软件开发人员。
|
|
10
|
+
|
|
11
|
+
如果有任何问题,或者想和我交流的话,欢迎联系我的邮件:zhenjiazhou0127@outlook.com
|
|
12
|
+
|
|
13
|
+
# 隐私统计与使用
|
|
14
|
+
|
|
15
|
+
我在博客里加入了谷歌的统计,会根据浏览器标识搜集一部分访客信息。
|
|
16
|
+
|
|
17
|
+
我很开心收到任何信息,请随意联系我。
|
|
18
|
+
|
|
19
|
+
# 结语
|
|
20
|
+
|
|
21
|
+
有时候,这星光的海洋似乎已经达到了黑暗的边缘;我满以为,在此之外,已是无边无际的大黑暗了。然而,只要一转瞬,再往上一看,依然是一片星光。
|
|
22
|
+
|
|
23
|
+
我志在寥阔,畴昔梦登天。摩挲素月,人世俯仰已千年。有客骖鸾并凤,云遇青山赤壁,相约上高寒。酌酒援北斗,我亦虱其间。
|
|
24
|
+
少歌曰:神甚放,形如眠。鸿鹄一再高举,天地睹方圆。欲重歌兮梦觉,推枕惘然独念,人事底亏全?有美人可语,秋水隔婵娟。
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { glob } from 'astro/loaders'
|
|
2
|
+
import { defineCollection } from 'astro:content'
|
|
3
|
+
import { z } from 'astro/zod'
|
|
4
|
+
import { discoverCollections } from '../discover-collections'
|
|
5
|
+
import { allLocales, themeConfig } from '@/config'
|
|
6
|
+
|
|
7
|
+
const posts = defineCollection({
|
|
8
|
+
loader: glob({
|
|
9
|
+
pattern: '**/*.{md,mdx}',
|
|
10
|
+
base: './content/posts',
|
|
11
|
+
// Keep multi-dot filenames (e.g. `foo.en.md`) distinct in Astro Content Layer.
|
|
12
|
+
// Otherwise, `foo.md` and `foo.en.md` may collide and overwrite each other.
|
|
13
|
+
generateId: ({ entry }) => entry.replace(/\.(md|mdx)$/, ''),
|
|
14
|
+
}),
|
|
15
|
+
schema: z.object({
|
|
16
|
+
// Title - optional with fallback to empty (posts without title become drafts)
|
|
17
|
+
title: z.string().optional().default(''),
|
|
18
|
+
// Support both Hexo 'date' and Retypeset 'published' fields
|
|
19
|
+
published: z.coerce.date().optional(),
|
|
20
|
+
date: z.coerce.date().optional(),
|
|
21
|
+
// optional
|
|
22
|
+
description: z.string().optional().default(''),
|
|
23
|
+
updated: z.preprocess(
|
|
24
|
+
val => val === '' ? undefined : val,
|
|
25
|
+
z.coerce.date().optional(),
|
|
26
|
+
),
|
|
27
|
+
tags: z.preprocess(
|
|
28
|
+
val => val === null ? [] : val,
|
|
29
|
+
z.union([
|
|
30
|
+
z.array(z.string()),
|
|
31
|
+
z.string().transform(s => s ? [s] : []),
|
|
32
|
+
]).optional().default([]),
|
|
33
|
+
),
|
|
34
|
+
// Hexo categories (convert to tags or keep separate)
|
|
35
|
+
categories: z.preprocess(
|
|
36
|
+
val => val === null ? [] : val,
|
|
37
|
+
z.union([
|
|
38
|
+
z.array(z.string()),
|
|
39
|
+
z.string().transform(s => s ? [s] : []),
|
|
40
|
+
]).optional().default([]),
|
|
41
|
+
),
|
|
42
|
+
// Advanced (handle null values)
|
|
43
|
+
draft: z.preprocess(val => val === null ? false : val, z.boolean().optional().default(false)),
|
|
44
|
+
pin: z.preprocess(val => val === null ? 0 : val, z.number().int().min(0).max(99).optional().default(0)),
|
|
45
|
+
toc: z.preprocess(val => val === null ? undefined : val, z.boolean().optional().default(themeConfig.global.toc)),
|
|
46
|
+
lang: z.preprocess(val => val === null ? '' : val, z.enum(['', ...allLocales]).optional().default('')),
|
|
47
|
+
// Hexo abbrlink - supports hex format like '17683e80' (handle null from YAML)
|
|
48
|
+
abbrlink: z.preprocess(
|
|
49
|
+
val => val === null ? '' : val,
|
|
50
|
+
z.string().optional().default('').refine(
|
|
51
|
+
abbrlink => !abbrlink || /^[a-zA-Z0-9\-]*$/.test(abbrlink),
|
|
52
|
+
{ message: 'Abbrlink can only contain letters, numbers and hyphens' },
|
|
53
|
+
),
|
|
54
|
+
),
|
|
55
|
+
// Semantic URL slug - takes priority over abbrlink
|
|
56
|
+
slug: z.preprocess(
|
|
57
|
+
val => val === null ? '' : val,
|
|
58
|
+
z.string().optional().default('').refine(
|
|
59
|
+
slug => !slug || /^[a-zA-Z0-9\-]+$/.test(slug),
|
|
60
|
+
{ message: 'Slug can only contain letters, numbers and hyphens' },
|
|
61
|
+
),
|
|
62
|
+
),
|
|
63
|
+
// Hexo-specific optional fields (handle null values from YAML)
|
|
64
|
+
mathjax: z.preprocess(
|
|
65
|
+
val => val === null ? undefined : val,
|
|
66
|
+
z.boolean().optional().default(false),
|
|
67
|
+
),
|
|
68
|
+
password: z.preprocess(
|
|
69
|
+
val => val === null ? undefined : val,
|
|
70
|
+
z.string().optional(),
|
|
71
|
+
),
|
|
72
|
+
copyright: z.preprocess(
|
|
73
|
+
val => val === null ? undefined : val,
|
|
74
|
+
z.boolean().optional().default(true),
|
|
75
|
+
),
|
|
76
|
+
// Allow passthrough of unknown Hexo fields
|
|
77
|
+
}).passthrough().transform((data) => {
|
|
78
|
+
// Map Hexo 'date' to 'published' if 'published' is not set
|
|
79
|
+
const published = data.published || data.date || new Date();
|
|
80
|
+
// Mark posts without title as draft
|
|
81
|
+
const draft = data.draft || !data.title;
|
|
82
|
+
return { ...data, published, draft };
|
|
83
|
+
}),
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
const notes = defineCollection({
|
|
87
|
+
loader: glob({
|
|
88
|
+
pattern: '**/*.{md,mdx}',
|
|
89
|
+
base: './content/notes',
|
|
90
|
+
// Keep multi-dot filenames (e.g. `foo.en.md`) distinct in Astro Content Layer.
|
|
91
|
+
// Otherwise, `foo.md` and `foo.en.md` may collide and overwrite each other.
|
|
92
|
+
generateId: ({ entry }) => entry.replace(/\.(md|mdx)$/, ''),
|
|
93
|
+
}),
|
|
94
|
+
schema: z.object({
|
|
95
|
+
// Title - optional with fallback to empty (notes without title become drafts)
|
|
96
|
+
title: z.string().optional().default(''),
|
|
97
|
+
// Support both Hexo 'date' and Retypeset 'published' fields
|
|
98
|
+
published: z.coerce.date().optional(),
|
|
99
|
+
date: z.coerce.date().optional(),
|
|
100
|
+
// optional
|
|
101
|
+
description: z.string().optional().default(''),
|
|
102
|
+
updated: z.preprocess(
|
|
103
|
+
val => val === '' ? undefined : val,
|
|
104
|
+
z.coerce.date().optional(),
|
|
105
|
+
),
|
|
106
|
+
tags: z.preprocess(
|
|
107
|
+
val => val === null ? [] : val,
|
|
108
|
+
z.union([
|
|
109
|
+
z.array(z.string()),
|
|
110
|
+
z.string().transform(s => s ? [s] : []),
|
|
111
|
+
]).optional().default([]),
|
|
112
|
+
),
|
|
113
|
+
// Hexo categories (convert to tags or keep separate)
|
|
114
|
+
categories: z.preprocess(
|
|
115
|
+
val => val === null ? [] : val,
|
|
116
|
+
z.union([
|
|
117
|
+
z.array(z.string()),
|
|
118
|
+
z.string().transform(s => s ? [s] : []),
|
|
119
|
+
]).optional().default([]),
|
|
120
|
+
),
|
|
121
|
+
// Advanced (handle null values)
|
|
122
|
+
draft: z.preprocess(val => val === null ? false : val, z.boolean().optional().default(false)),
|
|
123
|
+
pin: z.preprocess(val => val === null ? 0 : val, z.number().int().min(0).max(99).optional().default(0)),
|
|
124
|
+
toc: z.preprocess(val => val === null ? undefined : val, z.boolean().optional().default(themeConfig.global.toc)),
|
|
125
|
+
lang: z.preprocess(val => val === null ? '' : val, z.enum(['', ...allLocales]).optional().default('')),
|
|
126
|
+
// Semantic URL slug
|
|
127
|
+
slug: z.preprocess(
|
|
128
|
+
val => val === null ? '' : val,
|
|
129
|
+
z.string().optional().default('').refine(
|
|
130
|
+
slug => !slug || /^[a-zA-Z0-9\\-]+$/.test(slug),
|
|
131
|
+
{ message: 'Slug can only contain letters, numbers and hyphens' },
|
|
132
|
+
),
|
|
133
|
+
),
|
|
134
|
+
// Allow passthrough of unknown fields
|
|
135
|
+
}).passthrough().transform((data) => {
|
|
136
|
+
const published = data.published || data.date || new Date()
|
|
137
|
+
const draft = data.draft || !data.title
|
|
138
|
+
return { ...data, published, draft }
|
|
139
|
+
}),
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const journals = defineCollection({
|
|
143
|
+
loader: glob({
|
|
144
|
+
pattern: '**/*.{md,mdx}',
|
|
145
|
+
base: './content/journals',
|
|
146
|
+
// Keep multi-dot filenames (e.g. `foo.en.md`) distinct in Astro Content Layer.
|
|
147
|
+
// Otherwise, `foo.md` and `foo.en.md` may collide and overwrite each other.
|
|
148
|
+
generateId: ({ entry }) => entry.replace(/\.(md|mdx)$/, ''),
|
|
149
|
+
}),
|
|
150
|
+
schema: z.object({
|
|
151
|
+
// Title - optional with fallback to empty (journals without title become drafts)
|
|
152
|
+
title: z.string().optional().default(''),
|
|
153
|
+
// Support both Hexo 'date' and Retypeset 'published' fields
|
|
154
|
+
published: z.coerce.date().optional(),
|
|
155
|
+
date: z.coerce.date().optional(),
|
|
156
|
+
// optional
|
|
157
|
+
description: z.string().optional().default(''),
|
|
158
|
+
updated: z.preprocess(
|
|
159
|
+
val => val === '' ? undefined : val,
|
|
160
|
+
z.coerce.date().optional(),
|
|
161
|
+
),
|
|
162
|
+
tags: z.preprocess(
|
|
163
|
+
val => val === null ? [] : val,
|
|
164
|
+
z.union([
|
|
165
|
+
z.array(z.string()),
|
|
166
|
+
z.string().transform(s => s ? [s] : []),
|
|
167
|
+
]).optional().default([]),
|
|
168
|
+
),
|
|
169
|
+
// Hexo categories (convert to tags or keep separate)
|
|
170
|
+
categories: z.preprocess(
|
|
171
|
+
val => val === null ? [] : val,
|
|
172
|
+
z.union([
|
|
173
|
+
z.array(z.string()),
|
|
174
|
+
z.string().transform(s => s ? [s] : []),
|
|
175
|
+
]).optional().default([]),
|
|
176
|
+
),
|
|
177
|
+
// Advanced (handle null values)
|
|
178
|
+
draft: z.preprocess(val => val === null ? false : val, z.boolean().optional().default(false)),
|
|
179
|
+
pin: z.preprocess(val => val === null ? 0 : val, z.number().int().min(0).max(99).optional().default(0)),
|
|
180
|
+
toc: z.preprocess(val => val === null ? undefined : val, z.boolean().optional().default(themeConfig.global.toc)),
|
|
181
|
+
lang: z.preprocess(val => val === null ? '' : val, z.enum(['', ...allLocales]).optional().default('')),
|
|
182
|
+
// Semantic URL slug
|
|
183
|
+
slug: z.preprocess(
|
|
184
|
+
val => val === null ? '' : val,
|
|
185
|
+
z.string().optional().default('').refine(
|
|
186
|
+
slug => !slug || /^[a-zA-Z0-9\\-]+$/.test(slug),
|
|
187
|
+
{ message: 'Slug can only contain letters, numbers and hyphens' },
|
|
188
|
+
),
|
|
189
|
+
),
|
|
190
|
+
// Hexo-specific optional fields (handle null values from YAML)
|
|
191
|
+
mathjax: z.preprocess(
|
|
192
|
+
val => val === null ? undefined : val,
|
|
193
|
+
z.boolean().optional().default(false),
|
|
194
|
+
),
|
|
195
|
+
password: z.preprocess(
|
|
196
|
+
val => val === null ? undefined : val,
|
|
197
|
+
z.string().optional(),
|
|
198
|
+
),
|
|
199
|
+
copyright: z.preprocess(
|
|
200
|
+
val => val === null ? undefined : val,
|
|
201
|
+
z.boolean().optional().default(true),
|
|
202
|
+
),
|
|
203
|
+
// Allow passthrough of unknown fields
|
|
204
|
+
}).passthrough().transform((data) => {
|
|
205
|
+
const published = data.published || data.date || new Date()
|
|
206
|
+
const draft = data.draft || !data.title
|
|
207
|
+
return { ...data, published, draft }
|
|
208
|
+
}),
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
const about = defineCollection({
|
|
212
|
+
loader: glob({ pattern: '**/*.{md,mdx}', base: './content/about' }),
|
|
213
|
+
schema: z.object({
|
|
214
|
+
lang: z.enum(['', ...allLocales]).optional().default(''),
|
|
215
|
+
}),
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
// --- Dynamic collections -----------------------------------------------------
|
|
219
|
+
//
|
|
220
|
+
// Auto-register a collection for every top-level folder under `content/` that
|
|
221
|
+
// isn't a built-in (posts/notes/journals/_drafts/etc). Each one reuses the
|
|
222
|
+
// `posts` collection schema, so any frontmatter that works in `posts/` also
|
|
223
|
+
// works in a dynamic folder. See `discover-collections.ts` for the scan rules.
|
|
224
|
+
|
|
225
|
+
const postSchema = (posts as any).schema
|
|
226
|
+
|
|
227
|
+
const { dynamicFolders } = discoverCollections(process.cwd())
|
|
228
|
+
|
|
229
|
+
const dynamicCollections: Record<string, ReturnType<typeof defineCollection>> = {}
|
|
230
|
+
for (const folder of dynamicFolders) {
|
|
231
|
+
dynamicCollections[folder] = defineCollection({
|
|
232
|
+
loader: glob({
|
|
233
|
+
pattern: '**/*.{md,mdx}',
|
|
234
|
+
base: `./content/${folder}`,
|
|
235
|
+
generateId: ({ entry }) => entry.replace(/\.(md|mdx)$/, ''),
|
|
236
|
+
}),
|
|
237
|
+
schema: postSchema,
|
|
238
|
+
})
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export const collections = {
|
|
242
|
+
posts,
|
|
243
|
+
notes,
|
|
244
|
+
journals,
|
|
245
|
+
about,
|
|
246
|
+
...dynamicCollections,
|
|
247
|
+
}
|
package/src/env.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// <reference types="astro/client" />
|
|
2
|
+
/// <reference path="../.astro/types.d.ts" />
|
|
3
|
+
|
|
4
|
+
// Pagefind UI type declaration
|
|
5
|
+
interface PagefindUIOptions {
|
|
6
|
+
element: string
|
|
7
|
+
showImages?: boolean
|
|
8
|
+
showSubResults?: boolean
|
|
9
|
+
showEmptyFilters?: boolean
|
|
10
|
+
resetStyles?: boolean
|
|
11
|
+
bundlePath?: string
|
|
12
|
+
debounceTimeoutMs?: number
|
|
13
|
+
mergeIndex?: Array<{ bundlePath: string }>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface PagefindUIConstructor {
|
|
17
|
+
new (options: PagefindUIOptions): PagefindUIInstance
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface PagefindUIInstance {
|
|
21
|
+
triggerSearch(term: string): void
|
|
22
|
+
destroy(): void
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare const PagefindUI: PagefindUIConstructor
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Global Language Map
|
|
2
|
+
export const langMap = {
|
|
3
|
+
'de': ['de-DE'],
|
|
4
|
+
'en': ['en-US'],
|
|
5
|
+
'es': ['es-ES'],
|
|
6
|
+
'fr': ['fr-FR'],
|
|
7
|
+
'ja': ['ja-JP'],
|
|
8
|
+
'ko': ['ko-KR'],
|
|
9
|
+
'pl': ['pl-PL'],
|
|
10
|
+
'pt': ['pt-BR'],
|
|
11
|
+
'ru': ['ru-RU'],
|
|
12
|
+
'zh': ['zh-CN'],
|
|
13
|
+
'zh-tw': ['zh-TW'],
|
|
14
|
+
} as const
|
|
15
|
+
|
|
16
|
+
// Supported Languages
|
|
17
|
+
export type Language = keyof typeof langMap
|
|
18
|
+
|
|
19
|
+
// Giscus Language Map
|
|
20
|
+
// https://giscus.app/
|
|
21
|
+
export const giscusLocaleMap: Record<Language, string> = {
|
|
22
|
+
'de': 'de',
|
|
23
|
+
'en': 'en',
|
|
24
|
+
'es': 'es',
|
|
25
|
+
'fr': 'fr',
|
|
26
|
+
'ja': 'ja',
|
|
27
|
+
'ko': 'ko',
|
|
28
|
+
'pl': 'pl',
|
|
29
|
+
'pt': 'pt',
|
|
30
|
+
'ru': 'ru',
|
|
31
|
+
'zh': 'zh-CN',
|
|
32
|
+
'zh-tw': 'zh-TW',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Twikoo Language Map
|
|
36
|
+
// https://github.com/twikoojs/twikoo/blob/main/src/client/utils/i18n/index.js
|
|
37
|
+
export const twikooLocaleMap: Record<Language, string> = {
|
|
38
|
+
'de': 'en', // fallback to English
|
|
39
|
+
'en': 'en',
|
|
40
|
+
'es': 'en', // fallback to English
|
|
41
|
+
'fr': 'en', // fallback to English
|
|
42
|
+
'ja': 'ja',
|
|
43
|
+
'ko': 'ko',
|
|
44
|
+
'pl': 'en', // fallback to English
|
|
45
|
+
'pt': 'en', // fallback to English
|
|
46
|
+
'ru': 'en', // fallback to English
|
|
47
|
+
'zh': 'zh-cn',
|
|
48
|
+
'zh-tw': 'zh-tw',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Waline Language Map
|
|
52
|
+
// https://waline.js.org/en/guide/features/i18n.html
|
|
53
|
+
export const walineLocaleMap: Record<Language, string> = {
|
|
54
|
+
'de': 'en-US', // fallback to English
|
|
55
|
+
'en': 'en-US',
|
|
56
|
+
'es': 'es',
|
|
57
|
+
'fr': 'fr-FR',
|
|
58
|
+
'ja': 'jp-JP',
|
|
59
|
+
'ko': 'en-US', // fallback to English
|
|
60
|
+
'pl': 'en-US', // fallback to English
|
|
61
|
+
'pt': 'pt-BR',
|
|
62
|
+
'ru': 'ru-RU',
|
|
63
|
+
'zh': 'zh-CN',
|
|
64
|
+
'zh-tw': 'zh-TW',
|
|
65
|
+
}
|