@zeropress/build-core 0.1.8 → 0.1.9
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 +38 -6
- package/package.json +1 -1
- package/src/api/build-site.js +13 -3
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Shared build and partial-render core for ZeroPress.
|
|
|
9
9
|
This package is the deterministic rendering engine used by:
|
|
10
10
|
|
|
11
11
|
- `zeropress-admin-api-v2`
|
|
12
|
-
-
|
|
12
|
+
- [`@zeropress/build`](https://www.npmjs.com/package/@zeropress/build) package
|
|
13
13
|
|
|
14
14
|
It accepts canonical preview-data plus a validated theme package and produces static HTML artifacts through a writer interface.
|
|
15
15
|
|
|
@@ -59,7 +59,12 @@ import {
|
|
|
59
59
|
- `meta.json`
|
|
60
60
|
- writing outputs through a pluggable writer
|
|
61
61
|
|
|
62
|
-
It does not
|
|
62
|
+
It does not:
|
|
63
|
+
|
|
64
|
+
- fetch content from databases or APIs
|
|
65
|
+
- package or validate theme directories on its own unless the caller uses `buildSiteFromThemeDir`
|
|
66
|
+
- watch files, run a dev server, or perform deployment
|
|
67
|
+
- talk to queues, KV, Durable Objects, R2, GitHub, or other infrastructure directly
|
|
63
68
|
|
|
64
69
|
---
|
|
65
70
|
|
|
@@ -97,7 +102,7 @@ Returns:
|
|
|
97
102
|
}
|
|
98
103
|
],
|
|
99
104
|
manifest: {
|
|
100
|
-
generatedAt: '2026-04-02T00:00:
|
|
105
|
+
generatedAt: '2026-04-02T00:00:00Z',
|
|
101
106
|
files: [
|
|
102
107
|
{
|
|
103
108
|
path: 'index.html',
|
|
@@ -110,11 +115,29 @@ Returns:
|
|
|
110
115
|
}
|
|
111
116
|
```
|
|
112
117
|
|
|
118
|
+
Notes:
|
|
119
|
+
|
|
120
|
+
- `writer` is required
|
|
121
|
+
- `previewData` must already satisfy the canonical preview-data contract
|
|
122
|
+
- `themePackage` must already be a validated in-memory theme package
|
|
123
|
+
- `sitemap.xml` and `feed.xml` are emitted only when `site.url` is a non-empty canonical URL
|
|
124
|
+
- `robots.txt` and `meta.json` are still emitted when `generateSpecialFiles` is enabled
|
|
125
|
+
|
|
113
126
|
### `buildSelectedRoutes(input)`
|
|
114
127
|
|
|
115
128
|
Renders only selected post and list routes while preserving full-build parity for those outputs.
|
|
116
129
|
|
|
117
|
-
This is intended for
|
|
130
|
+
This is intended for targeted rebuilds, output parity checks, and other partial-render workflows.
|
|
131
|
+
|
|
132
|
+
Current selection scope is limited to:
|
|
133
|
+
|
|
134
|
+
- post detail routes
|
|
135
|
+
- index pagination routes
|
|
136
|
+
- archive routes
|
|
137
|
+
- category routes
|
|
138
|
+
- tag routes
|
|
139
|
+
|
|
140
|
+
It does not currently support selecting individual page routes.
|
|
118
141
|
|
|
119
142
|
Optional route templates are respected during both full and partial renders:
|
|
120
143
|
|
|
@@ -145,7 +168,7 @@ await buildSelectedRoutes({
|
|
|
145
168
|
|
|
146
169
|
Loads a theme directory from disk and renders it using the same core pipeline.
|
|
147
170
|
|
|
148
|
-
This is useful for local tooling
|
|
171
|
+
This is useful for local tooling that wants filesystem theme loading but still uses the same deterministic core renderer.
|
|
149
172
|
|
|
150
173
|
---
|
|
151
174
|
|
|
@@ -193,6 +216,8 @@ Theme validation is enforced through:
|
|
|
193
216
|
|
|
194
217
|
- [`@zeropress/theme-validator`](https://www.npmjs.com/package/@zeropress/theme-validator)
|
|
195
218
|
|
|
219
|
+
`buildSiteFromThemeDir()` is the convenience entry point that loads a theme directory and converts it into the required in-memory `themePackage`.
|
|
220
|
+
|
|
196
221
|
As of `preview-data v0.4`, the payload no longer carries `routes` arrays or raw HTML fragments such as `categories_html`.
|
|
197
222
|
|
|
198
223
|
Build-core now derives:
|
|
@@ -238,6 +263,13 @@ Supported options:
|
|
|
238
263
|
|
|
239
264
|
These options apply to both full builds and partial renders where relevant.
|
|
240
265
|
|
|
266
|
+
Defaults:
|
|
267
|
+
|
|
268
|
+
- `assetHashing: true`
|
|
269
|
+
- `generateSpecialFiles: true`
|
|
270
|
+
- `injectHtmx: true`
|
|
271
|
+
- `writeManifest: false`
|
|
272
|
+
|
|
241
273
|
---
|
|
242
274
|
|
|
243
275
|
## Requirements
|
|
@@ -251,7 +283,7 @@ These options apply to both full builds and partial renders where relevant.
|
|
|
251
283
|
|
|
252
284
|
- [@zeropress/preview-data-validator](https://www.npmjs.com/package/@zeropress/preview-data-validator)
|
|
253
285
|
- [@zeropress/theme-validator](https://www.npmjs.com/package/@zeropress/theme-validator)
|
|
254
|
-
- [zeropress
|
|
286
|
+
- [@zeropress/theme](https://www.npmjs.com/package/@zeropress/theme)
|
|
255
287
|
|
|
256
288
|
---
|
|
257
289
|
|
package/package.json
CHANGED
package/src/api/build-site.js
CHANGED
|
@@ -170,7 +170,7 @@ async function finalizeBuildResult(writer, summaries, options) {
|
|
|
170
170
|
let manifest;
|
|
171
171
|
if (options.writeManifest) {
|
|
172
172
|
manifest = {
|
|
173
|
-
generatedAt: new Date()
|
|
173
|
+
generatedAt: formatUtcIsoSeconds(new Date()),
|
|
174
174
|
files: summaries.map((file) => ({ ...file })),
|
|
175
175
|
};
|
|
176
176
|
await writeOutput(
|
|
@@ -327,6 +327,8 @@ function normalizePreviewData(previewData) {
|
|
|
327
327
|
posts: previewData.content.posts
|
|
328
328
|
.map((post) => ({
|
|
329
329
|
...post,
|
|
330
|
+
published_at_iso: normalizeIsoTimestamp(post.published_at_iso),
|
|
331
|
+
updated_at_iso: normalizeIsoTimestamp(post.updated_at_iso),
|
|
330
332
|
author_avatar: normalizeMediaField(post.author_avatar, normalizedSite.mediaBaseUrl),
|
|
331
333
|
featured_image: normalizeMediaField(post.featured_image, normalizedSite.mediaBaseUrl),
|
|
332
334
|
}))
|
|
@@ -1066,7 +1068,7 @@ function buildSitemapXml(site, emitted, generatedAt) {
|
|
|
1066
1068
|
const body = entries.map((entry) => {
|
|
1067
1069
|
const loc = escapeXml(resolveSiteUrl(site.url, entry.url));
|
|
1068
1070
|
const lastmod = entry.lastmod
|
|
1069
|
-
? `\n <lastmod>${entry.lastmod
|
|
1071
|
+
? `\n <lastmod>${formatUtcIsoSeconds(entry.lastmod)}</lastmod>`
|
|
1070
1072
|
: '';
|
|
1071
1073
|
return ` <url>\n <loc>${loc}</loc>${lastmod}\n <changefreq>${entry.changefreq}</changefreq>\n <priority>${entry.priority.toFixed(1)}</priority>\n </url>`;
|
|
1072
1074
|
}).join('\n');
|
|
@@ -1118,7 +1120,7 @@ function buildMetaJson(site, emitted, generatedAt) {
|
|
|
1118
1120
|
];
|
|
1119
1121
|
|
|
1120
1122
|
return JSON.stringify({
|
|
1121
|
-
generated: generatedAt
|
|
1123
|
+
generated: formatUtcIsoSeconds(generatedAt),
|
|
1122
1124
|
site: {
|
|
1123
1125
|
title: site.title,
|
|
1124
1126
|
description: site.description,
|
|
@@ -1199,6 +1201,14 @@ function toDate(value) {
|
|
|
1199
1201
|
return value ? new Date(value) : new Date();
|
|
1200
1202
|
}
|
|
1201
1203
|
|
|
1204
|
+
function formatUtcIsoSeconds(value) {
|
|
1205
|
+
return toDate(value).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
function normalizeIsoTimestamp(value) {
|
|
1209
|
+
return value ? formatUtcIsoSeconds(value) : '';
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1202
1212
|
function escapeXml(str) {
|
|
1203
1213
|
return String(str || '')
|
|
1204
1214
|
.replace(/&/g, '&')
|