@xexr/blog-platform 1.0.8 → 1.0.10
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 +110 -29
- package/dist/app/blog/[slug]/page.tsx +138 -17
- package/dist/app/blog/authors/[slug]/page.test.ts +108 -0
- package/dist/app/blog/authors/[slug]/page.tsx +387 -0
- package/dist/app/blog/page.tsx +138 -113
- package/dist/components/AuthorPages.test.ts +87 -0
- package/dist/components/AuthorPages.tsx +129 -0
- package/dist/index.d.mts +199 -70
- package/dist/index.d.ts +199 -70
- package/dist/index.js +51 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +51 -11
- package/dist/index.mjs.map +1 -1
- package/dist/lib/authors.ts +100 -0
- package/dist/lib/sitemap.ts +101 -82
- package/dist/lib/storage/drizzle.ts +15 -0
- package/dist/lib/structured-data.ts +3 -2
- package/dist/lib/urls.ts +7 -0
- package/dist/types/contracts.ts +12 -0
- package/dist/types/index.d.mts +8 -0
- package/dist/types/index.d.ts +8 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PublishedArticle, PublishedSite,
|
|
1
|
+
import { PublishedArticle, PublishedSite, PublishedAuthor, PublishResult, PublishedTopic } from './types/index.js';
|
|
2
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';
|
|
@@ -164,6 +164,55 @@ declare function generateArticleMetadata(
|
|
|
164
164
|
};
|
|
165
165
|
};
|
|
166
166
|
|
|
167
|
+
interface AuthorPageProps {
|
|
168
|
+
author: PublishedAuthor;
|
|
169
|
+
articles: PublishedArticle[];
|
|
170
|
+
site: PublishedSite;
|
|
171
|
+
className?: string;
|
|
172
|
+
basePath?: string;
|
|
173
|
+
theme?: BlogTheme;
|
|
174
|
+
pagination?: {
|
|
175
|
+
currentPage: number;
|
|
176
|
+
totalPages: number;
|
|
177
|
+
baseUrl?: string;
|
|
178
|
+
totalItems?: number;
|
|
179
|
+
};
|
|
180
|
+
navigation?: {
|
|
181
|
+
backToHome?: {
|
|
182
|
+
url: string;
|
|
183
|
+
label?: string;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
declare function AuthorPage({ author, articles, site, className, basePath, theme, pagination, navigation, }: AuthorPageProps): react_jsx_runtime.JSX.Element;
|
|
188
|
+
declare function generateAuthorPageMetadata(author: PublishedAuthor, site: PublishedSite, basePath?: string): {
|
|
189
|
+
title: string;
|
|
190
|
+
description: string;
|
|
191
|
+
authors: {
|
|
192
|
+
name: string;
|
|
193
|
+
}[];
|
|
194
|
+
openGraph: {
|
|
195
|
+
title: string;
|
|
196
|
+
description: string;
|
|
197
|
+
type: string;
|
|
198
|
+
url: string;
|
|
199
|
+
images: {
|
|
200
|
+
url: string;
|
|
201
|
+
alt: string;
|
|
202
|
+
}[] | undefined;
|
|
203
|
+
siteName: string;
|
|
204
|
+
};
|
|
205
|
+
twitter: {
|
|
206
|
+
card: string;
|
|
207
|
+
title: string;
|
|
208
|
+
description: string;
|
|
209
|
+
images: string[] | undefined;
|
|
210
|
+
};
|
|
211
|
+
alternates: {
|
|
212
|
+
canonical: string;
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
|
|
167
216
|
interface PaginationProps {
|
|
168
217
|
/** Current page number (1-indexed) */
|
|
169
218
|
currentPage: number;
|
|
@@ -252,8 +301,88 @@ declare function cn(...inputs: ClassValue[]): string;
|
|
|
252
301
|
*/
|
|
253
302
|
declare function normalizeBlogBasePath(basePath?: string): string;
|
|
254
303
|
declare function buildBlogPath(basePath: string | undefined, slug?: string): string;
|
|
304
|
+
declare function buildAuthorPath(basePath: string | undefined, authorSlug: string): string;
|
|
255
305
|
declare function getPathPrefixFromBlogUrl(blogUrl: string): string;
|
|
256
306
|
|
|
307
|
+
/**
|
|
308
|
+
* Database interface for blog platform storage
|
|
309
|
+
*
|
|
310
|
+
* This provides a simple interface for storing published articles
|
|
311
|
+
* without coupling to any specific database implementation.
|
|
312
|
+
* Customers can implement this interface with their preferred database.
|
|
313
|
+
*/
|
|
314
|
+
|
|
315
|
+
interface BlogPlatformStorage {
|
|
316
|
+
/**
|
|
317
|
+
* Store a published article
|
|
318
|
+
*/
|
|
319
|
+
saveArticle(article: PublishedArticle, idempotencyKey: string): Promise<PublishResult>;
|
|
320
|
+
/**
|
|
321
|
+
* Get an article by slug
|
|
322
|
+
*/
|
|
323
|
+
getArticle(slug: string): Promise<PublishedArticle | null>;
|
|
324
|
+
/**
|
|
325
|
+
* List all published articles
|
|
326
|
+
*/
|
|
327
|
+
listArticles(options?: {
|
|
328
|
+
limit?: number;
|
|
329
|
+
offset?: number;
|
|
330
|
+
sortBy?: "publishedAt" | "updatedAt";
|
|
331
|
+
order?: "asc" | "desc";
|
|
332
|
+
}): Promise<{
|
|
333
|
+
articles: PublishedArticle[];
|
|
334
|
+
total: number;
|
|
335
|
+
}>;
|
|
336
|
+
/**
|
|
337
|
+
* Remove an article by slug
|
|
338
|
+
*/
|
|
339
|
+
removeArticle(slug: string, idempotencyKey: string): Promise<PublishResult>;
|
|
340
|
+
/**
|
|
341
|
+
* Check if an operation was already performed (idempotency)
|
|
342
|
+
*/
|
|
343
|
+
checkIdempotency(idempotencyKey: string): Promise<PublishResult | null>;
|
|
344
|
+
/**
|
|
345
|
+
* Store the result of an operation for idempotency
|
|
346
|
+
*/
|
|
347
|
+
storeOperationResult(idempotencyKey: string, result: PublishResult): Promise<void>;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Default in-memory storage implementation for development/testing
|
|
351
|
+
* IMPORTANT: This is not suitable for production use!
|
|
352
|
+
*/
|
|
353
|
+
declare class InMemoryStorage implements BlogPlatformStorage {
|
|
354
|
+
private articles;
|
|
355
|
+
private operations;
|
|
356
|
+
saveArticle(article: PublishedArticle, idempotencyKey: string): Promise<PublishResult>;
|
|
357
|
+
getArticle(slug: string): Promise<PublishedArticle | null>;
|
|
358
|
+
listArticles(options?: {
|
|
359
|
+
limit?: number;
|
|
360
|
+
offset?: number;
|
|
361
|
+
sortBy?: "publishedAt" | "updatedAt";
|
|
362
|
+
order?: "asc" | "desc";
|
|
363
|
+
}): Promise<{
|
|
364
|
+
articles: PublishedArticle[];
|
|
365
|
+
total: number;
|
|
366
|
+
}>;
|
|
367
|
+
removeArticle(slug: string, idempotencyKey: string): Promise<PublishResult>;
|
|
368
|
+
checkIdempotency(idempotencyKey: string): Promise<PublishResult | null>;
|
|
369
|
+
storeOperationResult(idempotencyKey: string, result: PublishResult): Promise<void>;
|
|
370
|
+
}
|
|
371
|
+
declare function getStorage(): BlogPlatformStorage;
|
|
372
|
+
declare function setStorage(storage: BlogPlatformStorage): void;
|
|
373
|
+
|
|
374
|
+
interface AuthorArchive {
|
|
375
|
+
author: PublishedAuthor;
|
|
376
|
+
articles: PublishedArticle[];
|
|
377
|
+
}
|
|
378
|
+
interface AuthorArchiveOptions {
|
|
379
|
+
limit?: number;
|
|
380
|
+
offset?: number;
|
|
381
|
+
}
|
|
382
|
+
declare function getAuthorsFromArticles(articles: readonly PublishedArticle[]): PublishedAuthor[];
|
|
383
|
+
declare function getAuthorArchive(slug: string, articles: readonly PublishedArticle[]): AuthorArchive | null;
|
|
384
|
+
declare function loadAuthorArchive(slug: string, options?: AuthorArchiveOptions, storage?: BlogPlatformStorage): Promise<AuthorArchive | null>;
|
|
385
|
+
|
|
257
386
|
interface TopicArchive {
|
|
258
387
|
topic: PublishedTopic;
|
|
259
388
|
articles: PublishedArticle[];
|
|
@@ -280,6 +409,16 @@ interface BlogTopicArchivePageProps {
|
|
|
280
409
|
declare function BlogTopicsIndexPage({ articles, basePath, title, description, className, theme, }: BlogTopicsIndexPageProps): react_jsx_runtime.JSX.Element;
|
|
281
410
|
declare function BlogTopicArchivePage({ articles, topicSlug, basePath, className, theme, }: BlogTopicArchivePageProps): react_jsx_runtime.JSX.Element;
|
|
282
411
|
|
|
412
|
+
interface BlogAuthorsIndexPageProps {
|
|
413
|
+
articles: PublishedArticle[];
|
|
414
|
+
basePath?: string;
|
|
415
|
+
title?: string;
|
|
416
|
+
description?: string;
|
|
417
|
+
className?: string;
|
|
418
|
+
theme?: BlogTheme;
|
|
419
|
+
}
|
|
420
|
+
declare function BlogAuthorsIndexPage({ articles, basePath, title, description, className, theme, }: BlogAuthorsIndexPageProps): react_jsx_runtime.JSX.Element;
|
|
421
|
+
|
|
283
422
|
/**
|
|
284
423
|
* Authentication configuration interface
|
|
285
424
|
* Customers can implement this to customize authentication behavior
|
|
@@ -379,73 +518,6 @@ declare function initEnvAuth(envVarName?: string): void;
|
|
|
379
518
|
*/
|
|
380
519
|
declare function shouldSkipAuth(): boolean;
|
|
381
520
|
|
|
382
|
-
/**
|
|
383
|
-
* Database interface for blog platform storage
|
|
384
|
-
*
|
|
385
|
-
* This provides a simple interface for storing published articles
|
|
386
|
-
* without coupling to any specific database implementation.
|
|
387
|
-
* Customers can implement this interface with their preferred database.
|
|
388
|
-
*/
|
|
389
|
-
|
|
390
|
-
interface BlogPlatformStorage {
|
|
391
|
-
/**
|
|
392
|
-
* Store a published article
|
|
393
|
-
*/
|
|
394
|
-
saveArticle(article: PublishedArticle, idempotencyKey: string): Promise<PublishResult>;
|
|
395
|
-
/**
|
|
396
|
-
* Get an article by slug
|
|
397
|
-
*/
|
|
398
|
-
getArticle(slug: string): Promise<PublishedArticle | null>;
|
|
399
|
-
/**
|
|
400
|
-
* List all published articles
|
|
401
|
-
*/
|
|
402
|
-
listArticles(options?: {
|
|
403
|
-
limit?: number;
|
|
404
|
-
offset?: number;
|
|
405
|
-
sortBy?: "publishedAt" | "updatedAt";
|
|
406
|
-
order?: "asc" | "desc";
|
|
407
|
-
}): Promise<{
|
|
408
|
-
articles: PublishedArticle[];
|
|
409
|
-
total: number;
|
|
410
|
-
}>;
|
|
411
|
-
/**
|
|
412
|
-
* Remove an article by slug
|
|
413
|
-
*/
|
|
414
|
-
removeArticle(slug: string, idempotencyKey: string): Promise<PublishResult>;
|
|
415
|
-
/**
|
|
416
|
-
* Check if an operation was already performed (idempotency)
|
|
417
|
-
*/
|
|
418
|
-
checkIdempotency(idempotencyKey: string): Promise<PublishResult | null>;
|
|
419
|
-
/**
|
|
420
|
-
* Store the result of an operation for idempotency
|
|
421
|
-
*/
|
|
422
|
-
storeOperationResult(idempotencyKey: string, result: PublishResult): Promise<void>;
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* Default in-memory storage implementation for development/testing
|
|
426
|
-
* IMPORTANT: This is not suitable for production use!
|
|
427
|
-
*/
|
|
428
|
-
declare class InMemoryStorage implements BlogPlatformStorage {
|
|
429
|
-
private articles;
|
|
430
|
-
private operations;
|
|
431
|
-
saveArticle(article: PublishedArticle, idempotencyKey: string): Promise<PublishResult>;
|
|
432
|
-
getArticle(slug: string): Promise<PublishedArticle | null>;
|
|
433
|
-
listArticles(options?: {
|
|
434
|
-
limit?: number;
|
|
435
|
-
offset?: number;
|
|
436
|
-
sortBy?: "publishedAt" | "updatedAt";
|
|
437
|
-
order?: "asc" | "desc";
|
|
438
|
-
}): Promise<{
|
|
439
|
-
articles: PublishedArticle[];
|
|
440
|
-
total: number;
|
|
441
|
-
}>;
|
|
442
|
-
removeArticle(slug: string, idempotencyKey: string): Promise<PublishResult>;
|
|
443
|
-
checkIdempotency(idempotencyKey: string): Promise<PublishResult | null>;
|
|
444
|
-
storeOperationResult(idempotencyKey: string, result: PublishResult): Promise<void>;
|
|
445
|
-
}
|
|
446
|
-
declare function getStorage(): BlogPlatformStorage;
|
|
447
|
-
declare function setStorage(storage: BlogPlatformStorage): void;
|
|
448
|
-
|
|
449
521
|
/**
|
|
450
522
|
* Rate limiting for blog platform API endpoints
|
|
451
523
|
*
|
|
@@ -822,6 +894,63 @@ declare const bpArticles: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
822
894
|
}, {}, {
|
|
823
895
|
length: number | undefined;
|
|
824
896
|
}>;
|
|
897
|
+
featuredImageCaption: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
898
|
+
name: "featured_image_caption";
|
|
899
|
+
tableName: "bp_articles";
|
|
900
|
+
dataType: "string";
|
|
901
|
+
columnType: "SQLiteText";
|
|
902
|
+
data: string;
|
|
903
|
+
driverParam: string;
|
|
904
|
+
notNull: false;
|
|
905
|
+
hasDefault: false;
|
|
906
|
+
isPrimaryKey: false;
|
|
907
|
+
isAutoincrement: false;
|
|
908
|
+
hasRuntimeDefault: false;
|
|
909
|
+
enumValues: [string, ...string[]];
|
|
910
|
+
baseColumn: never;
|
|
911
|
+
identity: undefined;
|
|
912
|
+
generated: undefined;
|
|
913
|
+
}, {}, {
|
|
914
|
+
length: number | undefined;
|
|
915
|
+
}>;
|
|
916
|
+
featuredImageCreditText: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
917
|
+
name: "featured_image_credit_text";
|
|
918
|
+
tableName: "bp_articles";
|
|
919
|
+
dataType: "string";
|
|
920
|
+
columnType: "SQLiteText";
|
|
921
|
+
data: string;
|
|
922
|
+
driverParam: string;
|
|
923
|
+
notNull: false;
|
|
924
|
+
hasDefault: false;
|
|
925
|
+
isPrimaryKey: false;
|
|
926
|
+
isAutoincrement: false;
|
|
927
|
+
hasRuntimeDefault: false;
|
|
928
|
+
enumValues: [string, ...string[]];
|
|
929
|
+
baseColumn: never;
|
|
930
|
+
identity: undefined;
|
|
931
|
+
generated: undefined;
|
|
932
|
+
}, {}, {
|
|
933
|
+
length: number | undefined;
|
|
934
|
+
}>;
|
|
935
|
+
featuredImageCreditUrl: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
936
|
+
name: "featured_image_credit_url";
|
|
937
|
+
tableName: "bp_articles";
|
|
938
|
+
dataType: "string";
|
|
939
|
+
columnType: "SQLiteText";
|
|
940
|
+
data: string;
|
|
941
|
+
driverParam: string;
|
|
942
|
+
notNull: false;
|
|
943
|
+
hasDefault: false;
|
|
944
|
+
isPrimaryKey: false;
|
|
945
|
+
isAutoincrement: false;
|
|
946
|
+
hasRuntimeDefault: false;
|
|
947
|
+
enumValues: [string, ...string[]];
|
|
948
|
+
baseColumn: never;
|
|
949
|
+
identity: undefined;
|
|
950
|
+
generated: undefined;
|
|
951
|
+
}, {}, {
|
|
952
|
+
length: number | undefined;
|
|
953
|
+
}>;
|
|
825
954
|
authorJson: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
826
955
|
name: "author_json";
|
|
827
956
|
tableName: "bp_articles";
|
|
@@ -1359,7 +1488,7 @@ interface SitemapOptions {
|
|
|
1359
1488
|
/**
|
|
1360
1489
|
* Valid sitemap change frequency values as per XML sitemap standard.
|
|
1361
1490
|
*/
|
|
1362
|
-
type SitemapChangeFreq =
|
|
1491
|
+
type SitemapChangeFreq = "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
|
|
1363
1492
|
/**
|
|
1364
1493
|
* Next.js MetadataRoute.Sitemap compatible entry.
|
|
1365
1494
|
* This matches the expected format for Next.js sitemap generation.
|
|
@@ -1875,4 +2004,4 @@ declare function OPTIONS(request: NextRequest): Promise<NextResponse>;
|
|
|
1875
2004
|
|
|
1876
2005
|
declare const PACKAGE_VERSION: string;
|
|
1877
2006
|
|
|
1878
|
-
export { ApiKeyAuth, type AuthConfig, type AuthResult, ArticlePage as BlogArticlePage, BlogHomePage, type BlogPlatformConfig, type BlogPlatformStorage, type BlogPostingSchema, type BlogSitemapConfig, type BlogTheme, BlogTopicArchivePage, BlogTopicsIndexPage, type BreadcrumbListSchema, Button, type CanonicalUrlOptions, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DrizzleStorage, EnvAuth, type GeneratedMetadata, InMemoryStorage, type LinkTag, type MetaTag, type MetadataOptions, type NextjsSitemapEntry, NoAuth, type OrganizationSchema, PACKAGE_VERSION, Pagination$1 as Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, type PersonSchema, PublishResult, PublishedArticle, PublishedAuthor, PublishedSite, PublishedTopic, type RateLimitConfig, type RateLimitResult, Pagination as ShadcnPagination, type SitemapChangeFreq, type SitemapData, type SitemapEntry, type SitemapOptions, StructuredDataError, type StructuredDataOptions, type TopicArchive, UninitializedAuth, type WebSiteSchema, autoConfigureRateLimit, bpArticles, bpOperations, buildBlogPath, buttonVariants, checkRateLimit, cn, configureRateLimit, createBlogSitemapRoute, createDynamicBlogSitemap, createRateLimitErrorResponse, createStructuredDataScript, enforceRateLimit, extractKeywordsFromArticle, extractTableOfContents, extractTokenFromHeader, formatArticleDateMeta, generateArticleMetadata, generateArticleStructuredData, generateAuthorStructuredData, generateBlogHomeMetadata, generateBlogHomeStructuredData, generateBlogSitemapEntries, generateBreadcrumbStructuredData, generateCanonicalUrl, generateCanonicalUrlFromSlug, generateCompleteArticleStructuredData, generateOrganizationStructuredData, generatePaginationMetadata, generateSiteMetadata, generateSitemap, generateSitemapIndex, generateWebSiteStructuredData, getAllTopics, getArticlePrimaryTopic, getAuthConfig, getBaseUrl, getBlogThemeStyle, getDrizzleAdapterSql, getPathPrefixFromBlogUrl, getRateLimitHeaders, getStorage, getTopicArchive, initBlogPlatform, initBlogPlatformDev, initBlogPlatformOnce, initBlogPlatformProd, initEnvAuth, isValidCanonicalUrl, metadataToHtml, normalizeBlogBasePath, normalizeDomain, normalizeSlug, POST$1 as publishHandler, safeGenerateArticleStructuredData, setAuthConfig, setStorage, shouldSkipAuth, sitemapToXml, GET as slugExistsHandler, OPTIONS as slugExistsOptionsHandler, structuredDataToJsonLd, POST as unpublishHandler, updateArticleCanonicalUrl, usePagination, validateMetadata, validateSitemap, validateStructuredData, GET$1 as versionHandler };
|
|
2007
|
+
export { ApiKeyAuth, type AuthConfig, type AuthResult, type AuthorArchive, type AuthorArchiveOptions, ArticlePage as BlogArticlePage, AuthorPage as BlogAuthorPage, BlogAuthorsIndexPage, BlogHomePage, type BlogPlatformConfig, type BlogPlatformStorage, type BlogPostingSchema, type BlogSitemapConfig, type BlogTheme, BlogTopicArchivePage, BlogTopicsIndexPage, type BreadcrumbListSchema, Button, type CanonicalUrlOptions, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DrizzleStorage, EnvAuth, type GeneratedMetadata, InMemoryStorage, type LinkTag, type MetaTag, type MetadataOptions, type NextjsSitemapEntry, NoAuth, type OrganizationSchema, PACKAGE_VERSION, Pagination$1 as Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, type PersonSchema, PublishResult, PublishedArticle, PublishedAuthor, PublishedSite, PublishedTopic, type RateLimitConfig, type RateLimitResult, Pagination as ShadcnPagination, type SitemapChangeFreq, type SitemapData, type SitemapEntry, type SitemapOptions, StructuredDataError, type StructuredDataOptions, type TopicArchive, UninitializedAuth, type WebSiteSchema, autoConfigureRateLimit, bpArticles, bpOperations, buildAuthorPath, buildBlogPath, buttonVariants, checkRateLimit, cn, configureRateLimit, createBlogSitemapRoute, createDynamicBlogSitemap, createRateLimitErrorResponse, createStructuredDataScript, enforceRateLimit, extractKeywordsFromArticle, extractTableOfContents, extractTokenFromHeader, formatArticleDateMeta, generateArticleMetadata, generateArticleStructuredData, generateAuthorPageMetadata, generateAuthorStructuredData, generateBlogHomeMetadata, generateBlogHomeStructuredData, generateBlogSitemapEntries, generateBreadcrumbStructuredData, generateCanonicalUrl, generateCanonicalUrlFromSlug, generateCompleteArticleStructuredData, generateOrganizationStructuredData, generatePaginationMetadata, generateSiteMetadata, generateSitemap, generateSitemapIndex, generateWebSiteStructuredData, getAllTopics, getArticlePrimaryTopic, getAuthConfig, getAuthorArchive, getAuthorsFromArticles, getBaseUrl, getBlogThemeStyle, getDrizzleAdapterSql, getPathPrefixFromBlogUrl, getRateLimitHeaders, getStorage, getTopicArchive, initBlogPlatform, initBlogPlatformDev, initBlogPlatformOnce, initBlogPlatformProd, initEnvAuth, isValidCanonicalUrl, loadAuthorArchive, metadataToHtml, normalizeBlogBasePath, normalizeDomain, normalizeSlug, POST$1 as publishHandler, safeGenerateArticleStructuredData, setAuthConfig, setStorage, shouldSkipAuth, sitemapToXml, GET as slugExistsHandler, OPTIONS as slugExistsOptionsHandler, structuredDataToJsonLd, POST as unpublishHandler, updateArticleCanonicalUrl, usePagination, validateMetadata, validateSitemap, validateStructuredData, GET$1 as versionHandler };
|