@xexr/blog-platform 1.0.7 → 1.0.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/CHANGELOG.md +7 -0
- package/dist/app/blog/[slug]/page.d.ts +68 -0
- package/dist/app/blog/[slug]/page.tsx +155 -113
- package/dist/components/ArticleReadingProgress.tsx +208 -0
- package/dist/components/ArticleTopActions.tsx +179 -0
- package/dist/components/AuthorByline.tsx +569 -0
- package/dist/components/ExpandableArticleImage.tsx +79 -0
- package/dist/components/Pagination.tsx +236 -0
- package/dist/components/TopicArchivePages.tsx +204 -0
- package/dist/components/ui/badge.tsx +36 -0
- package/dist/components/ui/button.tsx +59 -0
- package/dist/components/ui/card.tsx +92 -0
- package/dist/components/ui/pagination.tsx +127 -0
- package/dist/components/ui/separator.tsx +29 -0
- package/dist/index.d.mts +59 -69
- package/dist/index.d.ts +59 -69
- package/dist/index.js +83 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +83 -8
- package/dist/index.mjs.map +1 -1
- package/dist/lib/article-ui.ts +158 -0
- package/dist/lib/auth.ts +354 -0
- package/dist/lib/cors.ts +243 -0
- package/dist/lib/database.ts +277 -0
- package/dist/lib/init.ts +186 -0
- package/dist/lib/mdx.ts +73 -0
- package/dist/lib/metadata.ts +558 -0
- package/dist/lib/ratelimit.ts +224 -0
- package/dist/lib/security-headers.ts +322 -0
- package/dist/lib/seo.ts +295 -0
- package/dist/lib/sitemap.ts +719 -0
- package/dist/lib/storage/drizzle.ts +400 -0
- package/dist/lib/structured-data.ts +608 -0
- package/dist/lib/topics.ts +56 -0
- package/dist/lib/urls.ts +29 -0
- package/dist/lib/utils.ts +6 -0
- package/dist/lib/version.ts +154 -0
- package/dist/types/contracts.ts +256 -0
- package/dist/types/index.d.mts +18 -1
- package/dist/types/index.d.ts +18 -1
- package/dist/types/index.ts +16 -0
- package/package.json +14 -9
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import {
|
|
3
|
+
ChevronLeftIcon,
|
|
4
|
+
ChevronRightIcon,
|
|
5
|
+
MoreHorizontalIcon,
|
|
6
|
+
} from "lucide-react"
|
|
7
|
+
|
|
8
|
+
import { cn } from "../../lib/utils"
|
|
9
|
+
import { buttonVariants } from "./button"
|
|
10
|
+
|
|
11
|
+
function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
|
|
12
|
+
return (
|
|
13
|
+
<nav
|
|
14
|
+
role="navigation"
|
|
15
|
+
aria-label="pagination"
|
|
16
|
+
data-slot="pagination"
|
|
17
|
+
className={cn("mx-auto flex w-full justify-center", className)}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function PaginationContent({
|
|
24
|
+
className,
|
|
25
|
+
...props
|
|
26
|
+
}: React.ComponentProps<"ul">) {
|
|
27
|
+
return (
|
|
28
|
+
<ul
|
|
29
|
+
data-slot="pagination-content"
|
|
30
|
+
className={cn("flex flex-row items-center gap-1", className)}
|
|
31
|
+
{...props}
|
|
32
|
+
/>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function PaginationItem({ ...props }: React.ComponentProps<"li">) {
|
|
37
|
+
return <li data-slot="pagination-item" {...props} />
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
type PaginationLinkProps = {
|
|
41
|
+
isActive?: boolean
|
|
42
|
+
size?: "default" | "sm" | "lg" | "icon"
|
|
43
|
+
} & React.ComponentProps<"a">
|
|
44
|
+
|
|
45
|
+
function PaginationLink({
|
|
46
|
+
className,
|
|
47
|
+
isActive,
|
|
48
|
+
size = "icon",
|
|
49
|
+
...props
|
|
50
|
+
}: PaginationLinkProps) {
|
|
51
|
+
return (
|
|
52
|
+
<a
|
|
53
|
+
aria-current={isActive ? "page" : undefined}
|
|
54
|
+
data-slot="pagination-link"
|
|
55
|
+
data-active={isActive}
|
|
56
|
+
className={cn(
|
|
57
|
+
buttonVariants({
|
|
58
|
+
variant: isActive ? "outline" : "ghost",
|
|
59
|
+
size,
|
|
60
|
+
}),
|
|
61
|
+
className
|
|
62
|
+
)}
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function PaginationPrevious({
|
|
69
|
+
className,
|
|
70
|
+
...props
|
|
71
|
+
}: React.ComponentProps<typeof PaginationLink>) {
|
|
72
|
+
return (
|
|
73
|
+
<PaginationLink
|
|
74
|
+
aria-label="Go to previous page"
|
|
75
|
+
size="default"
|
|
76
|
+
className={cn("gap-1 px-2.5 sm:pl-2.5", className)}
|
|
77
|
+
{...props}
|
|
78
|
+
>
|
|
79
|
+
<ChevronLeftIcon />
|
|
80
|
+
<span className="hidden sm:block">Previous</span>
|
|
81
|
+
</PaginationLink>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function PaginationNext({
|
|
86
|
+
className,
|
|
87
|
+
...props
|
|
88
|
+
}: React.ComponentProps<typeof PaginationLink>) {
|
|
89
|
+
return (
|
|
90
|
+
<PaginationLink
|
|
91
|
+
aria-label="Go to next page"
|
|
92
|
+
size="default"
|
|
93
|
+
className={cn("gap-1 px-2.5 sm:pr-2.5", className)}
|
|
94
|
+
{...props}
|
|
95
|
+
>
|
|
96
|
+
<span className="hidden sm:block">Next</span>
|
|
97
|
+
<ChevronRightIcon />
|
|
98
|
+
</PaginationLink>
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function PaginationEllipsis({
|
|
103
|
+
className,
|
|
104
|
+
...props
|
|
105
|
+
}: React.ComponentProps<"span">) {
|
|
106
|
+
return (
|
|
107
|
+
<span
|
|
108
|
+
aria-hidden
|
|
109
|
+
data-slot="pagination-ellipsis"
|
|
110
|
+
className={cn("flex size-9 items-center justify-center", className)}
|
|
111
|
+
{...props}
|
|
112
|
+
>
|
|
113
|
+
<MoreHorizontalIcon className="size-4" />
|
|
114
|
+
<span className="sr-only">More pages</span>
|
|
115
|
+
</span>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export {
|
|
120
|
+
Pagination,
|
|
121
|
+
PaginationContent,
|
|
122
|
+
PaginationLink,
|
|
123
|
+
PaginationItem,
|
|
124
|
+
PaginationPrevious,
|
|
125
|
+
PaginationNext,
|
|
126
|
+
PaginationEllipsis,
|
|
127
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import * as SeparatorPrimitive from "@radix-ui/react-separator"
|
|
3
|
+
|
|
4
|
+
import { cn } from "../../lib/utils"
|
|
5
|
+
|
|
6
|
+
const Separator = React.forwardRef<
|
|
7
|
+
React.ElementRef<typeof SeparatorPrimitive.Root>,
|
|
8
|
+
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
|
|
9
|
+
>(
|
|
10
|
+
(
|
|
11
|
+
{ className, orientation = "horizontal", decorative = true, ...props },
|
|
12
|
+
ref
|
|
13
|
+
) => (
|
|
14
|
+
<SeparatorPrimitive.Root
|
|
15
|
+
ref={ref}
|
|
16
|
+
decorative={decorative}
|
|
17
|
+
orientation={orientation}
|
|
18
|
+
className={cn(
|
|
19
|
+
"shrink-0 bg-border",
|
|
20
|
+
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
|
|
21
|
+
className
|
|
22
|
+
)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
)
|
|
26
|
+
)
|
|
27
|
+
Separator.displayName = SeparatorPrimitive.Root.displayName
|
|
28
|
+
|
|
29
|
+
export { Separator }
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PublishedArticle, PublishedSite, PublishedTopic, PublishResult, PublishedAuthor } from './types/index.mjs';
|
|
2
|
-
export { PublishPayload } from './types/index.mjs';
|
|
2
|
+
export { PublishPayload, PublishedAuthorSocialLinks } from './types/index.mjs';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import { CSSProperties } from 'react';
|
|
5
|
+
import { CSSProperties, ReactElement } from 'react';
|
|
6
6
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
7
7
|
import { VariantProps } from 'class-variance-authority';
|
|
8
8
|
import { ClassValue } from 'clsx';
|
|
@@ -100,78 +100,68 @@ declare function generateBlogHomeMetadata(siteName?: string, siteDescription?: s
|
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
interface ArticlePageProps {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
label?: string;
|
|
110
|
-
};
|
|
111
|
-
previousArticle?: {
|
|
112
|
-
url: string;
|
|
113
|
-
title: string;
|
|
114
|
-
featuredImage?: string;
|
|
115
|
-
featuredImageAlt?: string;
|
|
116
|
-
};
|
|
117
|
-
nextArticle?: {
|
|
118
|
-
url: string;
|
|
119
|
-
title: string;
|
|
120
|
-
featuredImage?: string;
|
|
121
|
-
featuredImageAlt?: string;
|
|
122
|
-
};
|
|
103
|
+
article: PublishedArticle;
|
|
104
|
+
className?: string;
|
|
105
|
+
navigation?: {
|
|
106
|
+
backToHome?: {
|
|
107
|
+
url: string;
|
|
108
|
+
label?: string;
|
|
123
109
|
};
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
postArticleCta?: {
|
|
130
|
-
title: string;
|
|
131
|
-
description?: string;
|
|
132
|
-
href: string;
|
|
133
|
-
label: string;
|
|
110
|
+
previousArticle?: {
|
|
111
|
+
url: string;
|
|
112
|
+
title: string;
|
|
113
|
+
featuredImage?: string;
|
|
114
|
+
featuredImageAlt?: string;
|
|
134
115
|
};
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
116
|
+
nextArticle?: {
|
|
117
|
+
url: string;
|
|
118
|
+
title: string;
|
|
119
|
+
featuredImage?: string;
|
|
120
|
+
featuredImageAlt?: string;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
basePath?: string;
|
|
124
|
+
theme?: BlogTheme;
|
|
125
|
+
postArticleCta?: {
|
|
126
|
+
title: string;
|
|
127
|
+
description?: string;
|
|
128
|
+
href: string;
|
|
129
|
+
label: string;
|
|
130
|
+
};
|
|
131
|
+
relatedArticles?: PublishedArticle[];
|
|
132
|
+
showShareLinks?: boolean;
|
|
139
133
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
134
|
+
|
|
135
|
+
declare function ArticlePage(props: ArticlePageProps): ReactElement;
|
|
136
|
+
|
|
137
|
+
declare function generateArticleMetadata(
|
|
138
|
+
article: PublishedArticle,
|
|
139
|
+
basePath?: string,
|
|
140
|
+
): {
|
|
141
|
+
title: string;
|
|
142
|
+
description: string;
|
|
143
|
+
keywords: string;
|
|
144
|
+
authors: { name: string }[] | undefined;
|
|
145
|
+
openGraph: {
|
|
146
146
|
title: string;
|
|
147
147
|
description: string;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
};
|
|
166
|
-
twitter: {
|
|
167
|
-
card: string;
|
|
168
|
-
title: string;
|
|
169
|
-
description: string;
|
|
170
|
-
images: string[] | undefined;
|
|
171
|
-
};
|
|
172
|
-
alternates: {
|
|
173
|
-
canonical: string;
|
|
174
|
-
};
|
|
148
|
+
type: string;
|
|
149
|
+
url: string;
|
|
150
|
+
images: { url: string; alt: string }[] | undefined;
|
|
151
|
+
publishedTime: string;
|
|
152
|
+
modifiedTime: string;
|
|
153
|
+
authors: string[] | undefined;
|
|
154
|
+
siteName: string;
|
|
155
|
+
};
|
|
156
|
+
twitter: {
|
|
157
|
+
card: string;
|
|
158
|
+
title: string;
|
|
159
|
+
description: string;
|
|
160
|
+
images: string[] | undefined;
|
|
161
|
+
};
|
|
162
|
+
alternates: {
|
|
163
|
+
canonical: string;
|
|
164
|
+
};
|
|
175
165
|
};
|
|
176
166
|
|
|
177
167
|
interface PaginationProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PublishedArticle, PublishedSite, PublishedTopic, PublishResult, PublishedAuthor } from './types/index.js';
|
|
2
|
-
export { PublishPayload } from './types/index.js';
|
|
2
|
+
export { PublishPayload, PublishedAuthorSocialLinks } from './types/index.js';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import { CSSProperties } from 'react';
|
|
5
|
+
import { CSSProperties, ReactElement } from 'react';
|
|
6
6
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
7
7
|
import { VariantProps } from 'class-variance-authority';
|
|
8
8
|
import { ClassValue } from 'clsx';
|
|
@@ -100,78 +100,68 @@ declare function generateBlogHomeMetadata(siteName?: string, siteDescription?: s
|
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
interface ArticlePageProps {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
label?: string;
|
|
110
|
-
};
|
|
111
|
-
previousArticle?: {
|
|
112
|
-
url: string;
|
|
113
|
-
title: string;
|
|
114
|
-
featuredImage?: string;
|
|
115
|
-
featuredImageAlt?: string;
|
|
116
|
-
};
|
|
117
|
-
nextArticle?: {
|
|
118
|
-
url: string;
|
|
119
|
-
title: string;
|
|
120
|
-
featuredImage?: string;
|
|
121
|
-
featuredImageAlt?: string;
|
|
122
|
-
};
|
|
103
|
+
article: PublishedArticle;
|
|
104
|
+
className?: string;
|
|
105
|
+
navigation?: {
|
|
106
|
+
backToHome?: {
|
|
107
|
+
url: string;
|
|
108
|
+
label?: string;
|
|
123
109
|
};
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
postArticleCta?: {
|
|
130
|
-
title: string;
|
|
131
|
-
description?: string;
|
|
132
|
-
href: string;
|
|
133
|
-
label: string;
|
|
110
|
+
previousArticle?: {
|
|
111
|
+
url: string;
|
|
112
|
+
title: string;
|
|
113
|
+
featuredImage?: string;
|
|
114
|
+
featuredImageAlt?: string;
|
|
134
115
|
};
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
116
|
+
nextArticle?: {
|
|
117
|
+
url: string;
|
|
118
|
+
title: string;
|
|
119
|
+
featuredImage?: string;
|
|
120
|
+
featuredImageAlt?: string;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
basePath?: string;
|
|
124
|
+
theme?: BlogTheme;
|
|
125
|
+
postArticleCta?: {
|
|
126
|
+
title: string;
|
|
127
|
+
description?: string;
|
|
128
|
+
href: string;
|
|
129
|
+
label: string;
|
|
130
|
+
};
|
|
131
|
+
relatedArticles?: PublishedArticle[];
|
|
132
|
+
showShareLinks?: boolean;
|
|
139
133
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
134
|
+
|
|
135
|
+
declare function ArticlePage(props: ArticlePageProps): ReactElement;
|
|
136
|
+
|
|
137
|
+
declare function generateArticleMetadata(
|
|
138
|
+
article: PublishedArticle,
|
|
139
|
+
basePath?: string,
|
|
140
|
+
): {
|
|
141
|
+
title: string;
|
|
142
|
+
description: string;
|
|
143
|
+
keywords: string;
|
|
144
|
+
authors: { name: string }[] | undefined;
|
|
145
|
+
openGraph: {
|
|
146
146
|
title: string;
|
|
147
147
|
description: string;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
};
|
|
166
|
-
twitter: {
|
|
167
|
-
card: string;
|
|
168
|
-
title: string;
|
|
169
|
-
description: string;
|
|
170
|
-
images: string[] | undefined;
|
|
171
|
-
};
|
|
172
|
-
alternates: {
|
|
173
|
-
canonical: string;
|
|
174
|
-
};
|
|
148
|
+
type: string;
|
|
149
|
+
url: string;
|
|
150
|
+
images: { url: string; alt: string }[] | undefined;
|
|
151
|
+
publishedTime: string;
|
|
152
|
+
modifiedTime: string;
|
|
153
|
+
authors: string[] | undefined;
|
|
154
|
+
siteName: string;
|
|
155
|
+
};
|
|
156
|
+
twitter: {
|
|
157
|
+
card: string;
|
|
158
|
+
title: string;
|
|
159
|
+
description: string;
|
|
160
|
+
images: string[] | undefined;
|
|
161
|
+
};
|
|
162
|
+
alternates: {
|
|
163
|
+
canonical: string;
|
|
164
|
+
};
|
|
175
165
|
};
|
|
176
166
|
|
|
177
167
|
interface PaginationProps {
|