@wix/himalaya-cli 0.1418.0 → 0.1420.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/dist/cli.mjs +189 -8
- package/guides/himi-json-output.md +1 -0
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -10096,7 +10096,10 @@ var validate_descriptor_core_exports = {};
|
|
|
10096
10096
|
__export(validate_descriptor_core_exports, {
|
|
10097
10097
|
CORE_PACKAGES: () => CORE_PACKAGES,
|
|
10098
10098
|
CRAWL_BLOCKING_PASSES: () => CRAWL_BLOCKING_PASSES,
|
|
10099
|
+
DESCRIPTOR_DEPTH_BUDGETS: () => DESCRIPTOR_DEPTH_BUDGETS,
|
|
10100
|
+
DEVICE_NETWORK_WITHHELD: () => DEVICE_NETWORK_WITHHELD,
|
|
10099
10101
|
DEVICE_PARITY_WITHHELD: () => DEVICE_PARITY_WITHHELD,
|
|
10102
|
+
DEVICE_WITHHELD: () => DEVICE_WITHHELD,
|
|
10100
10103
|
EMBEDDED_BINDING: () => EMBEDDED_BINDING,
|
|
10101
10104
|
INTEGER_MODIFIERS: () => INTEGER_MODIFIERS,
|
|
10102
10105
|
INTEGER_PROPS: () => INTEGER_PROPS,
|
|
@@ -10118,6 +10121,8 @@ __export(validate_descriptor_core_exports, {
|
|
|
10118
10121
|
bootBundleWorker: () => bootBundleWorker,
|
|
10119
10122
|
collectServiceBindings: () => collectServiceBindings,
|
|
10120
10123
|
componentPropFindings: () => componentPropFindings,
|
|
10124
|
+
depthBudgetFindings: () => depthBudgetFindings,
|
|
10125
|
+
depthBudgetIssues: () => depthBudgetIssues,
|
|
10121
10126
|
dryRunBundle: () => dryRunBundle,
|
|
10122
10127
|
enumFieldNames: () => enumFieldNames,
|
|
10123
10128
|
extractBundleContract: () => extractBundleContract,
|
|
@@ -10473,9 +10478,12 @@ async function bootBundleWorker(bundleJs, opts) {
|
|
|
10473
10478
|
}, info() {
|
|
10474
10479
|
}, debug() {
|
|
10475
10480
|
} },
|
|
10476
|
-
// A raw fetch is still a signal, not a silent hang (mirrors runBundleSandbox).
|
|
10477
|
-
|
|
10478
|
-
|
|
10481
|
+
// A raw fetch is still a signal, not a silent hang (mirrors runBundleSandbox). Under
|
|
10482
|
+
// deviceParity it is ABSENT instead, as on every device (#4499 — DEVICE_NETWORK_WITHHELD).
|
|
10483
|
+
...opts.deviceParity ? {} : {
|
|
10484
|
+
fetch: () => {
|
|
10485
|
+
throw new Error("`fetch` is not available \u2014 workers load data via the sanctioned Wix transport (`@himalaya/wix-*` or `globalThis.himalaya.wixApi.call`), not raw `fetch`.");
|
|
10486
|
+
}
|
|
10479
10487
|
},
|
|
10480
10488
|
// Under deviceParity these are ABSENT so a bundle touching one throws here exactly as it
|
|
10481
10489
|
// would on the FLOOR. Measured, not assumed (engine-parity runners, #1367): JSC and the
|
|
@@ -10522,7 +10530,7 @@ async function bootBundleWorker(bundleJs, opts) {
|
|
|
10522
10530
|
let guestActions;
|
|
10523
10531
|
let guestSession;
|
|
10524
10532
|
try {
|
|
10525
|
-
const hide = opts.deviceParity ?
|
|
10533
|
+
const hide = opts.deviceParity ? DEVICE_WITHHELD : void 0;
|
|
10526
10534
|
if (realm.runWithActions) {
|
|
10527
10535
|
const ran = await realm.runWithActions(bundleJs, sandbox, {
|
|
10528
10536
|
timeoutMs: 2e3 + budgetMs,
|
|
@@ -11612,6 +11620,100 @@ function bottomSheetFindings(descriptor) {
|
|
|
11612
11620
|
visit(descriptor, "", true);
|
|
11613
11621
|
return out2;
|
|
11614
11622
|
}
|
|
11623
|
+
function depthBudgetIssues(findings) {
|
|
11624
|
+
return findings.map((f2) => ({
|
|
11625
|
+
severity: "error",
|
|
11626
|
+
pass: "depth-budget",
|
|
11627
|
+
path: f2.path,
|
|
11628
|
+
message: f2.message,
|
|
11629
|
+
limit: f2.limit,
|
|
11630
|
+
actual: f2.actual
|
|
11631
|
+
}));
|
|
11632
|
+
}
|
|
11633
|
+
function depthBudgetFindings(descriptor) {
|
|
11634
|
+
const out2 = [];
|
|
11635
|
+
const templates = [];
|
|
11636
|
+
const isComponent = (v2) => {
|
|
11637
|
+
const body = v2?.body;
|
|
11638
|
+
return !!body && typeof body === "object" && typeof body.type === "string" && typeof body.package === "string";
|
|
11639
|
+
};
|
|
11640
|
+
const hostedTemplates = (v2, path2) => {
|
|
11641
|
+
const props = v2.body.props;
|
|
11642
|
+
const found = [];
|
|
11643
|
+
if (!props) return found;
|
|
11644
|
+
const itemsPath = props.itemsPath ?? props.items_path;
|
|
11645
|
+
const rowHost = v2.body.package === "himalaya" ? ROW_TEMPLATE_HOST_TYPES.has(v2.body.type) : true;
|
|
11646
|
+
if (rowHost && typeof itemsPath === "string" && itemsPath !== "" && Array.isArray(props.items) && isComponent(props.items[0])) {
|
|
11647
|
+
found.push({ node: props.items[0], path: `${path2}.body.props.items[0]`, host: `${v2.body.type} at ${path2}` });
|
|
11648
|
+
}
|
|
11649
|
+
if (isComponent(props.eventTemplate)) {
|
|
11650
|
+
found.push({ node: props.eventTemplate, path: `${path2}.body.props.eventTemplate`, host: `${v2.body.type} at ${path2}` });
|
|
11651
|
+
}
|
|
11652
|
+
return found;
|
|
11653
|
+
};
|
|
11654
|
+
const measure2 = (root, rootPath, mode) => {
|
|
11655
|
+
let depth = 0, nodes = 0, deepest = rootPath;
|
|
11656
|
+
const skip = /* @__PURE__ */ new Set();
|
|
11657
|
+
const stack = [
|
|
11658
|
+
{ v: root, path: rootPath, depth: 0, atRoot: mode === "screen" }
|
|
11659
|
+
];
|
|
11660
|
+
while (stack.length) {
|
|
11661
|
+
const { v: v2, path: path2, depth: parentDepth, atRoot } = stack.pop();
|
|
11662
|
+
if (skip.has(v2)) continue;
|
|
11663
|
+
if (Array.isArray(v2)) {
|
|
11664
|
+
for (let i2 = v2.length - 1; i2 >= 0; i2--) stack.push({ v: v2[i2], path: `${path2}[${i2}]`, depth: parentDepth, atRoot: false });
|
|
11665
|
+
continue;
|
|
11666
|
+
}
|
|
11667
|
+
if (!v2 || typeof v2 !== "object") continue;
|
|
11668
|
+
let here = parentDepth;
|
|
11669
|
+
if (isComponent(v2)) {
|
|
11670
|
+
here = parentDepth + 1;
|
|
11671
|
+
nodes += 1;
|
|
11672
|
+
if (here > depth) {
|
|
11673
|
+
depth = here;
|
|
11674
|
+
deepest = path2;
|
|
11675
|
+
}
|
|
11676
|
+
for (const t2 of hostedTemplates(v2, path2)) {
|
|
11677
|
+
if (mode === "screen") templates.push(t2);
|
|
11678
|
+
else skip.add(t2.node);
|
|
11679
|
+
}
|
|
11680
|
+
}
|
|
11681
|
+
const entries = Object.entries(v2);
|
|
11682
|
+
for (let i2 = entries.length - 1; i2 >= 0; i2--) {
|
|
11683
|
+
const [key2, child] = entries[i2];
|
|
11684
|
+
if (!child || typeof child !== "object" || isOpaqueAuthorJson(key2, child, atRoot)) continue;
|
|
11685
|
+
stack.push({ v: child, path: `${path2}.${key2}`, depth: here, atRoot: false });
|
|
11686
|
+
}
|
|
11687
|
+
}
|
|
11688
|
+
return { depth, nodes, deepest };
|
|
11689
|
+
};
|
|
11690
|
+
const flatten = "flatten the layout \u2014 drop wrapper stacks, or move a section into its own screen";
|
|
11691
|
+
const report3 = (what, m2, budget, rootPath) => {
|
|
11692
|
+
if (m2.depth > budget.maxDepth) {
|
|
11693
|
+
out2.push({
|
|
11694
|
+
measure: "depth",
|
|
11695
|
+
path: m2.deepest,
|
|
11696
|
+
limit: budget.maxDepth,
|
|
11697
|
+
actual: m2.depth,
|
|
11698
|
+
message: `${what} nests ${m2.depth} component levels; the limit is ${budget.maxDepth} (deepest node at ${m2.deepest}) \u2014 ${flatten}`
|
|
11699
|
+
});
|
|
11700
|
+
}
|
|
11701
|
+
if (m2.nodes > budget.maxNodes) {
|
|
11702
|
+
out2.push({
|
|
11703
|
+
measure: "nodes",
|
|
11704
|
+
path: rootPath,
|
|
11705
|
+
limit: budget.maxNodes,
|
|
11706
|
+
actual: m2.nodes,
|
|
11707
|
+
message: `${what} has ${m2.nodes} components; the limit is ${budget.maxNodes} \u2014 ${flatten}`
|
|
11708
|
+
});
|
|
11709
|
+
}
|
|
11710
|
+
};
|
|
11711
|
+
report3("screen", measure2(descriptor, "$", "screen"), DESCRIPTOR_DEPTH_BUDGETS.screen, "$");
|
|
11712
|
+
for (const t2 of templates) {
|
|
11713
|
+
report3(`row template of the ${t2.host}`, measure2(t2.node, t2.path, "template"), DESCRIPTOR_DEPTH_BUDGETS.rowTemplate, t2.path);
|
|
11714
|
+
}
|
|
11715
|
+
return out2;
|
|
11716
|
+
}
|
|
11615
11717
|
function topBarFindings(descriptor) {
|
|
11616
11718
|
const out2 = [];
|
|
11617
11719
|
const bar = descriptor?.topBar;
|
|
@@ -11763,6 +11865,11 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
11763
11865
|
const issues = [];
|
|
11764
11866
|
const strict = opts.strict ?? false;
|
|
11765
11867
|
const hygiene = strict ? "error" : "warning";
|
|
11868
|
+
const depthFindings = depthBudgetFindings(descriptor);
|
|
11869
|
+
const depthIssues = depthBudgetIssues(depthFindings);
|
|
11870
|
+
if (depthFindings.some((f2) => f2.measure === "depth" && f2.actual > UNSAFE_TO_RECURSE_DEPTH)) {
|
|
11871
|
+
return { screenId, ok: false, strict, issues: depthIssues, services: [] };
|
|
11872
|
+
}
|
|
11766
11873
|
const fixture = new FixtureValidator({ tokens: opts.tokens, allowedComponents: opts.allowedComponents });
|
|
11767
11874
|
const v2 = fixture.validate(descriptor);
|
|
11768
11875
|
const lbIntegrity = descriptor?.logicBundle?.integrity;
|
|
@@ -11866,6 +11973,7 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
11866
11973
|
for (const finding of topBarFindings(descriptor)) {
|
|
11867
11974
|
issues.push({ severity: "warning", pass: "top-bar", path: finding.path, message: finding.message });
|
|
11868
11975
|
}
|
|
11976
|
+
issues.push(...depthIssues);
|
|
11869
11977
|
const bindings = collectServiceBindings(descriptor);
|
|
11870
11978
|
const descriptorActions = collectDescriptorActions(descriptor);
|
|
11871
11979
|
const workerActions = descriptorActions.filter(({ actionId }) => actionId.startsWith("tier5."));
|
|
@@ -12365,7 +12473,7 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
12365
12473
|
services: Object.keys(services)
|
|
12366
12474
|
};
|
|
12367
12475
|
}
|
|
12368
|
-
var CRAWL_BLOCKING_PASSES, BOOT_EVAL_TIMEOUT_MS, DRIFT_PROBES, DEVICE_PARITY_WITHHELD, defaultEvaluator, bootEvaluator, actionEvaluator, NATIVE_PROP_ENUMS, KNOWN_PROPS, IN_ARRAY_BINDING_PROPS, SERVICE_SIGIL, INTEGER_PROPS, NATIVE_REQUIRED_PROPS, bareNestedClass, NATIVE_NESTED_CLASSES, NATIVE_MODIFIERS_CLASS, NATIVE_DESCRIPTOR_CLASS, NATIVE_DESCRIPTOR_NESTED, NATIVE_NESTED_PROPS, LENIENT_TOP_BAR_BLOCKS, MODIFIER_KEYS, INTEGER_MODIFIERS, MODIFIER_KINDS, SCHEMA_SCORED_NODES, CORE_PACKAGES, LEGACY_UNSCORED_KEYS, DYNAMIC_PLACEHOLDER, LITERAL_ONLY_PROPS, SERVICE_ONLY_BINDING_PROPS, WHOLE_VALUE_BINDING, EMBEDDED_BINDING, OPTIONS_BINDING_PROPS, EDITOR_SERVICE_NAME, SHEET_PLACEMENTS, TOP_BAR_TRAILING_LIMIT, TOP_BAR_NON_TRAILING, BUTTON_STYLES, EMPTY_STATE_ACTION_STYLES, EMPTY_STATE_ACTION_SIZES;
|
|
12476
|
+
var CRAWL_BLOCKING_PASSES, BOOT_EVAL_TIMEOUT_MS, DRIFT_PROBES, DEVICE_PARITY_WITHHELD, DEVICE_NETWORK_WITHHELD, DEVICE_WITHHELD, defaultEvaluator, bootEvaluator, actionEvaluator, NATIVE_PROP_ENUMS, KNOWN_PROPS, IN_ARRAY_BINDING_PROPS, SERVICE_SIGIL, INTEGER_PROPS, NATIVE_REQUIRED_PROPS, bareNestedClass, NATIVE_NESTED_CLASSES, NATIVE_MODIFIERS_CLASS, NATIVE_DESCRIPTOR_CLASS, NATIVE_DESCRIPTOR_NESTED, NATIVE_NESTED_PROPS, LENIENT_TOP_BAR_BLOCKS, MODIFIER_KEYS, INTEGER_MODIFIERS, MODIFIER_KINDS, SCHEMA_SCORED_NODES, CORE_PACKAGES, LEGACY_UNSCORED_KEYS, DYNAMIC_PLACEHOLDER, LITERAL_ONLY_PROPS, SERVICE_ONLY_BINDING_PROPS, WHOLE_VALUE_BINDING, EMBEDDED_BINDING, OPTIONS_BINDING_PROPS, EDITOR_SERVICE_NAME, SHEET_PLACEMENTS, DESCRIPTOR_DEPTH_BUDGETS, UNSAFE_TO_RECURSE_DEPTH, ROW_TEMPLATE_HOST_TYPES, TOP_BAR_TRAILING_LIMIT, TOP_BAR_NON_TRAILING, BUTTON_STYLES, EMPTY_STATE_ACTION_STYLES, EMPTY_STATE_ACTION_SIZES;
|
|
12369
12477
|
var init_validate_descriptor_core = __esm({
|
|
12370
12478
|
"../../core/dev-server/src/validate-descriptor.core.ts"() {
|
|
12371
12479
|
init_validator();
|
|
@@ -12379,6 +12487,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
12379
12487
|
init_media_value();
|
|
12380
12488
|
init_frame_limits();
|
|
12381
12489
|
init_rich_content();
|
|
12490
|
+
init_worker_subtree();
|
|
12382
12491
|
CRAWL_BLOCKING_PASSES = /* @__PURE__ */ new Set([
|
|
12383
12492
|
// A screen whose bindings do not resolve has no state to crawl.
|
|
12384
12493
|
"bindings",
|
|
@@ -12386,7 +12495,11 @@ var init_validate_descriptor_core = __esm({
|
|
|
12386
12495
|
"worker-subtree",
|
|
12387
12496
|
// A value outside a strict native enum decodes to nothing on device, so the crawl would be
|
|
12388
12497
|
// exercising a screen the device cannot render.
|
|
12389
|
-
"strict-enum"
|
|
12498
|
+
"strict-enum",
|
|
12499
|
+
// #4498 — a screen or row template over the nesting/node budget overflows a native stack on
|
|
12500
|
+
// decode/render, so there is no screen to crawl. (The publish refusal is separate: the pass is
|
|
12501
|
+
// always an error, and `himi push` refuses a depth-budget error even under `--force`.)
|
|
12502
|
+
"depth-budget"
|
|
12390
12503
|
]);
|
|
12391
12504
|
BOOT_EVAL_TIMEOUT_MS = 2e3;
|
|
12392
12505
|
DRIFT_PROBES = [
|
|
@@ -12406,6 +12519,25 @@ var init_validate_descriptor_core = __esm({
|
|
|
12406
12519
|
"TextDecoder",
|
|
12407
12520
|
"AbortController"
|
|
12408
12521
|
];
|
|
12522
|
+
DEVICE_NETWORK_WITHHELD = [
|
|
12523
|
+
"fetch",
|
|
12524
|
+
"XMLHttpRequest",
|
|
12525
|
+
"WebSocket",
|
|
12526
|
+
"EventSource",
|
|
12527
|
+
"importScripts",
|
|
12528
|
+
"WebTransport",
|
|
12529
|
+
"RTCPeerConnection",
|
|
12530
|
+
"webkitRTCPeerConnection",
|
|
12531
|
+
"Worker",
|
|
12532
|
+
"SharedWorker",
|
|
12533
|
+
"Image",
|
|
12534
|
+
"Audio",
|
|
12535
|
+
"open",
|
|
12536
|
+
"Request",
|
|
12537
|
+
"Response",
|
|
12538
|
+
"Headers"
|
|
12539
|
+
];
|
|
12540
|
+
DEVICE_WITHHELD = [...DEVICE_NETWORK_WITHHELD, ...DEVICE_PARITY_WITHHELD];
|
|
12409
12541
|
defaultEvaluator = null;
|
|
12410
12542
|
bootEvaluator = null;
|
|
12411
12543
|
actionEvaluator = null;
|
|
@@ -13358,6 +13490,12 @@ var init_validate_descriptor_core = __esm({
|
|
|
13358
13490
|
OPTIONS_BINDING_PROPS = /* @__PURE__ */ new Set(["optionsPath"]);
|
|
13359
13491
|
EDITOR_SERVICE_NAME = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
13360
13492
|
SHEET_PLACEMENTS = /* @__PURE__ */ new Set(["overlay", "inline"]);
|
|
13493
|
+
DESCRIPTOR_DEPTH_BUDGETS = Object.freeze({
|
|
13494
|
+
screen: Object.freeze({ maxDepth: 40, maxNodes: 2e3 }),
|
|
13495
|
+
rowTemplate: Object.freeze({ maxDepth: WORKER_SUBTREE_CEILINGS.maxDepth, maxNodes: WORKER_SUBTREE_CEILINGS.maxNodes })
|
|
13496
|
+
});
|
|
13497
|
+
UNSAFE_TO_RECURSE_DEPTH = 128;
|
|
13498
|
+
ROW_TEMPLATE_HOST_TYPES = /* @__PURE__ */ new Set(["LazyList", "Grid", "Carousel", "Menu"]);
|
|
13361
13499
|
TOP_BAR_TRAILING_LIMIT = 2;
|
|
13362
13500
|
TOP_BAR_NON_TRAILING = /* @__PURE__ */ new Set(["leading", "principal", "bottom", "keyboard", "overflow"]);
|
|
13363
13501
|
BUTTON_STYLES = /* @__PURE__ */ new Set(["filled", "tonal", "outlined", "text", "elevated", "bordered", "prominent", "plain", "glass", "primary", "secondary", "tertiary", "link", "destructive"]);
|
|
@@ -13882,7 +14020,10 @@ var validate_descriptor_exports = {};
|
|
|
13882
14020
|
__export(validate_descriptor_exports, {
|
|
13883
14021
|
CORE_PACKAGES: () => CORE_PACKAGES,
|
|
13884
14022
|
CRAWL_BLOCKING_PASSES: () => CRAWL_BLOCKING_PASSES,
|
|
14023
|
+
DESCRIPTOR_DEPTH_BUDGETS: () => DESCRIPTOR_DEPTH_BUDGETS,
|
|
14024
|
+
DEVICE_NETWORK_WITHHELD: () => DEVICE_NETWORK_WITHHELD,
|
|
13885
14025
|
DEVICE_PARITY_WITHHELD: () => DEVICE_PARITY_WITHHELD,
|
|
14026
|
+
DEVICE_WITHHELD: () => DEVICE_WITHHELD,
|
|
13886
14027
|
EMBEDDED_BINDING: () => EMBEDDED_BINDING,
|
|
13887
14028
|
INTEGER_MODIFIERS: () => INTEGER_MODIFIERS,
|
|
13888
14029
|
INTEGER_PROPS: () => INTEGER_PROPS,
|
|
@@ -13906,6 +14047,8 @@ __export(validate_descriptor_exports, {
|
|
|
13906
14047
|
bundleNameFromUrl: () => bundleNameFromUrl,
|
|
13907
14048
|
collectServiceBindings: () => collectServiceBindings,
|
|
13908
14049
|
componentPropFindings: () => componentPropFindings,
|
|
14050
|
+
depthBudgetFindings: () => depthBudgetFindings,
|
|
14051
|
+
depthBudgetIssues: () => depthBudgetIssues,
|
|
13909
14052
|
discoverNativeActions: () => discoverNativeActions,
|
|
13910
14053
|
dryRunBundle: () => dryRunBundle,
|
|
13911
14054
|
enumFieldNames: () => enumFieldNames,
|
|
@@ -16083,6 +16226,9 @@ ${opts.liveTransport ? ` var handle = { getState: function () { return def
|
|
|
16083
16226
|
globalThis.fetch = function () {
|
|
16084
16227
|
throw new Error("\`fetch\` is not available in the author-time sandbox \u2014 workers load data via the sanctioned Wix transport (\`@himalaya/wix-*\` or \`globalThis.himalaya.wixApi.call\`), not raw \`fetch\`.");
|
|
16085
16228
|
};
|
|
16229
|
+
// ...unless \`hide\` withholds it (deviceParity, #4499): every device has NO \`fetch\`, so a
|
|
16230
|
+
// stub here would let a \`typeof fetch === "function"\` branch pass and fail on the device.
|
|
16231
|
+
${(opts.hide ?? []).includes("fetch") ? " delete globalThis.fetch;" : ""}
|
|
16086
16232
|
// Timers honour \`hide\`. Installing them unconditionally made \`deviceParity\` report
|
|
16087
16233
|
// \`typeof setTimeout === "function"\` where node:vm correctly reported "undefined" \u2014 a FALSE
|
|
16088
16234
|
// GREEN on exactly the floor gate this realm exists to enforce. The URL family is never
|
|
@@ -141168,7 +141314,8 @@ var init_push_errors = __esm({
|
|
|
141168
141314
|
"not_carried_by_patch",
|
|
141169
141315
|
"authoring_unavailable",
|
|
141170
141316
|
"push_failed",
|
|
141171
|
-
"binary_capability_gap"
|
|
141317
|
+
"binary_capability_gap",
|
|
141318
|
+
"depth_budget_exceeded"
|
|
141172
141319
|
];
|
|
141173
141320
|
UX_CODES = {
|
|
141174
141321
|
absent: "ux_evidence_absent",
|
|
@@ -180506,6 +180653,10 @@ function describeNondeterministicWorkers(workers) {
|
|
|
180506
180653
|
return workers.length <= 1 ? workers.map(one).join("") : `${workers.slice(0, -1).map(one).join(", ")} and ${one(workers[workers.length - 1])}`;
|
|
180507
180654
|
}
|
|
180508
180655
|
var NONDETERMINISTIC_FIX = "move those clock or random values out of the service's initial state and compute them in an action instead (for example one the screen's onAppear dispatches)";
|
|
180656
|
+
function depthBudgetExceeded(report3) {
|
|
180657
|
+
return (report3.issues ?? []).some((i2) => i2.severity === "error" && i2.pass === "depth-budget");
|
|
180658
|
+
}
|
|
180659
|
+
var DEPTH_BUDGET_HINT = "a screen or row template is over the depth budget (see the depth-budget issues' path and limit) \u2014 flatten it; `--force` does not override this";
|
|
180509
180660
|
function summarizeLint(app, bres, outcome, strict, extraIssues = []) {
|
|
180510
180661
|
const issues = (outcome.lint ?? []).flatMap((s2) => s2.issues.map((i2) => ({ screen: s2.screenId, ...i2 })));
|
|
180511
180662
|
issues.push(...extraIssues);
|
|
@@ -184630,6 +184781,10 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
184630
184781
|
...await navIssues2(buildDir, strict),
|
|
184631
184782
|
...scaffoldSourceFindings
|
|
184632
184783
|
]);
|
|
184784
|
+
if (depthBudgetExceeded(report3)) {
|
|
184785
|
+
print({ ...report3, published: false, code: "depth_budget_exceeded", hint: DEPTH_BUDGET_HINT });
|
|
184786
|
+
return 1;
|
|
184787
|
+
}
|
|
184633
184788
|
if (hasErrors && !force) {
|
|
184634
184789
|
print({ ...report3, published: false, hint: "lint found errors \u2014 fix them, or re-run with --force to publish anyway" });
|
|
184635
184790
|
return 1;
|
|
@@ -186445,6 +186600,10 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
186445
186600
|
...storesV1Issues(dir, strict),
|
|
186446
186601
|
...await navIssues2(dir, strict)
|
|
186447
186602
|
]);
|
|
186603
|
+
if (depthBudgetExceeded(report3)) {
|
|
186604
|
+
print(pushFailure2("depth_budget_exceeded", { ...report3, pushed: false, hint: DEPTH_BUDGET_HINT }));
|
|
186605
|
+
return 1;
|
|
186606
|
+
}
|
|
186448
186607
|
if (hasErrors && !force) {
|
|
186449
186608
|
print(pushFailure2("lint_errors", { ...report3, pushed: false, hint: "lint found errors \u2014 fix them, or re-run `himi push --force` to publish anyway" }));
|
|
186450
186609
|
return 1;
|
|
@@ -187012,6 +187171,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
187012
187171
|
...storesV1Issues(dir, strict),
|
|
187013
187172
|
...await navIssues2(dir, strict)
|
|
187014
187173
|
]);
|
|
187174
|
+
if (depthBudgetExceeded(report3)) {
|
|
187175
|
+
rmSync24(built, { recursive: true, force: true });
|
|
187176
|
+
print({ ...report3, packed: false, code: "depth_budget_exceeded", hint: DEPTH_BUDGET_HINT });
|
|
187177
|
+
return 1;
|
|
187178
|
+
}
|
|
187015
187179
|
if (hasErrors && !force) {
|
|
187016
187180
|
rmSync24(built, { recursive: true, force: true });
|
|
187017
187181
|
print({ ...report3, packed: false, hint: "lint found errors \u2014 fix them, or re-run `himi pack --force` to pack anyway" });
|
|
@@ -188143,12 +188307,29 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
188143
188307
|
return 2;
|
|
188144
188308
|
}
|
|
188145
188309
|
const descriptor = readFileSync103(file2, "utf8");
|
|
188310
|
+
let parsed;
|
|
188146
188311
|
try {
|
|
188147
|
-
JSON.parse(descriptor);
|
|
188312
|
+
parsed = JSON.parse(descriptor);
|
|
188148
188313
|
} catch (e2) {
|
|
188149
188314
|
io2.error(JSON.stringify({ ok: false, error: "invalid_descriptor", file: file2, screen: id, message: `${file2} is not valid JSON: ${e2.message}` }));
|
|
188150
188315
|
return 1;
|
|
188151
188316
|
}
|
|
188317
|
+
const { depthBudgetFindings: depthBudgetFindings2, depthBudgetIssues: depthBudgetIssues2 } = await Promise.resolve().then(() => (init_validate_descriptor_core(), validate_descriptor_core_exports));
|
|
188318
|
+
const tooDeep = depthBudgetIssues2(depthBudgetFindings2(parsed));
|
|
188319
|
+
if (tooDeep.length > 0) {
|
|
188320
|
+
io2.error(JSON.stringify({
|
|
188321
|
+
ok: false,
|
|
188322
|
+
code: "depth_budget_exceeded",
|
|
188323
|
+
error: "depth_budget_exceeded",
|
|
188324
|
+
patched: false,
|
|
188325
|
+
app,
|
|
188326
|
+
screen: id,
|
|
188327
|
+
file: file2,
|
|
188328
|
+
issues: tooDeep,
|
|
188329
|
+
hint: "flatten the descriptor below the depth budget (see each issue's path and limit); `--force` does not override this"
|
|
188330
|
+
}, null, 2));
|
|
188331
|
+
return 1;
|
|
188332
|
+
}
|
|
188152
188333
|
const baseFound = await fetchReleaseManifest(client2, app, fromRelease);
|
|
188153
188334
|
if ("error" in baseFound) {
|
|
188154
188335
|
io2.error(JSON.stringify(baseFound));
|
|
@@ -47,6 +47,7 @@ keeps its existing fields and adds the code:
|
|
|
47
47
|
| `ux_evidence_inherited_screens` | A partial push inherits screens not covered by local UX evidence. |
|
|
48
48
|
| `ux_evidence_unreadable` | The UX evidence artifact cannot be read. |
|
|
49
49
|
| `lint_errors` | Build/lint validation found errors. |
|
|
50
|
+
| `depth_budget_exceeded` | A screen or a bound list/grid row template nests deeper, or has more components, than the depth budget (`depth-budget` validator pass). Each `issues[]` entry with `pass: "depth-budget"` carries the JSON `path` of the deepest node (or the tree root for a node count), the `limit` and the `actual` value. Takes precedence over `lint_errors`, and `--force` does not override it: content over the budget overflows the renderer's stack on devices already in the field. Flatten the layout and push again. `himi patch screen` refuses an over-deep raw descriptor with the same code, before any network request, and `himi pack` / `himi template publish` refuse with it even under `--force`. |
|
|
50
51
|
| `control_token_expired` | The selected control token has expired. |
|
|
51
52
|
| `app_source_contains_secrets` | Source archiving detected a possible credential. |
|
|
52
53
|
| `app_source_too_large` | The encoded source archive exceeds its limit. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1420.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"artifactId": "himalaya-cli"
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
|
-
"falconPackageHash": "
|
|
74
|
+
"falconPackageHash": "d2a780fce1a8d60a36a6f5cf4f8860d5d454764049e49a0fa39c2885"
|
|
75
75
|
}
|