@wix/himalaya-cli 0.837.0 → 0.838.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 +38 -2
- package/guides/himi-test.md +20 -2
- package/guides/testing-himi-apps.md +12 -5
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -42448,7 +42448,7 @@ async function crawlScreenJourney(opts) {
|
|
|
42448
42448
|
});
|
|
42449
42449
|
}
|
|
42450
42450
|
async function crawlScreenInner(opts) {
|
|
42451
|
-
const { screenId, descriptor, bundleJs, knownScreenIds } = opts;
|
|
42451
|
+
const { screenId, descriptor, bundleJs, knownScreenIds, linkableScreenIds } = opts;
|
|
42452
42452
|
const { call: wixCall, label: transport } = layeredTransport({
|
|
42453
42453
|
rules: opts.rules,
|
|
42454
42454
|
cmsSeed: opts.cmsSeed,
|
|
@@ -42833,13 +42833,44 @@ async function crawlScreenInner(opts) {
|
|
|
42833
42833
|
w.dispose();
|
|
42834
42834
|
}
|
|
42835
42835
|
}
|
|
42836
|
+
const edges = dedupeEdges(navEdges);
|
|
42837
|
+
if (linkableScreenIds?.size && !opts.capabilitySuccess) {
|
|
42838
|
+
const linkable = linkableScreenIds;
|
|
42839
|
+
const resolvesToLinkable = (target) => {
|
|
42840
|
+
if (linkable.has(target)) return true;
|
|
42841
|
+
for (const base of linkable) {
|
|
42842
|
+
if (target.length > base.length + 1 && target.startsWith(base)) {
|
|
42843
|
+
const sep11 = target[base.length];
|
|
42844
|
+
if (sep11 === "_" || sep11 === "/") return true;
|
|
42845
|
+
}
|
|
42846
|
+
}
|
|
42847
|
+
return false;
|
|
42848
|
+
};
|
|
42849
|
+
const reported = /* @__PURE__ */ new Set();
|
|
42850
|
+
for (const e of edges) {
|
|
42851
|
+
if (e.target === screenId) continue;
|
|
42852
|
+
if (reported.has(e.target)) continue;
|
|
42853
|
+
if (knownScreenIds.has(e.target) || resolvesToLinkable(e.target)) continue;
|
|
42854
|
+
reported.add(e.target);
|
|
42855
|
+
findings.push({
|
|
42856
|
+
screen: screenId,
|
|
42857
|
+
trigger: "boot",
|
|
42858
|
+
invariant: "nav-target-missing",
|
|
42859
|
+
severity: "warning",
|
|
42860
|
+
message: `"himi.open" targets "${e.target}", which is neither a baked screen nor one of this app's ${linkable.size} linkable screens (nor an instance of one) \u2014 the tap opens nothing`,
|
|
42861
|
+
at: e.via,
|
|
42862
|
+
actual: e.target,
|
|
42863
|
+
hint: "add the screen, or declare it in navigation.linkableScreens if it is a templated route the router resolves at runtime"
|
|
42864
|
+
});
|
|
42865
|
+
}
|
|
42866
|
+
}
|
|
42836
42867
|
return {
|
|
42837
42868
|
screen: screenId,
|
|
42838
42869
|
transport,
|
|
42839
42870
|
bundle: bundleJs ? descriptor?.logicBundle?.url ?? "bundle" : null,
|
|
42840
42871
|
actionsExercised: exercised,
|
|
42841
42872
|
actionsSkipped,
|
|
42842
|
-
navEdges:
|
|
42873
|
+
navEdges: edges,
|
|
42843
42874
|
...observations ? { observations } : {},
|
|
42844
42875
|
...unobservedActions.length ? { unobservedActions } : {},
|
|
42845
42876
|
findings: dedupe(findings),
|
|
@@ -45015,6 +45046,7 @@ async function runCrawl(opts) {
|
|
|
45015
45046
|
bundleJs: baked.bundleJs,
|
|
45016
45047
|
bundleMap: baked.bundleMap ?? null,
|
|
45017
45048
|
knownScreenIds,
|
|
45049
|
+
...opts.linkableScreenIds?.size ? { linkableScreenIds: opts.linkableScreenIds } : {},
|
|
45018
45050
|
rules: net?.rules ?? null,
|
|
45019
45051
|
...opts.cmsSeed && Object.keys(opts.cmsSeed).length ? { cmsSeed: opts.cmsSeed } : {},
|
|
45020
45052
|
...opts.canned?.count ? { canned: opts.canned.byKey } : {},
|
|
@@ -62333,6 +62365,10 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62333
62365
|
...cmsSeed ? { cmsSeed } : {},
|
|
62334
62366
|
...canned ? { canned } : {},
|
|
62335
62367
|
...tabRoots.size ? { tabRoots } : {},
|
|
62368
|
+
// The app's exact linkable set, straight off the build outcome (#2512) — arms the
|
|
62369
|
+
// nav-target check. Omitted when the build reported none, so the crawl stays silent
|
|
62370
|
+
// rather than judging every target against an empty set.
|
|
62371
|
+
...outcome.linkableScreenIds?.length ? { linkableScreenIds: new Set(outcome.linkableScreenIds) } : {},
|
|
62336
62372
|
...deep ? { deep } : {},
|
|
62337
62373
|
...offline ? { offline: true } : {},
|
|
62338
62374
|
...offline || flags["no-hostile"] === true ? { hostile: false } : {},
|
package/guides/himi-test.md
CHANGED
|
@@ -109,6 +109,7 @@ Only **unambiguous** defects, so a green run stays worth trusting:
|
|
|
109
109
|
| `unresolved-wix-media` | error | A media-typed prop holding a raw Wix media handle/id the renderer cannot load. |
|
|
110
110
|
| `binding-unresolved` | error / warning | A `$service:` binding aimed at state the worker never defines. It is an error when the missing value can leave visible UI blank. A direct prop with sibling `collapseWhenEmpty: true` is an advisory warning instead: the renderer deliberately removes that zero-size optional chrome, while the warning keeps the omitted contract auditable. |
|
|
111
111
|
| `nav-param-dropped` | error | A bound `himi.open` param that resolves to nothing, so the target opens without it and error-cards. |
|
|
112
|
+
| `nav-target-missing` | **warning** | A `himi.open` whose target is neither a baked screen, nor one of the app's declared `linkableScreens`, nor an instance of one (`course_detail_c1` under the base `course_detail`) — the tap opens nothing. Only judged when the caller supplies the app's exact linkable set; an absent set means no opinion, never a guess. A target still carrying an **unresolved** `$` token is dropped before it becomes an edge and is never judged — but one that RESOLVED to a concrete id is judged, which is the point: `$item.detailScreenId` resolving to `course_detail_c1` against the first row is exactly the case the instance rule exists for. |
|
|
112
113
|
| `poll-action-missing` | error | A `_poll` directive every host will silently ignore — an action the bundle never declares, a malformed `action`, a missing `id`, or a non-positive `intervalMs`. Each ends the same way: a screen that never refreshes, with nothing saying why. Nothing in the descriptor names the polled action, so no static check can see it. (A merely too-small interval is legal — the host clamps it.) |
|
|
113
114
|
| `no-request-issued` | **warning** | A worker that uses the Wix transport but never fetches — "the screen loaded with sample data." A warning: a conditional or tap-triggered fetch is legitimate. |
|
|
114
115
|
| `native-decode-failed` | error | Under `--native`, the real Swift/Kotlin decoder rejected the baked descriptor bytes (one bad enum blanks the whole screen on device). |
|
|
@@ -120,8 +121,25 @@ Only **unambiguous** defects, so a green run stays worth trusting:
|
|
|
120
121
|
| `typed-value-ignored` | **warning** | The crawl typed the value a control really carries — the payload key every renderer injects for that control — and the dispatch changed **nothing**: no state, no navigation, no request. The value is read off the app itself (an id from the control's own options, or a word from the worker's seeded state) and is always one the control is *not* already showing, so a reducer that ignores it cannot work on device. A warning because the input is the crawl's: a reducer that legitimately no-ops on a value is possible, and `himi-test.json` `skip[]` takes the invariant. |
|
|
121
122
|
|
|
122
123
|
**Deliberately never reported:** an empty collection · an `error` state (often the correct
|
|
123
|
-
answer to empty input) · a `null` optional
|
|
124
|
-
|
|
124
|
+
answer to empty input) · a `null` optional.
|
|
125
|
+
|
|
126
|
+
**Nav-target existence was on that list and came off it — read why before trusting it.**
|
|
127
|
+
Judging a target against an *approximation* of the router's screen set flagged working deep
|
|
128
|
+
links as dead on 15 of 37 apps, which retired the check. The exact set is the app-config's
|
|
129
|
+
`linkableScreens`, and a reader bug meant it arrived empty for a long time — so that verdict
|
|
130
|
+
was really measured against the **baked screen ids alone**, which is the approximation, not
|
|
131
|
+
against the exact set it was supposed to use.
|
|
132
|
+
|
|
133
|
+
Re-measured with the exact set, the check needed one more rule before it was silent: a linkable
|
|
134
|
+
entry declares a **base** (`course_detail`, with `paramKeys`) while a row navigates to a
|
|
135
|
+
worker-computed **instance** (`course_detail_c1`), and plain set membership reported two working
|
|
136
|
+
deep links as dead. With base-covers-its-instances it is silent everywhere it was measured —
|
|
137
|
+
**19 of 19 apps, no false positives.**
|
|
138
|
+
|
|
139
|
+
It ships at `warning`, with one real catch behind it: an app that declared four of its five
|
|
140
|
+
templated detail routes in `linkableScreens` and omitted the fifth, so a deep link to that
|
|
141
|
+
screen could not resolve while the in-app tap still worked. That is what distinguishes it from
|
|
142
|
+
a check that merely never fires.
|
|
125
143
|
|
|
126
144
|
> **A false failure is worse than no tool.** It teaches an author to stop reading the
|
|
127
145
|
> output, and then the real findings go unread too. When in doubt, the crawl stays quiet.
|
|
@@ -115,13 +115,20 @@ Only **unambiguous** defects, so a green run stays worth trusting:
|
|
|
115
115
|
| every `$service:` binding names state the worker actually defines | a binding aimed at nothing (service, or its first path segment — a deeper miss on an empty list is legitimately data-dependent and is **not** reported) |
|
|
116
116
|
| no nav param silently dropped | a bound `himi.open` param that resolves to nothing is **dropped** ([actionParams.ts](../core/web-renderer/src/actionParams.ts)), so the target opens without it and error-cards |
|
|
117
117
|
| a worker that uses the Wix transport actually issued a request | "the fetch never left and the screen loaded with sample data" — a **warning**, since a conditional or tap-triggered fetch is legitimate |
|
|
118
|
+
| a nav target actually resolves | a `himi.open` at a screen that is neither baked, nor declared in `linkableScreens`, nor an instance of a declared base — a **warning**, and only when the app's exact linkable set is available |
|
|
118
119
|
|
|
119
120
|
Deliberately **not** reported: an empty collection, an `error` state (often the correct answer
|
|
120
|
-
to empty input), a `null` optional field
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
to empty input), and a `null` optional field. When in doubt the crawl stays quiet: one false
|
|
122
|
+
failure teaches an author to stop reading the output, and then the real findings go unread too.
|
|
123
|
+
|
|
124
|
+
Nav-target existence was on that list until recently. The router's real set is the union of baked
|
|
125
|
+
screens, config-declared templated bases **and their instances**, and nav overrides —
|
|
126
|
+
approximating it flagged working deep links as dead on 15 of 37 apps. That verdict was measured
|
|
127
|
+
against baked ids alone, because a reader bug left the exact set (`linkableScreens`) empty. With
|
|
128
|
+
the exact set, plus the rule that a declared base covers its instances, it measured silent on
|
|
129
|
+
all 19 apps it was run against — **no false positives, and one real catch**: a templated detail
|
|
130
|
+
route an app never declared linkable, so deep links to it could not resolve. See
|
|
131
|
+
[himi-test.md](himi-test.md) for the full history.
|
|
125
132
|
|
|
126
133
|
### It runs the worker the way the DEVICE does
|
|
127
134
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.838.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": [
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"artifactId": "himalaya-cli"
|
|
64
64
|
}
|
|
65
65
|
},
|
|
66
|
-
"falconPackageHash": "
|
|
66
|
+
"falconPackageHash": "9fd823cad2c263e2917b872794458e3c97e9ffc0040e182088a08fa5"
|
|
67
67
|
}
|