@lobehub/chat 1.19.2 → 1.19.4
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.
Potentially problematic release.
This version of @lobehub/chat might be problematic. Click here for more details.
- package/CHANGELOG.md +42 -0
- package/Dockerfile +22 -20
- package/Dockerfile.database +22 -20
- package/README.md +8 -10
- package/README.zh-CN.md +8 -10
- package/next.config.mjs +10 -0
- package/package.json +6 -7
- package/scripts/buildSitemapIndex/index.ts +12 -0
- package/src/app/(main)/discover/(detail)/assistant/[slug]/page.tsx +1 -0
- package/src/app/(main)/discover/(detail)/model/[...slugs]/features/ProviderList/ProviderItem.tsx +1 -0
- package/src/app/(main)/discover/(detail)/model/[...slugs]/page.tsx +1 -0
- package/src/app/(main)/discover/(detail)/plugin/[slug]/page.tsx +1 -0
- package/src/app/(main)/discover/(detail)/provider/[slug]/features/ModelList/ModelItem.tsx +1 -0
- package/src/app/(main)/discover/(detail)/provider/[slug]/page.tsx +1 -0
- package/src/app/(main)/discover/(list)/_layout/Desktop/Nav.tsx +1 -0
- package/src/app/(main)/discover/_layout/Desktop/index.tsx +1 -0
- package/src/app/page.tsx +1 -1
- package/src/app/robots.tsx +16 -0
- package/src/app/sitemap.tsx +30 -0
- package/src/const/url.ts +2 -2
- package/src/server/ld.test.ts +102 -0
- package/src/server/ld.ts +3 -9
- package/src/server/metadata.test.ts +138 -0
- package/src/server/metadata.ts +3 -3
- package/src/server/modules/AssistantStore/index.test.ts +1 -1
- package/src/server/modules/AssistantStore/index.ts +2 -6
- package/src/server/sitemap.test.ts +179 -0
- package/src/server/sitemap.ts +243 -0
- package/src/server/translation.test.ts +137 -0
- package/src/server/utils/url.test.ts +61 -0
- package/src/server/utils/url.ts +9 -0
- package/next-sitemap.config.mjs +0 -53
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,48 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.19.4](https://github.com/lobehub/lobe-chat/compare/v1.19.3...v1.19.4)
|
6
|
+
|
7
|
+
<sup>Released on **2024-09-19**</sup>
|
8
|
+
|
9
|
+
#### ♻ Code Refactoring
|
10
|
+
|
11
|
+
- **misc**: Refactor the sitemap implement.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### Code refactoring
|
19
|
+
|
20
|
+
- **misc**: Refactor the sitemap implement, closes [#4012](https://github.com/lobehub/lobe-chat/issues/4012) ([d93a161](https://github.com/lobehub/lobe-chat/commit/d93a161))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
30
|
+
### [Version 1.19.3](https://github.com/lobehub/lobe-chat/compare/v1.19.2...v1.19.3)
|
31
|
+
|
32
|
+
<sup>Released on **2024-09-19**</sup>
|
33
|
+
|
34
|
+
<br/>
|
35
|
+
|
36
|
+
<details>
|
37
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
38
|
+
|
39
|
+
</details>
|
40
|
+
|
41
|
+
<div align="right">
|
42
|
+
|
43
|
+
[](#readme-top)
|
44
|
+
|
45
|
+
</div>
|
46
|
+
|
5
47
|
### [Version 1.19.2](https://github.com/lobehub/lobe-chat/compare/v1.19.1...v1.19.2)
|
6
48
|
|
7
49
|
<sup>Released on **2024-09-19**</sup>
|
package/Dockerfile
CHANGED
@@ -1,23 +1,30 @@
|
|
1
1
|
## Base image for all the stages
|
2
|
-
FROM node:20-
|
2
|
+
FROM node:20-slim AS base
|
3
3
|
|
4
4
|
ARG USE_CN_MIRROR
|
5
5
|
|
6
|
+
ENV DEBIAN_FRONTEND="noninteractive"
|
7
|
+
|
6
8
|
RUN \
|
7
9
|
# If you want to build docker in China, build with --build-arg USE_CN_MIRROR=true
|
8
10
|
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then \
|
9
|
-
sed -i "s/
|
11
|
+
sed -i "s/deb.debian.org/mirrors.ustc.edu.cn/g" "/etc/apt/sources.list.d/debian.sources"; \
|
10
12
|
fi \
|
11
13
|
# Add required package & update base package
|
12
|
-
&&
|
13
|
-
&&
|
14
|
-
&&
|
15
|
-
|
14
|
+
&& apt update \
|
15
|
+
&& apt install busybox proxychains-ng -qy \
|
16
|
+
&& apt full-upgrade -qy \
|
17
|
+
&& apt autoremove -qy --purge \
|
18
|
+
&& apt clean -qy \
|
19
|
+
# Configure BusyBox
|
20
|
+
&& busybox --install -s \
|
21
|
+
# Add nextjs:nodejs to run the app
|
16
22
|
&& addgroup --system --gid 1001 nodejs \
|
17
|
-
&& adduser --system --uid 1001 nextjs \
|
18
|
-
|
19
|
-
&&
|
20
|
-
|
23
|
+
&& adduser --system --home "/app" --gid 1001 -uid 1001 nextjs \
|
24
|
+
# Set permission for nextjs:nodejs
|
25
|
+
&& chown -R nextjs:nodejs "/etc/proxychains4.conf" \
|
26
|
+
# Cleanup temp files
|
27
|
+
&& rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/*
|
21
28
|
|
22
29
|
## Builder image, install all the dependencies and build the app
|
23
30
|
FROM base AS builder
|
@@ -89,7 +96,8 @@ FROM base
|
|
89
96
|
# Copy all the files from app, set the correct permission for prerender cache
|
90
97
|
COPY --from=app --chown=nextjs:nodejs /app /app
|
91
98
|
|
92
|
-
ENV NODE_ENV="production"
|
99
|
+
ENV NODE_ENV="production" \
|
100
|
+
NODE_TLS_REJECT_UNAUTHORIZED=""
|
93
101
|
|
94
102
|
# set hostname to localhost
|
95
103
|
ENV HOSTNAME="0.0.0.0" \
|
@@ -121,6 +129,8 @@ ENV \
|
|
121
129
|
DEEPSEEK_API_KEY="" \
|
122
130
|
# Fireworks AI
|
123
131
|
FIREWORKSAI_API_KEY="" FIREWORKSAI_MODEL_LIST="" \
|
132
|
+
# GitHub
|
133
|
+
GITHUB_TOKEN="" GITHUB_MODEL_LIST="" \
|
124
134
|
# Google
|
125
135
|
GOOGLE_API_KEY="" GOOGLE_PROXY_URL="" \
|
126
136
|
# Groq
|
@@ -193,15 +203,7 @@ CMD \
|
|
193
203
|
'tcp_read_time_out 15000' \
|
194
204
|
'[ProxyList]' \
|
195
205
|
"$protocol $host $port" \
|
196
|
-
> "/etc/
|
197
|
-
fi; \
|
198
|
-
# Fix DNS resolving issue in Docker Compose, ref https://github.com/lobehub/lobe-chat/pull/3837
|
199
|
-
if [ -f "/etc/resolv.conf" ]; then \
|
200
|
-
sudo chmod 666 "/etc/resolv.conf"; \
|
201
|
-
resolv_conf=$(grep '^nameserver' "/etc/resolv.conf" | awk '{print "nameserver " $2}'); \
|
202
|
-
printf "%s\n" \
|
203
|
-
"$resolv_conf" \
|
204
|
-
> "/etc/resolv.conf"; \
|
206
|
+
> "/etc/proxychains4.conf"; \
|
205
207
|
fi; \
|
206
208
|
# Run the server
|
207
209
|
${PROXYCHAINS} node "/app/server.js";
|
package/Dockerfile.database
CHANGED
@@ -1,23 +1,30 @@
|
|
1
1
|
## Base image for all the stages
|
2
|
-
FROM node:20-
|
2
|
+
FROM node:20-slim AS base
|
3
3
|
|
4
4
|
ARG USE_CN_MIRROR
|
5
5
|
|
6
|
+
ENV DEBIAN_FRONTEND="noninteractive"
|
7
|
+
|
6
8
|
RUN \
|
7
9
|
# If you want to build docker in China, build with --build-arg USE_CN_MIRROR=true
|
8
10
|
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then \
|
9
|
-
sed -i "s/
|
11
|
+
sed -i "s/deb.debian.org/mirrors.ustc.edu.cn/g" "/etc/apt/sources.list.d/debian.sources"; \
|
10
12
|
fi \
|
11
13
|
# Add required package & update base package
|
12
|
-
&&
|
13
|
-
&&
|
14
|
-
&&
|
15
|
-
|
14
|
+
&& apt update \
|
15
|
+
&& apt install busybox proxychains-ng -qy \
|
16
|
+
&& apt full-upgrade -qy \
|
17
|
+
&& apt autoremove -qy --purge \
|
18
|
+
&& apt clean -qy \
|
19
|
+
# Configure BusyBox
|
20
|
+
&& busybox --install -s \
|
21
|
+
# Add nextjs:nodejs to run the app
|
16
22
|
&& addgroup --system --gid 1001 nodejs \
|
17
|
-
&& adduser --system --uid 1001 nextjs \
|
18
|
-
|
19
|
-
&&
|
20
|
-
|
23
|
+
&& adduser --system --home "/app" --gid 1001 -uid 1001 nextjs \
|
24
|
+
# Set permission for nextjs:nodejs
|
25
|
+
&& chown -R nextjs:nodejs "/etc/proxychains4.conf" \
|
26
|
+
# Cleanup temp files
|
27
|
+
&& rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/*
|
21
28
|
|
22
29
|
## Builder image, install all the dependencies and build the app
|
23
30
|
FROM base AS builder
|
@@ -102,7 +109,8 @@ FROM base
|
|
102
109
|
# Copy all the files from app, set the correct permission for prerender cache
|
103
110
|
COPY --from=app --chown=nextjs:nodejs /app /app
|
104
111
|
|
105
|
-
ENV NODE_ENV="production"
|
112
|
+
ENV NODE_ENV="production" \
|
113
|
+
NODE_TLS_REJECT_UNAUTHORIZED=""
|
106
114
|
|
107
115
|
# set hostname to localhost
|
108
116
|
ENV HOSTNAME="0.0.0.0" \
|
@@ -153,6 +161,8 @@ ENV \
|
|
153
161
|
DEEPSEEK_API_KEY="" \
|
154
162
|
# Fireworks AI
|
155
163
|
FIREWORKSAI_API_KEY="" FIREWORKSAI_MODEL_LIST="" \
|
164
|
+
# GitHub
|
165
|
+
GITHUB_TOKEN="" GITHUB_MODEL_LIST="" \
|
156
166
|
# Google
|
157
167
|
GOOGLE_API_KEY="" GOOGLE_PROXY_URL="" \
|
158
168
|
# Groq
|
@@ -225,15 +235,7 @@ CMD \
|
|
225
235
|
'tcp_read_time_out 15000' \
|
226
236
|
'[ProxyList]' \
|
227
237
|
"$protocol $host $port" \
|
228
|
-
> "/etc/
|
229
|
-
fi; \
|
230
|
-
# Fix DNS resolving issue in Docker Compose, ref https://github.com/lobehub/lobe-chat/pull/3837
|
231
|
-
if [ -f "/etc/resolv.conf" ]; then \
|
232
|
-
sudo chmod 666 "/etc/resolv.conf"; \
|
233
|
-
resolv_conf=$(grep '^nameserver' "/etc/resolv.conf" | awk '{print "nameserver " $2}'); \
|
234
|
-
printf "%s\n" \
|
235
|
-
"$resolv_conf" \
|
236
|
-
> "/etc/resolv.conf"; \
|
238
|
+
> "/etc/proxychains4.conf"; \
|
237
239
|
fi; \
|
238
240
|
# Run migration
|
239
241
|
node "/app/docker.cjs"; \
|
package/README.md
CHANGED
@@ -285,16 +285,14 @@ Our marketplace is not just a showcase platform but also a collaborative space.
|
|
285
285
|
|
286
286
|
<!-- AGENT LIST -->
|
287
287
|
|
288
|
-
| Recent Submits
|
289
|
-
|
|
290
|
-
| [
|
291
|
-
| [
|
292
|
-
| [
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
> 📊 Total agents: [<kbd>**335**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
|
288
|
+
| Recent Submits | Description |
|
289
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
290
|
+
| [Fitness AI Trainer](https://chat-preview.lobehub.com/market?agent=ai-trainer)<br/><sup>By **[andreasvikke](https://github.com/andreasvikke)** on **2024-09-19**</sup> | AI workout assistant specializing in personalized plans, muscle targeting, form guidance, progress tracking, motivation, and VR training.<br/>`workout-assistant` `fitness` `exercise` `training` `nutrition` |
|
291
|
+
| [Alfred](https://chat-preview.lobehub.com/market?agent=alfred)<br/><sup>By **[Bern3rsH](https://github.com/Bern3rsH)** on **2024-09-19**</sup> | A versatile butler.<br/>`lifestyle` `personal` |
|
292
|
+
| [Career Development Mentor](https://chat-preview.lobehub.com/market?agent=career-development)<br/><sup>By **[daylight2022](https://github.com/daylight2022)** on **2024-09-19**</sup> | Professional career development planning and entrepreneurial consulting, providing practical advice through an in-depth understanding of user situations.<br/>`career-consulting` `career-planning` `entrepreneurship-guidance` `industry-insights` `skill-enhancement` |
|
293
|
+
| [Vocabulary Assistant](https://chat-preview.lobehub.com/market?agent=english-words-helper)<br/><sup>By **[SpeedupMaster](https://github.com/SpeedupMaster)** on **2024-09-19**</sup> | An assistant skilled in English word definitions and example sentence translations<br/>`vocabulary-assistant` `english` `translation` `example-sentences` `definitions` |
|
294
|
+
|
295
|
+
> 📊 Total agents: [<kbd>**351**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
|
298
296
|
|
299
297
|
<!-- AGENT LIST -->
|
300
298
|
|
package/README.zh-CN.md
CHANGED
@@ -273,16 +273,14 @@ LobeChat 的插件生态系统是其核心功能的重要扩展,它极大地
|
|
273
273
|
|
274
274
|
<!-- AGENT LIST -->
|
275
275
|
|
276
|
-
| 最近新增
|
277
|
-
|
|
278
|
-
| [
|
279
|
-
| [
|
280
|
-
| [
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
> 📊 Total agents: [<kbd>**335**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
|
276
|
+
| 最近新增 | 助手说明 |
|
277
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
|
278
|
+
| [健身 AI 教练](https://chat-preview.lobehub.com/market?agent=ai-trainer)<br/><sup>By **[andreasvikke](https://github.com/andreasvikke)** on **2024-09-19**</sup> | 专注于个性化计划、肌肉目标、姿势指导、进度跟踪、激励和虚拟现实训练的 AI 锻炼助手。<br/>`锻炼助手` `健身` `运动` `训练` `营养` |
|
279
|
+
| [Alfred](https://chat-preview.lobehub.com/market?agent=alfred)<br/><sup>By **[Bern3rsH](https://github.com/Bern3rsH)** on **2024-09-19**</sup> | 一位全能的管家。<br/>`生活` `个人` |
|
280
|
+
| [职业发展导师](https://chat-preview.lobehub.com/market?agent=career-development)<br/><sup>By **[daylight2022](https://github.com/daylight2022)** on **2024-09-19**</sup> | 专业的职业发展规划和创业咨询,通过深入了解用户情况提供切实可行的建议<br/>`职业咨询` `职业规划` `创业指导` `行业洞察` `技能提升` |
|
281
|
+
| [词汇助手](https://chat-preview.lobehub.com/market?agent=english-words-helper)<br/><sup>By **[SpeedupMaster](https://github.com/SpeedupMaster)** on **2024-09-19**</sup> | 擅长英语单词释义及例句翻译助手<br/>`词汇助手` `英语` `翻译` `例句` `释义` |
|
282
|
+
|
283
|
+
> 📊 Total agents: [<kbd>**351**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
|
286
284
|
|
287
285
|
<!-- AGENT LIST -->
|
288
286
|
|
package/next.config.mjs
CHANGED
@@ -107,6 +107,16 @@ const nextConfig = {
|
|
107
107
|
output: buildWithDocker ? 'standalone' : undefined,
|
108
108
|
reactStrictMode: true,
|
109
109
|
redirects: async () => [
|
110
|
+
{
|
111
|
+
destination: '/sitemap-index.xml',
|
112
|
+
permanent: true,
|
113
|
+
source: '/sitemap.xml',
|
114
|
+
},
|
115
|
+
{
|
116
|
+
destination: '/discover',
|
117
|
+
permanent: true,
|
118
|
+
source: '/market',
|
119
|
+
},
|
110
120
|
{
|
111
121
|
destination: '/settings/common',
|
112
122
|
permanent: true,
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.19.
|
3
|
+
"version": "1.19.4",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
5
5
|
"keywords": [
|
6
6
|
"framework",
|
@@ -29,11 +29,11 @@
|
|
29
29
|
"build": "next build",
|
30
30
|
"postbuild": "npm run build-sitemap && npm run build-migrate-db",
|
31
31
|
"build-migrate-db": "bun run db:migrate",
|
32
|
-
"build-sitemap": "
|
32
|
+
"build-sitemap": "tsx ./scripts/buildSitemapIndex/index.ts",
|
33
33
|
"build:analyze": "ANALYZE=true next build",
|
34
34
|
"build:docker": "DOCKER=true next build && npm run build-sitemap",
|
35
35
|
"db:generate": "drizzle-kit generate",
|
36
|
-
"db:migrate": "MIGRATION_DB=1 tsx scripts/migrateServerDB/index.ts",
|
36
|
+
"db:migrate": "MIGRATION_DB=1 tsx ./scripts/migrateServerDB/index.ts",
|
37
37
|
"db:push": "drizzle-kit push",
|
38
38
|
"db:push-test": "NODE_ENV=test drizzle-kit push",
|
39
39
|
"db:studio": "drizzle-kit studio",
|
@@ -65,11 +65,11 @@
|
|
65
65
|
"test:update": "vitest -u",
|
66
66
|
"type-check": "tsc --noEmit",
|
67
67
|
"webhook:ngrok": "ngrok http http://localhost:3011",
|
68
|
-
"workflow:docs": "tsx scripts/docsWorkflow/index.ts",
|
69
|
-
"workflow:i18n": "tsx scripts/i18nWorkflow/index.ts",
|
68
|
+
"workflow:docs": "tsx ./scripts/docsWorkflow/index.ts",
|
69
|
+
"workflow:i18n": "tsx ./scripts/i18nWorkflow/index.ts",
|
70
70
|
"workflow:mdx": "tsx ./scripts/mdxWorkflow/index.ts",
|
71
71
|
"workflow:mdx-with-lint": "tsx ./scripts/mdxWorkflow/index.ts && eslint \"docs/**/*.mdx\" --quiet --fix",
|
72
|
-
"workflow:readme": "tsx scripts/readmeWorkflow/index.ts"
|
72
|
+
"workflow:readme": "tsx ./scripts/readmeWorkflow/index.ts"
|
73
73
|
},
|
74
74
|
"lint-staged": {
|
75
75
|
"*.md": [
|
@@ -172,7 +172,6 @@
|
|
172
172
|
"next": "14.2.8",
|
173
173
|
"next-auth": "beta",
|
174
174
|
"next-mdx-remote": "^4.4.1",
|
175
|
-
"next-sitemap": "^4.2.3",
|
176
175
|
"nextjs-toploader": "^3.6.15",
|
177
176
|
"numeral": "^2.0.6",
|
178
177
|
"nuqs": "^1.17.8",
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { writeFileSync } from 'node:fs';
|
2
|
+
import { resolve } from 'node:path';
|
3
|
+
|
4
|
+
import { sitemapModule } from '@/server/sitemap';
|
5
|
+
|
6
|
+
const genSitemap = () => {
|
7
|
+
const sitemapIndexXML = sitemapModule.getIndex();
|
8
|
+
const filename = resolve(__dirname, '../../', 'public', 'sitemap-index.xml');
|
9
|
+
writeFileSync(filename, sitemapIndexXML);
|
10
|
+
};
|
11
|
+
|
12
|
+
genSitemap();
|
@@ -100,6 +100,7 @@ const Page = async ({ params, searchParams }: Props) => {
|
|
100
100
|
mobile={mobile}
|
101
101
|
sidebar={<InfoSidebar data={data} identifier={identifier} mobile={mobile} />}
|
102
102
|
/* ↓ cloud slot ↓ */
|
103
|
+
|
103
104
|
/* ↑ cloud slot ↑ */
|
104
105
|
>
|
105
106
|
<ProviderList data={providerData} identifier={identifier} mobile={mobile} />
|
@@ -102,6 +102,7 @@ const Page = async ({ params, searchParams }: Props) => {
|
|
102
102
|
mobile={mobile}
|
103
103
|
sidebar={<InfoSidebar data={data} identifier={identifier} />}
|
104
104
|
/* ↓ cloud slot ↓ */
|
105
|
+
|
105
106
|
/* ↑ cloud slot ↑ */
|
106
107
|
>
|
107
108
|
<ModelList identifier={identifier} mobile={mobile} modelData={modelData} />
|
package/src/app/page.tsx
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
import { MetadataRoute } from 'next';
|
2
|
+
|
3
|
+
import { sitemapModule } from '@/server/sitemap';
|
4
|
+
import { getCanonicalUrl } from '@/server/utils/url';
|
5
|
+
|
6
|
+
export default function robots(): MetadataRoute.Robots {
|
7
|
+
return {
|
8
|
+
host: getCanonicalUrl(),
|
9
|
+
rules: {
|
10
|
+
allow: ['/'],
|
11
|
+
disallow: ['/api/*'],
|
12
|
+
userAgent: '*',
|
13
|
+
},
|
14
|
+
sitemap: sitemapModule.getRobots(),
|
15
|
+
};
|
16
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { MetadataRoute } from 'next';
|
2
|
+
|
3
|
+
import { SitemapType, sitemapModule } from '@/server/sitemap';
|
4
|
+
|
5
|
+
export const generateSitemaps = async () => {
|
6
|
+
// Fetch the total number of products and calculate the number of sitemaps needed
|
7
|
+
return sitemapModule.sitemapIndexs;
|
8
|
+
};
|
9
|
+
|
10
|
+
const Sitemap = async ({ id }: { id: SitemapType }): Promise<MetadataRoute.Sitemap> => {
|
11
|
+
switch (id) {
|
12
|
+
case SitemapType.Pages: {
|
13
|
+
return sitemapModule.getPage();
|
14
|
+
}
|
15
|
+
case SitemapType.Assistants: {
|
16
|
+
return sitemapModule.getAssistants();
|
17
|
+
}
|
18
|
+
case SitemapType.Plugins: {
|
19
|
+
return sitemapModule.getPlugins();
|
20
|
+
}
|
21
|
+
case SitemapType.Models: {
|
22
|
+
return sitemapModule.getModels();
|
23
|
+
}
|
24
|
+
case SitemapType.Providers: {
|
25
|
+
return sitemapModule.getProviders();
|
26
|
+
}
|
27
|
+
}
|
28
|
+
};
|
29
|
+
|
30
|
+
export default Sitemap;
|
package/src/const/url.ts
CHANGED
@@ -2,6 +2,7 @@ import qs from 'query-string';
|
|
2
2
|
import urlJoin from 'url-join';
|
3
3
|
|
4
4
|
import { withBasePath } from '@/utils/basePath';
|
5
|
+
import { isDev } from '@/utils/env';
|
5
6
|
|
6
7
|
import pkg from '../../package.json';
|
7
8
|
import { INBOX_SESSION_ID } from './session';
|
@@ -12,8 +13,6 @@ export const OFFICIAL_URL = 'https://lobechat.com/';
|
|
12
13
|
export const OFFICIAL_PREVIEW_URL = 'https://chat-preview.lobehub.com/';
|
13
14
|
export const OFFICIAL_SITE = 'https://lobehub.com/';
|
14
15
|
|
15
|
-
export const getCanonicalUrl = (path: string) => urlJoin(OFFICIAL_URL, path);
|
16
|
-
|
17
16
|
export const OG_URL = '/og/cover.png?v=1';
|
18
17
|
|
19
18
|
export const GITHUB = pkg.homepage;
|
@@ -73,3 +72,4 @@ export const mailTo = (email: string) => `mailto:${email}`;
|
|
73
72
|
|
74
73
|
export const AES_GCM_URL = 'https://datatracker.ietf.org/doc/html/draft-ietf-avt-srtp-aes-gcm-01';
|
75
74
|
export const BASE_PROVIDER_DOC_URL = 'https://lobehub.com/docs/usage/providers';
|
75
|
+
export const SITEMAP_BASE_URL = isDev ? '/sitemap.xml/' : 'sitemap';
|
@@ -0,0 +1,102 @@
|
|
1
|
+
// @vitest-environment node
|
2
|
+
import { describe, expect, it } from 'vitest';
|
3
|
+
|
4
|
+
import { DEFAULT_LANG } from '@/const/locale';
|
5
|
+
|
6
|
+
import { AUTHOR_LIST, Ld } from './ld';
|
7
|
+
|
8
|
+
describe('Ld', () => {
|
9
|
+
const ld = new Ld();
|
10
|
+
|
11
|
+
describe('generate', () => {
|
12
|
+
it('should generate correct LD+JSON structure', () => {
|
13
|
+
const result = ld.generate({
|
14
|
+
title: 'Test Title',
|
15
|
+
description: 'Test Description',
|
16
|
+
url: 'https://example.com/test',
|
17
|
+
locale: DEFAULT_LANG,
|
18
|
+
});
|
19
|
+
|
20
|
+
expect(result['@context']).toBe('https://schema.org');
|
21
|
+
expect(Array.isArray(result['@graph'])).toBe(true);
|
22
|
+
expect(result['@graph'].length).toBeGreaterThan(0);
|
23
|
+
});
|
24
|
+
});
|
25
|
+
|
26
|
+
describe('genOrganization', () => {
|
27
|
+
it('should generate correct organization structure', () => {
|
28
|
+
const org = ld.genOrganization();
|
29
|
+
|
30
|
+
expect(org['@type']).toBe('Organization');
|
31
|
+
expect(org.name).toBe('LobeHub');
|
32
|
+
expect(org.url).toBe('https://lobehub.com/');
|
33
|
+
});
|
34
|
+
});
|
35
|
+
|
36
|
+
describe('getAuthors', () => {
|
37
|
+
it('should return default author when no ids provided', () => {
|
38
|
+
const author = ld.getAuthors();
|
39
|
+
expect(author['@type']).toBe('Organization');
|
40
|
+
});
|
41
|
+
|
42
|
+
it('should return person when valid id provided', () => {
|
43
|
+
const author = ld.getAuthors(['arvinxx']);
|
44
|
+
expect(author['@type']).toBe('Person');
|
45
|
+
// @ts-ignore
|
46
|
+
expect(author.name).toBe(AUTHOR_LIST.arvinxx.name);
|
47
|
+
});
|
48
|
+
});
|
49
|
+
|
50
|
+
describe('genWebPage', () => {
|
51
|
+
it('should generate correct webpage structure', () => {
|
52
|
+
const webpage = ld.genWebPage({
|
53
|
+
title: 'Test Page',
|
54
|
+
description: 'Test Description',
|
55
|
+
url: 'https://example.com/test',
|
56
|
+
locale: DEFAULT_LANG,
|
57
|
+
});
|
58
|
+
|
59
|
+
expect(webpage['@type']).toBe('WebPage');
|
60
|
+
expect(webpage.name).toBe('Test Page · LobeChat');
|
61
|
+
expect(webpage.description).toBe('Test Description');
|
62
|
+
});
|
63
|
+
});
|
64
|
+
|
65
|
+
describe('genImageObject', () => {
|
66
|
+
it('should generate correct image object', () => {
|
67
|
+
const image = ld.genImageObject({
|
68
|
+
image: 'https://example.com/image.jpg',
|
69
|
+
url: 'https://example.com/test',
|
70
|
+
});
|
71
|
+
|
72
|
+
expect(image['@type']).toBe('ImageObject');
|
73
|
+
expect(image.url).toBe('https://example.com/image.jpg');
|
74
|
+
});
|
75
|
+
});
|
76
|
+
|
77
|
+
describe('genWebSite', () => {
|
78
|
+
it('should generate correct website structure', () => {
|
79
|
+
const website = ld.genWebSite();
|
80
|
+
|
81
|
+
expect(website['@type']).toBe('WebSite');
|
82
|
+
expect(website.name).toBe('LobeChat');
|
83
|
+
});
|
84
|
+
});
|
85
|
+
|
86
|
+
describe('genArticle', () => {
|
87
|
+
it('should generate correct article structure', () => {
|
88
|
+
const article = ld.genArticle({
|
89
|
+
title: 'Test Article',
|
90
|
+
description: 'Test Description',
|
91
|
+
url: 'https://example.com/test',
|
92
|
+
author: ['arvinxx'],
|
93
|
+
identifier: 'test-id',
|
94
|
+
locale: DEFAULT_LANG,
|
95
|
+
});
|
96
|
+
|
97
|
+
expect(article['@type']).toBe('Article');
|
98
|
+
expect(article.headline).toBe('Test Article · LobeChat');
|
99
|
+
expect(article.author['@type']).toBe('Person');
|
100
|
+
});
|
101
|
+
});
|
102
|
+
});
|
package/src/server/ld.ts
CHANGED
@@ -3,15 +3,9 @@ import urlJoin from 'url-join';
|
|
3
3
|
|
4
4
|
import { BRANDING_NAME } from '@/const/branding';
|
5
5
|
import { DEFAULT_LANG } from '@/const/locale';
|
6
|
-
import {
|
7
|
-
EMAIL_BUSINESS,
|
8
|
-
EMAIL_SUPPORT,
|
9
|
-
OFFICIAL_SITE,
|
10
|
-
OFFICIAL_URL,
|
11
|
-
X,
|
12
|
-
getCanonicalUrl,
|
13
|
-
} from '@/const/url';
|
6
|
+
import { EMAIL_BUSINESS, EMAIL_SUPPORT, OFFICIAL_SITE, OFFICIAL_URL, X } from '@/const/url';
|
14
7
|
import { Locales } from '@/locales/resources';
|
8
|
+
import { getCanonicalUrl } from '@/server/utils/url';
|
15
9
|
|
16
10
|
import pkg from '../../package.json';
|
17
11
|
|
@@ -37,7 +31,7 @@ export const AUTHOR_LIST = {
|
|
37
31
|
},
|
38
32
|
};
|
39
33
|
|
40
|
-
class Ld {
|
34
|
+
export class Ld {
|
41
35
|
generate({
|
42
36
|
image = '/og/cover.png',
|
43
37
|
article,
|