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.
- package/.dockerignore +1 -0
- package/.env.local +2 -0
- package/.eslintrc.json +15 -0
- package/.github/stale.yml +16 -0
- package/.github/workflows/codeql-analysis.yml +73 -0
- package/.github/workflows/docker-ghcr.yaml +59 -0
- package/.prettierrc +9 -0
- package/.vscode/launch.json +28 -0
- package/.vscode/settings.json +6 -0
- package/Dockerfile +38 -0
- package/LICENSE +21 -0
- package/README.md +16 -0
- package/blog.config.js +454 -0
- package/components/Ackee.js +83 -0
- package/components/AdBlockDetect.js +40 -0
- package/components/AlgoliaSearchModal.js +250 -0
- package/components/Artalk.js +30 -0
- package/components/Busuanzi.js +26 -0
- package/components/ChatBase.js +19 -0
- package/components/Collapse.tsx +134 -0
- package/components/Comment.js +161 -0
- package/components/CommonHead.tsx +101 -0
- package/components/CommonScript.js +125 -0
- package/components/CusdisComponent.js +35 -0
- package/components/CustomContextMenu.js +221 -0
- package/components/DebugPanel.js +134 -0
- package/components/DisableCopy.js +21 -0
- package/components/Draggable.js +167 -0
- package/components/Equation.js +31 -0
- package/components/ExternalPlugins.js +75 -0
- package/components/ExternalScript.js +29 -0
- package/components/FacebookMessenger.js +255 -0
- package/components/FacebookPage.js +34 -0
- package/components/Fireworks.js +210 -0
- package/components/FlipCard.js +56 -0
- package/components/FlutteringRibbon.js +322 -0
- package/components/FullScreenButton.js +48 -0
- package/components/Giscus.js +33 -0
- package/components/Gitalk.js +42 -0
- package/components/GoogleAdsense.js +111 -0
- package/components/Gtag.js +18 -0
- package/components/HeroIcons.tsx +321 -0
- package/components/KatexReact.js +53 -0
- package/components/LazyImage.js +95 -0
- package/components/Live2D.js +52 -0
- package/components/Loading.js +20 -0
- package/components/Mark.js +28 -0
- package/components/NProgress.ts +8 -0
- package/components/Nest.js +124 -0
- package/components/NotionIcon.js +20 -0
- package/components/NotionPage.tsx +206 -0
- package/components/Player.js +54 -0
- package/components/PrismMac.js +236 -0
- package/components/QrCode.js +34 -0
- package/components/Ribbon.js +98 -0
- package/components/Sakura.js +192 -0
- package/components/Select.js +40 -0
- package/components/ShareBar.js +29 -0
- package/components/ShareButtons.js +403 -0
- package/components/SideBarDrawer.js +50 -0
- package/components/StarrySky.js +130 -0
- package/components/Tabs.js +64 -0
- package/components/ThemeSwitch.js +67 -0
- package/components/Twikoo.js +27 -0
- package/components/TwikooCommentCount.js +22 -0
- package/components/TwikooCommentCounter.js +78 -0
- package/components/TwikooRecentComments.js +11 -0
- package/components/Utterances.js +35 -0
- package/components/VConsole.js +76 -0
- package/components/ValineComponent.js +59 -0
- package/components/ValineCount.js +6 -0
- package/components/ValinePanel.js +3 -0
- package/components/Vercel.tsx +54 -0
- package/components/WWAds.js +18 -0
- package/components/WalineComponent.js +83 -0
- package/components/WebMention.js +173 -0
- package/components/Webwhiz.js +17 -0
- package/components/WordCount.js +73 -0
- package/hooks/useToggleClickOutSide.ts +32 -0
- package/hooks/useWindowSize.ts +30 -0
- package/lib/algolia.js +108 -0
- package/lib/busuanzi.js +99 -0
- package/lib/cache/cacheManager.ts +49 -0
- package/lib/cache/localFileCache.ts +56 -0
- package/lib/cache/memoryMache.ts +20 -0
- package/lib/cache/mongoDbCache.ts +70 -0
- package/lib/cache/types.ts +5 -0
- package/lib/font.js +46 -0
- package/lib/global.tsx +129 -0
- package/lib/gtag.js +17 -0
- package/lib/mailchimp.js +49 -0
- package/lib/memorize.js +0 -0
- package/lib/mhchem.js +1696 -0
- package/lib/notion/getAllCategories.ts +51 -0
- package/lib/notion/getAllPageIds.ts +51 -0
- package/lib/notion/getAllPosts.js +68 -0
- package/lib/notion/getAllTags.ts +43 -0
- package/lib/notion/getNotionData.ts +340 -0
- package/lib/notion/getPageInfoOfPostPage.ts +58 -0
- package/lib/notion/getPageProperties.ts +203 -0
- package/lib/notion/getPageTableOfContents.ts +107 -0
- package/lib/notion/getPostBlocks.ts +147 -0
- package/lib/notion/mapImage.ts +130 -0
- package/lib/notion/types.ts +125 -0
- package/lib/notion.js +2 -0
- package/lib/robots.txt.js +25 -0
- package/lib/rss.js +63 -0
- package/lib/sitemap.xml.js +67 -0
- package/lib/utils.js +212 -0
- package/next-env.d.ts +5 -0
- package/next-i18next.config.js +7 -0
- package/next-sitemap.config.js +11 -0
- package/next.config.js +124 -0
- package/package.json +92 -0
- package/pages/404.tsx +40 -0
- package/pages/[prefix]/[slug].tsx +123 -0
- package/pages/[prefix]/index.tsx +223 -0
- package/pages/_app.js +59 -0
- package/pages/_document.js +42 -0
- package/pages/api/subscribe.js +22 -0
- package/pages/archive/index.tsx +79 -0
- package/pages/category/[category]/index.tsx +87 -0
- package/pages/category/[category]/page/[page].tsx +103 -0
- package/pages/category/index.tsx +43 -0
- package/pages/index.tsx +88 -0
- package/pages/page/[page].tsx +93 -0
- package/pages/search/[keyword]/index.tsx +162 -0
- package/pages/search/[keyword]/page/[page].tsx +166 -0
- package/pages/search/index.tsx +69 -0
- package/pages/sitemap.xml.js +70 -0
- package/pages/tag/[tag]/index.tsx +73 -0
- package/pages/tag/[tag]/page/[page].tsx +87 -0
- package/pages/tag/index.tsx +42 -0
- package/postcss.config.js +6 -0
- package/public/ads.txt +1 -0
- package/public/avatar.png +0 -0
- package/public/avatar.svg +11 -0
- package/public/bg_image.jpg +0 -0
- package/public/css/all.min.css +9 -0
- package/public/css/custom.css +8 -0
- package/public/css/img-shadow.css +5 -0
- package/public/css/prism-mac-style.css +58 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +9 -0
- package/public/js/cusdis.es.js +107 -0
- package/public/js/custom.js +1 -0
- package/public/locales/en/common.json +44 -0
- package/public/locales/en/menu.json +9 -0
- package/public/locales/en/nav.json +11 -0
- package/public/locales/zh-CN/common.json +44 -0
- package/public/locales/zh-CN/menu.json +9 -0
- package/public/locales/zh-CN/nav.json +9 -0
- package/public/webfonts/fa-brands-400.ttf +0 -0
- package/public/webfonts/fa-brands-400.woff2 +0 -0
- package/public/webfonts/fa-regular-400.ttf +0 -0
- package/public/webfonts/fa-regular-400.woff2 +0 -0
- package/public/webfonts/fa-solid-900.ttf +0 -0
- package/public/webfonts/fa-solid-900.woff2 +0 -0
- package/public/webfonts/fa-v4compatibility.ttf +0 -0
- package/public/webfonts/fa-v4compatibility.woff2 +0 -0
- package/styles/animate.css +503 -0
- package/styles/globals.css +183 -0
- package/styles/notion.css +2064 -0
- package/styles/nprogress.css +84 -0
- package/styles/prism-theme.css +119 -0
- package/styles/utility-patterns.css +79 -0
- package/tailwind.config.js +37 -0
- package/theme/index.ts +6 -0
- package/theme/types/@theme-components.d.ts +29 -0
- package/theme/useLayout.ts +41 -0
- package/theme/utils.ts +108 -0
- package/themes/innocent/package.json +7 -0
- package/themes/innocent/theme.config.js +1 -0
- package/themes/nobelium/components/Announcement.tsx +27 -0
- package/themes/nobelium/components/ArticleFooter.tsx +39 -0
- package/themes/nobelium/components/ArticleInfo.tsx +58 -0
- package/themes/nobelium/components/ArticleLock.tsx +86 -0
- package/themes/nobelium/components/BlogArchiveItem.js +41 -0
- package/themes/nobelium/components/BlogListBar.js +39 -0
- package/themes/nobelium/components/BlogListPage.tsx +67 -0
- package/themes/nobelium/components/BlogListScroll.tsx +96 -0
- package/themes/nobelium/components/BlogPost.tsx +33 -0
- package/themes/nobelium/components/DarkModeButton.tsx +50 -0
- package/themes/nobelium/components/ExampleRecentComments.js +35 -0
- package/themes/nobelium/components/Footer.tsx +35 -0
- package/themes/nobelium/components/JumpToTopButton.tsx +39 -0
- package/themes/nobelium/components/LanguageSwitchButton.tsx +58 -0
- package/themes/nobelium/components/MenuItemCollapse.tsx +92 -0
- package/themes/nobelium/components/MenuItemDrop.tsx +83 -0
- package/themes/nobelium/components/Nav/Nav.module.css +50 -0
- package/themes/nobelium/components/Nav/Nav.tsx +187 -0
- package/themes/nobelium/components/RandomPostButton.tsx +31 -0
- package/themes/nobelium/components/SearchButton.tsx +31 -0
- package/themes/nobelium/components/SearchInput.tsx +94 -0
- package/themes/nobelium/components/SearchNavBar.js +19 -0
- package/themes/nobelium/components/SideBar.js +83 -0
- package/themes/nobelium/components/SvgIcon.js +29 -0
- package/themes/nobelium/components/TagItem.js +13 -0
- package/themes/nobelium/components/Tags.tsx +44 -0
- package/themes/nobelium/components/Title.js +19 -0
- package/themes/nobelium/index.tsx +28 -0
- package/themes/nobelium/layout/LayoutBase.tsx +79 -0
- package/themes/nobelium/pages/Archive.tsx +30 -0
- package/themes/nobelium/pages/Category.tsx +43 -0
- package/themes/nobelium/pages/Home.tsx +22 -0
- package/themes/nobelium/pages/PageNotFound.tsx +15 -0
- package/themes/nobelium/pages/Post.tsx +34 -0
- package/themes/nobelium/pages/PostList.tsx +74 -0
- package/themes/nobelium/pages/Search.tsx +65 -0
- package/themes/nobelium/pages/Tag.tsx +42 -0
- package/themes/nobelium/providers/index.tsx +60 -0
- package/themes/nobelium/stores/index.tsx +42 -0
- package/themes/nobelium/theme.config.ts +17 -0
- package/themes/nobelium/types/index.ts +10 -0
- package/tsconfig.json +29 -0
- package/types/index.ts +1 -0
- package/types/page.ts +102 -0
- 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;
|
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
|
+
}
|
package/lib/mailchimp.js
ADDED
@@ -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
|
+
}
|
package/lib/memorize.js
ADDED
File without changes
|