@wix/himalaya-cli 0.1569.0 → 0.1571.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/l10n-strings.d.ts +3 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/define-app.d.ts +8 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/auth-providers/wix/src/index.d.ts +7 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/screens/src/business-contact-service.d.ts +17 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/screens/src/business-contact.d.ts +73 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/screens/src/index.d.ts +3 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/screens/src/invite-target.d.ts +1 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/screens/src/invite.d.ts +148 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/blog-v3/src/extensions.d.ts +6 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/auth.mjs +17 -7
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core/validation.mjs +17 -7
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +17 -7
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/screens.mjs +575 -91
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/state.mjs +17 -7
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-auth.mjs +7 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-blog.mjs +1 -0
- package/dist/cli.mjs +1897 -1226
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/base44-app-to-himi-app.md +1 -1
- package/guides/capabilities.md +7 -0
- package/guides/getting-started.md +5 -0
- package/guides/himi-json-output.md +11 -0
- package/guides/himi-skill.md +5 -0
- package/guides/one-app-to-himi-app.md +267 -8
- package/guides/sdk-reference.json +2 -2
- package/guides/skill.md +5 -0
- package/guides/splash-screens.md +10 -1
- package/guides/tier-5-add-a-screen.md +20 -0
- package/guides/trim-a-template.md +5 -0
- package/guides/wix-business-context.md +11 -2
- package/package.json +2 -2
- package/templates/beauty-salon/config.ts +8 -1
- package/templates/beauty-salon/dev/index.ts +244 -1
- package/templates/beauty-salon/himalaya.content.json +3 -0
- package/templates/beauty-salon/tier5-src/_shared/member-read.ts +52 -0
- package/templates/beauty-salon/tier5-src/_shared/program-description.ts +11 -0
- package/templates/beauty-salon/tier5-src/business-contact/index.ts +6 -0
- package/templates/beauty-salon/tier5-src/himi-blog-post/index.ts +35 -12
- package/templates/beauty-salon/tier5-src/himi-branded-lite-home/index.ts +3 -3
- package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +6 -9
- package/templates/beauty-salon-owner/config.ts +1 -1
- package/templates/branded-lite/config.ts +8 -1
- package/templates/branded-lite/dev/index.ts +409 -2
- package/templates/branded-lite/himalaya.content.json +3 -0
- package/templates/branded-lite/tier5-src/_shared/member-read.ts +52 -0
- package/templates/branded-lite/tier5-src/_shared/program-description.ts +11 -0
- package/templates/branded-lite/tier5-src/business-contact/index.ts +6 -0
- package/templates/branded-lite/tier5-src/himi-blog-post/index.ts +35 -12
- package/templates/branded-lite/tier5-src/himi-branded-lite-home/index.ts +3 -3
- package/templates/branded-lite/tier5-src/himi-branded-lite-notifsettings/index.ts +39 -11
- package/templates/branded-lite/tier5-src/himi-branded-lite-program/index.ts +16 -14
- package/templates/branded-lite/tier5-src/himi-branded-lite-programs/index.ts +3 -7
- package/templates/branded-lite/tier5-src/himi-events-my-events/index.ts +76 -42
- package/templates/branded-lite/tier5-src/himi-store-product/index.ts +6 -9
- package/templates/branded-lite/tier5-src/wix-spaces-chat-thread/index.ts +101 -34
- package/templates/branded-lite/tier5-src/wix-spaces-forum-post/index.ts +23 -6
- package/templates/branded-lite/tier5-src/wix-spaces-member-detail/index.ts +26 -11
- package/templates/community-club/config.ts +8 -1
- package/templates/community-club/dev/index.ts +278 -2
- package/templates/community-club/himalaya.content.json +3 -0
- package/templates/community-club/tier5-src/_shared/branded-load-state.ts +106 -0
- package/templates/community-club/tier5-src/_shared/member-read.ts +52 -0
- package/templates/community-club/tier5-src/_shared/program-description.ts +11 -0
- package/templates/community-club/tier5-src/business-contact/index.ts +6 -0
- package/templates/community-club/tier5-src/himi-blog-post/index.ts +35 -12
- package/templates/community-club/tier5-src/himi-branded-lite-home/index.ts +3 -3
- package/templates/community-club/tier5-src/himi-events-my-events/index.ts +76 -42
- package/templates/community-club-owner/config.ts +1 -1
- package/templates/events-meetups/config.ts +8 -1
- package/templates/events-meetups/dev/index.ts +278 -2
- package/templates/events-meetups/himalaya.content.json +3 -0
- package/templates/events-meetups/tier5-src/_shared/branded-load-state.ts +106 -0
- package/templates/events-meetups/tier5-src/_shared/member-read.ts +52 -0
- package/templates/events-meetups/tier5-src/_shared/program-description.ts +11 -0
- package/templates/events-meetups/tier5-src/business-contact/index.ts +6 -0
- package/templates/events-meetups/tier5-src/himi-blog-post/index.ts +35 -12
- package/templates/events-meetups/tier5-src/himi-branded-lite-home/index.ts +3 -3
- package/templates/events-meetups/tier5-src/himi-events-my-events/index.ts +76 -42
- package/templates/events-meetups-owner/config.ts +1 -1
- package/templates/gym-fitness/config.ts +8 -1
- package/templates/gym-fitness/dev/index.ts +278 -2
- package/templates/gym-fitness/himalaya.content.json +3 -0
- package/templates/gym-fitness/tier5-src/_shared/member-read.ts +52 -0
- package/templates/gym-fitness/tier5-src/_shared/program-description.ts +11 -0
- package/templates/gym-fitness/tier5-src/business-contact/index.ts +6 -0
- package/templates/gym-fitness/tier5-src/himi-blog-post/index.ts +35 -12
- package/templates/gym-fitness/tier5-src/himi-branded-lite-home/index.ts +3 -3
- package/templates/gym-fitness/tier5-src/himi-events-my-events/index.ts +76 -42
- package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +6 -9
- package/templates/gym-fitness-owner/config.ts +1 -1
- package/templates/nonprofit-cause/config.ts +8 -1
- package/templates/nonprofit-cause/dev/index.ts +278 -2
- package/templates/nonprofit-cause/himalaya.content.json +3 -0
- package/templates/nonprofit-cause/tier5-src/_shared/branded-load-state.ts +106 -0
- package/templates/nonprofit-cause/tier5-src/_shared/member-read.ts +52 -0
- package/templates/nonprofit-cause/tier5-src/_shared/program-description.ts +11 -0
- package/templates/nonprofit-cause/tier5-src/business-contact/index.ts +6 -0
- package/templates/nonprofit-cause/tier5-src/himi-blog-post/index.ts +35 -12
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-home/index.ts +3 -3
- package/templates/nonprofit-cause/tier5-src/himi-events-my-events/index.ts +76 -42
- package/templates/nonprofit-cause-owner/config.ts +1 -1
- package/templates/owner-lite/config.ts +1 -1
- package/templates/podcast-creator/config.ts +8 -1
- package/templates/podcast-creator/dev/index.ts +278 -2
- package/templates/podcast-creator/himalaya.content.json +3 -0
- package/templates/podcast-creator/tier5-src/_shared/branded-load-state.ts +106 -0
- package/templates/podcast-creator/tier5-src/_shared/member-read.ts +52 -0
- package/templates/podcast-creator/tier5-src/_shared/program-description.ts +11 -0
- package/templates/podcast-creator/tier5-src/business-contact/index.ts +6 -0
- package/templates/podcast-creator/tier5-src/himi-blog-post/index.ts +35 -12
- package/templates/podcast-creator/tier5-src/himi-branded-lite-home/index.ts +3 -3
- package/templates/podcast-creator/tier5-src/himi-events-my-events/index.ts +76 -42
- package/templates/podcast-creator-owner/config.ts +1 -1
- package/templates/portfolio-creative/config.ts +8 -1
- package/templates/portfolio-creative/dev/index.ts +278 -2
- package/templates/portfolio-creative/himalaya.content.json +3 -0
- package/templates/portfolio-creative/tier5-src/_shared/branded-load-state.ts +106 -0
- package/templates/portfolio-creative/tier5-src/_shared/member-read.ts +52 -0
- package/templates/portfolio-creative/tier5-src/_shared/program-description.ts +11 -0
- package/templates/portfolio-creative/tier5-src/business-contact/index.ts +6 -0
- package/templates/portfolio-creative/tier5-src/himi-blog-post/index.ts +35 -12
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-home/index.ts +3 -3
- package/templates/portfolio-creative/tier5-src/himi-events-my-events/index.ts +76 -42
- package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +6 -9
- package/templates/portfolio-creative-owner/config.ts +1 -1
- package/templates/restaurant/config.ts +8 -1
- package/templates/restaurant/dev/index.ts +278 -2
- package/templates/restaurant/himalaya.content.json +3 -0
- package/templates/restaurant/tier5-src/_shared/branded-load-state.ts +106 -0
- package/templates/restaurant/tier5-src/_shared/member-read.ts +52 -0
- package/templates/restaurant/tier5-src/_shared/program-description.ts +11 -0
- package/templates/restaurant/tier5-src/business-contact/index.ts +6 -0
- package/templates/restaurant/tier5-src/himi-blog-post/index.ts +35 -12
- package/templates/restaurant/tier5-src/himi-branded-lite-home/index.ts +3 -3
- package/templates/restaurant/tier5-src/himi-events-my-events/index.ts +76 -42
- package/templates/restaurant-owner/config.ts +1 -1
- package/templates/retail-store/config.ts +8 -1
- package/templates/retail-store/dev/index.ts +244 -1
- package/templates/retail-store/himalaya.content.json +3 -0
- package/templates/retail-store/tier5-src/_shared/branded-load-state.ts +106 -0
- package/templates/retail-store/tier5-src/_shared/member-read.ts +52 -0
- package/templates/retail-store/tier5-src/_shared/program-description.ts +11 -0
- package/templates/retail-store/tier5-src/business-contact/index.ts +6 -0
- package/templates/retail-store/tier5-src/himi-blog-post/index.ts +35 -12
- package/templates/retail-store/tier5-src/himi-branded-lite-home/index.ts +3 -3
- package/templates/retail-store/tier5-src/himi-store-product/index.ts +6 -9
- package/templates/retail-store-owner/config.ts +1 -1
- package/templates/yoga-studio/config.ts +8 -1
- package/templates/yoga-studio/dev/index.ts +306 -2
- package/templates/yoga-studio/himalaya.content.json +3 -0
- package/templates/yoga-studio/tier5-src/_shared/member-read.ts +52 -0
- package/templates/yoga-studio/tier5-src/_shared/program-description.ts +11 -0
- package/templates/yoga-studio/tier5-src/business-contact/index.ts +6 -0
- package/templates/yoga-studio/tier5-src/himi-blog-post/index.ts +35 -12
- package/templates/yoga-studio/tier5-src/himi-branded-lite-home/index.ts +3 -3
- package/templates/yoga-studio/tier5-src/himi-branded-lite-program/index.ts +16 -14
- package/templates/yoga-studio/tier5-src/himi-branded-lite-programs/index.ts +3 -7
- package/templates/yoga-studio/tier5-src/himi-events-my-events/index.ts +76 -42
- package/templates/yoga-studio-owner/config.ts +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { WixProgram } from "@himalaya/wix-online-programs";
|
|
2
|
+
|
|
3
|
+
/** v3 nests the body in description.details; older responses use settings or a
|
|
4
|
+
* flat description. The body itself may be a Ricos document or serialized text. */
|
|
5
|
+
export function programDescription(program: WixProgram): unknown {
|
|
6
|
+
const raw = (program as { description?: unknown }).description;
|
|
7
|
+
const nested = raw && typeof raw === "object" ? raw as { details?: unknown; nodes?: unknown } : undefined;
|
|
8
|
+
return program.settings?.description ?? nested?.details
|
|
9
|
+
?? (typeof raw === "string" || Array.isArray(nested?.nodes) ? raw : undefined)
|
|
10
|
+
?? program.details?.description;
|
|
11
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createBusinessContactService } from "@himalaya/screens";
|
|
2
|
+
|
|
3
|
+
// Contact values and the optional public total are build-time source evidence.
|
|
4
|
+
// No owner API, device location, or cross-site source URL is read by this worker.
|
|
5
|
+
const svc = createBusinessContactService();
|
|
6
|
+
export { svc };
|
|
@@ -9,6 +9,7 @@ import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
|
9
9
|
import { formatDateMedium, formatMonthDay } from "../_shared/engine-intl.js";
|
|
10
10
|
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
11
11
|
import { richBody, ROW_IMAGE_WIDTH } from "../_shared/rich-body.js";
|
|
12
|
+
import { readAccess, assertReadAccess, readAccessDenied, readSignInFlags, NO_READ_SIGN_IN } from "../_shared/member-read.js";
|
|
12
13
|
|
|
13
14
|
// Offline-first (data-offline): the post body is a public read-through — when the
|
|
14
15
|
// live fetch fails (offline) fall back to the last-synced row the feed cached under
|
|
@@ -34,6 +35,7 @@ interface CommentRow {
|
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
interface S {
|
|
38
|
+
signInRequired: boolean; noSignIn: boolean; signInScreenId: string;
|
|
37
39
|
status: "loading" | "ready" | "error";
|
|
38
40
|
id: string;
|
|
39
41
|
title: string;
|
|
@@ -214,6 +216,7 @@ function derive(s: S): S {
|
|
|
214
216
|
}
|
|
215
217
|
|
|
216
218
|
const baseState: S = derive({
|
|
219
|
+
...NO_READ_SIGN_IN, signInScreenId: "himi_account",
|
|
217
220
|
status: "loading",
|
|
218
221
|
id: "",
|
|
219
222
|
title: "",
|
|
@@ -280,23 +283,28 @@ async function cachedPostState(s: S, id: string): Promise<S> {
|
|
|
280
283
|
});
|
|
281
284
|
}
|
|
282
285
|
|
|
283
|
-
|
|
286
|
+
let loadVersion = 0;
|
|
287
|
+
async function loadPostState(s: S): Promise<S | undefined> {
|
|
288
|
+
const version = ++loadVersion;
|
|
289
|
+
await svc.prepare();
|
|
290
|
+
const clean = { ...baseState, signInScreenId: s.signInScreenId };
|
|
284
291
|
const id = inputId();
|
|
285
292
|
if (!id) {
|
|
286
|
-
return derive({ ...
|
|
293
|
+
return derive({ ...clean, status: "ready", emptyText: copyParam("blogPost.notFoundText", "Post not found.") });
|
|
287
294
|
}
|
|
288
295
|
try {
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
296
|
+
const access = await readAccess();
|
|
297
|
+
const [postResult, commentsResult] = await Promise.allSettled([getPost(id, {}, { preserveAccessErrors: true }), listBlogComments(id)]);
|
|
298
|
+
if (postResult.status === "rejected") throw postResult.reason;
|
|
299
|
+
await assertReadAccess(access);
|
|
300
|
+
if (version !== loadVersion) return undefined;
|
|
293
301
|
const post = (((postResult.value as unknown as { post?: WixPost }).post) ?? postResult.value) as PostWithExtras;
|
|
294
302
|
const commentsUnavailable = commentsResult.status === "rejected";
|
|
295
303
|
const comments = commentsResult.status === "fulfilled" ? commentsResult.value.map(toCommentRow) : [];
|
|
296
304
|
const cover = imageUrl(post);
|
|
297
305
|
const title = post.title || "Untitled post";
|
|
298
306
|
return derive({
|
|
299
|
-
...
|
|
307
|
+
...clean,
|
|
300
308
|
status: "ready",
|
|
301
309
|
id,
|
|
302
310
|
title,
|
|
@@ -319,14 +327,23 @@ async function loadPostState(s: S): Promise<S> {
|
|
|
319
327
|
errorText: "",
|
|
320
328
|
emptyText: "",
|
|
321
329
|
});
|
|
322
|
-
} catch {
|
|
323
|
-
|
|
330
|
+
} catch (error) {
|
|
331
|
+
const flags = await readSignInFlags(error);
|
|
332
|
+
const failed = derive({ ...clean, ...flags, status: "error", id, errorText: copyParam("blogPost.errorText", "This post could not load.") });
|
|
333
|
+
if (version !== loadVersion) return undefined;
|
|
334
|
+
if (readAccessDenied(error)) return failed;
|
|
335
|
+
const access = await readAccess();
|
|
336
|
+
const cached = await cachedPostState(clean, id);
|
|
337
|
+
try { await assertReadAccess(access); }
|
|
338
|
+
catch { return version === loadVersion ? failed : undefined; }
|
|
339
|
+
return version === loadVersion ? cached : undefined;
|
|
324
340
|
}
|
|
325
341
|
}
|
|
326
342
|
|
|
327
343
|
const svc = defineService<S, {
|
|
328
|
-
|
|
329
|
-
|
|
344
|
+
prepare: (s: S) => S;
|
|
345
|
+
load: (s: S, arg?: unknown) => Promise<S | undefined>;
|
|
346
|
+
retry: (s: S) => Promise<S | undefined>;
|
|
330
347
|
like: (s: S) => Promise<S>;
|
|
331
348
|
unlike: (s: S) => Promise<S>;
|
|
332
349
|
toggleSave: (s: S) => S;
|
|
@@ -338,7 +355,12 @@ const svc = defineService<S, {
|
|
|
338
355
|
}>("himiBlogPost", {
|
|
339
356
|
state: baseState,
|
|
340
357
|
actions: {
|
|
341
|
-
|
|
358
|
+
prepare: (s) => ({ ...s, ...baseState }),
|
|
359
|
+
load: (s, arg) => {
|
|
360
|
+
stashCopy(arg);
|
|
361
|
+
const target = (arg as { signInScreenId?: unknown })?.signInScreenId;
|
|
362
|
+
return loadPostState({ ...s, signInScreenId: target === "himi_sign_in" ? target : s.signInScreenId });
|
|
363
|
+
},
|
|
342
364
|
retry: (s) => loadPostState({ ...s, status: "loading", errorText: "" }),
|
|
343
365
|
like: async (s) => {
|
|
344
366
|
if (!s.id) return derive({ ...s, actionMessage: copyParam("blogPost.noPostMessage", "No post selected.") });
|
|
@@ -409,5 +431,6 @@ const svc = defineService<S, {
|
|
|
409
431
|
},
|
|
410
432
|
});
|
|
411
433
|
|
|
434
|
+
svc.prepare();
|
|
412
435
|
svc.load();
|
|
413
436
|
export { svc };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { descriptionBody } from "../_shared/rich-body.js";
|
|
2
|
+
import { programDescription } from "../_shared/program-description.js";
|
|
1
3
|
import { fetchMemberBookings, type MemberBookingRow } from "../_shared/member-bookings.js";
|
|
2
4
|
import { hostSiteFromInput, hostedExploreCards, hostedHiddenFlags, type HostedExploreCard } from "../_shared/branded-lite-hosted.js";
|
|
3
5
|
import { memberAccess, assertMemberAccess } from "../_shared/member-access.js";
|
|
@@ -675,11 +677,9 @@ async function fetchHomePrograms(): Promise<ProgramCard[]> {
|
|
|
675
677
|
.map((p: WixProgram) => {
|
|
676
678
|
const desc = (p as { description?: unknown }).description;
|
|
677
679
|
const nestedTitle = desc && typeof desc === "object" ? (desc as { title?: string }).title : undefined;
|
|
678
|
-
const nestedDetails = desc && typeof desc === "object" ? (desc as { details?: string }).details : undefined;
|
|
679
680
|
const name = cleanTitle(p.settings?.title ?? nestedTitle ?? p.title) || copyParam("home.programFallbackName", "Program");
|
|
680
681
|
const image = programImage(p);
|
|
681
|
-
const details = (p.
|
|
682
|
-
.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
682
|
+
const details = descriptionBody(programDescription(p)).bodyText.replace(/\s+/g, " ").trim();
|
|
683
683
|
return {
|
|
684
684
|
id: p.id || name,
|
|
685
685
|
name,
|
|
@@ -19,7 +19,7 @@ import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
|
19
19
|
import { isBridgeUnavailable } from "../_shared/owner-load-error.js";
|
|
20
20
|
import { isProductSaved, toggleSavedProduct } from "../_shared/himi-store-saved.js";
|
|
21
21
|
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
22
|
-
import {
|
|
22
|
+
import { descriptionBody } from "../_shared/rich-body.js";
|
|
23
23
|
|
|
24
24
|
/** Live cart size (sum of line-item quantities) for the top-bar cart badge.
|
|
25
25
|
* Best-effort: a cart error just yields 0 (badge hidden), never fails the screen. */
|
|
@@ -74,9 +74,7 @@ function productPolicyBody(product: StoreProduct, kind: "returns" | "shipping"):
|
|
|
74
74
|
});
|
|
75
75
|
if (!section) return "";
|
|
76
76
|
const html = "plainDescription" in section ? section.plainDescription : undefined;
|
|
77
|
-
|
|
78
|
-
if (typeof section.description === "string") return plainText(section.description.replace(/ /gi, " "));
|
|
79
|
-
return richBody(section.description).bodyText;
|
|
77
|
+
return descriptionBody(html || section.description).bodyText;
|
|
80
78
|
}
|
|
81
79
|
|
|
82
80
|
/** The product id `lastProduct` was read for. A pooled screen re-appearing calls
|
|
@@ -140,13 +138,12 @@ function optionsHint(groups: StoreOption[], selection: StoreOptionSelection): st
|
|
|
140
138
|
return copyTemplate("product.optionsChoose", "Choose {options}", { options: missing.join(", ") });
|
|
141
139
|
}
|
|
142
140
|
|
|
143
|
-
/**
|
|
144
|
-
*
|
|
145
|
-
* `description` is an HTML string: stripped text, no document. */
|
|
141
|
+
/** Catalog V3 returns Ricos objects or serialized documents; V1 returns HTML.
|
|
142
|
+
* Keep plainDescription as the independent fallback, never raw document JSON. */
|
|
146
143
|
function productBody(p: StoreProduct): { description: string; descriptionJson: string } {
|
|
147
144
|
const raw = (p as { description?: unknown }).description;
|
|
148
|
-
const html =
|
|
149
|
-
const { bodyJson, bodyText } =
|
|
145
|
+
const html = descriptionBody(p.plainDescription).bodyText;
|
|
146
|
+
const { bodyJson, bodyText } = descriptionBody(raw, html);
|
|
150
147
|
return { description: html || bodyText, descriptionJson: bodyJson };
|
|
151
148
|
}
|
|
152
149
|
|
|
@@ -37,7 +37,7 @@ export default defineApp({
|
|
|
37
37
|
actions: "http://localhost:8190/v1/actions",
|
|
38
38
|
sync: "http://localhost:8190/v1/sync",
|
|
39
39
|
},
|
|
40
|
-
capabilities: ["live_activity","push","share","secure_storage","open_url","local_database","clipboard","ui","speech","camera","photos","file_picker","files","presigned_upload","app_info","biometrics","wix_platform","
|
|
40
|
+
capabilities: ["live_activity","push","share","secure_storage","open_url","local_database","clipboard","ui","speech","camera","photos","file_picker","files","presigned_upload","app_info","biometrics","wix_platform","stream","wix_api"],
|
|
41
41
|
designTokensPath: "./tokens.json",
|
|
42
42
|
// Native fallback; the T5 splash descriptor owns the editable launch appearance.
|
|
43
43
|
splash: {
|
|
@@ -37,7 +37,7 @@ export default defineApp({
|
|
|
37
37
|
actions: "http://localhost:8190/v1/actions",
|
|
38
38
|
sync: "http://localhost:8190/v1/sync",
|
|
39
39
|
},
|
|
40
|
-
capabilities: ["
|
|
40
|
+
capabilities: ["push","share","secure_storage","open_url","calendar","local_database","wix_api","wix_platform","app_info","iap","release_control","clipboard","theme","wix_cashier"],
|
|
41
41
|
cache: {
|
|
42
42
|
"rules": [
|
|
43
43
|
{
|
|
@@ -81,6 +81,13 @@ export default defineApp({
|
|
|
81
81
|
"parentScreenId": "himi_account",
|
|
82
82
|
"tabId": "profile"
|
|
83
83
|
},
|
|
84
|
+
{
|
|
85
|
+
"screenId": "himi_business_contact",
|
|
86
|
+
"isPublic": true,
|
|
87
|
+
"paramKeys": [],
|
|
88
|
+
"parentScreenId": "himi_account",
|
|
89
|
+
"tabId": "profile"
|
|
90
|
+
},
|
|
84
91
|
{
|
|
85
92
|
"screenId": "himi_appearance",
|
|
86
93
|
"isPublic": true,
|
|
@@ -6581,6 +6581,219 @@ const SCREENS = runtimeSetting({
|
|
|
6581
6581
|
"bundleVersion": "0.0.1"
|
|
6582
6582
|
}
|
|
6583
6583
|
},
|
|
6584
|
+
"himi_business_contact": {
|
|
6585
|
+
"screenId": "himi_business_contact",
|
|
6586
|
+
"title": "Business contact",
|
|
6587
|
+
"renderer": "sdui_intent",
|
|
6588
|
+
"schemaVersion": 1,
|
|
6589
|
+
"cacheControl": {
|
|
6590
|
+
"maxAge": 0,
|
|
6591
|
+
"staleWhileRevalidate": 0
|
|
6592
|
+
},
|
|
6593
|
+
"payload": {
|
|
6594
|
+
"id": "himi_business_contact.root",
|
|
6595
|
+
"body": {
|
|
6596
|
+
"package": "himalaya",
|
|
6597
|
+
"type": "VStack",
|
|
6598
|
+
"props": {
|
|
6599
|
+
"spacing": 16,
|
|
6600
|
+
"alignment": "leading",
|
|
6601
|
+
"children": [
|
|
6602
|
+
{
|
|
6603
|
+
"id": "himi_business_contact.section",
|
|
6604
|
+
"body": {
|
|
6605
|
+
"package": "himalaya",
|
|
6606
|
+
"type": "VStack",
|
|
6607
|
+
"props": {
|
|
6608
|
+
"spacing": 12,
|
|
6609
|
+
"alignment": "leading",
|
|
6610
|
+
"children": [
|
|
6611
|
+
{
|
|
6612
|
+
"id": "himi_business_contact.section.directions_copy",
|
|
6613
|
+
"body": {
|
|
6614
|
+
"package": "himalaya",
|
|
6615
|
+
"type": "Text",
|
|
6616
|
+
"props": {
|
|
6617
|
+
"text": "Directions",
|
|
6618
|
+
"style": "body",
|
|
6619
|
+
"collapseWhenEmpty": true
|
|
6620
|
+
}
|
|
6621
|
+
},
|
|
6622
|
+
"modifiers": {
|
|
6623
|
+
"hidden": true
|
|
6624
|
+
}
|
|
6625
|
+
},
|
|
6626
|
+
{
|
|
6627
|
+
"id": "himi_business_contact.section.unavailable",
|
|
6628
|
+
"body": {
|
|
6629
|
+
"package": "himalaya",
|
|
6630
|
+
"type": "Text",
|
|
6631
|
+
"props": {
|
|
6632
|
+
"text": "Contact details unavailable",
|
|
6633
|
+
"style": "body",
|
|
6634
|
+
"collapseWhenEmpty": true
|
|
6635
|
+
}
|
|
6636
|
+
}
|
|
6637
|
+
},
|
|
6638
|
+
{
|
|
6639
|
+
"id": "himi_business_contact.section.member_count",
|
|
6640
|
+
"body": {
|
|
6641
|
+
"package": "himalaya",
|
|
6642
|
+
"type": "FragmentSlot",
|
|
6643
|
+
"props": {
|
|
6644
|
+
"casePath": "$service:businessContact.memberCountCase",
|
|
6645
|
+
"defaultCase": "unavailable",
|
|
6646
|
+
"cases": [
|
|
6647
|
+
{
|
|
6648
|
+
"id": "one",
|
|
6649
|
+
"content": {
|
|
6650
|
+
"id": "himi_business_contact.section.members_one",
|
|
6651
|
+
"body": {
|
|
6652
|
+
"package": "himalaya",
|
|
6653
|
+
"type": "HStack",
|
|
6654
|
+
"props": {
|
|
6655
|
+
"spacing": 4,
|
|
6656
|
+
"alignment": "center",
|
|
6657
|
+
"children": [
|
|
6658
|
+
{
|
|
6659
|
+
"id": "himi_business_contact.section.count_one",
|
|
6660
|
+
"body": {
|
|
6661
|
+
"package": "himalaya",
|
|
6662
|
+
"type": "Text",
|
|
6663
|
+
"props": {
|
|
6664
|
+
"text": "$service:businessContact.memberCount",
|
|
6665
|
+
"style": "footnote",
|
|
6666
|
+
"collapseWhenEmpty": true
|
|
6667
|
+
}
|
|
6668
|
+
}
|
|
6669
|
+
},
|
|
6670
|
+
{
|
|
6671
|
+
"id": "himi_business_contact.section.unit_one",
|
|
6672
|
+
"body": {
|
|
6673
|
+
"package": "himalaya",
|
|
6674
|
+
"type": "Text",
|
|
6675
|
+
"props": {
|
|
6676
|
+
"text": "member",
|
|
6677
|
+
"style": "footnote",
|
|
6678
|
+
"collapseWhenEmpty": true
|
|
6679
|
+
}
|
|
6680
|
+
}
|
|
6681
|
+
}
|
|
6682
|
+
]
|
|
6683
|
+
}
|
|
6684
|
+
}
|
|
6685
|
+
}
|
|
6686
|
+
},
|
|
6687
|
+
{
|
|
6688
|
+
"id": "other",
|
|
6689
|
+
"content": {
|
|
6690
|
+
"id": "himi_business_contact.section.members_other",
|
|
6691
|
+
"body": {
|
|
6692
|
+
"package": "himalaya",
|
|
6693
|
+
"type": "HStack",
|
|
6694
|
+
"props": {
|
|
6695
|
+
"spacing": 4,
|
|
6696
|
+
"alignment": "center",
|
|
6697
|
+
"children": [
|
|
6698
|
+
{
|
|
6699
|
+
"id": "himi_business_contact.section.count_other",
|
|
6700
|
+
"body": {
|
|
6701
|
+
"package": "himalaya",
|
|
6702
|
+
"type": "Text",
|
|
6703
|
+
"props": {
|
|
6704
|
+
"text": "$service:businessContact.memberCount",
|
|
6705
|
+
"style": "footnote",
|
|
6706
|
+
"collapseWhenEmpty": true
|
|
6707
|
+
}
|
|
6708
|
+
}
|
|
6709
|
+
},
|
|
6710
|
+
{
|
|
6711
|
+
"id": "himi_business_contact.section.unit_other",
|
|
6712
|
+
"body": {
|
|
6713
|
+
"package": "himalaya",
|
|
6714
|
+
"type": "Text",
|
|
6715
|
+
"props": {
|
|
6716
|
+
"text": "members",
|
|
6717
|
+
"style": "footnote",
|
|
6718
|
+
"collapseWhenEmpty": true
|
|
6719
|
+
}
|
|
6720
|
+
}
|
|
6721
|
+
}
|
|
6722
|
+
]
|
|
6723
|
+
}
|
|
6724
|
+
}
|
|
6725
|
+
}
|
|
6726
|
+
},
|
|
6727
|
+
{
|
|
6728
|
+
"id": "unavailable",
|
|
6729
|
+
"content": {
|
|
6730
|
+
"id": "himi_business_contact.section.members_unavailable",
|
|
6731
|
+
"body": {
|
|
6732
|
+
"package": "himalaya",
|
|
6733
|
+
"type": "Text",
|
|
6734
|
+
"props": {
|
|
6735
|
+
"text": "Member count unavailable",
|
|
6736
|
+
"style": "footnote",
|
|
6737
|
+
"collapseWhenEmpty": true
|
|
6738
|
+
}
|
|
6739
|
+
}
|
|
6740
|
+
}
|
|
6741
|
+
}
|
|
6742
|
+
]
|
|
6743
|
+
}
|
|
6744
|
+
},
|
|
6745
|
+
"modifiers": {
|
|
6746
|
+
"hidden": true
|
|
6747
|
+
}
|
|
6748
|
+
},
|
|
6749
|
+
{
|
|
6750
|
+
"id": "himi_business_contact.section.feedback",
|
|
6751
|
+
"body": {
|
|
6752
|
+
"package": "himalaya",
|
|
6753
|
+
"type": "Text",
|
|
6754
|
+
"props": {
|
|
6755
|
+
"text": "$service:businessContact.message",
|
|
6756
|
+
"style": "footnote",
|
|
6757
|
+
"collapseWhenEmpty": true
|
|
6758
|
+
}
|
|
6759
|
+
}
|
|
6760
|
+
}
|
|
6761
|
+
]
|
|
6762
|
+
}
|
|
6763
|
+
}
|
|
6764
|
+
}
|
|
6765
|
+
]
|
|
6766
|
+
}
|
|
6767
|
+
},
|
|
6768
|
+
"modifiers": {
|
|
6769
|
+
"background": {
|
|
6770
|
+
"token": "surfacePrimary"
|
|
6771
|
+
},
|
|
6772
|
+
"padding": {
|
|
6773
|
+
"leading": 20,
|
|
6774
|
+
"trailing": 20,
|
|
6775
|
+
"top": 18,
|
|
6776
|
+
"bottom": 28
|
|
6777
|
+
},
|
|
6778
|
+
"onAppear": {
|
|
6779
|
+
"actionId": "tier5.businessContact.load",
|
|
6780
|
+
"args": {
|
|
6781
|
+
"showMemberCount": false
|
|
6782
|
+
}
|
|
6783
|
+
}
|
|
6784
|
+
}
|
|
6785
|
+
},
|
|
6786
|
+
"logicBundle": {
|
|
6787
|
+
"url": "http://localhost:8190/v1/bundles/business-contact?integrity=",
|
|
6788
|
+
"integrity": "",
|
|
6789
|
+
"contentType": "application/javascript+ts-bundle",
|
|
6790
|
+
"declaredCapabilities": [
|
|
6791
|
+
"open_url"
|
|
6792
|
+
],
|
|
6793
|
+
"minBinaryVersion": "0.1.0",
|
|
6794
|
+
"bundleVersion": "0.0.1"
|
|
6795
|
+
}
|
|
6796
|
+
},
|
|
6584
6797
|
"himi_appearance": {
|
|
6585
6798
|
"screenId": "himi_appearance",
|
|
6586
6799
|
"renderer": "sdui_intent",
|
|
@@ -23360,6 +23573,9 @@ const SCREENS = runtimeSetting({
|
|
|
23360
23573
|
"style": "body",
|
|
23361
23574
|
"color": "textSecondary"
|
|
23362
23575
|
}
|
|
23576
|
+
},
|
|
23577
|
+
"modifiers": {
|
|
23578
|
+
"hiddenPath": "$service:himiMyEvents.signInRequired"
|
|
23363
23579
|
}
|
|
23364
23580
|
},
|
|
23365
23581
|
{
|
|
@@ -23374,6 +23590,32 @@ const SCREENS = runtimeSetting({
|
|
|
23374
23590
|
"actionId": "tier5.himiMyEvents.load"
|
|
23375
23591
|
}
|
|
23376
23592
|
}
|
|
23593
|
+
},
|
|
23594
|
+
"modifiers": {
|
|
23595
|
+
"hiddenPath": "$service:himiMyEvents.signInRequired"
|
|
23596
|
+
}
|
|
23597
|
+
},
|
|
23598
|
+
{
|
|
23599
|
+
"id": "himi_my_events.retry.sign_in",
|
|
23600
|
+
"body": {
|
|
23601
|
+
"package": "himalaya",
|
|
23602
|
+
"type": "Button",
|
|
23603
|
+
"props": {
|
|
23604
|
+
"title": "Sign in",
|
|
23605
|
+
"style": "primary",
|
|
23606
|
+
"action": {
|
|
23607
|
+
"actionId": "himi.open",
|
|
23608
|
+
"params": {
|
|
23609
|
+
"screenId": "himi_sign_in",
|
|
23610
|
+
"mode": "signin",
|
|
23611
|
+
"modal": "1"
|
|
23612
|
+
},
|
|
23613
|
+
"presentation": "sheet"
|
|
23614
|
+
}
|
|
23615
|
+
}
|
|
23616
|
+
},
|
|
23617
|
+
"modifiers": {
|
|
23618
|
+
"hiddenPath": "$service:himiMyEvents.noSignIn"
|
|
23377
23619
|
}
|
|
23378
23620
|
}
|
|
23379
23621
|
]
|
|
@@ -23804,7 +24046,11 @@ const SCREENS = runtimeSetting({
|
|
|
23804
24046
|
"bottom": 24
|
|
23805
24047
|
},
|
|
23806
24048
|
"onAppear": {
|
|
23807
|
-
"actionId": "tier5.himiMyEvents.load"
|
|
24049
|
+
"actionId": "tier5.himiMyEvents.load",
|
|
24050
|
+
"params": {
|
|
24051
|
+
"signInScreenId": "himi_sign_in",
|
|
24052
|
+
"memberOnly": "1"
|
|
24053
|
+
}
|
|
23808
24054
|
}
|
|
23809
24055
|
}
|
|
23810
24056
|
},
|
|
@@ -32546,6 +32792,31 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
32546
32792
|
"hiddenPath": "$service:himiBrandedProgram.hidePriceRetry"
|
|
32547
32793
|
}
|
|
32548
32794
|
},
|
|
32795
|
+
{
|
|
32796
|
+
"id": "himi_program.description_rich",
|
|
32797
|
+
"body": {
|
|
32798
|
+
"package": "himalaya",
|
|
32799
|
+
"type": "RichContent",
|
|
32800
|
+
"props": {
|
|
32801
|
+
"documentJsonPath": "$service:himiBrandedProgram.descriptionJson",
|
|
32802
|
+
"onLink": {
|
|
32803
|
+
"actionId": "tier5.himiBrandedProgram.openLink"
|
|
32804
|
+
},
|
|
32805
|
+
"fallback": {
|
|
32806
|
+
"id": "",
|
|
32807
|
+
"body": {
|
|
32808
|
+
"package": "himalaya",
|
|
32809
|
+
"type": "Text",
|
|
32810
|
+
"props": {
|
|
32811
|
+
"text": "$service:himiBrandedProgram.description",
|
|
32812
|
+
"style": "body",
|
|
32813
|
+
"color": "textSecondary"
|
|
32814
|
+
}
|
|
32815
|
+
}
|
|
32816
|
+
}
|
|
32817
|
+
}
|
|
32818
|
+
}
|
|
32819
|
+
},
|
|
32549
32820
|
{
|
|
32550
32821
|
"id": "",
|
|
32551
32822
|
"body": {
|
|
@@ -32557,6 +32828,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
32557
32828
|
"color": "textSecondary",
|
|
32558
32829
|
"collapseWhenEmpty": true
|
|
32559
32830
|
}
|
|
32831
|
+
},
|
|
32832
|
+
"modifiers": {
|
|
32833
|
+
"hiddenPath": "$service:himiBrandedProgram.hasDescriptionJson"
|
|
32560
32834
|
}
|
|
32561
32835
|
}
|
|
32562
32836
|
]
|
|
@@ -36352,6 +36626,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
36352
36626
|
"style": "body",
|
|
36353
36627
|
"color": "textSecondary"
|
|
36354
36628
|
}
|
|
36629
|
+
},
|
|
36630
|
+
"modifiers": {
|
|
36631
|
+
"hiddenPath": "$service:himiBlogPost.signInRequired"
|
|
36355
36632
|
}
|
|
36356
36633
|
},
|
|
36357
36634
|
{
|
|
@@ -36366,6 +36643,32 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
36366
36643
|
"actionId": "tier5.himiBlogPost.retry"
|
|
36367
36644
|
}
|
|
36368
36645
|
}
|
|
36646
|
+
},
|
|
36647
|
+
"modifiers": {
|
|
36648
|
+
"hiddenPath": "$service:himiBlogPost.signInRequired"
|
|
36649
|
+
}
|
|
36650
|
+
},
|
|
36651
|
+
{
|
|
36652
|
+
"id": "himi_blog_post.retry.sign_in",
|
|
36653
|
+
"body": {
|
|
36654
|
+
"package": "himalaya",
|
|
36655
|
+
"type": "Button",
|
|
36656
|
+
"props": {
|
|
36657
|
+
"title": "Sign in",
|
|
36658
|
+
"style": "primary",
|
|
36659
|
+
"action": {
|
|
36660
|
+
"actionId": "himi.open",
|
|
36661
|
+
"params": {
|
|
36662
|
+
"screenId": "himi_sign_in",
|
|
36663
|
+
"mode": "signin",
|
|
36664
|
+
"modal": "1"
|
|
36665
|
+
},
|
|
36666
|
+
"presentation": "sheet"
|
|
36667
|
+
}
|
|
36668
|
+
}
|
|
36669
|
+
},
|
|
36670
|
+
"modifiers": {
|
|
36671
|
+
"hiddenPath": "$service:himiBlogPost.noSignIn"
|
|
36369
36672
|
}
|
|
36370
36673
|
}
|
|
36371
36674
|
]
|
|
@@ -37070,7 +37373,8 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
37070
37373
|
"onAppear": {
|
|
37071
37374
|
"actionId": "tier5.himiBlogPost.load",
|
|
37072
37375
|
"params": {
|
|
37073
|
-
"id": "__HIMI_ID__"
|
|
37376
|
+
"id": "__HIMI_ID__",
|
|
37377
|
+
"signInScreenId": "himi_sign_in"
|
|
37074
37378
|
}
|
|
37075
37379
|
}
|
|
37076
37380
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { memberAccess, memberAccessChanged, memberAccessDenied, type MemberAccess } from "./member-access.js";
|
|
2
|
+
import { needsSignIn } from "./branded-load-state.js";
|
|
3
|
+
|
|
4
|
+
/** Public reads stay public. Capture their reader only to reject a result that
|
|
5
|
+
* belongs to the identity/site which was active before the request. */
|
|
6
|
+
export interface ReadAccess { member: MemberAccess; tenant: string; }
|
|
7
|
+
export async function readAccess(): Promise<ReadAccess> {
|
|
8
|
+
const member = await memberAccess();
|
|
9
|
+
const input = (globalThis as { himalaya?: { input?: Record<string, unknown> } }).himalaya?.input;
|
|
10
|
+
return { member, tenant: JSON.stringify([input?.__himiPreferenceAccount ?? "", input?.__himiPreferenceBusiness ?? ""]) };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function assertReadAccess(access: ReadAccess): Promise<void> {
|
|
14
|
+
const current = await readAccess();
|
|
15
|
+
if (current.member.email !== access.member.email || current.member.scope !== access.member.scope || current.tenant !== access.tenant) throw memberAccessChanged();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Bridge errors put the actual status first; codes quoted inside the body are data. */
|
|
19
|
+
function httpStatus(error: unknown): string | undefined {
|
|
20
|
+
return /^HTTP\s*(\d{3})\b/i.exec(String((error as { message?: unknown })?.message ?? error))?.[1];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const NO_READ_SIGN_IN = { signInRequired: false, noSignIn: true };
|
|
24
|
+
|
|
25
|
+
/** An authorization refusal must not fall back to a previously cached article. */
|
|
26
|
+
export function readAccessDenied(error: unknown): boolean {
|
|
27
|
+
let cause = error;
|
|
28
|
+
for (let depth = 0; cause && depth < 4; depth++) {
|
|
29
|
+
const status = httpStatus(cause);
|
|
30
|
+
if (status ? status === "401" || status === "403" : memberAccessDenied(cause) || needsSignIn(cause)) return true;
|
|
31
|
+
cause = (cause as { cause?: unknown }).cause;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** A permission failure alone says nothing about whether signing in can help.
|
|
37
|
+
* In particular, a private member profile can be unavailable to members too.
|
|
38
|
+
* Only an authentication refusal for a current visitor offers Sign in. Follow
|
|
39
|
+
* SDK wrapper causes (blog getPost preserves its original read error there). */
|
|
40
|
+
export async function readSignInFlags(error: unknown): Promise<typeof NO_READ_SIGN_IN> {
|
|
41
|
+
let authenticationRequired = false;
|
|
42
|
+
let permissionRefused = false;
|
|
43
|
+
let cause = error;
|
|
44
|
+
for (let depth = 0; cause && depth < 4; depth++) {
|
|
45
|
+
const status = httpStatus(cause);
|
|
46
|
+
permissionRefused ||= status === "403";
|
|
47
|
+
authenticationRequired ||= status ? status === "401" : needsSignIn(cause);
|
|
48
|
+
cause = (cause as { cause?: unknown }).cause;
|
|
49
|
+
}
|
|
50
|
+
const signInRequired = !permissionRefused && authenticationRequired && !(await memberAccess()).email;
|
|
51
|
+
return { signInRequired, noSignIn: !signInRequired };
|
|
52
|
+
}
|