@wix/himalaya-cli 0.1021.0 → 0.1023.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/schema.d.ts +53 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/validator.d.ts +52 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +16 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/sdui.mjs +16 -0
- package/dist/cli.mjs +366 -170
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/component-reference.json +5 -5
- package/guides/component-reference.md +35 -0
- package/guides/designing-himi-screens.md +7 -3
- package/guides/headless-loop.md +8 -1
- package/guides/release-notes.md +40 -0
- package/guides/testing-himi-apps.md +9 -12
- package/guides/wix-api-usage.md +4 -2
- package/guides/wix-login-integration.md +2 -1
- package/guides/wix-sdk-overview.md +6 -1
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -6004,6 +6004,22 @@ var init_validator = __esm({
|
|
|
6004
6004
|
enum: ["selected", "disabled", "updates_frequently", "plays_sound", "starts_media"]
|
|
6005
6005
|
}
|
|
6006
6006
|
},
|
|
6007
|
+
// RFC 0058 §4 — focus and announcement (core.proto Modifiers 70–73). `modifiers`
|
|
6008
|
+
// is `additionalProperties: false`, so a descriptor carrying one of these would be
|
|
6009
|
+
// REJECTED on every arm at once until the validator knows it — which makes this
|
|
6010
|
+
// part of the vocabulary rather than a downstream consumer of it.
|
|
6011
|
+
focusOrder: { type: "integer" },
|
|
6012
|
+
focusGroup: { type: "boolean" },
|
|
6013
|
+
initialFocus: { type: "boolean" },
|
|
6014
|
+
announce: {
|
|
6015
|
+
type: "object",
|
|
6016
|
+
additionalProperties: false,
|
|
6017
|
+
properties: {
|
|
6018
|
+
politeness: { type: "string", enum: ["polite", "assertive"] },
|
|
6019
|
+
text: { type: "string" },
|
|
6020
|
+
trigger: { type: "string", enum: ["on_change", "on_appear", "both", "none"] }
|
|
6021
|
+
}
|
|
6022
|
+
},
|
|
6007
6023
|
// #1052 — explicit drop shadow (colour token + radius + offset), alongside the `shadow` token form.
|
|
6008
6024
|
boxShadow: {
|
|
6009
6025
|
type: "object",
|
|
@@ -8851,6 +8867,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
8851
8867
|
scrollToDatePath: "string",
|
|
8852
8868
|
stickyHeaders: "boolean"
|
|
8853
8869
|
},
|
|
8870
|
+
// RFC 0058 §4 — `modal` is the focus-trap tri-state on each of the four overlays.
|
|
8854
8871
|
AlertDialog: {
|
|
8855
8872
|
cancelAction: "any",
|
|
8856
8873
|
cancelLabel: "string",
|
|
@@ -8858,6 +8875,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
8858
8875
|
confirmLabel: "string",
|
|
8859
8876
|
destructive: "boolean",
|
|
8860
8877
|
message: "string",
|
|
8878
|
+
modal: "boolean",
|
|
8861
8879
|
title: "string"
|
|
8862
8880
|
},
|
|
8863
8881
|
Avatar: { imageUrl: "string", initials: "string", size: "number" },
|
|
@@ -8887,6 +8905,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
8887
8905
|
detents: "array",
|
|
8888
8906
|
dismissible: "boolean",
|
|
8889
8907
|
edge: "string",
|
|
8908
|
+
modal: "boolean",
|
|
8890
8909
|
onDismiss: "any",
|
|
8891
8910
|
presented: "boolean",
|
|
8892
8911
|
presentedPath: "string",
|
|
@@ -9170,7 +9189,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
9170
9189
|
startIndex: "number",
|
|
9171
9190
|
startPositionSeconds: "number"
|
|
9172
9191
|
},
|
|
9173
|
-
Menu: { anchor: "any", items: "array", itemsPath: "string", style: "string" },
|
|
9192
|
+
Menu: { anchor: "any", items: "array", itemsPath: "string", modal: "boolean", style: "string" },
|
|
9174
9193
|
MonthCalendar: {
|
|
9175
9194
|
decorations: "array",
|
|
9176
9195
|
decorationsPath: "string",
|
|
@@ -9223,6 +9242,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
9223
9242
|
anchor: "any",
|
|
9224
9243
|
content: "any",
|
|
9225
9244
|
edge: "string",
|
|
9245
|
+
modal: "boolean",
|
|
9226
9246
|
onDismiss: "any",
|
|
9227
9247
|
presented: "boolean",
|
|
9228
9248
|
presentedPath: "string"
|
|
@@ -9653,6 +9673,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
9653
9673
|
"blur",
|
|
9654
9674
|
"cornerRadius",
|
|
9655
9675
|
"enterDelayMs",
|
|
9676
|
+
"focusOrder",
|
|
9656
9677
|
"headingLevel",
|
|
9657
9678
|
"height",
|
|
9658
9679
|
"maxWidth",
|
|
@@ -15863,7 +15884,7 @@ var init_contained_dev_module = __esm({
|
|
|
15863
15884
|
|
|
15864
15885
|
// ../../core/dev-server/src/loader.ts
|
|
15865
15886
|
import { resolve as resolve21, basename as basename8, dirname as dirname17 } from "node:path";
|
|
15866
|
-
import { existsSync as existsSync29, readdirSync as readdirSync16, readFileSync as readFileSync28, mkdirSync as mkdirSync13 } from "node:fs";
|
|
15887
|
+
import { existsSync as existsSync29, readdirSync as readdirSync16, readFileSync as readFileSync28, mkdirSync as mkdirSync13, rmSync as rmSync5 } from "node:fs";
|
|
15867
15888
|
import { pathToFileURL as pathToFileURL5, fileURLToPath as fileURLToPath12 } from "node:url";
|
|
15868
15889
|
function resolveWixWebAuthConfig(app) {
|
|
15869
15890
|
const auth = app?.meta.auth;
|
|
@@ -15898,12 +15919,13 @@ function resolveDevEntry(name) {
|
|
|
15898
15919
|
}
|
|
15899
15920
|
return null;
|
|
15900
15921
|
}
|
|
15901
|
-
async function devModuleUrl(entry, dir) {
|
|
15922
|
+
async function devModuleUrl(entry, dir, fresh = false) {
|
|
15902
15923
|
const hasTypeScriptLoader = process.execArgv.some((arg) => arg.includes("tsx"));
|
|
15903
|
-
|
|
15904
|
-
|
|
15924
|
+
const direct = !isOffRepo() && hasTypeScriptLoader;
|
|
15925
|
+
if (direct && !fresh) return { url: pathToFileURL5(entry).href };
|
|
15926
|
+
const out = resolve21(dir, fresh ? `dist/.himi/dev-${process.pid}-${++freshLoads}.mjs` : "dist/.himi/dev.mjs");
|
|
15905
15927
|
mkdirSync13(dirname17(out), { recursive: true });
|
|
15906
|
-
await buildAppEntry(entry, out, {
|
|
15928
|
+
await buildAppEntry(entry, out, direct ? { confineTo: dir } : {
|
|
15907
15929
|
// Plain Node must resolve the published-style umbrella entry points for
|
|
15908
15930
|
// both standalone and in-repo CLI content. In-repo workspace packages
|
|
15909
15931
|
// intentionally point at `.ts` sources, which are only loadable under tsx.
|
|
@@ -15912,15 +15934,23 @@ async function devModuleUrl(entry, dir) {
|
|
|
15912
15934
|
absWorkingDir: dir,
|
|
15913
15935
|
confineTo: dir
|
|
15914
15936
|
});
|
|
15915
|
-
return pathToFileURL5(out).href;
|
|
15937
|
+
return { url: pathToFileURL5(out).href, ...fresh ? { transient: out } : {} };
|
|
15916
15938
|
}
|
|
15917
|
-
async function importDevModule(name, entry, dir) {
|
|
15918
|
-
const module = devModuleRealm() === "contained" ? await loadContainedDevModule(name, entry, dir) :
|
|
15939
|
+
async function importDevModule(name, entry, dir, fresh = false) {
|
|
15940
|
+
const module = devModuleRealm() === "contained" ? await loadContainedDevModule(name, entry, dir) : await importHostDevModule(entry, dir, fresh);
|
|
15919
15941
|
if (!module || !module.config) {
|
|
15920
15942
|
throw new Error(`${entry} must default-export an AppDevModule (got ${typeof module}).`);
|
|
15921
15943
|
}
|
|
15922
15944
|
return { name, module, meta: deriveAppMeta(name, module, readPlatformsJson(dir)), dir };
|
|
15923
15945
|
}
|
|
15946
|
+
async function importHostDevModule(entry, dir, fresh) {
|
|
15947
|
+
const { url, transient } = await devModuleUrl(entry, dir, fresh);
|
|
15948
|
+
try {
|
|
15949
|
+
return (await import(url)).default;
|
|
15950
|
+
} finally {
|
|
15951
|
+
if (transient) rmSync5(transient, { force: true });
|
|
15952
|
+
}
|
|
15953
|
+
}
|
|
15924
15954
|
function readPlatformsJson(dir) {
|
|
15925
15955
|
try {
|
|
15926
15956
|
const raw = JSON.parse(readFileSync28(resolve21(dir, "platforms.json"), "utf8"));
|
|
@@ -15931,7 +15961,7 @@ function readPlatformsJson(dir) {
|
|
|
15931
15961
|
return {};
|
|
15932
15962
|
}
|
|
15933
15963
|
}
|
|
15934
|
-
async function loadContent(dir) {
|
|
15964
|
+
async function loadContent(dir, opts = {}) {
|
|
15935
15965
|
const absDir = resolve21(dir);
|
|
15936
15966
|
const entry = resolve21(absDir, "dev/index.ts");
|
|
15937
15967
|
if (!existsSync29(entry)) {
|
|
@@ -15948,7 +15978,7 @@ async function loadContent(dir) {
|
|
|
15948
15978
|
}
|
|
15949
15979
|
if (typeof manifest.name === "string" && manifest.name) name = manifest.name;
|
|
15950
15980
|
}
|
|
15951
|
-
return importDevModule(name, entry, absDir);
|
|
15981
|
+
return importDevModule(name, entry, absDir, opts.fresh === true);
|
|
15952
15982
|
}
|
|
15953
15983
|
async function tryLoadApp(name) {
|
|
15954
15984
|
const found = resolveDevEntry(name);
|
|
@@ -15980,7 +16010,7 @@ function listAvailableApps() {
|
|
|
15980
16010
|
}
|
|
15981
16011
|
return out;
|
|
15982
16012
|
}
|
|
15983
|
-
var ROOT2, APP_ROOTS2, VALID_PLATFORM_KEYS2;
|
|
16013
|
+
var ROOT2, APP_ROOTS2, freshLoads, VALID_PLATFORM_KEYS2;
|
|
15984
16014
|
var init_loader = __esm({
|
|
15985
16015
|
"../../core/dev-server/src/loader.ts"() {
|
|
15986
16016
|
init_app_module();
|
|
@@ -15989,6 +16019,7 @@ var init_loader = __esm({
|
|
|
15989
16019
|
init_build_lib();
|
|
15990
16020
|
ROOT2 = resolve21(fileURLToPath12(new URL("../../..", import.meta.url)));
|
|
15991
16021
|
APP_ROOTS2 = ["apps", "test-apps"];
|
|
16022
|
+
freshLoads = 0;
|
|
15992
16023
|
VALID_PLATFORM_KEYS2 = /* @__PURE__ */ new Set([
|
|
15993
16024
|
...PREVIEW_SURFACES.map((s) => s.platformKey).filter((k) => k !== null),
|
|
15994
16025
|
...PREVIEW_EXEMPT_PLATFORM_KEYS
|
|
@@ -17293,6 +17324,21 @@ function absoluteUrlRejection(path2) {
|
|
|
17293
17324
|
}
|
|
17294
17325
|
return OWNER_SCOPED_WIX_HOST.test(host) ? "owner-only" : "open-proxy";
|
|
17295
17326
|
}
|
|
17327
|
+
async function mintAnonymousVisitor(clientId, fetchImpl = fetch) {
|
|
17328
|
+
const res = await fetchImpl(`${WIX_API}/oauth2/token`, {
|
|
17329
|
+
method: "POST",
|
|
17330
|
+
headers: { "Content-Type": "application/json" },
|
|
17331
|
+
body: JSON.stringify({ clientId, grantType: "anonymous" })
|
|
17332
|
+
});
|
|
17333
|
+
const text5 = await res.text();
|
|
17334
|
+
let j = {};
|
|
17335
|
+
try {
|
|
17336
|
+
j = text5 ? JSON.parse(text5) : {};
|
|
17337
|
+
} catch {
|
|
17338
|
+
}
|
|
17339
|
+
if (res.status !== 200 || !j.access_token) throw new Error(`visitor mint failed (${res.status})`);
|
|
17340
|
+
return j.access_token;
|
|
17341
|
+
}
|
|
17296
17342
|
async function wixVisitorCall(method, path2, body, token, fetchImpl = fetch, forwardedHeaders = {}) {
|
|
17297
17343
|
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(path2)) throw new Error("absolute URLs are not allowed");
|
|
17298
17344
|
const url = `${WIX_API}${path2.startsWith("/") ? path2 : `/${path2}`}`;
|
|
@@ -17369,43 +17415,13 @@ function wixClientIdOf(appConfigJson) {
|
|
|
17369
17415
|
if (typeof clientId !== "string" || !clientId) return { error: "no_client_id" };
|
|
17370
17416
|
return { clientId };
|
|
17371
17417
|
}
|
|
17372
|
-
var WIX_API, ONE_APP_SESSION, OWNER_SCOPED_WIX_HOST,
|
|
17418
|
+
var WIX_API, ONE_APP_SESSION, OWNER_SCOPED_WIX_HOST, WIX_FORWARDABLE_HEADERS, OWNER_REFRESH_MARGIN_MS, OWNER_RENEW_MIN_AGE_MS, OWNER_MINT_TIMEOUT_MS, OwnerInstanceCache, OWNER_SITES_QUERY_PATH, OWNER_SITES_COUNT_PATH, OwnerSitesCache;
|
|
17373
17419
|
var init_wix_bridge = __esm({
|
|
17374
17420
|
"../../core/serve-runtime/src/wix-bridge.ts"() {
|
|
17375
17421
|
init_sha256();
|
|
17376
17422
|
WIX_API = "https://www.wixapis.com";
|
|
17377
17423
|
ONE_APP_SESSION = "https://apps.wix.com/_api/one-app-session-web/v3/businesses";
|
|
17378
17424
|
OWNER_SCOPED_WIX_HOST = /(^|\.)wix\.com$/i;
|
|
17379
|
-
VisitorTokenCache = class {
|
|
17380
|
-
constructor(fetchImpl = fetch) {
|
|
17381
|
-
this.fetchImpl = fetchImpl;
|
|
17382
|
-
}
|
|
17383
|
-
cache = /* @__PURE__ */ new Map();
|
|
17384
|
-
async token(clientId, now = Date.now()) {
|
|
17385
|
-
const hit = this.cache.get(clientId);
|
|
17386
|
-
if (hit && hit.expiresAt > now) return hit.token;
|
|
17387
|
-
const res = await this.fetchImpl(`${WIX_API}/oauth2/token`, {
|
|
17388
|
-
method: "POST",
|
|
17389
|
-
headers: { "Content-Type": "application/json" },
|
|
17390
|
-
body: JSON.stringify({ clientId, grantType: "anonymous" })
|
|
17391
|
-
});
|
|
17392
|
-
const text5 = await res.text();
|
|
17393
|
-
let j = {};
|
|
17394
|
-
try {
|
|
17395
|
-
j = text5 ? JSON.parse(text5) : {};
|
|
17396
|
-
} catch {
|
|
17397
|
-
}
|
|
17398
|
-
if (res.status !== 200 || !j.access_token)
|
|
17399
|
-
throw new Error(`visitor mint failed (${res.status})`);
|
|
17400
|
-
const ttlMs = Math.max(60, (j.expires_in ?? 4 * 3600) - 60) * 1e3;
|
|
17401
|
-
this.cache.set(clientId, { token: j.access_token, expiresAt: now + ttlMs });
|
|
17402
|
-
return j.access_token;
|
|
17403
|
-
}
|
|
17404
|
-
/** Drop a cached token (e.g. after a 401 from wixapis) so the next call re-mints. */
|
|
17405
|
-
invalidate(clientId) {
|
|
17406
|
-
this.cache.delete(clientId);
|
|
17407
|
-
}
|
|
17408
|
-
};
|
|
17409
17425
|
WIX_FORWARDABLE_HEADERS = /* @__PURE__ */ new Set([
|
|
17410
17426
|
"x-wix-language",
|
|
17411
17427
|
"x-wix-linguist",
|
|
@@ -24134,6 +24150,9 @@ function autoGrowBox(contentHeight, lineHeight, verticalPadding, maxLines) {
|
|
|
24134
24150
|
const cap = Math.max(floor, lineHeight * lines + verticalPadding);
|
|
24135
24151
|
return { height: Math.max(floor, Math.min(contentHeight, cap)), scrolls: contentHeight > cap };
|
|
24136
24152
|
}
|
|
24153
|
+
function wrapModalMenu(modal, label2, placement, menu) {
|
|
24154
|
+
return modal ? /* @__PURE__ */ jsx6("div", { role: "dialog", "aria-modal": "true", "aria-label": label2, style: placement, children: menu }) : menu;
|
|
24155
|
+
}
|
|
24137
24156
|
function bindMediaSlot(value, sessionId) {
|
|
24138
24157
|
if (typeof value === "string") {
|
|
24139
24158
|
const prefix = `$media:${sessionId}.`;
|
|
@@ -24261,11 +24280,13 @@ function withExtras(name, render) {
|
|
|
24261
24280
|
}
|
|
24262
24281
|
const roleIsSynthetic = next[SYNTHETIC_TAP_ROLE] === true;
|
|
24263
24282
|
delete next[SYNTHETIC_TAP_ROLE];
|
|
24283
|
+
const tabIndexIsSynthetic = next[SYNTHETIC_TABINDEX] === true;
|
|
24284
|
+
delete next[SYNTHETIC_TABINDEX];
|
|
24264
24285
|
if (additive) next.style = additive;
|
|
24265
24286
|
const ownsInteractiveSemantics = isNativeInteractiveElement(el) || hasInteractiveReactDescendant(el);
|
|
24266
24287
|
if (ownsInteractiveSemantics) {
|
|
24267
24288
|
if (roleIsSynthetic) delete next.role;
|
|
24268
|
-
delete next.tabIndex;
|
|
24289
|
+
if (tabIndexIsSynthetic) delete next.tabIndex;
|
|
24269
24290
|
delete next.onKeyDown;
|
|
24270
24291
|
}
|
|
24271
24292
|
if (pass.style) next.style = { ...additive ?? prev.style ?? {}, ...pass.style };
|
|
@@ -24701,6 +24722,57 @@ function calKeyActivate(enabled, activate) {
|
|
|
24701
24722
|
activate();
|
|
24702
24723
|
};
|
|
24703
24724
|
}
|
|
24725
|
+
function restoreFocusOnDismiss(scope, opener) {
|
|
24726
|
+
const Observer = document.defaultView?.MutationObserver;
|
|
24727
|
+
if (!Observer) return;
|
|
24728
|
+
presentedOpeners.set(scope, opener);
|
|
24729
|
+
if (presentedObserver) return;
|
|
24730
|
+
presentedObserver = new Observer(() => {
|
|
24731
|
+
for (const [s, o] of presentedOpeners) {
|
|
24732
|
+
if (s.isConnected) continue;
|
|
24733
|
+
presentedOpeners.delete(s);
|
|
24734
|
+
const active = document.activeElement;
|
|
24735
|
+
if ((active == null || active === document.body) && o.isConnected && typeof o.focus === "function") o.focus();
|
|
24736
|
+
}
|
|
24737
|
+
if (presentedOpeners.size === 0) {
|
|
24738
|
+
presentedObserver?.disconnect();
|
|
24739
|
+
presentedObserver = null;
|
|
24740
|
+
}
|
|
24741
|
+
});
|
|
24742
|
+
presentedObserver.observe(document.body, { childList: true, subtree: true });
|
|
24743
|
+
}
|
|
24744
|
+
function ensureInitialFocusRuntime() {
|
|
24745
|
+
if (initialFocusScheduled || typeof document === "undefined") return;
|
|
24746
|
+
initialFocusScheduled = true;
|
|
24747
|
+
setTimeout(() => {
|
|
24748
|
+
initialFocusScheduled = false;
|
|
24749
|
+
const targets = Array.from(document.querySelectorAll("[data-himalaya-initial-focus]"));
|
|
24750
|
+
const active = document.activeElement;
|
|
24751
|
+
const unplaced = active == null || active === document.body;
|
|
24752
|
+
const fresh = targets.filter((t) => !initialFocusSeen.has(t));
|
|
24753
|
+
let presented;
|
|
24754
|
+
let presentedScope = null;
|
|
24755
|
+
for (const t of fresh) {
|
|
24756
|
+
const scope = t.closest(PRESENTED_SCOPE);
|
|
24757
|
+
if (scope && !(active && scope.contains(active))) {
|
|
24758
|
+
presented = t;
|
|
24759
|
+
presentedScope = scope;
|
|
24760
|
+
}
|
|
24761
|
+
}
|
|
24762
|
+
for (const t of fresh) initialFocusSeen.add(t);
|
|
24763
|
+
const el = presented ?? (unplaced ? fresh[0] : void 0);
|
|
24764
|
+
if (el && typeof el.focus === "function") {
|
|
24765
|
+
if (presented && presentedScope && !unplaced && active instanceof HTMLElement) {
|
|
24766
|
+
restoreFocusOnDismiss(presentedScope, active);
|
|
24767
|
+
}
|
|
24768
|
+
el.focus();
|
|
24769
|
+
}
|
|
24770
|
+
}, 0);
|
|
24771
|
+
}
|
|
24772
|
+
function ariaModal(modal, dflt) {
|
|
24773
|
+
const on3 = modal === true || modal === false ? modal : dflt;
|
|
24774
|
+
return on3 ? "true" : void 0;
|
|
24775
|
+
}
|
|
24704
24776
|
function applyA11ySemantics(node, ctx, extra) {
|
|
24705
24777
|
const m = node?.modifiers;
|
|
24706
24778
|
if (!m) return void 0;
|
|
@@ -24756,6 +24828,32 @@ function applyA11ySemantics(node, ctx, extra) {
|
|
|
24756
24828
|
}
|
|
24757
24829
|
}
|
|
24758
24830
|
}
|
|
24831
|
+
const focusOrder = m.focusOrder ?? m.focus_order;
|
|
24832
|
+
if (typeof focusOrder === "number" && Number.isFinite(focusOrder)) {
|
|
24833
|
+
extra.tabIndex = Math.max(1, Math.trunc(focusOrder) + 1);
|
|
24834
|
+
}
|
|
24835
|
+
if ((m.focusGroup ?? m.focus_group) === true && extra.role == null) extra.role = "group";
|
|
24836
|
+
if ((m.initialFocus ?? m.initial_focus) === true) {
|
|
24837
|
+
extra["data-himalaya-initial-focus"] = "1";
|
|
24838
|
+
if (extra.tabIndex == null) {
|
|
24839
|
+
extra.tabIndex = -1;
|
|
24840
|
+
extra[SYNTHETIC_TABINDEX] = true;
|
|
24841
|
+
}
|
|
24842
|
+
ensureInitialFocusRuntime();
|
|
24843
|
+
}
|
|
24844
|
+
const announce = m.announce;
|
|
24845
|
+
if (announce && typeof announce === "object" && !Array.isArray(announce)) {
|
|
24846
|
+
const trigger = str7(announce.trigger) ?? "on_change";
|
|
24847
|
+
if (trigger === "none") {
|
|
24848
|
+
extra["aria-live"] = "off";
|
|
24849
|
+
} else {
|
|
24850
|
+
extra["aria-live"] = str7(announce.politeness) === "assertive" ? "assertive" : "polite";
|
|
24851
|
+
extra["aria-atomic"] = "true";
|
|
24852
|
+
extra["aria-relevant"] = trigger === "on_appear" ? "additions" : trigger === "both" ? "additions text" : "text";
|
|
24853
|
+
const text5 = str7(announce.text);
|
|
24854
|
+
if (text5 && extra["aria-label"] == null) extra["aria-label"] = text5;
|
|
24855
|
+
}
|
|
24856
|
+
}
|
|
24759
24857
|
return hint;
|
|
24760
24858
|
}
|
|
24761
24859
|
function renderNodeInner(node, ctx) {
|
|
@@ -24848,7 +24946,10 @@ function renderNodeInner(node, ctx) {
|
|
|
24848
24946
|
extra.role = "button";
|
|
24849
24947
|
if (typeof el.type !== "string") extra[SYNTHETIC_TAP_ROLE] = true;
|
|
24850
24948
|
}
|
|
24851
|
-
extra.tabIndex
|
|
24949
|
+
if (extra.tabIndex == null) {
|
|
24950
|
+
extra.tabIndex = 0;
|
|
24951
|
+
if (typeof el.type !== "string") extra[SYNTHETIC_TABINDEX] = true;
|
|
24952
|
+
}
|
|
24852
24953
|
const prevOnKeyDown = el.props.onKeyDown;
|
|
24853
24954
|
extra.onKeyDown = (e) => {
|
|
24854
24955
|
prevOnKeyDown?.(e);
|
|
@@ -24896,6 +24997,7 @@ function renderNodeInner(node, ctx) {
|
|
|
24896
24997
|
if (composed) extra.style = composed;
|
|
24897
24998
|
}
|
|
24898
24999
|
}
|
|
25000
|
+
if (typeof el.type === "string") delete extra[SYNTHETIC_TABINDEX];
|
|
24899
25001
|
let out = Object.keys(extra).length ? React5.cloneElement(el, extra) : el;
|
|
24900
25002
|
if (a11yHint) {
|
|
24901
25003
|
out = /* @__PURE__ */ jsx6(A11yHintDescription, { hint: a11yHint, idBase: componentId, children: out });
|
|
@@ -25325,7 +25427,7 @@ function renderInner(node, ctx) {
|
|
|
25325
25427
|
case "Popover": {
|
|
25326
25428
|
return /* @__PURE__ */ jsxs3("div", { style: { display: "inline-flex", flexDirection: "column", alignItems: "flex-start", gap: 6, ...wrap }, children: [
|
|
25327
25429
|
props.anchor ? renderNode(props.anchor, ctx) : null,
|
|
25328
|
-
/* @__PURE__ */ jsx6("div", { role: "dialog", "aria-label": props.title != null ? asBoundText(props.title, ctx) : "Popover", style: { minWidth: 160, maxWidth: 280, background: C("surfacePrimary", "#fff"), border: `1px solid ${C("border", "#e3e3e3")}`, borderRadius: 12, boxShadow: "0 6px 20px rgba(0,0,0,.14)", padding: 12 }, children: props.content ? renderNode(props.content, ctx) : null })
|
|
25430
|
+
/* @__PURE__ */ jsx6("div", { role: "dialog", "aria-modal": ariaModal(props.modal, false), "aria-label": props.title != null ? asBoundText(props.title, ctx) : "Popover", style: { minWidth: 160, maxWidth: 280, background: C("surfacePrimary", "#fff"), border: `1px solid ${C("border", "#e3e3e3")}`, borderRadius: 12, boxShadow: "0 6px 20px rgba(0,0,0,.14)", padding: 12 }, children: props.content ? renderNode(props.content, ctx) : null })
|
|
25329
25431
|
] });
|
|
25330
25432
|
}
|
|
25331
25433
|
// ───────────── chips & selection (RFC 0030) ─────────────
|
|
@@ -25593,7 +25695,7 @@ function renderInner(node, ctx) {
|
|
|
25593
25695
|
] });
|
|
25594
25696
|
}
|
|
25595
25697
|
case "AlertDialog":
|
|
25596
|
-
return /* @__PURE__ */ jsxs3("div", { role: "alertdialog", "aria-modal":
|
|
25698
|
+
return /* @__PURE__ */ jsxs3("div", { role: "alertdialog", "aria-modal": ariaModal(props.modal, true), "aria-label": props.title != null ? asBoundText(props.title, ctx) : "Alert", style: { background: C("surfacePrimary", "#fff"), borderRadius: ctx.radius("lg", 14), padding: 18, width: "100%", boxSizing: "border-box", border: `1px solid ${C("border", "#e3e3e3")}`, boxShadow: "0 12px 30px -12px rgba(0,0,0,.4)", ...wrap }, children: [
|
|
25597
25699
|
/* @__PURE__ */ jsx6("div", { style: { fontFamily: bodyFont(ctx), fontWeight: 700, fontSize: 17, color: C("textPrimary", "#111") }, children: txt(props.title, ctx) }),
|
|
25598
25700
|
/* @__PURE__ */ jsx6("div", { style: { fontFamily: bodyFont(ctx), fontSize: 14, lineHeight: 1.45, color: C("textSecondary", "#666"), margin: "6px 0 16px" }, children: txt(props.message, ctx) }),
|
|
25599
25701
|
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: 10 }, children: [
|
|
@@ -25616,7 +25718,7 @@ function renderInner(node, ctx) {
|
|
|
25616
25718
|
}
|
|
25617
25719
|
}
|
|
25618
25720
|
}
|
|
25619
|
-
var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids, rowKids, staggeredKids, asTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, WorkerSubtreeNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, SYNTHETIC_TAP_ROLE, INFERRED_DECORATIVE, ICON_GLYPH, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ActivityIndicatorNode, BottomSheetNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RATING_METRICS, ratingMetrics, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, ARIA_ROLE, A11yHintDescription, WebRenderer;
|
|
25721
|
+
var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids, rowKids, staggeredKids, asTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, WorkerSubtreeNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, SYNTHETIC_TAP_ROLE, SYNTHETIC_TABINDEX, INFERRED_DECORATIVE, ICON_GLYPH, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ActivityIndicatorNode, BottomSheetNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RATING_METRICS, ratingMetrics, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, ARIA_ROLE, initialFocusScheduled, initialFocusSeen, PRESENTED_SCOPE, presentedOpeners, presentedObserver, A11yHintDescription, WebRenderer;
|
|
25620
25722
|
var init_renderNode = __esm({
|
|
25621
25723
|
"../../core/web-renderer/src/renderNode.tsx"() {
|
|
25622
25724
|
"use strict";
|
|
@@ -25981,7 +26083,9 @@ var init_renderNode = __esm({
|
|
|
25981
26083
|
AUTOCAPITALIZE_VALUES = /* @__PURE__ */ new Set(["none", "words", "sentences", "characters"]);
|
|
25982
26084
|
ENTER_KEY_HINTS = /* @__PURE__ */ new Set(["done", "go", "next", "send", "search"]);
|
|
25983
26085
|
AUTOGROW_CEILING = 12;
|
|
25984
|
-
EditableField = ({ props, ctx, wrap, multiline, id: htmlId, "data-component-id": componentId, "data-component-type": componentType }) => {
|
|
26086
|
+
EditableField = ({ props, ctx, wrap, multiline, id: htmlId, "data-component-id": componentId, "data-component-type": componentType, tabIndex: tabIndexProp, "data-hm-synthetic-tabindex": tabIndexIsSynthetic, "data-himalaya-initial-focus": initialFocusMarker, "aria-live": ariaLive, "aria-atomic": ariaAtomic, "aria-relevant": ariaRelevant, "aria-label": ariaLabelProp }) => {
|
|
26087
|
+
const tabIndex = tabIndexIsSynthetic === true ? void 0 : tabIndexProp;
|
|
26088
|
+
const a11yFwd = { tabIndex, "data-himalaya-initial-focus": initialFocusMarker, "aria-live": ariaLive, "aria-atomic": ariaAtomic, "aria-relevant": ariaRelevant };
|
|
25985
26089
|
const C = ctx.color;
|
|
25986
26090
|
const ctrl = props.text ?? props.value;
|
|
25987
26091
|
const cfg = ctrl && typeof ctrl === "object" ? ctrl : {};
|
|
@@ -26126,7 +26230,7 @@ var init_renderNode = __esm({
|
|
|
26126
26230
|
/* @__PURE__ */ jsxs3("div", { style: box, children: [
|
|
26127
26231
|
props.leadingIcon && accIcon(props.leadingIcon),
|
|
26128
26232
|
props.prefix && /* @__PURE__ */ jsx6("span", { style: { color: muted, flex: "none" }, children: String(props.prefix) }),
|
|
26129
|
-
multilineBox ? /* @__PURE__ */ jsx6("textarea", { "data-component-id": componentId, id: htmlId, "data-component-type": componentType, ref: inputRef, value: local, onChange: onInput, onFocus: onFieldFocus, onBlur: onFieldBlur, placeholder: placeholder2, rows: 2, "aria-label": placeholder2, "aria-invalid": errored || void 0, "aria-describedby": errorId, inputMode, autoCapitalize, maxLength, autoCorrect: suggestOff ? "off" : suggestOn ? "on" : void 0, spellCheck: suggestOff ? false : suggestOn ? true : void 0, autoComplete: suggestOff ? "off" : void 0, style: inputBase }) : /* @__PURE__ */ jsx6("input", { "data-component-id": componentId, id: htmlId, "data-component-type": componentType, ref: inputRef, type: secure ? "password" : "text", value: local, onChange: onInput, onKeyDown, onFocus: onFieldFocus, onBlur: onFieldBlur, placeholder: placeholder2, "aria-label": placeholder2, "aria-invalid": errored || void 0, "aria-describedby": errorId, inputMode, autoCapitalize, maxLength, autoCorrect: suggestOff ? "off" : suggestOn ? "on" : void 0, spellCheck: suggestOff ? false : suggestOn ? true : void 0, autoComplete: suggestOff ? "off" : void 0, enterKeyHint, style: inputBase }),
|
|
26233
|
+
multilineBox ? /* @__PURE__ */ jsx6("textarea", { "data-component-id": componentId, id: htmlId, "data-component-type": componentType, ...a11yFwd, ref: inputRef, value: local, onChange: onInput, onFocus: onFieldFocus, onBlur: onFieldBlur, placeholder: placeholder2, rows: 2, "aria-label": ariaLabelProp ?? placeholder2, "aria-invalid": errored || void 0, "aria-describedby": errorId, inputMode, autoCapitalize, maxLength, autoCorrect: suggestOff ? "off" : suggestOn ? "on" : void 0, spellCheck: suggestOff ? false : suggestOn ? true : void 0, autoComplete: suggestOff ? "off" : void 0, style: inputBase }) : /* @__PURE__ */ jsx6("input", { "data-component-id": componentId, id: htmlId, "data-component-type": componentType, ...a11yFwd, ref: inputRef, type: secure ? "password" : "text", value: local, onChange: onInput, onKeyDown, onFocus: onFieldFocus, onBlur: onFieldBlur, placeholder: placeholder2, "aria-label": ariaLabelProp ?? placeholder2, "aria-invalid": errored || void 0, "aria-describedby": errorId, inputMode, autoCapitalize, maxLength, autoCorrect: suggestOff ? "off" : suggestOn ? "on" : void 0, spellCheck: suggestOff ? false : suggestOn ? true : void 0, autoComplete: suggestOff ? "off" : void 0, enterKeyHint, style: inputBase }),
|
|
26130
26234
|
props.suffix && /* @__PURE__ */ jsx6("span", { style: { color: muted, flex: "none" }, children: String(props.suffix) }),
|
|
26131
26235
|
props.clearButton && local && /* @__PURE__ */ jsx6("span", { onClick: () => {
|
|
26132
26236
|
setLocal("");
|
|
@@ -26158,15 +26262,47 @@ var init_renderNode = __esm({
|
|
|
26158
26262
|
document.removeEventListener("keydown", onKey);
|
|
26159
26263
|
};
|
|
26160
26264
|
}, [open]);
|
|
26265
|
+
const modal = ariaModal(props.modal, false) === "true";
|
|
26266
|
+
const anchorLabel = props.anchor?.modifiers?.accessibilityLabel || "More actions";
|
|
26267
|
+
const popupPlacement = { position: "absolute", top: "100%", right: 0, zIndex: 20, marginTop: 4 };
|
|
26268
|
+
const anchorRef = React5.useRef(null);
|
|
26269
|
+
const menuRef = React5.useRef(null);
|
|
26270
|
+
const itemsKey = items.map((it, i) => `${it?.id ?? i}:${it?.disabled ? 0 : 1}`).join("|");
|
|
26271
|
+
React5.useEffect(() => {
|
|
26272
|
+
if (!open || !modal) return;
|
|
26273
|
+
const menu = menuRef.current;
|
|
26274
|
+
if (!menu || menu.contains(document.activeElement)) return;
|
|
26275
|
+
(menu.querySelector('[role="menuitem"][tabindex="0"]') ?? menu).focus();
|
|
26276
|
+
}, [open, modal, itemsKey]);
|
|
26277
|
+
React5.useEffect(() => {
|
|
26278
|
+
if (!open || !modal) return;
|
|
26279
|
+
return () => {
|
|
26280
|
+
const active = document.activeElement;
|
|
26281
|
+
if (active == null || active === document.body || !document.contains(active)) anchorRef.current?.focus();
|
|
26282
|
+
};
|
|
26283
|
+
}, [open, modal]);
|
|
26284
|
+
const trapTab = (e) => {
|
|
26285
|
+
if (!modal || e.key !== "Tab") return;
|
|
26286
|
+
const items2 = Array.from(menuRef.current?.querySelectorAll('[role="menuitem"][tabindex="0"]') ?? []);
|
|
26287
|
+
if (!items2.length) {
|
|
26288
|
+
e.preventDefault();
|
|
26289
|
+
return;
|
|
26290
|
+
}
|
|
26291
|
+
const at = items2.indexOf(document.activeElement);
|
|
26292
|
+
const next = e.shiftKey ? at <= 0 ? items2.length - 1 : at - 1 : at < 0 || at === items2.length - 1 ? 0 : at + 1;
|
|
26293
|
+
e.preventDefault();
|
|
26294
|
+
items2[next].focus();
|
|
26295
|
+
};
|
|
26161
26296
|
return /* @__PURE__ */ jsxs3("span", { ref: hostRef, style: { position: "relative", display: "inline-flex", ...wrap }, children: [
|
|
26162
26297
|
/* @__PURE__ */ jsx6(
|
|
26163
26298
|
"span",
|
|
26164
26299
|
{
|
|
26300
|
+
ref: anchorRef,
|
|
26165
26301
|
role: "button",
|
|
26166
26302
|
tabIndex: 0,
|
|
26167
26303
|
"aria-haspopup": "menu",
|
|
26168
26304
|
"aria-expanded": open,
|
|
26169
|
-
"aria-label":
|
|
26305
|
+
"aria-label": anchorLabel,
|
|
26170
26306
|
onClick: (e) => {
|
|
26171
26307
|
e.stopPropagation();
|
|
26172
26308
|
setOpen((v) => !v);
|
|
@@ -26182,11 +26318,14 @@ var init_renderNode = __esm({
|
|
|
26182
26318
|
children: props.anchor ? renderNode(props.anchor, ctx) : iconSvg("more", { size: 20, color: C("textSecondary", "#636b78") })
|
|
26183
26319
|
}
|
|
26184
26320
|
),
|
|
26185
|
-
open && /* @__PURE__ */ jsx6(
|
|
26321
|
+
open && wrapModalMenu(modal, anchorLabel, popupPlacement, /* @__PURE__ */ jsx6(
|
|
26186
26322
|
"div",
|
|
26187
26323
|
{
|
|
26324
|
+
ref: menuRef,
|
|
26188
26325
|
role: "menu",
|
|
26189
|
-
|
|
26326
|
+
tabIndex: modal ? -1 : void 0,
|
|
26327
|
+
onKeyDown: trapTab,
|
|
26328
|
+
style: { ...modal ? {} : popupPlacement, display: "flex", flexDirection: "column", minWidth: 180, background: C("surfacePrimary", "#fff"), border: `1px solid ${C("border", "#e3e3e3")}`, borderRadius: 12, boxShadow: "0 6px 20px rgba(0,0,0,.12)", overflow: "hidden", padding: 4 },
|
|
26190
26329
|
children: items.map((it, i) => /* @__PURE__ */ jsxs3(
|
|
26191
26330
|
"div",
|
|
26192
26331
|
{
|
|
@@ -26215,7 +26354,7 @@ var init_renderNode = __esm({
|
|
|
26215
26354
|
it?.id ?? i
|
|
26216
26355
|
))
|
|
26217
26356
|
}
|
|
26218
|
-
)
|
|
26357
|
+
))
|
|
26219
26358
|
] });
|
|
26220
26359
|
});
|
|
26221
26360
|
LoadMoreSentinel = ({ ctx, pagination }) => {
|
|
@@ -27092,6 +27231,7 @@ var init_renderNode = __esm({
|
|
|
27092
27231
|
] });
|
|
27093
27232
|
});
|
|
27094
27233
|
SYNTHETIC_TAP_ROLE = "data-hm-synthetic-role";
|
|
27234
|
+
SYNTHETIC_TABINDEX = "data-hm-synthetic-tabindex";
|
|
27095
27235
|
INFERRED_DECORATIVE = "data-hm-inferred-decorative";
|
|
27096
27236
|
ICON_GLYPH = "data-hm-icon-glyph";
|
|
27097
27237
|
INTERACTIVE_ROLES = /* @__PURE__ */ new Set([
|
|
@@ -27455,7 +27595,7 @@ var init_renderNode = __esm({
|
|
|
27455
27595
|
if (gated && presented !== true && presented !== "true") return null;
|
|
27456
27596
|
const grabber = props.showGrabber !== false;
|
|
27457
27597
|
const sheet = idiomControls(ctx.idiom).sheet;
|
|
27458
|
-
return /* @__PURE__ */ jsx6("div", { style: { position: "absolute", inset: 0, background: "rgba(0,0,0,.35)", zIndex: 50, display: "flex", flexDirection: "column", justifyContent: "flex-end", ...wrap }, children: /* @__PURE__ */ jsxs3("div", { role: "dialog", "aria-modal":
|
|
27598
|
+
return /* @__PURE__ */ jsx6("div", { style: { position: "absolute", inset: 0, background: "rgba(0,0,0,.35)", zIndex: 50, display: "flex", flexDirection: "column", justifyContent: "flex-end", ...wrap }, children: /* @__PURE__ */ jsxs3("div", { role: "dialog", "aria-modal": ariaModal(props.modal, true), "aria-label": props.title != null ? sheetTitle : "Sheet", style: { width: "100%", background: C("surfacePrimary", "#fff"), borderRadius: `${sheet.cornerRadius}px ${sheet.cornerRadius}px 0 0`, boxShadow: "0 -4px 24px rgba(0,0,0,.12)", overflow: "hidden" }, children: [
|
|
27459
27599
|
grabber && /* @__PURE__ */ jsx6("div", { style: { display: "flex", justifyContent: "center", padding: "8px 0 4px" }, children: /* @__PURE__ */ jsx6("div", { style: { width: sheet.grabberWidth, height: sheet.grabberHeight, borderRadius: 999, background: C("surfaceTertiary", "#d8dce2") } }) }),
|
|
27460
27600
|
/* @__PURE__ */ jsx6("div", { style: { padding: "8px 16px 16px" }, children: props.content ? renderNode(props.content, ctx) : null })
|
|
27461
27601
|
] }) });
|
|
@@ -28993,6 +29133,11 @@ var init_renderNode = __esm({
|
|
|
28993
29133
|
grid: "grid",
|
|
28994
29134
|
gridcell: "gridcell"
|
|
28995
29135
|
};
|
|
29136
|
+
initialFocusScheduled = false;
|
|
29137
|
+
initialFocusSeen = /* @__PURE__ */ new WeakSet();
|
|
29138
|
+
PRESENTED_SCOPE = '[aria-modal="true"], [role="dialog"], [role="alertdialog"], [role="menu"]';
|
|
29139
|
+
presentedOpeners = /* @__PURE__ */ new Map();
|
|
29140
|
+
presentedObserver = null;
|
|
28996
29141
|
A11yHintDescription = ({ hint, idBase, children, ...forwarded }) => {
|
|
28997
29142
|
const descId = `${idBase ?? "hm"}__hint${React5.useId()}`;
|
|
28998
29143
|
const own3 = children.props;
|
|
@@ -31877,7 +32022,7 @@ var init_config2 = __esm({
|
|
|
31877
32022
|
// ../../core/dev-server/src/index.ts
|
|
31878
32023
|
import { createServer as createServer2 } from "node:http";
|
|
31879
32024
|
import { readFile, stat } from "node:fs/promises";
|
|
31880
|
-
import { readFileSync as readFileSync39, existsSync as existsSync36, watch, mkdirSync as mkdirSync16, rmSync as
|
|
32025
|
+
import { readFileSync as readFileSync39, existsSync as existsSync36, watch, mkdirSync as mkdirSync16, rmSync as rmSync6 } from "node:fs";
|
|
31881
32026
|
import { extname as extname2, resolve as resolve30, normalize as normalize3, sep as sep7 } from "node:path";
|
|
31882
32027
|
import { createHash as createHash15, randomUUID } from "node:crypto";
|
|
31883
32028
|
import { fileURLToPath as fileURLToPath18, pathToFileURL as pathToFileURL6 } from "node:url";
|
|
@@ -32814,7 +32959,7 @@ async function reloadAppModuleNow(state, opts) {
|
|
|
32814
32959
|
return { ok: false, error };
|
|
32815
32960
|
} finally {
|
|
32816
32961
|
try {
|
|
32817
|
-
|
|
32962
|
+
rmSync6(outfile, { force: true });
|
|
32818
32963
|
} catch {
|
|
32819
32964
|
}
|
|
32820
32965
|
}
|
|
@@ -37942,7 +38087,8 @@ async function liveRenderServices(bundleJs, opts) {
|
|
|
37942
38087
|
});
|
|
37943
38088
|
}
|
|
37944
38089
|
async function buildReleaseFromContent(contentDir2, dest, opts = {}) {
|
|
37945
|
-
|
|
38090
|
+
const { freshModule, ...rest } = opts;
|
|
38091
|
+
return buildFromLoaded(await loadContent(contentDir2, { fresh: freshModule === true }), dest, rest);
|
|
37946
38092
|
}
|
|
37947
38093
|
function readTokensForLint(preloaded) {
|
|
37948
38094
|
try {
|
|
@@ -38902,7 +39048,7 @@ __export(progress_exports, {
|
|
|
38902
39048
|
import { spawn as spawn4 } from "node:child_process";
|
|
38903
39049
|
import { createHash as createHash19 } from "node:crypto";
|
|
38904
39050
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
38905
|
-
import { appendFileSync, closeSync, existsSync as existsSync38, lstatSync as lstatSync5, mkdirSync as mkdirSync17, openSync, readFileSync as readFileSync41, readSync, renameSync as renameSync3, rmSync as
|
|
39051
|
+
import { appendFileSync, closeSync, existsSync as existsSync38, lstatSync as lstatSync5, mkdirSync as mkdirSync17, openSync, readFileSync as readFileSync41, readSync, renameSync as renameSync3, rmSync as rmSync7, statSync as statSync7, writeFileSync as writeFileSync13 } from "node:fs";
|
|
38906
39052
|
import { join as join35, relative as relative5, resolve as resolve32, sep as sep8 } from "node:path";
|
|
38907
39053
|
function parseStep(raw) {
|
|
38908
39054
|
const v = raw.trim().toLowerCase();
|
|
@@ -38960,7 +39106,7 @@ function writeFileAtomic(file, content) {
|
|
|
38960
39106
|
writeFileSync13(tmp, content, { flag: "wx" });
|
|
38961
39107
|
renameSync3(tmp, file);
|
|
38962
39108
|
} catch (e) {
|
|
38963
|
-
|
|
39109
|
+
rmSync7(tmp, { force: true });
|
|
38964
39110
|
throw e;
|
|
38965
39111
|
}
|
|
38966
39112
|
}
|
|
@@ -39270,11 +39416,22 @@ function liveRun(dir) {
|
|
|
39270
39416
|
const build2 = obj(rec?.build);
|
|
39271
39417
|
try {
|
|
39272
39418
|
process.kill(pid, 0);
|
|
39419
|
+
const at = text(build2?.at);
|
|
39273
39420
|
return {
|
|
39274
39421
|
url,
|
|
39422
|
+
// Which run this is: a restart on the same port serves the same URL from a new process.
|
|
39423
|
+
runId: `${pid}@${text(rec?.startedAt) ?? ""}`,
|
|
39275
39424
|
buildError: build2?.ok === false ? text(build2.error) ?? "the last rebuild failed" : null,
|
|
39276
39425
|
// Only `--watch` wrote this record before plain runs did, so a record without the key is one.
|
|
39277
|
-
watching: rec?.watching !== false
|
|
39426
|
+
watching: rec?.watching !== false,
|
|
39427
|
+
lastBuild: build2 && at ? {
|
|
39428
|
+
at,
|
|
39429
|
+
ok: build2.ok !== false,
|
|
39430
|
+
ms: typeof build2.ms === "number" && Number.isFinite(build2.ms) ? Math.max(0, Math.round(build2.ms)) : null,
|
|
39431
|
+
screens: (Array.isArray(build2.screens) ? build2.screens : []).filter((x) => typeof x === "string").slice(0, 20),
|
|
39432
|
+
tokens: build2.tokens === true,
|
|
39433
|
+
config: build2.config === true
|
|
39434
|
+
} : null
|
|
39278
39435
|
};
|
|
39279
39436
|
} catch {
|
|
39280
39437
|
return null;
|
|
@@ -39391,6 +39548,7 @@ function renderStudioHtml(initial) {
|
|
|
39391
39548
|
<meta charset="utf-8">
|
|
39392
39549
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
39393
39550
|
<title>${escapeHtml(initial.app.name)} \xB7 build board</title>
|
|
39551
|
+
<link rel="icon" id="fav" href="data:,">
|
|
39394
39552
|
<style>
|
|
39395
39553
|
:root{--bg:#f6f5f2;--card:#fff;--ink:#1c1c1a;--muted:#6b6a64;--faint:#a3a19a;--line:#e6e3dc;--ok:#1f7a4d;--okbg:#e3f3ea;--warn:#8a5a00;--warnbg:#fbefd6;--bad:#a12a2a;--badbg:#fbe4e4;--accent:${accent};--shadow:0 1px 2px rgba(0,0,0,.04),0 4px 16px rgba(0,0,0,.04)}
|
|
39396
39554
|
@media (prefers-color-scheme:dark){:root{--bg:#121211;--card:#1c1c1a;--ink:#ecebe6;--muted:#a3a19a;--faint:#6b6a64;--line:#2c2b28;--okbg:#15301f;--ok:#7fd3a2;--warnbg:#33270f;--warn:#f0c46b;--badbg:#3a1616;--bad:#f09a9a;--shadow:none}}
|
|
@@ -39409,6 +39567,7 @@ h1{font-size:20px;font-weight:600;margin:0}.sub{color:var(--muted);font-size:13p
|
|
|
39409
39567
|
h2{font-size:12px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;margin:0 0 10px}
|
|
39410
39568
|
.phone{width:100%;max-width:300px;aspect-ratio:390/844;border-radius:34px;border:9px solid #111;background:#fff;overflow:hidden;margin:0 auto;display:block}
|
|
39411
39569
|
.phone img,.phone iframe{width:100%;height:100%;object-fit:cover;object-position:top;border:0;display:block;cursor:zoom-in}
|
|
39570
|
+
.phone.vpf{position:relative}.phone iframe.vp{position:absolute;top:0;left:0;width:390px;height:844px;transform-origin:0 0;transform:scale(var(--k,.72));cursor:auto}
|
|
39412
39571
|
.cap{text-align:center;color:var(--muted);font-size:12px;margin-top:8px}
|
|
39413
39572
|
.film{display:flex;gap:6px;overflow-x:auto;margin-top:12px;padding-bottom:4px}.film img{width:48px;aspect-ratio:390/844;object-fit:cover;object-position:top;border-radius:8px;border:1px solid var(--line);cursor:zoom-in}
|
|
39414
39573
|
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px}.chip{font-size:12px;padding:5px 10px;border-radius:999px;background:var(--card);border:1px solid var(--line);color:var(--muted)}
|
|
@@ -39423,12 +39582,26 @@ h2{font-size:12px;font-weight:600;color:var(--muted);text-transform:uppercase;le
|
|
|
39423
39582
|
.log .t{color:var(--faint);font-size:12px;min-width:64px;font-variant-numeric:tabular-nums}.log .s{font-size:11px;color:var(--muted);text-transform:capitalize}.log .imgs{display:flex;gap:6px;margin-top:6px}.log .imgs img{height:72px;border-radius:8px;border:1px solid var(--line);cursor:zoom-in}
|
|
39424
39583
|
.empty{color:var(--faint);font-size:13px;padding:8px 0}
|
|
39425
39584
|
#lb{position:fixed;inset:0;background:rgba(0,0,0,.72);display:none;align-items:center;justify-content:center;z-index:9;cursor:zoom-out}#lb img{max-height:92vh;max-width:92vw;border-radius:14px;background:#fff}
|
|
39585
|
+
.enter{animation:enter .7s cubic-bezier(.2,.8,.2,1) both}@keyframes enter{from{opacity:0;transform:translateY(10px) scale(.94);filter:grayscale(1)}to{opacity:1;transform:none;filter:none}}
|
|
39586
|
+
.changed .frame{animation:chg .9s ease both}@keyframes chg{35%{opacity:.25;transform:scale(.96)}100%{opacity:1;transform:none}}
|
|
39587
|
+
.step.fresh .bar{animation:fill .7s ease both;transform-origin:left}@keyframes fill{from{transform:scaleX(0)}to{transform:scaleX(1)}}
|
|
39588
|
+
.slidein{animation:slide .45s cubic-bezier(.2,.8,.2,1) both}@keyframes slide{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
|
|
39589
|
+
.phone.pulse{animation:pulse 1s ease-out}.phone.pulse.bad{animation-name:pulsebad}@keyframes pulse{from{outline:3px solid var(--ok);outline-offset:0}to{outline:3px solid transparent;outline-offset:10px}}@keyframes pulsebad{from{outline:3px solid var(--bad);outline-offset:0}to{outline:3px solid transparent;outline-offset:10px}}
|
|
39590
|
+
.toast{display:block;width:max-content;max-width:100%;margin:8px auto 0;font-size:12px;padding:4px 10px;border-radius:999px;background:var(--okbg);color:var(--ok);animation:toast 3.4s ease both}.toast.bad{background:var(--badbg);color:var(--bad)}@keyframes toast{0%{opacity:0;transform:translateY(4px)}10%,80%{opacity:1;transform:none}100%{opacity:0}}
|
|
39591
|
+
.icon,.step.cur .bar{transition:background-color .8s}.sw.pop span{animation:pop .6s ease both}@keyframes pop{50%{transform:scale(1.25)}}
|
|
39592
|
+
.quiet{color:var(--warn)}.quiet .dot{background:var(--warn)}.idle .dot{background:var(--faint)}
|
|
39593
|
+
.tog{font:inherit;font-size:12px;color:var(--muted);background:none;border:1px solid var(--line);border-radius:999px;padding:2px 9px;margin:6px 0 0 6px;cursor:pointer}.tog.on{color:var(--ink);border-color:var(--ink)}
|
|
39594
|
+
#fx{position:fixed;inset:0;width:100%;height:100%;pointer-events:none;z-index:8}
|
|
39595
|
+
@media (max-width:560px){header{flex-wrap:wrap}.right{margin-left:0;width:100%;text-align:left;display:flex;flex-wrap:wrap;align-items:center;gap:4px 12px}.right .clock{font-size:18px}.tog{margin:0 6px 0 0}}
|
|
39596
|
+
@media (prefers-reduced-motion:reduce){.enter,.changed .frame,.step.fresh .bar,.slidein,.phone.pulse,.sw.pop span,.toast{animation:none}.icon,.step.cur .bar{transition:none}}
|
|
39426
39597
|
</style>
|
|
39427
39598
|
</head>
|
|
39428
39599
|
<body>
|
|
39429
39600
|
<div class="wrap">
|
|
39430
39601
|
<header><img class="icon" id="icon" alt=""><div><h1 id="name"></h1><div class="sub">Build board \xB7 updates itself as the app is built</div></div>
|
|
39431
|
-
<div class="right"><div class="clock" id="clock">00:00</div><div class="live" id="live"><span class="dot"></span><span id="updated">live</span></div
|
|
39602
|
+
<div class="right"><div class="clock" id="clock">00:00</div><div class="live" id="live"><span class="dot"></span><span id="updated">live</span></div>
|
|
39603
|
+
<div><span class="live idle" id="agent"><span class="dot"></span><span id="agentt">Waiting for the agent</span></span></div>
|
|
39604
|
+
<div><button class="tog" id="snd" type="button" aria-pressed="false">Sound off</button><button class="tog" id="ntf" type="button" aria-pressed="false" hidden>Notices off</button></div></div></header>
|
|
39432
39605
|
<div class="steps" id="steps"></div>
|
|
39433
39606
|
<div class="card now"><div style="flex:1"><div class="meta" id="nowmeta">Now</div><div class="msg" id="nowmsg"></div></div></div>
|
|
39434
39607
|
<div class="grid">
|
|
@@ -39441,6 +39614,7 @@ h2{font-size:12px;font-weight:600;color:var(--muted);text-transform:uppercase;le
|
|
|
39441
39614
|
<div class="card section"><h2>Postcards</h2><ul class="log" id="log"></ul></div>
|
|
39442
39615
|
</div></div></div>
|
|
39443
39616
|
<div id="lb"><img alt=""></div>
|
|
39617
|
+
<canvas id="fx" aria-hidden="true"></canvas>
|
|
39444
39618
|
<script>window.__himiInitial = ${scriptJson(initial)};</script>
|
|
39445
39619
|
<script>
|
|
39446
39620
|
(function(){
|
|
@@ -39455,27 +39629,33 @@ function zoomable(img){img.addEventListener("click",function(){var lb=$("lb");lb
|
|
|
39455
39629
|
function img(src,cls){var i=el("img",cls);i.src=src;i.alt="";i.loading="lazy";zoomable(i);return i}
|
|
39456
39630
|
function chip(txt,kind){return el("span","chip"+(kind?" "+kind:""),txt)}
|
|
39457
39631
|
function render(s){
|
|
39458
|
-
document.title=s.app.name+" \xB7 build board";$("name").textContent=s.app.name;
|
|
39632
|
+
var sn=s.current?s.current.stepNumber:0;document.title=(sn?"("+sn+"/8) ":"")+s.app.name+" \xB7 build board";favicon(sn,!!(s.live&&s.live.buildError));$("name").textContent=s.app.name;
|
|
39459
39633
|
if(s.app.icon){$("icon").src=s.app.icon}else{$("icon").removeAttribute("src")}
|
|
39460
39634
|
var steps=$("steps");clear(steps);var n=s.current?s.current.stepNumber:0;
|
|
39461
39635
|
s.steps.forEach(function(name,i){var d=el("div","step"+(i+1<n?" done":i+1===n?" cur":""));d.appendChild(el("div","bar"));d.appendChild(el("div","lbl",(i+1)+". "+name));steps.appendChild(d)});
|
|
39462
39636
|
var last=s.journal[0];
|
|
39463
39637
|
$("nowmsg").textContent=last?last.message:"Waiting for the first postcard.";
|
|
39464
39638
|
$("nowmeta").textContent=last?("Now \xB7 "+(last.step?("step "+last.stepNumber+" of 8, "+last.step+" \xB7 "):"")+ago(last.ts)):"Now";
|
|
39465
|
-
var focus=$("focus");
|
|
39466
|
-
|
|
39639
|
+
var focus=$("focus");var film=$("film");clear(film);
|
|
39640
|
+
/* The live frame is KEPT across renders while its URL and its run are unchanged (a restarted run on
|
|
39641
|
+
the same port is a different server, and the old frame would never see its builds). A new iframe is a full page
|
|
39642
|
+
load of the preview: every postcard, rebuild and the once-a-minute re-render used to throw away
|
|
39643
|
+
the in-place repaint, the preview's scroll and wherever the owner had navigated inside it. */
|
|
39644
|
+
var kept=s.live?focus.querySelector("iframe"):null;if(kept&&(kept.getAttribute("src")!==s.live.url||kept.getAttribute("data-run")!==s.live.runId))kept=null;
|
|
39645
|
+
if(kept){while(focus.lastChild&&focus.lastChild!==kept.parentNode)focus.removeChild(focus.lastChild)}else clear(focus);
|
|
39646
|
+
if(s.live){$("focuslbl").textContent="Live preview";if(!kept){var f=el("div","phone vpf");var fr=document.createElement("iframe");fr.className="vp";fr.setAttribute("width","390");fr.setAttribute("height","844");fr.setAttribute("data-run",s.live.runId);fr.src=s.live.url;fr.title="Live preview";f.appendChild(fr);focus.appendChild(f)}fit();if(s.live.buildError){var be=el("div","chip bad",null);be.style.display="block";be.style.marginTop="8px";be.textContent="Last edit did not build, still showing the last good version: "+s.live.buildError;focus.appendChild(be)}focus.appendChild(el("div","cap",(s.live.watching?"Repaints as the app is edited \xB7 ":"The build this run started with; himi run --watch repaints on every edit \xB7 ")+s.live.url))}
|
|
39467
39647
|
else if(s.focus&&s.focus.frames.length){var fl=s.focus.frames;$("focuslbl").textContent="Latest \xB7 "+s.focus.id;var p=el("div","phone");p.appendChild(img(fl[fl.length-1].img));focus.appendChild(p);focus.appendChild(el("div","cap",fl.length+(fl.length===1?" version":" versions")+" so far"))}
|
|
39468
39648
|
else{$("focuslbl").textContent="Latest";focus.appendChild(el("div","empty","The first render appears here."))}
|
|
39469
39649
|
if(s.focus&&s.focus.frames.length>1)s.focus.frames.forEach(function(fm){film.appendChild(img(fm.img))});
|
|
39470
39650
|
var chips=$("chips");clear(chips);var h=s.health;
|
|
39471
39651
|
if(h.validate)chips.appendChild(chip(h.validate.ok?"Validate passing":"Validate: "+h.validate.errors+" errors",h.validate.ok?"ok":"bad"));
|
|
39472
|
-
if(h.test){var t=h.test;var
|
|
39652
|
+
if(h.test){var t=h.test;var moved=t.prevGaps!=null&&t.prevGaps!==t.gaps;var tc=chip("Test crawl: "+t.screens+" screens, "+t.actions+" actions, "+(moved?"gaps "+t.prevGaps+" \u2192 ":""),t.ok?"ok":"bad");var gn=el("span",null,String(t.gaps));gn.id="gapn";tc.appendChild(gn);if(!moved)tc.appendChild(document.createTextNode(" gaps"));chips.appendChild(tc)}
|
|
39473
39653
|
h.ux.forEach(function(u){chips.appendChild(chip("UX drive "+u.platform+": "+u.status,u.status==="passed"?"ok":u.status==="failed"?"bad":"warn"))});
|
|
39474
39654
|
if(h.push)chips.appendChild(chip((h.push.draft?"Draft published":"Published live")+" \xB7 "+h.push.releaseId.slice(0,10),h.push.draft?"warn":"ok"));
|
|
39475
39655
|
if(!chips.firstChild)chips.appendChild(chip("Checks appear here as validate, test and push run"));
|
|
39476
39656
|
var wall=$("wall");clear(wall);
|
|
39477
39657
|
if(!s.screens.length)wall.appendChild(el("div","empty","Screens appear here as they render."));
|
|
39478
|
-
s.screens.forEach(function(sc){var d=el("div","shot");var fr=el("div","frame");fr.appendChild(img(sc.img));d.appendChild(fr);d.appendChild(el("div","id",sc.id));
|
|
39658
|
+
s.screens.forEach(function(sc){var d=el("div","shot");d.setAttribute("data-id",sc.id);var fr=el("div","frame");fr.appendChild(img(sc.img));d.appendChild(fr);d.appendChild(el("div","id",sc.id));
|
|
39479
39659
|
if(recent(sc.firstSeen)&&sc.versions===1)d.appendChild(el("span","badge new","New"));else if(recent(sc.changedAt)&&sc.versions>1)d.appendChild(el("span","badge chg","Changed"));wall.appendChild(d)});
|
|
39480
39660
|
var brand=$("brand");clear(brand);$("brandcard").style.display=(s.brand.site||s.app.palette.length)?"":"none";
|
|
39481
39661
|
if(s.brand.site){var si=img(s.brand.site,"site");brand.appendChild(si)}
|
|
@@ -39486,14 +39666,61 @@ function render(s){
|
|
|
39486
39666
|
s.journal.forEach(function(j){var li=el("li");li.appendChild(el("div","t",hhmm(j.ts)));var body=el("div");body.appendChild(el("div",null,j.message));if(j.step)body.appendChild(el("div","s","step "+j.stepNumber+" \xB7 "+j.step));
|
|
39487
39667
|
if(j.images.length){var row=el("div","imgs");j.images.forEach(function(u){row.appendChild(img(u))});body.appendChild(row)}li.appendChild(body);log.appendChild(li)});
|
|
39488
39668
|
}
|
|
39489
|
-
|
|
39669
|
+
/* Motion, sound and notices answer a CHANGE, never a redraw: effects() compares what is on the page
|
|
39670
|
+
now with what it showed last, so opening the board, the once-a-minute redraw and the two-second
|
|
39671
|
+
poll of an unchanged state do nothing, and each effect names a real event. */
|
|
39672
|
+
var seen=null,actx=null,sound=false,notices=false;try{sound=localStorage.getItem("himiStudioSound")==="1";notices=localStorage.getItem("himiStudioNotify")==="1"}catch(e){}
|
|
39673
|
+
var raf=window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(f){return setTimeout(function(){f(Date.now())},16)};
|
|
39674
|
+
function now(){return window.performance&&performance.now?performance.now():Date.now()}
|
|
39675
|
+
function reduced(){try{return matchMedia("(prefers-reduced-motion: reduce)").matches}catch(e){return false}}
|
|
39676
|
+
function tone(f,t,d,v,type){if(!sound)return;try{if(!actx){var AC=window.AudioContext||window.webkitAudioContext;if(!AC)return;actx=new AC()}var o=actx.createOscillator(),g=actx.createGain(),n=actx.currentTime+(t||0),dd=d||.18;o.type=type||"sine";o.frequency.value=f;g.gain.setValueAtTime(0,n);g.gain.linearRampToValueAtTime(v||.05,n+.01);g.gain.exponentialRampToValueAtTime(.0001,n+dd);o.connect(g);g.connect(actx.destination);o.start(n);o.stop(n+dd+.05)}catch(e){}}
|
|
39677
|
+
var SND={tick:function(){tone(1320,0,.05,.025,"triangle")},post:function(){tone(880,0,.08,.03)},step:function(){tone(523);tone(784,.12)},win:function(){tone(523);tone(659,.1);tone(784,.2);tone(1047,.3,.35)},fail:function(){tone(160,0,.3,.05,"sawtooth")}};
|
|
39678
|
+
/* Notices are the BOARD's opt-in, not just the browser's: a permission granted to this origin once
|
|
39679
|
+
(an earlier board, another run) must not switch them on, and the toggle must switch them off. */
|
|
39680
|
+
function notify(title,body){try{if(notices&&"Notification" in window&&Notification.permission==="granted"&&document.hidden)new Notification(title,{body:body})}catch(e){}}
|
|
39681
|
+
function accentNow(){return (getComputedStyle(document.documentElement).getPropertyValue("--accent")||"").trim()||"#3b6fd8"}
|
|
39682
|
+
/* The preview lays out at a real phone's viewport (390 x 844 CSS px) and is scaled into the frame.
|
|
39683
|
+
Sized to the frame itself it was ~280px wide: narrower than any phone, so screens overflowed
|
|
39684
|
+
sideways and scrolled horizontally. */
|
|
39685
|
+
function fit(){var ph=$("focus").querySelector(".phone.vpf");if(!ph)return;var w=ph.clientWidth,h=ph.clientHeight;if(w&&h)ph.style.setProperty("--k",String(Math.min(w/390,h/844)))}
|
|
39686
|
+
window.addEventListener("resize",fit);
|
|
39687
|
+
function favicon(n,bad){try{var c=document.createElement("canvas");c.width=c.height=32;var x=c.getContext&&c.getContext("2d");if(!x)return;x.lineWidth=5;x.strokeStyle="rgba(128,128,128,.35)";x.beginPath();x.arc(16,16,12,0,6.2832);x.stroke();x.strokeStyle=accentNow();x.beginPath();x.arc(16,16,12,-1.5708,-1.5708+6.2832*n/8);x.stroke();if(bad){x.fillStyle="#d33";x.beginPath();x.arc(25,7,6,0,6.2832);x.fill()}$("fav").href=c.toDataURL("image/png")}catch(e){}}
|
|
39688
|
+
function burst(){var c=$("fx");c.setAttribute("data-bursts",String((+c.getAttribute("data-bursts")||0)+1));if(reduced())return;var x=c.getContext&&c.getContext("2d");if(!x)return;var W=c.width=innerWidth,H=c.height=innerHeight,cols=["#1f7a4d","#3b6fd8","#e0a030","#d4537e",accentNow()],P=[];for(var i=0;i<120;i++)P.push({x:W/2,y:H*.35,vx:(Math.random()-.5)*14,vy:-Math.random()*12-4,c:cols[i%cols.length],r:Math.random()*6.28});var t0=now();(function f(){x.clearRect(0,0,W,H);P.forEach(function(p){p.x+=p.vx;p.y+=p.vy;p.vy+=.35;p.r+=.2;x.save();x.translate(p.x,p.y);x.rotate(p.r);x.fillStyle=p.c;x.fillRect(-4,-2,8,4);x.restore()});if(now()-t0<2200)raf(f);else x.clearRect(0,0,W,H)})()}
|
|
39689
|
+
function countTo(e,a,b){if(!e)return;if(reduced()){e.textContent=String(b);return}var t0=now();(function f(){var k=Math.min(1,(now()-t0)/900);e.textContent=String(Math.round(a+(b-a)*k));if(k<1)raf(f)})()}
|
|
39690
|
+
function snap(s){var sc={},acc=null;s.screens.forEach(function(x){sc[x.id]=x.img});s.app.palette.forEach(function(p){if(p.name==="accentPrimary")acc=p.hex});return{screens:sc,step:s.current?s.current.stepNumber:0,top:s.journal[0]?s.journal[0].ts:null,build:s.live&&s.live.lastBuild?s.live.lastBuild.at:null,run:s.live?s.live.runId:null,push:s.health.push?s.health.push.releaseId:null,gaps:s.health.test?s.health.test.gaps:null,accent:acc}}
|
|
39691
|
+
function buildLine(b){if(!b.ok)return "Build failed \xB7 still showing the last good version";var what=b.screens.length?b.screens.slice(0,3).join(", ")+(b.screens.length>3?" +"+(b.screens.length-3):""):b.tokens?"design tokens":b.config?"app config":"no visible change";return "Rebuilt"+(b.ms!=null?" in "+(b.ms/1000).toFixed(1)+" s":"")+" \xB7 "+what}
|
|
39692
|
+
function effects(s){var is=snap(s),was=seen;seen=is;if(is.accent)document.documentElement.style.setProperty("--accent",is.accent);
|
|
39693
|
+
/* The phone (kept across renders) and the Now line outlive a render: clear what they played last. */
|
|
39694
|
+
var ph=$("focus").querySelector(".phone"),nm=$("nowmsg");if(ph)ph.classList.remove("pulse","bad");nm.classList.remove("slidein");if(!was)return;
|
|
39695
|
+
var ticked=false;[].forEach.call($("wall").children,function(d){var id=d.getAttribute("data-id");if(!id)return;if(!(id in was.screens)){d.classList.add("enter");ticked=true}else if(was.screens[id]!==is.screens[id]){d.classList.add("changed");ticked=true}});if(ticked)SND.tick();
|
|
39696
|
+
if(is.top&&is.top!==was.top){void nm.offsetWidth;nm.classList.add("slidein");var li=$("log").firstChild;if(li&&li.classList)li.classList.add("slidein");SND.post()}
|
|
39697
|
+
if(is.step>was.step){var cs=$("steps").children[is.step-1];if(cs)cs.classList.add("fresh");SND.step();notify(s.app.name+" \xB7 step "+is.step+" of 8",s.journal[0]?s.journal[0].message:s.steps[is.step-1])}
|
|
39698
|
+
/* A rebuild is a later build of the SAME run: a run appearing, or restarting, records its first
|
|
39699
|
+
build too, and nothing was rebuilt then. */
|
|
39700
|
+
if(is.build&&was.build&&is.run===was.run&&is.build!==was.build){var b=s.live.lastBuild;if(ph){void ph.offsetWidth;ph.classList.add("pulse");if(!b.ok)ph.classList.add("bad")}var tt=el("div","toast"+(b.ok?"":" bad"),buildLine(b));$("focus").appendChild(tt);setTimeout(function(){if(tt.parentNode)tt.parentNode.removeChild(tt)},3500);if(b.ok)SND.tick();else{SND.fail();notify(s.app.name+" \xB7 build failed",s.live.buildError||"")}}
|
|
39701
|
+
if(was.gaps!=null&&is.gaps!=null&&is.gaps!==was.gaps)countTo($("gapn"),was.gaps,is.gaps);
|
|
39702
|
+
if(is.accent&&was.accent&&is.accent!==was.accent){var sw=$("brand").querySelector(".sw");if(sw)sw.classList.add("pop");favicon(is.step,!!(s.live&&s.live.buildError))}
|
|
39703
|
+
var published=is.push&&is.push!==was.push,handed=is.step===8&&was.step<8;if(published||handed){burst();SND.win();notify(s.app.name,published?"Draft published":"Handed over")}
|
|
39704
|
+
}
|
|
39705
|
+
function activityAt(s){var m=0;function add(v){var d=v?Date.parse(v):0;if(d>m)m=d}if(s.journal[0])add(s.journal[0].ts);s.screens.forEach(function(x){add(x.changedAt)});if(s.live&&s.live.lastBuild)add(s.live.lastBuild.at);["validate","test","push"].forEach(function(k){if(s.health[k])add(s.health[k].at)});return m}
|
|
39706
|
+
function paintToggles(){var b=$("snd");b.textContent=sound?"Sound on":"Sound off";b.className="tog"+(sound?" on":"");b.setAttribute("aria-pressed",String(sound));var nb=$("ntf");if(!("Notification" in window)){nb.hidden=true;return}var p=Notification.permission,on=notices&&p==="granted";nb.hidden=p==="denied";nb.textContent=on?"Notices on":"Notices off";nb.className="tog"+(on?" on":"");nb.setAttribute("aria-pressed",String(on))}
|
|
39707
|
+
function setNotices(v){notices=v;try{localStorage.setItem("himiStudioNotify",v?"1":"0")}catch(e){}paintToggles()}
|
|
39708
|
+
$("snd").addEventListener("click",function(){sound=!sound;try{localStorage.setItem("himiStudioSound",sound?"1":"0")}catch(e){}if(sound){try{if(actx&&actx.resume)actx.resume()}catch(e){}SND.post()}paintToggles()});
|
|
39709
|
+
/* The click acts on what the button SAYS (the effective state), so a remembered opt-in whose browser
|
|
39710
|
+
permission was since reset reads "off" and one click asks for permission, not two. */
|
|
39711
|
+
$("ntf").addEventListener("click",function(){try{var p=Notification.permission;if(notices&&p==="granted"){setNotices(false);return}if(p==="granted"){setNotices(true);return}if(Notification.permission==="default")Promise.resolve(Notification.requestPermission()).then(function(p){setNotices(p==="granted")})}catch(e){}});
|
|
39712
|
+
document.addEventListener("click",function(){try{if(actx&&actx.state==="suspended")actx.resume()}catch(e){}},{once:true});
|
|
39713
|
+
paintToggles();
|
|
39714
|
+
window.__himiStudio=function(s){lastSeen=Date.now();if(!cur||cur.v!==s.v){cur=s;render(s);effects(s)}else{cur.generatedAt=s.generatedAt}};
|
|
39490
39715
|
$("lb").addEventListener("click",function(){this.style.display="none"});
|
|
39491
39716
|
window.__himiStudio(window.__himiInitial);
|
|
39492
39717
|
setInterval(function(){var sc=document.createElement("script");sc.src="state.js?t="+Date.now();sc.onload=sc.onerror=function(){sc.remove()};document.head.appendChild(sc)},2000);
|
|
39493
39718
|
var ticks=0;
|
|
39494
39719
|
setInterval(function(){if(!cur)return;if(++ticks%60===0)render(cur);var start=cur.startedAt?Date.parse(cur.startedAt):Date.now();var s=Math.max(0,Math.floor((Date.now()-start)/1000));var hh=Math.floor(s/3600),mm=Math.floor(s%3600/60),ss=s%60;
|
|
39495
39720
|
$("clock").textContent=(hh?hh+":":"")+(mm<10&&hh?"0":"")+mm+":"+(ss<10?"0":"")+ss;
|
|
39496
|
-
$("updated").textContent="updated "+ago(cur.generatedAt);$("live").className="live"+(Date.now()-lastSeen>10000?" stale":"")
|
|
39721
|
+
$("updated").textContent="updated "+ago(cur.generatedAt);$("live").className="live"+(Date.now()-lastSeen>10000?" stale":"");
|
|
39722
|
+
var a=activityAt(cur),q=a?Date.now()-a:0,done=cur.current&&cur.current.stepNumber===8;
|
|
39723
|
+
$("agent").className="live"+(!a?" idle":done?"":q>5*60*1000?" quiet":"");$("agentt").textContent=!a?"Waiting for the agent":done?"Handed over":q>5*60*1000?"Quiet for "+Math.floor(q/60000)+" min":"Agent active"},1000);
|
|
39497
39724
|
})();
|
|
39498
39725
|
</script>
|
|
39499
39726
|
</body>
|
|
@@ -41069,7 +41296,7 @@ __export(template_trim_exports, {
|
|
|
41069
41296
|
routeMatcher: () => routeMatcher,
|
|
41070
41297
|
runTemplateTrim: () => runTemplateTrim
|
|
41071
41298
|
});
|
|
41072
|
-
import { cpSync, existsSync as existsSync41, mkdirSync as mkdirSync19, readdirSync as readdirSync21, readFileSync as readFileSync45, renameSync as renameSync4, rmSync as
|
|
41299
|
+
import { cpSync, existsSync as existsSync41, mkdirSync as mkdirSync19, readdirSync as readdirSync21, readFileSync as readFileSync45, renameSync as renameSync4, rmSync as rmSync8, statSync as statSync10, writeFileSync as writeFileSync15 } from "node:fs";
|
|
41073
41300
|
import { dirname as dirname23, join as join38 } from "node:path";
|
|
41074
41301
|
function routeMatcher(pattern) {
|
|
41075
41302
|
const detail = /^\^([A-Za-z0-9_]+)\(\?:\[_\/\]\(\.\+\)\)\?\$$/.exec(pattern);
|
|
@@ -41832,11 +42059,11 @@ async function runTemplateTrim(req, deps) {
|
|
|
41832
42059
|
for (const name of [...moved].reverse()) renameSync4(join38(backup, "tier5-src", name), join38(dir, "tier5-src", name));
|
|
41833
42060
|
};
|
|
41834
42061
|
const dropBackup = () => {
|
|
41835
|
-
|
|
42062
|
+
rmSync8(backup, { recursive: true, force: true });
|
|
41836
42063
|
for (const d of [dirname23(backup), join38(dir, ".himi")]) {
|
|
41837
42064
|
if (d === join38(dir, ".himi") && hadHimi) break;
|
|
41838
42065
|
try {
|
|
41839
|
-
if (!readdirSync21(d).length)
|
|
42066
|
+
if (!readdirSync21(d).length) rmSync8(d, { recursive: true });
|
|
41840
42067
|
} catch {
|
|
41841
42068
|
}
|
|
41842
42069
|
}
|
|
@@ -42575,7 +42802,7 @@ __export(pack_exports, {
|
|
|
42575
42802
|
});
|
|
42576
42803
|
import { createHash as createHash21 } from "node:crypto";
|
|
42577
42804
|
import { deflateRawSync, inflateRawSync } from "node:zlib";
|
|
42578
|
-
import { existsSync as existsSync42, mkdirSync as mkdirSync20, readFileSync as readFileSync46, readdirSync as readdirSync22, rmSync as
|
|
42805
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync20, readFileSync as readFileSync46, readdirSync as readdirSync22, rmSync as rmSync9, statSync as statSync11, writeFileSync as writeFileSync16 } from "node:fs";
|
|
42579
42806
|
import { dirname as dirname24, join as join39, resolve as resolve37 } from "node:path";
|
|
42580
42807
|
function writeZip(entries) {
|
|
42581
42808
|
const sorted2 = entries.slice().sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
@@ -42794,7 +43021,7 @@ function packReleaseToDir(releaseRoot, app, outDir, opts = {}) {
|
|
|
42794
43021
|
const appDir2 = join39(resolve37(releaseRoot), app);
|
|
42795
43022
|
const { all, header, skipped } = buildEntries(appDir2, app, opts);
|
|
42796
43023
|
const dest = resolvePackageDirDest(resolve37(outDir), app, header.releaseId);
|
|
42797
|
-
|
|
43024
|
+
rmSync9(dest, { recursive: true, force: true });
|
|
42798
43025
|
let bytes2 = 0;
|
|
42799
43026
|
for (const entry of all) {
|
|
42800
43027
|
const target = join39(dest, entry.path);
|
|
@@ -42877,7 +43104,7 @@ function unpackTo(buf, dest, appFallback) {
|
|
|
42877
43104
|
if (!isSafeAppId(app)) throw new Error(`package declares an unsafe app id ${JSON.stringify(app)} \u2014 refusing to unpack it`);
|
|
42878
43105
|
const root = resolve37(dest);
|
|
42879
43106
|
const appDir2 = join39(root, app);
|
|
42880
|
-
|
|
43107
|
+
rmSync9(appDir2, { recursive: true, force: true });
|
|
42881
43108
|
for (const [rel, bytes2] of entries) {
|
|
42882
43109
|
const target = join39(appDir2, rel);
|
|
42883
43110
|
mkdirSync20(dirname24(target), { recursive: true });
|
|
@@ -42915,7 +43142,7 @@ __export(app_source_exports, {
|
|
|
42915
43142
|
writeConflicts: () => writeConflicts,
|
|
42916
43143
|
zipAppSource: () => zipAppSource
|
|
42917
43144
|
});
|
|
42918
|
-
import { readdirSync as readdirSync23, lstatSync as lstatSync6, readFileSync as readFileSync47, mkdirSync as mkdirSync21, writeFileSync as writeFileSync17, existsSync as existsSync43, rmSync as
|
|
43145
|
+
import { readdirSync as readdirSync23, lstatSync as lstatSync6, readFileSync as readFileSync47, mkdirSync as mkdirSync21, writeFileSync as writeFileSync17, existsSync as existsSync43, rmSync as rmSync10, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
42919
43146
|
import { join as join40, resolve as resolve38, sep as sep10 } from "node:path";
|
|
42920
43147
|
import { deflateRawSync as deflateRawSync2 } from "node:zlib";
|
|
42921
43148
|
function walkSourceTree(dir, file, skip) {
|
|
@@ -43063,7 +43290,7 @@ function writeConflicts(entries, destDir) {
|
|
|
43063
43290
|
function removeStaleSource(entries, destDir) {
|
|
43064
43291
|
const root = resolve38(destDir);
|
|
43065
43292
|
const removed = staleSourcePaths(entries, root);
|
|
43066
|
-
for (const rel of removed)
|
|
43293
|
+
for (const rel of removed) rmSync10(join40(root, ...rel.split("/")), { force: true });
|
|
43067
43294
|
const needed = /* @__PURE__ */ new Set();
|
|
43068
43295
|
for (const entry of entries) {
|
|
43069
43296
|
if (isDeniedSourcePath(entry.path)) continue;
|
|
@@ -45987,7 +46214,7 @@ __export(native_decode_exports, {
|
|
|
45987
46214
|
runNativeDecode: () => runNativeDecode
|
|
45988
46215
|
});
|
|
45989
46216
|
import { execFileSync as execFileSync5, spawnSync as spawnSync2 } from "node:child_process";
|
|
45990
|
-
import { existsSync as existsSync48, mkdtempSync as mkdtempSync2, readFileSync as readFileSync53, rmSync as
|
|
46217
|
+
import { existsSync as existsSync48, mkdtempSync as mkdtempSync2, readFileSync as readFileSync53, rmSync as rmSync11, writeFileSync as writeFileSync20 } from "node:fs";
|
|
45991
46218
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
45992
46219
|
import { join as join46 } from "node:path";
|
|
45993
46220
|
import { fileURLToPath as fileURLToPath20 } from "node:url";
|
|
@@ -46147,7 +46374,7 @@ function runNativeDecode(options) {
|
|
|
46147
46374
|
const stderr = failure.stderr ? ` \u2014 ${String(failure.stderr).trim().slice(0, 2e3)}` : "";
|
|
46148
46375
|
throw new Error(`iOS decoder oracle failed: ${failure.message}${stderr}`);
|
|
46149
46376
|
} finally {
|
|
46150
|
-
|
|
46377
|
+
rmSync11(descriptorDir, { recursive: true, force: true });
|
|
46151
46378
|
}
|
|
46152
46379
|
}
|
|
46153
46380
|
function runAndroidNativeDecode(options) {
|
|
@@ -46185,7 +46412,7 @@ function runAndroidNativeDecode(options) {
|
|
|
46185
46412
|
const stderr = failure.stderr ? ` \u2014 ${String(failure.stderr).trim().slice(0, 2e3)}` : "";
|
|
46186
46413
|
throw new Error(`Android decoder oracle failed: ${failure.message}${stderr}`);
|
|
46187
46414
|
} finally {
|
|
46188
|
-
|
|
46415
|
+
rmSync11(descriptorDir, { recursive: true, force: true });
|
|
46189
46416
|
}
|
|
46190
46417
|
}
|
|
46191
46418
|
function fieldAt(path2) {
|
|
@@ -47232,7 +47459,6 @@ function makeServeHandler(opts) {
|
|
|
47232
47459
|
);
|
|
47233
47460
|
})();
|
|
47234
47461
|
const webwixFetch = opts.webwixFetch ?? fetch;
|
|
47235
|
-
const webwixTokens = new VisitorTokenCache(webwixFetch);
|
|
47236
47462
|
const webwixOwnerInstances = new OwnerInstanceCache(webwixFetch);
|
|
47237
47463
|
const webwixOwnerSites = new OwnerSitesCache(webwixFetch);
|
|
47238
47464
|
const webwixOwnerRungOn = () => opts.webwixOwnerRung !== false;
|
|
@@ -47534,7 +47760,7 @@ ${releaseId}`;
|
|
|
47534
47760
|
const pkce = await generatePkce();
|
|
47535
47761
|
let authUrl;
|
|
47536
47762
|
try {
|
|
47537
|
-
const visitor = await
|
|
47763
|
+
const visitor = await mintAnonymousVisitor(resolved2.config.clientId, webwixFetch);
|
|
47538
47764
|
authUrl = await hostedAuthUrl(
|
|
47539
47765
|
{ ...resolved2.config, mode: path2.endsWith("/register") ? "signup" : "login", state, challenge: pkce.challenge },
|
|
47540
47766
|
visitor,
|
|
@@ -47605,7 +47831,14 @@ ${releaseId}`;
|
|
|
47605
47831
|
const reqPath = String(call.path ?? "/");
|
|
47606
47832
|
const body = call.body === void 0 ? void 0 : typeof call.body === "string" ? call.body : JSON.stringify(call.body);
|
|
47607
47833
|
const forwardedHeaders = normalizeWixForwardedHeaders(call.headers);
|
|
47834
|
+
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(reqPath)) {
|
|
47835
|
+
return absoluteUrlRejection(reqPath) === "owner-only" ? json3(501, { error: "webwix_owner_only", app: app2 }) : json3(400, { error: "absolute_urls_not_allowed" });
|
|
47836
|
+
}
|
|
47608
47837
|
const callerCookie = request.headers.get("cookie") ?? "";
|
|
47838
|
+
if (!call.checkOwnerSession && webwixOwnerRungOn() && method === "POST" && isOwnerSitesPath(reqPath) && !/wixSession2=/.test(callerCookie)) {
|
|
47839
|
+
served.rung = "sites";
|
|
47840
|
+
return json3(501, { error: "webwix_owner_no_session", app: app2 });
|
|
47841
|
+
}
|
|
47609
47842
|
if (!call.checkOwnerSession && webwixOwnerRungOn() && method === "POST" && isOwnerSitesPath(reqPath) && /wixSession2=/.test(callerCookie)) {
|
|
47610
47843
|
served.rung = "sites";
|
|
47611
47844
|
try {
|
|
@@ -47624,32 +47857,8 @@ ${releaseId}`;
|
|
|
47624
47857
|
}
|
|
47625
47858
|
if (call.ownerMsid !== void 0) {
|
|
47626
47859
|
served.rung = call.checkOwnerSession === true ? "gate" : "owner";
|
|
47627
|
-
if (!webwixOwnerRungOn()) {
|
|
47628
|
-
|
|
47629
|
-
}
|
|
47630
|
-
const msid = String(call.ownerMsid);
|
|
47631
|
-
if (!isSafeMsid(msid)) return json3(400, { error: "webwix_owner_bad_msid" });
|
|
47632
|
-
const cookie = request.headers.get("cookie") ?? "";
|
|
47633
|
-
if (!/wixSession2=/.test(cookie)) return json3(501, { error: "webwix_owner_no_session", app: app2 });
|
|
47634
|
-
try {
|
|
47635
|
-
const instance = await webwixOwnerInstances.instance(msid, cookie);
|
|
47636
|
-
if (call.checkOwnerSession === true) return json3(200, { status: 200, body: JSON.stringify({ ready: true }) }, { "cache-control": "no-store" });
|
|
47637
|
-
const first = await wixVisitorCall(method, reqPath, body, instance, webwixFetch, forwardedHeaders);
|
|
47638
|
-
if (first.status !== 401) return json3(200, first);
|
|
47639
|
-
webwixOwnerInstances.invalidate(msid, cookie);
|
|
47640
|
-
const fresh = await webwixOwnerInstances.instance(msid, cookie);
|
|
47641
|
-
return json3(200, await wixVisitorCall(method, reqPath, body, fresh, webwixFetch, forwardedHeaders));
|
|
47642
|
-
} catch (e) {
|
|
47643
|
-
const msg = String(e?.message ?? e);
|
|
47644
|
-
if (msg.includes("absolute URLs")) {
|
|
47645
|
-
return absoluteUrlRejection(reqPath) === "owner-only" ? json3(501, { error: "webwix_owner_only", app: app2 }) : json3(400, { error: "absolute_urls_not_allowed" });
|
|
47646
|
-
}
|
|
47647
|
-
if (msg.includes("owner mint failed")) {
|
|
47648
|
-
if (/owner mint failed \(5\d\d\)/.test(msg)) return json3(502, { error: "webwix_bridge_upstream_failed" });
|
|
47649
|
-
return json3(501, { error: "webwix_owner_mint_failed", app: app2 });
|
|
47650
|
-
}
|
|
47651
|
-
return json3(502, { error: "webwix_bridge_upstream_failed", detail: msg.slice(0, 200) });
|
|
47652
|
-
}
|
|
47860
|
+
if (!webwixOwnerRungOn()) return json3(503, { error: "webwix_owner_disabled" });
|
|
47861
|
+
return json3(501, { error: "webwix_owner_direct_only", app: app2 });
|
|
47653
47862
|
}
|
|
47654
47863
|
const resolved2 = wixClientIdOf(utf8Decode(cfgBytes));
|
|
47655
47864
|
if ("error" in resolved2) {
|
|
@@ -47666,28 +47875,11 @@ ${releaseId}`;
|
|
|
47666
47875
|
try {
|
|
47667
47876
|
return json3(200, await wixVisitorCall(method, reqPath, body, memberToken, webwixFetch, forwardedHeaders), { "cache-control": "no-store" });
|
|
47668
47877
|
} catch (e) {
|
|
47669
|
-
|
|
47670
|
-
if (msg.includes("absolute URLs")) {
|
|
47671
|
-
return absoluteUrlRejection(reqPath) === "owner-only" ? json3(501, { error: "webwix_owner_only", app: app2 }) : json3(400, { error: "absolute_urls_not_allowed" });
|
|
47672
|
-
}
|
|
47673
|
-
return json3(502, { error: "webwix_bridge_upstream_failed", detail: msg.slice(0, 200) });
|
|
47878
|
+
return json3(502, { error: "webwix_bridge_upstream_failed", detail: String(e?.message ?? e).slice(0, 200) });
|
|
47674
47879
|
}
|
|
47675
47880
|
}
|
|
47676
47881
|
}
|
|
47677
|
-
|
|
47678
|
-
const token = await webwixTokens.token(resolved2.clientId);
|
|
47679
|
-
const first = await wixVisitorCall(method, reqPath, body, token, webwixFetch, forwardedHeaders);
|
|
47680
|
-
if (first.status !== 401) return json3(200, first);
|
|
47681
|
-
webwixTokens.invalidate(resolved2.clientId);
|
|
47682
|
-
const fresh = await webwixTokens.token(resolved2.clientId);
|
|
47683
|
-
return json3(200, await wixVisitorCall(method, reqPath, body, fresh, webwixFetch, forwardedHeaders));
|
|
47684
|
-
} catch (e) {
|
|
47685
|
-
const msg = String(e?.message ?? e);
|
|
47686
|
-
if (msg.includes("absolute URLs")) {
|
|
47687
|
-
return absoluteUrlRejection(reqPath) === "owner-only" ? json3(501, { error: "webwix_owner_only", app: app2 }) : json3(400, { error: "absolute_urls_not_allowed" });
|
|
47688
|
-
}
|
|
47689
|
-
return json3(502, { error: "webwix_bridge_upstream_failed", detail: msg.slice(0, 200) });
|
|
47690
|
-
}
|
|
47882
|
+
return json3(501, { error: "webwix_visitor_direct_only", app: app2 });
|
|
47691
47883
|
})();
|
|
47692
47884
|
status = res.status;
|
|
47693
47885
|
return res;
|
|
@@ -48271,7 +48463,7 @@ function indexHtml(asset, pathname, creds, handoverAttempted = false) {
|
|
|
48271
48463
|
void pathname;
|
|
48272
48464
|
const nonce = scriptNonce();
|
|
48273
48465
|
const raw = new TextDecoder().decode(assetBytes(asset));
|
|
48274
|
-
const head = `<script nonce="${nonce}">${PREVIEW_BASE_JS}</script>` + (creds ? `<script nonce="${nonce}">${previewCredentialsJs(creds)}</script>` : handoverAttempted ? `<script nonce="${nonce}">${stripHandoverParamJs()}</script>` : "");
|
|
48466
|
+
const head = `<script nonce="${nonce}">${PREVIEW_BASE_JS}</script><script nonce="${nonce}">${PREVIEW_ENTRY_RECOVERY_JS}</script>` + (creds ? `<script nonce="${nonce}">${previewCredentialsJs(creds)}</script>` : handoverAttempted ? `<script nonce="${nonce}">${stripHandoverParamJs()}</script>` : "");
|
|
48275
48467
|
const html = raw.replace(/(=|url\()(["']?)\/preview\//g, "$1$2").replace(/<head(\s[^>]*)?>/i, (tag) => `${tag}${head}`);
|
|
48276
48468
|
return new Response(html, {
|
|
48277
48469
|
status: 200,
|
|
@@ -48323,7 +48515,7 @@ function previewResponse(pathname, assets, mount = "/preview", creds, handoverAt
|
|
|
48323
48515
|
headers: { "content-type": "application/json; charset=utf-8" }
|
|
48324
48516
|
});
|
|
48325
48517
|
}
|
|
48326
|
-
var T5_FRAME_CSP, PREVIEW_BASE_JS, MOUNT_STRIP;
|
|
48518
|
+
var T5_FRAME_CSP, PREVIEW_BASE_JS, PREVIEW_ENTRY_RECOVERY_JS, MOUNT_STRIP;
|
|
48327
48519
|
var init_preview2 = __esm({
|
|
48328
48520
|
"../../packages/serve/src/preview.ts"() {
|
|
48329
48521
|
T5_FRAME_CSP = "default-src 'none'; script-src 'unsafe-inline' 'unsafe-eval'; connect-src 'none'; img-src 'none'; media-src 'none'; style-src 'unsafe-inline'; base-uri 'none'; form-action 'none'";
|
|
@@ -48332,6 +48524,7 @@ var init_preview2 = __esm({
|
|
|
48332
48524
|
// the EARLIEST mount segment wins, mirroring the SPA's own deployBase (an app literally
|
|
48333
48525
|
// named "app" — /preview/a/app — must not hijack the base).
|
|
48334
48526
|
'(function(){var m=location.pathname.match(/^(.*?\\/(?:preview|app))(?:\\/|$)/);var b=document.createElement("base");b.href=(m?m[1]:"")+"/";document.head.insertBefore(b,document.head.firstChild)})();';
|
|
48527
|
+
PREVIEW_ENTRY_RECOVERY_JS = '(function(){var K="himalaya.preview.entryReload";function show(){if(document.getElementById("himalaya-preview-load-failed"))return;var d=document.createElement("div");d.id="himalaya-preview-load-failed";d.setAttribute("role","alert");d.style.cssText="position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:border-box;padding:32px;text-align:center;font:15px/1.5 system-ui,sans-serif;background:#f5f7fa;color:#111";var p=document.createElement("p");p.textContent="This app couldn\\u2019t load \\u2014 a new version may have just been published.";var b=document.createElement("button");b.type="button";b.textContent="Reload";b.addEventListener("click",function(){location.reload()});d.appendChild(p);d.appendChild(b);(document.body||document.documentElement).appendChild(d)}function failed(){var now=Date.now(),last=0;try{last=+sessionStorage.getItem(K)||0}catch(e){}if(now-last>60000){try{sessionStorage.setItem(K,String(now));location.reload();return}catch(e){}}if(document.body)show();else document.addEventListener("DOMContentLoaded",show)}window.addEventListener("error",function(e){var t=e&&e.target;if(t&&t.tagName==="SCRIPT"&&t.type==="module")failed()},true)})();';
|
|
48335
48528
|
MOUNT_STRIP = {
|
|
48336
48529
|
// Precompiled — this runs on every request of the public serving hot path.
|
|
48337
48530
|
"/preview": /^\/preview\/?/,
|
|
@@ -48578,21 +48771,21 @@ var init_preview_assets_generated = __esm({
|
|
|
48578
48771
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
48579
48772
|
init_preview_assets_format();
|
|
48580
48773
|
PREVIEW_ASSET_MANIFEST = [
|
|
48581
|
-
{ key: "assets/index-
|
|
48582
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
48583
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
48584
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
48585
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
48586
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
48587
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
48588
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
48589
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
48590
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
48591
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
48592
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
48593
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
48594
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
48595
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
48774
|
+
{ key: "assets/index-hHpGDjBZ.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1038931, sha256: "65ef206c528bdc3e9b7ec6907e734267cd225ed33513982c46ecb3bbdd6d44ee" },
|
|
48775
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1038939, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
48776
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1043549, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
48777
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1532133, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
48778
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1623057, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
48779
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1714041, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
48780
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1805021, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
48781
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1895893, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
48782
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 1986873, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
48783
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2095509, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
48784
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2204593, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
48785
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2313641, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
48786
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2421341, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
48787
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 2509449, length: 4947, sha256: "f07de6435f49d7608a56b7af529229f2ccc10901ab33a9e600e01f10b60975d6" },
|
|
48788
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2514396, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
|
|
48596
48789
|
];
|
|
48597
48790
|
}
|
|
48598
48791
|
});
|
|
@@ -48608,7 +48801,7 @@ __export(run_exports, {
|
|
|
48608
48801
|
runPackage: () => runPackage,
|
|
48609
48802
|
withoutProdServe: () => withoutProdServe
|
|
48610
48803
|
});
|
|
48611
|
-
import { cpSync as cpSync2, existsSync as existsSync52, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync3, readFileSync as readFileSync58, rmSync as
|
|
48804
|
+
import { cpSync as cpSync2, existsSync as existsSync52, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync3, readFileSync as readFileSync58, rmSync as rmSync12, statSync as statSync13 } from "node:fs";
|
|
48612
48805
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
48613
48806
|
import { dirname as dirname27, join as join50 } from "node:path";
|
|
48614
48807
|
import { fileURLToPath as fileURLToPath22 } from "node:url";
|
|
@@ -48644,7 +48837,7 @@ async function resolvePackage(source, workDir) {
|
|
|
48644
48837
|
const target = join50(root2, app2);
|
|
48645
48838
|
if (join50(source) !== target) {
|
|
48646
48839
|
mkdirSync25(root2, { recursive: true });
|
|
48647
|
-
|
|
48840
|
+
rmSync12(target, { recursive: true, force: true });
|
|
48648
48841
|
cpSync2(source, target, { recursive: true });
|
|
48649
48842
|
}
|
|
48650
48843
|
return {
|
|
@@ -48664,7 +48857,7 @@ async function resolvePackage(source, workDir) {
|
|
|
48664
48857
|
const { app, appDir: appDir2 } = unpackTo(bytes2, root);
|
|
48665
48858
|
const opened = openPackageDir(appDir2);
|
|
48666
48859
|
if (!opened.validation.ok) {
|
|
48667
|
-
|
|
48860
|
+
rmSync12(workDir ? appDir2 : root, { recursive: true, force: true });
|
|
48668
48861
|
throw new Error(`package is not valid:
|
|
48669
48862
|
${opened.validation.errors.join("\n ")}`);
|
|
48670
48863
|
}
|
|
@@ -48711,7 +48904,7 @@ async function runPackage(source, opts = {}) {
|
|
|
48711
48904
|
const resolved2 = await resolvePackage(source, opts.workDir);
|
|
48712
48905
|
const assets = opts.assets ?? (opts.spa ? /* @__PURE__ */ new Map() : await loadPreviewAssets());
|
|
48713
48906
|
if (!opts.spa && assets.size === 0) {
|
|
48714
|
-
if (resolved2.temp)
|
|
48907
|
+
if (resolved2.temp) rmSync12(resolved2.temp, { recursive: true, force: true });
|
|
48715
48908
|
throw new Error(NO_SPA_MESSAGE);
|
|
48716
48909
|
}
|
|
48717
48910
|
const plane = makePackageRunHandler({
|
|
@@ -48747,7 +48940,7 @@ async function runPackage(source, opts = {}) {
|
|
|
48747
48940
|
close: () => new Promise((done) => {
|
|
48748
48941
|
server.closeAllConnections?.();
|
|
48749
48942
|
server.close(() => {
|
|
48750
|
-
if (resolved2.temp)
|
|
48943
|
+
if (resolved2.temp) rmSync12(resolved2.temp, { recursive: true, force: true });
|
|
48751
48944
|
done();
|
|
48752
48945
|
});
|
|
48753
48946
|
})
|
|
@@ -48785,7 +48978,7 @@ __export(run_watch_exports, {
|
|
|
48785
48978
|
watchedContentDir: () => watchedContentDir,
|
|
48786
48979
|
writeRunRecord: () => writeRunRecord
|
|
48787
48980
|
});
|
|
48788
|
-
import { closeSync as closeSync2, constants, existsSync as existsSync53, fstatSync, lstatSync as lstatSync8, statSync as statSync14, mkdirSync as mkdirSync26, openSync as openSync2, readFileSync as readFileSync59, realpathSync as realpathSync6, renameSync as renameSync5, rmSync as
|
|
48981
|
+
import { closeSync as closeSync2, constants, existsSync as existsSync53, fstatSync, lstatSync as lstatSync8, statSync as statSync14, mkdirSync as mkdirSync26, openSync as openSync2, readFileSync as readFileSync59, realpathSync as realpathSync6, renameSync as renameSync5, rmSync as rmSync13, writeFileSync as writeFileSync22, watch as fsWatch } from "node:fs";
|
|
48789
48982
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
48790
48983
|
import { extname as extname4, join as join51, resolve as resolve42, sep as sep13 } from "node:path";
|
|
48791
48984
|
function diffReleases(prev, next) {
|
|
@@ -48923,7 +49116,7 @@ function writeRunRecord(dir, record2) {
|
|
|
48923
49116
|
`, { flag: "wx" });
|
|
48924
49117
|
renameSync5(tmp, join51(root, "run.json"));
|
|
48925
49118
|
} catch (e) {
|
|
48926
|
-
|
|
49119
|
+
rmSync13(tmp, { force: true });
|
|
48927
49120
|
throw e;
|
|
48928
49121
|
}
|
|
48929
49122
|
return true;
|
|
@@ -48944,7 +49137,7 @@ function removeRunRecord(dir, owner) {
|
|
|
48944
49137
|
}
|
|
48945
49138
|
if (typeof pid === "number" && pid !== owner) return;
|
|
48946
49139
|
}
|
|
48947
|
-
|
|
49140
|
+
rmSync13(join51(root, "run.json"), { force: true });
|
|
48948
49141
|
}
|
|
48949
49142
|
function boardFile(dir, pathname) {
|
|
48950
49143
|
let rel = null;
|
|
@@ -60012,7 +60205,7 @@ var init_context = __esm({
|
|
|
60012
60205
|
});
|
|
60013
60206
|
|
|
60014
60207
|
// src/cli.ts
|
|
60015
|
-
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync72, mkdirSync as mkdirSync30, writeFileSync as writeFileSync28, existsSync as existsSync60, rmSync as
|
|
60208
|
+
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync72, mkdirSync as mkdirSync30, writeFileSync as writeFileSync28, existsSync as existsSync60, rmSync as rmSync14, readdirSync as readdirSync27, statSync as statSync17, lstatSync as lstatSync9, accessSync, constants as constants2, renameSync as renameSync6, cpSync as cpSync3 } from "node:fs";
|
|
60016
60209
|
import { execFile, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn6 } from "node:child_process";
|
|
60017
60210
|
import { createHash as createHash27, randomUUID as randomUUID5 } from "node:crypto";
|
|
60018
60211
|
import { tmpdir as tmpdir5, homedir as homedir7, hostname } from "node:os";
|
|
@@ -63403,9 +63596,10 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
63403
63596
|
(--ai writes rows for you to review first)
|
|
63404
63597
|
himi secrets set|list|rotate --app <app> --name <name> [--environment preview|production]
|
|
63405
63598
|
encrypted secret metadata; set/rotate read the value from stdin
|
|
63406
|
-
himi render <screenId> [--content <dir>] [--scheme dark] [--png <file>] [--tree] [--dump-state] [--static] [--live] [--state <json|file>] [--input <json|file>] [--width <px> | --device <name>] [--rtl] [--load-budget <ms>]
|
|
63599
|
+
himi render <screenId> [--content <dir>] [--scheme dark] [--png [<file>]] [--tree] [--dump-state] [--static] [--live] [--state <json|file>] [--input <json|file>] [--width <px> | --device <name>] [--rtl] [--load-budget <ms>]
|
|
63407
63600
|
[--remote --app <app> --release <id>]
|
|
63408
63601
|
headless web render + diagnostics (no sim). Default: local content dir.
|
|
63602
|
+
A bare --png writes .himi/shots/<screenId>.png (what the build board shows).
|
|
63409
63603
|
--remote fetches GET /v1/preview/\u2026/render from the serve plane (post-push).
|
|
63410
63604
|
It returns the pushed descriptor STRUCTURE only \u2014 NO png and NO live data
|
|
63411
63605
|
(the serve has no headless browser); for a pixel view or REAL fetched data
|
|
@@ -63584,7 +63778,9 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
63584
63778
|
plane, no dev-server. With no argument it packs the current
|
|
63585
63779
|
content package first \u2014 edit, run, look at it.
|
|
63586
63780
|
--watch rebuilds on every save and repaints the open tab
|
|
63587
|
-
(a failed build keeps the last good preview).
|
|
63781
|
+
(a failed build keeps the last good preview). The build board
|
|
63782
|
+
is served beside it at /__himi/studio/ with the preview framed
|
|
63783
|
+
in it. Blocks until Ctrl-C.
|
|
63588
63784
|
himi flags list|set|ramp|rm [<key>] [--app <a>]
|
|
63589
63785
|
read/change operational flags (RFC 0013); writes report
|
|
63590
63786
|
servedNow from the device door, never just ok
|
|
@@ -63911,7 +64107,7 @@ var COMMANDS = [
|
|
|
63911
64107
|
{ name: "ux", summary: "audit or record mobile UX evidence. `audit` checks the public-safe contract, seeded blank acceptance rows, placeholder source copy, app-specific mocks, and iOS/Android audit records. It warns while existing templates migrate; `--strict` promotes missing evidence. `record` stores checks performed on an installed iOS/Android build: `--checks` is required for passed|failed and empty for unavailable, which drove nothing and needs a `--reason` instead. `record` also STAMPS the release it audited (it resolves the id from a build, the same one a push would publish), because an unforced `himi push` of a release with screens refuses when no drive is recorded for THAT release, or when the one that is recorded says `failed` \u2014 the artifact stopped being advice nobody reads (#2955). `unavailable` still satisfies it; only `failed` refuses.", required: "audit [--content <dir>] [--strict] [--json] | record --content <dir> --platform ios|android --status passed|failed|unavailable [--checks back,keyboard,...] [--reason <text>]" },
|
|
63912
64108
|
{ name: "progress", summary: 'the build JOURNAL an agent keeps for the owner while it works. `himi progress "<what changed>" --step <1-8|name> --image <png>` appends one postcard to .himi/progress.jsonl \u2014 the step is one of the customer journey\'s eight (discover, classify, plan, implement, brand, validate, review, download) \u2014 and COPIES each image, content-addressed, into .himi/history/, because .himi/shots/ is overwritten by every render and cleared by every full `himi test`, so a path into it would later show a different picture than the one the owner was sent. --image repeats. --notify also raises a best-effort desktop notification for an owner who stepped away. A bare `himi progress` prints the journal with the current step and elapsed time \u2014 also how an agent recovers its place after its context was compacted. Local only: nothing is sent anywhere.', required: '["<message>" [--step <1-8|name>] [--image <png>]\u2026 [--notify]] [--content <dir>]' },
|
|
63913
64109
|
{ name: "studio", summary: "open the BUILD BOARD \u2014 one local page the owner can leave open while an agent builds their app, which fills itself in: every screen as it renders (NEW/CHANGED badges, and each earlier version kept for a filmstrip), the journey stepper and the latest postcard from `himi progress`, the validate/test/UX/draft checks as they run, the site next to the app's home screen with its palette, and the navigation the test crawl followed. Writes .himi/studio/index.html and opens it; the page re-reads its state every two seconds, so nothing needs to be served. OPT-IN BY EXISTENCE: until this command has run, no other command touches .himi/studio/ \u2014 after it, render/test/validate/push/icon/site/ux/progress each refresh the board as they finish (best-effort; never fails a command). Every image is a content-addressed copy in .himi/history/, never a live path into .himi/shots/. Local only, no secrets: it never reads a preview token, handover code or control token. --no-open prints the path instead (SSH, CI). `himi studio reel` writes the MAKING-OF: one self-contained HTML file (every image inlined, nothing fetched) with a flipbook of the home screen version by version, captioned by the postcard in effect at the time, the final screens, and every postcard \u2014 sized to stay attachable, thinning frames first. Defaults to .himi/making-of.html (never archived by push); --out to put it elsewhere.", required: "[--content <dir>] [--no-open] | reel [--out <file>] [--no-open]" },
|
|
63914
|
-
{ name: "render", summary: "headless-render a screen with the web renderer: render-tree + diagnostics, optional --png <file
|
|
64110
|
+
{ name: "render", summary: "headless-render a screen with the web renderer: render-tree + diagnostics, optional --png [<file>] (bare: .himi/shots/<id>.png, what the build board shows), --scheme dark, --tree. Local by default (content dir). Pass --remote --app --release to hit GET /v1/preview/\u2026/render on the serve plane after a push. Boots the worker so $service bindings resolve; --static raw bindings; --live real Wix fetches; --state injects worker state; --input supplies pre-boot navigation params; --width/--device for PNG viewport; --rtl for dir=rtl + $env:isRTL.", required: "<screenId> [--content <dir>] [--scheme dark] [--png [<file>]] [--tree] [--static] [--live] [--state <json|file>] [--input <json|file>] [--width <px> | --device <name>] [--rtl] [--remote --app --release]" },
|
|
63915
64111
|
{ name: "cms", summary: "inspect, provision, and seed the app's CMS (Wix Data) collections, declared as a `cms` block in config.ts. `query` is READ-ONLY \u2014 by default it fetches ONLY the physical ids `config.ts` declares (item counts + schema drift) and reports `siteScanned: false`; it never lists the site, so an UNDECLARED `himi_<app>_` collection this app owns is not reached without `--all`. `--all` SCANS the site \u2014 every collection it lists is labeled `owned`/`adopted`/`foreign`, and it describes every foreign one \u2014 id, non-system field keys + types, and the site's read role \u2014 so an app with no `cms` block at all can DISCOVER a collection to adopt (`--all` is the one case where a missing `cms` block is not 'nothing to do'). Foreign collections are described up to a cap and are never item-counted (`itemCount: null`), because a row count is one query each; `foreign.count` is how many the scan LISTED \u2014 it follows the list endpoint's pages, and `listingIncomplete: true` says when the walk stopped short of the end, with `unlistedCollections` counting what it left out when Wix gave a paging total \u2014 and `foreign.truncated` says how many of those went undescribed, each still NAMED in `foreign.others` (id + displayName), so a collection the site already has is never hidden behind the cap. The scan is OWNER-scoped \u2014 it needs --site <msid> (or WIX_SITE_ID) plus owner auth via `wix token`; a visitor token can read a public collection's ITEMS but can never enumerate collections, so there is no tokenless discovery path. `create` reconciles declared collections additively and idempotently, and REFUSES any id outside the app's `himi_<app>_` namespace, so it is safe against a production site. It reports declared-vs-site `permissionDrift` but never writes permissions unless asked with --apply-permissions, so a field reconcile can't silently revert access control changed in the dashboard. `seed` inserts the git-tracked `seed:` rows into EMPTY owned collections (--force to add to a non-empty one; --ai writes placeholder rows plus a refinement prompt for you to review). Adopted collections (declared by `wixId`) are read-only and never created, updated, or seeded. Site from --site <msid> or WIX_SITE_ID; owner auth via `wix token`.", required: "query|create|seed [--site <msid>] [--content <dir>] [--all] [--dry-run] [--force] [--allow-destructive] [--apply-permissions] [--only <id>] [--ai] [--count <n>]" },
|
|
63916
64112
|
{ name: "data", summary: "read-only plan or explicitly provision/seed declared KV and Wix Data resources. Preview and production are separate scopes. KV administration uses the operator data plane from --data-url/HIMI_DATA_ADMIN_URL and HIMI_DATA_ADMIN_TOKEN; draft push never calls it.", required: "plan|create|seed [--site <msid>] [--environment preview|production] [--content <dir>] [--data-url <url>] [--dry-run] [--force]" },
|
|
63917
64113
|
{ name: "icons", summary: "list the valid Icon.name vocabulary (an unknown name renders a fallback glyph; validate warns on unknown names) (offline)", required: "[--json]" },
|
|
@@ -64305,7 +64501,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
64305
64501
|
};
|
|
64306
64502
|
const removeIfMine = (path2) => {
|
|
64307
64503
|
try {
|
|
64308
|
-
if (readLock(path2) === mine)
|
|
64504
|
+
if (readLock(path2) === mine) rmSync14(path2, { force: true });
|
|
64309
64505
|
} catch {
|
|
64310
64506
|
}
|
|
64311
64507
|
};
|
|
@@ -64328,7 +64524,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
64328
64524
|
hooks.underBreakLock?.();
|
|
64329
64525
|
if (current === void 0) return tryCreate(lockPath) ? release : void 0;
|
|
64330
64526
|
if (!isAbandoned(current)) return void 0;
|
|
64331
|
-
|
|
64527
|
+
rmSync14(lockPath, { force: true });
|
|
64332
64528
|
return tryCreate(lockPath) ? release : void 0;
|
|
64333
64529
|
} finally {
|
|
64334
64530
|
removeIfMine(breakPath);
|
|
@@ -65078,13 +65274,13 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
65078
65274
|
if (!entry.isDirectory()) continue;
|
|
65079
65275
|
const pid = Number(entry.name.startsWith(`${slug}-`) ? entry.name.slice(slug.length + 1) : NaN);
|
|
65080
65276
|
if (Number.isInteger(pid) && pid > 0 && pid !== process.pid && !stillRunning(pid)) {
|
|
65081
|
-
|
|
65277
|
+
rmSync14(join57(root, entry.name), { recursive: true, force: true });
|
|
65082
65278
|
}
|
|
65083
65279
|
}
|
|
65084
65280
|
} catch {
|
|
65085
65281
|
}
|
|
65086
65282
|
const dest = join57(root, `${slug}-${process.pid}`);
|
|
65087
|
-
|
|
65283
|
+
rmSync14(dest, { recursive: true, force: true });
|
|
65088
65284
|
mkdirSync30(dest, { recursive: true });
|
|
65089
65285
|
materializeSource(forBuild, displayName, dest, slug);
|
|
65090
65286
|
return dest;
|
|
@@ -65338,7 +65534,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
|
|
|
65338
65534
|
return null;
|
|
65339
65535
|
} finally {
|
|
65340
65536
|
if (out !== void 0) try {
|
|
65341
|
-
|
|
65537
|
+
rmSync14(out, { recursive: true, force: true });
|
|
65342
65538
|
} catch {
|
|
65343
65539
|
}
|
|
65344
65540
|
}
|
|
@@ -66844,7 +67040,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
66844
67040
|
renderDescriptorWeb: renderDescriptorWeb2,
|
|
66845
67041
|
renderPngBatch: renderPngBatch2,
|
|
66846
67042
|
writePng: (path2, base64) => writePngFile(path2, base64),
|
|
66847
|
-
clearDir: (d) =>
|
|
67043
|
+
clearDir: (d) => rmSync14(d, { recursive: true, force: true })
|
|
66848
67044
|
}
|
|
66849
67045
|
});
|
|
66850
67046
|
writtenShots = sp.written;
|
|
@@ -68066,7 +68262,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
68066
68262
|
...await navIssues2(dir, strict)
|
|
68067
68263
|
]);
|
|
68068
68264
|
if (hasErrors && !force) {
|
|
68069
|
-
|
|
68265
|
+
rmSync14(built, { recursive: true, force: true });
|
|
68070
68266
|
print({ ...report2, packed: false, hint: "lint found errors \u2014 fix them, or re-run `himi pack --force` to pack anyway" });
|
|
68071
68267
|
return 1;
|
|
68072
68268
|
}
|
|
@@ -68102,7 +68298,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
68102
68298
|
io.error(JSON.stringify({ error: e.message }));
|
|
68103
68299
|
return 1;
|
|
68104
68300
|
} finally {
|
|
68105
|
-
|
|
68301
|
+
rmSync14(built, { recursive: true, force: true });
|
|
68106
68302
|
}
|
|
68107
68303
|
}
|
|
68108
68304
|
// ---- himi import — turn a dev .himi back into an editable content package ----
|
|
@@ -68418,7 +68614,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
68418
68614
|
return;
|
|
68419
68615
|
}
|
|
68420
68616
|
const hasWorkers = bres.built.length > 0;
|
|
68421
|
-
const outcome = await buildReleaseFromContent2(dir, next, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {} });
|
|
68617
|
+
const outcome = await buildReleaseFromContent2(dir, next, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, freshModule: true });
|
|
68422
68618
|
const blocker = watchKit.rebuildBlocker(outcome, servedMissing);
|
|
68423
68619
|
if (blocker) {
|
|
68424
68620
|
await failed2(blocker);
|
|
@@ -68434,17 +68630,17 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
68434
68630
|
} catch {
|
|
68435
68631
|
cpSync3(join57(next, running.app), live2, { recursive: true });
|
|
68436
68632
|
}
|
|
68437
|
-
|
|
68633
|
+
rmSync14(retired, { recursive: true, force: true });
|
|
68438
68634
|
current = fresh;
|
|
68439
68635
|
servedMissing = outcome.missingBundles;
|
|
68440
68636
|
for (const [event, data] of watchKit.reloadEvents(diff)) bus.publish(event, data);
|
|
68441
|
-
record2(running, { ok: true, at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
68637
|
+
record2(running, { ok: true, at: (/* @__PURE__ */ new Date()).toISOString(), ms: Date.now() - t0, screens: diff.screens, tokens: diff.tokens, config: diff.config });
|
|
68442
68638
|
await refreshBoard();
|
|
68443
68639
|
io.error(JSON.stringify({ watch: "rebuilt", ms: Date.now() - t0, screens: diff.screens, tokens: diff.tokens, config: diff.config, tabs: bus.listeners }));
|
|
68444
68640
|
} catch (e) {
|
|
68445
68641
|
await failed2(e.message.split("\n")[0]);
|
|
68446
68642
|
} finally {
|
|
68447
|
-
|
|
68643
|
+
rmSync14(next, { recursive: true, force: true });
|
|
68448
68644
|
}
|
|
68449
68645
|
});
|
|
68450
68646
|
watcher = watchKit.watchContent(dir, () => rebuild?.());
|
|
@@ -68488,8 +68684,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
68488
68684
|
io.error(JSON.stringify({ error: e.message }));
|
|
68489
68685
|
return 1;
|
|
68490
68686
|
} finally {
|
|
68491
|
-
if (temp)
|
|
68492
|
-
if (served)
|
|
68687
|
+
if (temp) rmSync14(temp, { recursive: true, force: true });
|
|
68688
|
+
if (served) rmSync14(served, { recursive: true, force: true });
|
|
68493
68689
|
}
|
|
68494
68690
|
}
|
|
68495
68691
|
case "preview": {
|