@xexr/blog-platform 1.0.15 → 1.0.17
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/blog/[slug]/page.d.ts +3 -6
- package/dist/app/blog/[slug]/page.mdx-security.test.ts +135 -0
- package/dist/app/blog/[slug]/page.tsx +37 -19
- package/dist/index-Dr8HaKGm.d.mts +229 -0
- package/dist/index-Dr8HaKGm.d.ts +229 -0
- package/dist/index.d.mts +7 -10
- package/dist/index.d.ts +7 -10
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -11
- package/dist/index.mjs.map +1 -1
- package/dist/lib/mdx.ts +46 -2
- package/dist/lib/related-articles.d.mts +17 -0
- package/dist/lib/related-articles.d.ts +17 -0
- package/dist/lib/related-articles.js +2 -0
- package/dist/lib/related-articles.js.map +1 -0
- package/dist/lib/related-articles.mjs +2 -0
- package/dist/lib/related-articles.mjs.map +1 -0
- package/dist/lib/related-articles.ts +90 -0
- package/dist/{sitemap-BPTdXb9C.d.ts → sitemap-BmCh8BpN.d.ts} +1 -1
- package/dist/{sitemap-Dz9DB7py.d.mts → sitemap-Dbl4CUGI.d.mts} +1 -1
- package/dist/sitemap.d.mts +2 -2
- package/dist/sitemap.d.ts +2 -2
- package/dist/types/contracts.ts +31 -0
- package/dist/types/index.d.mts +1 -205
- package/dist/types/index.d.ts +1 -205
- package/package.json +8 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API contracts for the @xexr/blog-platform package.
|
|
3
|
+
*
|
|
4
|
+
* These types define the public interface between Bloggy and external blog platforms.
|
|
5
|
+
* They must remain stable and backward-compatible to ensure smooth upgrades.
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: These contracts should never import from the main Bloggy application
|
|
8
|
+
* to maintain clean separation of concerns and prevent coupling.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Public profile and social links for an author.
|
|
12
|
+
*/
|
|
13
|
+
interface PublishedAuthorSocialLinks {
|
|
14
|
+
/** Author website or profile URL */
|
|
15
|
+
readonly website?: string;
|
|
16
|
+
/** X/Twitter profile URL */
|
|
17
|
+
readonly x?: string;
|
|
18
|
+
/** Legacy Twitter profile URL */
|
|
19
|
+
readonly twitter?: string;
|
|
20
|
+
/** LinkedIn profile URL */
|
|
21
|
+
readonly linkedin?: string;
|
|
22
|
+
/** GitHub profile URL */
|
|
23
|
+
readonly github?: string;
|
|
24
|
+
/** Public contact email address */
|
|
25
|
+
readonly email?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Represents a published author with essential information for bylines and attribution.
|
|
29
|
+
*/
|
|
30
|
+
interface PublishedAuthor {
|
|
31
|
+
/** Unique identifier for the author */
|
|
32
|
+
readonly id: string;
|
|
33
|
+
/** Author's full name */
|
|
34
|
+
readonly name: string;
|
|
35
|
+
/** URL-friendly slug for author pages */
|
|
36
|
+
readonly slug: string;
|
|
37
|
+
/** Author's bio/description (optional) */
|
|
38
|
+
readonly bio?: string;
|
|
39
|
+
/** Author avatar image URL (optional) */
|
|
40
|
+
readonly avatarUrl?: string;
|
|
41
|
+
/** Public profile and social links (optional) */
|
|
42
|
+
readonly socialLinks?: PublishedAuthorSocialLinks;
|
|
43
|
+
/** Pronouns for proper attribution */
|
|
44
|
+
readonly pronouns?: string;
|
|
45
|
+
/** Whether this is a guest author */
|
|
46
|
+
readonly isGuest: boolean;
|
|
47
|
+
/** Tone adjectives that describe this author's writing style */
|
|
48
|
+
readonly toneAdjectives: readonly string[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Represents a published site with essential metadata for blog rendering.
|
|
52
|
+
*/
|
|
53
|
+
interface PublishedSite {
|
|
54
|
+
/** Unique identifier for the site */
|
|
55
|
+
readonly id: string;
|
|
56
|
+
/** Site name/title */
|
|
57
|
+
readonly name: string;
|
|
58
|
+
/** Site tagline/subtitle */
|
|
59
|
+
readonly tagline: string;
|
|
60
|
+
/** Site description */
|
|
61
|
+
readonly description: string;
|
|
62
|
+
/** Primary domain for the site */
|
|
63
|
+
readonly domain: string;
|
|
64
|
+
/** Site-wide tone adjectives for content context */
|
|
65
|
+
readonly toneAdjectives: readonly string[];
|
|
66
|
+
/** Default locale/language code */
|
|
67
|
+
readonly locale: string;
|
|
68
|
+
/** Optional Bloggy-owned newsletter capture configuration */
|
|
69
|
+
readonly newsletter?: PublishedNewsletterSettings;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Public configuration for Bloggy-owned newsletter capture.
|
|
73
|
+
*/
|
|
74
|
+
interface PublishedNewsletterSettings {
|
|
75
|
+
/** Whether the capture form should render */
|
|
76
|
+
readonly enabled: boolean;
|
|
77
|
+
/** Form heading */
|
|
78
|
+
readonly title: string;
|
|
79
|
+
/** Form supporting copy */
|
|
80
|
+
readonly description: string;
|
|
81
|
+
/** Submit button label */
|
|
82
|
+
readonly buttonLabel: string;
|
|
83
|
+
/** Base URL for the Bloggy instance that receives subscriptions */
|
|
84
|
+
readonly captureBaseUrl: string;
|
|
85
|
+
/** Site-scoped public token used to validate public submissions */
|
|
86
|
+
readonly publicSubscribeToken: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Public post-article CTA configuration.
|
|
90
|
+
*/
|
|
91
|
+
interface PublishedArticleCta {
|
|
92
|
+
/** CTA heading */
|
|
93
|
+
readonly title: string;
|
|
94
|
+
/** Optional supporting copy */
|
|
95
|
+
readonly description?: string;
|
|
96
|
+
/** Primary sign-up action */
|
|
97
|
+
readonly primary?: PublishedArticleCtaAction;
|
|
98
|
+
/** Secondary learn-more action */
|
|
99
|
+
readonly secondary?: PublishedArticleCtaAction;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Public post-article CTA link.
|
|
103
|
+
*/
|
|
104
|
+
interface PublishedArticleCtaAction {
|
|
105
|
+
/** Button label */
|
|
106
|
+
readonly label: string;
|
|
107
|
+
/** Safe http(s) URL or same-site relative path */
|
|
108
|
+
readonly href: string;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Public topic/category taxonomy assigned to published articles.
|
|
112
|
+
*/
|
|
113
|
+
interface PublishedTopic {
|
|
114
|
+
/** Unique identifier for the topic */
|
|
115
|
+
readonly id: string;
|
|
116
|
+
/** Display name */
|
|
117
|
+
readonly name: string;
|
|
118
|
+
/** URL-friendly slug for topic archive routing */
|
|
119
|
+
readonly slug: string;
|
|
120
|
+
/** Optional public description */
|
|
121
|
+
readonly description?: string;
|
|
122
|
+
/** Whether this is the article's primary topic */
|
|
123
|
+
readonly isPrimary: boolean;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Represents a published article with all necessary metadata for rendering
|
|
127
|
+
* on external blog platforms.
|
|
128
|
+
*/
|
|
129
|
+
interface PublishedArticle {
|
|
130
|
+
/** Unique identifier for the article */
|
|
131
|
+
readonly id: string;
|
|
132
|
+
/** URL-friendly slug for routing */
|
|
133
|
+
readonly slug: string;
|
|
134
|
+
/** Article title/headline */
|
|
135
|
+
readonly title: string;
|
|
136
|
+
/** Brief excerpt/summary for meta descriptions and previews */
|
|
137
|
+
readonly excerpt: string;
|
|
138
|
+
/** Full article content in markdown format */
|
|
139
|
+
readonly content: string;
|
|
140
|
+
/** Estimated reading time in seconds */
|
|
141
|
+
readonly readingSeconds: number;
|
|
142
|
+
/** Word count for analytics */
|
|
143
|
+
readonly wordCount: number;
|
|
144
|
+
/** Publication date as ISO 8601 string */
|
|
145
|
+
readonly publishedAt: string;
|
|
146
|
+
/** Last updated date as ISO 8601 string */
|
|
147
|
+
readonly updatedAt: string;
|
|
148
|
+
/** Author information (can be null for anonymous posts) */
|
|
149
|
+
readonly author: PublishedAuthor | null;
|
|
150
|
+
/** Site information */
|
|
151
|
+
readonly site: PublishedSite;
|
|
152
|
+
/** Optional post-article call-to-action */
|
|
153
|
+
readonly cta?: PublishedArticleCta;
|
|
154
|
+
/** Public topic taxonomy assigned to the article */
|
|
155
|
+
readonly topics?: readonly PublishedTopic[];
|
|
156
|
+
/** Featured image URL (optional) */
|
|
157
|
+
readonly featuredImage?: string;
|
|
158
|
+
/** Alt text for featured image */
|
|
159
|
+
readonly featuredImageAlt?: string;
|
|
160
|
+
/** Caption displayed with the featured image */
|
|
161
|
+
readonly featuredImageCaption?: string;
|
|
162
|
+
/** Credit text displayed with the featured image */
|
|
163
|
+
readonly featuredImageCreditText?: string;
|
|
164
|
+
/** Optional URL for the featured image credit */
|
|
165
|
+
readonly featuredImageCreditUrl?: string;
|
|
166
|
+
/** Featured image R2 key for CDN optimization (optional) */
|
|
167
|
+
readonly featuredImageKey?: string;
|
|
168
|
+
/** SEO meta tags */
|
|
169
|
+
readonly meta: {
|
|
170
|
+
/** Meta title (defaults to article title if not provided) */
|
|
171
|
+
readonly title?: string;
|
|
172
|
+
/** Meta description (defaults to excerpt if not provided) */
|
|
173
|
+
readonly description?: string;
|
|
174
|
+
/** Canonical URL for SEO */
|
|
175
|
+
readonly canonicalUrl?: string;
|
|
176
|
+
/** Keywords for SEO */
|
|
177
|
+
readonly keywords: readonly string[];
|
|
178
|
+
/** Open Graph image URL */
|
|
179
|
+
readonly ogImage?: string;
|
|
180
|
+
};
|
|
181
|
+
/** Article version for optimistic locking */
|
|
182
|
+
readonly version: number;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Payload structure for publishing operations.
|
|
186
|
+
* Used when sending publish/unpublish requests to blog platforms.
|
|
187
|
+
*/
|
|
188
|
+
interface PublishPayload {
|
|
189
|
+
/** The article to publish */
|
|
190
|
+
readonly article: PublishedArticle;
|
|
191
|
+
/** Idempotency key to prevent duplicate operations */
|
|
192
|
+
readonly idempotencyKey: string;
|
|
193
|
+
/** Optional slug override (defaults to article.slug) */
|
|
194
|
+
readonly slug?: string;
|
|
195
|
+
/** Optional meta description override (defaults to article.excerpt) */
|
|
196
|
+
readonly metaDescription?: string;
|
|
197
|
+
/** Platform-specific configuration */
|
|
198
|
+
readonly platformConfig?: Record<string, unknown>;
|
|
199
|
+
/** Whether this is a dry run (validation only) */
|
|
200
|
+
readonly dryRun?: boolean;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Result structure returned from publishing operations.
|
|
204
|
+
*/
|
|
205
|
+
interface PublishResult {
|
|
206
|
+
/** Whether the operation was successful */
|
|
207
|
+
readonly success: boolean;
|
|
208
|
+
/** The published article URL if successful */
|
|
209
|
+
readonly url?: string;
|
|
210
|
+
/** Platform-specific post ID */
|
|
211
|
+
readonly platformPostId?: string;
|
|
212
|
+
/** Publication timestamp as ISO 8601 string */
|
|
213
|
+
readonly publishedAt?: string;
|
|
214
|
+
/** Error information if unsuccessful */
|
|
215
|
+
readonly error?: {
|
|
216
|
+
/** Error code (PUB001-PUB011) */
|
|
217
|
+
readonly code: string;
|
|
218
|
+
/** Human-readable error message */
|
|
219
|
+
readonly message: string;
|
|
220
|
+
/** Additional error details */
|
|
221
|
+
readonly details?: Record<string, unknown>;
|
|
222
|
+
};
|
|
223
|
+
/** Validation warnings (for dry runs or minor issues) */
|
|
224
|
+
readonly warnings?: readonly string[];
|
|
225
|
+
/** Idempotency key used for this operation */
|
|
226
|
+
readonly idempotencyKey: string;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export type { PublishedTopic as P, PublishedArticle as a, PublishedSite as b, PublishedAuthor as c, PublishedNewsletterSettings as d, PublishedArticleCta as e, PublishResult as f, PublishPayload as g, PublishedAuthorSocialLinks as h };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { PublishedArticle, PublishedSite, PublishedNewsletterSettings, PublishedAuthor, PublishResult, PublishedTopic } from './
|
|
2
|
-
export { PublishPayload, PublishedAuthorSocialLinks } from './
|
|
1
|
+
import { a as PublishedArticle, b as PublishedSite, d as PublishedNewsletterSettings, e as PublishedArticleCta, c as PublishedAuthor, f as PublishResult, P as PublishedTopic } from './index-Dr8HaKGm.mjs';
|
|
2
|
+
export { g as PublishPayload, h as PublishedAuthorSocialLinks } from './index-Dr8HaKGm.mjs';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { CSSProperties, ReactElement } from 'react';
|
|
5
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
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';
|
|
9
|
+
export { RelatedArticleCandidate, RelatedFeaturedArticlesOptions, getRelatedFeaturedArticles } from './lib/related-articles.mjs';
|
|
9
10
|
import { NextRequest, NextResponse } from 'next/server';
|
|
10
11
|
import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
|
|
11
12
|
import { LibSQLDatabase } from 'drizzle-orm/libsql';
|
|
12
|
-
import { C as CanonicalUrlOptions } from './sitemap-
|
|
13
|
-
export { B as BlogSitemapConfig, N as NextjsSitemapEntry, S as SitemapChangeFreq, a as SitemapData, b as SitemapEntry, c as SitemapOptions, d as createBlogSitemapRoute, e as createDynamicBlogSitemap, g as generateBlogSitemapEntries, f as generateCanonicalUrl, h as generateCanonicalUrlFromSlug, i as generateSitemap, j as generateSitemapIndex, k as getBaseUrl, l as isValidCanonicalUrl, n as normalizeDomain, m as normalizeSlug, s as sitemapToXml, u as updateArticleCanonicalUrl, v as validateSitemap } from './sitemap-
|
|
13
|
+
import { C as CanonicalUrlOptions } from './sitemap-Dbl4CUGI.mjs';
|
|
14
|
+
export { B as BlogSitemapConfig, N as NextjsSitemapEntry, S as SitemapChangeFreq, a as SitemapData, b as SitemapEntry, c as SitemapOptions, d as createBlogSitemapRoute, e as createDynamicBlogSitemap, g as generateBlogSitemapEntries, f as generateCanonicalUrl, h as generateCanonicalUrlFromSlug, i as generateSitemap, j as generateSitemapIndex, k as getBaseUrl, l as isValidCanonicalUrl, n as normalizeDomain, m as normalizeSlug, s as sitemapToXml, u as updateArticleCanonicalUrl, v as validateSitemap } from './sitemap-Dbl4CUGI.mjs';
|
|
14
15
|
|
|
15
16
|
interface BlogTheme {
|
|
16
17
|
accentColor?: string;
|
|
@@ -118,14 +119,10 @@ interface ArticlePageProps {
|
|
|
118
119
|
};
|
|
119
120
|
basePath?: string;
|
|
120
121
|
theme?: BlogTheme;
|
|
121
|
-
postArticleCta?:
|
|
122
|
-
title: string;
|
|
123
|
-
description?: string;
|
|
124
|
-
href: string;
|
|
125
|
-
label: string;
|
|
126
|
-
};
|
|
122
|
+
postArticleCta?: PublishedArticleCta;
|
|
127
123
|
newsletter?: PublishedNewsletterSettings;
|
|
128
124
|
newsletterPreviewMode?: boolean;
|
|
125
|
+
articles?: PublishedArticle[];
|
|
129
126
|
relatedArticles?: PublishedArticle[];
|
|
130
127
|
showShareLinks?: boolean;
|
|
131
128
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { PublishedArticle, PublishedSite, PublishedNewsletterSettings, PublishedAuthor, PublishResult, PublishedTopic } from './
|
|
2
|
-
export { PublishPayload, PublishedAuthorSocialLinks } from './
|
|
1
|
+
import { a as PublishedArticle, b as PublishedSite, d as PublishedNewsletterSettings, e as PublishedArticleCta, c as PublishedAuthor, f as PublishResult, P as PublishedTopic } from './index-Dr8HaKGm.js';
|
|
2
|
+
export { g as PublishPayload, h as PublishedAuthorSocialLinks } from './index-Dr8HaKGm.js';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { CSSProperties, ReactElement } from 'react';
|
|
5
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
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';
|
|
9
|
+
export { RelatedArticleCandidate, RelatedFeaturedArticlesOptions, getRelatedFeaturedArticles } from './lib/related-articles.js';
|
|
9
10
|
import { NextRequest, NextResponse } from 'next/server';
|
|
10
11
|
import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
|
|
11
12
|
import { LibSQLDatabase } from 'drizzle-orm/libsql';
|
|
12
|
-
import { C as CanonicalUrlOptions } from './sitemap-
|
|
13
|
-
export { B as BlogSitemapConfig, N as NextjsSitemapEntry, S as SitemapChangeFreq, a as SitemapData, b as SitemapEntry, c as SitemapOptions, d as createBlogSitemapRoute, e as createDynamicBlogSitemap, g as generateBlogSitemapEntries, f as generateCanonicalUrl, h as generateCanonicalUrlFromSlug, i as generateSitemap, j as generateSitemapIndex, k as getBaseUrl, l as isValidCanonicalUrl, n as normalizeDomain, m as normalizeSlug, s as sitemapToXml, u as updateArticleCanonicalUrl, v as validateSitemap } from './sitemap-
|
|
13
|
+
import { C as CanonicalUrlOptions } from './sitemap-BmCh8BpN.js';
|
|
14
|
+
export { B as BlogSitemapConfig, N as NextjsSitemapEntry, S as SitemapChangeFreq, a as SitemapData, b as SitemapEntry, c as SitemapOptions, d as createBlogSitemapRoute, e as createDynamicBlogSitemap, g as generateBlogSitemapEntries, f as generateCanonicalUrl, h as generateCanonicalUrlFromSlug, i as generateSitemap, j as generateSitemapIndex, k as getBaseUrl, l as isValidCanonicalUrl, n as normalizeDomain, m as normalizeSlug, s as sitemapToXml, u as updateArticleCanonicalUrl, v as validateSitemap } from './sitemap-BmCh8BpN.js';
|
|
14
15
|
|
|
15
16
|
interface BlogTheme {
|
|
16
17
|
accentColor?: string;
|
|
@@ -118,14 +119,10 @@ interface ArticlePageProps {
|
|
|
118
119
|
};
|
|
119
120
|
basePath?: string;
|
|
120
121
|
theme?: BlogTheme;
|
|
121
|
-
postArticleCta?:
|
|
122
|
-
title: string;
|
|
123
|
-
description?: string;
|
|
124
|
-
href: string;
|
|
125
|
-
label: string;
|
|
126
|
-
};
|
|
122
|
+
postArticleCta?: PublishedArticleCta;
|
|
127
123
|
newsletter?: PublishedNewsletterSettings;
|
|
128
124
|
newsletterPreviewMode?: boolean;
|
|
125
|
+
articles?: PublishedArticle[];
|
|
129
126
|
relatedArticles?: PublishedArticle[];
|
|
130
127
|
showShareLinks?: boolean;
|
|
131
128
|
}
|