@tokenoftrust/cli 1.3.3-rc.0 → 1.3.3-rc.1
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 +1 -1
- package/src/validate.mjs +25 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/cli",
|
|
3
|
-
"version": "1.3.3-rc.
|
|
3
|
+
"version": "1.3.3-rc.1",
|
|
4
4
|
"description": "Token of Trust developer CLI — check out a tenant store, run it locally with save→reload, and submit it for preview. Installs the `tot` command.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Token of Trust",
|
package/src/validate.mjs
CHANGED
|
@@ -96,6 +96,28 @@ function validateRawHtmlBody(html) {
|
|
|
96
96
|
if (!html.includes("<")) return "no markup tags found";
|
|
97
97
|
return null;
|
|
98
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Does the tenant provide chrome to wrap body-only fragments? True when it ships
|
|
101
|
+
* EITHER a hand-authored `content/chrome.html`, OR a `content/chrome.json` that
|
|
102
|
+
* opts into the canonical shared chrome. Mirrors the serve-time resolution in
|
|
103
|
+
* apps/storefront getChromeHtml() → parseChromeConfig(): an opted-in config is
|
|
104
|
+
* rendered into the wrapper (renderRawChrome), so a fragment is NOT served naked.
|
|
105
|
+
* Kept in step with lib/chrome/parseConfig.ts's opt-in gate.
|
|
106
|
+
*/
|
|
107
|
+
function providesChrome(contentDir) {
|
|
108
|
+
if (existsSync(join(contentDir, "chrome.html"))) return true;
|
|
109
|
+
const configPath = join(contentDir, "chrome.json");
|
|
110
|
+
if (!existsSync(configPath)) return false;
|
|
111
|
+
const { value } = readJsonSafe(configPath);
|
|
112
|
+
if (value == null || typeof value !== "object") return false;
|
|
113
|
+
if (value.sharedChrome !== true) return false;
|
|
114
|
+
const brand = value.brand;
|
|
115
|
+
if (brand == null || typeof brand !== "object" || typeof brand.label !== "string") return false;
|
|
116
|
+
if (!Array.isArray(value.nav)) return false;
|
|
117
|
+
const footer = value.footer;
|
|
118
|
+
if (footer == null || typeof footer !== "object" || !Array.isArray(footer.columns)) return false;
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
99
121
|
|
|
100
122
|
// --- filesystem helpers ------------------------------------------------------
|
|
101
123
|
function readJsonSafe(path) {
|
|
@@ -186,8 +208,7 @@ export function validateTenant(tenantDir, opts = {}) {
|
|
|
186
208
|
}
|
|
187
209
|
|
|
188
210
|
// 4. raw HTML documents — validate + portability + resolution
|
|
189
|
-
const
|
|
190
|
-
const hasChrome = existsSync(chromePath);
|
|
211
|
+
const hasChrome = providesChrome(contentDir);
|
|
191
212
|
const htmlFiles = walk(contentDir, (p) => p.endsWith(".html"));
|
|
192
213
|
const pageTargets = buildPageTargetSet(contentDir, pagesDir);
|
|
193
214
|
|
|
@@ -204,8 +225,8 @@ export function validateTenant(tenantDir, opts = {}) {
|
|
|
204
225
|
if (!base && !isFullDocument(html) && !hasChrome) {
|
|
205
226
|
findings.push(
|
|
206
227
|
mk(ERROR, "html-fragment", r,
|
|
207
|
-
"is an HTML fragment but the tenant ships no
|
|
208
|
-
"make it a full <!doctype html> document, or add content/chrome.html with <!--PAGE_BODY-->"),
|
|
228
|
+
"is an HTML fragment but the tenant ships no chrome to wrap it — it will serve unwrapped/naked",
|
|
229
|
+
"make it a full <!doctype html> document, add a content/chrome.json with \"sharedChrome\": true (brand + nav + footer), or add content/chrome.html with <!--PAGE_BODY-->"),
|
|
209
230
|
);
|
|
210
231
|
}
|
|
211
232
|
if (STYLE_OPEN_WITH_ATTRS_RE.test(html)) {
|