@xexr/blog-platform 1.1.5 → 1.1.7

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 CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.7
4
+
5
+ ### Patch Changes
6
+
7
+ - Correct article subjects and author expertise, add topic and series archive structured data, and omit paginated URLs from sitemaps.
8
+ - 5e14632: Raise the `next` peer dependency range to `^15.5.28 || ^16.4.1`, excluding Next.js releases affected by the October 2026 Next.js security advisories (GHSA-2464-fhr4-w9xw, GHSA-p3m5-59mp-jv5r, GHSA-673q-mjm6-r5xr).
9
+
3
10
  ## 1.1.1
4
11
 
5
12
  ### Patch Changes
@@ -40,6 +47,7 @@
40
47
  This release requires consumers to use drizzle-orm >=0.44 and @libsql/client >=0.15.
41
48
 
42
49
  Updated packages:
50
+
43
51
  - @libsql/client: ^0.14.0 → ^0.15.0
44
52
  - drizzle-orm: ^0.38.0 → ^0.44.0
45
53
  - @radix-ui/react-separator: ^1.1.0 → ^1.1.1
@@ -0,0 +1,61 @@
1
+ import React from "react";
2
+ import type { PublishedArticle } from "../types/contracts";
3
+ import {
4
+ generateBreadcrumbStructuredData,
5
+ structuredDataToJsonLd,
6
+ } from "../lib/structured-data";
7
+ import { buildBlogPath } from "../lib/urls";
8
+
9
+ export function ArchiveStructuredData({
10
+ articles,
11
+ title,
12
+ kind,
13
+ slug,
14
+ basePath,
15
+ }: {
16
+ articles: PublishedArticle[];
17
+ title: string;
18
+ kind: "topics" | "series";
19
+ slug: string;
20
+ basePath: string;
21
+ }) {
22
+ const site = articles[0]?.site;
23
+ if (!site) return null;
24
+ const domain = site.domain;
25
+ const archivePath = buildBlogPath(basePath, `${kind}/${slug}`);
26
+ const collection = {
27
+ "@context": "https://schema.org" as const,
28
+ "@type": "CollectionPage",
29
+ name: title,
30
+ url: `https://${domain}${archivePath}`,
31
+ mainEntity: {
32
+ "@type": "ItemList",
33
+ itemListElement: articles.map((article, index) => ({
34
+ "@type": "ListItem",
35
+ position: index + 1,
36
+ name: article.title,
37
+ url: `https://${domain}${buildBlogPath(basePath, article.slug)}`,
38
+ })),
39
+ },
40
+ };
41
+ const breadcrumbs = generateBreadcrumbStructuredData(
42
+ [
43
+ { name: "Home", url: "/" },
44
+ { name: site.name, url: basePath },
45
+ {
46
+ name: kind === "topics" ? "Topics" : "Series",
47
+ url: buildBlogPath(basePath, kind),
48
+ },
49
+ { name: title, url: archivePath },
50
+ ],
51
+ { customDomain: domain },
52
+ );
53
+ return (
54
+ <script
55
+ type="application/ld+json"
56
+ dangerouslySetInnerHTML={{
57
+ __html: structuredDataToJsonLd([collection, breadcrumbs]),
58
+ }}
59
+ />
60
+ );
61
+ }
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { ArchiveStructuredData } from "./ArchiveStructuredData";
2
3
  import Image from "next/image.js";
3
4
  import Link from "next/link.js";
4
5
  import { formatDistanceToNow } from "date-fns";
@@ -122,6 +123,15 @@ export function BlogSeriesArchivePage({
122
123
  className,
123
124
  )}
124
125
  >
126
+ {archive && (
127
+ <ArchiveStructuredData
128
+ articles={archive.articles}
129
+ title={archive.series.title}
130
+ kind="series"
131
+ slug={seriesSlug}
132
+ basePath={normalizedBasePath}
133
+ />
134
+ )}
125
135
  <header className="mb-10 space-y-3 text-center">
126
136
  <Link
127
137
  href={buildBlogPath(normalizedBasePath, "series")}
@@ -2,10 +2,8 @@ import React from "react";
2
2
  import { renderToStaticMarkup } from "react-dom/server";
3
3
  import { describe, expect, it } from "vitest";
4
4
 
5
- import {
6
- BlogTopicArchivePage,
7
- BlogTopicsIndexPage,
8
- } from "./TopicArchivePages";
5
+ import { BlogTopicArchivePage, BlogTopicsIndexPage } from "./TopicArchivePages";
6
+ import { BlogSeriesArchivePage } from "./SeriesArchivePages";
9
7
  import type { PublishedArticle, PublishedSite } from "../types/contracts";
10
8
 
11
9
  const site: PublishedSite = {
@@ -99,3 +97,53 @@ describe("Blog topic archive pages", () => {
99
97
  expect(html).not.toContain("h-full w-full object-contain");
100
98
  });
101
99
  });
100
+
101
+ function schemas(html: string): unknown[] {
102
+ return [
103
+ ...html.matchAll(/<script type="application\/ld\+json">(.*?)<\/script>/g),
104
+ ].flatMap((match): unknown[] => JSON.parse(match[1]!) as unknown[]);
105
+ }
106
+
107
+ it("renders topic archive collection and breadcrumbs for the listed articles", () => {
108
+ const data = schemas(
109
+ renderToStaticMarkup(
110
+ React.createElement(BlogTopicArchivePage, {
111
+ articles: [article],
112
+ topicSlug: "recurring-work-and-routines",
113
+ basePath: "/new-blog",
114
+ }),
115
+ ),
116
+ );
117
+ expect(JSON.stringify(data)).toContain(
118
+ "https://example.com/new-blog/useful-routines",
119
+ );
120
+ expect(JSON.stringify(data)).toContain("CollectionPage");
121
+ expect(JSON.stringify(data)).toContain("BreadcrumbList");
122
+ });
123
+
124
+ it("renders series archive collection and breadcrumbs for the listed articles", () => {
125
+ const seriesArticle = {
126
+ ...article,
127
+ series: {
128
+ id: "s",
129
+ title: "Routines",
130
+ slug: "routines",
131
+ position: 1,
132
+ total: 1,
133
+ articles: [],
134
+ },
135
+ };
136
+ const data = schemas(
137
+ renderToStaticMarkup(
138
+ React.createElement(BlogSeriesArchivePage, {
139
+ articles: [seriesArticle],
140
+ seriesSlug: "routines",
141
+ }),
142
+ ),
143
+ );
144
+ expect(JSON.stringify(data)).toContain(
145
+ "https://example.com/blog/useful-routines",
146
+ );
147
+ expect(JSON.stringify(data)).toContain("CollectionPage");
148
+ expect(JSON.stringify(data)).toContain("BreadcrumbList");
149
+ });
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { ArchiveStructuredData } from "./ArchiveStructuredData";
2
3
  import Link from "next/link.js";
3
4
  import Image from "next/image.js";
4
5
  import { formatDistanceToNow } from "date-fns";
@@ -52,7 +53,7 @@ export function BlogTopicsIndexPage({
52
53
  <header className="mb-10 space-y-3 text-center">
53
54
  <Link
54
55
  href={normalizedBasePath}
55
- className="text-muted-foreground hover:text-[var(--blog-accent)] text-sm font-medium transition-colors"
56
+ className="text-muted-foreground text-sm font-medium transition-colors hover:text-[var(--blog-accent)]"
56
57
  >
57
58
  Back to all articles
58
59
  </Link>
@@ -88,7 +89,7 @@ export function BlogTopicsIndexPage({
88
89
  href={buildBlogPath(normalizedBasePath, `topics/${topic.slug}`)}
89
90
  className="group rounded-2xl border border-[var(--blog-accent-border)] bg-[var(--blog-card-bg)] p-5 transition hover:border-[var(--blog-accent)] hover:no-underline"
90
91
  >
91
- <h2 className="group-hover:text-[var(--blog-accent)] text-xl font-semibold transition-colors">
92
+ <h2 className="text-xl font-semibold transition-colors group-hover:text-[var(--blog-accent)]">
92
93
  {topic.name}
93
94
  </h2>
94
95
  {topic.description && (
@@ -126,10 +127,19 @@ export function BlogTopicArchivePage({
126
127
  className,
127
128
  )}
128
129
  >
130
+ {archive && (
131
+ <ArchiveStructuredData
132
+ articles={archive.articles}
133
+ title={archive.topic.name}
134
+ kind="topics"
135
+ slug={topicSlug}
136
+ basePath={normalizedBasePath}
137
+ />
138
+ )}
129
139
  <header className="mb-10 space-y-3 text-center">
130
140
  <Link
131
141
  href={buildBlogPath(normalizedBasePath, "topics")}
132
- className="text-muted-foreground hover:text-[var(--blog-accent)] text-sm font-medium transition-colors"
142
+ className="text-muted-foreground text-sm font-medium transition-colors hover:text-[var(--blog-accent)]"
133
143
  >
134
144
  Back to all topics
135
145
  </Link>
@@ -202,7 +212,7 @@ function TopicArticleCard({
202
212
  <span className="inline-flex rounded-full border border-[var(--blog-accent-border)] px-2.5 py-1 text-xs font-medium text-[var(--blog-text-accent)]">
203
213
  {topic.name}
204
214
  </span>
205
- <h2 className="group-hover:text-[var(--blog-accent)] text-xl font-semibold text-balance transition-colors">
215
+ <h2 className="text-xl font-semibold text-balance transition-colors group-hover:text-[var(--blog-accent)]">
206
216
  {article.title}
207
217
  </h2>
208
218
  {article.excerpt && (
@@ -44,6 +44,8 @@ interface PublishedAuthor {
44
44
  readonly pronouns?: string;
45
45
  /** Whether this is a guest author */
46
46
  readonly isGuest: boolean;
47
+ /** Areas of subject expertise. */
48
+ readonly expertise?: readonly string[];
47
49
  /** Tone adjectives that describe this author's writing style */
48
50
  readonly toneAdjectives: readonly string[];
49
51
  }
@@ -44,6 +44,8 @@ interface PublishedAuthor {
44
44
  readonly pronouns?: string;
45
45
  /** Whether this is a guest author */
46
46
  readonly isGuest: boolean;
47
+ /** Areas of subject expertise. */
48
+ readonly expertise?: readonly string[];
47
49
  /** Tone adjectives that describe this author's writing style */
48
50
  readonly toneAdjectives: readonly string[];
49
51
  }
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as PublishedArticle, b as PublishedSite, d as PublishedNewsletterSettings, e as PublishedArticleCta, c as PublishedAuthor, f as PublishResult, P as PublishedTopic, g as PublishedSeriesContext } from './index-CKWrb9a4.mjs';
2
- export { h as PublishPayload, i as PublishedAuthorSocialLinks } from './index-CKWrb9a4.mjs';
1
+ import { a as PublishedArticle, b as PublishedSite, d as PublishedNewsletterSettings, e as PublishedArticleCta, c as PublishedAuthor, f as PublishResult, P as PublishedTopic, g as PublishedSeriesContext } from './index-DsXjuPn4.mjs';
2
+ export { h as PublishPayload, i as PublishedAuthorSocialLinks } from './index-DsXjuPn4.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';
@@ -10,8 +10,8 @@ export { RelatedArticleCandidate, RelatedFeaturedArticlesOptions, getRelatedFeat
10
10
  import { NextRequest, NextResponse } from 'next/server.js';
11
11
  import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
12
12
  import { LibSQLDatabase } from 'drizzle-orm/libsql';
13
- import { C as CanonicalUrlOptions } from './sitemap-D3rS0iAF.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-D3rS0iAF.mjs';
13
+ import { C as CanonicalUrlOptions } from './sitemap-Dy7Q4ATM.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-Dy7Q4ATM.mjs';
15
15
 
16
16
  interface BlogTheme {
17
17
  accentColor?: string;
@@ -2283,4 +2283,5 @@ declare function OPTIONS(request: NextRequest): Promise<NextResponse>;
2283
2283
 
2284
2284
  declare const PACKAGE_VERSION: string;
2285
2285
 
2286
- export { ApiKeyAuth, type AuthConfig, type AuthResult, type AuthorArchive, type AuthorArchiveOptions, BLOG_PLATFORM_SCHEMA_VERSION, BLOG_PLATFORM_TABLE_NAMES, ArticlePage as BlogArticlePage, AuthorPage as BlogAuthorPage, BlogAuthorsIndexPage, BlogHomePage, type BlogPlatformConfig, type BlogPlatformSchemaCheckResult, BlogPlatformSchemaError, type BlogPlatformStorage, type BlogPlatformTableName, type BlogPostingSchema, BlogSeriesArchivePage, BlogSeriesArchiveRoutePage, BlogSeriesIndexPage, BlogSeriesPage, type BlogTheme, BlogTopicArchivePage, BlogTopicsIndexPage, type BreadcrumbListSchema, Button, CanonicalUrlOptions, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DrizzleStorage, EnvAuth, type GeneratedMetadata, InMemoryStorage, type LinkTag, type MetaTag, type MetadataOptions, NEWSLETTER_SUCCESS_MESSAGE, NewsletterSignup, type NewsletterSignupProps, NoAuth, type OrganizationSchema, PACKAGE_VERSION, Pagination$1 as Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, type PersonSchema, PublishResult, PublishedArticle, PublishedAuthor, PublishedNewsletterSettings, PublishedSite, PublishedTopic, type RateLimitConfig, type RateLimitResult, type SeriesArchive, SeriesNavigation, Pagination as ShadcnPagination, StructuredDataError, type StructuredDataOptions, type TopicArchive, UninitializedAuth, type WebSiteSchema, autoConfigureRateLimit, blogPlatformDrizzleSchema, bpArticles, bpMetadata, bpOperations, buildAuthorPath, buildBlogPath, buildSeriesPath, buttonVariants, checkDrizzleAdapterSchema, checkRateLimit, cn, POST as configHandler, OPTIONS$1 as configOptionsHandler, configureRateLimit, createRateLimitErrorResponse, createStructuredDataScript, createTokenFingerprint, enforceRateLimit, ensureDrizzleAdapterSchema, extractKeywordsFromArticle, extractTableOfContents, extractTokenFromHeader, formatArticleDateMeta, generateArticleMetadata, generateArticleStructuredData, generateAuthorPageMetadata, generateAuthorStructuredData, generateBlogHomeMetadata, generateBlogHomeStructuredData, generateBreadcrumbStructuredData, generateCompleteArticleStructuredData, generateOrganizationStructuredData, generatePaginationMetadata, generateSeriesArchiveMetadata, generateSeriesIndexMetadata, generateSiteMetadata, generateWebSiteStructuredData, getAllSeries, getAllTopics, getArticlePrimaryTopic, getArticleSeriesNavigation, getAuthConfig, getAuthorArchive, getAuthorsFromArticles, getBlogThemeStyle, getDrizzleAdapterSql, getPathPrefixFromBlogUrl, getRateLimitHeaders, getSeriesArchive, getStorage, getTopicArchive, GET$1 as indexNowKeyRoute, initBlogPlatform, initBlogPlatformDev, initBlogPlatformOnce, initBlogPlatformProd, initEnvAuth, loadAuthorArchive, metadataToHtml, normalizeBlogBasePath, POST$2 as publishHandler, safeGenerateArticleStructuredData, setAuthConfig, setStorage, shouldSkipAuth, GET as slugExistsHandler, OPTIONS as slugExistsOptionsHandler, structuredDataToJsonLd, POST$1 as unpublishHandler, usePagination, validateMetadata, validateStructuredData, GET$2 as versionHandler };
2286
+ export { ApiKeyAuth, BLOG_PLATFORM_SCHEMA_VERSION, BLOG_PLATFORM_TABLE_NAMES, ArticlePage as BlogArticlePage, AuthorPage as BlogAuthorPage, BlogAuthorsIndexPage, BlogHomePage, BlogPlatformSchemaError, BlogSeriesArchivePage, BlogSeriesArchiveRoutePage, BlogSeriesIndexPage, BlogSeriesPage, BlogTopicArchivePage, BlogTopicsIndexPage, Button, CanonicalUrlOptions, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DrizzleStorage, EnvAuth, InMemoryStorage, NEWSLETTER_SUCCESS_MESSAGE, NewsletterSignup, NoAuth, PACKAGE_VERSION, Pagination$1 as Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PublishResult, PublishedArticle, PublishedAuthor, PublishedNewsletterSettings, PublishedSite, PublishedTopic, SeriesNavigation, Pagination as ShadcnPagination, StructuredDataError, UninitializedAuth, autoConfigureRateLimit, blogPlatformDrizzleSchema, bpArticles, bpMetadata, bpOperations, buildAuthorPath, buildBlogPath, buildSeriesPath, buttonVariants, checkDrizzleAdapterSchema, checkRateLimit, cn, POST as configHandler, OPTIONS$1 as configOptionsHandler, configureRateLimit, createRateLimitErrorResponse, createStructuredDataScript, createTokenFingerprint, enforceRateLimit, ensureDrizzleAdapterSchema, extractKeywordsFromArticle, extractTableOfContents, extractTokenFromHeader, formatArticleDateMeta, generateArticleMetadata, generateArticleStructuredData, generateAuthorPageMetadata, generateAuthorStructuredData, generateBlogHomeMetadata, generateBlogHomeStructuredData, generateBreadcrumbStructuredData, generateCompleteArticleStructuredData, generateOrganizationStructuredData, generatePaginationMetadata, generateSeriesArchiveMetadata, generateSeriesIndexMetadata, generateSiteMetadata, generateWebSiteStructuredData, getAllSeries, getAllTopics, getArticlePrimaryTopic, getArticleSeriesNavigation, getAuthConfig, getAuthorArchive, getAuthorsFromArticles, getBlogThemeStyle, getDrizzleAdapterSql, getPathPrefixFromBlogUrl, getRateLimitHeaders, getSeriesArchive, getStorage, getTopicArchive, GET$1 as indexNowKeyRoute, initBlogPlatform, initBlogPlatformDev, initBlogPlatformOnce, initBlogPlatformProd, initEnvAuth, loadAuthorArchive, metadataToHtml, normalizeBlogBasePath, POST$2 as publishHandler, safeGenerateArticleStructuredData, setAuthConfig, setStorage, shouldSkipAuth, GET as slugExistsHandler, OPTIONS as slugExistsOptionsHandler, structuredDataToJsonLd, POST$1 as unpublishHandler, usePagination, validateMetadata, validateStructuredData, GET$2 as versionHandler };
2287
+ export type { AuthConfig, AuthResult, AuthorArchive, AuthorArchiveOptions, BlogPlatformConfig, BlogPlatformSchemaCheckResult, BlogPlatformStorage, BlogPlatformTableName, BlogPostingSchema, BlogTheme, BreadcrumbListSchema, GeneratedMetadata, LinkTag, MetaTag, MetadataOptions, NewsletterSignupProps, OrganizationSchema, PersonSchema, RateLimitConfig, RateLimitResult, SeriesArchive, StructuredDataOptions, TopicArchive, WebSiteSchema };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as PublishedArticle, b as PublishedSite, d as PublishedNewsletterSettings, e as PublishedArticleCta, c as PublishedAuthor, f as PublishResult, P as PublishedTopic, g as PublishedSeriesContext } from './index-CKWrb9a4.js';
2
- export { h as PublishPayload, i as PublishedAuthorSocialLinks } from './index-CKWrb9a4.js';
1
+ import { a as PublishedArticle, b as PublishedSite, d as PublishedNewsletterSettings, e as PublishedArticleCta, c as PublishedAuthor, f as PublishResult, P as PublishedTopic, g as PublishedSeriesContext } from './index-DsXjuPn4.js';
2
+ export { h as PublishPayload, i as PublishedAuthorSocialLinks } from './index-DsXjuPn4.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';
@@ -10,8 +10,8 @@ export { RelatedArticleCandidate, RelatedFeaturedArticlesOptions, getRelatedFeat
10
10
  import { NextRequest, NextResponse } from 'next/server.js';
11
11
  import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
12
12
  import { LibSQLDatabase } from 'drizzle-orm/libsql';
13
- import { C as CanonicalUrlOptions } from './sitemap-BDT3d496.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-BDT3d496.js';
13
+ import { C as CanonicalUrlOptions } from './sitemap-B64QGT4l.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-B64QGT4l.js';
15
15
 
16
16
  interface BlogTheme {
17
17
  accentColor?: string;
@@ -2283,4 +2283,5 @@ declare function OPTIONS(request: NextRequest): Promise<NextResponse>;
2283
2283
 
2284
2284
  declare const PACKAGE_VERSION: string;
2285
2285
 
2286
- export { ApiKeyAuth, type AuthConfig, type AuthResult, type AuthorArchive, type AuthorArchiveOptions, BLOG_PLATFORM_SCHEMA_VERSION, BLOG_PLATFORM_TABLE_NAMES, ArticlePage as BlogArticlePage, AuthorPage as BlogAuthorPage, BlogAuthorsIndexPage, BlogHomePage, type BlogPlatformConfig, type BlogPlatformSchemaCheckResult, BlogPlatformSchemaError, type BlogPlatformStorage, type BlogPlatformTableName, type BlogPostingSchema, BlogSeriesArchivePage, BlogSeriesArchiveRoutePage, BlogSeriesIndexPage, BlogSeriesPage, type BlogTheme, BlogTopicArchivePage, BlogTopicsIndexPage, type BreadcrumbListSchema, Button, CanonicalUrlOptions, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DrizzleStorage, EnvAuth, type GeneratedMetadata, InMemoryStorage, type LinkTag, type MetaTag, type MetadataOptions, NEWSLETTER_SUCCESS_MESSAGE, NewsletterSignup, type NewsletterSignupProps, NoAuth, type OrganizationSchema, PACKAGE_VERSION, Pagination$1 as Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, type PersonSchema, PublishResult, PublishedArticle, PublishedAuthor, PublishedNewsletterSettings, PublishedSite, PublishedTopic, type RateLimitConfig, type RateLimitResult, type SeriesArchive, SeriesNavigation, Pagination as ShadcnPagination, StructuredDataError, type StructuredDataOptions, type TopicArchive, UninitializedAuth, type WebSiteSchema, autoConfigureRateLimit, blogPlatformDrizzleSchema, bpArticles, bpMetadata, bpOperations, buildAuthorPath, buildBlogPath, buildSeriesPath, buttonVariants, checkDrizzleAdapterSchema, checkRateLimit, cn, POST as configHandler, OPTIONS$1 as configOptionsHandler, configureRateLimit, createRateLimitErrorResponse, createStructuredDataScript, createTokenFingerprint, enforceRateLimit, ensureDrizzleAdapterSchema, extractKeywordsFromArticle, extractTableOfContents, extractTokenFromHeader, formatArticleDateMeta, generateArticleMetadata, generateArticleStructuredData, generateAuthorPageMetadata, generateAuthorStructuredData, generateBlogHomeMetadata, generateBlogHomeStructuredData, generateBreadcrumbStructuredData, generateCompleteArticleStructuredData, generateOrganizationStructuredData, generatePaginationMetadata, generateSeriesArchiveMetadata, generateSeriesIndexMetadata, generateSiteMetadata, generateWebSiteStructuredData, getAllSeries, getAllTopics, getArticlePrimaryTopic, getArticleSeriesNavigation, getAuthConfig, getAuthorArchive, getAuthorsFromArticles, getBlogThemeStyle, getDrizzleAdapterSql, getPathPrefixFromBlogUrl, getRateLimitHeaders, getSeriesArchive, getStorage, getTopicArchive, GET$1 as indexNowKeyRoute, initBlogPlatform, initBlogPlatformDev, initBlogPlatformOnce, initBlogPlatformProd, initEnvAuth, loadAuthorArchive, metadataToHtml, normalizeBlogBasePath, POST$2 as publishHandler, safeGenerateArticleStructuredData, setAuthConfig, setStorage, shouldSkipAuth, GET as slugExistsHandler, OPTIONS as slugExistsOptionsHandler, structuredDataToJsonLd, POST$1 as unpublishHandler, usePagination, validateMetadata, validateStructuredData, GET$2 as versionHandler };
2286
+ export { ApiKeyAuth, BLOG_PLATFORM_SCHEMA_VERSION, BLOG_PLATFORM_TABLE_NAMES, ArticlePage as BlogArticlePage, AuthorPage as BlogAuthorPage, BlogAuthorsIndexPage, BlogHomePage, BlogPlatformSchemaError, BlogSeriesArchivePage, BlogSeriesArchiveRoutePage, BlogSeriesIndexPage, BlogSeriesPage, BlogTopicArchivePage, BlogTopicsIndexPage, Button, CanonicalUrlOptions, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DrizzleStorage, EnvAuth, InMemoryStorage, NEWSLETTER_SUCCESS_MESSAGE, NewsletterSignup, NoAuth, PACKAGE_VERSION, Pagination$1 as Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PublishResult, PublishedArticle, PublishedAuthor, PublishedNewsletterSettings, PublishedSite, PublishedTopic, SeriesNavigation, Pagination as ShadcnPagination, StructuredDataError, UninitializedAuth, autoConfigureRateLimit, blogPlatformDrizzleSchema, bpArticles, bpMetadata, bpOperations, buildAuthorPath, buildBlogPath, buildSeriesPath, buttonVariants, checkDrizzleAdapterSchema, checkRateLimit, cn, POST as configHandler, OPTIONS$1 as configOptionsHandler, configureRateLimit, createRateLimitErrorResponse, createStructuredDataScript, createTokenFingerprint, enforceRateLimit, ensureDrizzleAdapterSchema, extractKeywordsFromArticle, extractTableOfContents, extractTokenFromHeader, formatArticleDateMeta, generateArticleMetadata, generateArticleStructuredData, generateAuthorPageMetadata, generateAuthorStructuredData, generateBlogHomeMetadata, generateBlogHomeStructuredData, generateBreadcrumbStructuredData, generateCompleteArticleStructuredData, generateOrganizationStructuredData, generatePaginationMetadata, generateSeriesArchiveMetadata, generateSeriesIndexMetadata, generateSiteMetadata, generateWebSiteStructuredData, getAllSeries, getAllTopics, getArticlePrimaryTopic, getArticleSeriesNavigation, getAuthConfig, getAuthorArchive, getAuthorsFromArticles, getBlogThemeStyle, getDrizzleAdapterSql, getPathPrefixFromBlogUrl, getRateLimitHeaders, getSeriesArchive, getStorage, getTopicArchive, GET$1 as indexNowKeyRoute, initBlogPlatform, initBlogPlatformDev, initBlogPlatformOnce, initBlogPlatformProd, initEnvAuth, loadAuthorArchive, metadataToHtml, normalizeBlogBasePath, POST$2 as publishHandler, safeGenerateArticleStructuredData, setAuthConfig, setStorage, shouldSkipAuth, GET as slugExistsHandler, OPTIONS as slugExistsOptionsHandler, structuredDataToJsonLd, POST$1 as unpublishHandler, usePagination, validateMetadata, validateStructuredData, GET$2 as versionHandler };
2287
+ export type { AuthConfig, AuthResult, AuthorArchive, AuthorArchiveOptions, BlogPlatformConfig, BlogPlatformSchemaCheckResult, BlogPlatformStorage, BlogPlatformTableName, BlogPostingSchema, BlogTheme, BreadcrumbListSchema, GeneratedMetadata, LinkTag, MetaTag, MetadataOptions, NewsletterSignupProps, OrganizationSchema, PersonSchema, RateLimitConfig, RateLimitResult, SeriesArchive, StructuredDataOptions, TopicArchive, WebSiteSchema };