@wix/himalaya-cli 0.1575.0 → 0.1577.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/loyalty/src/index.d.ts +64 -6
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/online-programs/src/index.d.ts +87 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-loyalty.mjs +15 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-online-programs.mjs +42 -0
- package/dist/cli.mjs +10821 -10593
- package/dist/preview-assets.generated.bin +0 -0
- package/fixtures/wix-canned.json +56 -3
- package/guides/himi-json-output.md +8 -0
- package/guides/one-app-section-mappings.md +1 -1
- package/guides/one-app-to-himi-app.md +50 -1
- package/guides/sdk-reference.json +133 -9
- package/package.json +2 -2
- package/templates/beauty-salon/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/beauty-salon/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/beauty-salon-owner/dev/index.ts +52 -27
- package/templates/beauty-salon-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/branded-lite/config.ts +7 -0
- package/templates/branded-lite/dev/index.ts +833 -0
- package/templates/branded-lite/himalaya.content.json +3 -0
- package/templates/branded-lite/l10n/en.json +4 -2
- package/templates/branded-lite/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/branded-lite/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/branded-lite/tier5-src/himi-branded-lite-member-programs/index.ts +658 -0
- package/templates/community-club/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/community-club/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/community-club-owner/dev/index.ts +52 -27
- package/templates/community-club-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/events-meetups/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/events-meetups/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/events-meetups-owner/dev/index.ts +52 -27
- package/templates/events-meetups-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/gym-fitness/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/gym-fitness/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/gym-fitness-owner/dev/index.ts +52 -27
- package/templates/gym-fitness-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/himi-chat/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/nonprofit-cause/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/nonprofit-cause/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/nonprofit-cause-owner/dev/index.ts +52 -27
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/owner-lite/dev/index.ts +52 -27
- package/templates/owner-lite/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/podcast-creator/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/podcast-creator/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/podcast-creator-owner/dev/index.ts +52 -27
- package/templates/podcast-creator-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/portfolio-creative/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/portfolio-creative/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/portfolio-creative-owner/dev/index.ts +52 -27
- package/templates/portfolio-creative-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/restaurant/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/restaurant/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/restaurant-owner/dev/index.ts +52 -27
- package/templates/restaurant-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/retail-store/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/retail-store/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/retail-store-owner/dev/index.ts +52 -27
- package/templates/retail-store-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/yoga-studio/config.ts +7 -0
- package/templates/yoga-studio/dev/index.ts +833 -0
- package/templates/yoga-studio/himalaya.content.json +3 -0
- package/templates/yoga-studio/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/yoga-studio/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/yoga-studio/tier5-src/himi-branded-lite-member-programs/index.ts +658 -0
- package/templates/yoga-studio-owner/dev/index.ts +52 -27
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
|
Binary file
|
package/fixtures/wix-canned.json
CHANGED
|
@@ -528,6 +528,59 @@
|
|
|
528
528
|
"total": 0
|
|
529
529
|
}
|
|
530
530
|
},
|
|
531
|
+
"POST /online-programs/v3/participants/query": {
|
|
532
|
+
"participants": [
|
|
533
|
+
{
|
|
534
|
+
"id": "part-0001",
|
|
535
|
+
"programId": "prog-0001",
|
|
536
|
+
"memberId": "mem-0001",
|
|
537
|
+
"enrollmentStatus": "JOINED",
|
|
538
|
+
"progressStatus": "IN_PROGRESS",
|
|
539
|
+
"createdDate": "2026-10-01T09:00:00.000Z",
|
|
540
|
+
"progress": {
|
|
541
|
+
"totalStepsCompleted": 12,
|
|
542
|
+
"totalStepsAvailable": 30,
|
|
543
|
+
"completionPercentage": 40
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
],
|
|
547
|
+
"pagingMetadata": {
|
|
548
|
+
"count": 1,
|
|
549
|
+
"cursors": {
|
|
550
|
+
"next": null
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
"POST /online-programs/v3/participants/stats": {
|
|
555
|
+
"participationStats": [
|
|
556
|
+
{
|
|
557
|
+
"programId": "prog-0001",
|
|
558
|
+
"participantsCount": 18
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
"programId": "prog-0002",
|
|
562
|
+
"participantsCount": 7
|
|
563
|
+
}
|
|
564
|
+
]
|
|
565
|
+
},
|
|
566
|
+
"GET /_api/program-categories-service/v3/categories": {
|
|
567
|
+
"categories": [
|
|
568
|
+
{
|
|
569
|
+
"id": "cat-0001",
|
|
570
|
+
"label": "Brewing",
|
|
571
|
+
"assignedTo": [
|
|
572
|
+
"prog-0001"
|
|
573
|
+
]
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
"id": "cat-0002",
|
|
577
|
+
"label": "Roasting",
|
|
578
|
+
"assignedTo": [
|
|
579
|
+
"prog-0002"
|
|
580
|
+
]
|
|
581
|
+
}
|
|
582
|
+
]
|
|
583
|
+
},
|
|
531
584
|
"POST /online-programs/v3/programs/query": {
|
|
532
585
|
"programs": [
|
|
533
586
|
{
|
|
@@ -954,17 +1007,17 @@
|
|
|
954
1007
|
"total": 2
|
|
955
1008
|
}
|
|
956
1009
|
},
|
|
957
|
-
"GET /loyalty/v1/program": {
|
|
1010
|
+
"GET /loyalty-programs/v1/program": {
|
|
958
1011
|
"loyaltyProgram": {
|
|
959
1012
|
"name": "Roastery Rewards",
|
|
960
1013
|
"status": "ACTIVE",
|
|
961
1014
|
"pointDefinition": {
|
|
962
1015
|
"customName": "beans",
|
|
963
|
-
"icon": "
|
|
1016
|
+
"icon": { "url": "fixture-star.svg" }
|
|
964
1017
|
}
|
|
965
1018
|
}
|
|
966
1019
|
},
|
|
967
|
-
"GET /loyalty/v1/rewards": {
|
|
1020
|
+
"GET /loyalty-rewards/v1/rewards": {
|
|
968
1021
|
"rewards": [
|
|
969
1022
|
{
|
|
970
1023
|
"id": "rw-0001",
|
|
@@ -14,6 +14,14 @@ require those fields. Existing error-only push refusals now also carry `ok: fals
|
|
|
14
14
|
Output channels and process exit codes are unchanged. Read JSON failures on both
|
|
15
15
|
stdout and stderr; progress/warnings are not failure envelopes.
|
|
16
16
|
|
|
17
|
+
## `himi store preflight` / `himi store upload` / `himi testflight` config failures
|
|
18
|
+
|
|
19
|
+
| Code | Meaning |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `store_config_unavailable` | Loading the local store configuration threw an error, such as a missing or unreadable file. Exit 2; no build or upload runs. The existing `error` remains on stderr, alongside `findings` from the app preflight, including developer identity diagnostics available without store configuration. If preflight itself fails, its diagnostic is included as an error finding. |
|
|
22
|
+
|
|
23
|
+
Other legacy store failures, including `store status`, remain outside this migration.
|
|
24
|
+
|
|
17
25
|
`code` is the machine contract. `error`/`errors`/`message` describe the failure for
|
|
18
26
|
people and `hint`, when present, suggests recovery. Neither their wording nor the
|
|
19
27
|
presence of one of those legacy shapes identifies the failure class. The complete
|
|
@@ -47,7 +47,7 @@ The **Himalaya implementation** cell is blank for every unassigned row. Notes on
|
|
|
47
47
|
|
|
48
48
|
| Source sectionDefinitionId | Source viewer component | Himalaya implementation | Placement / reuse | Class | Settings, actions and gaps |
|
|
49
49
|
| --- | --- | --- | --- | --- | --- |
|
|
50
|
-
| `achievements_list_section` | `wix-one-app-achievements.SectionMemberChallengesScreen` | [Programs list/detail](https://github.com/wix-private/himalaya/blob/97f1542f2f7d6e8cb7a902b912c87dcaa37e5a67/apps/himi-branded-lite/dev/index.ts) + [programs worker](https://github.com/wix-private/himalaya/blob/97f1542f2f7d6e8cb7a902b912c87dcaa37e5a67/core/dev-server/tier5-bundles-src/himi-branded-lite-programs/index.ts "audience-lint-ok: optional pinned upstream evidence, not a local authoring dependency") | Existing base;
|
|
50
|
+
| `achievements_list_section` | `wix-one-app-achievements.SectionMemberChallengesScreen` | [Programs list/detail](https://github.com/wix-private/himalaya/blob/97f1542f2f7d6e8cb7a902b912c87dcaa37e5a67/apps/himi-branded-lite/dev/index.ts) + [programs worker](https://github.com/wix-private/himalaya/blob/97f1542f2f7d6e8cb7a902b912c87dcaa37e5a67/core/dev-server/tier5-bundles-src/himi-branded-lite-programs/index.ts "audience-lint-ok: optional pinned upstream evidence, not a local authoring dependency") | Existing base; member list added | Partial | `himi_member_programs` (worker `himi-branded-lite-member-programs`) is the member list: each card carries the signed-in member's standing from Participants v3 / Join Applications v3 (Joined, Program complete, Program ended, Pending request, Request approved, Invited, Participation suspended), a progress bar once started, the price before joining, the "All programs / Programs I joined" and category filters, cursor paging and pull-to-refresh; an ended program the member never joined is dropped. Still open: the 2-card section mode with "See all" (`extraProps.limit=2`, inline composition), join / cancel-request actions on the card itself (the card opens the program, which owns them), and Pricing Plans benefits ("Included in your plan"). |
|
|
51
51
|
| `achievements_carousel_section` | `wix-one-app-achievements.MemberChallengesCarousel` | [Programs data/detail](https://github.com/wix-private/himalaya/blob/97f1542f2f7d6e8cb7a902b912c87dcaa37e5a67/core/dev-server/tier5-bundles-src/himi-branded-lite-programs/index.ts "audience-lint-ok: optional pinned upstream evidence, not a local authoring dependency") + [Core Carousel](https://github.com/wix-private/himalaya/blob/97f1542f2f7d6e8cb7a902b912c87dcaa37e5a67/core/dev-server/src/builder.ts "audience-lint-ok: optional pinned upstream evidence, not a local authoring dependency") | Existing base; adaptation needed | Partial | Reuse the Programs feature and compose a carousel; preserve source extraProps.limit=5 and selected programs. No ready-made legacy Challenges carousel adapter is claimed. |
|
|
52
52
|
| `achievements_participant_carousel_section` | `wix-one-app-achievements.ParticipantChallengesCarousel` | | | Empty | The public Programs catalog is not a member-participating-programs carousel. No verified consumer participant/progress list implementation was found. |
|
|
53
53
|
|
|
@@ -255,7 +255,10 @@ Apply these interpretation rules:
|
|
|
255
255
|
bar that cannot be inspected is reported as unverified. The maintained `inviteAction`
|
|
256
256
|
builder is recognized; its conditional ID and hidden binding must also appear in
|
|
257
257
|
`topBarDefault.actions` with a configured `navLogicBundle`, even when the screen
|
|
258
|
-
overrides its bar.
|
|
258
|
+
overrides its bar. Observer/listener badges require live count bindings with
|
|
259
|
+
matching action IDs/value paths in the nav default and an accessible label.
|
|
260
|
+
Static counts cannot stand in for unavailable source data. A screen-only
|
|
261
|
+
binding is not subscribed. Platform definitions establish
|
|
259
262
|
a feature to account for; they do not alone prove visibility or access for every
|
|
260
263
|
visitor or member. Resolve those rules separately. This check is specific to this
|
|
261
264
|
migration workflow; it does not change the behavior of `himi validate`.
|
|
@@ -446,6 +449,52 @@ Apply these interpretation rules:
|
|
|
446
449
|
shared. No invitation is created while migrating or just loading the screen.
|
|
447
450
|
Source Invite produces an `interaction` coverage row requiring behavioral proof;
|
|
448
451
|
unresolved transport or permissions remain gaps, never silent omission.
|
|
452
|
+
- **Preserve source badge behavior.** Collected button definitions retain
|
|
453
|
+
`badgeObserverId`, `badgeListenerId` and `showBadgeOnVisitorMode`. Keep the
|
|
454
|
+
counter's actual site/member/shopper scope and visitor policy; the source's
|
|
455
|
+
ordinary observer/listener button defaults to member-only observation when the
|
|
456
|
+
visitor flag is absent. Coverage inventories these counters as separate
|
|
457
|
+
behavioral obligations for raw, iOS and Android definitions. It also inventories
|
|
458
|
+
custom-component behavior: a custom component can own a counter internally,
|
|
459
|
+
without observer/listener fields. Do not infer a count badge for every custom
|
|
460
|
+
component. Inspect its implementation and retain unknown behavior as unresolved.
|
|
461
|
+
|
|
462
|
+
Use a live `badge: { kind: "count", valuePath: "$service:sourceBadges.count" }`
|
|
463
|
+
only after implementing the actual source counter. Preserve the source button
|
|
464
|
+
ID, or map its current `top-bar` coverage row to the target `screenId` and
|
|
465
|
+
`controlId` when renaming it. A sibling action's badge cannot satisfy that row;
|
|
466
|
+
changed source definitions invalidate the mapping. Declare the same action ID
|
|
467
|
+
and value path in `navigation.topBarDefault.actions` and any complete screen
|
|
468
|
+
override, with `navLogicBundle`. Action IDs must be unique in each bar; distinct
|
|
469
|
+
source counters need distinct target actions within each source platform. Both
|
|
470
|
+
actions need their own tap handler and accessible label. Do not supply a static
|
|
471
|
+
`value` as a fallback. The top-bar check establishes inspectable wiring, not
|
|
472
|
+
the counter's data source, availability, refresh, permission or accessibility
|
|
473
|
+
behavior. A configured worker URL alone proves none of those.
|
|
474
|
+
|
|
475
|
+
Keep a successful zero as `0` and unavailable as `null`; verify positive, zero,
|
|
476
|
+
failed/missing reads and source/site/account replacement, including a delayed
|
|
477
|
+
response from the previous identity. Verify badge visibility and screen-reader
|
|
478
|
+
output against the source. A persistent nav worker needs a supported refresh
|
|
479
|
+
path; a screen-only load, page-row count or foreground push receipt count is
|
|
480
|
+
insufficient. The source Member notification aggregate is MOBILE/UNSEEN, capped
|
|
481
|
+
at100. `countUnseenNotifications({ site: boundMetaSiteId })` reads that aggregate
|
|
482
|
+
through the source Member route. It requires the updated native core, rebuilt
|
|
483
|
+
consuming binaries and published SDK; default web and old binaries remain
|
|
484
|
+
unavailable for this reader. Never replace that refusal with zero.
|
|
485
|
+
Chat counts unread rooms, while legacy cart counters can include unsynced local
|
|
486
|
+
quantities; a different shopper's or headless cart's zero is not a substitute.
|
|
487
|
+
If the source reader/refresh path is unverified, leave that badge unresolved.
|
|
488
|
+
Changing a button definition or its visitor policy invalidates its previous
|
|
489
|
+
coverage mapping and requires new behavioral evidence. `coverage sync` replaces
|
|
490
|
+
changed or moved header rows for the same source button within its bar with
|
|
491
|
+
unmapped rows. A one-to-one change between an observer/listener badge and a
|
|
492
|
+
custom component is a replacement. A different button at an old index, or a
|
|
493
|
+
remaining custom behavior after its explicit badge is removed, cannot hide a
|
|
494
|
+
removal. Older ledger rows without stable `sourceButtonId` metadata require
|
|
495
|
+
explicit reconciliation when changed; syncing unchanged evidence adds that
|
|
496
|
+
metadata. Removing a button or behavior without a replacement still requires
|
|
497
|
+
explicit ledger reconciliation.
|
|
449
498
|
- Verify the migrated app's native top bar, bottom tabs, back navigation and
|
|
450
499
|
configured actions on the affected devices, including RTL. A web screenshot
|
|
451
500
|
alone does not prove native navigation or control availability. Record any
|
|
@@ -22898,44 +22898,70 @@
|
|
|
22898
22898
|
"jsdoc": "/** The per-call header map for `opts`, or undefined when there is nothing to add — so\n * the no-options path calls the bridge with exactly the 3 arguments it always did. */",
|
|
22899
22899
|
"decl": "export function wixCall<T>(method: string, path: string, body?: unknown, readOptions?: WixCallOptions): Promise<T>;"
|
|
22900
22900
|
},
|
|
22901
|
+
{
|
|
22902
|
+
"name": "WixLoyaltyImage",
|
|
22903
|
+
"kind": "interface",
|
|
22904
|
+
"jsdoc": "",
|
|
22905
|
+
"decl": "export interface WixLoyaltyImage {\n id?: string;\n url?: string;\n height?: number;\n width?: number;\n altText?: string;\n filename?: string;\n}"
|
|
22906
|
+
},
|
|
22907
|
+
{
|
|
22908
|
+
"name": "WixLoyaltyRewardConfig",
|
|
22909
|
+
"kind": "interface",
|
|
22910
|
+
"jsdoc": "",
|
|
22911
|
+
"decl": "export interface WixLoyaltyRewardConfig {\n tierId?: string;\n costInPoints?: number;\n amount?: number;\n percentage?: number;\n}"
|
|
22912
|
+
},
|
|
22901
22913
|
{
|
|
22902
22914
|
"name": "WixLoyaltyProgram",
|
|
22903
22915
|
"kind": "interface",
|
|
22904
22916
|
"jsdoc": "",
|
|
22905
|
-
"decl": "export interface WixLoyaltyProgram {\n id?: string;\n name?: string;\n /** ACTIVE | DRAFT | PAUSED */\n status?: string;\n pointDefinition?: { customName?: string; icon?:
|
|
22917
|
+
"decl": "export interface WixLoyaltyProgram {\n id?: string;\n name?: string;\n /** ACTIVE | DRAFT | PAUSED */\n status?: string;\n pointDefinition?: { customName?: string; icon?: WixLoyaltyImage };\n}"
|
|
22906
22918
|
},
|
|
22907
22919
|
{
|
|
22908
22920
|
"name": "WixLoyaltyReward",
|
|
22909
22921
|
"kind": "interface",
|
|
22910
22922
|
"jsdoc": "",
|
|
22911
|
-
"decl": "export interface WixLoyaltyReward {\n id: string;\n name?: string;\n type?: string;\n requiredPoints?: number;\n active?: boolean;\n}"
|
|
22923
|
+
"decl": "export interface WixLoyaltyReward {\n id: string;\n name?: string;\n type?: string;\n /** Legacy adapter field. REST costs live in the reward's tier configurations. */\n requiredPoints?: number;\n discountAmount?: { configsByTier?: { tierId?: string; costInPoints?: number; amount?: string }[] };\n couponReward?: {\n fixedAmount?: { configsByTier?: WixLoyaltyRewardConfig[] };\n percentage?: { configsByTier?: WixLoyaltyRewardConfig[] };\n freeShipping?: { configsByTier?: WixLoyaltyRewardConfig[] };\n };\n active?: boolean;\n}"
|
|
22912
22924
|
},
|
|
22913
22925
|
{
|
|
22914
22926
|
"name": "WixLoyaltyTier",
|
|
22915
22927
|
"kind": "interface",
|
|
22916
22928
|
"jsdoc": "",
|
|
22917
|
-
"decl": "export interface WixLoyaltyTier {\n /** REST returns `id` (proto `_id`). */\n id?: string;\n tierDefinition?: { name?: string; icon?:
|
|
22929
|
+
"decl": "export interface WixLoyaltyTier {\n /** REST returns `id` (proto `_id`). */\n id?: string;\n tierDefinition?: { name?: string; icon?: WixLoyaltyImage };\n requiredPoints?: number;\n}"
|
|
22930
|
+
},
|
|
22931
|
+
{
|
|
22932
|
+
"name": "WixLoyaltyEarningRule",
|
|
22933
|
+
"kind": "interface",
|
|
22934
|
+
"jsdoc": "",
|
|
22935
|
+
"decl": "export interface WixLoyaltyEarningRule {\n id?: string;\n title?: string;\n status?: string;\n triggerActivityType?: string;\n fixedAmount?: { configs?: { tierId?: string; points?: number }[] };\n conversionRate?: { field?: string; configs?: { tierId?: string; moneyAmount?: number; points?: number }[] };\n}"
|
|
22918
22936
|
},
|
|
22919
22937
|
{
|
|
22920
22938
|
"name": "getLoyaltyProgram",
|
|
22921
22939
|
"kind": "function",
|
|
22922
|
-
"jsdoc": "/** GET /loyalty/v1/program → { loyaltyProgram }. */",
|
|
22940
|
+
"jsdoc": "/** GET /loyalty-programs/v1/program → { loyaltyProgram }. */",
|
|
22923
22941
|
"decl": "export function getLoyaltyProgram(readOptions?: WixCallOptions): Promise<{ loyaltyProgram?: WixLoyaltyProgram; program?: WixLoyaltyProgram }>;",
|
|
22924
|
-
"http": "GET /loyalty/v1/program"
|
|
22942
|
+
"http": "GET /loyalty-programs/v1/program"
|
|
22925
22943
|
},
|
|
22926
22944
|
{
|
|
22927
22945
|
"name": "listLoyaltyRewards",
|
|
22928
22946
|
"kind": "function",
|
|
22929
|
-
"jsdoc": "/** GET /loyalty/v1/rewards → { rewards }. */",
|
|
22947
|
+
"jsdoc": "/** GET /loyalty-rewards/v1/rewards → { rewards }. */",
|
|
22930
22948
|
"decl": "export function listLoyaltyRewards(readOptions?: WixCallOptions): Promise<{ rewards?: WixLoyaltyReward[] }>;",
|
|
22931
|
-
"http": "GET /loyalty/v1/rewards"
|
|
22949
|
+
"http": "GET /loyalty-rewards/v1/rewards"
|
|
22932
22950
|
},
|
|
22933
22951
|
{
|
|
22934
22952
|
"name": "listLoyaltyTiers",
|
|
22935
22953
|
"kind": "function",
|
|
22936
|
-
"jsdoc": "/** GET /loyalty/v1/tiers → { tiers }. The
|
|
22954
|
+
"jsdoc": "/** GET /loyalty-tiers/v1/tiers → { tiers }. The program tier ladder. */",
|
|
22937
22955
|
"decl": "export function listLoyaltyTiers(readOptions?: WixCallOptions): Promise<{ tiers?: WixLoyaltyTier[] }>;",
|
|
22938
|
-
"http": "GET /loyalty/v1/tiers"
|
|
22956
|
+
"http": "GET /loyalty-tiers/v1/tiers"
|
|
22957
|
+
},
|
|
22958
|
+
{
|
|
22959
|
+
"name": "listLoyaltyEarningRules",
|
|
22960
|
+
"kind": "function",
|
|
22961
|
+
"jsdoc": "/** Active and inactive earning rules in their raw REST shape; callers choose visibility.\n * @scope visitor\n */",
|
|
22962
|
+
"decl": "export function listLoyaltyEarningRules(readOptions?: WixCallOptions): Promise<{ earningRules?: WixLoyaltyEarningRule[] }>;",
|
|
22963
|
+
"http": "GET /_api/loyalty-earning-rules/v1/earning-rules/rules",
|
|
22964
|
+
"scope": "visitor"
|
|
22939
22965
|
},
|
|
22940
22966
|
{
|
|
22941
22967
|
"name": "LoyaltyOverview",
|
|
@@ -24094,6 +24120,104 @@
|
|
|
24094
24120
|
"kind": "function",
|
|
24095
24121
|
"jsdoc": "/** The cashier handle to settle, or \"\" when no payable order is available. */",
|
|
24096
24122
|
"decl": "export function payableIdOf(participant?: WixJoinedParticipant): string;"
|
|
24123
|
+
},
|
|
24124
|
+
{
|
|
24125
|
+
"name": "MEMBER_ENROLLMENT_STATUSES",
|
|
24126
|
+
"kind": "const",
|
|
24127
|
+
"jsdoc": "/** `Participant.enrollmentStatus` values the member list filters on. */",
|
|
24128
|
+
"decl": "export const MEMBER_ENROLLMENT_STATUSES = {\n joined: \"JOINED\",\n suspended: \"SUSPENDED\",\n unknown: \"UNKNOWN_ENROLLMENT_STATUS\",\n} as const;"
|
|
24129
|
+
},
|
|
24130
|
+
{
|
|
24131
|
+
"name": "MEMBER_FINISHED_PROGRESS_STATUSES",
|
|
24132
|
+
"kind": "const",
|
|
24133
|
+
"jsdoc": "/** `Participant.progressStatus` values that still count as a membership once the enrollment is over. */",
|
|
24134
|
+
"decl": "export const MEMBER_FINISHED_PROGRESS_STATUSES = [\"COMPLETED\", \"FAILED\"] as const;"
|
|
24135
|
+
},
|
|
24136
|
+
{
|
|
24137
|
+
"name": "WixMemberParticipantsQuery",
|
|
24138
|
+
"kind": "interface",
|
|
24139
|
+
"jsdoc": "",
|
|
24140
|
+
"decl": "export interface WixMemberParticipantsQuery {\n /** The signed-in member's id (`getMyMember().member.id`). Required: without it the query is the roster of everyone. */\n memberId: string;\n /** The `pagingMetadata.cursors.next` of the previous page; omit for the first page. */\n cursor?: string;\n /** Page size, default 100 (the upstream page cap for this query). */\n limit?: number;\n}"
|
|
24141
|
+
},
|
|
24142
|
+
{
|
|
24143
|
+
"name": "WixQueryMemberParticipantsResponse",
|
|
24144
|
+
"kind": "interface",
|
|
24145
|
+
"jsdoc": "",
|
|
24146
|
+
"decl": "export interface WixQueryMemberParticipantsResponse extends WixQueryParticipantsResponse {\n pagingMetadata?: WixQueryParticipantsResponse[\"pagingMetadata\"] & { cursors?: { next?: string | null } };\n}"
|
|
24147
|
+
},
|
|
24148
|
+
{
|
|
24149
|
+
"name": "queryMemberParticipants",
|
|
24150
|
+
"kind": "function",
|
|
24151
|
+
"jsdoc": "/**\n * POST /online-programs/v3/participants/query — the MEMBER'S participations, cursor-paged, with\n * progress. Joined and suspended enrollments, plus completed/failed ones whose enrollment has\n * ended, so a finished program still shows its outcome; left, removed and auto-removed\n * memberships are excluded. The query language has no `programId: {$in}` on this\n * endpoint, so callers match memberships to displayed programs locally.\n *\n * @scope member — requires the signed-in site member; `memberId` must be that member's own id\n * (`getMyMember().member.id`). An empty `participants` list means the member has no such\n * membership, never that the read failed: a failure rejects.\n */",
|
|
24152
|
+
"decl": "export function queryMemberParticipants(opts: WixMemberParticipantsQuery): Promise<WixQueryMemberParticipantsResponse>;",
|
|
24153
|
+
"http": "POST /online-programs/v3/participants/query",
|
|
24154
|
+
"scope": "member"
|
|
24155
|
+
},
|
|
24156
|
+
{
|
|
24157
|
+
"name": "WixProgramParticipationStats",
|
|
24158
|
+
"kind": "interface",
|
|
24159
|
+
"jsdoc": "",
|
|
24160
|
+
"decl": "export interface WixProgramParticipationStats {\n programId?: string;\n participantsCount?: number;\n autoRemovedCount?: number;\n}"
|
|
24161
|
+
},
|
|
24162
|
+
{
|
|
24163
|
+
"name": "WixGetParticipationStatsResponse",
|
|
24164
|
+
"kind": "interface",
|
|
24165
|
+
"jsdoc": "",
|
|
24166
|
+
"decl": "export interface WixGetParticipationStatsResponse { participationStats?: WixProgramParticipationStats[] }"
|
|
24167
|
+
},
|
|
24168
|
+
{
|
|
24169
|
+
"name": "getParticipationStats",
|
|
24170
|
+
"kind": "function",
|
|
24171
|
+
"jsdoc": "/** POST /online-programs/v3/participants/stats — participant counts for a batch of programs (one call per page).\n * `programIds` must be non-empty (an empty batch returns `{ participationStats: [] }` without a call);\n * a program missing from the answer has no count, not zero.\n * @scope visitor — counts are public; an anonymous visitor session is enough. */",
|
|
24172
|
+
"decl": "export function getParticipationStats(programIds: string[]): Promise<WixGetParticipationStatsResponse>;",
|
|
24173
|
+
"http": "POST /online-programs/v3/participants/stats",
|
|
24174
|
+
"scope": "visitor"
|
|
24175
|
+
},
|
|
24176
|
+
{
|
|
24177
|
+
"name": "WixJoinApplicationStatus",
|
|
24178
|
+
"kind": "type",
|
|
24179
|
+
"jsdoc": "/** `JoinApplication.status` — the member's standing BEFORE a participant exists (a private or paid program). */",
|
|
24180
|
+
"decl": "export type WixJoinApplicationStatus =\n | \"INVITED\"\n | \"APPROVAL_PENDING\"\n | \"APPROVED\"\n | \"PAYMENT_PENDING\"\n | \"SUSPENDED\"\n | \"DECLINED\"\n | \"CANCELLED\"\n | string;"
|
|
24181
|
+
},
|
|
24182
|
+
{
|
|
24183
|
+
"name": "WixJoinApplication",
|
|
24184
|
+
"kind": "interface",
|
|
24185
|
+
"jsdoc": "",
|
|
24186
|
+
"decl": "export interface WixJoinApplication {\n id?: string;\n programId?: string;\n memberId?: string;\n status?: WixJoinApplicationStatus;\n paymentStatus?: string;\n /** Set once the application became a participant. */\n participantId?: string;\n createdDate?: string;\n updatedDate?: string;\n}"
|
|
24187
|
+
},
|
|
24188
|
+
{
|
|
24189
|
+
"name": "WixGetCurrentJoinApplicationResponse",
|
|
24190
|
+
"kind": "interface",
|
|
24191
|
+
"jsdoc": "",
|
|
24192
|
+
"decl": "export interface WixGetCurrentJoinApplicationResponse { joinApplication?: WixJoinApplication }"
|
|
24193
|
+
},
|
|
24194
|
+
{
|
|
24195
|
+
"name": "getCurrentJoinApplication",
|
|
24196
|
+
"kind": "function",
|
|
24197
|
+
"jsdoc": "/** GET /online-programs/participants/v3/join-applications/current/{programId} — the signed-in member's\n * own application to ONE program, or none. Used per card only where an application can exist\n * (a private or a priced program the member has not joined). An answer with no `joinApplication`\n * means the member never applied.\n * @scope member — requires the signed-in site member; a visitor session has no application to read. */",
|
|
24198
|
+
"decl": "export function getCurrentJoinApplication(programId: string): Promise<WixGetCurrentJoinApplicationResponse>;",
|
|
24199
|
+
"http": "GET /online-programs/participants/v3/join-applications/current/{…}",
|
|
24200
|
+
"scope": "member"
|
|
24201
|
+
},
|
|
24202
|
+
{
|
|
24203
|
+
"name": "WixProgramCategory",
|
|
24204
|
+
"kind": "interface",
|
|
24205
|
+
"jsdoc": "",
|
|
24206
|
+
"decl": "export interface WixProgramCategory {\n id?: string;\n label?: string;\n /** Program ids the category is assigned to. */\n assignedTo?: string[];\n}"
|
|
24207
|
+
},
|
|
24208
|
+
{
|
|
24209
|
+
"name": "WixListProgramCategoriesResponse",
|
|
24210
|
+
"kind": "interface",
|
|
24211
|
+
"jsdoc": "",
|
|
24212
|
+
"decl": "export interface WixListProgramCategoriesResponse { categories?: WixProgramCategory[] }"
|
|
24213
|
+
},
|
|
24214
|
+
{
|
|
24215
|
+
"name": "listProgramCategories",
|
|
24216
|
+
"kind": "function",
|
|
24217
|
+
"jsdoc": "/** GET /_api/program-categories-service/v3/categories — every program category of the site (the\n * category filter's options). `/_api/…` paths ride the same bridge as the public ones (forms,\n * bookings-v2 and ecom already do). An empty `categories` list means the site has none.\n * @scope member — the One App member programs list calls it with the member's identity. NOT verified\n * live here: codegen/wix/auto/lock.json lists only the APP identity (ONLINE_PROGRAMS.CATEGORY_READ), so a\n * visitor or member token can get 403. A caller must treat a rejection as \"no category filter\", never\n * as an error screen. */",
|
|
24218
|
+
"decl": "export function listProgramCategories(): Promise<WixListProgramCategoriesResponse>;",
|
|
24219
|
+
"http": "GET /_api/program-categories-service/v3/categories",
|
|
24220
|
+
"scope": "member"
|
|
24097
24221
|
}
|
|
24098
24222
|
]
|
|
24099
24223
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1577.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": "9902ef55d169da2c82868b986ceafb0c54b8102e501f513b72e4c8c0"
|
|
75
75
|
}
|
|
@@ -119,6 +119,7 @@ export const HOSTED_SCREEN_VERTICALS: Readonly<Record<string, readonly BrandedLi
|
|
|
119
119
|
himi_portfolio: ["portfolio"],
|
|
120
120
|
himi_portfolio_project: ["portfolio"],
|
|
121
121
|
himi_programs: ["programs"],
|
|
122
|
+
himi_member_programs: ["programs"],
|
|
122
123
|
himi_reservations: ["reservations"],
|
|
123
124
|
himi_reserve: ["restaurants"],
|
|
124
125
|
himi_review: ["reviews"],
|
|
@@ -194,6 +194,14 @@ export function isTransportFailure(e: unknown): boolean {
|
|
|
194
194
|
return TRANSPORT.some((re) => re.test(msg));
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
/** A failed READ says nothing about the record's existence when Wix is
|
|
198
|
+
* unreachable, overloaded or failing. Unlike the legacy bridge predicate this
|
|
199
|
+
* is independent of preview mode; a live preview's gateway failure is one too. */
|
|
200
|
+
export function readWasUnreachable(e: unknown): boolean {
|
|
201
|
+
const msg = String((e as Error)?.message ?? e ?? "");
|
|
202
|
+
return isTransportFailure(e) || /HTTP (?:408|429|5\d{2})\b/.test(msg);
|
|
203
|
+
}
|
|
204
|
+
|
|
197
205
|
/** Transport failures that happen while CONNECTING — no connection, no route, no such host,
|
|
198
206
|
* connection refused — so the request provably never left the device. Every other
|
|
199
207
|
* transport failure (a timeout, a reset, a bad or truncated response, a browser's fetch
|
|
@@ -65684,16 +65684,17 @@ const SCREENS = runtimeSetting({
|
|
|
65684
65684
|
"type": "VStack",
|
|
65685
65685
|
"props": {
|
|
65686
65686
|
"spacing": 10,
|
|
65687
|
+
"alignment": "leading",
|
|
65687
65688
|
"children": [
|
|
65688
65689
|
{
|
|
65689
|
-
"id": "himi_owner_lite_inbox_thread.
|
|
65690
|
+
"id": "himi_owner_lite_inbox_thread.loading_text",
|
|
65690
65691
|
"body": {
|
|
65691
65692
|
"package": "himalaya",
|
|
65692
|
-
"type": "
|
|
65693
|
+
"type": "Text",
|
|
65693
65694
|
"props": {
|
|
65694
|
-
"
|
|
65695
|
-
"
|
|
65696
|
-
"
|
|
65695
|
+
"text": "Loading conversation…",
|
|
65696
|
+
"style": "body",
|
|
65697
|
+
"color": "textSecondary"
|
|
65697
65698
|
}
|
|
65698
65699
|
}
|
|
65699
65700
|
},
|
|
@@ -65701,51 +65702,75 @@ const SCREENS = runtimeSetting({
|
|
|
65701
65702
|
"id": "",
|
|
65702
65703
|
"body": {
|
|
65703
65704
|
"package": "himalaya",
|
|
65704
|
-
"type": "
|
|
65705
|
+
"type": "VStack",
|
|
65705
65706
|
"props": {
|
|
65707
|
+
"spacing": 10,
|
|
65706
65708
|
"children": [
|
|
65709
|
+
{
|
|
65710
|
+
"id": "himi_owner_lite_inbox_thread.sk1",
|
|
65711
|
+
"body": {
|
|
65712
|
+
"package": "himalaya",
|
|
65713
|
+
"type": "Skeleton",
|
|
65714
|
+
"props": {
|
|
65715
|
+
"width": 220,
|
|
65716
|
+
"height": 44,
|
|
65717
|
+
"cornerRadius": 16
|
|
65718
|
+
}
|
|
65719
|
+
}
|
|
65720
|
+
},
|
|
65707
65721
|
{
|
|
65708
65722
|
"id": "",
|
|
65709
65723
|
"body": {
|
|
65710
65724
|
"package": "himalaya",
|
|
65711
|
-
"type": "
|
|
65712
|
-
"props": {
|
|
65725
|
+
"type": "HStack",
|
|
65726
|
+
"props": {
|
|
65727
|
+
"children": [
|
|
65728
|
+
{
|
|
65729
|
+
"id": "",
|
|
65730
|
+
"body": {
|
|
65731
|
+
"package": "himalaya",
|
|
65732
|
+
"type": "Spacer",
|
|
65733
|
+
"props": {}
|
|
65734
|
+
}
|
|
65735
|
+
},
|
|
65736
|
+
{
|
|
65737
|
+
"id": "himi_owner_lite_inbox_thread.sk2",
|
|
65738
|
+
"body": {
|
|
65739
|
+
"package": "himalaya",
|
|
65740
|
+
"type": "Skeleton",
|
|
65741
|
+
"props": {
|
|
65742
|
+
"width": 180,
|
|
65743
|
+
"height": 44,
|
|
65744
|
+
"cornerRadius": 16
|
|
65745
|
+
}
|
|
65746
|
+
}
|
|
65747
|
+
}
|
|
65748
|
+
]
|
|
65749
|
+
}
|
|
65713
65750
|
}
|
|
65714
65751
|
},
|
|
65715
65752
|
{
|
|
65716
|
-
"id": "himi_owner_lite_inbox_thread.
|
|
65753
|
+
"id": "himi_owner_lite_inbox_thread.sk3",
|
|
65717
65754
|
"body": {
|
|
65718
65755
|
"package": "himalaya",
|
|
65719
65756
|
"type": "Skeleton",
|
|
65720
65757
|
"props": {
|
|
65721
|
-
"width":
|
|
65722
|
-
"height":
|
|
65758
|
+
"width": 240,
|
|
65759
|
+
"height": 64,
|
|
65723
65760
|
"cornerRadius": 16
|
|
65724
65761
|
}
|
|
65725
65762
|
}
|
|
65726
65763
|
}
|
|
65727
65764
|
]
|
|
65728
65765
|
}
|
|
65729
|
-
}
|
|
65730
|
-
|
|
65731
|
-
|
|
65732
|
-
|
|
65733
|
-
"body": {
|
|
65734
|
-
"package": "himalaya",
|
|
65735
|
-
"type": "Skeleton",
|
|
65736
|
-
"props": {
|
|
65737
|
-
"width": 240,
|
|
65738
|
-
"height": 64,
|
|
65739
|
-
"cornerRadius": 16
|
|
65740
|
-
}
|
|
65766
|
+
},
|
|
65767
|
+
"modifiers": {
|
|
65768
|
+
"fillMaxWidth": true,
|
|
65769
|
+
"accessibilityRole": "decorative"
|
|
65741
65770
|
}
|
|
65742
65771
|
}
|
|
65743
65772
|
]
|
|
65744
65773
|
}
|
|
65745
|
-
},
|
|
65746
|
-
"modifiers": {
|
|
65747
|
-
"fillMaxWidth": true,
|
|
65748
|
-
"accessibilityRole": "decorative"
|
|
65749
65774
|
}
|
|
65750
65775
|
}
|
|
65751
65776
|
},
|
|
@@ -194,6 +194,14 @@ export function isTransportFailure(e: unknown): boolean {
|
|
|
194
194
|
return TRANSPORT.some((re) => re.test(msg));
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
/** A failed READ says nothing about the record's existence when Wix is
|
|
198
|
+
* unreachable, overloaded or failing. Unlike the legacy bridge predicate this
|
|
199
|
+
* is independent of preview mode; a live preview's gateway failure is one too. */
|
|
200
|
+
export function readWasUnreachable(e: unknown): boolean {
|
|
201
|
+
const msg = String((e as Error)?.message ?? e ?? "");
|
|
202
|
+
return isTransportFailure(e) || /HTTP (?:408|429|5\d{2})\b/.test(msg);
|
|
203
|
+
}
|
|
204
|
+
|
|
197
205
|
/** Transport failures that happen while CONNECTING — no connection, no route, no such host,
|
|
198
206
|
* connection refused — so the request provably never left the device. Every other
|
|
199
207
|
* transport failure (a timeout, a reset, a bad or truncated response, a browser's fetch
|
|
@@ -10,7 +10,7 @@ import { getPost, getDraftPost, publishDraftPost, revertDraftPost, deleteDraftPo
|
|
|
10
10
|
import { parseRicosJson } from "@himalaya/wix-rich-content";
|
|
11
11
|
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
12
12
|
import { richBody } from "../_shared/rich-body.js";
|
|
13
|
-
import { ownerLoadError, isBridgeUnavailable,
|
|
13
|
+
import { ownerLoadError, isBridgeUnavailable, readWasUnreachable, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError, isNotFound } from "../_shared/owner-load-error.js";
|
|
14
14
|
import { DEMO_POSTS, DEMO_NOTE, DEMO_SAVE_NOTE } from "../_shared/owner-preview-demo.js";
|
|
15
15
|
import { stashCopy, copyParam } from "../_shared/himi-copy.js";
|
|
16
16
|
import { get as dbGet, upsert as dbUpsert, remove as dbRemove, type DbEntity } from "../_shared/owner-local-db.js";
|
|
@@ -270,14 +270,24 @@ async function refresh(prev: PostState, id: string, actionMessage = "", opts: {
|
|
|
270
270
|
try { post = (await getPost(id)).post; } catch (e) { lastError = postError = e; /* draft-only */ }
|
|
271
271
|
try { draft = (await getDraftPost(id)).draftPost; } catch (e) { lastError = e; /* published-only or missing */ }
|
|
272
272
|
if (!post && !draft) {
|
|
273
|
-
// Both arms swallowed their errors above
|
|
274
|
-
//
|
|
275
|
-
// back to the cached row or the demo post — never "post not found" for a post
|
|
276
|
-
// that was only unreachable.
|
|
273
|
+
// Both arms swallowed their errors above. Neither a failed published read
|
|
274
|
+
// nor a missing draft proves the post is gone.
|
|
277
275
|
// Either read counts: a published-only post's draft read is always a 404, so the
|
|
278
276
|
// published read's failure is the one that says whether the post was only unreachable.
|
|
279
277
|
for (const err of [postError, lastError]) {
|
|
280
|
-
|
|
278
|
+
// getPost may wrap the original read failure when its query fallback is
|
|
279
|
+
// empty. Preserve that cause's status instead of painting the wrapper's
|
|
280
|
+
// "Blog post not found" text for a gateway failure.
|
|
281
|
+
const cause = (err as { cause?: unknown } | undefined)?.cause;
|
|
282
|
+
for (const failure of [cause, err]) {
|
|
283
|
+
if (isBridgeUnavailable(failure) || readWasUnreachable(failure)) throw failure;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
for (const err of [postError, lastError]) {
|
|
287
|
+
// Non-transient access/validation failures keep their status too: the
|
|
288
|
+
// SDK's empty-query wrapper is not the reason this read failed.
|
|
289
|
+
const failure = (err as { cause?: unknown } | undefined)?.cause ?? err;
|
|
290
|
+
if (failure !== undefined && !isNotFound(failure)) throw failure;
|
|
281
291
|
}
|
|
282
292
|
// Wix says it is gone on BOTH reads (a published-only post's draft read is a 404 on its
|
|
283
293
|
// own): its cached row must not outlive it, or an offline load repaints a deleted post.
|
|
@@ -361,7 +371,8 @@ const svc = defineService<PostState, {
|
|
|
361
371
|
} catch (e) {
|
|
362
372
|
// Offline: fall back to the last-synced local row before the demo/error paths.
|
|
363
373
|
// Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
|
|
364
|
-
const cached = isNotFound(e) ? (await cacheDrop(id), null)
|
|
374
|
+
const cached = isNotFound(e) ? (await cacheDrop(id), null)
|
|
375
|
+
: readWasUnreachable(e) || isBridgeUnavailable(e) ? await cacheGet(id) : null;
|
|
365
376
|
if (cached) return cachedDetail(s, cached);
|
|
366
377
|
if (ownerDemoFallback(e)) {
|
|
367
378
|
const demo = demoDetail(s, id);
|
|
@@ -385,7 +396,8 @@ const svc = defineService<PostState, {
|
|
|
385
396
|
return loaded;
|
|
386
397
|
} catch (e) {
|
|
387
398
|
// Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
|
|
388
|
-
const cached = isNotFound(e) ? (await cacheDrop(s.id), null)
|
|
399
|
+
const cached = isNotFound(e) ? (await cacheDrop(s.id), null)
|
|
400
|
+
: readWasUnreachable(e) || isBridgeUnavailable(e) ? await cacheGet(s.id) : null;
|
|
389
401
|
if (cached) return cachedDetail(s, cached);
|
|
390
402
|
if (ownerDemoFallback(e)) {
|
|
391
403
|
const demo = demoDetail(s, s.id);
|
|
@@ -293,6 +293,13 @@ export default defineApp({
|
|
|
293
293
|
"parentScreenId": "himi_programs",
|
|
294
294
|
"tabId": ""
|
|
295
295
|
},
|
|
296
|
+
{
|
|
297
|
+
"screenId": "himi_member_programs",
|
|
298
|
+
"isPublic": true,
|
|
299
|
+
"paramKeys": [],
|
|
300
|
+
"parentScreenId": "himi_programs",
|
|
301
|
+
"tabId": ""
|
|
302
|
+
},
|
|
296
303
|
{
|
|
297
304
|
"screenId": "himi_plans",
|
|
298
305
|
"isPublic": true,
|