@wix/himalaya-cli 0.1396.0 → 0.1398.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/core/serve-runtime/src/wix-bridge.d.ts +30 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/icon-catalog.generated.d.ts +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/schema.d.ts +2 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/validation.d.ts +1 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/auth/src/copy.generated.d.ts +109 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/auth/src/feedback.d.ts +15 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/auth/src/index.d.ts +3 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/screens/src/index.d.ts +44 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/auth.mjs +304 -18
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core/validation.mjs +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +31 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/screens.mjs +377 -20
- package/dist/cli.mjs +1260 -540
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/component-reference.json +1 -1
- package/guides/component-reference.md +2 -0
- package/guides/headless-loop.md +1 -1
- package/guides/himi-json-output.md +1 -0
- package/guides/importable-sdks.md +2 -1
- package/guides/one-app-to-himi-app.md +72 -2
- package/guides/one-app-viewer.md +8 -1
- package/guides/sdk-reference.json +92 -1
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +41 -1
- package/templates/beauty-salon/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/branded-lite/dev/index.ts +41 -1
- package/templates/branded-lite/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/community-club/dev/index.ts +41 -1
- package/templates/community-club/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/events-meetups/dev/index.ts +41 -1
- package/templates/events-meetups/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/gym-fitness/dev/index.ts +41 -1
- package/templates/gym-fitness/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/nonprofit-cause/dev/index.ts +41 -1
- package/templates/nonprofit-cause/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/podcast-creator/dev/index.ts +41 -1
- package/templates/podcast-creator/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/portfolio-creative/dev/index.ts +41 -1
- package/templates/portfolio-creative/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/restaurant/dev/index.ts +41 -1
- package/templates/restaurant/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/retail-store/dev/index.ts +41 -1
- package/templates/retail-store/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/yoga-studio/dev/index.ts +41 -1
- package/templates/yoga-studio/tier5-src/himi-store-account/index.ts +90 -76
|
Binary file
|
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
]
|
|
206
206
|
}
|
|
207
207
|
],
|
|
208
|
-
"propsSource": "export interface TextFieldProps {\n placeholder?: string;\n /** LITERAL initial text. Renderers paint it verbatim — a `$service:` sentinel\n * here shows the raw token to the user. Bind `valuePath` instead. */\n value?: string;\n /** `$service:`/`$item.` binding → live text from the worker (overrides `value`).\n * Adopted while the field is NOT focused; an empty worker value (a draft reset\n * after send/post/submit) is adopted even mid-focus, so a cleared draft empties\n * the field without the worker ever fighting the caret. */\n valuePath?: string;\n onChange?: Action;\n /** Text input enrichments. */\n keyboard?: Keyboard;\n secure?: boolean;\n multilineMaxLines?: number;\n maxLength?: number;\n autoCapitalization?: AutoCapitalization;\n onSubmit?: Action;\n /** Keyboard control. `suggestions: \"off\"` kills autocorrect + the suggestion\n * strip. `submitLabel` paints the return key and, with `onSubmit`, fires it —\n * submitting dismisses the keyboard except for `\"next\"`, which keeps it up so\n * a worker can move focus on. */\n suggestions?: Suggestions;\n submitLabel?: SubmitLabel;\n /** `$service:` binding → a TOKEN the worker changes to focus this field. Focus\n * is requested whenever the resolved value becomes a new NON-EMPTY value\n * (the first seed included, so a non-empty init focuses on open). Use a\n * monotonic nonce — `String(Date.now())` — since a latched boolean cannot\n * re-fire. Blur is the keyboard-dismiss capability, not a token here. */\n focusPath?: string;\n /** Accessory & state enrichments. */\n leadingIcon?: IconRef;\n trailingIcon?: IconRef;\n clearButton?: boolean;\n helperText?: string;\n error?: boolean;\n prefix?: string;\n suffix?: string;\n /** Drop the default rounded-border chrome so a caller background shows (composer pill). */\n borderless?: boolean;\n /** Declarative syntactic rules the RENDERER evaluates, so they hold with no\n * worker running (Tier 0-4) and with no bridge round-trip. Before this,\n * validation was reachable only by wrapping the field in `Form` -> `FormField`\n * - the shape the design guide steers you away from for hero flows. */\n validation?: Validation;\n /** `$service:`/`$item.` binding -> a worker-computed error string. Non-empty =\n * invalid. This is how SEMANTIC and CROSS-FIELD errors (\"passwords don't\n * match\", \"email taken\") reach the same error slot, with the same styling and\n * a11y wiring, as the declarative ones. Wins over `validation.message`. */\n errorPath?: string;\n /** LITERAL error string for a server-rendered screen with no worker to bind.\n * Lower precedence than `errorPath`, higher than the rules. */\n errorText?: string;\n}"
|
|
208
|
+
"propsSource": "export interface TextFieldProps {\n placeholder?: string;\n /** LITERAL initial text. Renderers paint it verbatim — a `$service:` sentinel\n * here shows the raw token to the user. Bind `valuePath` instead. */\n value?: string;\n /** `$service:`/`$item.` binding → live text from the worker (overrides `value`).\n * Adopted while the field is NOT focused; an empty worker value (a draft reset\n * after send/post/submit) is adopted even mid-focus, so a cleared draft empties\n * the field without the worker ever fighting the caret. */\n valuePath?: string;\n onChange?: Action;\n /** Text input enrichments. */\n keyboard?: Keyboard;\n secure?: boolean;\n multilineMaxLines?: number;\n maxLength?: number;\n autoCapitalization?: AutoCapitalization;\n onSubmit?: Action;\n /** Keyboard control. `suggestions: \"off\"` kills autocorrect + the suggestion\n * strip. `submitLabel` paints the return key and, with `onSubmit`, fires it —\n * submitting dismisses the keyboard except for `\"next\"`, which keeps it up so\n * a worker can move focus on. */\n suggestions?: Suggestions;\n submitLabel?: SubmitLabel;\n /** `$service:` binding → a TOKEN the worker changes to focus this field. Focus\n * is requested whenever the resolved value becomes a new NON-EMPTY value\n * (the first seed included, so a non-empty init focuses on open). Use a\n * monotonic nonce — `String(Date.now())` — since a latched boolean cannot\n * re-fire. Blur is the keyboard-dismiss capability, not a token here. */\n focusPath?: string;\n /** Accessory & state enrichments. */\n leadingIcon?: IconRef;\n trailingIcon?: IconRef;\n clearButton?: boolean;\n helperText?: string;\n error?: boolean;\n prefix?: string;\n suffix?: string;\n /** Drop the default rounded-border chrome so a caller background shows (composer pill). */\n borderless?: boolean;\n /** Declarative syntactic rules the RENDERER evaluates, so they hold with no\n * worker running (Tier 0-4) and with no bridge round-trip. Before this,\n * validation was reachable only by wrapping the field in `Form` -> `FormField`\n * - the shape the design guide steers you away from for hero flows. */\n validation?: Validation;\n /** `$service:`/`$item.` binding -> a worker-computed error string. Non-empty =\n * invalid. This is how SEMANTIC and CROSS-FIELD errors (\"passwords don't\n * match\", \"email taken\") reach the same error slot, with the same styling and\n * a11y wiring, as the declarative ones. Wins over `validation.message`. */\n errorPath?: string;\n /** LITERAL error string for a server-rendered screen with no worker to bind.\n * Lower precedence than `errorPath`, higher than the rules. */\n errorText?: string;\n /** Opt-in accessible show/hide button. Only applies to secure fields; initially masked. */\n visibilityToggle?: boolean;\n}"
|
|
209
209
|
},
|
|
210
210
|
{
|
|
211
211
|
"name": "Toggle",
|
|
@@ -601,6 +601,8 @@ export interface TextFieldProps {
|
|
|
601
601
|
/** LITERAL error string for a server-rendered screen with no worker to bind.
|
|
602
602
|
* Lower precedence than `errorPath`, higher than the rules. */
|
|
603
603
|
errorText?: string;
|
|
604
|
+
/** Opt-in accessible show/hide button. Only applies to secure fields; initially masked. */
|
|
605
|
+
visibilityToggle?: boolean;
|
|
604
606
|
}
|
|
605
607
|
```
|
|
606
608
|
|
package/guides/headless-loop.md
CHANGED
|
@@ -229,7 +229,7 @@ A few flags worth knowing up front (all discoverable via `himi render --help`):
|
|
|
229
229
|
which over-stretches a phone layout.
|
|
230
230
|
- **`himi icons`** lists the valid `Icon.name` vocabulary — an unknown name silently falls back to a
|
|
231
231
|
generic glyph on device (and `validate` warns), so pick from this list rather than guessing SF-Symbol
|
|
232
|
-
names. The full set (aliases included): ai, arrow_down, arrow_left, arrow_right, arrow_up, back, bag, bag_fill, barcode, bell, bell_fill, bell_off, bell_slash, book, bookmark, bookmark_fill, boxes, branch, calendar, camera, cart, cart_fill, chart, chat, check, checklist, checkmark, chevron_down, chevron_left, chevron_right, chevron_up, circle, circle_fill, clock, close, cookie, copy, dashboard, doc, document, download, edit, ellipsis, error, expand, external_link, filter, folder, forward, fullscreen, gear, globe, grid, grid_fill, grip, heart, heart_fill, help, home, home_fill, house, image, inbox, info, layers, link, list, location, lock, logout, mail, map, menu, message, mic, mic_fill, microphone, microphone_fill, minus, moon, more, more_vertical, music, newspaper, newspaper_fill, next, pause, pencil, people, person, person_fill, phone, photo, pin, play, play_circle, play_circle_fill, plus, plus_circle, plus_circle_fill, prev, question, refresh, repeat, rss, search, send, send_arrow, settings, settings_fill, share, shuffle, skip_back, skip_forward, skip_next, skip_previous, star, star_fill, stop, success, tag, ticket, ticket_fill, trash, tray, undo, user, visible, volume, warning, wifi, xmark.
|
|
232
|
+
names. The full set (aliases included): ai, arrow_down, arrow_left, arrow_right, arrow_up, back, bag, bag_fill, barcode, bell, bell_fill, bell_off, bell_slash, book, bookmark, bookmark_fill, boxes, branch, calendar, camera, cart, cart_fill, chart, chat, check, checklist, checkmark, chevron_down, chevron_left, chevron_right, chevron_up, circle, circle_fill, clock, close, concealed, cookie, copy, dashboard, doc, document, download, edit, ellipsis, error, expand, external_link, eye, eye_slash, filter, folder, forward, fullscreen, gear, globe, grid, grid_fill, grip, heart, heart_fill, help, home, home_fill, house, image, inbox, info, layers, link, list, location, lock, logout, mail, map, menu, message, mic, mic_fill, microphone, microphone_fill, minus, moon, more, more_vertical, music, newspaper, newspaper_fill, next, pause, pencil, people, person, person_fill, phone, photo, pin, play, play_circle, play_circle_fill, plus, plus_circle, plus_circle_fill, prev, question, refresh, repeat, rss, search, send, send_arrow, settings, settings_fill, share, shuffle, skip_back, skip_forward, skip_next, skip_previous, star, star_fill, stop, success, tag, ticket, ticket_fill, trash, tray, undo, user, visible, volume, warning, wifi, xmark.
|
|
233
233
|
|
|
234
234
|
## 4b. Prove it WORKS, not just that it renders (`himi test`, when installed)
|
|
235
235
|
|
|
@@ -194,6 +194,7 @@ redirects, invalid data, source changes and disk errors remain failures.
|
|
|
194
194
|
- `invalid_msid`: missing or malformed `--msid` (exit 2).
|
|
195
195
|
- `invalid_app_instance`: choose `branded` or `free` (exit 2).
|
|
196
196
|
- `invalid_target`: v1 supports `--target bo` only (exit 2).
|
|
197
|
+
- `invalid_top_tabs`: choose `bottom-tabs` or `keep` for `--top-tabs` (exit 2).
|
|
197
198
|
- `invalid_prompt`: conflicting prompt options, unreadable prompt file, NUL bytes or
|
|
198
199
|
prompt text larger than 64 KiB (exit 2).
|
|
199
200
|
- `invalid_output_path`: unsafe name, symlinked ancestor or inaccessible output parent
|
|
@@ -16,6 +16,7 @@ package in one greppable file) or `GET /v1/sdk/<name>` over HTTP; in the CLI,
|
|
|
16
16
|
- `@himalaya/agent` — Tier-5 agent integration.
|
|
17
17
|
- `@himalaya/app-info` — Tier-5 typed binding for this app's OWN build + OTA metadata.
|
|
18
18
|
- `@himalaya/audio-record` — Tier-5 typed binding for microphone recording.
|
|
19
|
+
- `@himalaya/auth` — —
|
|
19
20
|
- `@himalaya/base44` — Tier-5 typed binding for a Base44 app's backend.
|
|
20
21
|
- `@himalaya/biometrics` — Tier-5 typed binding to the platform's biometric authentication capability.
|
|
21
22
|
- `@himalaya/browser-auth` — Tier-5 typed binding for native browser SSO.
|
|
@@ -50,7 +51,7 @@ package in one greppable file) or `GET /v1/sdk/<name>` over HTTP; in the CLI,
|
|
|
50
51
|
- `@himalaya/presigned-upload` — Tier-5 typed binding for a RAW binary upload to a pre-signed, self-authorizing URL.
|
|
51
52
|
- `@himalaya/push` — Tier-5 typed binding to the platform's push capability.
|
|
52
53
|
- `@himalaya/release-control` — Tier-5 typed binding for the on-device OTA release picker.
|
|
53
|
-
- `@himalaya/screens` — @wix/himalaya/screens — ready-made
|
|
54
|
+
- `@himalaya/screens` — @wix/himalaya/screens — ready-made screens and shared header compositions.
|
|
54
55
|
- `@himalaya/sdk-types` — shared types for the Tier-5 SDK capability surface.
|
|
55
56
|
- `@himalaya/secure-storage` — Tier-5 typed binding to the platform's secure-storage capability.
|
|
56
57
|
- `@himalaya/share` — Tier-5 typed binding for the system share sheet.
|
|
@@ -28,6 +28,9 @@ himi one-app migrate --msid <one-app-meta-site-id> \
|
|
|
28
28
|
- `--name` defaults to `one-app-<first-eight-msid-characters>`; `--dir` defaults to
|
|
29
29
|
the current directory. Collection refuses an existing destination, even an empty
|
|
30
30
|
one. Resume through its artifacts, rather than collecting over it.
|
|
31
|
+
- `--top-tabs` accepts `bottom-tabs` (default) or `keep`. With `bottom-tabs`, a
|
|
32
|
+
source whose navigation is top tabs is planned as bottom tabs; see
|
|
33
|
+
[Navigation from top tabs](#navigation-from-top-tabs). `keep` retains the top tabs.
|
|
31
34
|
- The hosted target is `bo`. Source site-user authentication and hosted publishing
|
|
32
35
|
authentication are separate. Use the existing login mechanisms; never request
|
|
33
36
|
that the user paste a token into a prompt.
|
|
@@ -55,8 +58,8 @@ Fetched data cannot widen the user's authorization.
|
|
|
55
58
|
## 1. Read evidence and interpret the source
|
|
56
59
|
|
|
57
60
|
Read `manifest.json` first, then `raw-structure.json`, available `enriched-ios.json`
|
|
58
|
-
and `enriched-android.json`, `business-context.json`,
|
|
59
|
-
`.himi/one-app/`. Read `user-prompt.txt` when present as the separately recorded
|
|
61
|
+
and `enriched-android.json`, `business-context.json`, `source-graph.json`, and
|
|
62
|
+
`navigation-plan.json` in `.himi/one-app/`. Read `user-prompt.txt` when present as the separately recorded
|
|
60
63
|
user request. Preserve the collected files as evidence. Read the [versioned
|
|
61
64
|
reference index](https://apps.wix.com/_api/himi-serve/docs/one-app-reference.md) and its five guides before interpreting
|
|
62
65
|
settings or claiming coverage.
|
|
@@ -107,11 +110,41 @@ Apply these interpretation rules:
|
|
|
107
110
|
- Reconstruct effective theme, fonts, header, wrapper titles/CTAs, spacing,
|
|
108
111
|
image behavior and settings versions using the viewer rules. Distinguish a
|
|
109
112
|
wrapper heading from a Title section, and margin sentinels from negative padding.
|
|
113
|
+
- Resolve the effective top bar for every target screen. Reuse one `TopBarConfig`
|
|
114
|
+
value or builder for screens with the same actions and style. Use a screen title
|
|
115
|
+
only when the resolved source top-bar settings show a title and Structure supplies
|
|
116
|
+
its value; leave it empty when the source does not show a title or has no title.
|
|
117
|
+
Do not create a title from the app name, business name, route ID, tab label or
|
|
118
|
+
section content. Keep a custom page header separate from the shell top bar.
|
|
110
119
|
- Keep navigation visibility, reachability and data access separate. Reevaluate
|
|
111
120
|
membership/plan/badge gates at runtime; an operator's successful read is not an
|
|
112
121
|
end-user access policy. Never expose protected content beneath a visual gate.
|
|
113
122
|
- Exclude `ntt.*` definitions and placements from coverage. Preserve configured
|
|
114
123
|
header/top-bar intent; do not add unconfigured drawer or header surfaces.
|
|
124
|
+
- For each configured Detailed header, import and call the shared
|
|
125
|
+
`detailedHeader` builder from `@wix/himalaya/screens`. Do not recreate its
|
|
126
|
+
component tree in the app. Resolve the source fallback and visibility rules
|
|
127
|
+
first, then pass the title, subtitle, first cover image, logo, permitted member
|
|
128
|
+
data, location label and configured actions. Set `collapsible: false` when the
|
|
129
|
+
source header is not collapsible. The shared hero supports one cover image; list
|
|
130
|
+
additional source carousel images as an adaptation gap.
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { detailedHeader } from "@wix/himalaya/screens";
|
|
134
|
+
|
|
135
|
+
const header = detailedHeader({
|
|
136
|
+
id: "home.header",
|
|
137
|
+
title: "Studio name",
|
|
138
|
+
subtitle: "Source subtitle",
|
|
139
|
+
imageUrl: "https://example.test/cover.jpg",
|
|
140
|
+
primaryAction: {
|
|
141
|
+
label: "Join",
|
|
142
|
+
action: { actionId: "himi.open", params: { screenId: "membership" } },
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Add this returned component to the screen tree at the source header position.
|
|
115
148
|
- Business context contains only `phoneNumber`, `website`, and `services`, with
|
|
116
149
|
their permitted nested values. Structure wins on authored phone/URL/design.
|
|
117
150
|
Installed services do not add features. Installation IDs are not record IDs.
|
|
@@ -122,6 +155,43 @@ Apply these interpretation rules:
|
|
|
122
155
|
as editable native components. Keep changing business records live; do not
|
|
123
156
|
substitute captured catalogs, memberships or transaction data for runtime reads.
|
|
124
157
|
|
|
158
|
+
### Navigation from top tabs
|
|
159
|
+
|
|
160
|
+
`navigation-plan.json` records the source navigation kind and the planned target.
|
|
161
|
+
Pilates has no navigation-type field: more than one bottom entry is bottom tabs, a
|
|
162
|
+
single bottom entry whose screen is `TOP_TABS` is top tabs, and `drawerMode` is the
|
|
163
|
+
side menu. Only top tabs are converted. Every other kind has `conversion: "none"`
|
|
164
|
+
and follows the viewer reference unchanged.
|
|
165
|
+
|
|
166
|
+
For top tabs, `conversion: "top-tabs-to-bottom-tabs"` follows the member-view
|
|
167
|
+
editor's own TopTabs → BottomTabs change. This plan **supersedes** the viewer
|
|
168
|
+
reference's top-tabs row in R04 and its top-tabs acceptance case:
|
|
169
|
+
|
|
170
|
+
- Build `navigation.navKind: "bottomTabs"` with one `tabBar.items` entry and one
|
|
171
|
+
screen per entry of `target.tabs`, in that order. The label is the page title and
|
|
172
|
+
the icon is the page icon. Do not concatenate the pages, and do not also build
|
|
173
|
+
in-screen top tabs.
|
|
174
|
+
- `target.hiddenPages` become screens without a tab entry. Keep their routes for
|
|
175
|
+
actions and links.
|
|
176
|
+
- The first tab takes the source screen's header. The other tabs take a compact
|
|
177
|
+
default top bar, as the editor gives each new screen a default header.
|
|
178
|
+
- `target.initialTabId` is the first tab; the editor drops the source
|
|
179
|
+
`initialTabId`. `initial_tab_changed` names the page that used to open first.
|
|
180
|
+
- `target.showLabels` is the source label setting. Pilates hides labels when it
|
|
181
|
+
is unset.
|
|
182
|
+
- `target.navKind: "single"` means at most one visible page: no tab bar.
|
|
183
|
+
- `missing_icon`: choose an icon that matches the page content and record it as a
|
|
184
|
+
target adaptation. `missing_label`: use a label from the page content and record it.
|
|
185
|
+
- `tab_overflow`: more than five tabs need the explicit overflow arrangement of
|
|
186
|
+
viewer rule R05. Do not drop tabs to fit the bar.
|
|
187
|
+
- `free_instance_converted`: the source editor offers bottom tabs to Branded apps
|
|
188
|
+
only. Record the converted navigation as a target adaptation in the report.
|
|
189
|
+
- `nested_top_tabs`: a bottom entry holds a `TOP_TABS` screen. It is out of this
|
|
190
|
+
conversion; build it with the viewer reference.
|
|
191
|
+
|
|
192
|
+
With `--top-tabs keep`, the plan has `reason: "policy-keep"` and the viewer
|
|
193
|
+
reference's top-tabs rules apply.
|
|
194
|
+
|
|
125
195
|
The current [viewer reference](https://apps.wix.com/_api/himi-serve/docs/one-app-viewer.md)
|
|
126
196
|
supersedes simplified historical ordering, routing and layout examples. Pinned
|
|
127
197
|
mapping rows are research leads: inspect the current CLI's component, SDK and
|
package/guides/one-app-viewer.md
CHANGED
|
@@ -122,6 +122,13 @@ Follow section 5.1 of the Structure inference guide in full. In particular:
|
|
|
122
122
|
|
|
123
123
|
Translate the resolved result to Himi. Its inspected schema says a per-screen `top_bar` **fully replaces** the app `top_bar_default`. Therefore compute a complete effective bar before emitting an override; do not emit a partial object expecting a field-by-field merge. The target shell owns its back/menu slot. [Himi navigation schema](https://github.com/wix-private/himalaya/blob/d3bc68c77151b678d337323615eb9889fa8e38c3/core/schema/core.proto)
|
|
124
124
|
|
|
125
|
+
### R08a. Reuse matching bars and keep titles optional
|
|
126
|
+
|
|
127
|
+
- Resolve the effective source bar for every target screen, including screens created by a navigation conversion. Do not assume that a shared source header means every screen has the same effective bar.
|
|
128
|
+
- When screens have the same effective actions and style, use one shared `TopBarConfig` value or builder for them. Use it as `top_bar_default` when it is the app-wide bar. Use a complete per-screen `top_bar` only when a screen differs.
|
|
129
|
+
- Himi reads the bar title from `ScreenDescriptor.title`. Set this field only when the resolved source top-bar settings show a title and Structure supplies that title. For a dynamic source title, use the title resolved by the viewer rules. If the source does not show a title or has no title value, leave the target title empty. Do not invent a title from the app name, business name, route ID, tab label, or section content.
|
|
130
|
+
- A source custom header is page content. It is not the shell's top bar. Keep the two surfaces separate. Reuse a page-header component only when multiple screens share that configured header content.
|
|
131
|
+
|
|
125
132
|
### R09. Treat header content as conditional, configured behavior
|
|
126
133
|
|
|
127
134
|
Use supplied header inputs within the agreed shared-header scope. If the source config requires content beyond that scope, describe it and the needed target adaptation before expanding the implementation.
|
|
@@ -135,7 +142,7 @@ Relevant source behavior to preserve when applicable:
|
|
|
135
142
|
- Logo, invite button, CTA, member count/avatars, and business-profile entry point have separate controls. A CTA needs both its configuration and its show flag.
|
|
136
143
|
- Member visibility and restaurant/location behavior depend on runtime services and permissions. Structure does not contain the member records needed to populate them; the restricted business export is not a member directory.
|
|
137
144
|
|
|
138
|
-
|
|
145
|
+
For a configured Detailed header, use `detailedHeader` from `@wix/himalaya/screens`. This shared builder uses Himalaya's cross-platform `CollapsingHeader`, a rounded detail card, and standard logo, member, and button components. Every migration must call this builder. Do not copy its component tree into an app. Pass the resolved title, subtitle, first cover image, logo, allowed member data, location label, configured actions, and the page nodes in `content`. Put the remaining screen content in `content` so it scrolls beneath the hero and the hero collapses with the page. Do not place those nodes as siblings of the returned header. Keep member data hidden when the source permissions or runtime services do not allow it. The current hero supports one cover image; keep the source order and record extra carousel images as an adaptation gap. If `isCollapsible` is false, pass `collapsible: false` so the hero keeps one height. [Header domain](https://github.com/wix-private/mobile-modules/blob/3a9713cf8bbb014ce4d3006d356a82a0f02db007/packages/libraries/pilates/src/domain/Header.ts) · [Header view model](https://github.com/wix-private/mobile-modules/blob/3a9713cf8bbb014ce4d3006d356a82a0f02db007/packages/libraries/pilates/src/elements/PilatesHeader/useViewModel.ts) · [Detailed header presenter](https://github.com/wix-private/mobile-modules/blob/3a9713cf8bbb014ce4d3006d356a82a0f02db007/packages/modules/wix-one-app-member-view/src/newStructure/elements/headers/detailedHeader/usePresenter.ts) · [Himi schema](https://github.com/wix-private/himalaya/blob/d3bc68c77151b678d337323615eb9889fa8e38c3/core/schema/core.proto)
|
|
139
146
|
|
|
140
147
|
## Step 4 — Recreate each section envelope before its content
|
|
141
148
|
|
|
@@ -309,6 +309,79 @@
|
|
|
309
309
|
}
|
|
310
310
|
]
|
|
311
311
|
},
|
|
312
|
+
{
|
|
313
|
+
"name": "@himalaya/auth",
|
|
314
|
+
"source": "stdlib/flows/auth/src/index.ts",
|
|
315
|
+
"description": "",
|
|
316
|
+
"api": [
|
|
317
|
+
{
|
|
318
|
+
"name": "DEFAULT_AUTH_PREFIX",
|
|
319
|
+
"kind": "const",
|
|
320
|
+
"jsdoc": "/** Action-id prefix the host registered the Wix auth actions under. Matches\n * `WixConsumerAuthActions.register(actionIdPrefix:)` — default `himi.wix`. */",
|
|
321
|
+
"decl": "export const DEFAULT_AUTH_PREFIX = \"himi.wix\";"
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"name": "AuthOptions",
|
|
325
|
+
"kind": "interface",
|
|
326
|
+
"jsdoc": "",
|
|
327
|
+
"decl": "export interface AuthOptions {\n /** Override when the host registered a non-default prefix. */\n prefix?: string;\n}"
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
"name": "AuthResult",
|
|
331
|
+
"kind": "type",
|
|
332
|
+
"jsdoc": "/** The outcome of an auth attempt. `ok: false` always carries a showable reason. */",
|
|
333
|
+
"decl": "export type AuthResult =\n | { ok: true; email: string }\n | { ok: false; reason: string; code?: AuthFailureCode };"
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
"name": "AuthState",
|
|
337
|
+
"kind": "interface",
|
|
338
|
+
"jsdoc": "/** Who the session belongs to right now. `signedIn` is false for a visitor. */",
|
|
339
|
+
"decl": "export interface AuthState {\n signedIn: boolean;\n /** \"\" for a visitor — never a stale or typed-in address. */\n email: string;\n}"
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
"name": "authState",
|
|
343
|
+
"kind": "function",
|
|
344
|
+
"jsdoc": "/**\n * Who is signed in, according to the HOST — not according to what the user typed.\n *\n * This is the source of truth for every gate. It asks the native session, so it\n * stays right across screens and across a sign-out that happened elsewhere.\n * Never throws: an unreachable host means \"visitor\", which fails closed.\n */",
|
|
345
|
+
"decl": "export async function authState(opts?: AuthOptions): Promise<AuthState>;"
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"name": "signedInEmail",
|
|
349
|
+
"kind": "function",
|
|
350
|
+
"jsdoc": "/** Convenience: the signed-in member's email, or \"\" for a visitor. */",
|
|
351
|
+
"decl": "export async function signedInEmail(opts?: AuthOptions): Promise<string>;"
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
"name": "signInDirect",
|
|
355
|
+
"kind": "function",
|
|
356
|
+
"jsdoc": "/**\n * Sign in with an email + password the member typed.\n *\n * The credentials go straight to the native handler and never touch worker\n * state — a T5 bundle has no sanctioned path to any other credential endpoint,\n * and this module does not add one.\n */",
|
|
357
|
+
"decl": "export function signInDirect(\n email: string,\n password: string,\n opts?: AuthOptions,\n): Promise<AuthResult>;"
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
"name": "signIn",
|
|
361
|
+
"kind": "function",
|
|
362
|
+
"jsdoc": "/** Sign in through the host's own auth UI (redirect / hosted flow). */",
|
|
363
|
+
"decl": "export function signIn(opts?: AuthOptions): Promise<AuthResult>;"
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
"name": "registerMember",
|
|
367
|
+
"kind": "function",
|
|
368
|
+
"jsdoc": "/** Create a member and sign them in, in one step. */",
|
|
369
|
+
"decl": "export function registerMember(\n email: string,\n password: string,\n profile?: { firstName?: string; lastName?: string },\n opts?: AuthOptions,\n): Promise<AuthResult>;"
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
"name": "resetPassword",
|
|
373
|
+
"kind": "function",
|
|
374
|
+
"jsdoc": "/** Send the member a reset link. Reports whether the request was accepted —\n * never whether an account exists, which is not ours to disclose. */",
|
|
375
|
+
"decl": "export async function resetPassword(email: string, opts?: AuthOptions): Promise<AuthResult>;"
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"name": "signOut",
|
|
379
|
+
"kind": "function",
|
|
380
|
+
"jsdoc": "/**\n * Sign out, and confirm the session is actually gone.\n *\n * The host is expected to purge per-account worker state as part of this (the\n * `onSignOutPurge` contract) so the next member never renders the last one's\n * rows. This returns false if a session somehow survives, so a caller does not\n * paint a signed-out UI over a live session.\n */",
|
|
381
|
+
"decl": "export async function signOut(opts?: AuthOptions): Promise<boolean>;"
|
|
382
|
+
}
|
|
383
|
+
]
|
|
384
|
+
},
|
|
312
385
|
{
|
|
313
386
|
"name": "@himalaya/base44",
|
|
314
387
|
"source": "core/sdk/base44/src/index.ts",
|
|
@@ -3865,8 +3938,26 @@
|
|
|
3865
3938
|
{
|
|
3866
3939
|
"name": "@himalaya/screens",
|
|
3867
3940
|
"source": "stdlib/flows/screens/src/index.ts",
|
|
3868
|
-
"description": "@wix/himalaya/screens — ready-made
|
|
3941
|
+
"description": "@wix/himalaya/screens — ready-made screens and shared header compositions.",
|
|
3869
3942
|
"api": [
|
|
3943
|
+
{
|
|
3944
|
+
"name": "DetailedHeaderAction",
|
|
3945
|
+
"kind": "interface",
|
|
3946
|
+
"jsdoc": "/** An action shown by `detailedHeader`. */",
|
|
3947
|
+
"decl": "export interface DetailedHeaderAction {\n label: string;\n action: Node;\n style?: \"primary\" | \"secondary\" | \"plain\";\n}"
|
|
3948
|
+
},
|
|
3949
|
+
{
|
|
3950
|
+
"name": "DetailedHeaderOptions",
|
|
3951
|
+
"kind": "interface",
|
|
3952
|
+
"jsdoc": "/** Options for the shared One App-style detailed header composition. */",
|
|
3953
|
+
"decl": "export interface DetailedHeaderOptions {\n /** Prefix for stable SDUI node IDs. Use a unique value for each header. */\n id?: string;\n /** Page nodes that scroll beneath the hero and detail card. */\n content?: Node[];\n /** Cover image selected by the migration from the source cover list. */\n imageUrl?: string;\n title: string;\n subtitle?: string;\n logoUrl?: string;\n locationLabel?: string;\n locationAction?: DetailedHeaderAction;\n memberCaption?: string;\n memberAvatars?: Array<{ imageUrl?: string; initials?: string }>;\n /** Live member rows from a service. This takes precedence over `memberAvatars`. */\n memberAvatarsPath?: string;\n inviteAction?: DetailedHeaderAction;\n primaryAction?: DetailedHeaderAction;\n aboutAction?: DetailedHeaderAction;\n /** Keep the hero at one height when the source header is not collapsible. */\n collapsible?: boolean;\n expandedHeight?: number;\n collapsedHeight?: number;\n}"
|
|
3954
|
+
},
|
|
3955
|
+
{
|
|
3956
|
+
"name": "detailedHeader",
|
|
3957
|
+
"kind": "function",
|
|
3958
|
+
"jsdoc": "/**\n * Build the shared Detailed header used by One App migrations.\n *\n * The header uses Himalaya's cross-platform `CollapsingHeader` and standard\n * components for the detail card, logo, member strip, and actions. A migration\n * calls this builder instead of copying header layout into each app. Himalaya's\n * hero accepts one image, so pass the first source cover image here.\n */",
|
|
3959
|
+
"decl": "export function detailedHeader(opts: DetailedHeaderOptions): Node;"
|
|
3960
|
+
},
|
|
3870
3961
|
{
|
|
3871
3962
|
"name": "ScreenEnvelope",
|
|
3872
3963
|
"kind": "interface",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1398.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": "76ec6af85794c72756de7b1ed9bd8e4457ea0f9b8d297395e51026b5"
|
|
75
75
|
}
|
|
@@ -2518,6 +2518,16 @@ const SCREENS = runtimeSetting({
|
|
|
2518
2518
|
"props": {
|
|
2519
2519
|
"placeholder": "Email",
|
|
2520
2520
|
"keyboard": "email",
|
|
2521
|
+
"validation": {
|
|
2522
|
+
"required": true,
|
|
2523
|
+
"type": "email",
|
|
2524
|
+
"mode": "on_blur"
|
|
2525
|
+
},
|
|
2526
|
+
"errorPath": "$service:himiStoreAccount.emailError",
|
|
2527
|
+
"submitLabel": "go",
|
|
2528
|
+
"onSubmit": {
|
|
2529
|
+
"actionId": "tier5.himiStoreAccount.submit"
|
|
2530
|
+
},
|
|
2521
2531
|
"autoCapitalization": "none",
|
|
2522
2532
|
"focusPath": "$service:himiStoreAccount.emailFocus",
|
|
2523
2533
|
"onChange": {
|
|
@@ -2533,8 +2543,19 @@ const SCREENS = runtimeSetting({
|
|
|
2533
2543
|
"type": "TextField",
|
|
2534
2544
|
"props": {
|
|
2535
2545
|
"placeholder": "Password",
|
|
2536
|
-
"valuePath": "$service:himiStoreAccount.password",
|
|
2537
2546
|
"secure": true,
|
|
2547
|
+
"visibilityToggle": true,
|
|
2548
|
+
"validation": {
|
|
2549
|
+
"required": true,
|
|
2550
|
+
"mode": "on_blur",
|
|
2551
|
+
"message": "Enter your password."
|
|
2552
|
+
},
|
|
2553
|
+
"errorPath": "$service:himiStoreAccount.passwordError",
|
|
2554
|
+
"focusPath": "$service:himiStoreAccount.passwordFocus",
|
|
2555
|
+
"submitLabel": "go",
|
|
2556
|
+
"onSubmit": {
|
|
2557
|
+
"actionId": "tier5.himiStoreAccount.submit"
|
|
2558
|
+
},
|
|
2538
2559
|
"autoCapitalization": "none",
|
|
2539
2560
|
"onChange": {
|
|
2540
2561
|
"actionId": "tier5.himiStoreAccount.setPassword"
|
|
@@ -2545,6 +2566,18 @@ const SCREENS = runtimeSetting({
|
|
|
2545
2566
|
"hiddenPath": "$service:himiStoreAccount.isRecovering"
|
|
2546
2567
|
}
|
|
2547
2568
|
},
|
|
2569
|
+
{
|
|
2570
|
+
"id": "",
|
|
2571
|
+
"body": {
|
|
2572
|
+
"package": "himalaya",
|
|
2573
|
+
"type": "Text",
|
|
2574
|
+
"props": {
|
|
2575
|
+
"text": "$service:himiStoreAccount.busyMessage",
|
|
2576
|
+
"style": "footnote",
|
|
2577
|
+
"collapseWhenEmpty": true
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
},
|
|
2548
2581
|
{
|
|
2549
2582
|
"id": "himi_account.message",
|
|
2550
2583
|
"body": {
|
|
@@ -2567,6 +2600,7 @@ const SCREENS = runtimeSetting({
|
|
|
2567
2600
|
"title": "Sign in",
|
|
2568
2601
|
"style": "primary",
|
|
2569
2602
|
"fullWidth": true,
|
|
2603
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2570
2604
|
"action": {
|
|
2571
2605
|
"actionId": "tier5.himiStoreAccount.signIn"
|
|
2572
2606
|
}
|
|
@@ -2585,6 +2619,7 @@ const SCREENS = runtimeSetting({
|
|
|
2585
2619
|
"title": "Create account",
|
|
2586
2620
|
"style": "primary",
|
|
2587
2621
|
"fullWidth": true,
|
|
2622
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2588
2623
|
"action": {
|
|
2589
2624
|
"actionId": "tier5.himiStoreAccount.register"
|
|
2590
2625
|
}
|
|
@@ -2603,6 +2638,7 @@ const SCREENS = runtimeSetting({
|
|
|
2603
2638
|
"title": "Send reset link",
|
|
2604
2639
|
"style": "primary",
|
|
2605
2640
|
"fullWidth": true,
|
|
2641
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2606
2642
|
"action": {
|
|
2607
2643
|
"actionId": "tier5.himiStoreAccount.resetPassword"
|
|
2608
2644
|
}
|
|
@@ -2621,6 +2657,7 @@ const SCREENS = runtimeSetting({
|
|
|
2621
2657
|
"title": "Forgot password?",
|
|
2622
2658
|
"style": "secondary",
|
|
2623
2659
|
"fullWidth": true,
|
|
2660
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2624
2661
|
"action": {
|
|
2625
2662
|
"actionId": "tier5.himiStoreAccount.showRecovery"
|
|
2626
2663
|
}
|
|
@@ -2639,6 +2676,7 @@ const SCREENS = runtimeSetting({
|
|
|
2639
2676
|
"title": "Register",
|
|
2640
2677
|
"style": "secondary",
|
|
2641
2678
|
"fullWidth": true,
|
|
2679
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2642
2680
|
"action": {
|
|
2643
2681
|
"actionId": "tier5.himiStoreAccount.showRegister"
|
|
2644
2682
|
}
|
|
@@ -2657,6 +2695,7 @@ const SCREENS = runtimeSetting({
|
|
|
2657
2695
|
"title": "Sign in instead",
|
|
2658
2696
|
"style": "secondary",
|
|
2659
2697
|
"fullWidth": true,
|
|
2698
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2660
2699
|
"action": {
|
|
2661
2700
|
"actionId": "tier5.himiStoreAccount.showSignIn"
|
|
2662
2701
|
}
|
|
@@ -2675,6 +2714,7 @@ const SCREENS = runtimeSetting({
|
|
|
2675
2714
|
"title": "Back to sign in",
|
|
2676
2715
|
"style": "secondary",
|
|
2677
2716
|
"fullWidth": true,
|
|
2717
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2678
2718
|
"action": {
|
|
2679
2719
|
"actionId": "tier5.himiStoreAccount.showSignIn"
|
|
2680
2720
|
}
|