@wix/himalaya-cli 0.1564.0 → 0.1566.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/flows/screens/src/index.d.ts +4 -4
- package/dist/cli.mjs +51 -3
- package/guides/iap-screen-adoption.md +6 -3
- package/guides/one-app-to-himi-app.md +34 -27
- package/guides/one-app-viewer.md +5 -3
- package/guides/sdk-reference.json +1 -1
- package/package.json +2 -2
- package/templates/beauty-salon/tier5-src/himi-store-account/index.ts +6 -3
- package/templates/branded-lite/tier5-src/himi-store-account/index.ts +6 -3
- package/templates/community-club/tier5-src/himi-store-account/index.ts +6 -3
- package/templates/events-meetups/tier5-src/himi-store-account/index.ts +6 -3
- package/templates/gym-fitness/tier5-src/himi-store-account/index.ts +6 -3
- package/templates/nonprofit-cause/tier5-src/himi-store-account/index.ts +6 -3
- package/templates/podcast-creator/tier5-src/himi-store-account/index.ts +6 -3
- package/templates/portfolio-creative/tier5-src/himi-store-account/index.ts +6 -3
- package/templates/restaurant/tier5-src/himi-store-account/index.ts +6 -3
- package/templates/retail-store/tier5-src/himi-store-account/index.ts +6 -3
- package/templates/yoga-studio/tier5-src/himi-store-account/index.ts +6 -3
|
@@ -35,12 +35,12 @@ export interface DetailedHeaderOptions {
|
|
|
35
35
|
collapsedHeight?: number;
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
|
-
* Build
|
|
38
|
+
* Build an optional Detailed cover header for screens that explicitly request one.
|
|
39
39
|
*
|
|
40
40
|
* The header uses Himalaya's cross-platform `CollapsingHeader` and standard
|
|
41
|
-
* components for the detail card, logo, member strip, and actions.
|
|
42
|
-
*
|
|
43
|
-
* hero accepts one image
|
|
41
|
+
* components for the detail card, logo, member strip, and actions. The One App
|
|
42
|
+
* migration workflow uses native navigation bars and does not call this builder.
|
|
43
|
+
* Himalaya's hero accepts one image.
|
|
44
44
|
*/
|
|
45
45
|
export declare function detailedHeader(opts: DetailedHeaderOptions): Node;
|
|
46
46
|
export interface ScreenEnvelope {
|
package/dist/cli.mjs
CHANGED
|
@@ -13604,6 +13604,7 @@ function webViewOriginAllowed(url, origins) {
|
|
|
13604
13604
|
}
|
|
13605
13605
|
var init_webview_origin = __esm({
|
|
13606
13606
|
"../../core/ts/src/webview-origin.ts"() {
|
|
13607
|
+
"use strict";
|
|
13607
13608
|
}
|
|
13608
13609
|
});
|
|
13609
13610
|
|
|
@@ -138915,6 +138916,7 @@ __export(build_exports2, {
|
|
|
138915
138916
|
BAKE_OFFLINE_BASE: () => BAKE_OFFLINE_BASE,
|
|
138916
138917
|
KNOWN_ICON_NAMES: () => KNOWN_ICON_NAMES,
|
|
138917
138918
|
SOURCEMAP_ON_DEMAND_PATH: () => SOURCEMAP_ON_DEMAND_PATH,
|
|
138919
|
+
SUPPORTED_COMPONENT_MIN_VERSION: () => SUPPORTED_COMPONENT_MIN_VERSION,
|
|
138918
138920
|
bakeCatalogs: () => bakeCatalogs,
|
|
138919
138921
|
bakeNeedsLiveOrigin: () => bakeNeedsLiveOrigin,
|
|
138920
138922
|
bakeWidgets: () => bakeWidgets,
|
|
@@ -138927,6 +138929,7 @@ __export(build_exports2, {
|
|
|
138927
138929
|
countingHostAnswers: () => countingHostAnswers,
|
|
138928
138930
|
countingWixCall: () => countingWixCall,
|
|
138929
138931
|
declaresHostProvidedIdentity: () => declaresHostProvidedIdentity,
|
|
138932
|
+
explicitMinRuntimeVersion: () => explicitMinRuntimeVersion,
|
|
138930
138933
|
gitSha: () => gitSha,
|
|
138931
138934
|
isMonorepoCheckout: () => isMonorepoCheckout,
|
|
138932
138935
|
l10nLintOptions: () => l10nLintOptions,
|
|
@@ -138936,6 +138939,7 @@ __export(build_exports2, {
|
|
|
138936
138939
|
listBuildableApps: () => listBuildableApps,
|
|
138937
138940
|
liveRenderServices: () => liveRenderServices,
|
|
138938
138941
|
maximumBinaryVersion: () => maximumBinaryVersion,
|
|
138942
|
+
navBundleMinBinaryVersion: () => navBundleMinBinaryVersion,
|
|
138939
138943
|
navLogicBundleUrl: () => navLogicBundleUrl,
|
|
138940
138944
|
pinBakedServerBaseUrl: () => pinBakedServerBaseUrl,
|
|
138941
138945
|
pinnedReleaseFromEnv: () => pinnedReleaseFromEnv,
|
|
@@ -138946,6 +138950,7 @@ __export(build_exports2, {
|
|
|
138946
138950
|
shellSha: () => shellSha,
|
|
138947
138951
|
snapshotTokens: () => snapshotTokens,
|
|
138948
138952
|
tokensSnapshotMessage: () => tokensSnapshotMessage,
|
|
138953
|
+
unsupportedComponentMinVersions: () => unsupportedComponentMinVersions,
|
|
138949
138954
|
withPinnedRelease: () => withPinnedRelease,
|
|
138950
138955
|
withStoreNavBundle: () => withStoreNavBundle,
|
|
138951
138956
|
withoutDevOnlyAppConfig: () => withoutDevOnlyAppConfig
|
|
@@ -139216,6 +139221,22 @@ function collectComponentTypes(value2, into = /* @__PURE__ */ new Set()) {
|
|
|
139216
139221
|
for (const child of Object.values(obj7)) collectComponentTypes(child, into);
|
|
139217
139222
|
return into;
|
|
139218
139223
|
}
|
|
139224
|
+
function unsupportedComponentMinVersions(value2, into = []) {
|
|
139225
|
+
if (!value2 || typeof value2 !== "object") return into;
|
|
139226
|
+
const obj7 = value2;
|
|
139227
|
+
const isComponent2 = typeof obj7.id === "string" && (obj7.body !== null && typeof obj7.body === "object" || typeof obj7.package === "string" && typeof obj7.type === "string");
|
|
139228
|
+
if (isComponent2 && typeof obj7.minVersion === "number" && obj7.minVersion > SUPPORTED_COMPONENT_MIN_VERSION) {
|
|
139229
|
+
into.push({ id: obj7.id, minVersion: obj7.minVersion });
|
|
139230
|
+
}
|
|
139231
|
+
for (const child of Object.values(obj7)) unsupportedComponentMinVersions(child, into);
|
|
139232
|
+
return into;
|
|
139233
|
+
}
|
|
139234
|
+
function explicitMinRuntimeVersion(raw) {
|
|
139235
|
+
if (raw === void 0 || raw.trim() === "") return null;
|
|
139236
|
+
const v2 = raw.trim();
|
|
139237
|
+
if (!/^\d+(?:\.\d+){0,2}$/.test(v2)) throw new Error(`invalid --min-runtime-version "${raw}": expected a numeric version like 1.7.0`);
|
|
139238
|
+
return v2;
|
|
139239
|
+
}
|
|
139219
139240
|
function collectNativeComponents(value2, into) {
|
|
139220
139241
|
if (!value2 || typeof value2 !== "object") return;
|
|
139221
139242
|
const obj7 = value2;
|
|
@@ -139238,6 +139259,21 @@ function maximumBinaryVersion(current, candidate) {
|
|
|
139238
139259
|
}
|
|
139239
139260
|
return current;
|
|
139240
139261
|
}
|
|
139262
|
+
function navBundleMinBinaryVersion(text12) {
|
|
139263
|
+
let cfg;
|
|
139264
|
+
try {
|
|
139265
|
+
cfg = JSON.parse(text12);
|
|
139266
|
+
} catch {
|
|
139267
|
+
return null;
|
|
139268
|
+
}
|
|
139269
|
+
let floor2 = null;
|
|
139270
|
+
for (const ref of [cfg?.app?.logicBundle, cfg?.navigation?.navLogicBundle, cfg?.navLogicBundle]) {
|
|
139271
|
+
if (!ref || typeof ref !== "object") continue;
|
|
139272
|
+
floor2 = maximumBinaryVersion(floor2, ref.minBinaryVersion);
|
|
139273
|
+
floor2 = maximumBinaryVersion(floor2, ref.min_binary_version);
|
|
139274
|
+
}
|
|
139275
|
+
return floor2;
|
|
139276
|
+
}
|
|
139241
139277
|
async function withStoreNavBundle(text12, address) {
|
|
139242
139278
|
let cfg;
|
|
139243
139279
|
try {
|
|
@@ -139312,7 +139348,8 @@ async function buildRelease(app, dest, opts = {}) {
|
|
|
139312
139348
|
return (await buildFromLoaded(loaded, dest, {
|
|
139313
139349
|
...tier5Dir ? { tier5Dir } : {},
|
|
139314
139350
|
...opts.fetchFace ? { fetchFace: opts.fetchFace } : {},
|
|
139315
|
-
...opts.keepDevOnlyAppConfig ? { keepDevOnlyAppConfig: true } : {}
|
|
139351
|
+
...opts.keepDevOnlyAppConfig ? { keepDevOnlyAppConfig: true } : {},
|
|
139352
|
+
...opts.minRuntimeVersion ? { minRuntimeVersion: opts.minRuntimeVersion } : {}
|
|
139316
139353
|
})).manifest;
|
|
139317
139354
|
}
|
|
139318
139355
|
function countingWixCall(base) {
|
|
@@ -139443,6 +139480,13 @@ function readTokensForLint(preloaded) {
|
|
|
139443
139480
|
}
|
|
139444
139481
|
async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
139445
139482
|
const app = preloaded.name;
|
|
139483
|
+
const assertComponentMinVersions = (screenId, descriptor) => {
|
|
139484
|
+
const bad2 = unsupportedComponentMinVersions(descriptor);
|
|
139485
|
+
if (!bad2.length) return;
|
|
139486
|
+
throw new Error(
|
|
139487
|
+
`screen ${screenId}: component minVersion is not enforced by any runtime (supported: ${SUPPORTED_COMPONENT_MIN_VERSION}) \u2014 ` + bad2.map((c2) => `${c2.id} asks for ${c2.minVersion}`).join(", ") + `. Declare what the release needs from the runtime as its floor instead: min_binary_version on the logic bundle, or release:build --min-runtime-version.`
|
|
139488
|
+
);
|
|
139489
|
+
};
|
|
139446
139490
|
const tier5Dir = opts.tier5Dir ?? TIER5_DIR;
|
|
139447
139491
|
const bundlePath = (name) => {
|
|
139448
139492
|
const own6 = join28(tier5Dir, `${name}.bundle.js`);
|
|
@@ -139629,7 +139673,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
139629
139673
|
if (input && typeof input === "object" && !Array.isArray(input)) bundleInputs.set(bundleName, input);
|
|
139630
139674
|
};
|
|
139631
139675
|
let handlers;
|
|
139632
|
-
let minBinaryVersion =
|
|
139676
|
+
let minBinaryVersion = explicitMinRuntimeVersion(opts.minRuntimeVersion);
|
|
139633
139677
|
const requiredCapabilities2 = new Set(config.capabilities ?? []);
|
|
139634
139678
|
const capabilityUsage = {
|
|
139635
139679
|
app: [...config.capabilities ?? []],
|
|
@@ -139868,6 +139912,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
139868
139912
|
continue;
|
|
139869
139913
|
}
|
|
139870
139914
|
const descriptor = await res.json();
|
|
139915
|
+
assertComponentMinVersions(screenId, descriptor);
|
|
139871
139916
|
collectNativeComponents(descriptor, requiredNativeComponents);
|
|
139872
139917
|
let bundleName = null;
|
|
139873
139918
|
const lb = logicBundleOf(descriptor);
|
|
@@ -140038,6 +140083,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
140038
140083
|
continue;
|
|
140039
140084
|
}
|
|
140040
140085
|
const descriptor = await res.json();
|
|
140086
|
+
assertComponentMinVersions(screenId, descriptor);
|
|
140041
140087
|
collectNativeComponents(descriptor, requiredNativeComponents);
|
|
140042
140088
|
let bundleName = null;
|
|
140043
140089
|
const lb = logicBundleOf(descriptor);
|
|
@@ -140163,6 +140209,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
140163
140209
|
});
|
|
140164
140210
|
await store.putAppConfig(app, text12);
|
|
140165
140211
|
appConfigHash = sha2563(text12);
|
|
140212
|
+
minBinaryVersion = maximumBinaryVersion(minBinaryVersion, navBundleMinBinaryVersion(text12));
|
|
140166
140213
|
if (collect2?.descriptors) for (const id of linkableScreenIdsFrom(text12)) linkable.add(id);
|
|
140167
140214
|
}
|
|
140168
140215
|
const ahRes = await devFetch(`${base}/v1/action-handlers/${encodeURIComponent(app)}`, { headers: { "X-Himalaya-App": app } });
|
|
@@ -140368,7 +140415,7 @@ function declaresHostProvidedIdentity(auth) {
|
|
|
140368
140415
|
const config = auth?.config;
|
|
140369
140416
|
return typeof config === "object" && config !== null && config.hostProvided === true;
|
|
140370
140417
|
}
|
|
140371
|
-
var BAKE_OFFLINE_BASE, KNOWN_ICON_NAMES, KNOWN_ICONS, APP_SERVICES_LINT_SCREEN, REPO_ROOT5, TIER5_DIR, requireFromHere, SOURCEMAP_ON_DEMAND_PATH, BAKED_SERVER_BASE_URL, SETTLE_TURNS;
|
|
140418
|
+
var BAKE_OFFLINE_BASE, KNOWN_ICON_NAMES, KNOWN_ICONS, APP_SERVICES_LINT_SCREEN, REPO_ROOT5, TIER5_DIR, requireFromHere, SOURCEMAP_ON_DEMAND_PATH, BAKED_SERVER_BASE_URL, SUPPORTED_COMPONENT_MIN_VERSION, SETTLE_TURNS;
|
|
140372
140419
|
var init_build3 = __esm({
|
|
140373
140420
|
"../release-build/build.ts"() {
|
|
140374
140421
|
init_site_view_metadata();
|
|
@@ -140412,6 +140459,7 @@ var init_build3 = __esm({
|
|
|
140412
140459
|
requireFromHere = createRequire3(import.meta.url);
|
|
140413
140460
|
SOURCEMAP_ON_DEMAND_PATH = join28(REPO_ROOT5, "core/dev-server/tier5-bundles-src/sourcemap-on-demand.mjs");
|
|
140414
140461
|
BAKED_SERVER_BASE_URL = "http://baked.himalaya.invalid";
|
|
140462
|
+
SUPPORTED_COMPONENT_MIN_VERSION = 1;
|
|
140415
140463
|
SETTLE_TURNS = 20;
|
|
140416
140464
|
}
|
|
140417
140465
|
});
|
|
@@ -103,9 +103,12 @@ support." (Wix refused it, so it stays held), `restoreUpToDateText` "Your purcha
|
|
|
103
103
|
"Couldn't reach the App Store. Try again." (also shown when the host cannot sell). A message belongs
|
|
104
104
|
to the session it ran for: after a sign-in or sign-out the control shows none.
|
|
105
105
|
|
|
106
|
-
**
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
**Reinstall.** A reinstall deletes the native managed ledger. In an app's own bound build, an
|
|
107
|
+
unfinished transaction under the app's bundle id is still the app's own, so restore resubmits it.
|
|
108
|
+
In Player or an explicit host, the tenant filter hides those transactions and restore finds none;
|
|
109
|
+
it still re-reads access ([transaction contract](iap-transaction-contract.md#activation-limits-and-compatibility)).
|
|
110
|
+
|
|
111
|
+
**Not covered yet.** On iOS `AppStore.sync()` errors are swallowed natively, so a failed sync currently reads as
|
|
109
112
|
up to date rather than the error copy.
|
|
110
113
|
|
|
111
114
|
## Migrating an existing app copy
|
|
@@ -147,7 +147,7 @@ Apply these interpretation rules:
|
|
|
147
147
|
only when the resolved source top-bar settings show a title and Structure supplies
|
|
148
148
|
its value; leave it empty when the source does not show a title or has no title.
|
|
149
149
|
Do not create a title from the app name, business name, route ID, tab label or
|
|
150
|
-
section content.
|
|
150
|
+
section content. Apply the native-navigation policy below to source custom headers.
|
|
151
151
|
- Keep navigation visibility, reachability and data access separate. Reevaluate
|
|
152
152
|
membership/plan/badge gates at runtime; an operator's successful read is not an
|
|
153
153
|
end-user access policy. Never expose protected content beneath a visual gate.
|
|
@@ -205,30 +205,34 @@ Apply these interpretation rules:
|
|
|
205
205
|
explicitly rather than treating a pass as full design parity. A deliberate difference
|
|
206
206
|
is waived only by a `design` coverage row with status `adapted` that cites the user's
|
|
207
207
|
instruction and explains the change. This check compares values, not rendered screens.
|
|
208
|
-
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
208
|
+
- **Native navigation is the migration target.** Use the shell's native top bar
|
|
209
|
+
and, for bottom-tab navigation, `navigation.tabBar.presentation: "native"`.
|
|
210
|
+
Do not recreate the source Detailed header, call `detailedHeader`, or insert a
|
|
211
|
+
`CollapsingHeader` hero/card above the page. This target adaptation supersedes
|
|
212
|
+
the older instruction to reproduce the source cover header; the source
|
|
213
|
+
research still explains how to interpret its settings.
|
|
214
|
+
- Emit resolved native actions in `navigation.topBarDefault` or a complete
|
|
215
|
+
per-screen `topBar` override. The shell owns back/menu controls. Per-screen
|
|
216
|
+
actions support `hiddenPath` when `navigation.topBarDefault.actions` declares
|
|
217
|
+
the same action ID and binding, evaluated by `navigation.navLogicBundle`.
|
|
218
|
+
Keep that registration for screen overrides: screen-only paths are not
|
|
219
|
+
subscribed, and an unresolved path leaves the action visible. Do not invent
|
|
220
|
+
visibility fields. These bindings control presentation only and must not
|
|
221
|
+
authorize data or actions. Preserve runtime access checks, and report any source visibility
|
|
222
|
+
rule that the target cannot represent as a gap. Preserve the title rule above:
|
|
223
|
+
a source cover title does not by itself authorize a native top-bar title.
|
|
224
|
+
- Account for source header content in `.himi/one-app/migration-report.md`.
|
|
225
|
+
Record the custom cover, carousel and overlapping card as an intentional
|
|
226
|
+
native-navigation adaptation there; do not invent header-presentation rows in
|
|
227
|
+
the derived coverage ledger. Preserve meaningful subtitle, location and configured CTA content
|
|
228
|
+
as ordinary page content or supported native actions, with the same runtime
|
|
229
|
+
access rules. Report unsupported avatar/logo/action behavior as a gap; do not
|
|
230
|
+
invent member data, drop a configured CTA silently, or add an in-page toolbar
|
|
231
|
+
to imitate a missing native control.
|
|
232
|
+
- Verify the migrated app's native top bar, bottom tabs, back navigation and
|
|
233
|
+
configured actions on the affected devices, including RTL. A web screenshot
|
|
234
|
+
alone does not prove native navigation or control availability. Record any
|
|
235
|
+
unavailable device check as unverified.
|
|
232
236
|
- Business context contains only `phoneNumber`, `website`, and `services`, with
|
|
233
237
|
their permitted nested values. Structure wins on authored phone/URL/design.
|
|
234
238
|
Installed services do not add features. Installation IDs are not record IDs.
|
|
@@ -257,8 +261,11 @@ reference's top-tabs row in R04 and its top-tabs acceptance case:
|
|
|
257
261
|
in-screen top tabs.
|
|
258
262
|
- `target.hiddenPages` become screens without a tab entry. Keep their routes for
|
|
259
263
|
actions and links.
|
|
260
|
-
- The
|
|
261
|
-
|
|
264
|
+
- The plan attaches the source screen's header settings to the first tab as
|
|
265
|
+
interpretation evidence; it does not require a custom header in the target.
|
|
266
|
+
Apply the native-navigation policy above to that tab too. Resolve every tab's
|
|
267
|
+
effective native top bar, with compact defaults for the other tabs as in the
|
|
268
|
+
editor conversion.
|
|
262
269
|
- `target.initialTabId` is the first tab; the editor drops the source
|
|
263
270
|
`initialTabId`. `initial_tab_changed` names the page that used to open first.
|
|
264
271
|
- `target.showLabels` is the source label setting. Pilates hides labels when it
|
package/guides/one-app-viewer.md
CHANGED
|
@@ -127,11 +127,11 @@ Translate the resolved result to Himi. Its inspected schema says a per-screen `t
|
|
|
127
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
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
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.
|
|
130
|
+
- A source custom header is page content in the original viewer. It is not the shell's top bar. Apply the current migration's native-navigation adaptation in R09 rather than duplicating the source header above the native bar.
|
|
131
131
|
|
|
132
132
|
### R09. Treat header content as conditional, configured behavior
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
The source rules below describe the original viewer. **For the current One App migration target, use native navigation bars, bottom tabs and the top bar; do not reproduce a custom Detailed cover header.** This target policy supersedes this reference's older shared-header recommendation. Keep the source facts as interpretation evidence and record the target adaptation explicitly.
|
|
135
135
|
|
|
136
136
|
Relevant source behavior to preserve when applicable:
|
|
137
137
|
|
|
@@ -142,7 +142,9 @@ Relevant source behavior to preserve when applicable:
|
|
|
142
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.
|
|
143
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.
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
Do not call `detailedHeader` or add a `CollapsingHeader` hero/card in the migrated screen. Configure the shell through `navigation.topBarDefault`, complete per-screen `topBar` overrides, and `navigation.tabBar.presentation: "native"` for bottom tabs. Keep R08a's title and action-resolution rules; the shell owns back/menu controls. The `navigation-plan.json` first-tab source-header reference is evidence, not an instruction to render the old header.
|
|
146
|
+
|
|
147
|
+
Record the omitted custom cover, carousel and overlapping card as an adaptation in `.himi/one-app/migration-report.md`; do not invent header-presentation rows in the derived coverage ledger. Preserve meaningful subtitle, location and configured CTA content as ordinary page content or supported native actions, subject to the original runtime access rules. Per-screen `topBar.actions` support `hiddenPath` when `navigation.topBarDefault.actions` declares the same action ID and binding, evaluated by `navigation.navLogicBundle`. Keep that registration for screen overrides: screen-only paths are not subscribed, and an unresolved path leaves the action visible. Preserve representable source visibility rules through these supported bindings; do not invent visibility fields. These bindings control presentation only, not authorization. Keep runtime access checks and report source visibility rules the target cannot represent as gaps. Unsupported leading avatars, logos or actions remain explicit gaps; do not invent member data or an in-page toolbar. Verify top bars, bottom tabs, back navigation and configured actions on affected native devices, including RTL; report unavailable checks as unverified. [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)
|
|
146
148
|
|
|
147
149
|
## Step 4 — Recreate each section envelope before its content
|
|
148
150
|
|
|
@@ -4117,7 +4117,7 @@
|
|
|
4117
4117
|
{
|
|
4118
4118
|
"name": "detailedHeader",
|
|
4119
4119
|
"kind": "function",
|
|
4120
|
-
"jsdoc": "/**\n * Build
|
|
4120
|
+
"jsdoc": "/**\n * Build an optional Detailed cover header for screens that explicitly request one.\n *\n * The header uses Himalaya's cross-platform `CollapsingHeader` and standard\n * components for the detail card, logo, member strip, and actions. The One App\n * migration workflow uses native navigation bars and does not call this builder.\n * Himalaya's hero accepts one image.\n */",
|
|
4121
4121
|
"decl": "export function detailedHeader(opts: DetailedHeaderOptions): Node;"
|
|
4122
4122
|
},
|
|
4123
4123
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1566.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": "59d9f7c34824b26777859c276927fa1bde614c8f64c26db04c10bfb3"
|
|
75
75
|
}
|
|
@@ -234,6 +234,9 @@ let signInPresentationRequested: "" | "sheet" | "full_screen" = "";
|
|
|
234
234
|
let signInReturnTabRequested = "";
|
|
235
235
|
let standaloneRequested = false;
|
|
236
236
|
let pollIdentityRequested = false;
|
|
237
|
+
// iOS can start the arg-less boot load after the appear refresh that asks for the row; the
|
|
238
|
+
// newer boot probe must not land, or be kept, without it.
|
|
239
|
+
let restorePurchasesRequested = false;
|
|
237
240
|
// Bumped by every mode switch, so a dropped probe never puts back a mode the visitor left.
|
|
238
241
|
let modeSwitches = 0;
|
|
239
242
|
|
|
@@ -246,6 +249,7 @@ function appearBase(): Partial<S> {
|
|
|
246
249
|
signInScreen: signInScreenRequested,
|
|
247
250
|
standalone: standaloneRequested,
|
|
248
251
|
pollIdentity: pollIdentityRequested,
|
|
252
|
+
restorePurchases: restorePurchasesRequested,
|
|
249
253
|
...(pollIdentityRequested ? { _poll: { ...IDENTITY_POLL } } : {}),
|
|
250
254
|
};
|
|
251
255
|
}
|
|
@@ -268,6 +272,7 @@ function appearConfig(s: S, arg: unknown): AppearConfig {
|
|
|
268
272
|
// Only the sign-in screen's route carries `mode`, so it marks the form from the boot load on.
|
|
269
273
|
standaloneRequested ||= s.standalone || appearing || (!routeInputConsumed && !!routeInput().mode);
|
|
270
274
|
pollIdentityRequested ||= s.pollIdentity || strField(arg, "pollIdentity") === "1";
|
|
275
|
+
restorePurchasesRequested ||= s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
271
276
|
// The form opens on the mode its route asked for each time it appears, sign-in by
|
|
272
277
|
// default: a pooled worker reopened with the same params must not open on the mode the
|
|
273
278
|
// last visit toggled to.
|
|
@@ -652,8 +657,7 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
652
657
|
// Not the boot load: it never carries the copy, and the appear refresh that does is coming.
|
|
653
658
|
if (strField(arg, "boot") !== "1") headingReady = true;
|
|
654
659
|
const memberAccountLinks = memberAccountLinksRequested;
|
|
655
|
-
|
|
656
|
-
if (restorePurchases) enterCommerce();
|
|
660
|
+
if (restorePurchasesRequested) enterCommerce();
|
|
657
661
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
658
662
|
let activityRows: AccountActivityRow[] = [];
|
|
659
663
|
if (profile.isMember) {
|
|
@@ -681,7 +685,6 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
681
685
|
email: profile.memberEmail || s.email,
|
|
682
686
|
message: "",
|
|
683
687
|
memberAccountLinks,
|
|
684
|
-
restorePurchases,
|
|
685
688
|
...appearBase(),
|
|
686
689
|
...config.mode,
|
|
687
690
|
...config.visit,
|
|
@@ -234,6 +234,9 @@ let signInPresentationRequested: "" | "sheet" | "full_screen" = "";
|
|
|
234
234
|
let signInReturnTabRequested = "";
|
|
235
235
|
let standaloneRequested = false;
|
|
236
236
|
let pollIdentityRequested = false;
|
|
237
|
+
// iOS can start the arg-less boot load after the appear refresh that asks for the row; the
|
|
238
|
+
// newer boot probe must not land, or be kept, without it.
|
|
239
|
+
let restorePurchasesRequested = false;
|
|
237
240
|
// Bumped by every mode switch, so a dropped probe never puts back a mode the visitor left.
|
|
238
241
|
let modeSwitches = 0;
|
|
239
242
|
|
|
@@ -246,6 +249,7 @@ function appearBase(): Partial<S> {
|
|
|
246
249
|
signInScreen: signInScreenRequested,
|
|
247
250
|
standalone: standaloneRequested,
|
|
248
251
|
pollIdentity: pollIdentityRequested,
|
|
252
|
+
restorePurchases: restorePurchasesRequested,
|
|
249
253
|
...(pollIdentityRequested ? { _poll: { ...IDENTITY_POLL } } : {}),
|
|
250
254
|
};
|
|
251
255
|
}
|
|
@@ -268,6 +272,7 @@ function appearConfig(s: S, arg: unknown): AppearConfig {
|
|
|
268
272
|
// Only the sign-in screen's route carries `mode`, so it marks the form from the boot load on.
|
|
269
273
|
standaloneRequested ||= s.standalone || appearing || (!routeInputConsumed && !!routeInput().mode);
|
|
270
274
|
pollIdentityRequested ||= s.pollIdentity || strField(arg, "pollIdentity") === "1";
|
|
275
|
+
restorePurchasesRequested ||= s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
271
276
|
// The form opens on the mode its route asked for each time it appears, sign-in by
|
|
272
277
|
// default: a pooled worker reopened with the same params must not open on the mode the
|
|
273
278
|
// last visit toggled to.
|
|
@@ -652,8 +657,7 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
652
657
|
// Not the boot load: it never carries the copy, and the appear refresh that does is coming.
|
|
653
658
|
if (strField(arg, "boot") !== "1") headingReady = true;
|
|
654
659
|
const memberAccountLinks = memberAccountLinksRequested;
|
|
655
|
-
|
|
656
|
-
if (restorePurchases) enterCommerce();
|
|
660
|
+
if (restorePurchasesRequested) enterCommerce();
|
|
657
661
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
658
662
|
let activityRows: AccountActivityRow[] = [];
|
|
659
663
|
if (profile.isMember) {
|
|
@@ -681,7 +685,6 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
681
685
|
email: profile.memberEmail || s.email,
|
|
682
686
|
message: "",
|
|
683
687
|
memberAccountLinks,
|
|
684
|
-
restorePurchases,
|
|
685
688
|
...appearBase(),
|
|
686
689
|
...config.mode,
|
|
687
690
|
...config.visit,
|
|
@@ -234,6 +234,9 @@ let signInPresentationRequested: "" | "sheet" | "full_screen" = "";
|
|
|
234
234
|
let signInReturnTabRequested = "";
|
|
235
235
|
let standaloneRequested = false;
|
|
236
236
|
let pollIdentityRequested = false;
|
|
237
|
+
// iOS can start the arg-less boot load after the appear refresh that asks for the row; the
|
|
238
|
+
// newer boot probe must not land, or be kept, without it.
|
|
239
|
+
let restorePurchasesRequested = false;
|
|
237
240
|
// Bumped by every mode switch, so a dropped probe never puts back a mode the visitor left.
|
|
238
241
|
let modeSwitches = 0;
|
|
239
242
|
|
|
@@ -246,6 +249,7 @@ function appearBase(): Partial<S> {
|
|
|
246
249
|
signInScreen: signInScreenRequested,
|
|
247
250
|
standalone: standaloneRequested,
|
|
248
251
|
pollIdentity: pollIdentityRequested,
|
|
252
|
+
restorePurchases: restorePurchasesRequested,
|
|
249
253
|
...(pollIdentityRequested ? { _poll: { ...IDENTITY_POLL } } : {}),
|
|
250
254
|
};
|
|
251
255
|
}
|
|
@@ -268,6 +272,7 @@ function appearConfig(s: S, arg: unknown): AppearConfig {
|
|
|
268
272
|
// Only the sign-in screen's route carries `mode`, so it marks the form from the boot load on.
|
|
269
273
|
standaloneRequested ||= s.standalone || appearing || (!routeInputConsumed && !!routeInput().mode);
|
|
270
274
|
pollIdentityRequested ||= s.pollIdentity || strField(arg, "pollIdentity") === "1";
|
|
275
|
+
restorePurchasesRequested ||= s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
271
276
|
// The form opens on the mode its route asked for each time it appears, sign-in by
|
|
272
277
|
// default: a pooled worker reopened with the same params must not open on the mode the
|
|
273
278
|
// last visit toggled to.
|
|
@@ -652,8 +657,7 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
652
657
|
// Not the boot load: it never carries the copy, and the appear refresh that does is coming.
|
|
653
658
|
if (strField(arg, "boot") !== "1") headingReady = true;
|
|
654
659
|
const memberAccountLinks = memberAccountLinksRequested;
|
|
655
|
-
|
|
656
|
-
if (restorePurchases) enterCommerce();
|
|
660
|
+
if (restorePurchasesRequested) enterCommerce();
|
|
657
661
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
658
662
|
let activityRows: AccountActivityRow[] = [];
|
|
659
663
|
if (profile.isMember) {
|
|
@@ -681,7 +685,6 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
681
685
|
email: profile.memberEmail || s.email,
|
|
682
686
|
message: "",
|
|
683
687
|
memberAccountLinks,
|
|
684
|
-
restorePurchases,
|
|
685
688
|
...appearBase(),
|
|
686
689
|
...config.mode,
|
|
687
690
|
...config.visit,
|
|
@@ -234,6 +234,9 @@ let signInPresentationRequested: "" | "sheet" | "full_screen" = "";
|
|
|
234
234
|
let signInReturnTabRequested = "";
|
|
235
235
|
let standaloneRequested = false;
|
|
236
236
|
let pollIdentityRequested = false;
|
|
237
|
+
// iOS can start the arg-less boot load after the appear refresh that asks for the row; the
|
|
238
|
+
// newer boot probe must not land, or be kept, without it.
|
|
239
|
+
let restorePurchasesRequested = false;
|
|
237
240
|
// Bumped by every mode switch, so a dropped probe never puts back a mode the visitor left.
|
|
238
241
|
let modeSwitches = 0;
|
|
239
242
|
|
|
@@ -246,6 +249,7 @@ function appearBase(): Partial<S> {
|
|
|
246
249
|
signInScreen: signInScreenRequested,
|
|
247
250
|
standalone: standaloneRequested,
|
|
248
251
|
pollIdentity: pollIdentityRequested,
|
|
252
|
+
restorePurchases: restorePurchasesRequested,
|
|
249
253
|
...(pollIdentityRequested ? { _poll: { ...IDENTITY_POLL } } : {}),
|
|
250
254
|
};
|
|
251
255
|
}
|
|
@@ -268,6 +272,7 @@ function appearConfig(s: S, arg: unknown): AppearConfig {
|
|
|
268
272
|
// Only the sign-in screen's route carries `mode`, so it marks the form from the boot load on.
|
|
269
273
|
standaloneRequested ||= s.standalone || appearing || (!routeInputConsumed && !!routeInput().mode);
|
|
270
274
|
pollIdentityRequested ||= s.pollIdentity || strField(arg, "pollIdentity") === "1";
|
|
275
|
+
restorePurchasesRequested ||= s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
271
276
|
// The form opens on the mode its route asked for each time it appears, sign-in by
|
|
272
277
|
// default: a pooled worker reopened with the same params must not open on the mode the
|
|
273
278
|
// last visit toggled to.
|
|
@@ -652,8 +657,7 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
652
657
|
// Not the boot load: it never carries the copy, and the appear refresh that does is coming.
|
|
653
658
|
if (strField(arg, "boot") !== "1") headingReady = true;
|
|
654
659
|
const memberAccountLinks = memberAccountLinksRequested;
|
|
655
|
-
|
|
656
|
-
if (restorePurchases) enterCommerce();
|
|
660
|
+
if (restorePurchasesRequested) enterCommerce();
|
|
657
661
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
658
662
|
let activityRows: AccountActivityRow[] = [];
|
|
659
663
|
if (profile.isMember) {
|
|
@@ -681,7 +685,6 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
681
685
|
email: profile.memberEmail || s.email,
|
|
682
686
|
message: "",
|
|
683
687
|
memberAccountLinks,
|
|
684
|
-
restorePurchases,
|
|
685
688
|
...appearBase(),
|
|
686
689
|
...config.mode,
|
|
687
690
|
...config.visit,
|
|
@@ -234,6 +234,9 @@ let signInPresentationRequested: "" | "sheet" | "full_screen" = "";
|
|
|
234
234
|
let signInReturnTabRequested = "";
|
|
235
235
|
let standaloneRequested = false;
|
|
236
236
|
let pollIdentityRequested = false;
|
|
237
|
+
// iOS can start the arg-less boot load after the appear refresh that asks for the row; the
|
|
238
|
+
// newer boot probe must not land, or be kept, without it.
|
|
239
|
+
let restorePurchasesRequested = false;
|
|
237
240
|
// Bumped by every mode switch, so a dropped probe never puts back a mode the visitor left.
|
|
238
241
|
let modeSwitches = 0;
|
|
239
242
|
|
|
@@ -246,6 +249,7 @@ function appearBase(): Partial<S> {
|
|
|
246
249
|
signInScreen: signInScreenRequested,
|
|
247
250
|
standalone: standaloneRequested,
|
|
248
251
|
pollIdentity: pollIdentityRequested,
|
|
252
|
+
restorePurchases: restorePurchasesRequested,
|
|
249
253
|
...(pollIdentityRequested ? { _poll: { ...IDENTITY_POLL } } : {}),
|
|
250
254
|
};
|
|
251
255
|
}
|
|
@@ -268,6 +272,7 @@ function appearConfig(s: S, arg: unknown): AppearConfig {
|
|
|
268
272
|
// Only the sign-in screen's route carries `mode`, so it marks the form from the boot load on.
|
|
269
273
|
standaloneRequested ||= s.standalone || appearing || (!routeInputConsumed && !!routeInput().mode);
|
|
270
274
|
pollIdentityRequested ||= s.pollIdentity || strField(arg, "pollIdentity") === "1";
|
|
275
|
+
restorePurchasesRequested ||= s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
271
276
|
// The form opens on the mode its route asked for each time it appears, sign-in by
|
|
272
277
|
// default: a pooled worker reopened with the same params must not open on the mode the
|
|
273
278
|
// last visit toggled to.
|
|
@@ -652,8 +657,7 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
652
657
|
// Not the boot load: it never carries the copy, and the appear refresh that does is coming.
|
|
653
658
|
if (strField(arg, "boot") !== "1") headingReady = true;
|
|
654
659
|
const memberAccountLinks = memberAccountLinksRequested;
|
|
655
|
-
|
|
656
|
-
if (restorePurchases) enterCommerce();
|
|
660
|
+
if (restorePurchasesRequested) enterCommerce();
|
|
657
661
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
658
662
|
let activityRows: AccountActivityRow[] = [];
|
|
659
663
|
if (profile.isMember) {
|
|
@@ -681,7 +685,6 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
681
685
|
email: profile.memberEmail || s.email,
|
|
682
686
|
message: "",
|
|
683
687
|
memberAccountLinks,
|
|
684
|
-
restorePurchases,
|
|
685
688
|
...appearBase(),
|
|
686
689
|
...config.mode,
|
|
687
690
|
...config.visit,
|
|
@@ -234,6 +234,9 @@ let signInPresentationRequested: "" | "sheet" | "full_screen" = "";
|
|
|
234
234
|
let signInReturnTabRequested = "";
|
|
235
235
|
let standaloneRequested = false;
|
|
236
236
|
let pollIdentityRequested = false;
|
|
237
|
+
// iOS can start the arg-less boot load after the appear refresh that asks for the row; the
|
|
238
|
+
// newer boot probe must not land, or be kept, without it.
|
|
239
|
+
let restorePurchasesRequested = false;
|
|
237
240
|
// Bumped by every mode switch, so a dropped probe never puts back a mode the visitor left.
|
|
238
241
|
let modeSwitches = 0;
|
|
239
242
|
|
|
@@ -246,6 +249,7 @@ function appearBase(): Partial<S> {
|
|
|
246
249
|
signInScreen: signInScreenRequested,
|
|
247
250
|
standalone: standaloneRequested,
|
|
248
251
|
pollIdentity: pollIdentityRequested,
|
|
252
|
+
restorePurchases: restorePurchasesRequested,
|
|
249
253
|
...(pollIdentityRequested ? { _poll: { ...IDENTITY_POLL } } : {}),
|
|
250
254
|
};
|
|
251
255
|
}
|
|
@@ -268,6 +272,7 @@ function appearConfig(s: S, arg: unknown): AppearConfig {
|
|
|
268
272
|
// Only the sign-in screen's route carries `mode`, so it marks the form from the boot load on.
|
|
269
273
|
standaloneRequested ||= s.standalone || appearing || (!routeInputConsumed && !!routeInput().mode);
|
|
270
274
|
pollIdentityRequested ||= s.pollIdentity || strField(arg, "pollIdentity") === "1";
|
|
275
|
+
restorePurchasesRequested ||= s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
271
276
|
// The form opens on the mode its route asked for each time it appears, sign-in by
|
|
272
277
|
// default: a pooled worker reopened with the same params must not open on the mode the
|
|
273
278
|
// last visit toggled to.
|
|
@@ -652,8 +657,7 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
652
657
|
// Not the boot load: it never carries the copy, and the appear refresh that does is coming.
|
|
653
658
|
if (strField(arg, "boot") !== "1") headingReady = true;
|
|
654
659
|
const memberAccountLinks = memberAccountLinksRequested;
|
|
655
|
-
|
|
656
|
-
if (restorePurchases) enterCommerce();
|
|
660
|
+
if (restorePurchasesRequested) enterCommerce();
|
|
657
661
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
658
662
|
let activityRows: AccountActivityRow[] = [];
|
|
659
663
|
if (profile.isMember) {
|
|
@@ -681,7 +685,6 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
681
685
|
email: profile.memberEmail || s.email,
|
|
682
686
|
message: "",
|
|
683
687
|
memberAccountLinks,
|
|
684
|
-
restorePurchases,
|
|
685
688
|
...appearBase(),
|
|
686
689
|
...config.mode,
|
|
687
690
|
...config.visit,
|
|
@@ -234,6 +234,9 @@ let signInPresentationRequested: "" | "sheet" | "full_screen" = "";
|
|
|
234
234
|
let signInReturnTabRequested = "";
|
|
235
235
|
let standaloneRequested = false;
|
|
236
236
|
let pollIdentityRequested = false;
|
|
237
|
+
// iOS can start the arg-less boot load after the appear refresh that asks for the row; the
|
|
238
|
+
// newer boot probe must not land, or be kept, without it.
|
|
239
|
+
let restorePurchasesRequested = false;
|
|
237
240
|
// Bumped by every mode switch, so a dropped probe never puts back a mode the visitor left.
|
|
238
241
|
let modeSwitches = 0;
|
|
239
242
|
|
|
@@ -246,6 +249,7 @@ function appearBase(): Partial<S> {
|
|
|
246
249
|
signInScreen: signInScreenRequested,
|
|
247
250
|
standalone: standaloneRequested,
|
|
248
251
|
pollIdentity: pollIdentityRequested,
|
|
252
|
+
restorePurchases: restorePurchasesRequested,
|
|
249
253
|
...(pollIdentityRequested ? { _poll: { ...IDENTITY_POLL } } : {}),
|
|
250
254
|
};
|
|
251
255
|
}
|
|
@@ -268,6 +272,7 @@ function appearConfig(s: S, arg: unknown): AppearConfig {
|
|
|
268
272
|
// Only the sign-in screen's route carries `mode`, so it marks the form from the boot load on.
|
|
269
273
|
standaloneRequested ||= s.standalone || appearing || (!routeInputConsumed && !!routeInput().mode);
|
|
270
274
|
pollIdentityRequested ||= s.pollIdentity || strField(arg, "pollIdentity") === "1";
|
|
275
|
+
restorePurchasesRequested ||= s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
271
276
|
// The form opens on the mode its route asked for each time it appears, sign-in by
|
|
272
277
|
// default: a pooled worker reopened with the same params must not open on the mode the
|
|
273
278
|
// last visit toggled to.
|
|
@@ -652,8 +657,7 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
652
657
|
// Not the boot load: it never carries the copy, and the appear refresh that does is coming.
|
|
653
658
|
if (strField(arg, "boot") !== "1") headingReady = true;
|
|
654
659
|
const memberAccountLinks = memberAccountLinksRequested;
|
|
655
|
-
|
|
656
|
-
if (restorePurchases) enterCommerce();
|
|
660
|
+
if (restorePurchasesRequested) enterCommerce();
|
|
657
661
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
658
662
|
let activityRows: AccountActivityRow[] = [];
|
|
659
663
|
if (profile.isMember) {
|
|
@@ -681,7 +685,6 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
681
685
|
email: profile.memberEmail || s.email,
|
|
682
686
|
message: "",
|
|
683
687
|
memberAccountLinks,
|
|
684
|
-
restorePurchases,
|
|
685
688
|
...appearBase(),
|
|
686
689
|
...config.mode,
|
|
687
690
|
...config.visit,
|
|
@@ -234,6 +234,9 @@ let signInPresentationRequested: "" | "sheet" | "full_screen" = "";
|
|
|
234
234
|
let signInReturnTabRequested = "";
|
|
235
235
|
let standaloneRequested = false;
|
|
236
236
|
let pollIdentityRequested = false;
|
|
237
|
+
// iOS can start the arg-less boot load after the appear refresh that asks for the row; the
|
|
238
|
+
// newer boot probe must not land, or be kept, without it.
|
|
239
|
+
let restorePurchasesRequested = false;
|
|
237
240
|
// Bumped by every mode switch, so a dropped probe never puts back a mode the visitor left.
|
|
238
241
|
let modeSwitches = 0;
|
|
239
242
|
|
|
@@ -246,6 +249,7 @@ function appearBase(): Partial<S> {
|
|
|
246
249
|
signInScreen: signInScreenRequested,
|
|
247
250
|
standalone: standaloneRequested,
|
|
248
251
|
pollIdentity: pollIdentityRequested,
|
|
252
|
+
restorePurchases: restorePurchasesRequested,
|
|
249
253
|
...(pollIdentityRequested ? { _poll: { ...IDENTITY_POLL } } : {}),
|
|
250
254
|
};
|
|
251
255
|
}
|
|
@@ -268,6 +272,7 @@ function appearConfig(s: S, arg: unknown): AppearConfig {
|
|
|
268
272
|
// Only the sign-in screen's route carries `mode`, so it marks the form from the boot load on.
|
|
269
273
|
standaloneRequested ||= s.standalone || appearing || (!routeInputConsumed && !!routeInput().mode);
|
|
270
274
|
pollIdentityRequested ||= s.pollIdentity || strField(arg, "pollIdentity") === "1";
|
|
275
|
+
restorePurchasesRequested ||= s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
271
276
|
// The form opens on the mode its route asked for each time it appears, sign-in by
|
|
272
277
|
// default: a pooled worker reopened with the same params must not open on the mode the
|
|
273
278
|
// last visit toggled to.
|
|
@@ -652,8 +657,7 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
652
657
|
// Not the boot load: it never carries the copy, and the appear refresh that does is coming.
|
|
653
658
|
if (strField(arg, "boot") !== "1") headingReady = true;
|
|
654
659
|
const memberAccountLinks = memberAccountLinksRequested;
|
|
655
|
-
|
|
656
|
-
if (restorePurchases) enterCommerce();
|
|
660
|
+
if (restorePurchasesRequested) enterCommerce();
|
|
657
661
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
658
662
|
let activityRows: AccountActivityRow[] = [];
|
|
659
663
|
if (profile.isMember) {
|
|
@@ -681,7 +685,6 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
681
685
|
email: profile.memberEmail || s.email,
|
|
682
686
|
message: "",
|
|
683
687
|
memberAccountLinks,
|
|
684
|
-
restorePurchases,
|
|
685
688
|
...appearBase(),
|
|
686
689
|
...config.mode,
|
|
687
690
|
...config.visit,
|
|
@@ -234,6 +234,9 @@ let signInPresentationRequested: "" | "sheet" | "full_screen" = "";
|
|
|
234
234
|
let signInReturnTabRequested = "";
|
|
235
235
|
let standaloneRequested = false;
|
|
236
236
|
let pollIdentityRequested = false;
|
|
237
|
+
// iOS can start the arg-less boot load after the appear refresh that asks for the row; the
|
|
238
|
+
// newer boot probe must not land, or be kept, without it.
|
|
239
|
+
let restorePurchasesRequested = false;
|
|
237
240
|
// Bumped by every mode switch, so a dropped probe never puts back a mode the visitor left.
|
|
238
241
|
let modeSwitches = 0;
|
|
239
242
|
|
|
@@ -246,6 +249,7 @@ function appearBase(): Partial<S> {
|
|
|
246
249
|
signInScreen: signInScreenRequested,
|
|
247
250
|
standalone: standaloneRequested,
|
|
248
251
|
pollIdentity: pollIdentityRequested,
|
|
252
|
+
restorePurchases: restorePurchasesRequested,
|
|
249
253
|
...(pollIdentityRequested ? { _poll: { ...IDENTITY_POLL } } : {}),
|
|
250
254
|
};
|
|
251
255
|
}
|
|
@@ -268,6 +272,7 @@ function appearConfig(s: S, arg: unknown): AppearConfig {
|
|
|
268
272
|
// Only the sign-in screen's route carries `mode`, so it marks the form from the boot load on.
|
|
269
273
|
standaloneRequested ||= s.standalone || appearing || (!routeInputConsumed && !!routeInput().mode);
|
|
270
274
|
pollIdentityRequested ||= s.pollIdentity || strField(arg, "pollIdentity") === "1";
|
|
275
|
+
restorePurchasesRequested ||= s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
271
276
|
// The form opens on the mode its route asked for each time it appears, sign-in by
|
|
272
277
|
// default: a pooled worker reopened with the same params must not open on the mode the
|
|
273
278
|
// last visit toggled to.
|
|
@@ -652,8 +657,7 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
652
657
|
// Not the boot load: it never carries the copy, and the appear refresh that does is coming.
|
|
653
658
|
if (strField(arg, "boot") !== "1") headingReady = true;
|
|
654
659
|
const memberAccountLinks = memberAccountLinksRequested;
|
|
655
|
-
|
|
656
|
-
if (restorePurchases) enterCommerce();
|
|
660
|
+
if (restorePurchasesRequested) enterCommerce();
|
|
657
661
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
658
662
|
let activityRows: AccountActivityRow[] = [];
|
|
659
663
|
if (profile.isMember) {
|
|
@@ -681,7 +685,6 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
681
685
|
email: profile.memberEmail || s.email,
|
|
682
686
|
message: "",
|
|
683
687
|
memberAccountLinks,
|
|
684
|
-
restorePurchases,
|
|
685
688
|
...appearBase(),
|
|
686
689
|
...config.mode,
|
|
687
690
|
...config.visit,
|
|
@@ -234,6 +234,9 @@ let signInPresentationRequested: "" | "sheet" | "full_screen" = "";
|
|
|
234
234
|
let signInReturnTabRequested = "";
|
|
235
235
|
let standaloneRequested = false;
|
|
236
236
|
let pollIdentityRequested = false;
|
|
237
|
+
// iOS can start the arg-less boot load after the appear refresh that asks for the row; the
|
|
238
|
+
// newer boot probe must not land, or be kept, without it.
|
|
239
|
+
let restorePurchasesRequested = false;
|
|
237
240
|
// Bumped by every mode switch, so a dropped probe never puts back a mode the visitor left.
|
|
238
241
|
let modeSwitches = 0;
|
|
239
242
|
|
|
@@ -246,6 +249,7 @@ function appearBase(): Partial<S> {
|
|
|
246
249
|
signInScreen: signInScreenRequested,
|
|
247
250
|
standalone: standaloneRequested,
|
|
248
251
|
pollIdentity: pollIdentityRequested,
|
|
252
|
+
restorePurchases: restorePurchasesRequested,
|
|
249
253
|
...(pollIdentityRequested ? { _poll: { ...IDENTITY_POLL } } : {}),
|
|
250
254
|
};
|
|
251
255
|
}
|
|
@@ -268,6 +272,7 @@ function appearConfig(s: S, arg: unknown): AppearConfig {
|
|
|
268
272
|
// Only the sign-in screen's route carries `mode`, so it marks the form from the boot load on.
|
|
269
273
|
standaloneRequested ||= s.standalone || appearing || (!routeInputConsumed && !!routeInput().mode);
|
|
270
274
|
pollIdentityRequested ||= s.pollIdentity || strField(arg, "pollIdentity") === "1";
|
|
275
|
+
restorePurchasesRequested ||= s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
271
276
|
// The form opens on the mode its route asked for each time it appears, sign-in by
|
|
272
277
|
// default: a pooled worker reopened with the same params must not open on the mode the
|
|
273
278
|
// last visit toggled to.
|
|
@@ -652,8 +657,7 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
652
657
|
// Not the boot load: it never carries the copy, and the appear refresh that does is coming.
|
|
653
658
|
if (strField(arg, "boot") !== "1") headingReady = true;
|
|
654
659
|
const memberAccountLinks = memberAccountLinksRequested;
|
|
655
|
-
|
|
656
|
-
if (restorePurchases) enterCommerce();
|
|
660
|
+
if (restorePurchasesRequested) enterCommerce();
|
|
657
661
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
658
662
|
let activityRows: AccountActivityRow[] = [];
|
|
659
663
|
if (profile.isMember) {
|
|
@@ -681,7 +685,6 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
681
685
|
email: profile.memberEmail || s.email,
|
|
682
686
|
message: "",
|
|
683
687
|
memberAccountLinks,
|
|
684
|
-
restorePurchases,
|
|
685
688
|
...appearBase(),
|
|
686
689
|
...config.mode,
|
|
687
690
|
...config.visit,
|
|
@@ -234,6 +234,9 @@ let signInPresentationRequested: "" | "sheet" | "full_screen" = "";
|
|
|
234
234
|
let signInReturnTabRequested = "";
|
|
235
235
|
let standaloneRequested = false;
|
|
236
236
|
let pollIdentityRequested = false;
|
|
237
|
+
// iOS can start the arg-less boot load after the appear refresh that asks for the row; the
|
|
238
|
+
// newer boot probe must not land, or be kept, without it.
|
|
239
|
+
let restorePurchasesRequested = false;
|
|
237
240
|
// Bumped by every mode switch, so a dropped probe never puts back a mode the visitor left.
|
|
238
241
|
let modeSwitches = 0;
|
|
239
242
|
|
|
@@ -246,6 +249,7 @@ function appearBase(): Partial<S> {
|
|
|
246
249
|
signInScreen: signInScreenRequested,
|
|
247
250
|
standalone: standaloneRequested,
|
|
248
251
|
pollIdentity: pollIdentityRequested,
|
|
252
|
+
restorePurchases: restorePurchasesRequested,
|
|
249
253
|
...(pollIdentityRequested ? { _poll: { ...IDENTITY_POLL } } : {}),
|
|
250
254
|
};
|
|
251
255
|
}
|
|
@@ -268,6 +272,7 @@ function appearConfig(s: S, arg: unknown): AppearConfig {
|
|
|
268
272
|
// Only the sign-in screen's route carries `mode`, so it marks the form from the boot load on.
|
|
269
273
|
standaloneRequested ||= s.standalone || appearing || (!routeInputConsumed && !!routeInput().mode);
|
|
270
274
|
pollIdentityRequested ||= s.pollIdentity || strField(arg, "pollIdentity") === "1";
|
|
275
|
+
restorePurchasesRequested ||= s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
271
276
|
// The form opens on the mode its route asked for each time it appears, sign-in by
|
|
272
277
|
// default: a pooled worker reopened with the same params must not open on the mode the
|
|
273
278
|
// last visit toggled to.
|
|
@@ -652,8 +657,7 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
652
657
|
// Not the boot load: it never carries the copy, and the appear refresh that does is coming.
|
|
653
658
|
if (strField(arg, "boot") !== "1") headingReady = true;
|
|
654
659
|
const memberAccountLinks = memberAccountLinksRequested;
|
|
655
|
-
|
|
656
|
-
if (restorePurchases) enterCommerce();
|
|
660
|
+
if (restorePurchasesRequested) enterCommerce();
|
|
657
661
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
658
662
|
let activityRows: AccountActivityRow[] = [];
|
|
659
663
|
if (profile.isMember) {
|
|
@@ -681,7 +685,6 @@ async function probe(s: S, arg?: unknown, config: AppearConfig = appearConfig(s,
|
|
|
681
685
|
email: profile.memberEmail || s.email,
|
|
682
686
|
message: "",
|
|
683
687
|
memberAccountLinks,
|
|
684
|
-
restorePurchases,
|
|
685
688
|
...appearBase(),
|
|
686
689
|
...config.mode,
|
|
687
690
|
...config.visit,
|