@wix/himalaya-cli 0.1066.0 → 0.1068.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/ts/src/index.d.ts +1 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/site-shell.d.ts +125 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +218 -0
- package/dist/cli.mjs +85 -44
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/wix-site-to-himi-app.md +6 -1
- package/package.json +2 -2
- package/templates/himi-chat/dev/index.ts +13 -2
- package/templates/himi-chat/tier5-src/himi-chat/index.ts +6 -2
package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/site-shell.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { IconName } from "./icon-catalog.generated.js";
|
|
2
|
+
import type { DrawerItem, NavTabItem, ScreenDescriptor, WebViewConfig } from "./schema.js";
|
|
3
|
+
/** Which hosting platform the site runs on. Selects origin allow-lists (and, once
|
|
4
|
+
* RFC 0062 phase 2 lands, the binary-shipped page adapter). */
|
|
5
|
+
export type SiteKind = "wix" | "base44";
|
|
6
|
+
/** Where a page lives in the native chrome. `overflow` pages are routable (deep links,
|
|
7
|
+
* in-site links) but get no tab and no drawer row. */
|
|
8
|
+
export type SitePagePlacement = "tab" | "drawer" | "overflow";
|
|
9
|
+
/** One page of the customer's site, as the app presents it. */
|
|
10
|
+
export interface SitePage {
|
|
11
|
+
/** Stable id — becomes the tab id and the `site_<id>` screen id. `[a-z0-9_]+`. */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Native label (tab / drawer row / screen title). Copy, never a hard-coded string
|
|
14
|
+
* in a descriptor — it comes from the provisioning file. */
|
|
15
|
+
title: string;
|
|
16
|
+
/** Path relative to the site's base URL: `"/"`, `"/shop"`, `"shop"`. Never a full
|
|
17
|
+
* URL — an off-site page would carry the native chrome over someone else's site. */
|
|
18
|
+
path: string;
|
|
19
|
+
/** Design-system icon. Absent ⇒ `"globe"`. */
|
|
20
|
+
icon?: IconName;
|
|
21
|
+
/** Absent ⇒ `"tab"`. */
|
|
22
|
+
placement?: SitePagePlacement;
|
|
23
|
+
/** Per-page overrides, merged OVER the shell preset. */
|
|
24
|
+
webView?: Partial<WebViewConfig>;
|
|
25
|
+
}
|
|
26
|
+
/** What the shell hides from the hosted site so the native chrome is the only chrome.
|
|
27
|
+
* Every flag defaults to `true` (hidden). */
|
|
28
|
+
export interface SiteChrome {
|
|
29
|
+
/** The site's own header on inner pages (the home page keeps it — its menu is the
|
|
30
|
+
* site's primary nav). */
|
|
31
|
+
hideSiteHeader?: boolean;
|
|
32
|
+
/** The site's footer. */
|
|
33
|
+
hideSiteFooter?: boolean;
|
|
34
|
+
/** The Wix ads banner shown on non-premium Wix sites. Configurable on purpose: the
|
|
35
|
+
* default is hidden, and an owner (or a policy decision) can turn it back on
|
|
36
|
+
* without a new binary, because the flag rides the OTA descriptor. */
|
|
37
|
+
hideWixAds?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** The whole site as a shell sees it. Mirrors the `site` block of a site-shell app's
|
|
40
|
+
* `provisioning.json`. */
|
|
41
|
+
export interface SiteShellConfig {
|
|
42
|
+
/** Base URL of the published site, `https` only. May carry a path — free Wix sites
|
|
43
|
+
* live at `https://<user>.wixsite.com/<site>`. */
|
|
44
|
+
origin: string;
|
|
45
|
+
kind: SiteKind;
|
|
46
|
+
pages: readonly SitePage[];
|
|
47
|
+
chrome?: SiteChrome;
|
|
48
|
+
}
|
|
49
|
+
/** At most four site tabs; the rest belong in the drawer. Four, not the usual phone-bar five,
|
|
50
|
+
* because every tab keeps its WebView warm (`keepAlive`) and the native keep-alive stores
|
|
51
|
+
* hold four views on BOTH platforms (`WebViewKeepAliveStore`, cap 4) — a fifth tab would
|
|
52
|
+
* evict and destroy the least-recent tab's WebView, losing its scroll and form state. */
|
|
53
|
+
export declare const SITE_SHELL_MAX_TABS = 4;
|
|
54
|
+
/** Screen-id prefix for every site page (`site_<page.id>`). */
|
|
55
|
+
export declare const SITE_SCREEN_PREFIX = "site_";
|
|
56
|
+
/** Identity-provider origins a hosted site's OAuth hops need to stay in-WebView.
|
|
57
|
+
* Moved here from `apps/demo-app/dev/live.ts` so every shell shares one list. */
|
|
58
|
+
export declare const OAUTH_IDP_ORIGINS: readonly string[];
|
|
59
|
+
/** Every Base44 app's origins (`*.base44.app`) plus `base44.com`, the OAuth consent + redirect
|
|
60
|
+
* target. The demo app's Base44 cover uses these; a SITE SHELL deliberately does not — see
|
|
61
|
+
* {@link siteAllowedOrigins}. */
|
|
62
|
+
export declare const BASE44_ORIGINS: readonly string[];
|
|
63
|
+
/**
|
|
64
|
+
* Normalize a site base URL: `https` only, lower-cased host, no query/fragment, no
|
|
65
|
+
* trailing slash. Throws on anything else — a base URL that is not a loadable https
|
|
66
|
+
* site would be baked into a binary and break every launch.
|
|
67
|
+
*/
|
|
68
|
+
export declare function normalizeSiteOrigin(origin: string): string;
|
|
69
|
+
/** The host a site's pages load from (`user.wixsite.com`, `www.example.com`). */
|
|
70
|
+
export declare function siteHost(origin: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* What a site's WebViews may navigate to without leaving the app — scheme-qualified PATH
|
|
73
|
+
* BOUNDARIES (`https://owner.wixsite.com/my-shop/`), which the native allow-list matchers
|
|
74
|
+
* (`WebViewOriginPolicy.matches` / `allowedOriginMatches`) read as "this path, with or without
|
|
75
|
+
* the trailing slash, and everything under it". So, for the bridge-enabled WebView:
|
|
76
|
+
* • https only — an `http` link or redirect to the same host leaves the app;
|
|
77
|
+
* • a free site stays inside its own path — `/other-site` on the same `<user>.wixsite.com`
|
|
78
|
+
* host is a different site, and leaves the app;
|
|
79
|
+
* • never a prefix of another host — `https://site.com/` does not admit `site.com.evil.io`.
|
|
80
|
+
* A custom Wix domain also admits its apex / `www.` twin, because Wix redirects between them.
|
|
81
|
+
* Nothing else is admitted for any kind: a Base44 tenant gets its own host only, never every
|
|
82
|
+
* `*.base44.app` tenant — Base44 sign-in runs in the system auth session (RFC 0062 phase 5),
|
|
83
|
+
* not in this WebView.
|
|
84
|
+
*/
|
|
85
|
+
export declare function siteAllowedOrigins(origin: string, kind: SiteKind): string[];
|
|
86
|
+
/** Join a page path onto the site's base URL. Rejects absolute URLs and `..`. */
|
|
87
|
+
export declare function sitePageUrl(origin: string, path: string): string;
|
|
88
|
+
/** `site_<page.id>`. */
|
|
89
|
+
export declare function siteScreenId(page: Pick<SitePage, "id">): string;
|
|
90
|
+
/**
|
|
91
|
+
* Hide the hosted site's footer and/or the Wix ads banner, and keep them hidden as the
|
|
92
|
+
* page mutates. Ported from `generateElementHidingScript` in the Wix RN app
|
|
93
|
+
* (`@wix/hybrid-mobile-platform`), minus the header branch — header hiding is the
|
|
94
|
+
* native `hideHostedSiteHeader` path, which keeps the home page's header.
|
|
95
|
+
*
|
|
96
|
+
* Interim delivery: this rides `injectJsDocumentEnd`. RFC 0062 phase 2 replaces it
|
|
97
|
+
* with a binary-shipped adapter selected by id (`hostedSiteAdapter` + `hideWixAds`),
|
|
98
|
+
* so no raw page script travels over the air.
|
|
99
|
+
*/
|
|
100
|
+
export declare function siteChromeHidingScript(options: {
|
|
101
|
+
hideFooter: boolean;
|
|
102
|
+
hideWixAds: boolean;
|
|
103
|
+
}): string;
|
|
104
|
+
/** Resolved chrome flags — every absent flag is `true`. */
|
|
105
|
+
export declare function resolveSiteChrome(chrome: SiteChrome | undefined): Required<SiteChrome>;
|
|
106
|
+
/**
|
|
107
|
+
* The WebView behaviour every site tab shares. Derived from the demo app's Site tab
|
|
108
|
+
* (`buildWebViewSiteApp`), which runs a real Wix site this way on both platforms:
|
|
109
|
+
* immersive (the site fills the tab; the native tab bar is the chrome), inset so an
|
|
110
|
+
* uncooperative site never renders under the status bar, off-site links leave the app
|
|
111
|
+
* through a prompt, and in-site history gets a floating back button.
|
|
112
|
+
*/
|
|
113
|
+
export declare function siteWebViewPreset(site: Pick<SiteShellConfig, "origin" | "kind" | "chrome">): WebViewConfig;
|
|
114
|
+
/** The Tier-3 descriptor for one site page. */
|
|
115
|
+
export declare function defineSiteTab(site: SiteShellConfig, page: SitePage): ScreenDescriptor;
|
|
116
|
+
/** Every site page's descriptor, keyed by screen id. */
|
|
117
|
+
export declare function siteScreens(site: SiteShellConfig): Record<string, ScreenDescriptor>;
|
|
118
|
+
/** Tab-bar and drawer items for a site. Pages beyond {@link SITE_SHELL_MAX_TABS} that
|
|
119
|
+
* asked for a tab fall into the drawer rather than disappearing. */
|
|
120
|
+
export declare function siteNav(site: SiteShellConfig): {
|
|
121
|
+
tabs: NavTabItem[];
|
|
122
|
+
drawer: DrawerItem[];
|
|
123
|
+
};
|
|
124
|
+
/** Throws with a legible message on a site description no shell can build from. */
|
|
125
|
+
export declare function assertSiteShellConfig(site: SiteShellConfig): void;
|
|
@@ -12964,10 +12964,213 @@ var AppRegistryClient = class {
|
|
|
12964
12964
|
return apps.some((a) => a.id === appId) ? "provisioned" : "unprovisioned";
|
|
12965
12965
|
}
|
|
12966
12966
|
};
|
|
12967
|
+
|
|
12968
|
+
// ../../core/ts/src/site-shell.ts
|
|
12969
|
+
var SITE_SHELL_MAX_TABS = 4;
|
|
12970
|
+
var SITE_SCREEN_PREFIX = "site_";
|
|
12971
|
+
var OAUTH_IDP_ORIGINS = [
|
|
12972
|
+
"accounts.google.com",
|
|
12973
|
+
"*.google.com",
|
|
12974
|
+
"*.googleusercontent.com",
|
|
12975
|
+
"*.gstatic.com"
|
|
12976
|
+
];
|
|
12977
|
+
var BASE44_ORIGINS = ["*.base44.app", "*.base44.com"];
|
|
12978
|
+
var PAGE_ID = /^[a-z0-9_]+$/;
|
|
12979
|
+
function normalizeSiteOrigin(origin) {
|
|
12980
|
+
const raw = (typeof origin === "string" ? origin : "").trim();
|
|
12981
|
+
let url;
|
|
12982
|
+
try {
|
|
12983
|
+
url = new URL(raw);
|
|
12984
|
+
} catch {
|
|
12985
|
+
throw new Error(`site origin ${JSON.stringify(origin)} is not a URL`);
|
|
12986
|
+
}
|
|
12987
|
+
if (url.protocol !== "https:") {
|
|
12988
|
+
throw new Error(`site origin ${JSON.stringify(origin)} must be https`);
|
|
12989
|
+
}
|
|
12990
|
+
if (url.username || url.password) {
|
|
12991
|
+
throw new Error(`site origin ${JSON.stringify(origin)} must not carry credentials`);
|
|
12992
|
+
}
|
|
12993
|
+
if (url.search || url.hash) {
|
|
12994
|
+
throw new Error(`site origin ${JSON.stringify(origin)} must not carry a query or fragment`);
|
|
12995
|
+
}
|
|
12996
|
+
const path = url.pathname.replace(/\/+$/, "");
|
|
12997
|
+
return `https://${url.host.toLowerCase()}${path}`;
|
|
12998
|
+
}
|
|
12999
|
+
function siteHost(origin) {
|
|
13000
|
+
return new URL(normalizeSiteOrigin(origin)).host;
|
|
13001
|
+
}
|
|
13002
|
+
function siteAllowedOrigins(origin, kind) {
|
|
13003
|
+
const base = new URL(normalizeSiteOrigin(origin));
|
|
13004
|
+
const host = base.host;
|
|
13005
|
+
const path = base.pathname.replace(/\/+$/, "");
|
|
13006
|
+
const hosts = [host];
|
|
13007
|
+
const isWixFreeHost = host.endsWith(".wixsite.com") || host.endsWith(".wixstudio.com");
|
|
13008
|
+
if (!isWixFreeHost && kind === "wix") hosts.push(host.startsWith("www.") ? host.slice(4) : `www.${host}`);
|
|
13009
|
+
return hosts.map((h) => `https://${h}${path}/`);
|
|
13010
|
+
}
|
|
13011
|
+
function sitePageUrl(origin, path) {
|
|
13012
|
+
const base = normalizeSiteOrigin(origin);
|
|
13013
|
+
const raw = (typeof path === "string" ? path : "").trim();
|
|
13014
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(raw) || raw.startsWith("//")) {
|
|
13015
|
+
throw new Error(`site page path ${JSON.stringify(path)} must be relative to the site`);
|
|
13016
|
+
}
|
|
13017
|
+
if (raw.includes("\\")) {
|
|
13018
|
+
throw new Error(`site page path ${JSON.stringify(path)} must not contain a backslash`);
|
|
13019
|
+
}
|
|
13020
|
+
const trimmed = raw.replace(/^\/+/, "");
|
|
13021
|
+
const joined = trimmed ? `${base}/${trimmed}` : base;
|
|
13022
|
+
const resolved = new URL(joined);
|
|
13023
|
+
const baseUrl = new URL(base);
|
|
13024
|
+
const basePath = baseUrl.pathname.replace(/\/+$/, "");
|
|
13025
|
+
const inside = resolved.pathname === basePath || resolved.pathname === `${basePath}/` || resolved.pathname.startsWith(`${basePath}/`);
|
|
13026
|
+
if (resolved.host !== baseUrl.host || !inside) {
|
|
13027
|
+
throw new Error(`site page path ${JSON.stringify(path)} resolves outside the site`);
|
|
13028
|
+
}
|
|
13029
|
+
return joined;
|
|
13030
|
+
}
|
|
13031
|
+
function siteScreenId(page) {
|
|
13032
|
+
return `${SITE_SCREEN_PREFIX}${page.id}`;
|
|
13033
|
+
}
|
|
13034
|
+
function siteChromeHidingScript(options) {
|
|
13035
|
+
if (!options.hideFooter && !options.hideWixAds) return "";
|
|
13036
|
+
return `(function(){
|
|
13037
|
+
if (window.__himiSiteChromeHider) return;
|
|
13038
|
+
window.__himiSiteChromeHider = true;
|
|
13039
|
+
var HIDE_FOOTER = ${options.hideFooter ? "true" : "false"};
|
|
13040
|
+
var HIDE_ADS = ${options.hideWixAds ? "true" : "false"};
|
|
13041
|
+
function hide(el, collapse) {
|
|
13042
|
+
if (!el) return;
|
|
13043
|
+
el.style.display = 'none';
|
|
13044
|
+
el.style.visibility = 'hidden';
|
|
13045
|
+
if (collapse) { el.style.height = '0px'; el.style.overflow = 'hidden'; }
|
|
13046
|
+
}
|
|
13047
|
+
function pass() {
|
|
13048
|
+
if (HIDE_FOOTER) {
|
|
13049
|
+
hide(document.getElementsByTagName('footer')[0] ||
|
|
13050
|
+
document.querySelector('footer[id^="comp-"]') ||
|
|
13051
|
+
document.querySelector('[class*="wixui-footer"]') ||
|
|
13052
|
+
document.querySelector('[data-mesh-id*="SITE_FOOTER"]') ||
|
|
13053
|
+
document.querySelector('[id*="SITE_FOOTER"]'), false);
|
|
13054
|
+
}
|
|
13055
|
+
if (HIDE_ADS) {
|
|
13056
|
+
hide(document.getElementById('WIX_ADS') ||
|
|
13057
|
+
document.querySelector('.WIX_ADS') ||
|
|
13058
|
+
document.querySelector('[class*="WIX_ADS"]'), true);
|
|
13059
|
+
}
|
|
13060
|
+
}
|
|
13061
|
+
var scheduled = false;
|
|
13062
|
+
function schedule() {
|
|
13063
|
+
if (scheduled) return;
|
|
13064
|
+
scheduled = true;
|
|
13065
|
+
requestAnimationFrame(function(){ scheduled = false; pass(); });
|
|
13066
|
+
}
|
|
13067
|
+
function start() {
|
|
13068
|
+
pass();
|
|
13069
|
+
new MutationObserver(schedule).observe(document.documentElement, { childList: true, subtree: true });
|
|
13070
|
+
}
|
|
13071
|
+
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start);
|
|
13072
|
+
else start();
|
|
13073
|
+
})();`;
|
|
13074
|
+
}
|
|
13075
|
+
function resolveSiteChrome(chrome) {
|
|
13076
|
+
return {
|
|
13077
|
+
hideSiteHeader: chrome?.hideSiteHeader ?? true,
|
|
13078
|
+
hideSiteFooter: chrome?.hideSiteFooter ?? true,
|
|
13079
|
+
hideWixAds: chrome?.hideWixAds ?? true
|
|
13080
|
+
};
|
|
13081
|
+
}
|
|
13082
|
+
function siteWebViewPreset(site) {
|
|
13083
|
+
const chrome = resolveSiteChrome(site.chrome);
|
|
13084
|
+
const hidingScript = site.kind === "wix" ? siteChromeHidingScript({ hideFooter: chrome.hideSiteFooter, hideWixAds: chrome.hideWixAds }) : siteChromeHidingScript({ hideFooter: chrome.hideSiteFooter, hideWixAds: false });
|
|
13085
|
+
const config = {
|
|
13086
|
+
layout: "inset",
|
|
13087
|
+
immersive: true,
|
|
13088
|
+
hideHostedSiteHeader: chrome.hideSiteHeader,
|
|
13089
|
+
pullToRefresh: true,
|
|
13090
|
+
showProgressBar: true,
|
|
13091
|
+
syncStatusBarAppearance: true,
|
|
13092
|
+
allowedOrigins: siteAllowedOrigins(site.origin, site.kind),
|
|
13093
|
+
externalLinks: "system_browser",
|
|
13094
|
+
promptBeforeExternalLink: true,
|
|
13095
|
+
// A real external site, not Himalaya screens — its links stay in its WebView.
|
|
13096
|
+
interceptInternalLinks: false,
|
|
13097
|
+
floatingBackButton: { enabled: true },
|
|
13098
|
+
autoReloadOnCrash: true,
|
|
13099
|
+
domStorageEnabled: true,
|
|
13100
|
+
// Each tab keeps its own warm WebView across tab switches (keyed by screen id on both
|
|
13101
|
+
// platforms; see SITE_SHELL_MAX_TABS for why the tab count stays within the store's cap).
|
|
13102
|
+
keepAlive: true
|
|
13103
|
+
};
|
|
13104
|
+
if (hidingScript) config.injectJsDocumentEnd = hidingScript;
|
|
13105
|
+
return config;
|
|
13106
|
+
}
|
|
13107
|
+
function defineSiteTab(site, page) {
|
|
13108
|
+
assertSitePage(page);
|
|
13109
|
+
const preset = siteWebViewPreset(site);
|
|
13110
|
+
return {
|
|
13111
|
+
screenId: siteScreenId(page),
|
|
13112
|
+
renderer: "webview_native_bridge",
|
|
13113
|
+
title: page.title,
|
|
13114
|
+
url: sitePageUrl(site.origin, page.path),
|
|
13115
|
+
capabilitiesRequired: [],
|
|
13116
|
+
schemaVersion: 1,
|
|
13117
|
+
// Wix serves page HTML `no-cache`; the descriptor itself is cheap to revalidate.
|
|
13118
|
+
cacheControl: { maxAge: 600, staleWhileRevalidate: 86400 },
|
|
13119
|
+
webViewConfig: { ...preset, ...page.webView ?? {} }
|
|
13120
|
+
};
|
|
13121
|
+
}
|
|
13122
|
+
function siteScreens(site) {
|
|
13123
|
+
assertSiteShellConfig(site);
|
|
13124
|
+
return Object.fromEntries(site.pages.map((page) => [siteScreenId(page), defineSiteTab(site, page)]));
|
|
13125
|
+
}
|
|
13126
|
+
function siteNav(site) {
|
|
13127
|
+
assertSiteShellConfig(site);
|
|
13128
|
+
const tabs = [];
|
|
13129
|
+
const drawer = [];
|
|
13130
|
+
for (const page of site.pages) {
|
|
13131
|
+
const placement = page.placement ?? "tab";
|
|
13132
|
+
const icon = page.icon ?? "globe";
|
|
13133
|
+
if (placement === "tab" && tabs.length < SITE_SHELL_MAX_TABS) {
|
|
13134
|
+
tabs.push({ id: page.id, screenId: siteScreenId(page), label: page.title, icon });
|
|
13135
|
+
}
|
|
13136
|
+
if (placement !== "overflow") {
|
|
13137
|
+
drawer.push({ id: `drawer_${page.id}`, screenId: siteScreenId(page), label: page.title, icon });
|
|
13138
|
+
}
|
|
13139
|
+
}
|
|
13140
|
+
return { tabs, drawer };
|
|
13141
|
+
}
|
|
13142
|
+
function assertSitePage(page) {
|
|
13143
|
+
if (!page || typeof page.id !== "string" || !PAGE_ID.test(page.id)) {
|
|
13144
|
+
throw new Error(`site page id ${JSON.stringify(page?.id)} must match ${PAGE_ID}`);
|
|
13145
|
+
}
|
|
13146
|
+
if (typeof page.title !== "string" || !page.title.trim()) {
|
|
13147
|
+
throw new Error(`site page ${page.id} needs a title`);
|
|
13148
|
+
}
|
|
13149
|
+
}
|
|
13150
|
+
function assertSiteShellConfig(site) {
|
|
13151
|
+
normalizeSiteOrigin(site.origin);
|
|
13152
|
+
if (site.kind !== "wix" && site.kind !== "base44") {
|
|
13153
|
+
throw new Error(`site kind ${JSON.stringify(site.kind)} must be "wix" or "base44"`);
|
|
13154
|
+
}
|
|
13155
|
+
if (!Array.isArray(site.pages) || site.pages.length === 0) {
|
|
13156
|
+
throw new Error("a site shell needs at least one page");
|
|
13157
|
+
}
|
|
13158
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13159
|
+
for (const page of site.pages) {
|
|
13160
|
+
assertSitePage(page);
|
|
13161
|
+
if (seen.has(page.id)) throw new Error(`site page id ${page.id} is declared twice`);
|
|
13162
|
+
seen.add(page.id);
|
|
13163
|
+
sitePageUrl(site.origin, page.path);
|
|
13164
|
+
}
|
|
13165
|
+
if (!site.pages.some((page) => (page.placement ?? "tab") === "tab")) {
|
|
13166
|
+
throw new Error('a site shell needs at least one page with placement "tab"');
|
|
13167
|
+
}
|
|
13168
|
+
}
|
|
12967
13169
|
export {
|
|
12968
13170
|
ALL_ORIENTATIONS,
|
|
12969
13171
|
APP_ID_PATTERN,
|
|
12970
13172
|
AppRegistryClient,
|
|
13173
|
+
BASE44_ORIGINS,
|
|
12971
13174
|
CHASSIS_GEOMETRY,
|
|
12972
13175
|
CORE_COMPONENTS,
|
|
12973
13176
|
DEFAULT_DISTRIBUTION,
|
|
@@ -12988,6 +13191,7 @@ export {
|
|
|
12988
13191
|
LAUNCH_MANIFEST_SCHEMA,
|
|
12989
13192
|
LAUNCH_NAMESPACE,
|
|
12990
13193
|
LINK_MOUNT_PATHS,
|
|
13194
|
+
OAUTH_IDP_ORIGINS,
|
|
12991
13195
|
ORIGIN_PARAM_KEYS,
|
|
12992
13196
|
PACKAGE_SHARE_ID_PATTERN,
|
|
12993
13197
|
PLAYER_PREVIEW_SEGMENT_PATTERN,
|
|
@@ -12995,6 +13199,8 @@ export {
|
|
|
12995
13199
|
PREVIEW_SURFACES,
|
|
12996
13200
|
PROJECTION_SNAPSHOT_SIZE,
|
|
12997
13201
|
RTL_LOCALES,
|
|
13202
|
+
SITE_SCREEN_PREFIX,
|
|
13203
|
+
SITE_SHELL_MAX_TABS,
|
|
12998
13204
|
SIZE_CLASS_BREAKPOINTS,
|
|
12999
13205
|
SPLASH_MAX_HOLD_MS_MAX,
|
|
13000
13206
|
SPLASH_MIN_VISIBLE_MS_MAX,
|
|
@@ -13013,6 +13219,7 @@ export {
|
|
|
13013
13219
|
WORKER_SUBTREE_COMMON_ACTION_PATHS,
|
|
13014
13220
|
WORKER_SUBTREE_SAFE_TYPE_RULES,
|
|
13015
13221
|
activeMediaItem,
|
|
13222
|
+
assertSiteShellConfig,
|
|
13016
13223
|
baselineMediaCapabilities,
|
|
13017
13224
|
bucket,
|
|
13018
13225
|
buildHimiPreviewUrl,
|
|
@@ -13029,6 +13236,7 @@ export {
|
|
|
13029
13236
|
decodeLaunchParams,
|
|
13030
13237
|
defaultMessage,
|
|
13031
13238
|
defineApp,
|
|
13239
|
+
defineSiteTab,
|
|
13032
13240
|
effectiveFieldRule,
|
|
13033
13241
|
errorMessageFor,
|
|
13034
13242
|
evaluate,
|
|
@@ -13052,6 +13260,7 @@ export {
|
|
|
13052
13260
|
isWidgetFamilySurface,
|
|
13053
13261
|
layoutDirection,
|
|
13054
13262
|
mergeIdiomOverlay,
|
|
13263
|
+
normalizeSiteOrigin,
|
|
13055
13264
|
parseNumeric,
|
|
13056
13265
|
primarySubtag,
|
|
13057
13266
|
resolveAppIdentity,
|
|
@@ -13063,6 +13272,7 @@ export {
|
|
|
13063
13272
|
resolveMode,
|
|
13064
13273
|
resolveOrientationEnvelope,
|
|
13065
13274
|
resolveResponsiveSize,
|
|
13275
|
+
resolveSiteChrome,
|
|
13066
13276
|
resolveSizeClass,
|
|
13067
13277
|
resolveSurfaceEnvelope,
|
|
13068
13278
|
resolveSurfaceNav,
|
|
@@ -13071,6 +13281,14 @@ export {
|
|
|
13071
13281
|
screenDescriptorSchema,
|
|
13072
13282
|
selectIdiomOverlay,
|
|
13073
13283
|
shouldRevealError,
|
|
13284
|
+
siteAllowedOrigins,
|
|
13285
|
+
siteChromeHidingScript,
|
|
13286
|
+
siteHost,
|
|
13287
|
+
siteNav,
|
|
13288
|
+
sitePageUrl,
|
|
13289
|
+
siteScreenId,
|
|
13290
|
+
siteScreens,
|
|
13291
|
+
siteWebViewPreset,
|
|
13074
13292
|
stripOriginParams,
|
|
13075
13293
|
summarize,
|
|
13076
13294
|
surfaceById,
|
package/dist/cli.mjs
CHANGED
|
@@ -1437,8 +1437,12 @@ function sentinelizeArchive(raw, fallbackName) {
|
|
|
1437
1437
|
} catch {
|
|
1438
1438
|
}
|
|
1439
1439
|
const name = contentName ?? config.match(/\bname\s*:\s*["']([^"'\n]+)["']/)?.[1] ?? fallbackName;
|
|
1440
|
+
const packageSlug = new RegExp(`\\b(const PACKAGE_SLUG = )"${escapeRe(name)}"`, "g");
|
|
1440
1441
|
return Object.fromEntries(
|
|
1441
|
-
entries.map(([rel, body]) => [
|
|
1442
|
+
entries.map(([rel, body]) => [
|
|
1443
|
+
rel,
|
|
1444
|
+
sentinelizeIdentity(body, { name: IDENTITY_FILES.has(rel) ? name : void 0, ids }).replace(packageSlug, '$1"__HIMI_APP_SLUG__"')
|
|
1445
|
+
])
|
|
1442
1446
|
);
|
|
1443
1447
|
}
|
|
1444
1448
|
function materializeSource(files, name, destDir, slug = name) {
|
|
@@ -3866,6 +3870,14 @@ var init_dist_jobs = __esm({
|
|
|
3866
3870
|
bundleId: { ios: "ent.wix.ownerlite.dev", android: "com.wix.himi.ownerlite.dev" },
|
|
3867
3871
|
provisioningEnv: "HIMI_OWNER_LITE_PROVISIONING_JSON"
|
|
3868
3872
|
},
|
|
3873
|
+
// RFC 0062 — the site shell: the customer's own website as native-framed Tier-3 tabs.
|
|
3874
|
+
// Brandable (its package.json declares prepare:customer), so dist bakes the fetched
|
|
3875
|
+
// contract's identity, icon, brand colour and `site` block into the binary.
|
|
3876
|
+
brandy: {
|
|
3877
|
+
appDir: "apps/himi-brandy",
|
|
3878
|
+
bundleId: { ios: "ent.wix.brandy.dev", android: "com.wix.himi.brandy.dev" },
|
|
3879
|
+
provisioningEnv: "HIMI_BRANDY_PROVISIONING_JSON"
|
|
3880
|
+
},
|
|
3869
3881
|
player: {
|
|
3870
3882
|
appDir: "apps/himi-player",
|
|
3871
3883
|
bundleId: { ios: "dev.himalaya.player.dev", android: "dev.himalaya.player.dev" },
|
|
@@ -12446,7 +12458,6 @@ function resolveIdiom(tokens, ctx = {}) {
|
|
|
12446
12458
|
var IDIOM_CONTEXTS, UNSAFE_KEYS;
|
|
12447
12459
|
var init_idiom = __esm({
|
|
12448
12460
|
"../../core/ts/src/idiom.ts"() {
|
|
12449
|
-
"use strict";
|
|
12450
12461
|
IDIOM_CONTEXTS = {
|
|
12451
12462
|
ios: { native: ["ios"] },
|
|
12452
12463
|
android: { native: ["material"] },
|
|
@@ -22302,7 +22313,7 @@ function bindingPlaceholder(v, ctx) {
|
|
|
22302
22313
|
if (ctx.runtimeDegraded) return null;
|
|
22303
22314
|
return /* @__PURE__ */ jsx("span", { style: { color: ctx.color("textSecondary", "#9aa2ad"), fontStyle: "italic", overflowWrap: "anywhere", wordBreak: "break-word" }, children: v.replace(/^\$/, "") });
|
|
22304
22315
|
}
|
|
22305
|
-
function mdScan(src) {
|
|
22316
|
+
function mdScan(src, linkStyle = "") {
|
|
22306
22317
|
const re = new RegExp(MD_INLINE.source, "g");
|
|
22307
22318
|
let out = "";
|
|
22308
22319
|
let last = 0;
|
|
@@ -22314,21 +22325,22 @@ function mdScan(src) {
|
|
|
22314
22325
|
} else if (label2 !== void 0) {
|
|
22315
22326
|
if (/^https?:\/\//i.test(url)) {
|
|
22316
22327
|
const href = mdEsc(url).replace(/"/g, """);
|
|
22317
|
-
out += `<a href="${href}" target="_blank" rel="noopener noreferrer">${mdScan(label2)}</a>`;
|
|
22328
|
+
out += `<a href="${href}" target="_blank" rel="noopener noreferrer"${linkStyle}>${mdScan(label2, linkStyle)}</a>`;
|
|
22318
22329
|
} else {
|
|
22319
22330
|
out += mdEsc(whole);
|
|
22320
22331
|
}
|
|
22321
22332
|
} else if (bold !== void 0) {
|
|
22322
|
-
out += `<b>${mdScan(bold)}</b>`;
|
|
22333
|
+
out += `<b>${mdScan(bold, linkStyle)}</b>`;
|
|
22323
22334
|
} else {
|
|
22324
|
-
out += `<i>${mdScan(italic)}</i>`;
|
|
22335
|
+
out += `<i>${mdScan(italic, linkStyle)}</i>`;
|
|
22325
22336
|
}
|
|
22326
22337
|
last = m.index + whole.length;
|
|
22327
22338
|
}
|
|
22328
22339
|
return out + mdEsc(src.slice(last));
|
|
22329
22340
|
}
|
|
22330
|
-
function mdInline(text5) {
|
|
22331
|
-
|
|
22341
|
+
function mdInline(text5, linkColor) {
|
|
22342
|
+
const safe = typeof linkColor === "string" && /^[#a-zA-Z0-9(),.%\s-]+$/.test(linkColor) ? linkColor : "";
|
|
22343
|
+
return { __html: mdScan(text5, safe ? ` style="color:${safe}"` : "") };
|
|
22332
22344
|
}
|
|
22333
22345
|
function sevColor(ctx, sev) {
|
|
22334
22346
|
switch (sev) {
|
|
@@ -22343,6 +22355,20 @@ function sevColor(ctx, sev) {
|
|
|
22343
22355
|
return ctx.color("accentPrimary", "#116DFF");
|
|
22344
22356
|
}
|
|
22345
22357
|
}
|
|
22358
|
+
function accentTextColor(ctx) {
|
|
22359
|
+
return ctx.color("accentText", ctx.color("accentPrimary", "#116DFF"));
|
|
22360
|
+
}
|
|
22361
|
+
function sevTextColor(ctx, sev) {
|
|
22362
|
+
switch (sev) {
|
|
22363
|
+
case "success":
|
|
22364
|
+
case "warning":
|
|
22365
|
+
case "danger":
|
|
22366
|
+
case "error":
|
|
22367
|
+
return sevColor(ctx, sev);
|
|
22368
|
+
default:
|
|
22369
|
+
return accentTextColor(ctx);
|
|
22370
|
+
}
|
|
22371
|
+
}
|
|
22346
22372
|
function iconGlyph(name) {
|
|
22347
22373
|
if (typeof name !== "string" || !name) return "\xB7";
|
|
22348
22374
|
const key2 = name.toLowerCase().replace(/[_.\s-]/g, "");
|
|
@@ -22874,7 +22900,6 @@ function shouldRevealError(args) {
|
|
|
22874
22900
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
22875
22901
|
var init_validation = __esm({
|
|
22876
22902
|
"../../core/ts/src/validation.ts"() {
|
|
22877
|
-
"use strict";
|
|
22878
22903
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
22879
22904
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
22880
22905
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -25728,7 +25753,7 @@ var init_controls = __esm({
|
|
|
25728
25753
|
"aria-selected": on3,
|
|
25729
25754
|
tabIndex: on3 ? 0 : -1,
|
|
25730
25755
|
onClick: () => select(i),
|
|
25731
|
-
style: { all: "unset", display: "flex", gap: 6, alignItems: "center", minWidth: 44, minHeight: 44, padding: "10px 0", fontFamily: FONT(ctx), fontWeight: 600, fontSize: 14, cursor: "pointer", color: on3 ?
|
|
25756
|
+
style: { all: "unset", display: "flex", gap: 6, alignItems: "center", minWidth: 44, minHeight: 44, padding: "10px 0", fontFamily: FONT(ctx), fontWeight: 600, fontSize: 14, cursor: "pointer", color: on3 ? accentTextColor(ctx) : C("textSecondary", "#777"), borderBottom: on3 ? `2px solid ${C("accentPrimary", "#116DFF")}` : "2px solid transparent", marginBottom: -1 },
|
|
25732
25757
|
children: [
|
|
25733
25758
|
asText2(t.label),
|
|
25734
25759
|
t.badge && /* @__PURE__ */ jsx4("span", { "aria-hidden": true, style: { fontSize: 10, fontWeight: 700, background: C("surfaceTertiary", "#eee"), color: C("textSecondary", "#666"), padding: "1px 6px", borderRadius: 999 }, children: t.badge })
|
|
@@ -26475,7 +26500,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
26475
26500
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
26476
26501
|
var init_worker_subtree = __esm({
|
|
26477
26502
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
26478
|
-
"use strict";
|
|
26479
26503
|
init_worker_subtree_safe_types_generated();
|
|
26480
26504
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
26481
26505
|
maxEncodedBytes: 65536,
|
|
@@ -27802,9 +27826,6 @@ function actionClick(ctx, action) {
|
|
|
27802
27826
|
ctx.onAction(resolveItemDeep2(action, ctx));
|
|
27803
27827
|
};
|
|
27804
27828
|
}
|
|
27805
|
-
function accentTextColor(ctx) {
|
|
27806
|
-
return ctx.color("accentText", ctx.color("accentPrimary", "#116DFF"));
|
|
27807
|
-
}
|
|
27808
27829
|
function actionTextButton(ctx, action, label2, color, extra) {
|
|
27809
27830
|
if (action == null) return null;
|
|
27810
27831
|
const onClick = actionClick(ctx, action);
|
|
@@ -28485,7 +28506,7 @@ function renderInner(node, ctx) {
|
|
|
28485
28506
|
/* @__PURE__ */ jsx6("div", { style: { width: 46, height: 46, borderRadius: 13, background: C("surfaceTertiary", "#eee"), display: "grid", placeItems: "center", margin: "0 auto 12px", color: C("textSecondary", "#9aa2ad") }, children: iconSvg(props.icon, { size: 24 }) }),
|
|
28486
28507
|
/* @__PURE__ */ jsx6("div", { style: { fontFamily: bodyFont(ctx), fontWeight: 600, fontSize: 16, color: C("textPrimary", "#111") }, children: asBoundText(props.title, ctx) || "Empty" }),
|
|
28487
28508
|
props.subtitle && /* @__PURE__ */ jsx6("div", { style: { fontFamily: bodyFont(ctx), fontSize: 13, color: C("textSecondary", "#888"), marginTop: 3 }, children: txt(props.subtitle, ctx) }),
|
|
28488
|
-
actionTextButton(ctx, props.action, asBoundText(props.actionLabel, ctx) || "Take action",
|
|
28509
|
+
actionTextButton(ctx, props.action, asBoundText(props.actionLabel, ctx) || "Take action", accentTextColor(ctx), { margin: "12px auto 0", textAlign: "center" })
|
|
28489
28510
|
] });
|
|
28490
28511
|
// ───────────── atoms ─────────────
|
|
28491
28512
|
case "Text":
|
|
@@ -28495,7 +28516,7 @@ function renderInner(node, ctx) {
|
|
|
28495
28516
|
return /* @__PURE__ */ jsx6("div", { style: { fontFamily: bodyFont(ctx), lineHeight: 1.5, overflowWrap: "break-word", color: C(resolveScalarStatic(props.color, ctx) ?? "textPrimary", "#13171e"), ...wrap }, children: runs.map((r, i) => {
|
|
28496
28517
|
const marks = Array.isArray(r.marks) ? r.marks : [];
|
|
28497
28518
|
const f = ctx.font(r.style);
|
|
28498
|
-
return /* @__PURE__ */ jsx6("span", { style: { fontSize: f.remSize, fontWeight: marks.includes("bold") ? 700 : f.weight, fontStyle: marks.includes("italic") ? "italic" : void 0, textDecoration: marks.includes("underline") ? "underline" : void 0, ...f.family ? { fontFamily: fontStack(f.family, ctx.idiom) } : {}, ...r.color ? { color: C(r.color) } : {}, ...marks.includes("code") ? { fontFamily: "ui-monospace, monospace", background: C("surfaceTertiary", "#eee"), padding: "1px 5px", borderRadius: 4 } : {} }, children: txt(r.text, ctx) }, i);
|
|
28519
|
+
return /* @__PURE__ */ jsx6("span", { style: { fontSize: f.remSize, fontWeight: marks.includes("bold") ? 700 : f.weight, fontStyle: marks.includes("italic") ? "italic" : void 0, textDecoration: marks.includes("underline") || marks.includes("link") ? "underline" : void 0, ...f.family ? { fontFamily: fontStack(f.family, ctx.idiom) } : {}, ...r.color ? { color: C(r.color) } : marks.includes("link") ? { color: accentTextColor(ctx) } : {}, ...marks.includes("code") ? { fontFamily: "ui-monospace, monospace", background: C("surfaceTertiary", "#eee"), padding: "1px 5px", borderRadius: 4 } : {} }, children: txt(r.text, ctx) }, i);
|
|
28499
28520
|
}) });
|
|
28500
28521
|
}
|
|
28501
28522
|
case "Image":
|
|
@@ -28524,11 +28545,14 @@ function renderInner(node, ctx) {
|
|
|
28524
28545
|
const liveCount = typeof props.text === "string" && /^\$(?:service|flag)\b/.test(props.text);
|
|
28525
28546
|
const badgeLabel = m?.accessibilityLabel ?? m?.accessibility_label;
|
|
28526
28547
|
const badgeRole = roleDeclared ? void 0 : liveCount ? "status" : typeof badgeLabel === "string" && badgeLabel.trim() !== "" ? "img" : void 0;
|
|
28527
|
-
|
|
28548
|
+
const fg = _bt ? c : sevTextColor(ctx, props.style ?? "info");
|
|
28549
|
+
return /* @__PURE__ */ jsx6("span", { role: badgeRole, style: { display: "inline-flex", alignItems: "center", padding: "3px 9px", borderRadius: 999, fontSize: 12, fontWeight: 700, fontFamily: bodyFont(ctx), background: `color-mix(in srgb, ${c} 16%, ${C("surfacePrimary", "#fff")})`, color: fg, ...wrap }, children: ctx.empty ? "" : txt(props.text, ctx) || "Badge" });
|
|
28528
28550
|
}
|
|
28529
28551
|
case "Tag": {
|
|
28530
|
-
const
|
|
28531
|
-
|
|
28552
|
+
const tagToken = boundTokenName(props.tokenPath, props.token, ctx);
|
|
28553
|
+
const c = C(tagToken ?? "accentPrimary", "#116DFF");
|
|
28554
|
+
const tagFg = tagToken ? c : accentTextColor(ctx);
|
|
28555
|
+
return /* @__PURE__ */ jsx6("span", { style: { display: "inline-flex", alignItems: "center", padding: "5px 11px", borderRadius: 999, fontSize: 13, fontWeight: 600, fontFamily: bodyFont(ctx), background: `color-mix(in srgb, ${c} 14%, ${C("surfacePrimary", "#fff")})`, border: `1px solid color-mix(in srgb, ${c} 30%, transparent)`, color: tagFg, ...wrap }, children: ctx.empty ? "" : txt(props.text, ctx) || "Tag" });
|
|
28532
28556
|
}
|
|
28533
28557
|
case "ProgressBar":
|
|
28534
28558
|
return /* @__PURE__ */ jsx6(ProgressBarNode, { props, ctx, wrap });
|
|
@@ -28779,7 +28803,7 @@ function renderInner(node, ctx) {
|
|
|
28779
28803
|
return /* @__PURE__ */ jsx6("div", { style: { display: "flex", flexDirection: "column", gap: 6, width: "100%", ...wrap }, children: branch ? renderNode(props[branch], ctx) : cfg && typeof cfg === "object" ? /* @__PURE__ */ jsxs3("div", { style: { textAlign: "center", padding: "24px 12px", color: C("textSecondary", "#9aa2ad") }, children: [
|
|
28780
28804
|
cfg.title && /* @__PURE__ */ jsx6("div", { style: { fontSize: 15, fontWeight: 600, color: C("textPrimary", "#111") }, children: asText2(cfg.title) }),
|
|
28781
28805
|
(cfg.subtitle ?? cfg.message) && /* @__PURE__ */ jsx6("div", { style: { fontSize: 13, marginTop: 4 }, children: asText2(cfg.subtitle ?? cfg.message) }),
|
|
28782
|
-
actionTextButton(ctx, cfg.retry ?? cfg.action, asText2(cfg.retryLabel) || asText2(cfg.actionLabel) || (cfg.retry != null ? "Retry" : "Take action"),
|
|
28806
|
+
actionTextButton(ctx, cfg.retry ?? cfg.action, asText2(cfg.retryLabel) || asText2(cfg.actionLabel) || (cfg.retry != null ? "Retry" : "Take action"), accentTextColor(ctx), { margin: "12px auto 0", textAlign: "center" })
|
|
28783
28807
|
] }) : null });
|
|
28784
28808
|
}
|
|
28785
28809
|
case "FragmentSlot":
|
|
@@ -30410,7 +30434,8 @@ var init_renderNode = __esm({
|
|
|
30410
30434
|
display: "grid",
|
|
30411
30435
|
placeItems: "center",
|
|
30412
30436
|
fontSize: 18,
|
|
30413
|
-
color:
|
|
30437
|
+
color: accentTextColor(ctx),
|
|
30438
|
+
// #3275 — a glyph on a neutral key
|
|
30414
30439
|
border: `1px solid ${C("border", "#e3e3e3")}`,
|
|
30415
30440
|
cursor: ctx.onAction && !disabled(at) ? "pointer" : "default",
|
|
30416
30441
|
opacity: disabled(at) ? 0.4 : 1,
|
|
@@ -30595,7 +30620,7 @@ var init_renderNode = __esm({
|
|
|
30595
30620
|
const resolved2 = resolveScalarStatic(props.text, ctx);
|
|
30596
30621
|
return resolved2 == null ? null : String(resolved2);
|
|
30597
30622
|
})();
|
|
30598
|
-
const content = countContent != null ? countContent : icuPattern != null ? /* @__PURE__ */ jsx6(InterpolatedTextView, { pattern: icuPattern, params: props.template?.params ?? {}, ctx }) : mdSource != null ? /* @__PURE__ */ jsx6("span", { dangerouslySetInnerHTML: mdInline(mdSource) }) : txt(props.text, ctx);
|
|
30623
|
+
const content = countContent != null ? countContent : icuPattern != null ? /* @__PURE__ */ jsx6(InterpolatedTextView, { pattern: icuPattern, params: props.template?.params ?? {}, ctx }) : mdSource != null ? /* @__PURE__ */ jsx6("span", { dangerouslySetInnerHTML: mdInline(mdSource, accentTextColor(ctx)) }) : txt(props.text, ctx);
|
|
30599
30624
|
const tAlign = props.textAlign === "center" ? "center" : props.textAlign === "trailing" ? "right" : props.textAlign === "justify" ? "justify" : props.textAlign === "leading" ? "left" : void 0;
|
|
30600
30625
|
const tDecor = props.decoration === "strikethrough" ? "line-through" : props.decoration === "underline" ? "underline" : void 0;
|
|
30601
30626
|
const ln = typeof props.lineSpacing === "number" ? pxToRem((f.line ?? 1.4) * f.size + props.lineSpacing) : f.line;
|
|
@@ -30641,7 +30666,7 @@ var init_renderNode = __esm({
|
|
|
30641
30666
|
}
|
|
30642
30667
|
if (props.icon != null && props.url == null && props.asset == null && imgInitials == null) {
|
|
30643
30668
|
const side2 = typeof w === "number" ? w : 40;
|
|
30644
|
-
return /* @__PURE__ */ jsx6("div", { style: { width: side2, height: side2, borderRadius: "50%", background: ph ?? C("surfaceTertiary", "#e6e6e6"), display: "grid", placeItems: "center", flex: "none", ...wrap }, children: iconSvg(props.icon, { size: Math.max(14, Math.round(side2 * 0.5)), color:
|
|
30669
|
+
return /* @__PURE__ */ jsx6("div", { style: { width: side2, height: side2, borderRadius: "50%", background: ph ?? C("surfaceTertiary", "#e6e6e6"), display: "grid", placeItems: "center", flex: "none", ...wrap }, children: iconSvg(props.icon, { size: Math.max(14, Math.round(side2 * 0.5)), color: accentTextColor(ctx) }) });
|
|
30645
30670
|
}
|
|
30646
30671
|
return /* @__PURE__ */ jsx6("div", { style: { width: w, height: boxHeight, aspectRatio: ar, borderRadius: r, background: ph ?? (hasSource ? `linear-gradient(135deg, ${C("surfaceTertiary", "#e6e6e6")}, ${C("surfaceSecondary", "#f2f2f2")})` : "transparent"), color: C("textSecondary", "#999"), display: "flex", alignItems: "center", justifyContent: "center", fontFamily: "ui-monospace, monospace", fontSize: 11, flex: "none", ...wrap }, children: banner || !hasSource ? "" : "\u2022" });
|
|
30647
30672
|
});
|
|
@@ -31318,11 +31343,13 @@ var init_renderNode = __esm({
|
|
|
31318
31343
|
const effectivePositionMs = seeked ?? positionMs;
|
|
31319
31344
|
const progress = scrub ?? (durationMs > 0 ? Math.min(Math.max(effectivePositionMs / durationMs, 0), 1) : 0);
|
|
31320
31345
|
const clockMs = scrub != null || effectivePositionMs > 0 || isPlaying || isLoading ? Math.min(Math.round(progress * durationMs), durationMs) : durationMs;
|
|
31321
|
-
const
|
|
31346
|
+
const tintToken = resolveScalarStatic(props.tint, ctx);
|
|
31347
|
+
const tint = C(tintToken ?? "accentPrimary", "#116DFF");
|
|
31322
31348
|
const danger = C("danger", "#E62214");
|
|
31323
31349
|
const secondary = C("textSecondary", "#636B78");
|
|
31324
31350
|
const onAccent = C("textOnAccent", "#FFFFFF");
|
|
31325
31351
|
const accent = isFailed ? danger : tint;
|
|
31352
|
+
const accentLabel = isFailed ? danger : tintToken ? tint : accentTextColor(ctx);
|
|
31326
31353
|
const emit = (action, extra) => {
|
|
31327
31354
|
if (!ctx.onAction || !action) return;
|
|
31328
31355
|
const a = resolveItemDeep2(action, ctx);
|
|
@@ -31490,7 +31517,7 @@ var init_renderNode = __esm({
|
|
|
31490
31517
|
fontSize: 11,
|
|
31491
31518
|
fontWeight: 600,
|
|
31492
31519
|
fontFamily: "inherit",
|
|
31493
|
-
color:
|
|
31520
|
+
color: accentLabel,
|
|
31494
31521
|
background: C("surfaceSecondary", "#F5F7FA"),
|
|
31495
31522
|
borderRadius: 999,
|
|
31496
31523
|
padding: "3px 7px"
|
|
@@ -32155,7 +32182,7 @@ var init_renderNode = __esm({
|
|
|
32155
32182
|
}
|
|
32156
32183
|
)
|
|
32157
32184
|
] }),
|
|
32158
|
-
/* @__PURE__ */ jsx6("div", { style: { display: "flex", marginLeft: 44, minWidth: days.length * 90 }, children: laneMode ? laneCols.map((lane) => /* @__PURE__ */ jsx6("div", { "data-lane": lane.id, style: { flex: "1 1 0", minWidth: 0, textAlign: "center", fontFamily: bodyFont(ctx), fontSize: 12, fontWeight: 600, color: C("textSecondary", "#888"), padding: "4px 2px", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: laneTitle(lane.id) }, lane.id)) : days.map((d, i) => /* @__PURE__ */ jsx6("div", { style: { flex: "1 1 0", minWidth: 0, textAlign: "center", fontFamily: bodyFont(ctx), fontSize: 11, fontWeight: 600, color: dayKeys[i] === nowKey ?
|
|
32185
|
+
/* @__PURE__ */ jsx6("div", { style: { display: "flex", marginLeft: 44, minWidth: days.length * 90 }, children: laneMode ? laneCols.map((lane) => /* @__PURE__ */ jsx6("div", { "data-lane": lane.id, style: { flex: "1 1 0", minWidth: 0, textAlign: "center", fontFamily: bodyFont(ctx), fontSize: 12, fontWeight: 600, color: C("textSecondary", "#888"), padding: "4px 2px", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: laneTitle(lane.id) }, lane.id)) : days.map((d, i) => /* @__PURE__ */ jsx6("div", { style: { flex: "1 1 0", minWidth: 0, textAlign: "center", fontFamily: bodyFont(ctx), fontSize: 11, fontWeight: 600, color: dayKeys[i] === nowKey ? accentTextColor(ctx) : C("textSecondary", "#888") }, children: d.toLocaleDateString(void 0, { weekday: "short", day: "numeric" }) }, i)) }),
|
|
32159
32186
|
days.some((_, i) => (byDay.get(dayKeys[i])?.allDay.length ?? 0) > 0) && /* @__PURE__ */ jsx6("div", { style: { display: "flex", marginLeft: 44, gap: 2, marginBottom: 4, minWidth: days.length * 90 }, children: days.map((d, i) => /* @__PURE__ */ jsx6("div", { style: { flex: "1 1 0", minWidth: 0, display: "flex", flexDirection: "column", gap: 2, padding: "0 1px" }, children: (byDay.get(dayKeys[i])?.allDay ?? []).map((ev, j) => {
|
|
32160
32187
|
const tappable = !!(ev?.onTap || props.onSelectEvent);
|
|
32161
32188
|
return /* @__PURE__ */ jsx6(
|
|
@@ -33831,6 +33858,12 @@ var init_app_registry_client = __esm({
|
|
|
33831
33858
|
}
|
|
33832
33859
|
});
|
|
33833
33860
|
|
|
33861
|
+
// ../../core/ts/src/site-shell.ts
|
|
33862
|
+
var init_site_shell = __esm({
|
|
33863
|
+
"../../core/ts/src/site-shell.ts"() {
|
|
33864
|
+
}
|
|
33865
|
+
});
|
|
33866
|
+
|
|
33834
33867
|
// ../../core/ts/src/index.ts
|
|
33835
33868
|
var init_src5 = __esm({
|
|
33836
33869
|
"../../core/ts/src/index.ts"() {
|
|
@@ -33857,6 +33890,7 @@ var init_src5 = __esm({
|
|
|
33857
33890
|
init_app_link();
|
|
33858
33891
|
init_app_identity();
|
|
33859
33892
|
init_app_registry_client();
|
|
33893
|
+
init_site_shell();
|
|
33860
33894
|
}
|
|
33861
33895
|
});
|
|
33862
33896
|
|
|
@@ -53070,21 +53104,21 @@ var init_preview_assets_generated = __esm({
|
|
|
53070
53104
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
53071
53105
|
init_preview_assets_format();
|
|
53072
53106
|
PREVIEW_ASSET_MANIFEST = [
|
|
53073
|
-
{ key: "assets/index-
|
|
53074
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
53075
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
53076
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
53077
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
53078
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
53079
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
53080
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
53081
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
53082
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
53083
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
53084
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
53085
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
53086
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
53087
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
53107
|
+
{ key: "assets/index-DlDXdHId.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1063092, sha256: "758c655ba88cbb54101f690281513fcff56aaa8b4a31dd49545d0f30f45e05f8" },
|
|
53108
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1063100, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
53109
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1067710, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
53110
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1556294, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
53111
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1647218, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
53112
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1738202, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
53113
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1829182, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
53114
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1920054, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
53115
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 2011034, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
53116
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2119670, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
53117
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2228754, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
53118
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2337802, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
53119
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2445502, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
53120
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 2533610, length: 4947, sha256: "7a5bedfb0fdf0c376ce40bba70539332bca4b2fad4e4112465fb1875e03aa29b" },
|
|
53121
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2538557, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
|
|
53088
53122
|
];
|
|
53089
53123
|
}
|
|
53090
53124
|
});
|
|
@@ -59417,6 +59451,13 @@ async function applyOverlays(input) {
|
|
|
59417
59451
|
);
|
|
59418
59452
|
}
|
|
59419
59453
|
const appDir2 = join61(repoRoot2, shellAppDir(shell));
|
|
59454
|
+
const committedPath = join61(appDir2, "provisioning.json");
|
|
59455
|
+
const committedSite = existsSync62(committedPath) ? JSON.parse(readFileSync73(committedPath, "utf8")).site : void 0;
|
|
59456
|
+
if (committedSite !== void 0 && overlay.site === void 0) {
|
|
59457
|
+
throw new Error(
|
|
59458
|
+
`shell "${shell}" is a site shell: its contract names the customer's website (a \`site\` block), which this analysis does not produce yet. Write the site block into a contract and run \`npm run prepare:customer -- --contract <file>\` in ${shellAppDir(shell)} (or \`himi dist --shell ${shell}\`).`
|
|
59459
|
+
);
|
|
59460
|
+
}
|
|
59420
59461
|
const packageDir = dirname33(resolve45(input.overlayPath));
|
|
59421
59462
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir2, packageDir, overlay });
|
|
59422
59463
|
wrote.push(...staged);
|
|
@@ -67366,7 +67407,7 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
67366
67407
|
carries no attestation, source archive, assets, icon or
|
|
67367
67408
|
minBinaryVersion \u2014 all named in the output.
|
|
67368
67409
|
himi dist [--app <a>] [--platform ios,android] [--release <id>] [--allow-draft] [--target <t>]
|
|
67369
|
-
[--shell branded-lite|owner-lite|player|demo-app] [--signing wix-managed|byo]
|
|
67410
|
+
[--shell branded-lite|owner-lite|brandy|player|demo-app] [--signing wix-managed|byo]
|
|
67370
67411
|
[--android-signing qa-keystore|wix-keystore|debug]
|
|
67371
67412
|
[--borrow-ios-id <bundleId>] [--no-wait] [--force]
|
|
67372
67413
|
build an INSTALLABLE QA binary (signed IPA / APK) on
|
|
@@ -67378,7 +67419,7 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
67378
67419
|
the in-repo default is a local dev plane that isn't
|
|
67379
67420
|
reachable off-repo.
|
|
67380
67421
|
--shell picks the native host to sign into (branded-lite |
|
|
67381
|
-
owner-lite | player | demo-app). --signing defaults to
|
|
67422
|
+
owner-lite | brandy | player | demo-app). --signing defaults to
|
|
67382
67423
|
wix-managed: the Wix Apple account mints a per-app
|
|
67383
67424
|
identity for the build, so you provision nothing.
|
|
67384
67425
|
--signing byo (your own Apple account) is reserved and
|
|
@@ -67666,7 +67707,7 @@ var COMMANDS = [
|
|
|
67666
67707
|
{ name: "patch", summary: 'change ONE item of a published app \u2014 a screen descriptor, a Tier-5 bundle, tokens, or the app-config baseline \u2014 from a RAW FILE, with no content package and no build. The low-level door: it does not lint your package, because there is no package here; `himi push --only <selector>` is the same edit with the full build + lint gate and is what to reach for when the package is in hand. Derives a new release from the app\'s current LIVE release, or from `--from-release <id>`. An explicit `--draft` or `--live` is REQUIRED \u2014 a patch has no default blast radius \u2014 and `--notes` is required with `--live` on a screen or app-config patch, because off-repo `gitSha` is "dev" and the ledger notes are then the only durable record of bytes that correspond to no commit. A branch does not merge: activating one derived from an older release reverts every item the patch does not move, so that case is refused until `--accept-regressions`. A bundle patch must repoint a screen (`--for-screen`) or the bytes land under a manifest key nothing reads. It cannot ADD a screen (screens are git-only, RFC 0012), never claims a slug \u2014 the app must already be published \u2014 and carries no attestation, source archive, assets, icon or minBinaryVersion, each named in the output.', required: "screen <id> --file <descriptor.json> [--bundle <sha256|none>] | bundle --file <bundle.js> (--for-screen <id>[,<id>] | --no-rebind) | tokens --file <tokens.json> | app-config --file <app-config.json> ; (--draft|--live) --app <a> [--from-release <id>] [--accept-regressions] [--label <n>] [--notes <t>] [--force] [--target <t>] (--control-token)" },
|
|
67667
67708
|
{ name: "flags", summary: "read and change the app's OPERATIONAL flags (RFC 0013) \u2014 `list` prints what the DEVICE door serves, `set <key> --definition` creates or replaces one, `ramp <key>` moves its rollout share or kills it, `rm <key>` deletes it and echoes the definition back so the removal is reversible. Every write is followed by a read of the same door the device uses, and the answer is reported as `servedNow`: flags are stored in the app's git-committed flags.json, so a control plane with no checkout accepts a write it will never serve.", required: "list|set|ramp|rm [<key>] [--definition <json|@file>] [--percent 0-100] [--enabled true|false] [--app <a>] (--control-token)" },
|
|
67668
67709
|
{ name: "visibility", summary: "read (no value) or set whether the public registry (/v1/apps + the Himi Player picker) LISTS the app. `public` lists it for everyone; `unlisted` hides it from listings while direct reads by app id \u2014 deep links, previews \u2014 keep working. App from --app or the content dir. Setting it needs no republish.", required: "[public|unlisted] [--app <a>] [--content <dir>] (--control-token)" },
|
|
67669
|
-
{ name: "dist", summary: "build an INSTALLABLE QA binary (signed IPA / APK) on the Wix Job Service Mac pool and return an install link \u2014 the serve plane brokers the job, the pool builds it. WAITS for the build by default (~4 min) and prints the install link; `--no-wait` returns a jobId immediately instead. Omitting `--release` builds whatever is LIVE for the app. A named draft is refused unless `--allow-draft` makes that exceptional build explicit. `status <jobId>` / `watch <jobId>` / `list --app <a>` / `cancel <jobId>` inspect and stop builds (`watch` reports up front whether the job mints its own signing identity or borrows one, so a doomed iOS build is cancellable in seconds rather than after the archive). Off-repo, name a target \u2014 `--target wix` for a self-serve Wix login or `--target bo` for the internal employee path (the in-repo default is a local dev plane that isn't reachable off-repo); self-serve callers may build their OWN apps under a tighter budget (2 in flight / 5 per 24h), while a manage-only owner-role credential is refused. `--shell` picks the native host to sign into (branded-lite | owner-lite | player | demo-app). `--signing` defaults to `wix-managed` \u2014 the Wix Apple account mints a per-app signing identity for the build, so the caller provisions no Apple credentials of their own; `--signing byo` (sign with your own Apple account) is reserved and 501s. `--android-signing` is the Android counterpart and a SEPARATE axis (a keystore, not an Apple account): `qa-keystore` (default \u2014 the repo's committed QA key, identical on every pool machine, so a build installs over the previous one), `wix-keystore` (the Wix key the pool machine carries; the build FAILS naming the paths searched if it carries none, rather than quietly signing with something else), or `debug` (the old per-machine key \u2014 QA must uninstall any previous build first). NOT the normal way to ship: screens, Tier-5 bundles, tokens and app-config all go over the air with `himi push` in seconds \u2014 a binary trip is only needed for a NATIVE delta (a new SDUI component, a new declared capability/entitlement, a new bundle id, or a minBinaryVersion floor bump). Refuses to build an app whose launcher icon is missing, a placeholder, or one a store would reject \u2014 the one thing a binary carries that no later OTA push can fix; `--force` builds anyway", required: "[--app <a>] [--platform ios,android] [--release <id>] [--allow-draft] [--target <t>] [--shell branded-lite|owner-lite|player|demo-app] [--signing wix-managed|byo] [--android-signing qa-keystore|wix-keystore|debug] [--borrow-ios-id <bundleId>] [--no-wait] [--force] | status <jobId> [--target <t>] | watch <jobId> [--target <t>] [--interval <ms>] | list --app <a> [--target <t>] | cancel <jobId> [--target <t>]" },
|
|
67710
|
+
{ name: "dist", summary: "build an INSTALLABLE QA binary (signed IPA / APK) on the Wix Job Service Mac pool and return an install link \u2014 the serve plane brokers the job, the pool builds it. WAITS for the build by default (~4 min) and prints the install link; `--no-wait` returns a jobId immediately instead. Omitting `--release` builds whatever is LIVE for the app. A named draft is refused unless `--allow-draft` makes that exceptional build explicit. `status <jobId>` / `watch <jobId>` / `list --app <a>` / `cancel <jobId>` inspect and stop builds (`watch` reports up front whether the job mints its own signing identity or borrows one, so a doomed iOS build is cancellable in seconds rather than after the archive). Off-repo, name a target \u2014 `--target wix` for a self-serve Wix login or `--target bo` for the internal employee path (the in-repo default is a local dev plane that isn't reachable off-repo); self-serve callers may build their OWN apps under a tighter budget (2 in flight / 5 per 24h), while a manage-only owner-role credential is refused. `--shell` picks the native host to sign into (branded-lite | owner-lite | brandy | player | demo-app); `brandy` is the site shell \u2014 the customer's own website as native-framed tabs. `--signing` defaults to `wix-managed` \u2014 the Wix Apple account mints a per-app signing identity for the build, so the caller provisions no Apple credentials of their own; `--signing byo` (sign with your own Apple account) is reserved and 501s. `--android-signing` is the Android counterpart and a SEPARATE axis (a keystore, not an Apple account): `qa-keystore` (default \u2014 the repo's committed QA key, identical on every pool machine, so a build installs over the previous one), `wix-keystore` (the Wix key the pool machine carries; the build FAILS naming the paths searched if it carries none, rather than quietly signing with something else), or `debug` (the old per-machine key \u2014 QA must uninstall any previous build first). NOT the normal way to ship: screens, Tier-5 bundles, tokens and app-config all go over the air with `himi push` in seconds \u2014 a binary trip is only needed for a NATIVE delta (a new SDUI component, a new declared capability/entitlement, a new bundle id, or a minBinaryVersion floor bump). Refuses to build an app whose launcher icon is missing, a placeholder, or one a store would reject \u2014 the one thing a binary carries that no later OTA push can fix; `--force` builds anyway", required: "[--app <a>] [--platform ios,android] [--release <id>] [--allow-draft] [--target <t>] [--shell branded-lite|owner-lite|brandy|player|demo-app] [--signing wix-managed|byo] [--android-signing qa-keystore|wix-keystore|debug] [--borrow-ios-id <bundleId>] [--no-wait] [--force] | status <jobId> [--target <t>] | watch <jobId> [--target <t>] [--interval <ms>] | list --app <a> [--target <t>] | cancel <jobId> [--target <t>]" },
|
|
67670
67711
|
{ name: "testflight", summary: 'build, sign and upload an app to TestFlight (internal testers \u2014 no Beta App Review), then WAIT until App Store Connect finishes processing it. Sugar for `store upload --track testflight`. Prompts first: a build number is consumed permanently on a real Apple account and cannot be reused \u2014 `--yes` for CI, `--dry-run` to see the plan without touching anything. The wait is the real check, not a nicety: fastlane prints "Successfully uploaded" for a binary App Store Connect then rejects in processing, and a rejected binary leaves NO build record at all (the reason is emailed). Public App Store review is deliberately NOT automatable here \u2014 `--track appstore` is refused; use /submit-ios-app when you mean to go public', required: "<app> [--track testflight|internal] [--profile <name>] [--yes] [--dry-run] [--skip-build] [--no-wait] [--json]" },
|
|
67671
67712
|
{ name: "store", summary: "the App Store Connect group behind `testflight`. `preflight <app>` checks readiness offline (icon, entitlements, encryption flag, version, store.config ids, listing + review record); `upload <app>` is what `testflight` runs; `status <app>` reads live build + processing state. `--profile` selects WHICH App Store Connect account: an app built for a Wix customer ships under the CUSTOMER's Apple team (Apple guideline 4.2.6 forbids an app-generation service submitting on a client's behalf), declared per-app as ios.credentialProfile in store.config.yaml and resolved from ~/.himalaya/store-credentials/<name>.json \u2014 the .p8 itself never enters the repo", required: "preflight <app> [--profile <n>] | upload <app> [--track <t>] [--profile <n>] [--yes] [--dry-run] | status <app> [--profile <n>]" },
|
|
67672
67713
|
{ name: "guide", summary: "print the Himalaya overview + headless dev loop + available topics (offline)", required: "[--json]" },
|
|
Binary file
|
|
@@ -6,6 +6,11 @@ app that is **another client of that site** — same catalog, CMS, members, form
|
|
|
6
6
|
IA and UX rewritten for a phone. Not a WebView. Not a shrunk desktop. Not
|
|
7
7
|
`--apply` onto Branded Lite and stop.
|
|
8
8
|
|
|
9
|
+
> **Not this page: "my website, as an app, today."** That is the *site shell*
|
|
10
|
+
> (`himi dist --shell brandy`) — the customer's live site in native-framed WebView tabs. It is a separate, day-0 path that
|
|
11
|
+
> graduates to this page's native app one tab at a time; it never replaces it. Everything
|
|
12
|
+
> below is the native app.
|
|
13
|
+
|
|
9
14
|
This page is the body of `himi docs wix-site-to-himi-app`. The hosted CLI skill
|
|
10
15
|
([skill.md](https://apps.wix.com/_api/himi-serve/skill.md)) should send you here
|
|
11
16
|
when the user gave a site URL / client id. Analyze is collect+judge
|
|
@@ -248,7 +253,7 @@ state), and pass `himi test`. Then run
|
|
|
248
253
|
- Never invoke Velo HTTP functions **from analyze** (or as a substitute for rewriting Velo *pages*). To create/update/publish the site's HTTP API use `himi site function` (`himi docs wix-site-http-functions`).
|
|
249
254
|
- Never log contact PII; never paste `secrets-backend`.
|
|
250
255
|
- Never invent CMS schemas when the book’s CMS chapter is empty but the site has forms.
|
|
251
|
-
- Never pixel-clone the website; never wrap it in a WebView.
|
|
256
|
+
- Never pixel-clone the website; never wrap it in a WebView (the WebView product is the separate site shell, `--shell brandy` — not this guide's output).
|
|
252
257
|
- Never edit the Himalaya monorepo’s committed `apps/himi-branded-lite/provisioning.json`.
|
|
253
258
|
|
|
254
259
|
## See also
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1068.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": [
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"artifactId": "himalaya-cli"
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
|
-
"falconPackageHash": "
|
|
68
|
+
"falconPackageHash": "d27d980f58b63c6236045887c8cfe93d017ac0d63ffdb1bcba762d90"
|
|
69
69
|
}
|
|
@@ -3,8 +3,19 @@
|
|
|
3
3
|
// fill __HIMI_ID__ sentinels per request.
|
|
4
4
|
import config from "../config.js";
|
|
5
5
|
|
|
6
|
+
// The chat screen names your app by its display name: config.ts `name`. `himi init` fills
|
|
7
|
+
// that field AND this constant with the package slug, and "Message my-app" is not copy — so
|
|
8
|
+
// while the two are equal the screen uses neutral copy. Give the app a name and it is used.
|
|
9
|
+
const PACKAGE_SLUG = "__HIMI_APP_SLUG__";
|
|
10
|
+
const displayName = ((): string => {
|
|
11
|
+
const name = String(config.name ?? "").trim();
|
|
12
|
+
return name && name !== PACKAGE_SLUG ? name : "";
|
|
13
|
+
})();
|
|
14
|
+
|
|
6
15
|
const runtimeSetting = (value: unknown): unknown => {
|
|
7
16
|
if (value === "__HIMI_PODCAST_FEED_URL__") return process.env.PODCAST_FEED_URL?.trim() || "";
|
|
17
|
+
if (value === "__HIMI_MESSAGE_CTA__") return displayName ? `Message ${displayName}` : "Send a message";
|
|
18
|
+
if (value === "__HIMI_CHAT_TITLE__") return displayName || "Chat";
|
|
8
19
|
if (Array.isArray(value)) return value.map(runtimeSetting);
|
|
9
20
|
if (!value || typeof value !== "object") return value;
|
|
10
21
|
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, runtimeSetting(child)]));
|
|
@@ -1129,7 +1140,7 @@ const SCREENS = runtimeSetting({
|
|
|
1129
1140
|
"package": "himalaya",
|
|
1130
1141
|
"type": "Text",
|
|
1131
1142
|
"props": {
|
|
1132
|
-
"text": "
|
|
1143
|
+
"text": "__HIMI_CHAT_TITLE__",
|
|
1133
1144
|
"style": "body",
|
|
1134
1145
|
"color": "textPrimary",
|
|
1135
1146
|
"maxLines": 1
|
|
@@ -1263,7 +1274,7 @@ const SCREENS = runtimeSetting({
|
|
|
1263
1274
|
"kind": "text",
|
|
1264
1275
|
"text": {
|
|
1265
1276
|
"value": "$service:chat.input",
|
|
1266
|
-
"placeholder": "
|
|
1277
|
+
"placeholder": "__HIMI_MESSAGE_CTA__",
|
|
1267
1278
|
"onChange": {
|
|
1268
1279
|
"actionId": "tier5.chat.setInput"
|
|
1269
1280
|
},
|
|
@@ -118,8 +118,12 @@ interface ChatState {
|
|
|
118
118
|
|
|
119
119
|
// ── Content ─────────────────────────────────────────────────────────────────
|
|
120
120
|
|
|
121
|
+
// Neither string names the app. `himi init` knows only the package slug, not your app's
|
|
122
|
+
// display name, so a named greeting opened every new app on "Hi — I'm my-app." and a
|
|
123
|
+
// named system prompt had the model introduce itself that way. To have the assistant use
|
|
124
|
+
// your app's name, write it into both strings.
|
|
121
125
|
const GREETING =
|
|
122
|
-
"Hi
|
|
126
|
+
"Hi! Ask anything, send a photo, or tap the mic for a voice message. " +
|
|
123
127
|
"Cloud LLM by default; flip Private mode in Settings to stay on-device.";
|
|
124
128
|
|
|
125
129
|
const SUGGESTIONS: Chip[] = [
|
|
@@ -136,7 +140,7 @@ const SAMPLES: Sample[] = [
|
|
|
136
140
|
];
|
|
137
141
|
|
|
138
142
|
const SYSTEM_PROMPT =
|
|
139
|
-
"You are
|
|
143
|
+
"You are a helpful personal assistant. Reply clearly and concisely. " +
|
|
140
144
|
"Respond ONLY with JSON matching the schema { reply: string }.";
|
|
141
145
|
|
|
142
146
|
const REPLY_SCHEMA = {
|