nnbb 0.0.1

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 (218) hide show
  1. package/.dockerignore +1 -0
  2. package/.env.local +2 -0
  3. package/.eslintrc.json +15 -0
  4. package/.github/stale.yml +16 -0
  5. package/.github/workflows/codeql-analysis.yml +73 -0
  6. package/.github/workflows/docker-ghcr.yaml +59 -0
  7. package/.prettierrc +9 -0
  8. package/.vscode/launch.json +28 -0
  9. package/.vscode/settings.json +6 -0
  10. package/Dockerfile +38 -0
  11. package/LICENSE +21 -0
  12. package/README.md +16 -0
  13. package/blog.config.js +454 -0
  14. package/components/Ackee.js +83 -0
  15. package/components/AdBlockDetect.js +40 -0
  16. package/components/AlgoliaSearchModal.js +250 -0
  17. package/components/Artalk.js +30 -0
  18. package/components/Busuanzi.js +26 -0
  19. package/components/ChatBase.js +19 -0
  20. package/components/Collapse.tsx +134 -0
  21. package/components/Comment.js +161 -0
  22. package/components/CommonHead.tsx +101 -0
  23. package/components/CommonScript.js +125 -0
  24. package/components/CusdisComponent.js +35 -0
  25. package/components/CustomContextMenu.js +221 -0
  26. package/components/DebugPanel.js +134 -0
  27. package/components/DisableCopy.js +21 -0
  28. package/components/Draggable.js +167 -0
  29. package/components/Equation.js +31 -0
  30. package/components/ExternalPlugins.js +75 -0
  31. package/components/ExternalScript.js +29 -0
  32. package/components/FacebookMessenger.js +255 -0
  33. package/components/FacebookPage.js +34 -0
  34. package/components/Fireworks.js +210 -0
  35. package/components/FlipCard.js +56 -0
  36. package/components/FlutteringRibbon.js +322 -0
  37. package/components/FullScreenButton.js +48 -0
  38. package/components/Giscus.js +33 -0
  39. package/components/Gitalk.js +42 -0
  40. package/components/GoogleAdsense.js +111 -0
  41. package/components/Gtag.js +18 -0
  42. package/components/HeroIcons.tsx +321 -0
  43. package/components/KatexReact.js +53 -0
  44. package/components/LazyImage.js +95 -0
  45. package/components/Live2D.js +52 -0
  46. package/components/Loading.js +20 -0
  47. package/components/Mark.js +28 -0
  48. package/components/NProgress.ts +8 -0
  49. package/components/Nest.js +124 -0
  50. package/components/NotionIcon.js +20 -0
  51. package/components/NotionPage.tsx +206 -0
  52. package/components/Player.js +54 -0
  53. package/components/PrismMac.js +236 -0
  54. package/components/QrCode.js +34 -0
  55. package/components/Ribbon.js +98 -0
  56. package/components/Sakura.js +192 -0
  57. package/components/Select.js +40 -0
  58. package/components/ShareBar.js +29 -0
  59. package/components/ShareButtons.js +403 -0
  60. package/components/SideBarDrawer.js +50 -0
  61. package/components/StarrySky.js +130 -0
  62. package/components/Tabs.js +64 -0
  63. package/components/ThemeSwitch.js +67 -0
  64. package/components/Twikoo.js +27 -0
  65. package/components/TwikooCommentCount.js +22 -0
  66. package/components/TwikooCommentCounter.js +78 -0
  67. package/components/TwikooRecentComments.js +11 -0
  68. package/components/Utterances.js +35 -0
  69. package/components/VConsole.js +76 -0
  70. package/components/ValineComponent.js +59 -0
  71. package/components/ValineCount.js +6 -0
  72. package/components/ValinePanel.js +3 -0
  73. package/components/Vercel.tsx +54 -0
  74. package/components/WWAds.js +18 -0
  75. package/components/WalineComponent.js +83 -0
  76. package/components/WebMention.js +173 -0
  77. package/components/Webwhiz.js +17 -0
  78. package/components/WordCount.js +73 -0
  79. package/hooks/useToggleClickOutSide.ts +32 -0
  80. package/hooks/useWindowSize.ts +30 -0
  81. package/lib/algolia.js +108 -0
  82. package/lib/busuanzi.js +99 -0
  83. package/lib/cache/cacheManager.ts +49 -0
  84. package/lib/cache/localFileCache.ts +56 -0
  85. package/lib/cache/memoryMache.ts +20 -0
  86. package/lib/cache/mongoDbCache.ts +70 -0
  87. package/lib/cache/types.ts +5 -0
  88. package/lib/font.js +46 -0
  89. package/lib/global.tsx +129 -0
  90. package/lib/gtag.js +17 -0
  91. package/lib/mailchimp.js +49 -0
  92. package/lib/memorize.js +0 -0
  93. package/lib/mhchem.js +1696 -0
  94. package/lib/notion/getAllCategories.ts +51 -0
  95. package/lib/notion/getAllPageIds.ts +51 -0
  96. package/lib/notion/getAllPosts.js +68 -0
  97. package/lib/notion/getAllTags.ts +43 -0
  98. package/lib/notion/getNotionData.ts +340 -0
  99. package/lib/notion/getPageInfoOfPostPage.ts +58 -0
  100. package/lib/notion/getPageProperties.ts +203 -0
  101. package/lib/notion/getPageTableOfContents.ts +107 -0
  102. package/lib/notion/getPostBlocks.ts +147 -0
  103. package/lib/notion/mapImage.ts +130 -0
  104. package/lib/notion/types.ts +125 -0
  105. package/lib/notion.js +2 -0
  106. package/lib/robots.txt.js +25 -0
  107. package/lib/rss.js +63 -0
  108. package/lib/sitemap.xml.js +67 -0
  109. package/lib/utils.js +212 -0
  110. package/next-env.d.ts +5 -0
  111. package/next-i18next.config.js +7 -0
  112. package/next-sitemap.config.js +11 -0
  113. package/next.config.js +124 -0
  114. package/package.json +92 -0
  115. package/pages/404.tsx +40 -0
  116. package/pages/[prefix]/[slug].tsx +123 -0
  117. package/pages/[prefix]/index.tsx +223 -0
  118. package/pages/_app.js +59 -0
  119. package/pages/_document.js +42 -0
  120. package/pages/api/subscribe.js +22 -0
  121. package/pages/archive/index.tsx +79 -0
  122. package/pages/category/[category]/index.tsx +87 -0
  123. package/pages/category/[category]/page/[page].tsx +103 -0
  124. package/pages/category/index.tsx +43 -0
  125. package/pages/index.tsx +88 -0
  126. package/pages/page/[page].tsx +93 -0
  127. package/pages/search/[keyword]/index.tsx +162 -0
  128. package/pages/search/[keyword]/page/[page].tsx +166 -0
  129. package/pages/search/index.tsx +69 -0
  130. package/pages/sitemap.xml.js +70 -0
  131. package/pages/tag/[tag]/index.tsx +73 -0
  132. package/pages/tag/[tag]/page/[page].tsx +87 -0
  133. package/pages/tag/index.tsx +42 -0
  134. package/postcss.config.js +6 -0
  135. package/public/ads.txt +1 -0
  136. package/public/avatar.png +0 -0
  137. package/public/avatar.svg +11 -0
  138. package/public/bg_image.jpg +0 -0
  139. package/public/css/all.min.css +9 -0
  140. package/public/css/custom.css +8 -0
  141. package/public/css/img-shadow.css +5 -0
  142. package/public/css/prism-mac-style.css +58 -0
  143. package/public/favicon.ico +0 -0
  144. package/public/favicon.svg +9 -0
  145. package/public/js/cusdis.es.js +107 -0
  146. package/public/js/custom.js +1 -0
  147. package/public/locales/en/common.json +44 -0
  148. package/public/locales/en/menu.json +9 -0
  149. package/public/locales/en/nav.json +11 -0
  150. package/public/locales/zh-CN/common.json +44 -0
  151. package/public/locales/zh-CN/menu.json +9 -0
  152. package/public/locales/zh-CN/nav.json +9 -0
  153. package/public/webfonts/fa-brands-400.ttf +0 -0
  154. package/public/webfonts/fa-brands-400.woff2 +0 -0
  155. package/public/webfonts/fa-regular-400.ttf +0 -0
  156. package/public/webfonts/fa-regular-400.woff2 +0 -0
  157. package/public/webfonts/fa-solid-900.ttf +0 -0
  158. package/public/webfonts/fa-solid-900.woff2 +0 -0
  159. package/public/webfonts/fa-v4compatibility.ttf +0 -0
  160. package/public/webfonts/fa-v4compatibility.woff2 +0 -0
  161. package/styles/animate.css +503 -0
  162. package/styles/globals.css +183 -0
  163. package/styles/notion.css +2064 -0
  164. package/styles/nprogress.css +84 -0
  165. package/styles/prism-theme.css +119 -0
  166. package/styles/utility-patterns.css +79 -0
  167. package/tailwind.config.js +37 -0
  168. package/theme/index.ts +6 -0
  169. package/theme/types/@theme-components.d.ts +29 -0
  170. package/theme/useLayout.ts +41 -0
  171. package/theme/utils.ts +108 -0
  172. package/themes/innocent/package.json +7 -0
  173. package/themes/innocent/theme.config.js +1 -0
  174. package/themes/nobelium/components/Announcement.tsx +27 -0
  175. package/themes/nobelium/components/ArticleFooter.tsx +39 -0
  176. package/themes/nobelium/components/ArticleInfo.tsx +58 -0
  177. package/themes/nobelium/components/ArticleLock.tsx +86 -0
  178. package/themes/nobelium/components/BlogArchiveItem.js +41 -0
  179. package/themes/nobelium/components/BlogListBar.js +39 -0
  180. package/themes/nobelium/components/BlogListPage.tsx +67 -0
  181. package/themes/nobelium/components/BlogListScroll.tsx +96 -0
  182. package/themes/nobelium/components/BlogPost.tsx +33 -0
  183. package/themes/nobelium/components/DarkModeButton.tsx +50 -0
  184. package/themes/nobelium/components/ExampleRecentComments.js +35 -0
  185. package/themes/nobelium/components/Footer.tsx +35 -0
  186. package/themes/nobelium/components/JumpToTopButton.tsx +39 -0
  187. package/themes/nobelium/components/LanguageSwitchButton.tsx +58 -0
  188. package/themes/nobelium/components/MenuItemCollapse.tsx +92 -0
  189. package/themes/nobelium/components/MenuItemDrop.tsx +83 -0
  190. package/themes/nobelium/components/Nav/Nav.module.css +50 -0
  191. package/themes/nobelium/components/Nav/Nav.tsx +187 -0
  192. package/themes/nobelium/components/RandomPostButton.tsx +31 -0
  193. package/themes/nobelium/components/SearchButton.tsx +31 -0
  194. package/themes/nobelium/components/SearchInput.tsx +94 -0
  195. package/themes/nobelium/components/SearchNavBar.js +19 -0
  196. package/themes/nobelium/components/SideBar.js +83 -0
  197. package/themes/nobelium/components/SvgIcon.js +29 -0
  198. package/themes/nobelium/components/TagItem.js +13 -0
  199. package/themes/nobelium/components/Tags.tsx +44 -0
  200. package/themes/nobelium/components/Title.js +19 -0
  201. package/themes/nobelium/index.tsx +28 -0
  202. package/themes/nobelium/layout/LayoutBase.tsx +79 -0
  203. package/themes/nobelium/pages/Archive.tsx +30 -0
  204. package/themes/nobelium/pages/Category.tsx +43 -0
  205. package/themes/nobelium/pages/Home.tsx +22 -0
  206. package/themes/nobelium/pages/PageNotFound.tsx +15 -0
  207. package/themes/nobelium/pages/Post.tsx +34 -0
  208. package/themes/nobelium/pages/PostList.tsx +74 -0
  209. package/themes/nobelium/pages/Search.tsx +65 -0
  210. package/themes/nobelium/pages/Tag.tsx +42 -0
  211. package/themes/nobelium/providers/index.tsx +60 -0
  212. package/themes/nobelium/stores/index.tsx +42 -0
  213. package/themes/nobelium/theme.config.ts +17 -0
  214. package/themes/nobelium/types/index.ts +10 -0
  215. package/tsconfig.json +29 -0
  216. package/types/index.ts +1 -0
  217. package/types/page.ts +102 -0
  218. package/vercel.json +5 -0
@@ -0,0 +1,70 @@
1
+ import { MongoClient } from 'mongodb';
2
+
3
+ const DB_URL = process.env.MONGO_DB_URL as string;
4
+ const DB_NAME = process.env.MONGO_DB_NAME as string;
5
+ const DB_COLLECTION = 'posts';
6
+
7
+ let client: MongoClient | null = null;
8
+
9
+ async function connectToDatabase() {
10
+ if (!client) {
11
+ client = await MongoClient.connect(DB_URL, {
12
+ // Optional connection pooling config
13
+ maxPoolSize: 10, // Maintain up to 10 socket connections
14
+ });
15
+ }
16
+ return client.db(DB_NAME);
17
+ }
18
+
19
+ export async function getCache(key: string) {
20
+ try {
21
+ const dbo = await connectToDatabase();
22
+ const query = { block_id: key };
23
+ const res = await dbo.collection(DB_COLLECTION).findOne(query);
24
+ return res;
25
+ } catch (err) {
26
+ console.error(`Failed to get cache for key: ${key}`, err);
27
+ throw err;
28
+ }
29
+ }
30
+
31
+ export async function setCache(key: string, data: any) {
32
+ try {
33
+ const dbo = await connectToDatabase();
34
+ data.block_id = key;
35
+ const query = { block_id: key };
36
+ const jsonObj = JSON.parse(JSON.stringify(data));
37
+
38
+ const updRes = await dbo
39
+ .collection(DB_COLLECTION)
40
+ .updateOne(query, { $set: jsonObj });
41
+ console.log('Update result', key, updRes);
42
+
43
+ if (updRes.matchedCount === 0) {
44
+ const insertRes = await dbo.collection(DB_COLLECTION).insertOne(jsonObj);
45
+ console.log('Insert result', key, insertRes);
46
+ }
47
+
48
+ return data;
49
+ } catch (err) {
50
+ console.error(`Failed to set cache for key: ${key}`, err);
51
+ throw err;
52
+ }
53
+ }
54
+
55
+ export async function delCache(key: string) {
56
+ try {
57
+ const dbo = await connectToDatabase();
58
+ const query = { block_id: key };
59
+ const res = await dbo.collection(DB_COLLECTION).deleteOne(query);
60
+ console.log('Delete result', key, res);
61
+ return null;
62
+ } catch (err) {
63
+ console.error(`Failed to delete cache for key: ${key}`, err);
64
+ throw err;
65
+ }
66
+ }
67
+
68
+ const mongoDbCache = { getCache, setCache, delCache };
69
+
70
+ export default mongoDbCache;
@@ -0,0 +1,5 @@
1
+ export interface CacheManager {
2
+ getCache: (key: string) => any;
3
+ setCache: (key: string, value: any) => void;
4
+ delCache: (key: string) => void;
5
+ }
package/lib/font.js ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * 在此处配置字体
3
+ */
4
+ import BLOG from '../blog.config';
5
+
6
+ // const { fontFamily } = require('tailwindcss/defaultTheme')
7
+
8
+ function CJK() {
9
+ switch (BLOG.LANG.toLowerCase()) {
10
+ case 'zh-cn':
11
+ case 'zh-sg':
12
+ return 'SC';
13
+ case 'zh':
14
+ case 'zh-hk':
15
+ case 'zh-tw':
16
+ return 'TC';
17
+ case 'ja':
18
+ case 'ja-jp':
19
+ return 'JP';
20
+ case 'ko':
21
+ case 'ko-kr':
22
+ return 'KR';
23
+ default:
24
+ return null;
25
+ }
26
+ }
27
+
28
+ const fontSansCJK = !CJK()
29
+ ? []
30
+ : [`"Noto Sans CJK ${CJK()}"`, `"Noto Sans ${CJK()}"`];
31
+ const fontSerifCJK = !CJK()
32
+ ? []
33
+ : [`"Noto Serif CJK ${CJK()}"`, `"Noto Serif ${CJK()}"`];
34
+
35
+ const fontFamilies = {
36
+ sans: [...BLOG.FONT_SANS, ...fontSansCJK],
37
+ serif: [...BLOG.FONT_SERIF, ...fontSerifCJK],
38
+ noEmoji: [
39
+ 'ui-sans-serif',
40
+ 'system-ui',
41
+ '-apple-system',
42
+ 'BlinkMacSystemFont',
43
+ 'sans-serif',
44
+ ],
45
+ };
46
+ module.exports = { fontFamilies };
package/lib/global.tsx ADDED
@@ -0,0 +1,129 @@
1
+ import { createContext, useContext, useEffect, useState } from 'react';
2
+ import { useRouter } from 'next/router';
3
+ import BLOG from '@/blog.config';
4
+ import {
5
+ THEMES,
6
+ initTheme,
7
+ initDarkMode,
8
+ operateDarkMode,
9
+ saveDarkModeToLocalStorage,
10
+ } from '@/theme';
11
+ import { getQueryVariable } from './utils';
12
+ import { progressStart, progressDone } from '@/components/NProgress';
13
+
14
+ import type { FunctionComponent, ReactNode } from 'react';
15
+
16
+ export interface GlobalContextProps {
17
+ theme: string;
18
+ isDarkMode: boolean;
19
+ onLoading: boolean;
20
+ siteInfo: unknown;
21
+ categoryOptions: unknown;
22
+ tagOptions: unknown;
23
+ switchTheme: (theme: string) => void;
24
+ setTheme: (theme: string) => void;
25
+ updateDarkMode: (isDarkMode: boolean) => void;
26
+ setOnLoading: (onLoading: boolean) => void;
27
+ }
28
+
29
+ const GlobalContext = createContext<GlobalContextProps>({
30
+ theme: BLOG.THEME,
31
+ isDarkMode: false,
32
+ onLoading: false,
33
+ siteInfo: {},
34
+ categoryOptions: [],
35
+ tagOptions: [],
36
+ switchTheme: () => {},
37
+ setTheme: () => {},
38
+ updateDarkMode: () => {},
39
+ setOnLoading: () => {},
40
+ });
41
+
42
+ /**
43
+ * 全局变量Provider,包括语言本地化、样式主题、搜索词
44
+ * @param children
45
+ * @returns {JSX.Element}
46
+ * @constructor
47
+ */
48
+ export const GlobalContextProvider: FunctionComponent<
49
+ GlobalContextProps & {
50
+ children: ReactNode;
51
+ }
52
+ > = (props) => {
53
+ const { children, siteInfo, categoryOptions, tagOptions } = props;
54
+ const router = useRouter();
55
+ // lang 为所选语言,如 zh-CN,
56
+ // locale 为对应语言的配置对象
57
+ const [theme, setTheme] = useState(BLOG.THEME); // 默认博客主题
58
+ const [isDarkMode, updateDarkMode] = useState(BLOG.APPEARANCE === 'dark'); // 默认深色模式
59
+ const [onLoading, setOnLoading] = useState(false); // 抓取文章数据
60
+
61
+ useEffect(() => {
62
+ updateDarkMode(initDarkMode());
63
+ initTheme();
64
+ }, []);
65
+
66
+ // 切换暗黑模式
67
+ useEffect(() => {
68
+ saveDarkModeToLocalStorage(isDarkMode);
69
+ operateDarkMode(isDarkMode);
70
+ }, [isDarkMode]);
71
+
72
+ useEffect(() => {
73
+ const handleStart = (url: string) => {
74
+ progressStart();
75
+ const { theme } = router.query;
76
+ if (theme && !url.includes(`theme=${theme}`)) {
77
+ const newUrl = `${url}${url.includes('?') ? '&' : '?'}theme=${theme}`;
78
+ router.push(newUrl);
79
+ }
80
+ setOnLoading(true);
81
+ };
82
+ const handleStop = () => {
83
+ progressDone();
84
+ setOnLoading(false);
85
+ };
86
+ const queryTheme = getQueryVariable('theme') || BLOG.THEME;
87
+ setTheme(queryTheme);
88
+ router.events.on('routeChangeStart', handleStart);
89
+ router.events.on('routeChangeError', handleStop);
90
+ router.events.on('routeChangeComplete', handleStop);
91
+ return () => {
92
+ router.events.off('routeChangeStart', handleStart);
93
+ router.events.off('routeChangeComplete', handleStop);
94
+ router.events.off('routeChangeError', handleStop);
95
+ };
96
+ }, [router]);
97
+
98
+ // 切换主题
99
+ function switchTheme() {
100
+ const currentIndex = THEMES.indexOf(theme);
101
+ const newIndex = currentIndex < THEMES.length - 1 ? currentIndex + 1 : 0;
102
+ const newTheme = THEMES[newIndex];
103
+ const query = router.query;
104
+ query.theme = newTheme;
105
+ router.push({ pathname: router.pathname, query });
106
+ return newTheme;
107
+ }
108
+
109
+ return (
110
+ <GlobalContext.Provider
111
+ value={{
112
+ onLoading,
113
+ setOnLoading,
114
+ isDarkMode,
115
+ updateDarkMode,
116
+ theme,
117
+ setTheme,
118
+ switchTheme,
119
+ siteInfo,
120
+ categoryOptions,
121
+ tagOptions,
122
+ }}
123
+ >
124
+ {children}
125
+ </GlobalContext.Provider>
126
+ );
127
+ };
128
+
129
+ export const useGlobal = () => useContext(GlobalContext);
package/lib/gtag.js ADDED
@@ -0,0 +1,17 @@
1
+ import BLOG from '@/blog.config'
2
+
3
+ // https://developers.google.com/analytics/devguides/collection/gtagjs/pages
4
+ export const pageview = url => {
5
+ window.gtag('config', BLOG.ANALYTICS_GOOGLE_ID, {
6
+ page_path: url
7
+ })
8
+ }
9
+
10
+ // https://developers.google.com/analytics/devguides/collection/gtagjs/events
11
+ export const event = ({ action, category, label, value }) => {
12
+ window.gtag('event', action, {
13
+ event_category: category,
14
+ event_label: label,
15
+ value: value
16
+ })
17
+ }
@@ -0,0 +1,49 @@
1
+ import BLOG from '@/blog.config'
2
+
3
+ /**
4
+ * 订阅邮件-服务端接口
5
+ * @param {*} email
6
+ * @returns
7
+ */
8
+ export default function subscribeToMailchimpApi({ email, first_name = '', last_name = '' }) {
9
+ const listId = BLOG.MAILCHIMP_LIST_ID // 替换为你的邮件列表 ID
10
+ const apiKey = BLOG.MAILCHIMP_API_KEY // 替换为你的 API KEY
11
+ if (!email || !listId || !apiKey) {
12
+ return {}
13
+ }
14
+ const data = {
15
+ email_address: email,
16
+ status: 'subscribed',
17
+ merge_fields: {
18
+ FNAME: first_name,
19
+ LNAME: last_name
20
+ }
21
+ }
22
+ return fetch(`https://us18.api.mailchimp.com/3.0/lists/${listId}/members`, {
23
+ method: 'POST',
24
+ headers: {
25
+ Authorization: `apikey ${apiKey}`,
26
+ 'Content-Type': 'application/json'
27
+ },
28
+ body: JSON.stringify(data)
29
+ })
30
+ }
31
+
32
+ /**
33
+ * 客户端接口
34
+ * @param {*} email
35
+ * @param {*} firstName
36
+ * @param {*} lastName
37
+ * @returns
38
+ */
39
+ export async function subscribeToNewsletter(email, firstName, lastName) {
40
+ const response = await fetch('/api/subscribe', {
41
+ method: 'POST',
42
+ headers: {
43
+ 'Content-Type': 'application/json'
44
+ },
45
+ body: JSON.stringify({ email, first_name: firstName, last_name: lastName })
46
+ })
47
+ const data = await response.json()
48
+ return data
49
+ }
File without changes