@wix/himalaya-cli 0.1067.0 → 0.1069.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 +130 -63
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/wix-site-to-himi-app.md +6 -1
- package/package.json +2 -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
|
@@ -484,6 +484,36 @@ var init_ownership = __esm({
|
|
|
484
484
|
}
|
|
485
485
|
});
|
|
486
486
|
|
|
487
|
+
// ../../core/serve-storage/src/wip-pointer.ts
|
|
488
|
+
function wipSupported(store) {
|
|
489
|
+
if (!store.getWipRecord || !store.updateWipRecord) return false;
|
|
490
|
+
return store.supportsWip ? store.supportsWip() : true;
|
|
491
|
+
}
|
|
492
|
+
function normalizeWipRecord(value) {
|
|
493
|
+
if (!value || typeof value !== "object") return { wip: null, promoted: [], evictedBefore: null };
|
|
494
|
+
const v = value;
|
|
495
|
+
const wip = v.wip && typeof v.wip.releaseId === "string" ? v.wip : null;
|
|
496
|
+
const promoted = (Array.isArray(v.promoted) ? v.promoted : []).flatMap((entry) => {
|
|
497
|
+
if (typeof entry === "string") return [{ id: entry, at: null }];
|
|
498
|
+
const e = entry;
|
|
499
|
+
return e && typeof e.id === "string" ? [{ id: e.id, at: storedTime(e.at) }] : [];
|
|
500
|
+
});
|
|
501
|
+
return { wip, promoted, evictedBefore: storedTime(v.evictedBefore) };
|
|
502
|
+
}
|
|
503
|
+
async function readWip(store, app) {
|
|
504
|
+
if (!wipSupported(store)) return "unsupported";
|
|
505
|
+
const { wip, promoted } = normalizeWipRecord(await store.getWipRecord(app));
|
|
506
|
+
if (!wip || promoted.some((p) => p.id === wip.releaseId)) return null;
|
|
507
|
+
const live2 = await store.getManifest(app);
|
|
508
|
+
return live2?.releaseId === wip.releaseId ? null : wip;
|
|
509
|
+
}
|
|
510
|
+
var storedTime;
|
|
511
|
+
var init_wip_pointer = __esm({
|
|
512
|
+
"../../core/serve-storage/src/wip-pointer.ts"() {
|
|
513
|
+
storedTime = (value) => typeof value === "string" && !Number.isNaN(Date.parse(value)) ? value : null;
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
|
|
487
517
|
// ../../core/serve-storage/src/store.ts
|
|
488
518
|
function validateFunctionManifest(manifest) {
|
|
489
519
|
const dataErrors = validateDataResources(manifest.functionDataResources, manifest.app).filter((issue2) => issue2.severity === "error");
|
|
@@ -526,6 +556,14 @@ async function retainedReleaseRefs(store, app, keepRecent = 20, keepReleaseIds =
|
|
|
526
556
|
}
|
|
527
557
|
}
|
|
528
558
|
}
|
|
559
|
+
const offered = await readWip(store, app);
|
|
560
|
+
if (offered && offered !== "unsupported" && !loaded.has(offered.releaseId) && store.getManifestById) {
|
|
561
|
+
const m = await store.getManifestById(app, offered.releaseId);
|
|
562
|
+
if (m) {
|
|
563
|
+
manifests.push(m);
|
|
564
|
+
loaded.add(m.releaseId);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
529
567
|
for (const releaseId of new Set(keepReleaseIds)) {
|
|
530
568
|
if (loaded.has(releaseId)) continue;
|
|
531
569
|
if (!store.getManifestById) throw new Error(`cannot retain function job release ${releaseId}: versioned manifest lookup is unsupported`);
|
|
@@ -554,6 +592,7 @@ var TEMPLATE_APP_PREFIX;
|
|
|
554
592
|
var init_store = __esm({
|
|
555
593
|
"../../core/serve-storage/src/store.ts"() {
|
|
556
594
|
init_ownership();
|
|
595
|
+
init_wip_pointer();
|
|
557
596
|
TEMPLATE_APP_PREFIX = "himi-template-";
|
|
558
597
|
}
|
|
559
598
|
});
|
|
@@ -764,34 +803,28 @@ var init_file_store = __esm({
|
|
|
764
803
|
else ledger.push(entry);
|
|
765
804
|
writeFileSync2(this.ledgerPath(app), JSON.stringify(ledger, null, 2));
|
|
766
805
|
}
|
|
767
|
-
// ---- RFC 0061 §3.1 owner-follow `wip`
|
|
768
|
-
// Inside the app directory, so `remove` and `reset` take it with the app. `
|
|
769
|
-
// for the way this backend is deployed — ONE writer process (serve-control; serve only
|
|
770
|
-
// the read,
|
|
806
|
+
// ---- RFC 0061 §3.1 owner-follow `wip` record ----
|
|
807
|
+
// Inside the app directory, so `remove` and `reset` take it with the app. `updateWipRecord` is a
|
|
808
|
+
// CAS for the way this backend is deployed — ONE writer process (serve-control; serve only
|
|
809
|
+
// reads): the read, `fn` and write below are synchronous with no await between them, so no other
|
|
771
810
|
// request in that process can land in the middle. It is not a cross-process lock.
|
|
772
|
-
wipPath(app) {
|
|
773
|
-
return join2(this.appDir(app), "_wip.json");
|
|
774
|
-
}
|
|
775
811
|
readWipSync(app) {
|
|
776
812
|
const b = this.read(app, "_wip.json");
|
|
777
813
|
if (!b) return null;
|
|
778
814
|
try {
|
|
779
|
-
|
|
780
|
-
return wip && typeof wip.releaseId === "string" ? wip : null;
|
|
815
|
+
return JSON.parse(b.toString("utf8"));
|
|
781
816
|
} catch {
|
|
782
817
|
return null;
|
|
783
818
|
}
|
|
784
819
|
}
|
|
785
|
-
async
|
|
786
|
-
mkdirSync2(this.appDir(app), { recursive: true });
|
|
787
|
-
writeFileSync2(this.wipPath(app), JSON.stringify(wip, null, 2));
|
|
788
|
-
}
|
|
789
|
-
async getWip(app) {
|
|
820
|
+
async getWipRecord(app) {
|
|
790
821
|
return this.readWipSync(app);
|
|
791
822
|
}
|
|
792
|
-
async
|
|
793
|
-
|
|
794
|
-
|
|
823
|
+
async updateWipRecord(app, fn) {
|
|
824
|
+
const next = fn(this.readWipSync(app));
|
|
825
|
+
if (next === void 0) return false;
|
|
826
|
+
mkdirSync2(this.appDir(app), { recursive: true });
|
|
827
|
+
writeFileSync2(join2(this.appDir(app), "_wip.json"), JSON.stringify(next, null, 2));
|
|
795
828
|
return true;
|
|
796
829
|
}
|
|
797
830
|
bundleUrl(_app, sha2565) {
|
|
@@ -3870,6 +3903,14 @@ var init_dist_jobs = __esm({
|
|
|
3870
3903
|
bundleId: { ios: "ent.wix.ownerlite.dev", android: "com.wix.himi.ownerlite.dev" },
|
|
3871
3904
|
provisioningEnv: "HIMI_OWNER_LITE_PROVISIONING_JSON"
|
|
3872
3905
|
},
|
|
3906
|
+
// RFC 0062 — the site shell: the customer's own website as native-framed Tier-3 tabs.
|
|
3907
|
+
// Brandable (its package.json declares prepare:customer), so dist bakes the fetched
|
|
3908
|
+
// contract's identity, icon, brand colour and `site` block into the binary.
|
|
3909
|
+
brandy: {
|
|
3910
|
+
appDir: "apps/himi-brandy",
|
|
3911
|
+
bundleId: { ios: "ent.wix.brandy.dev", android: "com.wix.himi.brandy.dev" },
|
|
3912
|
+
provisioningEnv: "HIMI_BRANDY_PROVISIONING_JSON"
|
|
3913
|
+
},
|
|
3873
3914
|
player: {
|
|
3874
3915
|
appDir: "apps/himi-player",
|
|
3875
3916
|
bundleId: { ios: "dev.himalaya.player.dev", android: "dev.himalaya.player.dev" },
|
|
@@ -22305,7 +22346,7 @@ function bindingPlaceholder(v, ctx) {
|
|
|
22305
22346
|
if (ctx.runtimeDegraded) return null;
|
|
22306
22347
|
return /* @__PURE__ */ jsx("span", { style: { color: ctx.color("textSecondary", "#9aa2ad"), fontStyle: "italic", overflowWrap: "anywhere", wordBreak: "break-word" }, children: v.replace(/^\$/, "") });
|
|
22307
22348
|
}
|
|
22308
|
-
function mdScan(src) {
|
|
22349
|
+
function mdScan(src, linkStyle = "") {
|
|
22309
22350
|
const re = new RegExp(MD_INLINE.source, "g");
|
|
22310
22351
|
let out = "";
|
|
22311
22352
|
let last = 0;
|
|
@@ -22317,21 +22358,22 @@ function mdScan(src) {
|
|
|
22317
22358
|
} else if (label2 !== void 0) {
|
|
22318
22359
|
if (/^https?:\/\//i.test(url)) {
|
|
22319
22360
|
const href = mdEsc(url).replace(/"/g, """);
|
|
22320
|
-
out += `<a href="${href}" target="_blank" rel="noopener noreferrer">${mdScan(label2)}</a>`;
|
|
22361
|
+
out += `<a href="${href}" target="_blank" rel="noopener noreferrer"${linkStyle}>${mdScan(label2, linkStyle)}</a>`;
|
|
22321
22362
|
} else {
|
|
22322
22363
|
out += mdEsc(whole);
|
|
22323
22364
|
}
|
|
22324
22365
|
} else if (bold !== void 0) {
|
|
22325
|
-
out += `<b>${mdScan(bold)}</b>`;
|
|
22366
|
+
out += `<b>${mdScan(bold, linkStyle)}</b>`;
|
|
22326
22367
|
} else {
|
|
22327
|
-
out += `<i>${mdScan(italic)}</i>`;
|
|
22368
|
+
out += `<i>${mdScan(italic, linkStyle)}</i>`;
|
|
22328
22369
|
}
|
|
22329
22370
|
last = m.index + whole.length;
|
|
22330
22371
|
}
|
|
22331
22372
|
return out + mdEsc(src.slice(last));
|
|
22332
22373
|
}
|
|
22333
|
-
function mdInline(text5) {
|
|
22334
|
-
|
|
22374
|
+
function mdInline(text5, linkColor) {
|
|
22375
|
+
const safe = typeof linkColor === "string" && /^[#a-zA-Z0-9(),.%\s-]+$/.test(linkColor) ? linkColor : "";
|
|
22376
|
+
return { __html: mdScan(text5, safe ? ` style="color:${safe}"` : "") };
|
|
22335
22377
|
}
|
|
22336
22378
|
function sevColor(ctx, sev) {
|
|
22337
22379
|
switch (sev) {
|
|
@@ -22346,6 +22388,20 @@ function sevColor(ctx, sev) {
|
|
|
22346
22388
|
return ctx.color("accentPrimary", "#116DFF");
|
|
22347
22389
|
}
|
|
22348
22390
|
}
|
|
22391
|
+
function accentTextColor(ctx) {
|
|
22392
|
+
return ctx.color("accentText", ctx.color("accentPrimary", "#116DFF"));
|
|
22393
|
+
}
|
|
22394
|
+
function sevTextColor(ctx, sev) {
|
|
22395
|
+
switch (sev) {
|
|
22396
|
+
case "success":
|
|
22397
|
+
case "warning":
|
|
22398
|
+
case "danger":
|
|
22399
|
+
case "error":
|
|
22400
|
+
return sevColor(ctx, sev);
|
|
22401
|
+
default:
|
|
22402
|
+
return accentTextColor(ctx);
|
|
22403
|
+
}
|
|
22404
|
+
}
|
|
22349
22405
|
function iconGlyph(name) {
|
|
22350
22406
|
if (typeof name !== "string" || !name) return "\xB7";
|
|
22351
22407
|
const key2 = name.toLowerCase().replace(/[_.\s-]/g, "");
|
|
@@ -25730,7 +25786,7 @@ var init_controls = __esm({
|
|
|
25730
25786
|
"aria-selected": on3,
|
|
25731
25787
|
tabIndex: on3 ? 0 : -1,
|
|
25732
25788
|
onClick: () => select(i),
|
|
25733
|
-
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 ?
|
|
25789
|
+
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 },
|
|
25734
25790
|
children: [
|
|
25735
25791
|
asText2(t.label),
|
|
25736
25792
|
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 })
|
|
@@ -27803,9 +27859,6 @@ function actionClick(ctx, action) {
|
|
|
27803
27859
|
ctx.onAction(resolveItemDeep2(action, ctx));
|
|
27804
27860
|
};
|
|
27805
27861
|
}
|
|
27806
|
-
function accentTextColor(ctx) {
|
|
27807
|
-
return ctx.color("accentText", ctx.color("accentPrimary", "#116DFF"));
|
|
27808
|
-
}
|
|
27809
27862
|
function actionTextButton(ctx, action, label2, color, extra) {
|
|
27810
27863
|
if (action == null) return null;
|
|
27811
27864
|
const onClick = actionClick(ctx, action);
|
|
@@ -28486,7 +28539,7 @@ function renderInner(node, ctx) {
|
|
|
28486
28539
|
/* @__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 }) }),
|
|
28487
28540
|
/* @__PURE__ */ jsx6("div", { style: { fontFamily: bodyFont(ctx), fontWeight: 600, fontSize: 16, color: C("textPrimary", "#111") }, children: asBoundText(props.title, ctx) || "Empty" }),
|
|
28488
28541
|
props.subtitle && /* @__PURE__ */ jsx6("div", { style: { fontFamily: bodyFont(ctx), fontSize: 13, color: C("textSecondary", "#888"), marginTop: 3 }, children: txt(props.subtitle, ctx) }),
|
|
28489
|
-
actionTextButton(ctx, props.action, asBoundText(props.actionLabel, ctx) || "Take action",
|
|
28542
|
+
actionTextButton(ctx, props.action, asBoundText(props.actionLabel, ctx) || "Take action", accentTextColor(ctx), { margin: "12px auto 0", textAlign: "center" })
|
|
28490
28543
|
] });
|
|
28491
28544
|
// ───────────── atoms ─────────────
|
|
28492
28545
|
case "Text":
|
|
@@ -28496,7 +28549,7 @@ function renderInner(node, ctx) {
|
|
|
28496
28549
|
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) => {
|
|
28497
28550
|
const marks = Array.isArray(r.marks) ? r.marks : [];
|
|
28498
28551
|
const f = ctx.font(r.style);
|
|
28499
|
-
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);
|
|
28552
|
+
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);
|
|
28500
28553
|
}) });
|
|
28501
28554
|
}
|
|
28502
28555
|
case "Image":
|
|
@@ -28525,11 +28578,14 @@ function renderInner(node, ctx) {
|
|
|
28525
28578
|
const liveCount = typeof props.text === "string" && /^\$(?:service|flag)\b/.test(props.text);
|
|
28526
28579
|
const badgeLabel = m?.accessibilityLabel ?? m?.accessibility_label;
|
|
28527
28580
|
const badgeRole = roleDeclared ? void 0 : liveCount ? "status" : typeof badgeLabel === "string" && badgeLabel.trim() !== "" ? "img" : void 0;
|
|
28528
|
-
|
|
28581
|
+
const fg = _bt ? c : sevTextColor(ctx, props.style ?? "info");
|
|
28582
|
+
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" });
|
|
28529
28583
|
}
|
|
28530
28584
|
case "Tag": {
|
|
28531
|
-
const
|
|
28532
|
-
|
|
28585
|
+
const tagToken = boundTokenName(props.tokenPath, props.token, ctx);
|
|
28586
|
+
const c = C(tagToken ?? "accentPrimary", "#116DFF");
|
|
28587
|
+
const tagFg = tagToken ? c : accentTextColor(ctx);
|
|
28588
|
+
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" });
|
|
28533
28589
|
}
|
|
28534
28590
|
case "ProgressBar":
|
|
28535
28591
|
return /* @__PURE__ */ jsx6(ProgressBarNode, { props, ctx, wrap });
|
|
@@ -28780,7 +28836,7 @@ function renderInner(node, ctx) {
|
|
|
28780
28836
|
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: [
|
|
28781
28837
|
cfg.title && /* @__PURE__ */ jsx6("div", { style: { fontSize: 15, fontWeight: 600, color: C("textPrimary", "#111") }, children: asText2(cfg.title) }),
|
|
28782
28838
|
(cfg.subtitle ?? cfg.message) && /* @__PURE__ */ jsx6("div", { style: { fontSize: 13, marginTop: 4 }, children: asText2(cfg.subtitle ?? cfg.message) }),
|
|
28783
|
-
actionTextButton(ctx, cfg.retry ?? cfg.action, asText2(cfg.retryLabel) || asText2(cfg.actionLabel) || (cfg.retry != null ? "Retry" : "Take action"),
|
|
28839
|
+
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" })
|
|
28784
28840
|
] }) : null });
|
|
28785
28841
|
}
|
|
28786
28842
|
case "FragmentSlot":
|
|
@@ -30411,7 +30467,8 @@ var init_renderNode = __esm({
|
|
|
30411
30467
|
display: "grid",
|
|
30412
30468
|
placeItems: "center",
|
|
30413
30469
|
fontSize: 18,
|
|
30414
|
-
color:
|
|
30470
|
+
color: accentTextColor(ctx),
|
|
30471
|
+
// #3275 — a glyph on a neutral key
|
|
30415
30472
|
border: `1px solid ${C("border", "#e3e3e3")}`,
|
|
30416
30473
|
cursor: ctx.onAction && !disabled(at) ? "pointer" : "default",
|
|
30417
30474
|
opacity: disabled(at) ? 0.4 : 1,
|
|
@@ -30596,7 +30653,7 @@ var init_renderNode = __esm({
|
|
|
30596
30653
|
const resolved2 = resolveScalarStatic(props.text, ctx);
|
|
30597
30654
|
return resolved2 == null ? null : String(resolved2);
|
|
30598
30655
|
})();
|
|
30599
|
-
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);
|
|
30656
|
+
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);
|
|
30600
30657
|
const tAlign = props.textAlign === "center" ? "center" : props.textAlign === "trailing" ? "right" : props.textAlign === "justify" ? "justify" : props.textAlign === "leading" ? "left" : void 0;
|
|
30601
30658
|
const tDecor = props.decoration === "strikethrough" ? "line-through" : props.decoration === "underline" ? "underline" : void 0;
|
|
30602
30659
|
const ln = typeof props.lineSpacing === "number" ? pxToRem((f.line ?? 1.4) * f.size + props.lineSpacing) : f.line;
|
|
@@ -30642,7 +30699,7 @@ var init_renderNode = __esm({
|
|
|
30642
30699
|
}
|
|
30643
30700
|
if (props.icon != null && props.url == null && props.asset == null && imgInitials == null) {
|
|
30644
30701
|
const side2 = typeof w === "number" ? w : 40;
|
|
30645
|
-
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:
|
|
30702
|
+
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) }) });
|
|
30646
30703
|
}
|
|
30647
30704
|
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" });
|
|
30648
30705
|
});
|
|
@@ -31319,11 +31376,13 @@ var init_renderNode = __esm({
|
|
|
31319
31376
|
const effectivePositionMs = seeked ?? positionMs;
|
|
31320
31377
|
const progress = scrub ?? (durationMs > 0 ? Math.min(Math.max(effectivePositionMs / durationMs, 0), 1) : 0);
|
|
31321
31378
|
const clockMs = scrub != null || effectivePositionMs > 0 || isPlaying || isLoading ? Math.min(Math.round(progress * durationMs), durationMs) : durationMs;
|
|
31322
|
-
const
|
|
31379
|
+
const tintToken = resolveScalarStatic(props.tint, ctx);
|
|
31380
|
+
const tint = C(tintToken ?? "accentPrimary", "#116DFF");
|
|
31323
31381
|
const danger = C("danger", "#E62214");
|
|
31324
31382
|
const secondary = C("textSecondary", "#636B78");
|
|
31325
31383
|
const onAccent = C("textOnAccent", "#FFFFFF");
|
|
31326
31384
|
const accent = isFailed ? danger : tint;
|
|
31385
|
+
const accentLabel = isFailed ? danger : tintToken ? tint : accentTextColor(ctx);
|
|
31327
31386
|
const emit = (action, extra) => {
|
|
31328
31387
|
if (!ctx.onAction || !action) return;
|
|
31329
31388
|
const a = resolveItemDeep2(action, ctx);
|
|
@@ -31491,7 +31550,7 @@ var init_renderNode = __esm({
|
|
|
31491
31550
|
fontSize: 11,
|
|
31492
31551
|
fontWeight: 600,
|
|
31493
31552
|
fontFamily: "inherit",
|
|
31494
|
-
color:
|
|
31553
|
+
color: accentLabel,
|
|
31495
31554
|
background: C("surfaceSecondary", "#F5F7FA"),
|
|
31496
31555
|
borderRadius: 999,
|
|
31497
31556
|
padding: "3px 7px"
|
|
@@ -32156,7 +32215,7 @@ var init_renderNode = __esm({
|
|
|
32156
32215
|
}
|
|
32157
32216
|
)
|
|
32158
32217
|
] }),
|
|
32159
|
-
/* @__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 ?
|
|
32218
|
+
/* @__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)) }),
|
|
32160
32219
|
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) => {
|
|
32161
32220
|
const tappable = !!(ev?.onTap || props.onSelectEvent);
|
|
32162
32221
|
return /* @__PURE__ */ jsx6(
|
|
@@ -33832,6 +33891,12 @@ var init_app_registry_client = __esm({
|
|
|
33832
33891
|
}
|
|
33833
33892
|
});
|
|
33834
33893
|
|
|
33894
|
+
// ../../core/ts/src/site-shell.ts
|
|
33895
|
+
var init_site_shell = __esm({
|
|
33896
|
+
"../../core/ts/src/site-shell.ts"() {
|
|
33897
|
+
}
|
|
33898
|
+
});
|
|
33899
|
+
|
|
33835
33900
|
// ../../core/ts/src/index.ts
|
|
33836
33901
|
var init_src5 = __esm({
|
|
33837
33902
|
"../../core/ts/src/index.ts"() {
|
|
@@ -33858,6 +33923,7 @@ var init_src5 = __esm({
|
|
|
33858
33923
|
init_app_link();
|
|
33859
33924
|
init_app_identity();
|
|
33860
33925
|
init_app_registry_client();
|
|
33926
|
+
init_site_shell();
|
|
33861
33927
|
}
|
|
33862
33928
|
});
|
|
33863
33929
|
|
|
@@ -38191,12 +38257,6 @@ var init_src6 = __esm({
|
|
|
38191
38257
|
}
|
|
38192
38258
|
});
|
|
38193
38259
|
|
|
38194
|
-
// ../../core/serve-storage/src/wip-pointer.ts
|
|
38195
|
-
var init_wip_pointer = __esm({
|
|
38196
|
-
"../../core/serve-storage/src/wip-pointer.ts"() {
|
|
38197
|
-
}
|
|
38198
|
-
});
|
|
38199
|
-
|
|
38200
38260
|
// ../../core/serve-storage/src/release-patch.ts
|
|
38201
38261
|
import { createHash as createHash17 } from "node:crypto";
|
|
38202
38262
|
function sha256hex(b) {
|
|
@@ -53071,21 +53131,21 @@ var init_preview_assets_generated = __esm({
|
|
|
53071
53131
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
53072
53132
|
init_preview_assets_format();
|
|
53073
53133
|
PREVIEW_ASSET_MANIFEST = [
|
|
53074
|
-
{ key: "assets/index-
|
|
53075
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
53076
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
53077
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
53078
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
53079
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
53080
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
53081
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
53082
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
53083
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
53084
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
53085
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
53086
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
53087
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
53088
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
53134
|
+
{ key: "assets/index-DlDXdHId.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1063092, sha256: "758c655ba88cbb54101f690281513fcff56aaa8b4a31dd49545d0f30f45e05f8" },
|
|
53135
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1063100, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
53136
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1067710, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
53137
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1556294, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
53138
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1647218, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
53139
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1738202, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
53140
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1829182, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
53141
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1920054, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
53142
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 2011034, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
53143
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2119670, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
53144
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2228754, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
53145
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2337802, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
53146
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2445502, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
53147
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 2533610, length: 4947, sha256: "7a5bedfb0fdf0c376ce40bba70539332bca4b2fad4e4112465fb1875e03aa29b" },
|
|
53148
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2538557, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
|
|
53089
53149
|
];
|
|
53090
53150
|
}
|
|
53091
53151
|
});
|
|
@@ -59418,6 +59478,13 @@ async function applyOverlays(input) {
|
|
|
59418
59478
|
);
|
|
59419
59479
|
}
|
|
59420
59480
|
const appDir2 = join61(repoRoot2, shellAppDir(shell));
|
|
59481
|
+
const committedPath = join61(appDir2, "provisioning.json");
|
|
59482
|
+
const committedSite = existsSync62(committedPath) ? JSON.parse(readFileSync73(committedPath, "utf8")).site : void 0;
|
|
59483
|
+
if (committedSite !== void 0 && overlay.site === void 0) {
|
|
59484
|
+
throw new Error(
|
|
59485
|
+
`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}\`).`
|
|
59486
|
+
);
|
|
59487
|
+
}
|
|
59421
59488
|
const packageDir = dirname33(resolve45(input.overlayPath));
|
|
59422
59489
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir2, packageDir, overlay });
|
|
59423
59490
|
wrote.push(...staged);
|
|
@@ -67367,7 +67434,7 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
67367
67434
|
carries no attestation, source archive, assets, icon or
|
|
67368
67435
|
minBinaryVersion \u2014 all named in the output.
|
|
67369
67436
|
himi dist [--app <a>] [--platform ios,android] [--release <id>] [--allow-draft] [--target <t>]
|
|
67370
|
-
[--shell branded-lite|owner-lite|player|demo-app] [--signing wix-managed|byo]
|
|
67437
|
+
[--shell branded-lite|owner-lite|brandy|player|demo-app] [--signing wix-managed|byo]
|
|
67371
67438
|
[--android-signing qa-keystore|wix-keystore|debug]
|
|
67372
67439
|
[--borrow-ios-id <bundleId>] [--no-wait] [--force]
|
|
67373
67440
|
build an INSTALLABLE QA binary (signed IPA / APK) on
|
|
@@ -67379,7 +67446,7 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
67379
67446
|
the in-repo default is a local dev plane that isn't
|
|
67380
67447
|
reachable off-repo.
|
|
67381
67448
|
--shell picks the native host to sign into (branded-lite |
|
|
67382
|
-
owner-lite | player | demo-app). --signing defaults to
|
|
67449
|
+
owner-lite | brandy | player | demo-app). --signing defaults to
|
|
67383
67450
|
wix-managed: the Wix Apple account mints a per-app
|
|
67384
67451
|
identity for the build, so you provision nothing.
|
|
67385
67452
|
--signing byo (your own Apple account) is reserved and
|
|
@@ -67667,7 +67734,7 @@ var COMMANDS = [
|
|
|
67667
67734
|
{ 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)" },
|
|
67668
67735
|
{ 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)" },
|
|
67669
67736
|
{ 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)" },
|
|
67670
|
-
{ 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>]" },
|
|
67737
|
+
{ 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>]" },
|
|
67671
67738
|
{ 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]" },
|
|
67672
67739
|
{ 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>]" },
|
|
67673
67740
|
{ 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.1069.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": "d66a8a95769c3eb84b52d4da2233db6689f1f833a2b254304aff2bc0"
|
|
69
69
|
}
|