@wix/himalaya-cli 0.1417.0 → 0.1419.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 +157 -5
- package/guides/himi-json-output.md +1 -0
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -7715,6 +7715,7 @@ function resolveTranslation(value, catalog3, sourceCatalog) {
|
|
|
7715
7715
|
var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
|
|
7716
7716
|
var init_bindings = __esm({
|
|
7717
7717
|
"../../core/ts/src/bindings.ts"() {
|
|
7718
|
+
"use strict";
|
|
7718
7719
|
BINDING_SIGILS = ["service", "flag", "item", "t"];
|
|
7719
7720
|
BINDING_SIGIL_RE = new RegExp(
|
|
7720
7721
|
`^\\$(?:${BINDING_SIGILS.filter((s2) => s2 !== "t").join("|")})\\b|^\\$t:`
|
|
@@ -10095,6 +10096,7 @@ var validate_descriptor_core_exports = {};
|
|
|
10095
10096
|
__export(validate_descriptor_core_exports, {
|
|
10096
10097
|
CORE_PACKAGES: () => CORE_PACKAGES,
|
|
10097
10098
|
CRAWL_BLOCKING_PASSES: () => CRAWL_BLOCKING_PASSES,
|
|
10099
|
+
DESCRIPTOR_DEPTH_BUDGETS: () => DESCRIPTOR_DEPTH_BUDGETS,
|
|
10098
10100
|
DEVICE_PARITY_WITHHELD: () => DEVICE_PARITY_WITHHELD,
|
|
10099
10101
|
EMBEDDED_BINDING: () => EMBEDDED_BINDING,
|
|
10100
10102
|
INTEGER_MODIFIERS: () => INTEGER_MODIFIERS,
|
|
@@ -10117,6 +10119,8 @@ __export(validate_descriptor_core_exports, {
|
|
|
10117
10119
|
bootBundleWorker: () => bootBundleWorker,
|
|
10118
10120
|
collectServiceBindings: () => collectServiceBindings,
|
|
10119
10121
|
componentPropFindings: () => componentPropFindings,
|
|
10122
|
+
depthBudgetFindings: () => depthBudgetFindings,
|
|
10123
|
+
depthBudgetIssues: () => depthBudgetIssues,
|
|
10120
10124
|
dryRunBundle: () => dryRunBundle,
|
|
10121
10125
|
enumFieldNames: () => enumFieldNames,
|
|
10122
10126
|
extractBundleContract: () => extractBundleContract,
|
|
@@ -11611,6 +11615,100 @@ function bottomSheetFindings(descriptor) {
|
|
|
11611
11615
|
visit(descriptor, "", true);
|
|
11612
11616
|
return out2;
|
|
11613
11617
|
}
|
|
11618
|
+
function depthBudgetIssues(findings) {
|
|
11619
|
+
return findings.map((f2) => ({
|
|
11620
|
+
severity: "error",
|
|
11621
|
+
pass: "depth-budget",
|
|
11622
|
+
path: f2.path,
|
|
11623
|
+
message: f2.message,
|
|
11624
|
+
limit: f2.limit,
|
|
11625
|
+
actual: f2.actual
|
|
11626
|
+
}));
|
|
11627
|
+
}
|
|
11628
|
+
function depthBudgetFindings(descriptor) {
|
|
11629
|
+
const out2 = [];
|
|
11630
|
+
const templates = [];
|
|
11631
|
+
const isComponent = (v2) => {
|
|
11632
|
+
const body = v2?.body;
|
|
11633
|
+
return !!body && typeof body === "object" && typeof body.type === "string" && typeof body.package === "string";
|
|
11634
|
+
};
|
|
11635
|
+
const hostedTemplates = (v2, path2) => {
|
|
11636
|
+
const props = v2.body.props;
|
|
11637
|
+
const found = [];
|
|
11638
|
+
if (!props) return found;
|
|
11639
|
+
const itemsPath = props.itemsPath ?? props.items_path;
|
|
11640
|
+
const rowHost = v2.body.package === "himalaya" ? ROW_TEMPLATE_HOST_TYPES.has(v2.body.type) : true;
|
|
11641
|
+
if (rowHost && typeof itemsPath === "string" && itemsPath !== "" && Array.isArray(props.items) && isComponent(props.items[0])) {
|
|
11642
|
+
found.push({ node: props.items[0], path: `${path2}.body.props.items[0]`, host: `${v2.body.type} at ${path2}` });
|
|
11643
|
+
}
|
|
11644
|
+
if (isComponent(props.eventTemplate)) {
|
|
11645
|
+
found.push({ node: props.eventTemplate, path: `${path2}.body.props.eventTemplate`, host: `${v2.body.type} at ${path2}` });
|
|
11646
|
+
}
|
|
11647
|
+
return found;
|
|
11648
|
+
};
|
|
11649
|
+
const measure2 = (root, rootPath, mode) => {
|
|
11650
|
+
let depth = 0, nodes = 0, deepest = rootPath;
|
|
11651
|
+
const skip = /* @__PURE__ */ new Set();
|
|
11652
|
+
const stack = [
|
|
11653
|
+
{ v: root, path: rootPath, depth: 0, atRoot: mode === "screen" }
|
|
11654
|
+
];
|
|
11655
|
+
while (stack.length) {
|
|
11656
|
+
const { v: v2, path: path2, depth: parentDepth, atRoot } = stack.pop();
|
|
11657
|
+
if (skip.has(v2)) continue;
|
|
11658
|
+
if (Array.isArray(v2)) {
|
|
11659
|
+
for (let i2 = v2.length - 1; i2 >= 0; i2--) stack.push({ v: v2[i2], path: `${path2}[${i2}]`, depth: parentDepth, atRoot: false });
|
|
11660
|
+
continue;
|
|
11661
|
+
}
|
|
11662
|
+
if (!v2 || typeof v2 !== "object") continue;
|
|
11663
|
+
let here = parentDepth;
|
|
11664
|
+
if (isComponent(v2)) {
|
|
11665
|
+
here = parentDepth + 1;
|
|
11666
|
+
nodes += 1;
|
|
11667
|
+
if (here > depth) {
|
|
11668
|
+
depth = here;
|
|
11669
|
+
deepest = path2;
|
|
11670
|
+
}
|
|
11671
|
+
for (const t2 of hostedTemplates(v2, path2)) {
|
|
11672
|
+
if (mode === "screen") templates.push(t2);
|
|
11673
|
+
else skip.add(t2.node);
|
|
11674
|
+
}
|
|
11675
|
+
}
|
|
11676
|
+
const entries = Object.entries(v2);
|
|
11677
|
+
for (let i2 = entries.length - 1; i2 >= 0; i2--) {
|
|
11678
|
+
const [key2, child] = entries[i2];
|
|
11679
|
+
if (!child || typeof child !== "object" || isOpaqueAuthorJson(key2, child, atRoot)) continue;
|
|
11680
|
+
stack.push({ v: child, path: `${path2}.${key2}`, depth: here, atRoot: false });
|
|
11681
|
+
}
|
|
11682
|
+
}
|
|
11683
|
+
return { depth, nodes, deepest };
|
|
11684
|
+
};
|
|
11685
|
+
const flatten = "flatten the layout \u2014 drop wrapper stacks, or move a section into its own screen";
|
|
11686
|
+
const report3 = (what, m2, budget, rootPath) => {
|
|
11687
|
+
if (m2.depth > budget.maxDepth) {
|
|
11688
|
+
out2.push({
|
|
11689
|
+
measure: "depth",
|
|
11690
|
+
path: m2.deepest,
|
|
11691
|
+
limit: budget.maxDepth,
|
|
11692
|
+
actual: m2.depth,
|
|
11693
|
+
message: `${what} nests ${m2.depth} component levels; the limit is ${budget.maxDepth} (deepest node at ${m2.deepest}) \u2014 ${flatten}`
|
|
11694
|
+
});
|
|
11695
|
+
}
|
|
11696
|
+
if (m2.nodes > budget.maxNodes) {
|
|
11697
|
+
out2.push({
|
|
11698
|
+
measure: "nodes",
|
|
11699
|
+
path: rootPath,
|
|
11700
|
+
limit: budget.maxNodes,
|
|
11701
|
+
actual: m2.nodes,
|
|
11702
|
+
message: `${what} has ${m2.nodes} components; the limit is ${budget.maxNodes} \u2014 ${flatten}`
|
|
11703
|
+
});
|
|
11704
|
+
}
|
|
11705
|
+
};
|
|
11706
|
+
report3("screen", measure2(descriptor, "$", "screen"), DESCRIPTOR_DEPTH_BUDGETS.screen, "$");
|
|
11707
|
+
for (const t2 of templates) {
|
|
11708
|
+
report3(`row template of the ${t2.host}`, measure2(t2.node, t2.path, "template"), DESCRIPTOR_DEPTH_BUDGETS.rowTemplate, t2.path);
|
|
11709
|
+
}
|
|
11710
|
+
return out2;
|
|
11711
|
+
}
|
|
11614
11712
|
function topBarFindings(descriptor) {
|
|
11615
11713
|
const out2 = [];
|
|
11616
11714
|
const bar = descriptor?.topBar;
|
|
@@ -11762,6 +11860,11 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
11762
11860
|
const issues = [];
|
|
11763
11861
|
const strict = opts.strict ?? false;
|
|
11764
11862
|
const hygiene = strict ? "error" : "warning";
|
|
11863
|
+
const depthFindings = depthBudgetFindings(descriptor);
|
|
11864
|
+
const depthIssues = depthBudgetIssues(depthFindings);
|
|
11865
|
+
if (depthFindings.some((f2) => f2.measure === "depth" && f2.actual > UNSAFE_TO_RECURSE_DEPTH)) {
|
|
11866
|
+
return { screenId, ok: false, strict, issues: depthIssues, services: [] };
|
|
11867
|
+
}
|
|
11765
11868
|
const fixture = new FixtureValidator({ tokens: opts.tokens, allowedComponents: opts.allowedComponents });
|
|
11766
11869
|
const v2 = fixture.validate(descriptor);
|
|
11767
11870
|
const lbIntegrity = descriptor?.logicBundle?.integrity;
|
|
@@ -11865,6 +11968,7 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
11865
11968
|
for (const finding of topBarFindings(descriptor)) {
|
|
11866
11969
|
issues.push({ severity: "warning", pass: "top-bar", path: finding.path, message: finding.message });
|
|
11867
11970
|
}
|
|
11971
|
+
issues.push(...depthIssues);
|
|
11868
11972
|
const bindings = collectServiceBindings(descriptor);
|
|
11869
11973
|
const descriptorActions = collectDescriptorActions(descriptor);
|
|
11870
11974
|
const workerActions = descriptorActions.filter(({ actionId }) => actionId.startsWith("tier5."));
|
|
@@ -12364,7 +12468,7 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
12364
12468
|
services: Object.keys(services)
|
|
12365
12469
|
};
|
|
12366
12470
|
}
|
|
12367
|
-
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;
|
|
12471
|
+
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, 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;
|
|
12368
12472
|
var init_validate_descriptor_core = __esm({
|
|
12369
12473
|
"../../core/dev-server/src/validate-descriptor.core.ts"() {
|
|
12370
12474
|
init_validator();
|
|
@@ -12378,6 +12482,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
12378
12482
|
init_media_value();
|
|
12379
12483
|
init_frame_limits();
|
|
12380
12484
|
init_rich_content();
|
|
12485
|
+
init_worker_subtree();
|
|
12381
12486
|
CRAWL_BLOCKING_PASSES = /* @__PURE__ */ new Set([
|
|
12382
12487
|
// A screen whose bindings do not resolve has no state to crawl.
|
|
12383
12488
|
"bindings",
|
|
@@ -12385,7 +12490,11 @@ var init_validate_descriptor_core = __esm({
|
|
|
12385
12490
|
"worker-subtree",
|
|
12386
12491
|
// A value outside a strict native enum decodes to nothing on device, so the crawl would be
|
|
12387
12492
|
// exercising a screen the device cannot render.
|
|
12388
|
-
"strict-enum"
|
|
12493
|
+
"strict-enum",
|
|
12494
|
+
// #4498 — a screen or row template over the nesting/node budget overflows a native stack on
|
|
12495
|
+
// decode/render, so there is no screen to crawl. (The publish refusal is separate: the pass is
|
|
12496
|
+
// always an error, and `himi push` refuses a depth-budget error even under `--force`.)
|
|
12497
|
+
"depth-budget"
|
|
12389
12498
|
]);
|
|
12390
12499
|
BOOT_EVAL_TIMEOUT_MS = 2e3;
|
|
12391
12500
|
DRIFT_PROBES = [
|
|
@@ -13357,6 +13466,12 @@ var init_validate_descriptor_core = __esm({
|
|
|
13357
13466
|
OPTIONS_BINDING_PROPS = /* @__PURE__ */ new Set(["optionsPath"]);
|
|
13358
13467
|
EDITOR_SERVICE_NAME = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
13359
13468
|
SHEET_PLACEMENTS = /* @__PURE__ */ new Set(["overlay", "inline"]);
|
|
13469
|
+
DESCRIPTOR_DEPTH_BUDGETS = Object.freeze({
|
|
13470
|
+
screen: Object.freeze({ maxDepth: 40, maxNodes: 2e3 }),
|
|
13471
|
+
rowTemplate: Object.freeze({ maxDepth: WORKER_SUBTREE_CEILINGS.maxDepth, maxNodes: WORKER_SUBTREE_CEILINGS.maxNodes })
|
|
13472
|
+
});
|
|
13473
|
+
UNSAFE_TO_RECURSE_DEPTH = 128;
|
|
13474
|
+
ROW_TEMPLATE_HOST_TYPES = /* @__PURE__ */ new Set(["LazyList", "Grid", "Carousel", "Menu"]);
|
|
13360
13475
|
TOP_BAR_TRAILING_LIMIT = 2;
|
|
13361
13476
|
TOP_BAR_NON_TRAILING = /* @__PURE__ */ new Set(["leading", "principal", "bottom", "keyboard", "overflow"]);
|
|
13362
13477
|
BUTTON_STYLES = /* @__PURE__ */ new Set(["filled", "tonal", "outlined", "text", "elevated", "bordered", "prominent", "plain", "glass", "primary", "secondary", "tertiary", "link", "destructive"]);
|
|
@@ -13881,6 +13996,7 @@ var validate_descriptor_exports = {};
|
|
|
13881
13996
|
__export(validate_descriptor_exports, {
|
|
13882
13997
|
CORE_PACKAGES: () => CORE_PACKAGES,
|
|
13883
13998
|
CRAWL_BLOCKING_PASSES: () => CRAWL_BLOCKING_PASSES,
|
|
13999
|
+
DESCRIPTOR_DEPTH_BUDGETS: () => DESCRIPTOR_DEPTH_BUDGETS,
|
|
13884
14000
|
DEVICE_PARITY_WITHHELD: () => DEVICE_PARITY_WITHHELD,
|
|
13885
14001
|
EMBEDDED_BINDING: () => EMBEDDED_BINDING,
|
|
13886
14002
|
INTEGER_MODIFIERS: () => INTEGER_MODIFIERS,
|
|
@@ -13905,6 +14021,8 @@ __export(validate_descriptor_exports, {
|
|
|
13905
14021
|
bundleNameFromUrl: () => bundleNameFromUrl,
|
|
13906
14022
|
collectServiceBindings: () => collectServiceBindings,
|
|
13907
14023
|
componentPropFindings: () => componentPropFindings,
|
|
14024
|
+
depthBudgetFindings: () => depthBudgetFindings,
|
|
14025
|
+
depthBudgetIssues: () => depthBudgetIssues,
|
|
13908
14026
|
discoverNativeActions: () => discoverNativeActions,
|
|
13909
14027
|
dryRunBundle: () => dryRunBundle,
|
|
13910
14028
|
enumFieldNames: () => enumFieldNames,
|
|
@@ -17035,7 +17153,6 @@ function resolveIdiom(tokens2, ctx = {}) {
|
|
|
17035
17153
|
var IDIOM_CONTEXTS, UNSAFE_KEYS;
|
|
17036
17154
|
var init_idiom = __esm({
|
|
17037
17155
|
"../../core/ts/src/idiom.ts"() {
|
|
17038
|
-
"use strict";
|
|
17039
17156
|
IDIOM_CONTEXTS = {
|
|
17040
17157
|
ios: { native: ["ios"] },
|
|
17041
17158
|
android: { native: ["material"] },
|
|
@@ -141168,7 +141285,8 @@ var init_push_errors = __esm({
|
|
|
141168
141285
|
"not_carried_by_patch",
|
|
141169
141286
|
"authoring_unavailable",
|
|
141170
141287
|
"push_failed",
|
|
141171
|
-
"binary_capability_gap"
|
|
141288
|
+
"binary_capability_gap",
|
|
141289
|
+
"depth_budget_exceeded"
|
|
141172
141290
|
];
|
|
141173
141291
|
UX_CODES = {
|
|
141174
141292
|
absent: "ux_evidence_absent",
|
|
@@ -180506,6 +180624,10 @@ function describeNondeterministicWorkers(workers) {
|
|
|
180506
180624
|
return workers.length <= 1 ? workers.map(one).join("") : `${workers.slice(0, -1).map(one).join(", ")} and ${one(workers[workers.length - 1])}`;
|
|
180507
180625
|
}
|
|
180508
180626
|
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)";
|
|
180627
|
+
function depthBudgetExceeded(report3) {
|
|
180628
|
+
return (report3.issues ?? []).some((i2) => i2.severity === "error" && i2.pass === "depth-budget");
|
|
180629
|
+
}
|
|
180630
|
+
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
180631
|
function summarizeLint(app, bres, outcome, strict, extraIssues = []) {
|
|
180510
180632
|
const issues = (outcome.lint ?? []).flatMap((s2) => s2.issues.map((i2) => ({ screen: s2.screenId, ...i2 })));
|
|
180511
180633
|
issues.push(...extraIssues);
|
|
@@ -184630,6 +184752,10 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
184630
184752
|
...await navIssues2(buildDir, strict),
|
|
184631
184753
|
...scaffoldSourceFindings
|
|
184632
184754
|
]);
|
|
184755
|
+
if (depthBudgetExceeded(report3)) {
|
|
184756
|
+
print({ ...report3, published: false, code: "depth_budget_exceeded", hint: DEPTH_BUDGET_HINT });
|
|
184757
|
+
return 1;
|
|
184758
|
+
}
|
|
184633
184759
|
if (hasErrors && !force) {
|
|
184634
184760
|
print({ ...report3, published: false, hint: "lint found errors \u2014 fix them, or re-run with --force to publish anyway" });
|
|
184635
184761
|
return 1;
|
|
@@ -186445,6 +186571,10 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
186445
186571
|
...storesV1Issues(dir, strict),
|
|
186446
186572
|
...await navIssues2(dir, strict)
|
|
186447
186573
|
]);
|
|
186574
|
+
if (depthBudgetExceeded(report3)) {
|
|
186575
|
+
print(pushFailure2("depth_budget_exceeded", { ...report3, pushed: false, hint: DEPTH_BUDGET_HINT }));
|
|
186576
|
+
return 1;
|
|
186577
|
+
}
|
|
186448
186578
|
if (hasErrors && !force) {
|
|
186449
186579
|
print(pushFailure2("lint_errors", { ...report3, pushed: false, hint: "lint found errors \u2014 fix them, or re-run `himi push --force` to publish anyway" }));
|
|
186450
186580
|
return 1;
|
|
@@ -187012,6 +187142,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
187012
187142
|
...storesV1Issues(dir, strict),
|
|
187013
187143
|
...await navIssues2(dir, strict)
|
|
187014
187144
|
]);
|
|
187145
|
+
if (depthBudgetExceeded(report3)) {
|
|
187146
|
+
rmSync24(built, { recursive: true, force: true });
|
|
187147
|
+
print({ ...report3, packed: false, code: "depth_budget_exceeded", hint: DEPTH_BUDGET_HINT });
|
|
187148
|
+
return 1;
|
|
187149
|
+
}
|
|
187015
187150
|
if (hasErrors && !force) {
|
|
187016
187151
|
rmSync24(built, { recursive: true, force: true });
|
|
187017
187152
|
print({ ...report3, packed: false, hint: "lint found errors \u2014 fix them, or re-run `himi pack --force` to pack anyway" });
|
|
@@ -188143,12 +188278,29 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
188143
188278
|
return 2;
|
|
188144
188279
|
}
|
|
188145
188280
|
const descriptor = readFileSync103(file2, "utf8");
|
|
188281
|
+
let parsed;
|
|
188146
188282
|
try {
|
|
188147
|
-
JSON.parse(descriptor);
|
|
188283
|
+
parsed = JSON.parse(descriptor);
|
|
188148
188284
|
} catch (e2) {
|
|
188149
188285
|
io2.error(JSON.stringify({ ok: false, error: "invalid_descriptor", file: file2, screen: id, message: `${file2} is not valid JSON: ${e2.message}` }));
|
|
188150
188286
|
return 1;
|
|
188151
188287
|
}
|
|
188288
|
+
const { depthBudgetFindings: depthBudgetFindings2, depthBudgetIssues: depthBudgetIssues2 } = await Promise.resolve().then(() => (init_validate_descriptor_core(), validate_descriptor_core_exports));
|
|
188289
|
+
const tooDeep = depthBudgetIssues2(depthBudgetFindings2(parsed));
|
|
188290
|
+
if (tooDeep.length > 0) {
|
|
188291
|
+
io2.error(JSON.stringify({
|
|
188292
|
+
ok: false,
|
|
188293
|
+
code: "depth_budget_exceeded",
|
|
188294
|
+
error: "depth_budget_exceeded",
|
|
188295
|
+
patched: false,
|
|
188296
|
+
app,
|
|
188297
|
+
screen: id,
|
|
188298
|
+
file: file2,
|
|
188299
|
+
issues: tooDeep,
|
|
188300
|
+
hint: "flatten the descriptor below the depth budget (see each issue's path and limit); `--force` does not override this"
|
|
188301
|
+
}, null, 2));
|
|
188302
|
+
return 1;
|
|
188303
|
+
}
|
|
188152
188304
|
const baseFound = await fetchReleaseManifest(client2, app, fromRelease);
|
|
188153
188305
|
if ("error" in baseFound) {
|
|
188154
188306
|
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.1419.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": "ee7c2063084b2cc9cfe97bd9969ad339ad9ea61d026dcfcbe7b4f9e5"
|
|
75
75
|
}
|