@zeropress/build-core 0.6.2 → 0.6.4

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 CHANGED
@@ -14,9 +14,9 @@ This package is the canonical rendering core for preview-data and theme packages
14
14
  Public contract references:
15
15
 
16
16
  - [Preview Data v0.6 Spec](https://zeropress.dev/spec/preview-data-v0.6.html)
17
- - [Preview Data v0.6 Schema](https://zeropress.dev/schemas/preview-data.v0.6.schema.json)
17
+ - [Preview Data v0.6 Schema](https://schemas.zeropress.dev/preview-data/v0.6/schema.json)
18
18
  - [Theme Runtime v0.6 Spec](https://zeropress.dev/spec/theme-runtime-v0.6.html)
19
- - [Theme Runtime v0.6 Schema](https://zeropress.dev/schemas/theme.v0.6.runtime.schema.json)
19
+ - [Theme Runtime v0.6 Schema](https://schemas.zeropress.dev/theme-runtime/v0.6/schema.json)
20
20
 
21
21
  It accepts canonical preview-data plus a validated theme package and produces static HTML artifacts through a writer interface.
22
22
 
@@ -56,7 +56,6 @@ import {
56
56
  - `sitemap.xml`
57
57
  - `feed.xml`
58
58
  - fallback `robots.txt`
59
- - `/_zeropress/comment-policy.json`
60
59
  - `/_zeropress/search.json` when native search is enabled
61
60
  - `/_zeropress/search.js` when native search is enabled
62
61
  - `/_zeropress/search_pagefind.js` when native search is enabled
@@ -192,10 +191,6 @@ Build-core derives:
192
191
  - `reading_time`
193
192
  - `comments_enabled`
194
193
 
195
- It also emits a comments allowlist artifact:
196
-
197
- - `/_zeropress/comment-policy.json`
198
-
199
194
  Comment availability is derived from preview-data policy:
200
195
 
201
196
  - `site.disallow_comments`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeropress/build-core",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "description": "Shared ZeroPress build core",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -34,10 +34,10 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "@zeropress/slug-policy": "0.1.0",
37
- "@zeropress/preview-data-validator": "0.6.2",
38
- "@zeropress/theme-validator": "0.6.2",
39
- "highlight.js": "^11.11.1",
40
- "markdown-it": "^14.1.0",
41
- "markdown-it-anchor": "^9.2.0"
37
+ "@zeropress/preview-data-validator": "0.6.3",
38
+ "@zeropress/theme-validator": "0.6.4",
39
+ "highlight.js": "11.11.1",
40
+ "markdown-it": "14.2.0",
41
+ "markdown-it-anchor": "9.2.0"
42
42
  }
43
43
  }
@@ -37,7 +37,6 @@ const DEFAULT_POST_INDEX = Object.freeze({
37
37
  paginate: true,
38
38
  });
39
39
  const PERMALINK_OUTPUT_STYLES = new Set(['directory', 'html-extension']);
40
- const COMMENT_POLICY_OUTPUT_PATH = '_zeropress/comment-policy.json';
41
40
  const SEARCH_INDEX_OUTPUT_PATH = '_zeropress/search.json';
42
41
  const SEARCH_ADAPTER_OUTPUT_PATH = '_zeropress/search.js';
43
42
  const SEARCH_PAGEFIND_ADAPTER_OUTPUT_PATH = '_zeropress/search_pagefind.js';
@@ -100,14 +99,6 @@ export async function buildSite(input) {
100
99
  await writeOutput(state.writer, state.summaries, assetOutput.path, assetOutput.content, assetOutput.contentType);
101
100
  }
102
101
 
103
- await writeOutput(
104
- state.writer,
105
- state.summaries,
106
- COMMENT_POLICY_OUTPUT_PATH,
107
- state.commentPolicyContent,
108
- 'application/json',
109
- );
110
-
111
102
  if (shouldGenerateSearchArtifacts(state, options)) {
112
103
  await writeOutput(state.writer, state.summaries, SEARCH_INDEX_OUTPUT_PATH, buildSearchIndexJson(state), 'application/json');
113
104
  await writeOutput(state.writer, state.summaries, SEARCH_ADAPTER_OUTPUT_PATH, buildSearchAdapterJs(), 'application/javascript');
@@ -173,7 +164,6 @@ async function createBuildState(input, options) {
173
164
  customHtml: previewData.custom_html,
174
165
  favicon: previewData.site.favicon,
175
166
  exposeGenerator: previewData.site.expose_generator !== false,
176
- commentPolicyContent: buildCommentPolicyManifest(renderData.posts),
177
167
  options,
178
168
  generatedAt: new Date(),
179
169
  emitted: {
@@ -239,7 +229,9 @@ async function renderRoute(state, templateName, route) {
239
229
  route: routeContext,
240
230
  meta: buildPageMeta(state.previewData.site, {
241
231
  currentUrl,
242
- title: state.previewData.site.title,
232
+ title: route.is_front_page === true
233
+ ? buildFrontPageTitle(state.previewData.site)
234
+ : state.previewData.site.title,
243
235
  description: state.previewData.site.description,
244
236
  ogType: 'website',
245
237
  }),
@@ -286,7 +278,7 @@ async function renderFrontPage(state, route) {
286
278
  route: routeContext,
287
279
  meta: buildPageMeta(state.previewData.site, {
288
280
  currentUrl,
289
- title: buildDocumentTitle(page.title, state.previewData.site.title),
281
+ title: buildFrontPageTitle(state.previewData.site),
290
282
  description: page.excerpt,
291
283
  ogType: 'website',
292
284
  image: page.featured_image,
@@ -319,7 +311,7 @@ async function renderFrontPage(state, route) {
319
311
  route: routeContext,
320
312
  meta: buildPageMeta(state.previewData.site, {
321
313
  currentUrl,
322
- title: state.previewData.site.title,
314
+ title: buildFrontPageTitle(state.previewData.site),
323
315
  description: state.previewData.site.description,
324
316
  ogType: 'website',
325
317
  }),
@@ -441,13 +433,17 @@ async function maybeRenderNotFoundPage(state) {
441
433
  }
442
434
 
443
435
  function normalizePreviewData(previewData, options = {}) {
436
+ const media_base_url = normalizeOptionalString(previewData.site.media_base_url);
444
437
  const normalizedSite = {
445
438
  ...previewData.site,
446
- media_base_url: normalizeOptionalString(previewData.site.media_base_url),
439
+ media_base_url,
447
440
  media_delivery_mode: MEDIA_DELIVERY_MODES.has(previewData.site.media_delivery_mode)
448
441
  ? previewData.site.media_delivery_mode
449
442
  : 'none',
450
- favicon: normalizeSiteFavicon(previewData.site.favicon || options.favicon),
443
+ favicon: previewData.site.favicon
444
+ ? normalizeSiteFavicon(previewData.site.favicon, media_base_url)
445
+ : normalizeSiteFavicon(options.favicon, ''),
446
+ logo: normalizeSiteLogo(previewData.site.logo, media_base_url),
451
447
  posts_per_page: Number.isInteger(previewData.site.posts_per_page) && previewData.site.posts_per_page > 0
452
448
  ? previewData.site.posts_per_page
453
449
  : DEFAULT_POSTS_PER_PAGE,
@@ -738,7 +734,7 @@ function normalizeCustomHtml(customHtml) {
738
734
  };
739
735
  }
740
736
 
741
- function normalizeSiteFavicon(favicon) {
737
+ function normalizeSiteFavicon(favicon, media_base_url) {
742
738
  if (!favicon || typeof favicon !== 'object') {
743
739
  return undefined;
744
740
  }
@@ -747,13 +743,30 @@ function normalizeSiteFavicon(favicon) {
747
743
  for (const key of ['icon', 'svg', 'png', 'apple_touch_icon']) {
748
744
  const value = normalizeOptionalString(favicon[key]);
749
745
  if (value) {
750
- normalized[key] = value;
746
+ normalized[key] = normalizeMediaField(value, media_base_url);
751
747
  }
752
748
  }
753
749
 
754
750
  return Object.keys(normalized).length ? normalized : undefined;
755
751
  }
756
752
 
753
+ function normalizeSiteLogo(logo, media_base_url) {
754
+ if (!logo || typeof logo !== 'object') {
755
+ return undefined;
756
+ }
757
+
758
+ const src = normalizeMediaField(logo.src, media_base_url);
759
+ if (!src) {
760
+ return undefined;
761
+ }
762
+
763
+ const alt = normalizeOptionalString(logo.alt);
764
+ return {
765
+ src,
766
+ ...(alt ? { alt } : {}),
767
+ };
768
+ }
769
+
757
770
  function normalizePermalinks(permalinks) {
758
771
  const source = permalinks && typeof permalinks === 'object' ? permalinks : {};
759
772
  const outputStyle = typeof source.output_style === 'string' && PERMALINK_OUTPUT_STYLES.has(source.output_style)
@@ -1006,8 +1019,12 @@ function attachCollectionCursors(posts, pages, collections) {
1006
1019
  return;
1007
1020
  }
1008
1021
 
1022
+ const cursor = buildCollectionCursor(collectionId, collection, items, index);
1009
1023
  target.collection_cursors = target.collection_cursors || {};
1010
- target.collection_cursors[collectionId] = buildCollectionCursor(collectionId, collection, items, index);
1024
+ target.collection_cursors[collectionId] = cursor;
1025
+ if (!target.collection_cursor) {
1026
+ target.collection_cursor = cursor;
1027
+ }
1011
1028
  });
1012
1029
  }
1013
1030
  }
@@ -1434,18 +1451,6 @@ function preparePost(post, site, authorsById, categoriesBySlug, tagsBySlug, them
1434
1451
  };
1435
1452
  }
1436
1453
 
1437
- function buildCommentPolicyManifest(posts) {
1438
- const commentablePosts = posts
1439
- .filter((post) => post.status === 'published' && post.comments_enabled === true)
1440
- .map((post) => post.public_id)
1441
- .filter((value) => Number.isInteger(value) && value > 0);
1442
-
1443
- return JSON.stringify({
1444
- version: 1,
1445
- commentable_posts: commentablePosts,
1446
- }, null, 2);
1447
- }
1448
-
1449
1454
  function buildTaxonomyRoutes(options) {
1450
1455
  const routes = [];
1451
1456
 
@@ -2094,6 +2099,12 @@ function buildDocumentTitle(contentTitle, siteTitle) {
2094
2099
  return `${resolvedContentTitle} - ${resolvedSiteTitle}`;
2095
2100
  }
2096
2101
 
2102
+ function buildFrontPageTitle(site) {
2103
+ const resolvedSiteTitle = normalizeNonEmptyString(site.title, '');
2104
+ const resolvedDescription = normalizeOptionalString(site.description);
2105
+ return resolvedDescription ? `${resolvedSiteTitle} - ${resolvedDescription}` : resolvedSiteTitle;
2106
+ }
2107
+
2097
2108
  function buildMetaHeadTags(meta) {
2098
2109
  const tags = [];
2099
2110
 
@@ -2398,7 +2409,6 @@ function assertPlannedOutputPathsSafe(state) {
2398
2409
  const plannedPaths = [
2399
2410
  ...routeEntries.map((entry) => entry.outputPath),
2400
2411
  ...state.assetOutputs.map((assetOutput) => assetOutput.path),
2401
- COMMENT_POLICY_OUTPUT_PATH,
2402
2412
  ];
2403
2413
 
2404
2414
  if (shouldGenerateSearchArtifacts(state, state.options)) {