@xexr/blog-platform 1.1.4 → 1.1.5
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.tsx +10 -3
- package/dist/app/blog/page.tsx +12 -11
- package/dist/app/blog/series/[slug]/page.d.ts +28 -0
- package/dist/app/blog/series/[slug]/page.tsx +39 -0
- package/dist/app/blog/series/page.d.ts +24 -0
- package/dist/app/blog/series/page.tsx +28 -0
- package/dist/components/SeriesArchivePages.tsx +212 -0
- package/dist/components/SeriesNavigation.tsx +117 -0
- package/dist/{index-Dr8HaKGm.d.mts → index-CKWrb9a4.d.mts} +43 -1
- package/dist/{index-Dr8HaKGm.d.ts → index-CKWrb9a4.d.ts} +43 -1
- package/dist/index.d.mts +85 -5
- package/dist/index.d.ts +85 -5
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +12 -12
- package/dist/index.mjs.map +1 -1
- package/dist/lib/related-articles.d.mts +1 -1
- package/dist/lib/related-articles.d.ts +1 -1
- package/dist/lib/series.ts +55 -0
- package/dist/lib/sitemap.ts +76 -4
- package/dist/lib/storage/drizzle.ts +9 -0
- package/dist/lib/urls.ts +7 -0
- package/dist/{sitemap-BmCh8BpN.d.ts → sitemap-BDT3d496.d.ts} +7 -1
- package/dist/{sitemap-Dbl4CUGI.d.mts → sitemap-D3rS0iAF.d.mts} +7 -1
- package/dist/sitemap.d.mts +2 -2
- package/dist/sitemap.d.ts +2 -2
- package/dist/sitemap.js +5 -5
- package/dist/sitemap.js.map +1 -1
- package/dist/sitemap.mjs +5 -5
- package/dist/sitemap.mjs.map +1 -1
- package/dist/types/contracts.ts +58 -0
- package/dist/types/index.d.mts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
PublishedArticle,
|
|
3
|
+
PublishedSeriesContext,
|
|
4
|
+
} from "../types/contracts";
|
|
5
|
+
|
|
6
|
+
export interface SeriesArchive {
|
|
7
|
+
series: PublishedSeriesContext;
|
|
8
|
+
articles: PublishedArticle[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function getAllSeries(
|
|
12
|
+
articles: PublishedArticle[],
|
|
13
|
+
): PublishedSeriesContext[] {
|
|
14
|
+
const seriesBySlug = new Map<string, PublishedSeriesContext>();
|
|
15
|
+
|
|
16
|
+
for (const article of articles) {
|
|
17
|
+
if (
|
|
18
|
+
article.series &&
|
|
19
|
+
(!seriesBySlug.has(article.series.slug) ||
|
|
20
|
+
article.series.articles.length >
|
|
21
|
+
(seriesBySlug.get(article.series.slug)?.articles.length ?? 0))
|
|
22
|
+
) {
|
|
23
|
+
seriesBySlug.set(article.series.slug, article.series);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return Array.from(seriesBySlug.values()).sort((a, b) =>
|
|
28
|
+
a.title.localeCompare(b.title),
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getSeriesArchive(
|
|
33
|
+
articles: PublishedArticle[],
|
|
34
|
+
seriesSlug: string,
|
|
35
|
+
): SeriesArchive | null {
|
|
36
|
+
const matchingArticles = articles
|
|
37
|
+
.filter((article) => article.series?.slug === seriesSlug)
|
|
38
|
+
.sort((a, b) => (a.series?.position ?? 0) - (b.series?.position ?? 0));
|
|
39
|
+
|
|
40
|
+
if (matchingArticles.length === 0) return null;
|
|
41
|
+
|
|
42
|
+
const series = matchingArticles[0]?.series;
|
|
43
|
+
if (!series) return null;
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
series,
|
|
47
|
+
articles: matchingArticles,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function getArticleSeriesNavigation(
|
|
52
|
+
article: PublishedArticle,
|
|
53
|
+
): PublishedSeriesContext | null {
|
|
54
|
+
return article.series ?? null;
|
|
55
|
+
}
|
package/dist/lib/sitemap.ts
CHANGED
|
@@ -36,8 +36,9 @@ import {
|
|
|
36
36
|
normalizeDomain,
|
|
37
37
|
type CanonicalUrlOptions,
|
|
38
38
|
} from "./seo";
|
|
39
|
+
import { getAllSeries } from "./series";
|
|
39
40
|
import { getAllTopics } from "./topics";
|
|
40
|
-
import { buildAuthorPath, buildBlogPath } from "./urls";
|
|
41
|
+
import { buildAuthorPath, buildBlogPath, buildSeriesPath } from "./urls";
|
|
41
42
|
|
|
42
43
|
/**
|
|
43
44
|
* Configuration options for sitemap generation.
|
|
@@ -52,6 +53,9 @@ export interface SitemapOptions {
|
|
|
52
53
|
/** Whether to include topic pages in sitemap */
|
|
53
54
|
includeTopicPages?: boolean;
|
|
54
55
|
|
|
56
|
+
/** Whether to include series pages in sitemap */
|
|
57
|
+
includeSeriesPages?: boolean;
|
|
58
|
+
|
|
55
59
|
/** Whether to include pagination pages in sitemap */
|
|
56
60
|
includePaginationPages?: boolean;
|
|
57
61
|
|
|
@@ -71,6 +75,8 @@ export interface SitemapOptions {
|
|
|
71
75
|
authorPages?: SitemapChangeFreq;
|
|
72
76
|
/** Change frequency for topic index and archive pages */
|
|
73
77
|
topicPages?: SitemapChangeFreq;
|
|
78
|
+
/** Change frequency for series index and archive pages */
|
|
79
|
+
seriesPages?: SitemapChangeFreq;
|
|
74
80
|
/** Change frequency for pagination pages */
|
|
75
81
|
paginationPages?: SitemapChangeFreq;
|
|
76
82
|
};
|
|
@@ -85,6 +91,8 @@ export interface SitemapOptions {
|
|
|
85
91
|
authorPages?: number;
|
|
86
92
|
/** Priority for topic index and archive pages (0.0-1.0) */
|
|
87
93
|
topicPages?: number;
|
|
94
|
+
/** Priority for series index and archive pages (0.0-1.0) */
|
|
95
|
+
seriesPages?: number;
|
|
88
96
|
/** Priority for pagination pages (0.0-1.0) */
|
|
89
97
|
paginationPages?: number;
|
|
90
98
|
};
|
|
@@ -204,6 +212,7 @@ export async function generateBlogSitemapEntries(
|
|
|
204
212
|
const {
|
|
205
213
|
includeAuthorPages = true,
|
|
206
214
|
includeTopicPages = true,
|
|
215
|
+
includeSeriesPages = true,
|
|
207
216
|
includePaginationPages = true,
|
|
208
217
|
articlesPerPage = 10,
|
|
209
218
|
maxEntries = 50000,
|
|
@@ -221,6 +230,7 @@ export async function generateBlogSitemapEntries(
|
|
|
221
230
|
const sitemapAuthors =
|
|
222
231
|
authors.length > 0 ? authors : getAuthorsFromArticles(articles);
|
|
223
232
|
const sitemapTopics = getAllTopics([...articles]);
|
|
233
|
+
const sitemapSeries = getAllSeries([...articles]);
|
|
224
234
|
|
|
225
235
|
// Add blog home page
|
|
226
236
|
entries.push({
|
|
@@ -257,7 +267,9 @@ export async function generateBlogSitemapEntries(
|
|
|
257
267
|
if (entries.length >= maxEntries) return;
|
|
258
268
|
|
|
259
269
|
const topicArticles = articles.filter((article) =>
|
|
260
|
-
(article.topics ?? []).some(
|
|
270
|
+
(article.topics ?? []).some(
|
|
271
|
+
(candidate) => candidate.slug === topic.slug,
|
|
272
|
+
),
|
|
261
273
|
);
|
|
262
274
|
|
|
263
275
|
entries.push({
|
|
@@ -269,6 +281,32 @@ export async function generateBlogSitemapEntries(
|
|
|
269
281
|
});
|
|
270
282
|
}
|
|
271
283
|
|
|
284
|
+
if (includeSeriesPages && sitemapSeries.length > 0) {
|
|
285
|
+
if (entries.length < maxEntries) {
|
|
286
|
+
entries.push({
|
|
287
|
+
url: `${baseUrl}${buildBlogPath(pathPrefix, "series")}`,
|
|
288
|
+
lastModified: getLatestModificationDate(articles),
|
|
289
|
+
changeFrequency: changeFrequency.seriesPages ?? "weekly",
|
|
290
|
+
priority: priority.seriesPages ?? 0.6,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
sitemapSeries.forEach((series) => {
|
|
295
|
+
if (entries.length >= maxEntries) return;
|
|
296
|
+
|
|
297
|
+
const seriesArticles = articles.filter(
|
|
298
|
+
(article) => article.series?.slug === series.slug,
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
entries.push({
|
|
302
|
+
url: `${baseUrl}${buildSeriesPath(pathPrefix, series.slug)}`,
|
|
303
|
+
lastModified: getLatestModificationDate(seriesArticles),
|
|
304
|
+
changeFrequency: changeFrequency.seriesPages ?? "weekly",
|
|
305
|
+
priority: priority.seriesPages ?? 0.6,
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
272
310
|
// Add author pages if enabled
|
|
273
311
|
if (includeAuthorPages && sitemapAuthors.length > 0) {
|
|
274
312
|
if (entries.length < maxEntries) {
|
|
@@ -338,6 +376,7 @@ export function generateSitemap(
|
|
|
338
376
|
const {
|
|
339
377
|
includeAuthorPages = true,
|
|
340
378
|
includeTopicPages = true,
|
|
379
|
+
includeSeriesPages = true,
|
|
341
380
|
includePaginationPages = true,
|
|
342
381
|
articlesPerPage = 10,
|
|
343
382
|
maxEntries = 50000,
|
|
@@ -356,6 +395,7 @@ export function generateSitemap(
|
|
|
356
395
|
const sitemapAuthors =
|
|
357
396
|
authors.length > 0 ? authors : getAuthorsFromArticles(articles);
|
|
358
397
|
const sitemapTopics = getAllTopics([...articles]);
|
|
398
|
+
const sitemapSeries = getAllSeries([...articles]);
|
|
359
399
|
|
|
360
400
|
// Calculate total potential entries to determine if truncation will occur
|
|
361
401
|
let potentialEntries = 1; // Home page
|
|
@@ -363,8 +403,12 @@ export function generateSitemap(
|
|
|
363
403
|
if (includeTopicPages && sitemapTopics.length > 0) {
|
|
364
404
|
potentialEntries += sitemapTopics.length + 1; // Topic index + topic pages
|
|
365
405
|
}
|
|
406
|
+
if (includeSeriesPages && sitemapSeries.length > 0) {
|
|
407
|
+
potentialEntries += sitemapSeries.length + 1; // Series index + series pages
|
|
408
|
+
}
|
|
366
409
|
if (includeAuthorPages) {
|
|
367
|
-
potentialEntries +=
|
|
410
|
+
potentialEntries +=
|
|
411
|
+
sitemapAuthors.length > 0 ? sitemapAuthors.length + 1 : 0; // Authors index + author pages
|
|
368
412
|
}
|
|
369
413
|
if (includePaginationPages && articles.length > articlesPerPage) {
|
|
370
414
|
const totalPages = Math.ceil(articles.length / articlesPerPage);
|
|
@@ -408,7 +452,9 @@ export function generateSitemap(
|
|
|
408
452
|
if (entries.length >= maxEntries) return;
|
|
409
453
|
|
|
410
454
|
const topicArticles = articles.filter((article) =>
|
|
411
|
-
(article.topics ?? []).some(
|
|
455
|
+
(article.topics ?? []).some(
|
|
456
|
+
(candidate) => candidate.slug === topic.slug,
|
|
457
|
+
),
|
|
412
458
|
);
|
|
413
459
|
|
|
414
460
|
entries.push({
|
|
@@ -420,6 +466,32 @@ export function generateSitemap(
|
|
|
420
466
|
});
|
|
421
467
|
}
|
|
422
468
|
|
|
469
|
+
if (includeSeriesPages && sitemapSeries.length > 0) {
|
|
470
|
+
if (entries.length < maxEntries) {
|
|
471
|
+
entries.push({
|
|
472
|
+
loc: `${baseUrl}${buildBlogPath(pathPrefix, "series")}`,
|
|
473
|
+
lastmod: getLatestModificationDate(articles),
|
|
474
|
+
changefreq: changeFrequency.seriesPages ?? "weekly",
|
|
475
|
+
priority: priority.seriesPages ?? 0.6,
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
sitemapSeries.forEach((series) => {
|
|
480
|
+
if (entries.length >= maxEntries) return;
|
|
481
|
+
|
|
482
|
+
const seriesArticles = articles.filter(
|
|
483
|
+
(article) => article.series?.slug === series.slug,
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
entries.push({
|
|
487
|
+
loc: `${baseUrl}${buildSeriesPath(pathPrefix, series.slug)}`,
|
|
488
|
+
lastmod: getLatestModificationDate(seriesArticles),
|
|
489
|
+
changefreq: changeFrequency.seriesPages ?? "weekly",
|
|
490
|
+
priority: priority.seriesPages ?? 0.6,
|
|
491
|
+
});
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
|
|
423
495
|
// Add author pages if enabled
|
|
424
496
|
if (includeAuthorPages && sitemapAuthors.length > 0) {
|
|
425
497
|
if (entries.length < maxEntries) {
|
|
@@ -98,6 +98,7 @@ function toRow(article: PublishedArticle): ArticleRow {
|
|
|
98
98
|
metaJson: JSON.stringify({
|
|
99
99
|
...article.meta,
|
|
100
100
|
__bloggyTopics: article.topics ?? [],
|
|
101
|
+
__bloggySeries: article.series ?? null,
|
|
101
102
|
__bloggyCta: article.cta ?? null,
|
|
102
103
|
}),
|
|
103
104
|
version: article.version,
|
|
@@ -126,6 +127,7 @@ function fromRow(row: ArticleRow): PublishedArticle {
|
|
|
126
127
|
site: JSON.parse(row.siteJson) as PublishedSite,
|
|
127
128
|
cta: extractCta(row.metaJson),
|
|
128
129
|
topics: extractTopics(row.metaJson),
|
|
130
|
+
series: extractSeries(row.metaJson),
|
|
129
131
|
meta: extractMeta(row.metaJson),
|
|
130
132
|
version: row.version,
|
|
131
133
|
};
|
|
@@ -133,6 +135,7 @@ function fromRow(row: ArticleRow): PublishedArticle {
|
|
|
133
135
|
|
|
134
136
|
type StoredArticleMeta = PublishedArticle["meta"] & {
|
|
135
137
|
__bloggyTopics?: PublishedArticle["topics"];
|
|
138
|
+
__bloggySeries?: PublishedArticle["series"] | null;
|
|
136
139
|
__bloggyCta?: PublishedArticle["cta"] | null;
|
|
137
140
|
};
|
|
138
141
|
|
|
@@ -150,9 +153,15 @@ function extractCta(metaJson: string): PublishedArticle["cta"] {
|
|
|
150
153
|
return parsed.__bloggyCta ?? undefined;
|
|
151
154
|
}
|
|
152
155
|
|
|
156
|
+
function extractSeries(metaJson: string): PublishedArticle["series"] {
|
|
157
|
+
const parsed = parseStoredMeta(metaJson);
|
|
158
|
+
return parsed.__bloggySeries ?? undefined;
|
|
159
|
+
}
|
|
160
|
+
|
|
153
161
|
function extractMeta(metaJson: string): PublishedArticle["meta"] {
|
|
154
162
|
const parsed = parseStoredMeta(metaJson);
|
|
155
163
|
delete parsed.__bloggyTopics;
|
|
164
|
+
delete parsed.__bloggySeries;
|
|
156
165
|
delete parsed.__bloggyCta;
|
|
157
166
|
const meta = parsed;
|
|
158
167
|
return meta;
|
package/dist/lib/urls.ts
CHANGED
|
@@ -30,6 +30,13 @@ export function buildAuthorPath(
|
|
|
30
30
|
return buildBlogPath(basePath, `authors/${authorSlug}`);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
export function buildSeriesPath(
|
|
34
|
+
basePath: string | undefined,
|
|
35
|
+
seriesSlug: string,
|
|
36
|
+
): string {
|
|
37
|
+
return buildBlogPath(basePath, `series/${seriesSlug}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
33
40
|
export function getPathPrefixFromBlogUrl(blogUrl: string): string {
|
|
34
41
|
const parsed = new URL(blogUrl);
|
|
35
42
|
return normalizeBlogBasePath(parsed.pathname);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as PublishedArticle, b as PublishedSite, c as PublishedAuthor } from './index-
|
|
1
|
+
import { a as PublishedArticle, b as PublishedSite, c as PublishedAuthor } from './index-CKWrb9a4.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* SEO utilities for canonical URL generation and validation.
|
|
@@ -171,6 +171,8 @@ interface SitemapOptions {
|
|
|
171
171
|
includeAuthorPages?: boolean;
|
|
172
172
|
/** Whether to include topic pages in sitemap */
|
|
173
173
|
includeTopicPages?: boolean;
|
|
174
|
+
/** Whether to include series pages in sitemap */
|
|
175
|
+
includeSeriesPages?: boolean;
|
|
174
176
|
/** Whether to include pagination pages in sitemap */
|
|
175
177
|
includePaginationPages?: boolean;
|
|
176
178
|
/** Number of articles per page for pagination calculation */
|
|
@@ -187,6 +189,8 @@ interface SitemapOptions {
|
|
|
187
189
|
authorPages?: SitemapChangeFreq;
|
|
188
190
|
/** Change frequency for topic index and archive pages */
|
|
189
191
|
topicPages?: SitemapChangeFreq;
|
|
192
|
+
/** Change frequency for series index and archive pages */
|
|
193
|
+
seriesPages?: SitemapChangeFreq;
|
|
190
194
|
/** Change frequency for pagination pages */
|
|
191
195
|
paginationPages?: SitemapChangeFreq;
|
|
192
196
|
};
|
|
@@ -200,6 +204,8 @@ interface SitemapOptions {
|
|
|
200
204
|
authorPages?: number;
|
|
201
205
|
/** Priority for topic index and archive pages (0.0-1.0) */
|
|
202
206
|
topicPages?: number;
|
|
207
|
+
/** Priority for series index and archive pages (0.0-1.0) */
|
|
208
|
+
seriesPages?: number;
|
|
203
209
|
/** Priority for pagination pages (0.0-1.0) */
|
|
204
210
|
paginationPages?: number;
|
|
205
211
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as PublishedArticle, b as PublishedSite, c as PublishedAuthor } from './index-
|
|
1
|
+
import { a as PublishedArticle, b as PublishedSite, c as PublishedAuthor } from './index-CKWrb9a4.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* SEO utilities for canonical URL generation and validation.
|
|
@@ -171,6 +171,8 @@ interface SitemapOptions {
|
|
|
171
171
|
includeAuthorPages?: boolean;
|
|
172
172
|
/** Whether to include topic pages in sitemap */
|
|
173
173
|
includeTopicPages?: boolean;
|
|
174
|
+
/** Whether to include series pages in sitemap */
|
|
175
|
+
includeSeriesPages?: boolean;
|
|
174
176
|
/** Whether to include pagination pages in sitemap */
|
|
175
177
|
includePaginationPages?: boolean;
|
|
176
178
|
/** Number of articles per page for pagination calculation */
|
|
@@ -187,6 +189,8 @@ interface SitemapOptions {
|
|
|
187
189
|
authorPages?: SitemapChangeFreq;
|
|
188
190
|
/** Change frequency for topic index and archive pages */
|
|
189
191
|
topicPages?: SitemapChangeFreq;
|
|
192
|
+
/** Change frequency for series index and archive pages */
|
|
193
|
+
seriesPages?: SitemapChangeFreq;
|
|
190
194
|
/** Change frequency for pagination pages */
|
|
191
195
|
paginationPages?: SitemapChangeFreq;
|
|
192
196
|
};
|
|
@@ -200,6 +204,8 @@ interface SitemapOptions {
|
|
|
200
204
|
authorPages?: number;
|
|
201
205
|
/** Priority for topic index and archive pages (0.0-1.0) */
|
|
202
206
|
topicPages?: number;
|
|
207
|
+
/** Priority for series index and archive pages (0.0-1.0) */
|
|
208
|
+
seriesPages?: number;
|
|
203
209
|
/** Priority for pagination pages (0.0-1.0) */
|
|
204
210
|
paginationPages?: number;
|
|
205
211
|
};
|
package/dist/sitemap.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import './index-
|
|
2
|
-
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, i as generateSitemap, j as generateSitemapIndex, s as sitemapToXml, v as validateSitemap } from './sitemap-
|
|
1
|
+
import './index-CKWrb9a4.mjs';
|
|
2
|
+
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, i as generateSitemap, j as generateSitemapIndex, s as sitemapToXml, v as validateSitemap } from './sitemap-D3rS0iAF.mjs';
|
package/dist/sitemap.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import './index-
|
|
2
|
-
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, i as generateSitemap, j as generateSitemapIndex, s as sitemapToXml, v as validateSitemap } from './sitemap-
|
|
1
|
+
import './index-CKWrb9a4.js';
|
|
2
|
+
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, i as generateSitemap, j as generateSitemapIndex, s as sitemapToXml, v as validateSitemap } from './sitemap-BDT3d496.js';
|
package/dist/sitemap.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
'use strict';function
|
|
2
|
-
`)});return [
|
|
3
|
-
`)}function
|
|
4
|
-
`)});return [r,i,...n
|
|
5
|
-
`)}function
|
|
1
|
+
'use strict';function O(t){let e=new Map;for(let r of t)r.author?.slug&&e.set(r.author.slug,L(e.get(r.author.slug),r.author));return Array.from(e.values()).sort((r,i)=>r.name.localeCompare(i.name))}function L(t,e){return t?{...t,bio:t.bio??e.bio,avatarUrl:t.avatarUrl??e.avatarUrl,pronouns:t.pronouns??e.pronouns,socialLinks:t.socialLinks??e.socialLinks,toneAdjectives:t.toneAdjectives.length>0?t.toneAdjectives:e.toneAdjectives}:e}function R(t,e=true){let r=t.trim();return r=r.replace(/\/+$/,""),/^https?:\/\//.exec(r)||(r=`${e?"https":"http"}://${r}`),e&&r.startsWith("http://")&&(r=r.replace("http://","https://")),r}function k(t){let e=t.trim();if(!e)throw new Error("Slug cannot be empty");if(!/^[a-z0-9-]+$/.test(e))throw new Error("Slug can only contain lowercase letters, numbers, and hyphens");let i=e.replace(/-+/g,"-").replace(/^-+|-+$/g,"");if(!i)throw new Error("Slug cannot consist only of hyphens");return i}function _(t,e={}){let{forceHttps:r=true,removeTrailingSlash:i=true,domain:n=t.site.domain,pathPrefix:a="/blog"}=e;if(!n)throw new Error("Domain is required for canonical URL generation");if(!t.slug)throw new Error("Article slug is required for canonical URL generation");let l=R(n,r),P=k(t.slug),b=a.replace(/^(?!\/)/,"/").replace(/\/+$/,""),o=`${l}${b}/${P}`;return i&&(o=o.replace(/\/+$/,"")),o}function U(t){let e=new Map;for(let r of t)r.series&&(!e.has(r.series.slug)||r.series.articles.length>(e.get(r.series.slug)?.articles.length??0))&&e.set(r.series.slug,r.series);return Array.from(e.values()).sort((r,i)=>r.title.localeCompare(i.title))}function q(t){let e=new Map;for(let r of t)for(let i of r.topics??[])e.has(i.slug)||e.set(i.slug,i);return Array.from(e.values()).sort((r,i)=>r.name.localeCompare(i.name))}function D(t="/blog"){let e=t.trim();return !e||e==="/"?"":e.replace(/^(?!\/)/,"/").replace(/\/+$/,"")}function y(t,e){let r=D(t),i=e?.replace(/^\/+/,"").replace(/\/+$/,"");return i?`${r}/${i}`.replace(/\/+/g,"/"):r||"/"}function B(t,e){return y(t,`authors/${e}`)}function F(t,e){return y(t,`series/${e}`)}async function C(t,e,r=[],i={}){let{includeAuthorPages:n=true,includeTopicPages:a=true,includeSeriesPages:l=true,includePaginationPages:P=true,articlesPerPage:b=10,maxEntries:o=5e4,changeFrequency:u={},priority:c={}}=i,s=[],h=R(i.canonical?.domain??t.domain,i.canonical?.forceHttps??true),m=i.canonical?.pathPrefix??"/blog",v=r.length>0?r:O(e),S=q([...e]),x=U([...e]);if(s.push({url:`${h}${m}`,lastModified:f(e),changeFrequency:u.homePage??"daily",priority:c.homePage??1}),e.forEach(p=>{if(s.length>=o)return;let d=_(p,i.canonical);s.push({url:d,lastModified:p.updatedAt,changeFrequency:u.articles??"monthly",priority:c.articles??.8});}),a&&S.length>0&&(s.length<o&&s.push({url:`${h}${y(m,"topics")}`,lastModified:f(e),changeFrequency:u.topicPages??"weekly",priority:c.topicPages??.6}),S.forEach(p=>{if(s.length>=o)return;let d=e.filter(w=>(w.topics??[]).some(g=>g.slug===p.slug));s.push({url:`${h}${y(m,`topics/${p.slug}`)}`,lastModified:f(d),changeFrequency:u.topicPages??"weekly",priority:c.topicPages??.6});})),l&&x.length>0&&(s.length<o&&s.push({url:`${h}${y(m,"series")}`,lastModified:f(e),changeFrequency:u.seriesPages??"weekly",priority:c.seriesPages??.6}),x.forEach(p=>{if(s.length>=o)return;let d=e.filter(w=>w.series?.slug===p.slug);s.push({url:`${h}${F(m,p.slug)}`,lastModified:f(d),changeFrequency:u.seriesPages??"weekly",priority:c.seriesPages??.6});})),n&&v.length>0&&(s.length<o&&s.push({url:`${h}${y(m,"authors")}`,lastModified:f(e),changeFrequency:u.authorPages??"weekly",priority:c.authorPages??.6}),v.forEach(p=>{if(s.length>=o)return;let d=`${h}${B(m,p.slug)}`,w=e.filter(A=>A.author?.id===p.id),g=f(w);s.push({url:d,lastModified:g,changeFrequency:u.authorPages??"weekly",priority:c.authorPages??.6});})),P&&e.length>b){let p=Math.ceil(e.length/b);for(let d=2;d<=p&&!(s.length>=o);d++)s.push({url:`${h}${m}?page=${d}`,lastModified:f(e),changeFrequency:u.paginationPages??"daily",priority:c.paginationPages??.5});}return s}function te(t,e,r=[],i={}){let{includeAuthorPages:n=true,includeTopicPages:a=true,includeSeriesPages:l=true,includePaginationPages:P=true,articlesPerPage:b=10,maxEntries:o=5e4,changeFrequency:u={},priority:c={}}=i,s=[],h=R(i.canonical?.domain??t.domain,i.canonical?.forceHttps??true),m=i.canonical?.pathPrefix??"/blog",v=new Date().toISOString(),S=r.length>0?r:O(e),x=q([...e]),p=U([...e]),d=1;if(d+=e.length,a&&x.length>0&&(d+=x.length+1),l&&p.length>0&&(d+=p.length+1),n&&(d+=S.length>0?S.length+1:0),P&&e.length>b){let g=Math.ceil(e.length/b);d+=g-1;}let w=d>o;if(s.push({loc:`${h}${m}`,lastmod:f(e),changefreq:u.homePage??"daily",priority:c.homePage??1}),e.forEach(g=>{if(s.length>=o)return;let A=_(g,i.canonical);s.push({loc:A,lastmod:g.updatedAt,changefreq:u.articles??"monthly",priority:c.articles??.8});}),a&&x.length>0&&(s.length<o&&s.push({loc:`${h}${y(m,"topics")}`,lastmod:f(e),changefreq:u.topicPages??"weekly",priority:c.topicPages??.6}),x.forEach(g=>{if(s.length>=o)return;let A=e.filter($=>($.topics??[]).some(T=>T.slug===g.slug));s.push({loc:`${h}${y(m,`topics/${g.slug}`)}`,lastmod:f(A),changefreq:u.topicPages??"weekly",priority:c.topicPages??.6});})),l&&p.length>0&&(s.length<o&&s.push({loc:`${h}${y(m,"series")}`,lastmod:f(e),changefreq:u.seriesPages??"weekly",priority:c.seriesPages??.6}),p.forEach(g=>{if(s.length>=o)return;let A=e.filter($=>$.series?.slug===g.slug);s.push({loc:`${h}${F(m,g.slug)}`,lastmod:f(A),changefreq:u.seriesPages??"weekly",priority:c.seriesPages??.6});})),n&&S.length>0&&(s.length<o&&s.push({loc:`${h}${y(m,"authors")}`,lastmod:f(e),changefreq:u.authorPages??"weekly",priority:c.authorPages??.6}),S.forEach(g=>{if(s.length>=o)return;let A=`${h}${B(m,g.slug)}`,$=e.filter(M=>M.author?.id===g.id),T=f($);s.push({loc:A,lastmod:T,changefreq:u.authorPages??"weekly",priority:c.authorPages??.6});})),P&&e.length>b){let g=Math.ceil(e.length/b);for(let A=2;A<=g&&!(s.length>=o);A++)s.push({loc:`${h}${m}?page=${A}`,lastmod:f(e),changefreq:u.paginationPages??"daily",priority:c.paginationPages??.5});}return {entries:s,totalEntries:s.length,truncated:w,generatedAt:v,baseUrl:h}}function G(t){let e='<?xml version="1.0" encoding="UTF-8"?>',r='<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',i="</urlset>",n=t.entries.map(a=>{let l=[];return l.push(" <url>"),l.push(` <loc>${E(a.loc)}</loc>`),a.lastmod&&l.push(` <lastmod>${E(a.lastmod)}</lastmod>`),a.changefreq&&l.push(` <changefreq>${E(a.changefreq)}</changefreq>`),a.priority!==void 0&&l.push(` <priority>${a.priority.toFixed(1)}</priority>`),l.push(" </url>"),l.join(`
|
|
2
|
+
`)});return [e,r,...n,i].join(`
|
|
3
|
+
`)}function re(t,e){let r='<?xml version="1.0" encoding="UTF-8"?>',i='<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',n="</sitemapindex>",a=t.map(l=>{let P=[];return P.push(" <sitemap>"),P.push(` <loc>${E(l.url)}</loc>`),l.lastmod&&P.push(` <lastmod>${E(l.lastmod)}</lastmod>`),P.push(" </sitemap>"),P.join(`
|
|
4
|
+
`)});return [r,i,...a,n].join(`
|
|
5
|
+
`)}function ie(t){let e=[],r=[];t.entries.length===0?e.push("Sitemap must contain at least one URL"):t.entries.length>5e4&&e.push("Sitemap contains more than 50,000 URLs (Google limit)"),t.truncated&&r.push("Sitemap was truncated due to size limits"),t.entries.forEach((n,a)=>{try{new URL(n.loc);}catch{e.push(`Invalid URL at entry ${a+1}: ${n.loc}`);}n.priority!==void 0&&(n.priority<0||n.priority>1)&&e.push(`Invalid priority at entry ${a+1}: must be between 0.0 and 1.0`),n.lastmod&&!I(n.lastmod)&&e.push(`Invalid lastmod date at entry ${a+1}: ${n.lastmod}`),n.loc.length>2048&&r.push(`URL at entry ${a+1} exceeds 2048 character limit`);});let i=new Map;return t.entries.forEach(n=>{let a=i.get(n.loc)??0;i.set(n.loc,a+1);}),i.forEach((n,a)=>{n>1&&e.push(`Duplicate URL found: ${a} (appears ${n} times)`);}),{valid:e.length===0,errors:e,warnings:r}}function f(t){return t.length===0?new Date().toISOString():t.reduce((r,i)=>{let n=new Date(i.updatedAt);return n>r?n:r},new Date(t[0].updatedAt)).toISOString()}function se(t,e,r=[],i={}){return async function(){let l=(await C(t,e,r,i)).map(o=>({loc:o.url,lastmod:typeof o.lastModified=="string"?o.lastModified:o.lastModified?.toISOString(),changefreq:o.changeFrequency,priority:o.priority})),P={entries:l,totalEntries:l.length,generatedAt:new Date().toISOString(),baseUrl:R(i.canonical?.domain??t.domain,i.canonical?.forceHttps??true)},b=G(P);return new Response(b,{headers:{"Content-Type":"application/xml","Cache-Control":"public, max-age=3600, s-maxage=3600"}})}}function ne(t){return async function(){let r=[...t.staticRoutes??[],...t.getStaticRoutes?await t.getStaticRoutes():[]],i=await t.getSite(),n=await t.getArticles(),a=t.getAuthors?await t.getAuthors():[];return [...r,...await C(i,n,a,t.options)]}}function E(t){let e={"&":"&","<":"<",">":">",'"':""","'":"'"};return t.replace(/[&<>"']/g,r=>e[r]??r)}function I(t){try{let e=new Date(t),r=e.toISOString(),i=t.endsWith("Z")&&!t.includes(".")?t.replace("Z",".000Z"):t;return r===i&&!isNaN(e.getTime())}catch{return false}}exports.createBlogSitemapRoute=se;exports.createDynamicBlogSitemap=ne;exports.generateBlogSitemapEntries=C;exports.generateSitemap=te;exports.generateSitemapIndex=re;exports.sitemapToXml=G;exports.validateSitemap=ie;//# sourceMappingURL=sitemap.js.map
|
|
6
6
|
//# sourceMappingURL=sitemap.js.map
|