@wix/himalaya-cli 0.833.0 → 0.835.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/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/bookings-v2/src/extensions.d.ts +39 -15
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-v1/src/display.d.ts +27 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-v1/src/products-v3.d.ts +24 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-bookings.mjs +3 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-stores.mjs +29 -8
- package/dist/cli.mjs +1393 -137
- package/guides/headless-loop.md +3 -1
- package/guides/himi-test.md +10 -3
- package/guides/mobile-ux.md +46 -7
- package/guides/sdk-reference.json +22 -44
- package/guides/testing-himi-apps.md +5 -4
- package/guides/tier-5-add-a-screen.md +1 -1
- package/package.json +2 -2
- package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +7 -6
- package/templates/branded-lite/tier5-src/himi-store-product/index.ts +7 -6
- package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +7 -6
- package/templates/himi-chat/dev/index.ts +2 -2
- package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +7 -6
- package/templates/retail-store/tier5-src/himi-store-product/index.ts +7 -6
package/guides/headless-loop.md
CHANGED
|
@@ -194,7 +194,9 @@ closed. The loop to teach an agent: **build → test → close the top ledger ga
|
|
|
194
194
|
Before calling a multi-screen app ready, run `himi ux audit --content . --strict` and fix the
|
|
195
195
|
acceptance/evidence gaps it reports. After driving a native shell, record what actually happened
|
|
196
196
|
with `himi ux record --content . --platform ios|android --status passed|failed|unavailable
|
|
197
|
-
--checks back,keyboard
|
|
197
|
+
[--checks back,keyboard,…]`. `--checks` is required for `passed`/`failed` and names what you
|
|
198
|
+
actually drove; an unavailable platform drove nothing, so it takes no checks and needs its reason
|
|
199
|
+
recorded, not guessed.
|
|
198
200
|
|
|
199
201
|
Report v2 sharpens all of it: a worker throw carries `in tier5-src/<screen>/index.ts:<line>`
|
|
200
202
|
(mapped through the bundle's sourcemap — fix it without grepping), the ledger lists worker
|
package/guides/himi-test.md
CHANGED
|
@@ -66,9 +66,15 @@ CLI orchestration: `tools/himi-cli/src/test.ts`.
|
|
|
66
66
|
|
|
67
67
|
## Typed form journeys
|
|
68
68
|
|
|
69
|
-
The
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
The crawl types into a control **only when it can read a legal value off the app itself** — an id
|
|
70
|
+
from the control's own `options`/`optionsPath` that is not the one selected, or a word from the
|
|
71
|
+
booted worker's own seeded state that is not what the field already shows — and only for a control
|
|
72
|
+
the payload contract names. A `Slider`, `Stepper`, `Toggle` or `DatePicker` has no such source, so
|
|
73
|
+
those still dispatch with the descriptor's default (often empty) value, and the gap ledger says so
|
|
74
|
+
per screen.
|
|
75
|
+
|
|
76
|
+
For a flow where the real proof is **typed value → submit → visible completion** — several fields,
|
|
77
|
+
in order, ending in a rendered result — add a short screen-local journey to `himi-test.json`:
|
|
72
78
|
|
|
73
79
|
```json
|
|
74
80
|
{
|
|
@@ -111,6 +117,7 @@ Only **unambiguous** defects, so a green run stays worth trusting:
|
|
|
111
117
|
| `refresh-not-idempotent` | **warning** | `refresh` from a fresh boot settles somewhere other than the boot did, on identical data — usually a refresh that appends instead of replacing. |
|
|
112
118
|
| `list-shrank-on-load-more` | **warning** | A "load more" returned FEWER rows than before it ran: the new page replaced the list instead of extending it. |
|
|
113
119
|
| `list-grew-on-filter` | **warning** | A filter, search or sort made a list longer. Narrowing can reorder or remove, never add. |
|
|
120
|
+
| `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. |
|
|
114
121
|
|
|
115
122
|
**Deliberately never reported:** an empty collection · an `error` state (often the correct
|
|
116
123
|
answer to empty input) · a `null` optional · whether a nav target *exists* (approximating
|
package/guides/mobile-ux.md
CHANGED
|
@@ -131,8 +131,9 @@ Use `himi ux audit --content <app>` as the repeatable evidence check. It is advi
|
|
|
131
131
|
existing templates migrate; `--strict` promotes an incomplete contract, remaining template
|
|
132
132
|
copy, missing app fixtures, or unrecorded platform audit to a release blocker. After actually
|
|
133
133
|
driving a native shell, record the result—not an assumption—with `himi ux record --content <app>
|
|
134
|
-
--platform ios|android --status passed|failed|unavailable --checks back,keyboard
|
|
135
|
-
unavailable platform
|
|
134
|
+
--platform ios|android --status passed|failed|unavailable [--checks back,keyboard,...]`. `--checks`
|
|
135
|
+
is required for `passed`/`failed` and names what you actually drove; an unavailable platform drove
|
|
136
|
+
nothing, so it takes no checks and needs a `--reason` instead.
|
|
136
137
|
|
|
137
138
|
### Strict audit contract
|
|
138
139
|
|
|
@@ -140,15 +141,53 @@ unavailable platform needs a reason.
|
|
|
140
141
|
rewrite that drops a required string is caught in the loop you are already running rather than at
|
|
141
142
|
the end of it. `himi validate --strict` and `himi ux audit --strict` both promote that warning to a
|
|
142
143
|
**release blocker**. Both read the same exact markers, and each gate **substring-matches** these
|
|
143
|
-
phrases — so use them verbatim: a semantically equivalent rewrite ("each state exposes exactly
|
|
144
|
-
primary call to action") fails the same as omitting them:
|
|
144
|
+
three phrases — so use them verbatim: a semantically equivalent rewrite ("each state exposes exactly
|
|
145
|
+
one primary call to action") fails the same as omitting them:
|
|
145
146
|
|
|
146
147
|
- The heading `## Implementation acceptance`.
|
|
147
148
|
- The heading `## Evidence`.
|
|
148
149
|
- The phrase `one primary CTA per state`.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
|
|
151
|
+
The fourth marker, **width evidence**, is graded by **content, not by phrase** — it is a
|
|
152
|
+
fact about what you rendered rather than a string, so there is nothing to paste. Satisfy it either
|
|
153
|
+
way:
|
|
154
|
+
|
|
155
|
+
- Name two pixel widths spanning compact → wider, within about 400 characters of each other so
|
|
156
|
+
they read as one statement: one **below 600px** (compact) and one **at 600px or wider** (medium
|
|
157
|
+
or expanded). `Rendered 320, 390 and 834 (home-320.png, home-390.png, home-834.png)` satisfies it
|
|
158
|
+
— a single width does not. What this proves is that you rendered more than one size class, not
|
|
159
|
+
which wider one: 600px is the `medium` breakpoint and `expanded` begins at 840px, so 834 counts
|
|
160
|
+
as wider without being expanded. The two bands are contiguous, so every width you actually render
|
|
161
|
+
counts as one or the other: `pixel` (412) and `iphone-max` (430) from `himi render --device` are
|
|
162
|
+
compact.
|
|
163
|
+
Each number must read as a **width**: give it a unit (`834px`), put it in a screenshot filename
|
|
164
|
+
(`home-834.png`, `home-834-dark.png`, `home-834x1112.png`), or name it with the vocabulary of
|
|
165
|
+
widths — `width`, `wide`, `pixel`, `viewport`, `breakpoint`, `compact`, `expanded`, `column`,
|
|
166
|
+
`portrait`, `landscape`. One such word covers a whole list of widths from either end (`Rendered
|
|
167
|
+
320, 390 and 834 widths`, `Widths: 320, 390, 834` and `Rendered compact (320) and expanded (834)`
|
|
168
|
+
all work), and the list may wrap across lines — but it does not reach across another phrase or
|
|
169
|
+
into the next line unless that line continues the list: in `Rendered home at 834px; p95
|
|
170
|
+
250 ms` only `834` is a width, so that line names a single width and is still reported. In a
|
|
171
|
+
`390x844` pair the first number is the width and the second is the height, so one portrait
|
|
172
|
+
screenshot is one width — `home-390x844.png` on its own is not two. Bare
|
|
173
|
+
digits count for nothing, which keeps a latency budget, a price or an issue number from standing
|
|
174
|
+
in for the half you did not render. A number in the 1990-2099 range needs its **unit** to count
|
|
175
|
+
as a width: `2048px` is taken at its word, while a bare `2026` and a year-shaped filename
|
|
176
|
+
(`shot-2026.png`, `evidence-2026-09-18.png`) are not widths — `home-2048.png` cannot be told
|
|
177
|
+
apart from `shot-2026.png`, so spell the unit when your render really is that wide.
|
|
178
|
+
`render` is deliberately **not** one of the cues: an acceptance row says "renders in under
|
|
179
|
+
250 ms" far more often than it names a viewport. Neither is a pixel measurement of something
|
|
180
|
+
that is not a viewport — `Row height 320px`, `Font size: 512px` and `844 tall` are ignored,
|
|
181
|
+
because a unit says pixels, not width. Assets are judged by the SENTENCE they sit in rather than
|
|
182
|
+
by word order: a sentence naming an image, logo, banner, hero, icon, media or artwork is a record
|
|
183
|
+
of assets, so none of its numbers count — `Use 320px-wide mobile and 1024px-wide desktop hero
|
|
184
|
+
images` records no render. A screenshot **filename** is the exception and outranks the sentence
|
|
185
|
+
it appears in, because a file that was written is the strongest evidence this marker takes:
|
|
186
|
+
`Screenshots: hero-320.png and hero-834.png` counts.
|
|
187
|
+
- Or keep the scaffold's own sentence, `compact (320/360)` followed later by `expanded`, which is
|
|
188
|
+
still accepted as-is. The two **may wrap across lines** — the check is not line-based — but
|
|
189
|
+
`expanded` must follow within about 400 characters, so keep them in the same sentence or bullet
|
|
190
|
+
rather than in separate sections.
|
|
152
191
|
|
|
153
192
|
A `MOBILE-UX.md` that is **absent or empty** is not four missing markers. `himi ux audit` reports it
|
|
154
193
|
once, as a missing contract; `himi validate` stays silent about it entirely. Asking for the document
|
|
@@ -7105,39 +7105,12 @@
|
|
|
7105
7105
|
"decl": "export function updateService(serviceId: string, service: WixServiceWrite & { revision?: string }): Promise<WixUpdateServiceResponse>;",
|
|
7106
7106
|
"http": "PATCH /bookings/v2/services/{…}"
|
|
7107
7107
|
},
|
|
7108
|
-
{
|
|
7109
|
-
"name": "deleteService",
|
|
7110
|
-
"kind": "function",
|
|
7111
|
-
"jsdoc": "/** Delete a service — DELETE /bookings/v1/services/{id}. */",
|
|
7112
|
-
"decl": "export function deleteService(serviceId: string): Promise<WixDeleteServiceResponse>;",
|
|
7113
|
-
"http": "DELETE /bookings/v1/services/{…}"
|
|
7114
|
-
},
|
|
7115
|
-
{
|
|
7116
|
-
"name": "WixListBookingsResponse",
|
|
7117
|
-
"kind": "interface",
|
|
7118
|
-
"jsdoc": "",
|
|
7119
|
-
"decl": "export interface WixListBookingsResponse {\n bookings: WixBooking[];\n}"
|
|
7120
|
-
},
|
|
7121
|
-
{
|
|
7122
|
-
"name": "listBookings",
|
|
7123
|
-
"kind": "function",
|
|
7124
|
-
"jsdoc": "/** List bookings — GET /bookings/v1/bookings. */",
|
|
7125
|
-
"decl": "export function listBookings(): Promise<WixListBookingsResponse>;",
|
|
7126
|
-
"http": "GET /bookings/v1/bookings"
|
|
7127
|
-
},
|
|
7128
7108
|
{
|
|
7129
7109
|
"name": "WixGetBookingResponse",
|
|
7130
7110
|
"kind": "interface",
|
|
7131
7111
|
"jsdoc": "",
|
|
7132
7112
|
"decl": "export interface WixGetBookingResponse {\n booking: WixBooking;\n}"
|
|
7133
7113
|
},
|
|
7134
|
-
{
|
|
7135
|
-
"name": "getBooking",
|
|
7136
|
-
"kind": "function",
|
|
7137
|
-
"jsdoc": "/** Fetch a single booking by id — GET /bookings/v1/bookings/{id}. */",
|
|
7138
|
-
"decl": "export function getBooking(bookingId: string): Promise<WixGetBookingResponse>;",
|
|
7139
|
-
"http": "GET /bookings/v1/bookings/{…}"
|
|
7140
|
-
},
|
|
7141
7114
|
{
|
|
7142
7115
|
"name": "WixBookingWrite",
|
|
7143
7116
|
"kind": "interface",
|
|
@@ -7150,13 +7123,6 @@
|
|
|
7150
7123
|
"jsdoc": "",
|
|
7151
7124
|
"decl": "export interface WixCreateBookingResponse {\n booking: WixBooking;\n}"
|
|
7152
7125
|
},
|
|
7153
|
-
{
|
|
7154
|
-
"name": "createBooking",
|
|
7155
|
-
"kind": "function",
|
|
7156
|
-
"jsdoc": "/** Create a booking on behalf of a client — POST /bookings/v1/bookings. */",
|
|
7157
|
-
"decl": "export function createBooking(booking: WixBookingWrite): Promise<WixCreateBookingResponse>;",
|
|
7158
|
-
"http": "POST /bookings/v1/bookings"
|
|
7159
|
-
},
|
|
7160
7126
|
{
|
|
7161
7127
|
"name": "WixUpdateBookingResponse",
|
|
7162
7128
|
"kind": "interface",
|
|
@@ -7234,11 +7200,17 @@
|
|
|
7234
7200
|
"jsdoc": "",
|
|
7235
7201
|
"decl": "export interface WixQueryAvailabilityResponse { availabilityEntries?: WixAvailabilityEntry[] }"
|
|
7236
7202
|
},
|
|
7203
|
+
{
|
|
7204
|
+
"name": "WixServiceAvailabilityOptions",
|
|
7205
|
+
"kind": "interface",
|
|
7206
|
+
"jsdoc": "/** How to bound an availability query. `bookable` is a `query.filter` member — the\n * request's `query` has only `filter` and `sort`, so there is NO paging member and\n * a `paging: { limit }` you add is silently dropped rather than honoured. */",
|
|
7207
|
+
"decl": "export interface WixServiceAvailabilityOptions {\n /** Bookable slots only. Defaults to `true`; pass `false` to get the unbookable\n * ones too (a greyed-out calendar), which is what the endpoint returns unfiltered. */\n bookable?: boolean;\n}"
|
|
7208
|
+
},
|
|
7237
7209
|
{
|
|
7238
7210
|
"name": "queryServiceAvailability",
|
|
7239
7211
|
"kind": "function",
|
|
7240
|
-
"jsdoc": "
|
|
7241
|
-
"decl": "export function queryServiceAvailability(serviceId: string
|
|
7212
|
+
"jsdoc": "/**\n * Query bookable slots for a service in a date window —\n * POST /bookings/v1/availability/query. Verified live (571 entries).\n *\n * BOUND IT. Unfiltered, this returns every slot in the window, bookable AND\n * unbookable — a two-week window on a busy calendar is hundreds of entries and a\n * response big enough to stall a worker. Two things bound it, and only one of them\n * is a parameter here:\n *\n * - `bookable`, which this now defaults to `true`. Slots you cannot book are not\n * what a booking screen is paging through.\n * - THE WINDOW ITSELF. Ask for the days you are about to paint, not the month.\n *\n * What is NOT available is paging: the request's `query` carries only `filter` and\n * `sort`, so a `paging: { limit }` is an unknown field the server drops on the\n * floor — which is why \"it ignores its own paging.limit\" is a misreading. There was\n * never a paging member to ignore.\n *\n * A per-day cap (`slotsPerDay`) is deliberately NOT offered. This v1 Availability\n * Calendar endpoint is absent from the current published Wix reference (superseded\n * by Time Slots V2), and the two plausible spellings put it in different places — a\n * `query.filter` member, or a top-level sibling of `query`. An unknown field in\n * either position is dropped silently rather than rejected, so shipping the wrong\n * guess would hand callers a knob that does nothing while this comment promised it\n * worked. Narrow the window instead, until the level can be confirmed against a\n * schema or a live call.\n */",
|
|
7213
|
+
"decl": "export function queryServiceAvailability(\n serviceId: string,\n startDate: string,\n endDate: string,\n options: WixServiceAvailabilityOptions = {},\n): Promise<WixQueryAvailabilityResponse>;",
|
|
7242
7214
|
"http": "POST /bookings/v1/availability/query"
|
|
7243
7215
|
},
|
|
7244
7216
|
{
|
|
@@ -7342,7 +7314,7 @@
|
|
|
7342
7314
|
{
|
|
7343
7315
|
"name": "getBookingFull",
|
|
7344
7316
|
"kind": "function",
|
|
7345
|
-
"jsdoc": "/** Rich single-booking read — GET /bookings/v1/bookings/{id}. Returns the full\n * booking (payment/intake/location/staff/attendance). The booking-detail data source. */",
|
|
7317
|
+
"jsdoc": "/** Rich single-booking read — GET /bookings/v1/bookings/{id}. Returns the full\n * booking (payment/intake/location/staff/attendance). The booking-detail data source.\n * Owner-scoped: needs an owner/BO session; a visitor or member token gets 403. A\n * member-facing screen reads its own bookings via `queryBookings` instead. */",
|
|
7346
7318
|
"decl": "export function getBookingFull(bookingId: string): Promise<WixGetBookingFullResponse>;",
|
|
7347
7319
|
"http": "GET /bookings/v1/bookings/{…}"
|
|
7348
7320
|
},
|
|
@@ -20549,16 +20521,16 @@
|
|
|
20549
20521
|
{
|
|
20550
20522
|
"name": "queryStoreProducts",
|
|
20551
20523
|
"kind": "function",
|
|
20552
|
-
"jsdoc": "",
|
|
20553
|
-
"decl": "export async function queryStoreProducts(limit = 50
|
|
20524
|
+
"jsdoc": "/** List products from whichever catalog this site runs. `fields` is additive — it\n * WIDENS the default v3 display fieldset rather than replacing it. */",
|
|
20525
|
+
"decl": "export async function queryStoreProducts(\n limit = 50,\n cursor?: string,\n fields?: readonly string[],\n): Promise<StoreProductsResponse>;",
|
|
20554
20526
|
"http": "POST /stores/v3/products/query"
|
|
20555
20527
|
},
|
|
20556
20528
|
{
|
|
20557
20529
|
"name": "getStoreProduct",
|
|
20558
20530
|
"kind": "function",
|
|
20559
|
-
"jsdoc": "",
|
|
20560
|
-
"decl": "export async function getStoreProduct(productId: string): Promise<StoreGetProductResponse>;",
|
|
20561
|
-
"http": "GET /stores/v3/products/{…}?
|
|
20531
|
+
"jsdoc": "/** Read one product from whichever catalog this site runs. `fields` is additive —\n * it WIDENS the default v3 display fieldset rather than replacing it. */",
|
|
20532
|
+
"decl": "export async function getStoreProduct(\n productId: string,\n fields?: readonly string[],\n): Promise<StoreGetProductResponse>;",
|
|
20533
|
+
"http": "GET /stores/v3/products/{…}?{…}"
|
|
20562
20534
|
},
|
|
20563
20535
|
{
|
|
20564
20536
|
"name": "productPrice",
|
|
@@ -20806,7 +20778,7 @@
|
|
|
20806
20778
|
"name": "StoreProduct",
|
|
20807
20779
|
"kind": "interface",
|
|
20808
20780
|
"jsdoc": "",
|
|
20809
|
-
"decl": "export interface StoreProduct {\n id?: string;\n name?: string;\n slug?: string;\n description?: string;\n plainDescription?: string;\n media?: {\n mainMedia?: WixMediaSlot;\n main?: WixMediaSlot;\n items?: WixMediaSlot[];\n };\n price?: { formatted?: { price?: string }; price?: number; currency?: string };\n priceData?: { formatted?: { price?: string }; price?: number; currency?: string };\n currency?: string;\n actualPriceRange?: {\n minValue?: { amount?: string; formattedAmount?: string; currency?: string };\n maxValue?: { amount?: string; formattedAmount?: string; currency?: string };\n };\n}"
|
|
20781
|
+
"decl": "export interface StoreProduct {\n id?: string;\n name?: string;\n slug?: string;\n description?: string;\n plainDescription?: string;\n /** Both gallery layouts: V1 `mainMedia`/`items`, V3 `main`/`itemsInfo.items`. */\n media?: {\n mainMedia?: WixMediaSlot;\n main?: WixMediaSlot;\n items?: WixMediaSlot[];\n itemsInfo?: { items?: WixMediaSlot[] };\n };\n price?: { formatted?: { price?: string }; price?: number; currency?: string };\n priceData?: { formatted?: { price?: string }; price?: number; currency?: string };\n currency?: string;\n actualPriceRange?: {\n minValue?: { amount?: string; formattedAmount?: string; currency?: string };\n maxValue?: { amount?: string; formattedAmount?: string; currency?: string };\n };\n}"
|
|
20810
20782
|
},
|
|
20811
20783
|
{
|
|
20812
20784
|
"name": "StoreProductsResponse",
|
|
@@ -20824,7 +20796,7 @@
|
|
|
20824
20796
|
"name": "StoreProductSearch",
|
|
20825
20797
|
"kind": "interface",
|
|
20826
20798
|
"jsdoc": "/** User-facing product discovery. V3 name search/sorting belong to Search\n * Products; Query Products deliberately does not support the name field.\n * V1 uses its documented JSON-string filter/sort dialect. */",
|
|
20827
|
-
"decl": "export interface StoreProductSearch {\n query?: string;\n sort?: 'default' | 'az' | 'za';\n ids?: string[];\n limit?: number;\n cursor?: string;\n}"
|
|
20799
|
+
"decl": "export interface StoreProductSearch {\n query?: string;\n sort?: 'default' | 'az' | 'za';\n ids?: string[];\n limit?: number;\n cursor?: string;\n /** Extra v3 fieldsets. Additive — widens the default, never replaces it. */\n fields?: readonly string[];\n}"
|
|
20828
20800
|
},
|
|
20829
20801
|
{
|
|
20830
20802
|
"name": "searchStoreProducts",
|
|
@@ -20839,6 +20811,12 @@
|
|
|
20839
20811
|
"jsdoc": "",
|
|
20840
20812
|
"decl": "export {\n wixMediaUrl,\n isUnsizedWixMedia,\n WIX_LIST_IMAGE,\n WIX_DETAIL_IMAGE,\n type WixImageSize,\n} from \"@himalaya/wix-media\";"
|
|
20841
20813
|
},
|
|
20814
|
+
{
|
|
20815
|
+
"name": "productGallery",
|
|
20816
|
+
"kind": "function",
|
|
20817
|
+
"jsdoc": "/**\n * EVERY image on the product, sized, in wire order — the gallery a detail screen\n * pages through, not just the one tile `productImage` returns.\n *\n * It reads both catalog layouts (V1 `media.items`, V3 `media.itemsInfo.items`) and\n * falls back to the primary image when the product carries no gallery, so a caller\n * always gets a non-empty list for a product that has any image at all. Empty slots\n * and duplicates are dropped.\n *\n * Exported because the gallery union was being re-derived by hand in ~10 template\n * workers, each free to miss a layout — which is exactly how a V3 store silently\n * lost its thumbnails. Defaults to the LIST budget like `productImage`; pass\n * `WIX_DETAIL_IMAGE` for a full-bleed pager, or `null` for the stored originals.\n */",
|
|
20818
|
+
"decl": "export function productGallery(p: StoreProduct, size: WixImageSize | null = WIX_LIST_IMAGE): string[];"
|
|
20819
|
+
},
|
|
20842
20820
|
{
|
|
20843
20821
|
"name": "plainText",
|
|
20844
20822
|
"kind": "function",
|
|
@@ -38,13 +38,14 @@ answers three questions:
|
|
|
38
38
|
> himi test --content . --json
|
|
39
39
|
> himi render home --content . --png home-light.png # one scheme per invocation
|
|
40
40
|
> himi render home --content . --scheme dark --png home-dark.png
|
|
41
|
-
> himi ux record --content . --platform ios --status unavailable --
|
|
42
|
-
> himi ux record --content . --platform android --status unavailable --
|
|
41
|
+
> himi ux record --content . --platform ios --status unavailable --reason "no simulator off-repo"
|
|
42
|
+
> himi ux record --content . --platform android --status unavailable --reason "no emulator off-repo"
|
|
43
43
|
> himi ux audit --content . --strict
|
|
44
44
|
> ```
|
|
45
45
|
>
|
|
46
|
-
> Use `--status passed` and
|
|
47
|
-
> `unavailable`
|
|
46
|
+
> Use `--status passed` and `--checks` naming what you actually drove when you did drive a device.
|
|
47
|
+
> An `unavailable` platform takes **no `--checks`** — nothing was driven, so there is nothing to
|
|
48
|
+
> list — and requires a `--reason`, which is the point: it records the gap rather than hiding it.
|
|
48
49
|
|
|
49
50
|
---
|
|
50
51
|
|
|
@@ -334,7 +334,7 @@ happened — or, honestly, that it could not.
|
|
|
334
334
|
```
|
|
335
335
|
himi ux audit --strict # the gate that fails on a missing per-platform record
|
|
336
336
|
himi ux record --content . --platform ios --status passed --checks back,keyboard,scroll
|
|
337
|
-
himi ux record --content . --platform ios --status unavailable --
|
|
337
|
+
himi ux record --content . --platform ios --status unavailable --reason "no simulator on this machine"
|
|
338
338
|
```
|
|
339
339
|
|
|
340
340
|
For the full tier ladder — which test tier observes which kind of change, and what a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.835.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": "28f3f50cd02d76203d4daf19d83865ed5be46f5158dc74ca6e1764b1"
|
|
67
67
|
}
|
|
@@ -3,7 +3,7 @@ import { defineService } from "@himalaya/state";
|
|
|
3
3
|
import { share as shareSheet } from "@himalaya/share";
|
|
4
4
|
import { addToCurrentCart, getCurrentCart } from "@himalaya/wix-ecom";
|
|
5
5
|
import { get, upsert, enqueue, type DbEntity } from "@himalaya/local-db";
|
|
6
|
-
import { getStoreProduct, plainText, productImage, productPrice, wixMediaUrl,
|
|
6
|
+
import { getStoreProduct, plainText, productImage, productPrice, wixMediaUrl, productGallery as sdkProductGallery, WIX_DETAIL_IMAGE, type StoreProduct } from "../_shared/himi-store.js";
|
|
7
7
|
import { cleanTitle } from "../_shared/himi-text.js";
|
|
8
8
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
9
9
|
import { isBridgeUnavailable } from "../_shared/owner-load-error.js";
|
|
@@ -96,11 +96,12 @@ export function productGallery(p: StoreProduct): GalleryItem[] {
|
|
|
96
96
|
// entry goes through the same CDN transform — the primary AND the extra media
|
|
97
97
|
// items, which would otherwise stay untouched 4000px originals.
|
|
98
98
|
push(productImage(p, WIX_DETAIL_IMAGE));
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
// The SDK helper reads BOTH gallery layouts — V1 `media.items` and Catalog V3
|
|
100
|
+
// `media.itemsInfo.items`. This loop used to walk `media.items` itself, which is
|
|
101
|
+
// the V1 spelling only, so a V3 product with a ten-image gallery rendered as one
|
|
102
|
+
// image no matter what the read asked for. One reader, not a private copy per
|
|
103
|
+
// worker — that is how the two layouts drifted apart in the first place.
|
|
104
|
+
for (const url of sdkProductGallery(p, WIX_DETAIL_IMAGE)) push(url);
|
|
104
105
|
return urls.map((url) => ({ url }));
|
|
105
106
|
}
|
|
106
107
|
|
|
@@ -3,7 +3,7 @@ import { defineService } from "@himalaya/state";
|
|
|
3
3
|
import { share as shareSheet } from "@himalaya/share";
|
|
4
4
|
import { addToCurrentCart, getCurrentCart } from "@himalaya/wix-ecom";
|
|
5
5
|
import { get, upsert, enqueue, type DbEntity } from "@himalaya/local-db";
|
|
6
|
-
import { getStoreProduct, plainText, productImage, productPrice, wixMediaUrl,
|
|
6
|
+
import { getStoreProduct, plainText, productImage, productPrice, wixMediaUrl, productGallery as sdkProductGallery, WIX_DETAIL_IMAGE, type StoreProduct } from "../_shared/himi-store.js";
|
|
7
7
|
import { cleanTitle } from "../_shared/himi-text.js";
|
|
8
8
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
9
9
|
import { isBridgeUnavailable } from "../_shared/owner-load-error.js";
|
|
@@ -96,11 +96,12 @@ export function productGallery(p: StoreProduct): GalleryItem[] {
|
|
|
96
96
|
// entry goes through the same CDN transform — the primary AND the extra media
|
|
97
97
|
// items, which would otherwise stay untouched 4000px originals.
|
|
98
98
|
push(productImage(p, WIX_DETAIL_IMAGE));
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
// The SDK helper reads BOTH gallery layouts — V1 `media.items` and Catalog V3
|
|
100
|
+
// `media.itemsInfo.items`. This loop used to walk `media.items` itself, which is
|
|
101
|
+
// the V1 spelling only, so a V3 product with a ten-image gallery rendered as one
|
|
102
|
+
// image no matter what the read asked for. One reader, not a private copy per
|
|
103
|
+
// worker — that is how the two layouts drifted apart in the first place.
|
|
104
|
+
for (const url of sdkProductGallery(p, WIX_DETAIL_IMAGE)) push(url);
|
|
104
105
|
return urls.map((url) => ({ url }));
|
|
105
106
|
}
|
|
106
107
|
|
|
@@ -3,7 +3,7 @@ import { defineService } from "@himalaya/state";
|
|
|
3
3
|
import { share as shareSheet } from "@himalaya/share";
|
|
4
4
|
import { addToCurrentCart, getCurrentCart } from "@himalaya/wix-ecom";
|
|
5
5
|
import { get, upsert, enqueue, type DbEntity } from "@himalaya/local-db";
|
|
6
|
-
import { getStoreProduct, plainText, productImage, productPrice, wixMediaUrl,
|
|
6
|
+
import { getStoreProduct, plainText, productImage, productPrice, wixMediaUrl, productGallery as sdkProductGallery, WIX_DETAIL_IMAGE, type StoreProduct } from "../_shared/himi-store.js";
|
|
7
7
|
import { cleanTitle } from "../_shared/himi-text.js";
|
|
8
8
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
9
9
|
import { isBridgeUnavailable } from "../_shared/owner-load-error.js";
|
|
@@ -96,11 +96,12 @@ export function productGallery(p: StoreProduct): GalleryItem[] {
|
|
|
96
96
|
// entry goes through the same CDN transform — the primary AND the extra media
|
|
97
97
|
// items, which would otherwise stay untouched 4000px originals.
|
|
98
98
|
push(productImage(p, WIX_DETAIL_IMAGE));
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
// The SDK helper reads BOTH gallery layouts — V1 `media.items` and Catalog V3
|
|
100
|
+
// `media.itemsInfo.items`. This loop used to walk `media.items` itself, which is
|
|
101
|
+
// the V1 spelling only, so a V3 product with a ten-image gallery rendered as one
|
|
102
|
+
// image no matter what the read asked for. One reader, not a private copy per
|
|
103
|
+
// worker — that is how the two layouts drifted apart in the first place.
|
|
104
|
+
for (const url of sdkProductGallery(p, WIX_DETAIL_IMAGE)) push(url);
|
|
104
105
|
return urls.map((url) => ({ url }));
|
|
105
106
|
}
|
|
106
107
|
|
|
@@ -1269,13 +1269,13 @@ const SCREENS = runtimeSetting({
|
|
|
1269
1269
|
"style": "primary",
|
|
1270
1270
|
"size": "sm",
|
|
1271
1271
|
"fullWidth": false,
|
|
1272
|
-
"accessibilityLabel": "Send",
|
|
1273
1272
|
"action": {
|
|
1274
1273
|
"actionId": "tier5.chat.send"
|
|
1275
1274
|
}
|
|
1276
1275
|
}
|
|
1277
1276
|
},
|
|
1278
1277
|
"modifiers": {
|
|
1278
|
+
"accessibilityLabel": "Send",
|
|
1279
1279
|
"hiddenPath": "$service:chat.busy"
|
|
1280
1280
|
}
|
|
1281
1281
|
},
|
|
@@ -1291,13 +1291,13 @@ const SCREENS = runtimeSetting({
|
|
|
1291
1291
|
"style": "primary",
|
|
1292
1292
|
"size": "sm",
|
|
1293
1293
|
"fullWidth": false,
|
|
1294
|
-
"accessibilityLabel": "Stop",
|
|
1295
1294
|
"action": {
|
|
1296
1295
|
"actionId": "tier5.chat.stop"
|
|
1297
1296
|
}
|
|
1298
1297
|
}
|
|
1299
1298
|
},
|
|
1300
1299
|
"modifiers": {
|
|
1300
|
+
"accessibilityLabel": "Stop",
|
|
1301
1301
|
"hiddenPath": "$service:chat.idle"
|
|
1302
1302
|
}
|
|
1303
1303
|
},
|
|
@@ -3,7 +3,7 @@ import { defineService } from "@himalaya/state";
|
|
|
3
3
|
import { share as shareSheet } from "@himalaya/share";
|
|
4
4
|
import { addToCurrentCart, getCurrentCart } from "@himalaya/wix-ecom";
|
|
5
5
|
import { get, upsert, enqueue, type DbEntity } from "@himalaya/local-db";
|
|
6
|
-
import { getStoreProduct, plainText, productImage, productPrice, wixMediaUrl,
|
|
6
|
+
import { getStoreProduct, plainText, productImage, productPrice, wixMediaUrl, productGallery as sdkProductGallery, WIX_DETAIL_IMAGE, type StoreProduct } from "../_shared/himi-store.js";
|
|
7
7
|
import { cleanTitle } from "../_shared/himi-text.js";
|
|
8
8
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
9
9
|
import { isBridgeUnavailable } from "../_shared/owner-load-error.js";
|
|
@@ -96,11 +96,12 @@ export function productGallery(p: StoreProduct): GalleryItem[] {
|
|
|
96
96
|
// entry goes through the same CDN transform — the primary AND the extra media
|
|
97
97
|
// items, which would otherwise stay untouched 4000px originals.
|
|
98
98
|
push(productImage(p, WIX_DETAIL_IMAGE));
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
// The SDK helper reads BOTH gallery layouts — V1 `media.items` and Catalog V3
|
|
100
|
+
// `media.itemsInfo.items`. This loop used to walk `media.items` itself, which is
|
|
101
|
+
// the V1 spelling only, so a V3 product with a ten-image gallery rendered as one
|
|
102
|
+
// image no matter what the read asked for. One reader, not a private copy per
|
|
103
|
+
// worker — that is how the two layouts drifted apart in the first place.
|
|
104
|
+
for (const url of sdkProductGallery(p, WIX_DETAIL_IMAGE)) push(url);
|
|
104
105
|
return urls.map((url) => ({ url }));
|
|
105
106
|
}
|
|
106
107
|
|
|
@@ -3,7 +3,7 @@ import { defineService } from "@himalaya/state";
|
|
|
3
3
|
import { share as shareSheet } from "@himalaya/share";
|
|
4
4
|
import { addToCurrentCart, getCurrentCart } from "@himalaya/wix-ecom";
|
|
5
5
|
import { get, upsert, enqueue, type DbEntity } from "@himalaya/local-db";
|
|
6
|
-
import { getStoreProduct, plainText, productImage, productPrice, wixMediaUrl,
|
|
6
|
+
import { getStoreProduct, plainText, productImage, productPrice, wixMediaUrl, productGallery as sdkProductGallery, WIX_DETAIL_IMAGE, type StoreProduct } from "../_shared/himi-store.js";
|
|
7
7
|
import { cleanTitle } from "../_shared/himi-text.js";
|
|
8
8
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
9
9
|
import { isBridgeUnavailable } from "../_shared/owner-load-error.js";
|
|
@@ -96,11 +96,12 @@ export function productGallery(p: StoreProduct): GalleryItem[] {
|
|
|
96
96
|
// entry goes through the same CDN transform — the primary AND the extra media
|
|
97
97
|
// items, which would otherwise stay untouched 4000px originals.
|
|
98
98
|
push(productImage(p, WIX_DETAIL_IMAGE));
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
// The SDK helper reads BOTH gallery layouts — V1 `media.items` and Catalog V3
|
|
100
|
+
// `media.itemsInfo.items`. This loop used to walk `media.items` itself, which is
|
|
101
|
+
// the V1 spelling only, so a V3 product with a ten-image gallery rendered as one
|
|
102
|
+
// image no matter what the read asked for. One reader, not a private copy per
|
|
103
|
+
// worker — that is how the two layouts drifted apart in the first place.
|
|
104
|
+
for (const url of sdkProductGallery(p, WIX_DETAIL_IMAGE)) push(url);
|
|
104
105
|
return urls.map((url) => ({ url }));
|
|
105
106
|
}
|
|
106
107
|
|