@zeropress/build-core 0.6.5 → 0.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/package.json +2 -2
- package/src/api/build-site.js +23 -3
- package/src/index.d.ts +1 -0
- package/src/render/content-renderer.js +6 -4
package/README.md
CHANGED
|
@@ -120,7 +120,8 @@ Notes:
|
|
|
120
120
|
- `writer` is required
|
|
121
121
|
- `previewData` must already satisfy the canonical preview-data contract
|
|
122
122
|
- `themePackage` must already be a validated in-memory theme package
|
|
123
|
-
- `sitemap.xml`
|
|
123
|
+
- `sitemap.xml` is emitted only when `site.url` is a non-empty canonical URL
|
|
124
|
+
- `feed.xml` is emitted only when `site.url` is a non-empty canonical URL and `generateFeed` is not `false`
|
|
124
125
|
- callers may pass `sitemapStylesheetHref` to add an XML stylesheet processing instruction to generated `sitemap.xml`
|
|
125
126
|
- fallback `robots.txt` is emitted when `generateSpecialFiles` is enabled and `generateRobotsTxt` is not `false`
|
|
126
127
|
- fallback `robots.txt` uses `site.indexing`; `false` emits `Disallow: /`, while missing or `true` emits `Allow: /`
|
|
@@ -229,6 +230,7 @@ Supported options:
|
|
|
229
230
|
- `favicon`
|
|
230
231
|
- `sitemapStylesheetHref`
|
|
231
232
|
- `generateSpecialFiles`
|
|
233
|
+
- `generateFeed`
|
|
232
234
|
- `generateRobotsTxt`
|
|
233
235
|
- `writeManifest`
|
|
234
236
|
|
|
@@ -238,6 +240,7 @@ Defaults:
|
|
|
238
240
|
|
|
239
241
|
- `assetHashing: true`
|
|
240
242
|
- `generateSpecialFiles: true`
|
|
243
|
+
- `generateFeed: true`
|
|
241
244
|
- `generateRobotsTxt: true`
|
|
242
245
|
- `writeManifest: false`
|
|
243
246
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeropress/build-core",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.8",
|
|
4
4
|
"description": "Shared ZeroPress build core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@zeropress/slug-policy": "0.1.0",
|
|
37
|
-
"@zeropress/preview-data-validator": "0.6.
|
|
37
|
+
"@zeropress/preview-data-validator": "0.6.6",
|
|
38
38
|
"@zeropress/theme-validator": "0.6.5",
|
|
39
39
|
"highlight.js": "11.11.1",
|
|
40
40
|
"markdown-it": "14.2.0",
|
package/src/api/build-site.js
CHANGED
|
@@ -9,6 +9,7 @@ import { ZeroPressEngine } from '../render/zeropress-engine.js';
|
|
|
9
9
|
const DEFAULT_OPTIONS = {
|
|
10
10
|
assetHashing: true,
|
|
11
11
|
generateSpecialFiles: true,
|
|
12
|
+
generateFeed: true,
|
|
12
13
|
generateRobotsTxt: true,
|
|
13
14
|
writeManifest: false,
|
|
14
15
|
};
|
|
@@ -115,7 +116,9 @@ export async function buildSite(input) {
|
|
|
115
116
|
buildSitemapXml(state.previewData.site, state.emitted, state.generatedAt, options.sitemapStylesheetHref),
|
|
116
117
|
'application/xml',
|
|
117
118
|
);
|
|
118
|
-
|
|
119
|
+
if (shouldGenerateFeed(options)) {
|
|
120
|
+
await writeOutput(state.writer, state.summaries, 'feed.xml', buildFeedXml(state.previewData.site, state.emitted, state.generatedAt), 'application/rss+xml');
|
|
121
|
+
}
|
|
119
122
|
}
|
|
120
123
|
if (shouldGenerateRobotsTxt(options)) {
|
|
121
124
|
await writeOutput(state.writer, state.summaries, 'robots.txt', buildRobotsTxt(state.previewData.site), 'text/plain');
|
|
@@ -294,6 +297,7 @@ async function renderFrontPage(state, route) {
|
|
|
294
297
|
url: currentUrl,
|
|
295
298
|
title: page.title,
|
|
296
299
|
description: page.excerpt,
|
|
300
|
+
updatedAt: page.updated_at_iso,
|
|
297
301
|
includeInFeed: false,
|
|
298
302
|
includeInSitemap: !isDelistedDocument(page),
|
|
299
303
|
};
|
|
@@ -400,6 +404,7 @@ async function renderPage(state, page) {
|
|
|
400
404
|
url: currentUrl,
|
|
401
405
|
title: page.title,
|
|
402
406
|
description: page.excerpt,
|
|
407
|
+
updatedAt: page.updated_at_iso,
|
|
403
408
|
status: page.status,
|
|
404
409
|
includeInSitemap: page.omit_from_sitemap !== true && !isDelistedDocument(page),
|
|
405
410
|
});
|
|
@@ -508,6 +513,7 @@ function normalizePreviewData(previewData, options = {}) {
|
|
|
508
513
|
const featuredMedia = deriveManagedMedia(featuredImage, mediaRegistry, normalizedSite);
|
|
509
514
|
return {
|
|
510
515
|
...page,
|
|
516
|
+
...(page.updated_at_iso ? { updated_at_iso: normalizeIsoTimestamp(page.updated_at_iso) } : {}),
|
|
511
517
|
discoverability: normalizeDiscoverability(page.discoverability),
|
|
512
518
|
featured_image: featuredImage,
|
|
513
519
|
...(featuredMedia ? { featured_media: featuredMedia } : {}),
|
|
@@ -995,6 +1001,8 @@ function buildCollectionPageSummary(page, frontPage) {
|
|
|
995
1001
|
url: frontPage?.type === 'page' && frontPage.page_slug === page.slug ? '/' : page.url,
|
|
996
1002
|
excerpt: page.excerpt || '',
|
|
997
1003
|
featured_image: page.featured_image || '',
|
|
1004
|
+
updated_at: page.updated_at || '',
|
|
1005
|
+
updated_at_iso: page.updated_at_iso || '',
|
|
998
1006
|
...(page.featured_media ? { featured_media: { ...page.featured_media } } : {}),
|
|
999
1007
|
meta: page.meta,
|
|
1000
1008
|
data: page.data,
|
|
@@ -1057,6 +1065,8 @@ function buildCollectionCursorItemSummary(item) {
|
|
|
1057
1065
|
url: item.url,
|
|
1058
1066
|
excerpt: item.excerpt || '',
|
|
1059
1067
|
featured_image: item.featured_image || '',
|
|
1068
|
+
updated_at: item.updated_at || '',
|
|
1069
|
+
updated_at_iso: item.updated_at_iso || '',
|
|
1060
1070
|
meta: item.meta,
|
|
1061
1071
|
data: item.data,
|
|
1062
1072
|
};
|
|
@@ -1389,6 +1399,7 @@ function preparePage(page, site) {
|
|
|
1389
1399
|
document_type: documentType,
|
|
1390
1400
|
html: renderedDocument.html,
|
|
1391
1401
|
toc: renderedDocument.toc,
|
|
1402
|
+
updated_at: page.updated_at_iso ? formatTimestamp(page.updated_at_iso, site) : '',
|
|
1392
1403
|
};
|
|
1393
1404
|
}
|
|
1394
1405
|
|
|
@@ -2421,7 +2432,10 @@ function assertPlannedOutputPathsSafe(state) {
|
|
|
2421
2432
|
plannedPaths.push('robots.txt');
|
|
2422
2433
|
}
|
|
2423
2434
|
if (hasCanonicalSiteUrl(state.previewData.site.url)) {
|
|
2424
|
-
plannedPaths.push('sitemap.xml'
|
|
2435
|
+
plannedPaths.push('sitemap.xml');
|
|
2436
|
+
if (shouldGenerateFeed(state.options)) {
|
|
2437
|
+
plannedPaths.push('feed.xml');
|
|
2438
|
+
}
|
|
2425
2439
|
}
|
|
2426
2440
|
}
|
|
2427
2441
|
|
|
@@ -2633,7 +2647,7 @@ function buildSearchPageItem(page, url) {
|
|
|
2633
2647
|
categories: [],
|
|
2634
2648
|
tags: [],
|
|
2635
2649
|
published_at_iso: '',
|
|
2636
|
-
updated_at_iso:
|
|
2650
|
+
updated_at_iso: normalizeIsoTimestamp(page.updated_at_iso),
|
|
2637
2651
|
content_text: htmlToSearchText(page.html),
|
|
2638
2652
|
};
|
|
2639
2653
|
}
|
|
@@ -3073,6 +3087,7 @@ function buildSitemapXml(site, emitted, generatedAt, stylesheetHref = '') {
|
|
|
3073
3087
|
...(emitted.frontPage && emitted.frontPage.includeInSitemap !== false
|
|
3074
3088
|
? [{
|
|
3075
3089
|
url: emitted.frontPage.url,
|
|
3090
|
+
...(emitted.frontPage.updatedAt ? { lastmod: toDate(emitted.frontPage.updatedAt) } : {}),
|
|
3076
3091
|
changefreq: 'daily',
|
|
3077
3092
|
priority: 1.0,
|
|
3078
3093
|
}]
|
|
@@ -3094,6 +3109,7 @@ function buildSitemapXml(site, emitted, generatedAt, stylesheetHref = '') {
|
|
|
3094
3109
|
.filter((page) => page.includeInSitemap !== false)
|
|
3095
3110
|
.map((page) => ({
|
|
3096
3111
|
url: page.url,
|
|
3112
|
+
...(page.updatedAt ? { lastmod: toDate(page.updatedAt) } : {}),
|
|
3097
3113
|
changefreq: 'monthly',
|
|
3098
3114
|
priority: 0.7,
|
|
3099
3115
|
})),
|
|
@@ -3148,6 +3164,10 @@ function shouldGenerateRobotsTxt(options) {
|
|
|
3148
3164
|
return options.generateSpecialFiles && options.generateRobotsTxt !== false;
|
|
3149
3165
|
}
|
|
3150
3166
|
|
|
3167
|
+
function shouldGenerateFeed(options) {
|
|
3168
|
+
return options.generateSpecialFiles && options.generateFeed !== false;
|
|
3169
|
+
}
|
|
3170
|
+
|
|
3151
3171
|
function shouldGenerateSearchArtifacts(state, options) {
|
|
3152
3172
|
return options.generateSpecialFiles && state.previewData.site.search === true;
|
|
3153
3173
|
}
|
package/src/index.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ function renderMarkdownDocument(content) {
|
|
|
49
49
|
function createMarkdownRenderer(toc) {
|
|
50
50
|
const markdown = new MarkdownIt({
|
|
51
51
|
html: true,
|
|
52
|
-
linkify:
|
|
52
|
+
linkify: false,
|
|
53
53
|
typographer: true,
|
|
54
54
|
breaks: true,
|
|
55
55
|
highlight(value, language) {
|
|
@@ -162,8 +162,10 @@ function markdownTaskLists(markdown) {
|
|
|
162
162
|
addTokenClass(listItemToken, 'task-list-item');
|
|
163
163
|
|
|
164
164
|
const checkboxToken = new state.Token('html_inline', '', 0);
|
|
165
|
-
const
|
|
166
|
-
|
|
165
|
+
const isChecked = markerMatch[1].toLowerCase() === 'x';
|
|
166
|
+
const checked = isChecked ? ' checked' : '';
|
|
167
|
+
const label = isChecked ? 'Completed task' : 'Incomplete task';
|
|
168
|
+
checkboxToken.content = `<input class="task-list-item-checkbox" type="checkbox"${checked} disabled aria-label="${label}"> `;
|
|
167
169
|
|
|
168
170
|
const strippedContent = token.content.slice(markerMatch[0].length);
|
|
169
171
|
token.content = strippedContent;
|
|
@@ -337,7 +339,7 @@ function sanitizeHtml(html) {
|
|
|
337
339
|
aside: new Set(['role', 'class', 'id']),
|
|
338
340
|
img: new Set(['src', 'srcset', 'sizes', 'alt', 'title', 'class', 'id', 'width', 'height', 'loading', 'decoding']),
|
|
339
341
|
iframe: new Set(['src', 'width', 'height', 'frameborder', 'allowfullscreen', 'class']),
|
|
340
|
-
input: new Set(['type', 'checked', 'disabled', 'class', 'id']),
|
|
342
|
+
input: new Set(['type', 'checked', 'disabled', 'class', 'id', 'aria-label']),
|
|
341
343
|
source: new Set(['src', 'srcset', 'sizes', 'type', 'media', 'width', 'height', 'class', 'id']),
|
|
342
344
|
'*': new Set(['class', 'id']),
|
|
343
345
|
};
|