sbuilder-mcp 0.40.0 → 0.42.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/CHANGELOG.md +25 -0
- package/CHANGELOG.vi.md +25 -0
- package/README.md +2 -2
- package/README.vi.md +2 -2
- package/dist/catalog/api.generated.js +5 -1
- package/dist/catalog/checkout.generated.js +15 -1
- package/dist/catalog/deadkeys.generated.js +29 -0
- package/dist/catalog/element-search.js +21 -3
- package/dist/catalog/elements.generated.js +886 -26
- package/dist/catalog/search.js +28 -0
- package/dist/catalog/shapes.generated.js +11 -1
- package/dist/catalog/storepages.generated.js +156 -7
- package/dist/catalog/translations.generated.js +8 -3
- package/dist/domains/site/discover.js +89 -2
- package/dist/domains/site/importmap.js +53 -14
- package/dist/domains/site/inert.js +153 -0
- package/dist/domains/site/patterns.js +144 -0
- package/dist/domains/site/shape.js +11 -1
- package/dist/domains/site/vocabulary.js +142 -1
- package/dist/tools/importpage.js +52 -10
- package/dist/tools/page.js +33 -1
- package/dist/vision/capture.js +174 -24
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,31 @@ All notable changes to this project are documented in this file.
|
|
|
6
6
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
7
7
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
8
|
|
|
9
|
+
## [0.42.0] - 2026-09-14
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- sb_traits_for now returns specials_values alongside config_values, growing the legal-value vocabulary from 3 globally-unique keys to 26 keys scoped per element (cart-total's part, breadcrumb's source, divider's contentType/contentPosition/orientation, dropdown/popover's panelAlign/placement, media-dataset's layout, popup's triggerType, tab's tabPosition, product-image-feature's mainImageSource, list-dataset's loadingMode, locale-switcher's labelMode, member-field's field, and the shared backgroundSceneSource among them), so a control whose name does not match its write key still resolves to the right vocabulary; sb_set now warns when a written value falls outside the element's vocabulary, naming the values that actually do something.
|
|
13
|
+
- sb_set now warns when a config or specials write targets a key that no renderer, editor, or runtime reads anywhere in the platform, instead of storing it silently with no effect at all; the first catalog scan of every seeded key against the platform's own source found exactly one, config.splitDirection on image-comparison.
|
|
14
|
+
- npm run codegen and npm run codegen:check now warn when an element's own AI hints describe it in "renders only through/inside" language while the element is missing from the inert-element table or its rejection ledger, catching drift like the quickview element that had already shipped unnoticed.
|
|
15
|
+
- The catalog now covers the platform's background 3D scene feature on flex-section, flex-block and dataset-block (backgroundSceneSource, effect, gallery, model, veil and color config keys), reachable through sb_traits_for and sb_add.
|
|
16
|
+
- A product's shape (sb_api_find / sb_api_call) now includes modelUrl, the product's optional 3D model URL, and the binding-source count grew from 78 to 79 to cover it.
|
|
17
|
+
- chat-widget's launcher text is now translatable through sb_traits_for's translatable field, alongside its existing title.
|
|
18
|
+
|
|
19
|
+
## [0.41.0] - 2026-09-13
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- `sb_templates` / `sb_template_use` gain four new built-in layout patterns — `sb_product_shelf` and `sb_category_strip` are real `list-dataset` repeaters bound to the catalogue rather than static tiles, `sb_brand_wall` frames library logos with `contain` instead of a photograph's median-ratio crop, and `sb_trust_band` composes icon-plus-line reassurances from exact platform icon ids.
|
|
23
|
+
- `sb_api_find` and `sb_api_call` now attach a `product_traps` note to the four operations that create or replace a whole product, naming three facts a `ProductInput` body cannot show on its own: price lives on the variant rather than the product, a colliding slug is silently renamed rather than refused, and an image can be ingested straight from a URL in one hop.
|
|
24
|
+
- The inert-element table grew from 3 to 20 entries after an audit of all 113 catalog elements, adding `quickview`, `bundle-items`, `chat-widget`, `currency-switcher`, `theme-switcher`, `form-step-count`, `form-step-button`, `order-receipt`, `payment-status`, `points-card`, `points-prompt`, `list-empty`, `list-loading`, `rating-stars`, `accordion-content`, `menu-drawer` and `menu-panel` — elements that render convincingly on the first write while doing nothing useful, so `sb_add` can now warn about them before publish.
|
|
25
|
+
- `sb_import_site` now reads a sitemap index's own child filenames to tell record pages (products, categories, brands, tags) from page-shaped ones, and excludes the record kinds from the import plan by default instead of picking whichever URLs happen to win the page cap.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- `sb_import` and `sb_import_site` no longer turn an `<svg>`'s wrapper or utility class into a confident wrong icon; a class candidate is only considered when it carries a prefix a real icon set actually stamps, ranked by length only as a tie-break among those.
|
|
29
|
+
- `sb_import` and `sb_import_site` now build a captured list as a real `list` of `list-item` nodes carrying the platform's own marker icon, instead of a column of text nodes each with a literal bullet glyph glued on.
|
|
30
|
+
- The `structure` fidelity score no longer reports arrangement loss on pages with lists; the shape comparison now counts a captured list's rows as real children instead of scoring the list as an empty leaf.
|
|
31
|
+
- `sb_import_site`'s theme write and its per-node color/font-size stamping no longer fight each other; the four token fields a default style preset already resolves through the theme are dropped from the stamped literals once the theme write actually lands, so an imported page's colors stay controlled by the theme instead of a literal that silently outranks it forever.
|
|
32
|
+
- The `coverage` score reported by `sb_import` and `sb_import_site` no longer counts text the importer deliberately declines (chrome, hidden elements, form controls, decorative content) as lost content, and no longer misses text in a bare top-level `<nav>` or a hidden `<select>` that the page-section walk never visits at all.
|
|
33
|
+
|
|
9
34
|
## [0.40.0] - 2026-09-13
|
|
10
35
|
|
|
11
36
|
### Added
|
package/CHANGELOG.vi.md
CHANGED
|
@@ -6,6 +6,31 @@ Mọi thay đổi đáng chú ý của dự án được ghi lại trong file n
|
|
|
6
6
|
Định dạng dựa trên [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
7
7
|
và dự án tuân theo [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
8
|
|
|
9
|
+
## [0.42.0] - 2026-09-14
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- sb_traits_for giờ trả thêm specials_values bên cạnh config_values, mở rộng bảng giá trị hợp lệ từ 3 khóa dùng chung toàn cục lên 26 khóa gắn theo từng phần tử (part của cart-total, source của breadcrumb, contentType/contentPosition/orientation của divider, panelAlign/placement của dropdown/popover, layout của media-dataset, triggerType của popup, tabPosition của tab, mainImageSource của product-image-feature, loadingMode của list-dataset, labelMode của locale-switcher, field của member-field, cùng backgroundSceneSource dùng chung), nhờ đó một control có tên khác với key nó ghi vẫn tra đúng bảng giá trị. sb_set giờ cảnh báo khi giá trị được ghi nằm ngoài bảng giá trị của phần tử đó, nêu rõ những giá trị thật sự có tác dụng.
|
|
13
|
+
- sb_set giờ cảnh báo khi một lệnh ghi config hoặc specials nhắm vào một key mà không renderer, không editor, không runtime nào trong nền tảng đọc tới, thay vì âm thầm lưu lại mà không có tác dụng gì; lượt quét đầu tiên đối chiếu mọi key được seed với chính mã nguồn nền tảng tìm ra đúng một trường hợp, config.splitDirection trên image-comparison.
|
|
14
|
+
- npm run codegen và npm run codegen:check giờ cảnh báo khi mô tả AI hint của một phần tử dùng ngôn ngữ kiểu "chỉ render qua/bên trong" nhưng phần tử đó lại vắng mặt trong bảng phần tử "inert" lẫn sổ loại trừ của nó, bắt được các trường hợp trôi dạt như phần tử quickview từng lên hàng mà không ai để ý.
|
|
15
|
+
- Catalog giờ bao phủ tính năng nền cảnh 3D của nền tảng trên flex-section, flex-block và dataset-block (các config key backgroundSceneSource, effect, gallery, model, veil và màu sắc), có thể tra qua sb_traits_for và dùng qua sb_add.
|
|
16
|
+
- Shape của sản phẩm (sb_api_find / sb_api_call) giờ có thêm modelUrl, URL mô hình 3D tùy chọn của sản phẩm, và số nguồn binding tăng từ 78 lên 79 để bao phủ nó.
|
|
17
|
+
- Chữ trên nút mở chat của chat-widget giờ dịch được qua field translatable của sb_traits_for, cùng với title vốn đã có.
|
|
18
|
+
|
|
19
|
+
## [0.41.0] - 2026-09-13
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- `sb_templates` / `sb_template_use` có thêm bốn layout dựng sẵn — `sb_product_shelf` và `sb_category_strip` là repeater `list-dataset` thật, gắn vào catalogue thay vì các ô tĩnh; `sb_brand_wall` đóng khung logo lấy từ thư viện bằng `contain` thay vì crop theo tỉ lệ trung vị của ảnh chụp; `sb_trust_band` ghép các dòng cam kết icon-kèm-chữ từ đúng các id icon của nền tảng.
|
|
23
|
+
- `sb_api_find` và `sb_api_call` giờ đính kèm ghi chú `product_traps` vào bốn operation tạo hoặc thay thế toàn bộ một sản phẩm, nêu rõ ba điều mà body `ProductInput` không tự nói lên được: giá nằm ở variant chứ không phải ở product, một slug trùng bị đổi tên âm thầm chứ không bị từ chối, và có thể nạp ảnh thẳng từ URL trong một bước thay vì hai.
|
|
24
|
+
- Bảng phần tử "inert" tăng từ 3 lên 20 mục sau khi rà soát toàn bộ 113 phần tử trong catalog, thêm `quickview`, `bundle-items`, `chat-widget`, `currency-switcher`, `theme-switcher`, `form-step-count`, `form-step-button`, `order-receipt`, `payment-status`, `points-card`, `points-prompt`, `list-empty`, `list-loading`, `rating-stars`, `accordion-content`, `menu-drawer` và `menu-panel` — những phần tử trông có vẻ hoàn chỉnh ngay ở lần ghi đầu tiên nhưng không làm được gì cả, nên `sb_add` giờ có thể cảnh báo về chúng trước khi publish.
|
|
25
|
+
- `sb_import_site` giờ đọc tên file của từng sitemap con trong một sitemap index để phân biệt trang dữ liệu (sản phẩm, danh mục, thương hiệu, tag) với trang nội dung thông thường, và mặc định loại các trang dữ liệu khỏi kế hoạch import thay vì chọn đại URL nào thắng giới hạn số trang.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- `sb_import` và `sb_import_site` không còn biến class wrapper hay class tiện ích của một `<svg>` thành một icon sai nhưng trông chắc chắn đúng; một class chỉ được xét khi mang tiền tố mà một bộ icon thật sự dùng, và chỉ xếp hạng theo độ dài như một cách phân định giữa các ứng viên đó.
|
|
29
|
+
- `sb_import` và `sb_import_site` giờ dựng một danh sách đã capture thành `list` thật gồm các `list-item`, mang icon đánh dấu riêng của nền tảng, thay vì một cột các node văn bản mỗi cái gắn cứng một ký tự bullet.
|
|
30
|
+
- Điểm `structure` trong đo lường fidelity không còn báo mất cấu trúc trên các trang có danh sách; phép so sánh hình dạng giờ tính các dòng của một danh sách đã capture là con thật thay vì tính danh sách đó như một lá rỗng.
|
|
31
|
+
- Bản ghi theme của `sb_import_site` và việc gán màu/cỡ chữ literal lên từng node không còn triệt tiêu lẫn nhau; bốn field token mà một style preset mặc định vốn đã phân giải qua theme sẽ bị bỏ khỏi các literal được gán ngay khi bản ghi theme thực sự có hiệu lực, nhờ đó màu sắc của trang được import vẫn do theme kiểm soát thay vì một literal âm thầm đè lên nó mãi mãi.
|
|
32
|
+
- Điểm `coverage` mà `sb_import` và `sb_import_site` báo cáo không còn tính phần chữ mà importer chủ động bỏ qua (chrome, phần tử ẩn, control của form, nội dung trang trí) là nội dung bị mất, và không còn bỏ sót chữ nằm trong một `<nav>` cấp cao nhất hay một `<select>` ẩn mà lượt duyệt theo section chưa bao giờ chạm tới.
|
|
33
|
+
|
|
9
34
|
## [0.40.0] - 2026-09-13
|
|
10
35
|
|
|
11
36
|
### Added
|
package/README.md
CHANGED
|
@@ -94,7 +94,7 @@ in this client: one would put the very key the platform exists to hold back into
|
|
|
94
94
|
| `sb_move` | Move a node to another parent |
|
|
95
95
|
| `sb_remove` | Remove a node and its subtree |
|
|
96
96
|
| `sb_duplicate` | Copy a node and its subtree under fresh ids, right after the original |
|
|
97
|
-
| `sb_templates` | The store's saved section templates, plus the BUILT-IN layouts — hero, feature trio, stats, FAQ, CTA band — composed against the page's own tokens |
|
|
97
|
+
| `sb_templates` | The store's saved section templates, plus the BUILT-IN layouts — hero, feature trio, stats, FAQ, CTA band, product shelf, category strip, brand wall, trust band — composed against the page's own tokens |
|
|
98
98
|
| `sb_template_use` | Instantiate a template into a page |
|
|
99
99
|
| `sb_page_list` | Every page on the site |
|
|
100
100
|
| `sb_page_create` | Create a page — a store type arrives with the editor's own starting document; `type` is the route for checkout, product, category, post, course |
|
|
@@ -113,7 +113,7 @@ in this client: one would put the very key the platform exists to hold back into
|
|
|
113
113
|
| `sb_undo` | Put back what a PUT replaced. The SECOND answer for a page, not the only one: the platform has versions, history and restore (`sb_api_find` "page versions"), which outlive this process — reach for those first and use this for every other shaped PUT |
|
|
114
114
|
|
|
115
115
|
Twenty-eight tools, **524 API operations** (175 of the 234 writes carrying a body shape read
|
|
116
|
-
off the handler),
|
|
116
|
+
off the handler), 113 elements, 79 binding sources. `sb_api_find`
|
|
117
117
|
is an index rather than a tool per endpoint, so the tool list stays short while everything
|
|
118
118
|
the platform can do stays reachable — and operations added to the platform arrive with the
|
|
119
119
|
next `npm run codegen`.
|
package/README.vi.md
CHANGED
|
@@ -91,7 +91,7 @@ nhét ngược lại vào mọi bản cài.
|
|
|
91
91
|
| `sb_move` | Chuyển node sang cha khác |
|
|
92
92
|
| `sb_remove` | Xoá node và cả cây con |
|
|
93
93
|
| `sb_duplicate` | Nhân bản một node và cả cây con dưới id mới, ngay sau bản gốc |
|
|
94
|
-
| `sb_templates` | Section template đã lưu của cửa hàng, cộng bộ layout DỰNG SẴN — hero, ba lợi ích, số liệu, FAQ, dải kêu gọi — soạn theo token của chính trang |
|
|
94
|
+
| `sb_templates` | Section template đã lưu của cửa hàng, cộng bộ layout DỰNG SẴN — hero, ba lợi ích, số liệu, FAQ, dải kêu gọi, kệ sản phẩm, dải danh mục, dải logo, dải cam kết — soạn theo token của chính trang |
|
|
95
95
|
| `sb_template_use` | Thả một template vào trang |
|
|
96
96
|
| `sb_page_list` | Mọi trang của site |
|
|
97
97
|
| `sb_page_create` | Tạo một trang — trang cửa hàng sinh ra đã có sẵn tài liệu như trong editor; `type` là đường đi cho checkout, product, category, post, course |
|
|
@@ -110,7 +110,7 @@ nhét ngược lại vào mọi bản cài.
|
|
|
110
110
|
| `sb_undo` | Trả lại thứ mà một lệnh PUT đã ghi đè. Với TRANG thì đây là đường về thứ hai chứ không phải duy nhất: nền tảng có version, history và restore (`sb_api_find` "page versions"), và chúng sống lâu hơn tiến trình này — hãy dùng chúng trước, còn tool này cho mọi PUT có hình dạng khác |
|
|
111
111
|
|
|
112
112
|
Hai mươi tám tool, **524 operation API** (175 trong 234 lệnh ghi có hình dạng body đọc thẳng
|
|
113
|
-
từ handler),
|
|
113
|
+
từ handler), 113 element, 79 nguồn binding. `sb_api_find` là
|
|
114
114
|
một chỉ mục chứ không phải mỗi endpoint một tool, nên danh sách tool vẫn ngắn trong khi mọi
|
|
115
115
|
thứ nền tảng làm được vẫn với tới — và operation mới thêm bên nền tảng sẽ tự có sau lần
|
|
116
116
|
`npm run codegen` kế tiếp.
|
|
@@ -8717,7 +8717,7 @@ export const API_OPERATIONS = [
|
|
|
8717
8717
|
"in": "query",
|
|
8718
8718
|
"required": false,
|
|
8719
8719
|
"type": "string",
|
|
8720
|
-
"description": "image | video | font | other"
|
|
8720
|
+
"description": "image | video | font | model | other"
|
|
8721
8721
|
},
|
|
8722
8722
|
{
|
|
8723
8723
|
"name": "search",
|
|
@@ -17503,6 +17503,10 @@ export const API_DEFINITIONS = {
|
|
|
17503
17503
|
}
|
|
17504
17504
|
]
|
|
17505
17505
|
},
|
|
17506
|
+
"modelUrl": {
|
|
17507
|
+
"description": "ModelURL is the product's 3D model (.glb / .gltf), so a page can show the\nthing itself instead of photographs of it.\n\nONE model, not a gallery — which is why this is a scalar beside the two\nslices above rather than a third one. A product has one shape; a second\nmodel of the same product would be a different colourway or a different\nproduct, and both of those already have somewhere to live. Making it a\nlist \"for later\" would cost a migration to take back and would force\nevery reader to answer \"which one\" with no rule to answer it by.\n\nEmpty is the normal value and means \"no model\": every product that\nexisted before this field, and every product in every store that sells\nthings nobody has modelled.\n\nIt is a URL into this site's own media library in the ordinary case, but\nnothing here requires that — an externally hosted .glb is a legitimate\nvalue, and the usage adapter simply finds no match for one, which is the\ntrue answer.",
|
|
17508
|
+
"type": "string"
|
|
17509
|
+
},
|
|
17506
17510
|
"moneyOverride": {
|
|
17507
17511
|
"description": "MoneyOverride is an opaque per-product money-display override (compact-convert\nrules + exchange-rate overrides), stored as a JSONB blob. The domain keeps it\nopaque — it is decoded at the render boundary (bindings.ProductSource →\nrender.ProductData) — so products stays decoupled from render/money, the same\nway the site settings document is an opaque blob. Empty ({}/null) → no override.",
|
|
17508
17512
|
"type": "array",
|
|
@@ -556,7 +556,21 @@ export const CHECKOUT_PAGE_DOCUMENT = {
|
|
|
556
556
|
"paddingTop": "48px",
|
|
557
557
|
"paddingBottom": "48px"
|
|
558
558
|
},
|
|
559
|
-
"config": {
|
|
559
|
+
"config": {
|
|
560
|
+
"backgroundSceneSource": "",
|
|
561
|
+
"backgroundSceneEffect": "gradient-mesh",
|
|
562
|
+
"backgroundSceneGallery": "podium",
|
|
563
|
+
"backgroundSceneSpeed": "normal",
|
|
564
|
+
"backgroundSceneIntensity": "normal",
|
|
565
|
+
"backgroundSceneColors": "theme",
|
|
566
|
+
"backgroundSceneColor1": "#171717",
|
|
567
|
+
"backgroundSceneColor2": "#ffffff",
|
|
568
|
+
"backgroundSceneColor3": "#6b7280",
|
|
569
|
+
"backgroundSceneUrl": "",
|
|
570
|
+
"backgroundSceneModelUrl": "",
|
|
571
|
+
"backgroundSceneVeil": 0,
|
|
572
|
+
"backgroundSceneVeilColor": "#000000"
|
|
573
|
+
},
|
|
560
574
|
"specials": {
|
|
561
575
|
"stylePreset": "container-section"
|
|
562
576
|
},
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const DEAD_KEY_SOURCE = {
|
|
2
|
+
"files": 3966,
|
|
3
|
+
"identifiers": 76235,
|
|
4
|
+
"seededKeys": 384,
|
|
5
|
+
"dead": 1
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Keys an element SEEDS and no renderer anywhere reads.
|
|
9
|
+
*
|
|
10
|
+
* Keyed by the key NAME, not by `namespace.key`: the index is a flat set of
|
|
11
|
+
* identifiers, so it cannot tell one namespace from the other and a key read
|
|
12
|
+
* anywhere is read in both.
|
|
13
|
+
*
|
|
14
|
+
* A write to one of these stores, saves, publishes and renders exactly as
|
|
15
|
+
* before. `sb_set` says so at the moment of the write; nothing refuses it,
|
|
16
|
+
* because the platform accepts the value and a refusal here would invent a rule
|
|
17
|
+
* it does not have.
|
|
18
|
+
*/
|
|
19
|
+
export const DEAD_KEYS = {
|
|
20
|
+
"splitDirection": {
|
|
21
|
+
"key": "splitDirection",
|
|
22
|
+
"namespaces": [
|
|
23
|
+
"config"
|
|
24
|
+
],
|
|
25
|
+
"seededBy": [
|
|
26
|
+
"image-comparison"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ELEMENTS, TRAIT_WRITES } from './elements.generated.js';
|
|
2
|
-
import { animationValues, animationVocabulary, vocabulariesForWrites } from '../domains/site/vocabulary.js';
|
|
2
|
+
import { animationValues, animationVocabulary, elementVocabularies, sharedVocabularies, vocabulariesForWrites, } from '../domains/site/vocabulary.js';
|
|
3
3
|
import { neverTranslatedOn, translatableSpecials } from '../domains/site/translate.js';
|
|
4
4
|
/** Eight to choose from; the hints for the chosen one come with sb_traits_for. */
|
|
5
5
|
export const DEFAULT_CATALOG_LIMIT = 8;
|
|
@@ -120,10 +120,28 @@ export function traitsFor(type, control) {
|
|
|
120
120
|
// this element's defaults and in its control list, and no TRAIT_WRITES entry
|
|
121
121
|
// names it — so a per-control attachment reaches none of them, which is how
|
|
122
122
|
// the first version of this was wrong.
|
|
123
|
+
//
|
|
124
|
+
// TWO FIELDS RATHER THAN ONE, because the caller writes two namespaces and
|
|
125
|
+
// `sb_set` takes them separately. Every entry names its `writeKey`, which is
|
|
126
|
+
// the half a control name does not give you: `divider_orientation` writes
|
|
127
|
+
// `orientation`, and eleven of the thirteen joined controls are like it.
|
|
123
128
|
...(() => {
|
|
124
129
|
const keys = new Set([...Object.keys(el.defaults?.config ?? {}), ...el.controls]);
|
|
125
|
-
|
|
126
|
-
|
|
130
|
+
// The globally-unique three keep their own key AS the write key; saying so
|
|
131
|
+
// is what lets a reader take every entry in this object the same way.
|
|
132
|
+
const config = Object.fromEntries(Object.entries(vocabulariesForWrites([...keys])).map(([k, v]) => [k, { writeKey: k, ...v }]));
|
|
133
|
+
const specials = {};
|
|
134
|
+
const own = { ...sharedVocabularies(el.defaults ?? {}), ...elementVocabularies(el.type) };
|
|
135
|
+
for (const [k, { target, ...v }] of Object.entries(own)) {
|
|
136
|
+
// `target` is dropped rather than repeated: the field it lands in is the
|
|
137
|
+
// namespace, and a key restated on every entry is the dilution the token
|
|
138
|
+
// budget has already caught twice on this one result.
|
|
139
|
+
(target === 'specials' ? specials : config)[k] = v;
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
...(Object.keys(config).length ? { config_values: config } : {}),
|
|
143
|
+
...(Object.keys(specials).length ? { specials_values: specials } : {}),
|
|
144
|
+
};
|
|
127
145
|
})(),
|
|
128
146
|
// THE ENTRANCE ANIMATION, for the 73 element types that offer it. It does
|
|
129
147
|
// not ride in `config_values` because it is not a word — it is an OBJECT
|