@btst/stack 1.0.1 → 1.1.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/README.md +156 -709
- package/dist/api/index.cjs +2 -1
- package/dist/api/index.d.cts +4 -3
- package/dist/api/index.d.mts +4 -3
- package/dist/api/index.d.ts +4 -3
- package/dist/api/index.mjs +1 -1
- package/dist/client/components/compose.cjs +68 -0
- package/dist/client/components/compose.mjs +65 -0
- package/dist/client/components/error-boundary.cjs +24 -0
- package/dist/client/components/error-boundary.mjs +22 -0
- package/dist/client/components/index.cjs +10 -0
- package/dist/client/components/index.d.cts +52 -0
- package/dist/client/components/index.d.mts +52 -0
- package/dist/client/components/index.d.ts +52 -0
- package/dist/client/components/index.mjs +2 -0
- package/dist/client/index.cjs +24 -5
- package/dist/client/index.d.cts +125 -8
- package/dist/client/index.d.mts +125 -8
- package/dist/client/index.d.ts +125 -8
- package/dist/client/index.mjs +21 -4
- package/dist/client/meta-utils.cjs +162 -0
- package/dist/client/meta-utils.mjs +160 -0
- package/dist/client/path-utils.cjs +15 -0
- package/dist/client/path-utils.mjs +13 -0
- package/dist/client/sitemap-utils.cjs +14 -0
- package/dist/client/sitemap-utils.mjs +12 -0
- package/dist/context/index.cjs +6 -63
- package/dist/context/index.d.cts +21 -24
- package/dist/context/index.d.mts +21 -24
- package/dist/context/index.d.ts +21 -24
- package/dist/context/index.mjs +1 -61
- package/dist/context/provider.cjs +51 -0
- package/dist/context/provider.mjs +46 -0
- package/dist/index.cjs +2 -3
- package/dist/index.d.cts +3 -2
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +1 -2
- package/dist/plugins/api/index.cjs +13 -0
- package/dist/plugins/api/index.d.cts +40 -0
- package/dist/plugins/api/index.d.mts +40 -0
- package/dist/plugins/api/index.d.ts +40 -0
- package/dist/plugins/api/index.mjs +8 -0
- package/dist/plugins/blog/api/index.cjs +11 -0
- package/dist/plugins/blog/api/index.d.cts +7 -0
- package/dist/plugins/blog/api/index.d.mts +7 -0
- package/dist/plugins/blog/api/index.d.ts +7 -0
- package/dist/plugins/blog/api/index.mjs +2 -0
- package/dist/plugins/blog/api/plugin.cjs +569 -0
- package/dist/plugins/blog/api/plugin.mjs +565 -0
- package/dist/plugins/blog/client/components/forms/image-field.cjs +133 -0
- package/dist/plugins/blog/client/components/forms/image-field.mjs +131 -0
- package/dist/plugins/blog/client/components/forms/markdown-editor-styles.css +30 -0
- package/dist/plugins/blog/client/components/forms/markdown-editor.cjs +106 -0
- package/dist/plugins/blog/client/components/forms/markdown-editor.mjs +104 -0
- package/dist/plugins/blog/client/components/forms/post-forms.cjs +401 -0
- package/dist/plugins/blog/client/components/forms/post-forms.mjs +398 -0
- package/dist/plugins/blog/client/components/forms/tags-multiselect.cjs +71 -0
- package/dist/plugins/blog/client/components/forms/tags-multiselect.mjs +65 -0
- package/dist/plugins/blog/client/components/index.cjs +17 -0
- package/dist/plugins/blog/client/components/index.d.cts +22 -0
- package/dist/plugins/blog/client/components/index.d.mts +22 -0
- package/dist/plugins/blog/client/components/index.d.ts +22 -0
- package/dist/plugins/blog/client/components/index.mjs +12 -0
- package/dist/plugins/blog/client/components/loading/form-page-skeleton.cjs +62 -0
- package/dist/plugins/blog/client/components/loading/form-page-skeleton.mjs +60 -0
- package/dist/plugins/blog/client/components/loading/index.cjs +20 -0
- package/dist/plugins/blog/client/components/loading/index.mjs +16 -0
- package/dist/plugins/blog/client/components/loading/list-page-skeleton.cjs +26 -0
- package/dist/plugins/blog/client/components/loading/list-page-skeleton.mjs +24 -0
- package/dist/plugins/blog/client/components/loading/page-header-skeleton.cjs +13 -0
- package/dist/plugins/blog/client/components/loading/page-header-skeleton.mjs +11 -0
- package/dist/plugins/blog/client/components/loading/post-card-skeleton.cjs +22 -0
- package/dist/plugins/blog/client/components/loading/post-card-skeleton.mjs +20 -0
- package/dist/plugins/blog/client/components/loading/post-page-skeleton.cjs +56 -0
- package/dist/plugins/blog/client/components/loading/post-page-skeleton.mjs +54 -0
- package/dist/plugins/blog/client/components/pages/404-page.cjs +19 -0
- package/dist/plugins/blog/client/components/pages/404-page.mjs +17 -0
- package/dist/plugins/blog/client/components/pages/edit-post-page.cjs +41 -0
- package/dist/plugins/blog/client/components/pages/edit-post-page.internal.cjs +57 -0
- package/dist/plugins/blog/client/components/pages/edit-post-page.internal.mjs +55 -0
- package/dist/plugins/blog/client/components/pages/edit-post-page.mjs +39 -0
- package/dist/plugins/blog/client/components/pages/home-page.cjs +41 -0
- package/dist/plugins/blog/client/components/pages/home-page.internal.cjs +61 -0
- package/dist/plugins/blog/client/components/pages/home-page.internal.mjs +59 -0
- package/dist/plugins/blog/client/components/pages/home-page.mjs +39 -0
- package/dist/plugins/blog/client/components/pages/new-post-page.cjs +37 -0
- package/dist/plugins/blog/client/components/pages/new-post-page.internal.cjs +53 -0
- package/dist/plugins/blog/client/components/pages/new-post-page.internal.mjs +51 -0
- package/dist/plugins/blog/client/components/pages/new-post-page.mjs +35 -0
- package/dist/plugins/blog/client/components/pages/post-page.cjs +39 -0
- package/dist/plugins/blog/client/components/pages/post-page.internal.cjs +101 -0
- package/dist/plugins/blog/client/components/pages/post-page.internal.mjs +99 -0
- package/dist/plugins/blog/client/components/pages/post-page.mjs +37 -0
- package/dist/plugins/blog/client/components/pages/tag-page.cjs +39 -0
- package/dist/plugins/blog/client/components/pages/tag-page.internal.cjs +61 -0
- package/dist/plugins/blog/client/components/pages/tag-page.internal.mjs +59 -0
- package/dist/plugins/blog/client/components/pages/tag-page.mjs +37 -0
- package/dist/plugins/blog/client/components/shared/better-blog-attribution.cjs +24 -0
- package/dist/plugins/blog/client/components/shared/better-blog-attribution.mjs +22 -0
- package/dist/plugins/blog/client/components/shared/default-error.cjs +18 -0
- package/dist/plugins/blog/client/components/shared/default-error.mjs +16 -0
- package/dist/plugins/blog/client/components/shared/defaults.cjs +13 -0
- package/dist/plugins/blog/client/components/shared/defaults.mjs +10 -0
- package/dist/plugins/blog/client/components/shared/empty-list.cjs +21 -0
- package/dist/plugins/blog/client/components/shared/empty-list.mjs +19 -0
- package/dist/plugins/blog/client/components/shared/error-placeholder.cjs +24 -0
- package/dist/plugins/blog/client/components/shared/error-placeholder.mjs +22 -0
- package/dist/plugins/blog/client/components/shared/highlight-text.cjs +53 -0
- package/dist/plugins/blog/client/components/shared/highlight-text.mjs +51 -0
- package/dist/plugins/blog/client/components/shared/markdown-content-styles.css +328 -0
- package/dist/plugins/blog/client/components/shared/markdown-content.cjs +324 -0
- package/dist/plugins/blog/client/components/shared/markdown-content.mjs +315 -0
- package/dist/plugins/blog/client/components/shared/on-this-page.cjs +161 -0
- package/dist/plugins/blog/client/components/shared/on-this-page.mjs +158 -0
- package/dist/plugins/blog/client/components/shared/page-header.cjs +40 -0
- package/dist/plugins/blog/client/components/shared/page-header.mjs +38 -0
- package/dist/plugins/blog/client/components/shared/page-layout.cjs +24 -0
- package/dist/plugins/blog/client/components/shared/page-layout.mjs +22 -0
- package/dist/plugins/blog/client/components/shared/page-wrapper.cjs +23 -0
- package/dist/plugins/blog/client/components/shared/page-wrapper.mjs +21 -0
- package/dist/plugins/blog/client/components/shared/post-card.cjs +279 -0
- package/dist/plugins/blog/client/components/shared/post-card.mjs +277 -0
- package/dist/plugins/blog/client/components/shared/post-navigation.cjs +74 -0
- package/dist/plugins/blog/client/components/shared/post-navigation.mjs +72 -0
- package/dist/plugins/blog/client/components/shared/posts-list.cjs +48 -0
- package/dist/plugins/blog/client/components/shared/posts-list.mjs +46 -0
- package/dist/plugins/blog/client/components/shared/recent-posts-carousel.cjs +59 -0
- package/dist/plugins/blog/client/components/shared/recent-posts-carousel.mjs +57 -0
- package/dist/plugins/blog/client/components/shared/search-input.cjs +136 -0
- package/dist/plugins/blog/client/components/shared/search-input.mjs +117 -0
- package/dist/plugins/blog/client/components/shared/search-modal.cjs +135 -0
- package/dist/plugins/blog/client/components/shared/search-modal.mjs +116 -0
- package/dist/plugins/blog/client/components/shared/tags-list.cjs +22 -0
- package/dist/plugins/blog/client/components/shared/tags-list.mjs +20 -0
- package/dist/plugins/blog/client/components/shared/use-route-lifecycle.cjs +50 -0
- package/dist/plugins/blog/client/components/shared/use-route-lifecycle.mjs +48 -0
- package/dist/plugins/blog/client/hooks/blog-hooks.cjs +380 -0
- package/dist/plugins/blog/client/hooks/blog-hooks.mjs +368 -0
- package/dist/plugins/blog/client/hooks/index.cjs +17 -0
- package/dist/plugins/blog/client/hooks/index.d.cts +150 -0
- package/dist/plugins/blog/client/hooks/index.d.mts +150 -0
- package/dist/plugins/blog/client/hooks/index.d.ts +150 -0
- package/dist/plugins/blog/client/hooks/index.mjs +1 -0
- package/dist/plugins/blog/client/hooks/use-debounce.cjs +16 -0
- package/dist/plugins/blog/client/hooks/use-debounce.mjs +14 -0
- package/dist/plugins/blog/client/index.cjs +7 -0
- package/dist/plugins/blog/client/index.d.cts +414 -0
- package/dist/plugins/blog/client/index.d.mts +414 -0
- package/dist/plugins/blog/client/index.d.ts +414 -0
- package/dist/plugins/blog/client/index.mjs +1 -0
- package/dist/plugins/blog/client/localization/blog-card.cjs +7 -0
- package/dist/plugins/blog/client/localization/blog-card.mjs +5 -0
- package/dist/plugins/blog/client/localization/blog-common.cjs +10 -0
- package/dist/plugins/blog/client/localization/blog-common.mjs +8 -0
- package/dist/plugins/blog/client/localization/blog-forms.cjs +40 -0
- package/dist/plugins/blog/client/localization/blog-forms.mjs +38 -0
- package/dist/plugins/blog/client/localization/blog-list.cjs +18 -0
- package/dist/plugins/blog/client/localization/blog-list.mjs +16 -0
- package/dist/plugins/blog/client/localization/blog-post.cjs +13 -0
- package/dist/plugins/blog/client/localization/blog-post.mjs +11 -0
- package/dist/plugins/blog/client/localization/index.cjs +17 -0
- package/dist/plugins/blog/client/localization/index.mjs +15 -0
- package/dist/plugins/blog/client/plugin.cjs +462 -0
- package/dist/plugins/blog/client/plugin.mjs +460 -0
- package/dist/plugins/blog/client.css +3 -0
- package/dist/plugins/blog/db.cjs +90 -0
- package/dist/plugins/blog/db.mjs +88 -0
- package/dist/plugins/blog/query-keys.cjs +181 -0
- package/dist/plugins/blog/query-keys.d.cts +530 -0
- package/dist/plugins/blog/query-keys.d.mts +530 -0
- package/dist/plugins/blog/query-keys.d.ts +530 -0
- package/dist/plugins/blog/query-keys.mjs +179 -0
- package/dist/plugins/blog/schemas.cjs +39 -0
- package/dist/plugins/blog/schemas.mjs +35 -0
- package/dist/plugins/blog/style.css +22 -0
- package/dist/plugins/blog/utils.cjs +97 -0
- package/dist/plugins/blog/utils.mjs +87 -0
- package/dist/plugins/client/index.cjs +15 -0
- package/dist/plugins/client/index.d.cts +57 -0
- package/dist/plugins/client/index.d.mts +57 -0
- package/dist/plugins/client/index.d.ts +57 -0
- package/dist/plugins/client/index.mjs +9 -0
- package/dist/{shared/stack.3OUyGp_E.mjs → plugins/utils.mjs} +1 -1
- package/dist/shared/{stack.DORw_1ps.d.cts → stack.ByOugz9d.d.cts} +17 -1
- package/dist/shared/{stack.DORw_1ps.d.mts → stack.ByOugz9d.d.mts} +17 -1
- package/dist/shared/{stack.DORw_1ps.d.ts → stack.ByOugz9d.d.ts} +17 -1
- package/dist/shared/stack.CoPoHVfV.d.cts +76 -0
- package/dist/shared/stack.CoPoHVfV.d.mts +76 -0
- package/dist/shared/stack.CoPoHVfV.d.ts +76 -0
- package/package.json +102 -14
- package/src/__tests__/plugins.test.tsx +539 -0
- package/src/__tests__/sitemap.test.ts +60 -0
- package/src/api/index.ts +75 -0
- package/src/client/components/compose.tsx +116 -0
- package/src/client/components/error-boundary.tsx +30 -0
- package/src/client/components/index.tsx +2 -0
- package/src/client/index.ts +109 -0
- package/src/client/meta-utils.ts +228 -0
- package/src/client/path-utils.ts +38 -0
- package/src/client/sitemap-utils.ts +46 -0
- package/src/context/index.ts +1 -0
- package/src/context/provider.tsx +157 -0
- package/src/index.ts +1 -0
- package/src/plugins/api/index.ts +50 -0
- package/src/plugins/blog/api/index.ts +2 -0
- package/src/plugins/blog/api/plugin.ts +759 -0
- package/src/plugins/blog/client/components/forms/image-field.tsx +165 -0
- package/src/plugins/blog/client/components/forms/markdown-editor-styles.css +30 -0
- package/src/plugins/blog/client/components/forms/markdown-editor.tsx +136 -0
- package/src/plugins/blog/client/components/forms/post-forms.tsx +531 -0
- package/src/plugins/blog/client/components/forms/tags-multiselect.tsx +79 -0
- package/src/plugins/blog/client/components/index.tsx +11 -0
- package/src/plugins/blog/client/components/loading/form-page-skeleton.tsx +75 -0
- package/src/plugins/blog/client/components/loading/index.tsx +27 -0
- package/src/plugins/blog/client/components/loading/list-page-skeleton.tsx +38 -0
- package/src/plugins/blog/client/components/loading/page-header-skeleton.tsx +10 -0
- package/src/plugins/blog/client/components/loading/post-card-skeleton.tsx +30 -0
- package/src/plugins/blog/client/components/loading/post-page-skeleton.tsx +75 -0
- package/src/plugins/blog/client/components/pages/404-page.tsx +23 -0
- package/src/plugins/blog/client/components/pages/edit-post-page.internal.tsx +60 -0
- package/src/plugins/blog/client/components/pages/edit-post-page.tsx +40 -0
- package/src/plugins/blog/client/components/pages/home-page.internal.tsx +71 -0
- package/src/plugins/blog/client/components/pages/home-page.tsx +42 -0
- package/src/plugins/blog/client/components/pages/new-post-page.internal.tsx +59 -0
- package/src/plugins/blog/client/components/pages/new-post-page.tsx +36 -0
- package/src/plugins/blog/client/components/pages/post-page.internal.tsx +142 -0
- package/src/plugins/blog/client/components/pages/post-page.tsx +38 -0
- package/src/plugins/blog/client/components/pages/tag-page.internal.tsx +74 -0
- package/src/plugins/blog/client/components/pages/tag-page.tsx +38 -0
- package/src/plugins/blog/client/components/shared/better-blog-attribution.tsx +19 -0
- package/src/plugins/blog/client/components/shared/default-error.tsx +20 -0
- package/src/plugins/blog/client/components/shared/defaults.tsx +9 -0
- package/src/plugins/blog/client/components/shared/empty-list.tsx +25 -0
- package/src/plugins/blog/client/components/shared/error-placeholder.tsx +20 -0
- package/src/plugins/blog/client/components/shared/highlight-text.tsx +80 -0
- package/src/plugins/blog/client/components/shared/markdown-content-styles.css +328 -0
- package/src/plugins/blog/client/components/shared/markdown-content.tsx +448 -0
- package/src/plugins/blog/client/components/shared/on-this-page.tsx +234 -0
- package/src/plugins/blog/client/components/shared/page-header.tsx +35 -0
- package/src/plugins/blog/client/components/shared/page-layout.tsx +23 -0
- package/src/plugins/blog/client/components/shared/page-wrapper.tsx +32 -0
- package/src/plugins/blog/client/components/shared/post-card.tsx +308 -0
- package/src/plugins/blog/client/components/shared/post-navigation.tsx +98 -0
- package/src/plugins/blog/client/components/shared/posts-list.tsx +67 -0
- package/src/plugins/blog/client/components/shared/recent-posts-carousel.tsx +79 -0
- package/src/plugins/blog/client/components/shared/search-input.tsx +146 -0
- package/src/plugins/blog/client/components/shared/search-modal.tsx +162 -0
- package/src/plugins/blog/client/components/shared/tags-list.tsx +34 -0
- package/src/plugins/blog/client/components/shared/use-route-lifecycle.tsx +68 -0
- package/src/plugins/blog/client/hooks/blog-hooks.tsx +623 -0
- package/src/plugins/blog/client/hooks/index.tsx +1 -0
- package/src/plugins/blog/client/hooks/use-debounce.ts +43 -0
- package/src/plugins/blog/client/index.ts +9 -0
- package/src/plugins/blog/client/localization/blog-card.ts +3 -0
- package/src/plugins/blog/client/localization/blog-common.ts +7 -0
- package/src/plugins/blog/client/localization/blog-forms.ts +45 -0
- package/src/plugins/blog/client/localization/blog-list.ts +14 -0
- package/src/plugins/blog/client/localization/blog-post.ts +9 -0
- package/src/plugins/blog/client/localization/index.ts +15 -0
- package/src/plugins/blog/client/overrides.ts +123 -0
- package/src/plugins/blog/client/plugin.tsx +672 -0
- package/src/plugins/blog/client.css +3 -0
- package/src/plugins/blog/db.ts +90 -0
- package/src/plugins/blog/query-keys.ts +267 -0
- package/src/plugins/blog/schemas.ts +39 -0
- package/src/plugins/blog/style.css +22 -0
- package/src/plugins/blog/types.ts +37 -0
- package/src/plugins/blog/utils.ts +144 -0
- package/src/plugins/client/index.ts +53 -0
- package/src/plugins/index.ts +0 -0
- package/src/plugins/utils.ts +35 -0
- package/src/types.ts +209 -0
- package/dist/plugins/index.cjs +0 -15
- package/dist/plugins/index.d.cts +0 -64
- package/dist/plugins/index.d.mts +0 -64
- package/dist/plugins/index.d.ts +0 -64
- package/dist/plugins/index.mjs +0 -11
- package/dist/shared/stack.DrUAVfIH.d.cts +0 -17
- package/dist/shared/stack.DrUAVfIH.d.mts +0 -17
- package/dist/shared/stack.DrUAVfIH.d.ts +0 -17
- /package/dist/{shared/stack.CktCg4PJ.cjs → plugins/utils.cjs} +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const zod = require('zod');
|
|
4
|
+
|
|
5
|
+
const dateFields = {
|
|
6
|
+
publishedAt: zod.z.coerce.date().optional(),
|
|
7
|
+
createdAt: zod.z.coerce.date().optional(),
|
|
8
|
+
updatedAt: zod.z.coerce.date().optional()
|
|
9
|
+
};
|
|
10
|
+
const coreFields = {
|
|
11
|
+
title: zod.z.string().min(1, "Title is required"),
|
|
12
|
+
content: zod.z.string().min(1, "Content is required"),
|
|
13
|
+
excerpt: zod.z.string().min(1, "Excerpt is required"),
|
|
14
|
+
image: zod.z.string().optional(),
|
|
15
|
+
published: zod.z.boolean().optional().default(false),
|
|
16
|
+
slug: zod.z.string().min(1, "Slug is required"),
|
|
17
|
+
tags: zod.z.array(
|
|
18
|
+
zod.z.union([
|
|
19
|
+
zod.z.object({ name: zod.z.string() }),
|
|
20
|
+
zod.z.object({ id: zod.z.string(), name: zod.z.string(), slug: zod.z.string() })
|
|
21
|
+
])
|
|
22
|
+
).optional().default([])
|
|
23
|
+
};
|
|
24
|
+
const PostDomainSchema = zod.z.object({
|
|
25
|
+
id: zod.z.string().optional(),
|
|
26
|
+
...coreFields,
|
|
27
|
+
...dateFields
|
|
28
|
+
});
|
|
29
|
+
const createPostSchema = PostDomainSchema.extend({
|
|
30
|
+
slug: PostDomainSchema.shape.slug.optional()
|
|
31
|
+
}).omit({ id: true });
|
|
32
|
+
const updatePostSchema = PostDomainSchema.extend({
|
|
33
|
+
id: zod.z.string()
|
|
34
|
+
// required on update
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
exports.PostDomainSchema = PostDomainSchema;
|
|
38
|
+
exports.createPostSchema = createPostSchema;
|
|
39
|
+
exports.updatePostSchema = updatePostSchema;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
const dateFields = {
|
|
4
|
+
publishedAt: z.coerce.date().optional(),
|
|
5
|
+
createdAt: z.coerce.date().optional(),
|
|
6
|
+
updatedAt: z.coerce.date().optional()
|
|
7
|
+
};
|
|
8
|
+
const coreFields = {
|
|
9
|
+
title: z.string().min(1, "Title is required"),
|
|
10
|
+
content: z.string().min(1, "Content is required"),
|
|
11
|
+
excerpt: z.string().min(1, "Excerpt is required"),
|
|
12
|
+
image: z.string().optional(),
|
|
13
|
+
published: z.boolean().optional().default(false),
|
|
14
|
+
slug: z.string().min(1, "Slug is required"),
|
|
15
|
+
tags: z.array(
|
|
16
|
+
z.union([
|
|
17
|
+
z.object({ name: z.string() }),
|
|
18
|
+
z.object({ id: z.string(), name: z.string(), slug: z.string() })
|
|
19
|
+
])
|
|
20
|
+
).optional().default([])
|
|
21
|
+
};
|
|
22
|
+
const PostDomainSchema = z.object({
|
|
23
|
+
id: z.string().optional(),
|
|
24
|
+
...coreFields,
|
|
25
|
+
...dateFields
|
|
26
|
+
});
|
|
27
|
+
const createPostSchema = PostDomainSchema.extend({
|
|
28
|
+
slug: PostDomainSchema.shape.slug.optional()
|
|
29
|
+
}).omit({ id: true });
|
|
30
|
+
const updatePostSchema = PostDomainSchema.extend({
|
|
31
|
+
id: z.string()
|
|
32
|
+
// required on update
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export { PostDomainSchema, createPostSchema, updatePostSchema };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
@import "./client.css";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Blog Plugin CSS - Includes Tailwind class scanning
|
|
5
|
+
*
|
|
6
|
+
* When consumed from npm, Tailwind v4 will automatically scan this package's
|
|
7
|
+
* source files for Tailwind classes. Consumers only need:
|
|
8
|
+
* @import "@btst/stack/plugins/blog/css";
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/* Scan this package's source files for Tailwind classes */
|
|
12
|
+
@source "../../../src/**/*.{ts,tsx}";
|
|
13
|
+
|
|
14
|
+
/* Scan UI package components (if in monorepo) */
|
|
15
|
+
@source "../../../../@workspace/ui/src/**/*.{ts,tsx}";
|
|
16
|
+
|
|
17
|
+
/* Scan UI package components (if installed as npm package) */
|
|
18
|
+
@source "../../../node_modules/@workspace/ui/src/**/*.{ts,tsx}";
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* alternatively consumer can use @source "../node_modules/@btst/stack/src/**\/*.{ts,tsx}";
|
|
22
|
+
*/
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const clsx = require('clsx');
|
|
4
|
+
const tailwindMerge = require('tailwind-merge');
|
|
5
|
+
const slug = require('slug');
|
|
6
|
+
|
|
7
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
8
|
+
|
|
9
|
+
const slug__default = /*#__PURE__*/_interopDefaultCompat(slug);
|
|
10
|
+
|
|
11
|
+
function slugify(text, locale = "en") {
|
|
12
|
+
return slug__default(text, { lower: true, locale });
|
|
13
|
+
}
|
|
14
|
+
function cn(...inputs) {
|
|
15
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
16
|
+
}
|
|
17
|
+
function throttle(callback, waitMs) {
|
|
18
|
+
let timerId = null;
|
|
19
|
+
let lastInvokeTime = 0;
|
|
20
|
+
let trailingArgs = null;
|
|
21
|
+
const invoke = (args) => {
|
|
22
|
+
lastInvokeTime = Date.now();
|
|
23
|
+
callback(...args);
|
|
24
|
+
};
|
|
25
|
+
const throttled = (...args) => {
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
const remaining = waitMs - (now - lastInvokeTime);
|
|
28
|
+
if (lastInvokeTime === 0) {
|
|
29
|
+
invoke(args);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (remaining <= 0 || remaining > waitMs) {
|
|
33
|
+
if (timerId) {
|
|
34
|
+
clearTimeout(timerId);
|
|
35
|
+
timerId = null;
|
|
36
|
+
}
|
|
37
|
+
invoke(args);
|
|
38
|
+
} else {
|
|
39
|
+
trailingArgs = args;
|
|
40
|
+
if (!timerId) {
|
|
41
|
+
timerId = setTimeout(() => {
|
|
42
|
+
timerId = null;
|
|
43
|
+
if (trailingArgs) {
|
|
44
|
+
invoke(trailingArgs);
|
|
45
|
+
trailingArgs = null;
|
|
46
|
+
}
|
|
47
|
+
}, remaining);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
throttled.cancel = () => {
|
|
52
|
+
if (timerId) {
|
|
53
|
+
clearTimeout(timerId);
|
|
54
|
+
timerId = null;
|
|
55
|
+
}
|
|
56
|
+
trailingArgs = null;
|
|
57
|
+
lastInvokeTime = 0;
|
|
58
|
+
};
|
|
59
|
+
throttled.flush = () => {
|
|
60
|
+
if (timerId && trailingArgs) {
|
|
61
|
+
clearTimeout(timerId);
|
|
62
|
+
timerId = null;
|
|
63
|
+
invoke(trailingArgs);
|
|
64
|
+
trailingArgs = null;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
return throttled;
|
|
68
|
+
}
|
|
69
|
+
function stripHtml(html) {
|
|
70
|
+
let text = html.replace(/<[^>]*>/g, "");
|
|
71
|
+
text = text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(///g, "/").replace(/ /g, " ").replace(/…/g, "...");
|
|
72
|
+
return text.replace(/\s+/g, " ").trim();
|
|
73
|
+
}
|
|
74
|
+
function stripMarkdown(markdown) {
|
|
75
|
+
let text = markdown;
|
|
76
|
+
text = text.replace(/^#{1,6}\s+/gm, "");
|
|
77
|
+
text = text.replace(/\*\*([^*]+)\*\*/g, "$1");
|
|
78
|
+
text = text.replace(/\*([^*]+)\*/g, "$1");
|
|
79
|
+
text = text.replace(/__([^_]+)__/g, "$1");
|
|
80
|
+
text = text.replace(/_([^_]+)_/g, "$1");
|
|
81
|
+
text = text.replace(/~~([^~]+)~~/g, "$1");
|
|
82
|
+
text = text.replace(/`([^`]+)`/g, "$1");
|
|
83
|
+
text = text.replace(/```[\s\S]*?```/g, "");
|
|
84
|
+
text = text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
|
|
85
|
+
text = text.replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1");
|
|
86
|
+
text = text.replace(/^>\s+/gm, "");
|
|
87
|
+
text = text.replace(/^[-*]{3,}$/gm, "");
|
|
88
|
+
text = text.replace(/^[\s]*[-*+]\s+/gm, "");
|
|
89
|
+
text = text.replace(/^[\s]*\d+\.\s+/gm, "");
|
|
90
|
+
return text.replace(/\n\s*\n/g, "\n").replace(/\s+/g, " ").trim();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
exports.cn = cn;
|
|
94
|
+
exports.slugify = slugify;
|
|
95
|
+
exports.stripHtml = stripHtml;
|
|
96
|
+
exports.stripMarkdown = stripMarkdown;
|
|
97
|
+
exports.throttle = throttle;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { clsx } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
import slug from 'slug';
|
|
4
|
+
|
|
5
|
+
function slugify(text, locale = "en") {
|
|
6
|
+
return slug(text, { lower: true, locale });
|
|
7
|
+
}
|
|
8
|
+
function cn(...inputs) {
|
|
9
|
+
return twMerge(clsx(inputs));
|
|
10
|
+
}
|
|
11
|
+
function throttle(callback, waitMs) {
|
|
12
|
+
let timerId = null;
|
|
13
|
+
let lastInvokeTime = 0;
|
|
14
|
+
let trailingArgs = null;
|
|
15
|
+
const invoke = (args) => {
|
|
16
|
+
lastInvokeTime = Date.now();
|
|
17
|
+
callback(...args);
|
|
18
|
+
};
|
|
19
|
+
const throttled = (...args) => {
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
const remaining = waitMs - (now - lastInvokeTime);
|
|
22
|
+
if (lastInvokeTime === 0) {
|
|
23
|
+
invoke(args);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (remaining <= 0 || remaining > waitMs) {
|
|
27
|
+
if (timerId) {
|
|
28
|
+
clearTimeout(timerId);
|
|
29
|
+
timerId = null;
|
|
30
|
+
}
|
|
31
|
+
invoke(args);
|
|
32
|
+
} else {
|
|
33
|
+
trailingArgs = args;
|
|
34
|
+
if (!timerId) {
|
|
35
|
+
timerId = setTimeout(() => {
|
|
36
|
+
timerId = null;
|
|
37
|
+
if (trailingArgs) {
|
|
38
|
+
invoke(trailingArgs);
|
|
39
|
+
trailingArgs = null;
|
|
40
|
+
}
|
|
41
|
+
}, remaining);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
throttled.cancel = () => {
|
|
46
|
+
if (timerId) {
|
|
47
|
+
clearTimeout(timerId);
|
|
48
|
+
timerId = null;
|
|
49
|
+
}
|
|
50
|
+
trailingArgs = null;
|
|
51
|
+
lastInvokeTime = 0;
|
|
52
|
+
};
|
|
53
|
+
throttled.flush = () => {
|
|
54
|
+
if (timerId && trailingArgs) {
|
|
55
|
+
clearTimeout(timerId);
|
|
56
|
+
timerId = null;
|
|
57
|
+
invoke(trailingArgs);
|
|
58
|
+
trailingArgs = null;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
return throttled;
|
|
62
|
+
}
|
|
63
|
+
function stripHtml(html) {
|
|
64
|
+
let text = html.replace(/<[^>]*>/g, "");
|
|
65
|
+
text = text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(///g, "/").replace(/ /g, " ").replace(/…/g, "...");
|
|
66
|
+
return text.replace(/\s+/g, " ").trim();
|
|
67
|
+
}
|
|
68
|
+
function stripMarkdown(markdown) {
|
|
69
|
+
let text = markdown;
|
|
70
|
+
text = text.replace(/^#{1,6}\s+/gm, "");
|
|
71
|
+
text = text.replace(/\*\*([^*]+)\*\*/g, "$1");
|
|
72
|
+
text = text.replace(/\*([^*]+)\*/g, "$1");
|
|
73
|
+
text = text.replace(/__([^_]+)__/g, "$1");
|
|
74
|
+
text = text.replace(/_([^_]+)_/g, "$1");
|
|
75
|
+
text = text.replace(/~~([^~]+)~~/g, "$1");
|
|
76
|
+
text = text.replace(/`([^`]+)`/g, "$1");
|
|
77
|
+
text = text.replace(/```[\s\S]*?```/g, "");
|
|
78
|
+
text = text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
|
|
79
|
+
text = text.replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1");
|
|
80
|
+
text = text.replace(/^>\s+/gm, "");
|
|
81
|
+
text = text.replace(/^[-*]{3,}$/gm, "");
|
|
82
|
+
text = text.replace(/^[\s]*[-*+]\s+/gm, "");
|
|
83
|
+
text = text.replace(/^[\s]*\d+\.\s+/gm, "");
|
|
84
|
+
return text.replace(/\n\s*\n/g, "\n").replace(/\s+/g, " ").trim();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { cn, slugify, stripHtml, stripMarkdown, throttle };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const utils = require('../utils.cjs');
|
|
4
|
+
const yar = require('@btst/yar');
|
|
5
|
+
const client = require('better-call/client');
|
|
6
|
+
|
|
7
|
+
function defineClientPlugin(plugin) {
|
|
8
|
+
return plugin;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
exports.createApiClient = utils.createApiClient;
|
|
12
|
+
exports.createRoute = yar.createRoute;
|
|
13
|
+
exports.createRouter = yar.createRouter;
|
|
14
|
+
exports.createClient = client.createClient;
|
|
15
|
+
exports.defineClientPlugin = defineClientPlugin;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { C as ClientPlugin } from '../../shared/stack.ByOugz9d.cjs';
|
|
2
|
+
export { P as PluginOverrides } from '../../shared/stack.ByOugz9d.cjs';
|
|
3
|
+
import { createClient } from 'better-call/client';
|
|
4
|
+
export { createClient } from 'better-call/client';
|
|
5
|
+
import { Router, Endpoint } from 'better-call';
|
|
6
|
+
export { Route, createRoute, createRouter } from '@btst/yar';
|
|
7
|
+
import '@btst/db';
|
|
8
|
+
|
|
9
|
+
interface CreateApiClientOptions {
|
|
10
|
+
baseURL?: string;
|
|
11
|
+
basePath?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a Better Call API client with proper URL handling for both server and client side
|
|
15
|
+
* @param options - Configuration options
|
|
16
|
+
* @param options.baseURL - The base URL (e.g., 'http://localhost:3000'). If not provided, uses relative URLs (same domain)
|
|
17
|
+
* @param options.basePath - The API base path (defaults to '/')
|
|
18
|
+
* @template TRouter - The router type (Router or Record<string, Endpoint>)
|
|
19
|
+
*/
|
|
20
|
+
declare function createApiClient<TRouter extends Router | Record<string, Endpoint> = Record<string, Endpoint>>(options?: CreateApiClientOptions): ReturnType<typeof createClient<TRouter>>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Plugin utilities and types for building standalone plugins
|
|
24
|
+
*
|
|
25
|
+
* This module exports everything needed to create custom plugins
|
|
26
|
+
* for Better Stack outside of this package.
|
|
27
|
+
*
|
|
28
|
+
* Note: Backend and Client plugins are separate to prevent SSR issues
|
|
29
|
+
* and enable better code splitting. Import them separately:
|
|
30
|
+
* - Backend: import type { BackendPlugin } from "@btst/stack/plugins/api"
|
|
31
|
+
* - Client: import type { ClientPlugin } from "@btst/stack/plugins/client"
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Helper to define a client plugin with full type inference
|
|
36
|
+
*
|
|
37
|
+
* Automatically infers route keys, hook names, and their types without needing casts.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const messagesPlugin = defineClientPlugin({
|
|
42
|
+
* name: "messages",
|
|
43
|
+
* routes: () => ({
|
|
44
|
+
* messagesList: createRoute("/messages", () => ({ ... }))
|
|
45
|
+
* }),
|
|
46
|
+
* hooks: () => ({
|
|
47
|
+
* useMessages: () => { ... }
|
|
48
|
+
* })
|
|
49
|
+
* });
|
|
50
|
+
* // No casts needed - route keys, hook names, and types are all preserved!
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @template TPlugin - The exact plugin definition (auto-inferred)
|
|
54
|
+
*/
|
|
55
|
+
declare function defineClientPlugin<TPlugin extends ClientPlugin<any, any>>(plugin: TPlugin): TPlugin;
|
|
56
|
+
|
|
57
|
+
export { ClientPlugin, createApiClient, defineClientPlugin };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { C as ClientPlugin } from '../../shared/stack.ByOugz9d.mjs';
|
|
2
|
+
export { P as PluginOverrides } from '../../shared/stack.ByOugz9d.mjs';
|
|
3
|
+
import { createClient } from 'better-call/client';
|
|
4
|
+
export { createClient } from 'better-call/client';
|
|
5
|
+
import { Router, Endpoint } from 'better-call';
|
|
6
|
+
export { Route, createRoute, createRouter } from '@btst/yar';
|
|
7
|
+
import '@btst/db';
|
|
8
|
+
|
|
9
|
+
interface CreateApiClientOptions {
|
|
10
|
+
baseURL?: string;
|
|
11
|
+
basePath?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a Better Call API client with proper URL handling for both server and client side
|
|
15
|
+
* @param options - Configuration options
|
|
16
|
+
* @param options.baseURL - The base URL (e.g., 'http://localhost:3000'). If not provided, uses relative URLs (same domain)
|
|
17
|
+
* @param options.basePath - The API base path (defaults to '/')
|
|
18
|
+
* @template TRouter - The router type (Router or Record<string, Endpoint>)
|
|
19
|
+
*/
|
|
20
|
+
declare function createApiClient<TRouter extends Router | Record<string, Endpoint> = Record<string, Endpoint>>(options?: CreateApiClientOptions): ReturnType<typeof createClient<TRouter>>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Plugin utilities and types for building standalone plugins
|
|
24
|
+
*
|
|
25
|
+
* This module exports everything needed to create custom plugins
|
|
26
|
+
* for Better Stack outside of this package.
|
|
27
|
+
*
|
|
28
|
+
* Note: Backend and Client plugins are separate to prevent SSR issues
|
|
29
|
+
* and enable better code splitting. Import them separately:
|
|
30
|
+
* - Backend: import type { BackendPlugin } from "@btst/stack/plugins/api"
|
|
31
|
+
* - Client: import type { ClientPlugin } from "@btst/stack/plugins/client"
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Helper to define a client plugin with full type inference
|
|
36
|
+
*
|
|
37
|
+
* Automatically infers route keys, hook names, and their types without needing casts.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const messagesPlugin = defineClientPlugin({
|
|
42
|
+
* name: "messages",
|
|
43
|
+
* routes: () => ({
|
|
44
|
+
* messagesList: createRoute("/messages", () => ({ ... }))
|
|
45
|
+
* }),
|
|
46
|
+
* hooks: () => ({
|
|
47
|
+
* useMessages: () => { ... }
|
|
48
|
+
* })
|
|
49
|
+
* });
|
|
50
|
+
* // No casts needed - route keys, hook names, and types are all preserved!
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @template TPlugin - The exact plugin definition (auto-inferred)
|
|
54
|
+
*/
|
|
55
|
+
declare function defineClientPlugin<TPlugin extends ClientPlugin<any, any>>(plugin: TPlugin): TPlugin;
|
|
56
|
+
|
|
57
|
+
export { ClientPlugin, createApiClient, defineClientPlugin };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { C as ClientPlugin } from '../../shared/stack.ByOugz9d.js';
|
|
2
|
+
export { P as PluginOverrides } from '../../shared/stack.ByOugz9d.js';
|
|
3
|
+
import { createClient } from 'better-call/client';
|
|
4
|
+
export { createClient } from 'better-call/client';
|
|
5
|
+
import { Router, Endpoint } from 'better-call';
|
|
6
|
+
export { Route, createRoute, createRouter } from '@btst/yar';
|
|
7
|
+
import '@btst/db';
|
|
8
|
+
|
|
9
|
+
interface CreateApiClientOptions {
|
|
10
|
+
baseURL?: string;
|
|
11
|
+
basePath?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a Better Call API client with proper URL handling for both server and client side
|
|
15
|
+
* @param options - Configuration options
|
|
16
|
+
* @param options.baseURL - The base URL (e.g., 'http://localhost:3000'). If not provided, uses relative URLs (same domain)
|
|
17
|
+
* @param options.basePath - The API base path (defaults to '/')
|
|
18
|
+
* @template TRouter - The router type (Router or Record<string, Endpoint>)
|
|
19
|
+
*/
|
|
20
|
+
declare function createApiClient<TRouter extends Router | Record<string, Endpoint> = Record<string, Endpoint>>(options?: CreateApiClientOptions): ReturnType<typeof createClient<TRouter>>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Plugin utilities and types for building standalone plugins
|
|
24
|
+
*
|
|
25
|
+
* This module exports everything needed to create custom plugins
|
|
26
|
+
* for Better Stack outside of this package.
|
|
27
|
+
*
|
|
28
|
+
* Note: Backend and Client plugins are separate to prevent SSR issues
|
|
29
|
+
* and enable better code splitting. Import them separately:
|
|
30
|
+
* - Backend: import type { BackendPlugin } from "@btst/stack/plugins/api"
|
|
31
|
+
* - Client: import type { ClientPlugin } from "@btst/stack/plugins/client"
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Helper to define a client plugin with full type inference
|
|
36
|
+
*
|
|
37
|
+
* Automatically infers route keys, hook names, and their types without needing casts.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const messagesPlugin = defineClientPlugin({
|
|
42
|
+
* name: "messages",
|
|
43
|
+
* routes: () => ({
|
|
44
|
+
* messagesList: createRoute("/messages", () => ({ ... }))
|
|
45
|
+
* }),
|
|
46
|
+
* hooks: () => ({
|
|
47
|
+
* useMessages: () => { ... }
|
|
48
|
+
* })
|
|
49
|
+
* });
|
|
50
|
+
* // No casts needed - route keys, hook names, and types are all preserved!
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @template TPlugin - The exact plugin definition (auto-inferred)
|
|
54
|
+
*/
|
|
55
|
+
declare function defineClientPlugin<TPlugin extends ClientPlugin<any, any>>(plugin: TPlugin): TPlugin;
|
|
56
|
+
|
|
57
|
+
export { ClientPlugin, createApiClient, defineClientPlugin };
|
|
@@ -39,6 +39,11 @@ interface ClientPlugin<TOverrides = Record<string, never>, TRoutes extends Recor
|
|
|
39
39
|
* Returns yar routes that will be composed into the router
|
|
40
40
|
*/
|
|
41
41
|
routes: () => TRoutes;
|
|
42
|
+
/**
|
|
43
|
+
* Optional sitemap generator for this plugin. Should return absolute URLs.
|
|
44
|
+
* Implementations can call their own API endpoints to include dynamic routes.
|
|
45
|
+
*/
|
|
46
|
+
sitemap?: () => Promise<Sitemap> | Sitemap;
|
|
42
47
|
}
|
|
43
48
|
/**
|
|
44
49
|
* Configuration for creating the backend library
|
|
@@ -111,6 +116,17 @@ type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) exten
|
|
|
111
116
|
*/
|
|
112
117
|
interface ClientLib<TRoutes extends Record<string, Route> = Record<string, Route>> {
|
|
113
118
|
router: ReturnType<typeof createRouter<TRoutes, {}>>;
|
|
119
|
+
generateSitemap: () => Promise<Sitemap>;
|
|
114
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Minimal sitemap entry shape aligned with Next.js MetadataRoute.Sitemap
|
|
123
|
+
*/
|
|
124
|
+
type SitemapEntry = {
|
|
125
|
+
url: string;
|
|
126
|
+
lastModified?: string | Date;
|
|
127
|
+
changeFrequency?: "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
|
|
128
|
+
priority?: number;
|
|
129
|
+
};
|
|
130
|
+
type Sitemap = Array<SitemapEntry>;
|
|
115
131
|
|
|
116
|
-
export type { BackendPlugin as B, ClientPlugin as C,
|
|
132
|
+
export type { BackendPlugin as B, ClientPlugin as C, PluginOverrides as P, Sitemap as S, PluginRoutes as a, ClientLibConfig as b, ClientLib as c, PrefixedPluginRoutes as d, BackendLibConfig as e, BackendLib as f };
|
|
@@ -39,6 +39,11 @@ interface ClientPlugin<TOverrides = Record<string, never>, TRoutes extends Recor
|
|
|
39
39
|
* Returns yar routes that will be composed into the router
|
|
40
40
|
*/
|
|
41
41
|
routes: () => TRoutes;
|
|
42
|
+
/**
|
|
43
|
+
* Optional sitemap generator for this plugin. Should return absolute URLs.
|
|
44
|
+
* Implementations can call their own API endpoints to include dynamic routes.
|
|
45
|
+
*/
|
|
46
|
+
sitemap?: () => Promise<Sitemap> | Sitemap;
|
|
42
47
|
}
|
|
43
48
|
/**
|
|
44
49
|
* Configuration for creating the backend library
|
|
@@ -111,6 +116,17 @@ type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) exten
|
|
|
111
116
|
*/
|
|
112
117
|
interface ClientLib<TRoutes extends Record<string, Route> = Record<string, Route>> {
|
|
113
118
|
router: ReturnType<typeof createRouter<TRoutes, {}>>;
|
|
119
|
+
generateSitemap: () => Promise<Sitemap>;
|
|
114
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Minimal sitemap entry shape aligned with Next.js MetadataRoute.Sitemap
|
|
123
|
+
*/
|
|
124
|
+
type SitemapEntry = {
|
|
125
|
+
url: string;
|
|
126
|
+
lastModified?: string | Date;
|
|
127
|
+
changeFrequency?: "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
|
|
128
|
+
priority?: number;
|
|
129
|
+
};
|
|
130
|
+
type Sitemap = Array<SitemapEntry>;
|
|
115
131
|
|
|
116
|
-
export type { BackendPlugin as B, ClientPlugin as C,
|
|
132
|
+
export type { BackendPlugin as B, ClientPlugin as C, PluginOverrides as P, Sitemap as S, PluginRoutes as a, ClientLibConfig as b, ClientLib as c, PrefixedPluginRoutes as d, BackendLibConfig as e, BackendLib as f };
|
|
@@ -39,6 +39,11 @@ interface ClientPlugin<TOverrides = Record<string, never>, TRoutes extends Recor
|
|
|
39
39
|
* Returns yar routes that will be composed into the router
|
|
40
40
|
*/
|
|
41
41
|
routes: () => TRoutes;
|
|
42
|
+
/**
|
|
43
|
+
* Optional sitemap generator for this plugin. Should return absolute URLs.
|
|
44
|
+
* Implementations can call their own API endpoints to include dynamic routes.
|
|
45
|
+
*/
|
|
46
|
+
sitemap?: () => Promise<Sitemap> | Sitemap;
|
|
42
47
|
}
|
|
43
48
|
/**
|
|
44
49
|
* Configuration for creating the backend library
|
|
@@ -111,6 +116,17 @@ type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) exten
|
|
|
111
116
|
*/
|
|
112
117
|
interface ClientLib<TRoutes extends Record<string, Route> = Record<string, Route>> {
|
|
113
118
|
router: ReturnType<typeof createRouter<TRoutes, {}>>;
|
|
119
|
+
generateSitemap: () => Promise<Sitemap>;
|
|
114
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Minimal sitemap entry shape aligned with Next.js MetadataRoute.Sitemap
|
|
123
|
+
*/
|
|
124
|
+
type SitemapEntry = {
|
|
125
|
+
url: string;
|
|
126
|
+
lastModified?: string | Date;
|
|
127
|
+
changeFrequency?: "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
|
|
128
|
+
priority?: number;
|
|
129
|
+
};
|
|
130
|
+
type Sitemap = Array<SitemapEntry>;
|
|
115
131
|
|
|
116
|
-
export type { BackendPlugin as B, ClientPlugin as C,
|
|
132
|
+
export type { BackendPlugin as B, ClientPlugin as C, PluginOverrides as P, Sitemap as S, PluginRoutes as a, ClientLibConfig as b, ClientLib as c, PrefixedPluginRoutes as d, BackendLibConfig as e, BackendLib as f };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
type Post = {
|
|
4
|
+
id: string;
|
|
5
|
+
authorId?: string;
|
|
6
|
+
defaultLocale?: string;
|
|
7
|
+
slug: string;
|
|
8
|
+
title: string;
|
|
9
|
+
content: string;
|
|
10
|
+
excerpt: string;
|
|
11
|
+
image?: string;
|
|
12
|
+
published: boolean;
|
|
13
|
+
status?: "DRAFT" | "PUBLISHED";
|
|
14
|
+
tags: Tag[];
|
|
15
|
+
publishedAt?: Date;
|
|
16
|
+
createdAt: Date;
|
|
17
|
+
updatedAt: Date;
|
|
18
|
+
};
|
|
19
|
+
type Tag = {
|
|
20
|
+
id: string;
|
|
21
|
+
slug: string;
|
|
22
|
+
name: string;
|
|
23
|
+
createdAt: Date;
|
|
24
|
+
updatedAt: Date;
|
|
25
|
+
};
|
|
26
|
+
interface SerializedPost extends Omit<Post, "createdAt" | "updatedAt" | "publishedAt" | "tags"> {
|
|
27
|
+
tags: SerializedTag[];
|
|
28
|
+
publishedAt?: string;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
updatedAt: string;
|
|
31
|
+
}
|
|
32
|
+
interface SerializedTag extends Omit<Tag, "createdAt" | "updatedAt"> {
|
|
33
|
+
createdAt: string;
|
|
34
|
+
updatedAt: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare const createPostSchema: z.ZodObject<{
|
|
38
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
39
|
+
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
40
|
+
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
41
|
+
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
42
|
+
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
43
|
+
title: z.ZodString;
|
|
44
|
+
content: z.ZodString;
|
|
45
|
+
excerpt: z.ZodString;
|
|
46
|
+
image: z.ZodOptional<z.ZodString>;
|
|
47
|
+
tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
48
|
+
name: z.ZodString;
|
|
49
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
50
|
+
id: z.ZodString;
|
|
51
|
+
name: z.ZodString;
|
|
52
|
+
slug: z.ZodString;
|
|
53
|
+
}, z.core.$strip>]>>>>;
|
|
54
|
+
}, z.core.$strip>;
|
|
55
|
+
declare const updatePostSchema: z.ZodObject<{
|
|
56
|
+
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
57
|
+
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
58
|
+
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
59
|
+
title: z.ZodString;
|
|
60
|
+
content: z.ZodString;
|
|
61
|
+
excerpt: z.ZodString;
|
|
62
|
+
image: z.ZodOptional<z.ZodString>;
|
|
63
|
+
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
64
|
+
slug: z.ZodString;
|
|
65
|
+
tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
66
|
+
name: z.ZodString;
|
|
67
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
68
|
+
id: z.ZodString;
|
|
69
|
+
name: z.ZodString;
|
|
70
|
+
slug: z.ZodString;
|
|
71
|
+
}, z.core.$strip>]>>>>;
|
|
72
|
+
id: z.ZodString;
|
|
73
|
+
}, z.core.$strip>;
|
|
74
|
+
|
|
75
|
+
export { createPostSchema as c, updatePostSchema as u };
|
|
76
|
+
export type { Post as P, SerializedPost as S, Tag as T, SerializedTag as a };
|