@uniweb/build 0.70.1 → 0.71.0
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/package.json +8 -8
- package/src/uwx/same-content.js +1 -1
- package/src/uwx/site-diff.js +2 -2
- package/src/uwx/site-project.js +14 -52
- package/src/uwx/site.js +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/build",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.71.0",
|
|
4
4
|
"description": "Build tooling for the Uniweb Component Web Platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
"sharp": "^0.35.3",
|
|
59
59
|
"yaml": "^2.5.0",
|
|
60
60
|
"@uniweb/content-writer": "^0.3.4",
|
|
61
|
-
"@uniweb/projections": "^0.7.9",
|
|
62
|
-
"@uniweb/content-reader": "^1.2.7",
|
|
63
|
-
"@uniweb/schemas": "^0.9.0",
|
|
64
61
|
"@uniweb/semantic-parser": "^1.4.1",
|
|
65
|
-
"@uniweb/
|
|
62
|
+
"@uniweb/projections": "^0.7.10",
|
|
63
|
+
"@uniweb/theming": "^0.1.16",
|
|
64
|
+
"@uniweb/content-reader": "^1.2.7",
|
|
65
|
+
"@uniweb/schemas": "^0.9.1"
|
|
66
66
|
},
|
|
67
67
|
"optionalDependencies": {
|
|
68
|
-
"@uniweb/runtime": "^0.28.
|
|
68
|
+
"@uniweb/runtime": "^0.28.1"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
|
@@ -74,8 +74,8 @@
|
|
|
74
74
|
"@tailwindcss/vite": "^4.0.0",
|
|
75
75
|
"@vitejs/plugin-react": "^4.0.0 || ^5.0.0",
|
|
76
76
|
"vite-plugin-svgr": "^4.0.0",
|
|
77
|
-
"@uniweb/
|
|
78
|
-
"@uniweb/
|
|
77
|
+
"@uniweb/core": "^0.34.0",
|
|
78
|
+
"@uniweb/runtime": "^0.28.1"
|
|
79
79
|
},
|
|
80
80
|
"peerDependenciesMeta": {
|
|
81
81
|
"vite": {
|
package/src/uwx/same-content.js
CHANGED
|
@@ -32,7 +32,7 @@ export function sameMarkdownDocument(markdown, doc) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// A document without the attributes that only restate a default: an inset's `embedKind: 'visual'`,
|
|
35
|
-
// which the parser writes and the pull's re-inlining
|
|
35
|
+
// which the parser writes and the pull's re-inlining (retired 2026-09-28) left out — so a body holding
|
|
36
36
|
// an inset never compared as unchanged (measured 2026-09-26 on the `marketing` template's hero).
|
|
37
37
|
function withoutDefaults(doc) {
|
|
38
38
|
return JSON.parse(JSON.stringify(doc), (_, v) => {
|
package/src/uwx/site-diff.js
CHANGED
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
// It needs TWO bases, and that is the non-obvious part.
|
|
30
30
|
//
|
|
31
31
|
// Our document and the backend's are not byte-comparable renderings of the same
|
|
32
|
-
// unit: the backend's copy carries fields we don't emit (
|
|
33
|
-
//
|
|
32
|
+
// unit: the backend's copy carries fields we don't emit (its own `$uuid`, for
|
|
33
|
+
// one) and serializes in its own key order. So a hash
|
|
34
34
|
// taken on our side and one taken on theirs differ for a unit NEITHER side touched.
|
|
35
35
|
// A single base therefore validates exactly one comparison and silently corrupts
|
|
36
36
|
// the other — with a local-representation base every unit looks "changed
|
package/src/uwx/site-project.js
CHANGED
|
@@ -383,50 +383,12 @@ export function siteInfoToConfig({ document, siteRoot, backend = null, sourceLoc
|
|
|
383
383
|
// Section records → section .md files
|
|
384
384
|
// ---------------------------------------------------------------------------
|
|
385
385
|
|
|
386
|
-
/**
|
|
387
|
-
* Re-inline a section's extracted insets back into its ProseMirror content —
|
|
388
|
-
* the exact inverse of content-collector's `extractInsets`. The producer pulls
|
|
389
|
-
* each `{params}` ref out of the body into an `insets[]` array
|
|
390
|
-
* and leaves an `inset_placeholder` behind; content-writer only serializes
|
|
391
|
-
* `inset_ref` nodes, so we restore them before serializing or the inset would
|
|
392
|
-
* be reported as unmappable and dropped.
|
|
393
|
-
*
|
|
394
|
-
* @param {object} content - the section's ProseMirror document (placeholders in)
|
|
395
|
-
* @param {Array} insets - `[{ refId, type, params, title, embedKind }]`
|
|
396
|
-
* @returns {object} a content document with `inset_ref` nodes restored
|
|
397
|
-
*/
|
|
398
|
-
function reinlineInsets(content, insets) {
|
|
399
|
-
if (!content || !Array.isArray(content.content) || !Array.isArray(insets) || insets.length === 0) {
|
|
400
|
-
return content
|
|
401
|
-
}
|
|
402
|
-
const byRef = new Map(insets.map((i) => [i.refId, i]))
|
|
403
|
-
|
|
404
|
-
const visit = (nodes) =>
|
|
405
|
-
nodes.map((node) => {
|
|
406
|
-
if (!node) return node
|
|
407
|
-
if (node.type === 'inset_placeholder') {
|
|
408
|
-
const inset = byRef.get(node.attrs?.refId)
|
|
409
|
-
if (!inset) return node // no match → leave the placeholder (the guard reports it)
|
|
410
|
-
const attrs = { component: inset.type, ...(inset.params || {}) }
|
|
411
|
-
if (inset.title != null) attrs.alt = inset.title
|
|
412
|
-
// `visual` is the extractor's default — omit it so the projected markdown
|
|
413
|
-
// doesn't gain a spurious `{embedKind=visual}` the source never had.
|
|
414
|
-
if (inset.embedKind && inset.embedKind !== 'visual') attrs.embedKind = inset.embedKind
|
|
415
|
-
return { type: 'inset_ref', attrs }
|
|
416
|
-
}
|
|
417
|
-
if (Array.isArray(node.content)) return { ...node, content: visit(node.content) }
|
|
418
|
-
return node
|
|
419
|
-
})
|
|
420
|
-
|
|
421
|
-
return { ...content, content: visit(content.content) }
|
|
422
|
-
}
|
|
423
|
-
|
|
424
386
|
/**
|
|
425
387
|
* Project one section `$`-record (from `page_sections` / `layout_sections`) to a
|
|
426
388
|
* section `.md` file — the inverse of site.js `mapSectionData`. Frontmatter is
|
|
427
|
-
* `type` + the flat `params`
|
|
428
|
-
* `fetch`
|
|
429
|
-
*
|
|
389
|
+
* `type` + `hidden` + the flat `params` (`background` and `theme` among them) +
|
|
390
|
+
* the data declaration (`params.fetch`, else the `fetch` field) + `id` (`stable_id`);
|
|
391
|
+
* the body is the section's content serialized to markdown. Idempotent.
|
|
430
392
|
*
|
|
431
393
|
* Note: `$children` (a section's child sections) are NOT written here — the page
|
|
432
394
|
* walk (`pageSectionsToFiles`) writes each to its own file and nests it under its
|
|
@@ -444,7 +406,10 @@ function reinlineInsets(content, insets) {
|
|
|
444
406
|
export function sectionRecordToFile({ filePath, record, sourceLocale = LOCALIZED_FIELD_ASSUMPTION.defaultSourceLocale, collector, freeformRelPath, freeformCandidates = null, writeId = true, context = null }) {
|
|
445
407
|
// ⛔ A stored `preset` or `input` is not written back: neither has an effect, and the build
|
|
446
408
|
// would only warn about it (2026-09-27).
|
|
447
|
-
|
|
409
|
+
// ⛔ No `background` / `theme_override` / `insets`: the site-content Model dropped all three
|
|
410
|
+
// (2026-09-28), with a stored background and theme copied into `params`. Until then a field
|
|
411
|
+
// filled in where `params` lacked the key, and a stored `insets[]` was re-inlined into the body.
|
|
412
|
+
const { type, stable_id, hidden, params, content, fetch } = record || {}
|
|
448
413
|
|
|
449
414
|
// A localized `content` field unwraps to the source-locale doc for the body; its
|
|
450
415
|
// target-locale structural maps are captured into the locales/ collector, and any
|
|
@@ -452,7 +417,7 @@ export function sectionRecordToFile({ filePath, record, sourceLocale = LOCALIZED
|
|
|
452
417
|
// locales/freeform/. A bare doc (source-only / pre-localization) passes through.
|
|
453
418
|
const sourceContent = unwrapLocalizedContent(content, sourceLocale, collector, freeformRelPath, freeformCandidates, context)
|
|
454
419
|
|
|
455
|
-
const { hidden: paramHidden, ...paramsRest } = params && typeof params === 'object' ? params : {}
|
|
420
|
+
const { hidden: paramHidden, fetch: paramFetch, ...paramsRest } = params && typeof params === 'object' ? params : {}
|
|
456
421
|
const frontmatter = {}
|
|
457
422
|
if (type !== undefined) frontmatter.type = type
|
|
458
423
|
// ⭐ `hidden:` says what the store says: written for a hidden section, and removed from the
|
|
@@ -461,25 +426,22 @@ export function sectionRecordToFile({ filePath, record, sourceLocale = LOCALIZED
|
|
|
461
426
|
// `params`, so one stored there counts when the field is absent.
|
|
462
427
|
frontmatter.hidden = (typeof hidden === 'boolean' ? hidden : paramHidden === true) ? true : undefined
|
|
463
428
|
Object.assign(frontmatter, paramsRest)
|
|
464
|
-
// ⚠️ A stored `background` / `theme_override` field wins over the same key in `params` while
|
|
465
|
-
// one is stored: an editor may still write the fields rather than `params` (2026-09-28;
|
|
466
|
-
// uwx-format.md § A page section's fields, Order).
|
|
467
|
-
if (background !== undefined) frontmatter.background = background
|
|
468
|
-
if (theme_override !== undefined) frontmatter.theme = theme_override
|
|
469
429
|
// Invert the build's resolution rather than copy it — see fetch-shapes.js. A new
|
|
470
430
|
// file gets `query:` for a declaration of names alone; a section that declares
|
|
471
431
|
// its data locally keeps it (`writeSectionFile`, the declaration keys).
|
|
472
|
-
|
|
473
|
-
|
|
432
|
+
// ⭐ From `params.fetch` when present — where a section carries its data since 2026-09-28 —
|
|
433
|
+
// else the stored field.
|
|
434
|
+
const ownFetch = paramFetch !== undefined ? paramFetch : fetch
|
|
435
|
+
if (ownFetch !== undefined) {
|
|
436
|
+
const { key, value } = authorableDeclaration(ownFetch)
|
|
474
437
|
frontmatter[key] = value
|
|
475
438
|
}
|
|
476
439
|
// `id:` only where the file's name does not already give it (`writeId`, `pageSectionsToFiles`).
|
|
477
440
|
if (stable_id !== undefined && writeId) frontmatter.id = stable_id
|
|
478
441
|
|
|
479
|
-
const body = insets ? reinlineInsets(sourceContent, insets) : sourceContent
|
|
480
442
|
// ⛔ Not `type: Content` into a file that names no type: it is what the push sent for it, and
|
|
481
443
|
// absent, the foundation's `defaultSection` renders it. Until 2026-09-26 a pull wrote it back.
|
|
482
|
-
return writeSectionFile({ filePath, content:
|
|
444
|
+
return writeSectionFile({ filePath, content: sourceContent, params: frontmatter, implied: { type: FILLED_SECTION_TYPE } })
|
|
483
445
|
}
|
|
484
446
|
|
|
485
447
|
// ---------------------------------------------------------------------------
|
package/src/uwx/site.js
CHANGED
|
@@ -302,6 +302,10 @@ function localizePageMeta(page, route, sourceLocale, translations) {
|
|
|
302
302
|
|
|
303
303
|
function mapSectionData(section) {
|
|
304
304
|
const params = { ...section.params }
|
|
305
|
+
// ⭐ The section's own data rides in `params.fetch` [Diego, 2026-09-28] — nothing on a store's
|
|
306
|
+
// side acts on it by name. ⚠️ Also sent as the `fetch` field it had until then, until an
|
|
307
|
+
// editor's reader looks in `params.fetch` (uwx-format.md § A page section's fields).
|
|
308
|
+
if (section.fetch) params.fetch = section.fetch
|
|
305
309
|
const data = { type: section.type || FILLED_SECTION_TYPE } // entity type requires `type`
|
|
306
310
|
setIf(data, 'stable_id', section.stableId ?? undefined)
|
|
307
311
|
// ⭐ A draft section — the store's own `hidden`, which an editor also writes [2026-09-28].
|