@jant/core 0.3.6 → 0.3.8
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/dist/app.js +11 -21
- package/dist/client.js +1 -0
- package/dist/db/schema.js +15 -0
- package/dist/i18n/locales/en.js +1 -1
- package/dist/i18n/locales/zh-Hans.js +1 -1
- package/dist/i18n/locales/zh-Hant.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/image.js +3 -3
- package/dist/lib/media-helpers.js +43 -0
- package/dist/lib/nav-reorder.js +27 -0
- package/dist/lib/navigation.js +35 -0
- package/dist/lib/schemas.js +32 -2
- package/dist/lib/sse.js +7 -8
- package/dist/lib/theme-components.js +49 -0
- package/dist/routes/api/posts.js +101 -5
- package/dist/routes/api/timeline.js +115 -0
- package/dist/routes/api/upload.js +9 -5
- package/dist/routes/dash/media.js +38 -0
- package/dist/routes/dash/navigation.js +274 -0
- package/dist/routes/dash/posts.js +45 -6
- package/dist/routes/feed/rss.js +10 -1
- package/dist/routes/pages/archive.js +14 -27
- package/dist/routes/pages/collection.js +10 -19
- package/dist/routes/pages/home.js +88 -98
- package/dist/routes/pages/page.js +19 -38
- package/dist/routes/pages/post.js +61 -48
- package/dist/routes/pages/search.js +13 -26
- package/dist/services/collection.js +13 -0
- package/dist/services/index.js +3 -1
- package/dist/services/media.js +55 -2
- package/dist/services/navigation.js +115 -0
- package/dist/services/post.js +26 -1
- package/dist/theme/components/MediaGallery.js +107 -0
- package/dist/theme/components/PostForm.js +158 -2
- package/dist/theme/components/PostList.js +5 -0
- package/dist/theme/components/index.js +3 -0
- package/dist/theme/components/timeline/ArticleCard.js +50 -0
- package/dist/theme/components/timeline/ImageCard.js +86 -0
- package/dist/theme/components/timeline/LinkCard.js +62 -0
- package/dist/theme/components/timeline/NoteCard.js +37 -0
- package/dist/theme/components/timeline/QuoteCard.js +51 -0
- package/dist/theme/components/timeline/ThreadPreview.js +52 -0
- package/dist/theme/components/timeline/TimelineFeed.js +43 -0
- package/dist/theme/components/timeline/TimelineItem.js +25 -0
- package/dist/theme/components/timeline/index.js +8 -0
- package/dist/theme/layouts/DashLayout.js +8 -0
- package/dist/theme/layouts/SiteLayout.js +160 -0
- package/dist/theme/layouts/index.js +1 -0
- package/dist/types/sortablejs.d.js +5 -0
- package/dist/types.js +27 -0
- package/package.json +3 -2
- package/src/__tests__/helpers/app.ts +6 -1
- package/src/__tests__/helpers/db.ts +20 -0
- package/src/app.tsx +11 -25
- package/src/client.ts +1 -0
- package/src/db/migrations/0002_add_media_attachments.sql +3 -0
- package/src/db/migrations/0003_add_navigation_links.sql +8 -0
- package/src/db/migrations/meta/0003_snapshot.json +821 -0
- package/src/db/migrations/meta/_journal.json +14 -0
- package/src/db/schema.ts +15 -0
- package/src/i18n/locales/en.po +170 -58
- package/src/i18n/locales/en.ts +1 -1
- package/src/i18n/locales/zh-Hans.po +162 -71
- package/src/i18n/locales/zh-Hans.ts +1 -1
- package/src/i18n/locales/zh-Hant.po +162 -71
- package/src/i18n/locales/zh-Hant.ts +1 -1
- package/src/index.ts +13 -1
- package/src/lib/__tests__/schemas.test.ts +89 -1
- package/src/lib/__tests__/sse.test.ts +13 -1
- package/src/lib/__tests__/theme-components.test.ts +107 -0
- package/src/lib/image.ts +3 -3
- package/src/lib/media-helpers.ts +54 -0
- package/src/lib/nav-reorder.ts +26 -0
- package/src/lib/navigation.ts +46 -0
- package/src/lib/schemas.ts +47 -1
- package/src/lib/sse.ts +10 -11
- package/src/lib/theme-components.ts +76 -0
- package/src/routes/api/__tests__/posts.test.ts +239 -0
- package/src/routes/api/__tests__/timeline.test.ts +242 -0
- package/src/routes/api/posts.ts +134 -5
- package/src/routes/api/timeline.tsx +145 -0
- package/src/routes/api/upload.ts +9 -5
- package/src/routes/dash/media.tsx +50 -0
- package/src/routes/dash/navigation.tsx +306 -0
- package/src/routes/dash/posts.tsx +79 -7
- package/src/routes/feed/rss.ts +14 -1
- package/src/routes/pages/archive.tsx +15 -23
- package/src/routes/pages/collection.tsx +8 -15
- package/src/routes/pages/home.tsx +121 -88
- package/src/routes/pages/page.tsx +17 -30
- package/src/routes/pages/post.tsx +64 -40
- package/src/routes/pages/search.tsx +18 -22
- package/src/services/__tests__/collection.test.ts +102 -0
- package/src/services/__tests__/media.test.ts +282 -7
- package/src/services/__tests__/navigation.test.ts +213 -0
- package/src/services/__tests__/post-timeline.test.ts +220 -0
- package/src/services/collection.ts +19 -0
- package/src/services/index.ts +7 -0
- package/src/services/media.ts +78 -2
- package/src/services/navigation.ts +165 -0
- package/src/services/post.ts +48 -1
- package/src/styles/components.css +59 -0
- package/src/theme/components/MediaGallery.tsx +128 -0
- package/src/theme/components/PostForm.tsx +170 -2
- package/src/theme/components/PostList.tsx +7 -0
- package/src/theme/components/index.ts +13 -0
- package/src/theme/components/timeline/ArticleCard.tsx +57 -0
- package/src/theme/components/timeline/ImageCard.tsx +80 -0
- package/src/theme/components/timeline/LinkCard.tsx +66 -0
- package/src/theme/components/timeline/NoteCard.tsx +41 -0
- package/src/theme/components/timeline/QuoteCard.tsx +55 -0
- package/src/theme/components/timeline/ThreadPreview.tsx +49 -0
- package/src/theme/components/timeline/TimelineFeed.tsx +52 -0
- package/src/theme/components/timeline/TimelineItem.tsx +39 -0
- package/src/theme/components/timeline/index.ts +8 -0
- package/src/theme/layouts/DashLayout.tsx +10 -0
- package/src/theme/layouts/SiteLayout.tsx +184 -0
- package/src/theme/layouts/index.ts +1 -0
- package/src/types/sortablejs.d.ts +23 -0
- package/src/types.ts +97 -0
- package/dist/app.d.ts +0 -38
- package/dist/app.d.ts.map +0 -1
- package/dist/auth.d.ts +0 -25
- package/dist/auth.d.ts.map +0 -1
- package/dist/db/index.d.ts +0 -10
- package/dist/db/index.d.ts.map +0 -1
- package/dist/db/schema.d.ts +0 -1507
- package/dist/db/schema.d.ts.map +0 -1
- package/dist/i18n/Trans.d.ts +0 -25
- package/dist/i18n/Trans.d.ts.map +0 -1
- package/dist/i18n/context.d.ts +0 -69
- package/dist/i18n/context.d.ts.map +0 -1
- package/dist/i18n/detect.d.ts +0 -20
- package/dist/i18n/detect.d.ts.map +0 -1
- package/dist/i18n/i18n.d.ts +0 -32
- package/dist/i18n/i18n.d.ts.map +0 -1
- package/dist/i18n/index.d.ts +0 -41
- package/dist/i18n/index.d.ts.map +0 -1
- package/dist/i18n/locales/en.d.ts +0 -3
- package/dist/i18n/locales/en.d.ts.map +0 -1
- package/dist/i18n/locales/zh-Hans.d.ts +0 -3
- package/dist/i18n/locales/zh-Hans.d.ts.map +0 -1
- package/dist/i18n/locales/zh-Hant.d.ts +0 -3
- package/dist/i18n/locales/zh-Hant.d.ts.map +0 -1
- package/dist/i18n/locales.d.ts +0 -11
- package/dist/i18n/locales.d.ts.map +0 -1
- package/dist/i18n/middleware.d.ts +0 -21
- package/dist/i18n/middleware.d.ts.map +0 -1
- package/dist/index.d.ts +0 -16
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/config.d.ts +0 -83
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/constants.d.ts +0 -37
- package/dist/lib/constants.d.ts.map +0 -1
- package/dist/lib/image.d.ts +0 -73
- package/dist/lib/image.d.ts.map +0 -1
- package/dist/lib/index.d.ts +0 -9
- package/dist/lib/index.d.ts.map +0 -1
- package/dist/lib/markdown.d.ts +0 -60
- package/dist/lib/markdown.d.ts.map +0 -1
- package/dist/lib/schemas.d.ts +0 -113
- package/dist/lib/schemas.d.ts.map +0 -1
- package/dist/lib/sqid.d.ts +0 -60
- package/dist/lib/sqid.d.ts.map +0 -1
- package/dist/lib/sse.d.ts +0 -192
- package/dist/lib/sse.d.ts.map +0 -1
- package/dist/lib/theme.d.ts +0 -44
- package/dist/lib/theme.d.ts.map +0 -1
- package/dist/lib/time.d.ts +0 -90
- package/dist/lib/time.d.ts.map +0 -1
- package/dist/lib/url.d.ts +0 -82
- package/dist/lib/url.d.ts.map +0 -1
- package/dist/middleware/auth.d.ts +0 -24
- package/dist/middleware/auth.d.ts.map +0 -1
- package/dist/middleware/onboarding.d.ts +0 -26
- package/dist/middleware/onboarding.d.ts.map +0 -1
- package/dist/routes/api/posts.d.ts +0 -13
- package/dist/routes/api/posts.d.ts.map +0 -1
- package/dist/routes/api/search.d.ts +0 -13
- package/dist/routes/api/search.d.ts.map +0 -1
- package/dist/routes/api/upload.d.ts +0 -16
- package/dist/routes/api/upload.d.ts.map +0 -1
- package/dist/routes/dash/collections.d.ts +0 -13
- package/dist/routes/dash/collections.d.ts.map +0 -1
- package/dist/routes/dash/index.d.ts +0 -15
- package/dist/routes/dash/index.d.ts.map +0 -1
- package/dist/routes/dash/media.d.ts +0 -16
- package/dist/routes/dash/media.d.ts.map +0 -1
- package/dist/routes/dash/pages.d.ts +0 -15
- package/dist/routes/dash/pages.d.ts.map +0 -1
- package/dist/routes/dash/posts.d.ts +0 -13
- package/dist/routes/dash/posts.d.ts.map +0 -1
- package/dist/routes/dash/redirects.d.ts +0 -13
- package/dist/routes/dash/redirects.d.ts.map +0 -1
- package/dist/routes/dash/settings.d.ts +0 -15
- package/dist/routes/dash/settings.d.ts.map +0 -1
- package/dist/routes/feed/rss.d.ts +0 -13
- package/dist/routes/feed/rss.d.ts.map +0 -1
- package/dist/routes/feed/sitemap.d.ts +0 -13
- package/dist/routes/feed/sitemap.d.ts.map +0 -1
- package/dist/routes/pages/archive.d.ts +0 -15
- package/dist/routes/pages/archive.d.ts.map +0 -1
- package/dist/routes/pages/collection.d.ts +0 -13
- package/dist/routes/pages/collection.d.ts.map +0 -1
- package/dist/routes/pages/home.d.ts +0 -13
- package/dist/routes/pages/home.d.ts.map +0 -1
- package/dist/routes/pages/page.d.ts +0 -15
- package/dist/routes/pages/page.d.ts.map +0 -1
- package/dist/routes/pages/post.d.ts +0 -13
- package/dist/routes/pages/post.d.ts.map +0 -1
- package/dist/routes/pages/search.d.ts +0 -13
- package/dist/routes/pages/search.d.ts.map +0 -1
- package/dist/services/collection.d.ts +0 -31
- package/dist/services/collection.d.ts.map +0 -1
- package/dist/services/index.d.ts +0 -28
- package/dist/services/index.d.ts.map +0 -1
- package/dist/services/media.d.ts +0 -27
- package/dist/services/media.d.ts.map +0 -1
- package/dist/services/post.d.ts +0 -31
- package/dist/services/post.d.ts.map +0 -1
- package/dist/services/redirect.d.ts +0 -15
- package/dist/services/redirect.d.ts.map +0 -1
- package/dist/services/search.d.ts +0 -26
- package/dist/services/search.d.ts.map +0 -1
- package/dist/services/settings.d.ts +0 -18
- package/dist/services/settings.d.ts.map +0 -1
- package/dist/theme/color-themes.d.ts +0 -30
- package/dist/theme/color-themes.d.ts.map +0 -1
- package/dist/theme/components/ActionButtons.d.ts +0 -43
- package/dist/theme/components/ActionButtons.d.ts.map +0 -1
- package/dist/theme/components/CrudPageHeader.d.ts +0 -23
- package/dist/theme/components/CrudPageHeader.d.ts.map +0 -1
- package/dist/theme/components/DangerZone.d.ts +0 -36
- package/dist/theme/components/DangerZone.d.ts.map +0 -1
- package/dist/theme/components/EmptyState.d.ts +0 -27
- package/dist/theme/components/EmptyState.d.ts.map +0 -1
- package/dist/theme/components/ListItemRow.d.ts +0 -15
- package/dist/theme/components/ListItemRow.d.ts.map +0 -1
- package/dist/theme/components/PageForm.d.ts +0 -14
- package/dist/theme/components/PageForm.d.ts.map +0 -1
- package/dist/theme/components/Pagination.d.ts +0 -46
- package/dist/theme/components/Pagination.d.ts.map +0 -1
- package/dist/theme/components/PostForm.d.ts +0 -11
- package/dist/theme/components/PostForm.d.ts.map +0 -1
- package/dist/theme/components/PostList.d.ts +0 -10
- package/dist/theme/components/PostList.d.ts.map +0 -1
- package/dist/theme/components/ThreadView.d.ts +0 -15
- package/dist/theme/components/ThreadView.d.ts.map +0 -1
- package/dist/theme/components/TypeBadge.d.ts +0 -12
- package/dist/theme/components/TypeBadge.d.ts.map +0 -1
- package/dist/theme/components/VisibilityBadge.d.ts +0 -12
- package/dist/theme/components/VisibilityBadge.d.ts.map +0 -1
- package/dist/theme/components/index.d.ts +0 -13
- package/dist/theme/components/index.d.ts.map +0 -1
- package/dist/theme/index.d.ts +0 -21
- package/dist/theme/index.d.ts.map +0 -1
- package/dist/theme/layouts/BaseLayout.d.ts +0 -23
- package/dist/theme/layouts/BaseLayout.d.ts.map +0 -1
- package/dist/theme/layouts/DashLayout.d.ts +0 -17
- package/dist/theme/layouts/DashLayout.d.ts.map +0 -1
- package/dist/theme/layouts/index.d.ts +0 -3
- package/dist/theme/layouts/index.d.ts.map +0 -1
- package/dist/types.d.ts +0 -213
- package/dist/types.d.ts.map +0 -1
|
@@ -30,7 +30,7 @@ function PostsListContent({ posts }) {
|
|
|
30
30
|
]
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
|
-
function NewPostContent() {
|
|
33
|
+
function NewPostContent({ collections }) {
|
|
34
34
|
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
35
35
|
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
36
36
|
children: [
|
|
@@ -42,7 +42,8 @@ function NewPostContent() {
|
|
|
42
42
|
})
|
|
43
43
|
}),
|
|
44
44
|
/*#__PURE__*/ _jsx(PostForm, {
|
|
45
|
-
action: "/dash/posts"
|
|
45
|
+
action: "/dash/posts",
|
|
46
|
+
collections: collections
|
|
46
47
|
})
|
|
47
48
|
]
|
|
48
49
|
});
|
|
@@ -71,12 +72,15 @@ postsRoutes.get("/", async (c)=>{
|
|
|
71
72
|
// New post form
|
|
72
73
|
postsRoutes.get("/new", async (c)=>{
|
|
73
74
|
const siteName = await getSiteName(c);
|
|
75
|
+
const collections = await c.var.services.collections.list();
|
|
74
76
|
return c.html(/*#__PURE__*/ _jsx(DashLayout, {
|
|
75
77
|
c: c,
|
|
76
78
|
title: "New Post",
|
|
77
79
|
siteName: siteName,
|
|
78
80
|
currentPath: "/dash/posts",
|
|
79
|
-
children: /*#__PURE__*/ _jsx(NewPostContent, {
|
|
81
|
+
children: /*#__PURE__*/ _jsx(NewPostContent, {
|
|
82
|
+
collections: collections
|
|
83
|
+
})
|
|
80
84
|
}));
|
|
81
85
|
});
|
|
82
86
|
// Create post
|
|
@@ -88,8 +92,17 @@ postsRoutes.post("/", async (c)=>{
|
|
|
88
92
|
content: body.content,
|
|
89
93
|
visibility: body.visibility,
|
|
90
94
|
sourceUrl: body.sourceUrl || undefined,
|
|
95
|
+
sourceName: body.sourceName || undefined,
|
|
91
96
|
path: body.path || undefined
|
|
92
97
|
});
|
|
98
|
+
// Attach media if provided
|
|
99
|
+
if (body.mediaIds && body.mediaIds.length > 0) {
|
|
100
|
+
await c.var.services.media.attachToPost(post.id, body.mediaIds);
|
|
101
|
+
}
|
|
102
|
+
// Sync collection associations
|
|
103
|
+
if (body.collectionIds) {
|
|
104
|
+
await c.var.services.collections.syncPostCollections(post.id, body.collectionIds);
|
|
105
|
+
}
|
|
93
106
|
return dsRedirect(`/dash/posts/${sqid.encode(post.id)}`);
|
|
94
107
|
});
|
|
95
108
|
function ViewPostContent({ post }) {
|
|
@@ -135,7 +148,7 @@ function ViewPostContent({ post }) {
|
|
|
135
148
|
]
|
|
136
149
|
});
|
|
137
150
|
}
|
|
138
|
-
function EditPostContent({ post }) {
|
|
151
|
+
function EditPostContent({ post, mediaAttachments, r2PublicUrl, imageTransformUrl, collections, postCollectionIds }) {
|
|
139
152
|
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
140
153
|
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
141
154
|
children: [
|
|
@@ -148,7 +161,12 @@ function EditPostContent({ post }) {
|
|
|
148
161
|
}),
|
|
149
162
|
/*#__PURE__*/ _jsx(PostForm, {
|
|
150
163
|
post: post,
|
|
151
|
-
action: `/dash/posts/${sqid.encode(post.id)}
|
|
164
|
+
action: `/dash/posts/${sqid.encode(post.id)}`,
|
|
165
|
+
mediaAttachments: mediaAttachments,
|
|
166
|
+
r2PublicUrl: r2PublicUrl,
|
|
167
|
+
imageTransformUrl: imageTransformUrl,
|
|
168
|
+
collections: collections,
|
|
169
|
+
postCollectionIds: postCollectionIds
|
|
152
170
|
})
|
|
153
171
|
]
|
|
154
172
|
});
|
|
@@ -178,13 +196,24 @@ postsRoutes.get("/:id/edit", async (c)=>{
|
|
|
178
196
|
const post = await c.var.services.posts.getById(id);
|
|
179
197
|
if (!post) return c.notFound();
|
|
180
198
|
const siteName = await getSiteName(c);
|
|
199
|
+
const mediaAttachments = await c.var.services.media.getByPostId(post.id);
|
|
200
|
+
const r2PublicUrl = c.env.R2_PUBLIC_URL;
|
|
201
|
+
const imageTransformUrl = c.env.IMAGE_TRANSFORM_URL;
|
|
202
|
+
const collections = await c.var.services.collections.list();
|
|
203
|
+
const postCollections = await c.var.services.collections.getCollectionsForPost(post.id);
|
|
204
|
+
const postCollectionIds = postCollections.map((col)=>col.id);
|
|
181
205
|
return c.html(/*#__PURE__*/ _jsx(DashLayout, {
|
|
182
206
|
c: c,
|
|
183
207
|
title: `Edit: ${post.title || "Post"}`,
|
|
184
208
|
siteName: siteName,
|
|
185
209
|
currentPath: "/dash/posts",
|
|
186
210
|
children: /*#__PURE__*/ _jsx(EditPostContent, {
|
|
187
|
-
post: post
|
|
211
|
+
post: post,
|
|
212
|
+
mediaAttachments: mediaAttachments,
|
|
213
|
+
r2PublicUrl: r2PublicUrl,
|
|
214
|
+
imageTransformUrl: imageTransformUrl,
|
|
215
|
+
collections: collections,
|
|
216
|
+
postCollectionIds: postCollectionIds
|
|
188
217
|
})
|
|
189
218
|
}));
|
|
190
219
|
});
|
|
@@ -199,14 +228,24 @@ postsRoutes.post("/:id", async (c)=>{
|
|
|
199
228
|
content: body.content || null,
|
|
200
229
|
visibility: body.visibility,
|
|
201
230
|
sourceUrl: body.sourceUrl || null,
|
|
231
|
+
sourceName: body.sourceName || null,
|
|
202
232
|
path: body.path || null
|
|
203
233
|
});
|
|
234
|
+
// Update media attachments if provided
|
|
235
|
+
if (body.mediaIds !== undefined) {
|
|
236
|
+
await c.var.services.media.attachToPost(id, body.mediaIds);
|
|
237
|
+
}
|
|
238
|
+
// Sync collection associations
|
|
239
|
+
if (body.collectionIds !== undefined) {
|
|
240
|
+
await c.var.services.collections.syncPostCollections(id, body.collectionIds);
|
|
241
|
+
}
|
|
204
242
|
return dsRedirect(`/dash/posts/${sqid.encode(id)}`);
|
|
205
243
|
});
|
|
206
244
|
// Delete post
|
|
207
245
|
postsRoutes.post("/:id/delete", async (c)=>{
|
|
208
246
|
const id = sqid.decode(c.req.param("id"));
|
|
209
247
|
if (!id) return c.notFound();
|
|
248
|
+
await c.var.services.media.detachFromPost(id);
|
|
210
249
|
await c.var.services.posts.delete(id);
|
|
211
250
|
return dsRedirect("/dash/posts");
|
|
212
251
|
});
|
package/dist/routes/feed/rss.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/ import { Hono } from "hono";
|
|
4
4
|
import * as sqid from "../../lib/sqid.js";
|
|
5
5
|
import * as time from "../../lib/time.js";
|
|
6
|
+
import { getMediaUrl } from "../../lib/image.js";
|
|
6
7
|
export const rssRoutes = new Hono();
|
|
7
8
|
// RSS 2.0 Feed - main feed at /feed
|
|
8
9
|
rssRoutes.get("/", async (c)=>{
|
|
@@ -10,6 +11,7 @@ rssRoutes.get("/", async (c)=>{
|
|
|
10
11
|
const siteName = all["SITE_NAME"] ?? "Jant";
|
|
11
12
|
const siteDescription = all["SITE_DESCRIPTION"] ?? "";
|
|
12
13
|
const siteUrl = c.env.SITE_URL;
|
|
14
|
+
const r2PublicUrl = c.env.R2_PUBLIC_URL;
|
|
13
15
|
const posts = await c.var.services.posts.list({
|
|
14
16
|
visibility: [
|
|
15
17
|
"featured",
|
|
@@ -17,17 +19,24 @@ rssRoutes.get("/", async (c)=>{
|
|
|
17
19
|
],
|
|
18
20
|
limit: 50
|
|
19
21
|
});
|
|
22
|
+
// Batch load media for enclosures
|
|
23
|
+
const postIds = posts.map((p)=>p.id);
|
|
24
|
+
const mediaMap = await c.var.services.media.getByPostIds(postIds);
|
|
20
25
|
const items = posts.map((post)=>{
|
|
21
26
|
const link = `${siteUrl}/p/${sqid.encode(post.id)}`;
|
|
22
27
|
const title = post.title || `Post #${post.id}`;
|
|
23
28
|
const pubDate = new Date(post.publishedAt * 1000).toUTCString();
|
|
29
|
+
// Add enclosure for first media attachment
|
|
30
|
+
const postMedia = mediaMap.get(post.id);
|
|
31
|
+
const firstMedia = postMedia?.[0];
|
|
32
|
+
const enclosure = firstMedia ? `\n <enclosure url="${getMediaUrl(firstMedia.id, firstMedia.r2Key, r2PublicUrl)}" length="${firstMedia.size}" type="${firstMedia.mimeType}"/>` : "";
|
|
24
33
|
return `
|
|
25
34
|
<item>
|
|
26
35
|
<title><![CDATA[${escapeXml(title)}]]></title>
|
|
27
36
|
<link>${link}</link>
|
|
28
37
|
<guid isPermaLink="true">${link}</guid>
|
|
29
38
|
<pubDate>${pubDate}</pubDate>
|
|
30
|
-
<description><![CDATA[${post.contentHtml || ""}]]></description
|
|
39
|
+
<description><![CDATA[${post.contentHtml || ""}]]></description>${enclosure}
|
|
31
40
|
</item>`;
|
|
32
41
|
}).join("");
|
|
33
42
|
const rss = `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
2
|
-
import { getSiteName } from "../../lib/config.js";
|
|
3
2
|
/**
|
|
4
3
|
* Archive Page Route
|
|
5
4
|
*
|
|
6
5
|
* Shows all posts, optionally filtered by type
|
|
7
6
|
*/ import { Hono } from "hono";
|
|
8
7
|
import { useLingui as $_useLingui } from "@jant/core/i18n";
|
|
9
|
-
import { BaseLayout } from "../../theme/layouts/index.js";
|
|
8
|
+
import { BaseLayout, SiteLayout } from "../../theme/layouts/index.js";
|
|
10
9
|
import { Pagination } from "../../theme/components/index.js";
|
|
11
10
|
import { POST_TYPES } from "../../types.js";
|
|
12
11
|
import * as sqid from "../../lib/sqid.js";
|
|
13
12
|
import * as time from "../../lib/time.js";
|
|
13
|
+
import { getNavigationData } from "../../lib/navigation.js";
|
|
14
14
|
const PAGE_SIZE = 50;
|
|
15
15
|
export const archiveRoutes = new Hono();
|
|
16
16
|
function getTypeLabel(type) {
|
|
@@ -89,7 +89,6 @@ function ArchiveContent({ displayPosts, hasMore, nextCursor, type, grouped, repl
|
|
|
89
89
|
message: "Archive"
|
|
90
90
|
});
|
|
91
91
|
return /*#__PURE__*/ _jsxs("div", {
|
|
92
|
-
class: "container py-8",
|
|
93
92
|
children: [
|
|
94
93
|
/*#__PURE__*/ _jsxs("header", {
|
|
95
94
|
class: "mb-8",
|
|
@@ -183,21 +182,6 @@ function ArchiveContent({ displayPosts, hasMore, nextCursor, type, grouped, repl
|
|
|
183
182
|
baseUrl: type ? `/archive?type=${type}` : "/archive",
|
|
184
183
|
hasMore: hasMore,
|
|
185
184
|
nextCursor: nextCursor
|
|
186
|
-
}),
|
|
187
|
-
/*#__PURE__*/ _jsx("nav", {
|
|
188
|
-
class: "mt-4",
|
|
189
|
-
children: /*#__PURE__*/ _jsxs("a", {
|
|
190
|
-
href: "/",
|
|
191
|
-
class: "text-sm hover:underline",
|
|
192
|
-
children: [
|
|
193
|
-
"←",
|
|
194
|
-
" ",
|
|
195
|
-
$__i18n._({
|
|
196
|
-
id: "x4RuFo",
|
|
197
|
-
message: "Back to home"
|
|
198
|
-
})
|
|
199
|
-
]
|
|
200
|
-
})
|
|
201
185
|
})
|
|
202
186
|
]
|
|
203
187
|
});
|
|
@@ -209,7 +193,7 @@ archiveRoutes.get("/", async (c)=>{
|
|
|
209
193
|
// Parse cursor
|
|
210
194
|
const cursorParam = c.req.query("cursor");
|
|
211
195
|
const cursor = cursorParam ? parseInt(cursorParam, 10) : undefined;
|
|
212
|
-
const
|
|
196
|
+
const navData = await getNavigationData(c);
|
|
213
197
|
// Fetch one extra to check for more
|
|
214
198
|
const posts = await c.var.services.posts.list({
|
|
215
199
|
type,
|
|
@@ -240,15 +224,18 @@ archiveRoutes.get("/", async (c)=>{
|
|
|
240
224
|
grouped.get(key).push(post);
|
|
241
225
|
}
|
|
242
226
|
return c.html(/*#__PURE__*/ _jsx(BaseLayout, {
|
|
243
|
-
title: `Archive - ${siteName}`,
|
|
227
|
+
title: `Archive - ${navData.siteName}`,
|
|
244
228
|
c: c,
|
|
245
|
-
children: /*#__PURE__*/ _jsx(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
229
|
+
children: /*#__PURE__*/ _jsx(SiteLayout, {
|
|
230
|
+
...navData,
|
|
231
|
+
children: /*#__PURE__*/ _jsx(ArchiveContent, {
|
|
232
|
+
displayPosts: displayPosts,
|
|
233
|
+
hasMore: hasMore,
|
|
234
|
+
nextCursor: nextCursor,
|
|
235
|
+
type: type,
|
|
236
|
+
grouped: grouped,
|
|
237
|
+
replyCounts: replyCounts
|
|
238
|
+
})
|
|
252
239
|
})
|
|
253
240
|
}));
|
|
254
241
|
});
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
2
|
-
import { getSiteName } from "../../lib/config.js";
|
|
3
2
|
/**
|
|
4
3
|
* Collection Page Route
|
|
5
4
|
*/ import { Hono } from "hono";
|
|
6
5
|
import { useLingui as $_useLingui } from "@jant/core/i18n";
|
|
7
|
-
import { BaseLayout } from "../../theme/layouts/index.js";
|
|
6
|
+
import { BaseLayout, SiteLayout } from "../../theme/layouts/index.js";
|
|
8
7
|
import * as sqid from "../../lib/sqid.js";
|
|
9
8
|
import * as time from "../../lib/time.js";
|
|
9
|
+
import { getNavigationData } from "../../lib/navigation.js";
|
|
10
10
|
export const collectionRoutes = new Hono();
|
|
11
11
|
function CollectionContent({ collection, posts }) {
|
|
12
12
|
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
13
13
|
return /*#__PURE__*/ _jsxs("div", {
|
|
14
|
-
class: "container py-8",
|
|
15
14
|
children: [
|
|
16
15
|
/*#__PURE__*/ _jsxs("header", {
|
|
17
16
|
class: "mb-8",
|
|
@@ -61,17 +60,6 @@ function CollectionContent({ collection, posts }) {
|
|
|
61
60
|
})
|
|
62
61
|
]
|
|
63
62
|
}, post.id))
|
|
64
|
-
}),
|
|
65
|
-
/*#__PURE__*/ _jsx("nav", {
|
|
66
|
-
class: "mt-8",
|
|
67
|
-
children: /*#__PURE__*/ _jsx("a", {
|
|
68
|
-
href: "/",
|
|
69
|
-
class: "text-sm hover:underline",
|
|
70
|
-
children: $__i18n._({
|
|
71
|
-
id: "biOepV",
|
|
72
|
-
message: "← Back to home"
|
|
73
|
-
})
|
|
74
|
-
})
|
|
75
63
|
})
|
|
76
64
|
]
|
|
77
65
|
});
|
|
@@ -81,14 +69,17 @@ collectionRoutes.get("/:path", async (c)=>{
|
|
|
81
69
|
const collection = await c.var.services.collections.getByPath(path);
|
|
82
70
|
if (!collection) return c.notFound();
|
|
83
71
|
const posts = await c.var.services.collections.getPosts(collection.id);
|
|
84
|
-
const
|
|
72
|
+
const navData = await getNavigationData(c);
|
|
85
73
|
return c.html(/*#__PURE__*/ _jsx(BaseLayout, {
|
|
86
|
-
title: `${collection.title} - ${siteName}`,
|
|
74
|
+
title: `${collection.title} - ${navData.siteName}`,
|
|
87
75
|
description: collection.description ?? undefined,
|
|
88
76
|
c: c,
|
|
89
|
-
children: /*#__PURE__*/ _jsx(
|
|
90
|
-
|
|
91
|
-
|
|
77
|
+
children: /*#__PURE__*/ _jsx(SiteLayout, {
|
|
78
|
+
...navData,
|
|
79
|
+
children: /*#__PURE__*/ _jsx(CollectionContent, {
|
|
80
|
+
collection: collection,
|
|
81
|
+
posts: posts
|
|
82
|
+
})
|
|
92
83
|
})
|
|
93
84
|
}));
|
|
94
85
|
});
|
|
@@ -1,119 +1,109 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "hono/jsx/jsx-runtime";
|
|
2
2
|
/**
|
|
3
3
|
* Home Page Route
|
|
4
|
+
*
|
|
5
|
+
* Timeline feed with per-type card components and thread previews.
|
|
4
6
|
*/ import { Hono } from "hono";
|
|
5
7
|
import { useLingui as $_useLingui } from "@jant/core/i18n";
|
|
6
|
-
import { BaseLayout } from "../../theme/layouts/index.js";
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
8
|
+
import { BaseLayout, SiteLayout } from "../../theme/layouts/index.js";
|
|
9
|
+
import { buildMediaMap } from "../../lib/media-helpers.js";
|
|
10
|
+
import { resolveTimelineFeed } from "../../lib/theme-components.js";
|
|
11
|
+
import { TimelineFeed as DefaultTimelineFeed } from "../../theme/components/timeline/TimelineFeed.js";
|
|
12
|
+
import { getNavigationData } from "../../lib/navigation.js";
|
|
13
|
+
const PAGE_SIZE = 20;
|
|
10
14
|
export const homeRoutes = new Hono();
|
|
11
|
-
function HomeContent({
|
|
15
|
+
function HomeContent({ FeedComponent, feedProps }) {
|
|
12
16
|
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
13
|
-
return /*#__PURE__*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/*#__PURE__*/ _jsx("h1", {
|
|
20
|
-
class: "text-2xl font-semibold",
|
|
21
|
-
children: siteName
|
|
22
|
-
}),
|
|
23
|
-
/*#__PURE__*/ _jsxs("nav", {
|
|
24
|
-
class: "flex items-center gap-4 text-sm",
|
|
25
|
-
children: [
|
|
26
|
-
/*#__PURE__*/ _jsx("a", {
|
|
27
|
-
href: "/archive",
|
|
28
|
-
class: "text-muted-foreground hover:text-foreground",
|
|
29
|
-
children: $__i18n._({
|
|
30
|
-
id: "B495Gs",
|
|
31
|
-
message: "Archive"
|
|
32
|
-
})
|
|
33
|
-
}),
|
|
34
|
-
/*#__PURE__*/ _jsx("a", {
|
|
35
|
-
href: "/feed",
|
|
36
|
-
class: "text-muted-foreground hover:text-foreground",
|
|
37
|
-
children: "RSS"
|
|
38
|
-
})
|
|
39
|
-
]
|
|
40
|
-
})
|
|
41
|
-
]
|
|
42
|
-
}),
|
|
43
|
-
/*#__PURE__*/ _jsx("main", {
|
|
44
|
-
class: "flex flex-col gap-6",
|
|
45
|
-
children: posts.length === 0 ? /*#__PURE__*/ _jsx("p", {
|
|
46
|
-
class: "text-muted-foreground",
|
|
47
|
-
children: $__i18n._({
|
|
48
|
-
id: "ODiSoW",
|
|
49
|
-
message: "No posts yet."
|
|
50
|
-
})
|
|
51
|
-
}) : posts.map((post)=>/*#__PURE__*/ _jsxs("article", {
|
|
52
|
-
class: "h-entry",
|
|
53
|
-
children: [
|
|
54
|
-
post.title && /*#__PURE__*/ _jsx("h2", {
|
|
55
|
-
class: "p-name text-lg font-medium mb-2",
|
|
56
|
-
children: /*#__PURE__*/ _jsx("a", {
|
|
57
|
-
href: `/p/${sqid.encode(post.id)}`,
|
|
58
|
-
class: "u-url hover:underline",
|
|
59
|
-
children: post.title
|
|
60
|
-
})
|
|
61
|
-
}),
|
|
62
|
-
/*#__PURE__*/ _jsx("div", {
|
|
63
|
-
class: "e-content prose prose-sm",
|
|
64
|
-
dangerouslySetInnerHTML: {
|
|
65
|
-
__html: post.contentHtml || ""
|
|
66
|
-
}
|
|
67
|
-
}),
|
|
68
|
-
/*#__PURE__*/ _jsxs("footer", {
|
|
69
|
-
class: "mt-2 text-sm text-muted-foreground",
|
|
70
|
-
children: [
|
|
71
|
-
/*#__PURE__*/ _jsx("time", {
|
|
72
|
-
class: "dt-published",
|
|
73
|
-
datetime: time.toISOString(post.publishedAt),
|
|
74
|
-
children: time.formatDate(post.publishedAt)
|
|
75
|
-
}),
|
|
76
|
-
post.visibility === "featured" && /*#__PURE__*/ _jsx("span", {
|
|
77
|
-
class: "ml-2 text-xs",
|
|
78
|
-
children: $__i18n._({
|
|
79
|
-
id: "FkMol5",
|
|
80
|
-
message: "Featured"
|
|
81
|
-
})
|
|
82
|
-
})
|
|
83
|
-
]
|
|
84
|
-
})
|
|
85
|
-
]
|
|
86
|
-
}, post.id))
|
|
87
|
-
}),
|
|
88
|
-
posts.length >= 20 && /*#__PURE__*/ _jsx("nav", {
|
|
89
|
-
class: "mt-8 text-center",
|
|
90
|
-
children: /*#__PURE__*/ _jsx("a", {
|
|
91
|
-
href: "/archive",
|
|
92
|
-
class: "text-sm text-muted-foreground hover:text-foreground",
|
|
93
|
-
children: $__i18n._({
|
|
94
|
-
id: "mTOYla",
|
|
95
|
-
message: "View all posts →"
|
|
96
|
-
})
|
|
97
|
-
})
|
|
17
|
+
return /*#__PURE__*/ _jsx(_Fragment, {
|
|
18
|
+
children: feedProps.items.length === 0 ? /*#__PURE__*/ _jsx("p", {
|
|
19
|
+
class: "text-muted-foreground",
|
|
20
|
+
children: $__i18n._({
|
|
21
|
+
id: "ODiSoW",
|
|
22
|
+
message: "No posts yet."
|
|
98
23
|
})
|
|
99
|
-
|
|
24
|
+
}) : /*#__PURE__*/ _jsx(FeedComponent, {
|
|
25
|
+
...feedProps
|
|
26
|
+
})
|
|
100
27
|
});
|
|
101
28
|
}
|
|
102
29
|
homeRoutes.get("/", async (c)=>{
|
|
103
|
-
const
|
|
30
|
+
const navData = await getNavigationData(c);
|
|
31
|
+
// Fetch one extra to determine if there are more
|
|
104
32
|
const posts = await c.var.services.posts.list({
|
|
105
33
|
visibility: [
|
|
106
34
|
"featured",
|
|
107
35
|
"quiet"
|
|
108
36
|
],
|
|
109
|
-
|
|
37
|
+
excludeReplies: true,
|
|
38
|
+
excludeTypes: [
|
|
39
|
+
"page"
|
|
40
|
+
],
|
|
41
|
+
limit: PAGE_SIZE + 1
|
|
110
42
|
});
|
|
43
|
+
const hasMore = posts.length > PAGE_SIZE;
|
|
44
|
+
const displayPosts = hasMore ? posts.slice(0, PAGE_SIZE) : posts;
|
|
45
|
+
// Batch load media attachments
|
|
46
|
+
const postIds = displayPosts.map((p)=>p.id);
|
|
47
|
+
const rawMediaMap = await c.var.services.media.getByPostIds(postIds);
|
|
48
|
+
const r2PublicUrl = c.env.R2_PUBLIC_URL;
|
|
49
|
+
const imageTransformUrl = c.env.IMAGE_TRANSFORM_URL;
|
|
50
|
+
const mediaMap = buildMediaMap(rawMediaMap, r2PublicUrl, imageTransformUrl);
|
|
51
|
+
// Get reply counts to identify thread roots
|
|
52
|
+
const replyCounts = await c.var.services.posts.getReplyCounts(postIds);
|
|
53
|
+
const threadRootIds = postIds.filter((id)=>(replyCounts.get(id) ?? 0) > 0);
|
|
54
|
+
// Batch load thread previews
|
|
55
|
+
const threadPreviews = await c.var.services.posts.getThreadPreviews(threadRootIds, 3);
|
|
56
|
+
// Batch load media for preview replies
|
|
57
|
+
const previewReplyIds = [];
|
|
58
|
+
for (const replies of threadPreviews.values()){
|
|
59
|
+
for (const reply of replies){
|
|
60
|
+
previewReplyIds.push(reply.id);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const previewMediaMap = previewReplyIds.length > 0 ? buildMediaMap(await c.var.services.media.getByPostIds(previewReplyIds), r2PublicUrl, imageTransformUrl) : new Map();
|
|
64
|
+
// Assemble timeline items
|
|
65
|
+
const items = displayPosts.map((post)=>{
|
|
66
|
+
const postWithMedia = {
|
|
67
|
+
...post,
|
|
68
|
+
mediaAttachments: mediaMap.get(post.id) ?? []
|
|
69
|
+
};
|
|
70
|
+
const replyCount = replyCounts.get(post.id) ?? 0;
|
|
71
|
+
const previewReplies = threadPreviews.get(post.id);
|
|
72
|
+
if (replyCount > 0 && previewReplies) {
|
|
73
|
+
return {
|
|
74
|
+
post: postWithMedia,
|
|
75
|
+
threadPreview: {
|
|
76
|
+
replies: previewReplies.map((r)=>({
|
|
77
|
+
...r,
|
|
78
|
+
mediaAttachments: previewMediaMap.get(r.id) ?? []
|
|
79
|
+
})),
|
|
80
|
+
totalReplyCount: replyCount
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
post: postWithMedia
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
// Determine next cursor
|
|
89
|
+
const lastPost = displayPosts[displayPosts.length - 1];
|
|
90
|
+
const nextCursor = hasMore && lastPost ? lastPost.id : undefined;
|
|
91
|
+
// Resolve theme components
|
|
92
|
+
const Feed = resolveTimelineFeed(DefaultTimelineFeed, c.var.config.theme?.components);
|
|
93
|
+
const feedProps = {
|
|
94
|
+
items,
|
|
95
|
+
hasMore,
|
|
96
|
+
nextCursor
|
|
97
|
+
};
|
|
111
98
|
return c.html(/*#__PURE__*/ _jsx(BaseLayout, {
|
|
112
|
-
title: siteName,
|
|
99
|
+
title: navData.siteName,
|
|
113
100
|
c: c,
|
|
114
|
-
children: /*#__PURE__*/ _jsx(
|
|
115
|
-
|
|
116
|
-
|
|
101
|
+
children: /*#__PURE__*/ _jsx(SiteLayout, {
|
|
102
|
+
...navData,
|
|
103
|
+
children: /*#__PURE__*/ _jsx(HomeContent, {
|
|
104
|
+
FeedComponent: Feed,
|
|
105
|
+
feedProps: feedProps
|
|
106
|
+
})
|
|
117
107
|
})
|
|
118
108
|
}));
|
|
119
109
|
});
|
|
@@ -1,47 +1,25 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
2
|
-
import { getSiteName } from "../../lib/config.js";
|
|
3
2
|
/**
|
|
4
3
|
* Custom Page Route
|
|
5
4
|
*
|
|
6
5
|
* Catch-all route for custom pages accessible via their path field
|
|
7
6
|
*/ import { Hono } from "hono";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
7
|
+
import { BaseLayout, SiteLayout } from "../../theme/layouts/index.js";
|
|
8
|
+
import { getNavigationData } from "../../lib/navigation.js";
|
|
10
9
|
export const pageRoutes = new Hono();
|
|
11
10
|
function PageContent({ page }) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class: "container py-8 max-w-2xl",
|
|
11
|
+
return /*#__PURE__*/ _jsxs("article", {
|
|
12
|
+
class: "h-entry",
|
|
15
13
|
children: [
|
|
16
|
-
/*#__PURE__*/
|
|
17
|
-
class: "
|
|
18
|
-
children:
|
|
19
|
-
page.title && /*#__PURE__*/ _jsx("h1", {
|
|
20
|
-
class: "p-name text-3xl font-semibold mb-6",
|
|
21
|
-
children: page.title
|
|
22
|
-
}),
|
|
23
|
-
/*#__PURE__*/ _jsx("div", {
|
|
24
|
-
class: "e-content prose",
|
|
25
|
-
dangerouslySetInnerHTML: {
|
|
26
|
-
__html: page.contentHtml || ""
|
|
27
|
-
}
|
|
28
|
-
})
|
|
29
|
-
]
|
|
14
|
+
page.title && /*#__PURE__*/ _jsx("h1", {
|
|
15
|
+
class: "p-name text-3xl font-semibold mb-6",
|
|
16
|
+
children: page.title
|
|
30
17
|
}),
|
|
31
|
-
/*#__PURE__*/ _jsx("
|
|
32
|
-
class: "
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
children: [
|
|
37
|
-
"←",
|
|
38
|
-
" ",
|
|
39
|
-
$__i18n._({
|
|
40
|
-
id: "x4RuFo",
|
|
41
|
-
message: "Back to home"
|
|
42
|
-
})
|
|
43
|
-
]
|
|
44
|
-
})
|
|
18
|
+
/*#__PURE__*/ _jsx("div", {
|
|
19
|
+
class: "e-content prose",
|
|
20
|
+
dangerouslySetInnerHTML: {
|
|
21
|
+
__html: page.contentHtml || ""
|
|
22
|
+
}
|
|
45
23
|
})
|
|
46
24
|
]
|
|
47
25
|
});
|
|
@@ -59,13 +37,16 @@ pageRoutes.get("/:path", async (c)=>{
|
|
|
59
37
|
if (page.visibility === "draft") {
|
|
60
38
|
return c.notFound();
|
|
61
39
|
}
|
|
62
|
-
const
|
|
40
|
+
const navData = await getNavigationData(c);
|
|
63
41
|
return c.html(/*#__PURE__*/ _jsx(BaseLayout, {
|
|
64
|
-
title: `${page.title} - ${siteName}`,
|
|
42
|
+
title: `${page.title} - ${navData.siteName}`,
|
|
65
43
|
description: page.content?.slice(0, 160),
|
|
66
44
|
c: c,
|
|
67
|
-
children: /*#__PURE__*/ _jsx(
|
|
68
|
-
|
|
45
|
+
children: /*#__PURE__*/ _jsx(SiteLayout, {
|
|
46
|
+
...navData,
|
|
47
|
+
children: /*#__PURE__*/ _jsx(PageContent, {
|
|
48
|
+
page: page
|
|
49
|
+
})
|
|
69
50
|
})
|
|
70
51
|
}));
|
|
71
52
|
});
|