@wix/himalaya-cli 0.1541.0 → 0.1543.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.
@@ -103,4 +103,8 @@ export declare function handleWixGateway(gw: WixGatewayState, app: string, admin
103
103
  /** The ACTIVE app's own Wix clientId (loader.resolveWixClientId) — the mint-retry
104
104
  * below mints an anonymous visitor token from it so each app hits its OWN site.
105
105
  * Falls back to WIX_DEV_CLIENT_ID (env / amit1 default) when absent. */
106
- wixClientId?: string): Promise<boolean>;
106
+ wixClientId?: string,
107
+ /** The ACTIVE app's MetaSite when it is bound with `visitorSource: "one-app"`: no retry then —
108
+ * it has no clientId to mint from (the fallback is another site), and a One App re-mint would
109
+ * be a new visitor. */
110
+ oneAppMetaSiteId?: string): Promise<boolean>;
@@ -1,5 +1,9 @@
1
1
  /** Mint an anonymous visitor access token for the client. */
2
2
  export declare function mintVisitor(clientId: string): Promise<string>;
3
+ /** The site's One App visitor instance (`visitorSource: "one-app"`) for a one-shot CLI read
4
+ * (`render --live`, `test --record`) — sent bare as `Authorization`, like `mintVisitor`'s token.
5
+ * Node only: no CORS stands in the way here. The dev-server's web sessions keep their own. */
6
+ export declare function mintOneAppVisitorToken(metaSiteId: string): Promise<string>;
3
7
  /** Direct (captcha-free) Wix Headless member login → real member access token. */
4
8
  export declare function memberDirectLogin(clientId: string, redirectUri: string, email: string, password: string): Promise<{
5
9
  memberToken: string;
@@ -14,6 +14,27 @@ export interface WixBridgeEnvelope {
14
14
  * one per pod any more — the one server-side use left is the member-login redirect, which needs a
15
15
  * visitor token to build Wix's hosted-login URL once per login. */
16
16
  export declare function mintAnonymousVisitor(clientId: string, fetchImpl?: typeof fetch): Promise<string>;
17
+ /** A One App visitor signed instance and the time Wix stops honouring it (`validUntil`). */
18
+ export interface OneAppVisitorInstance {
19
+ instance: string;
20
+ expiresAt: number;
21
+ }
22
+ /**
23
+ * The site's One App VISITOR signed instance — the anonymous identity a Branded One App visitor
24
+ * uses (`WixConsumerAuthProvider({ visitorSource: "one-app", metaSiteId })`). Needs no credential
25
+ * and no OAuth client on the site. Sent to wixapis.com as a bare `Authorization` value: `Bearer
26
+ * <instance>` is a 400. Each mint is a NEW visitor, so callers keep it until `expiresAt`.
27
+ * Server-side only for the browser: the endpoint sends no CORS headers.
28
+ */
29
+ export declare function mintOneAppVisitor(msid: string, fetchImpl?: typeof fetch, timeoutMs?: number): Promise<OneAppVisitorInstance>;
30
+ /** The MetaSite an auth provider binds through the One App visitor identity
31
+ * (`WixConsumerAuthProvider({ visitorSource: "one-app", metaSiteId })`), or null. */
32
+ export declare function oneAppMetaSiteIdOf(auth: {
33
+ providerId?: unknown;
34
+ config?: unknown;
35
+ } | null | undefined): string | null;
36
+ /** The same, read off a published app-config's `authConfig`. */
37
+ export declare function oneAppVisitorMsidOf(appConfigJson: string): string | null;
17
38
  /**
18
39
  * Proxy one REST call to wixapis.com with the given token. `path` must be
19
40
  * origin-relative — an absolute URL is the caller trying to use the bridge as an
@@ -42,8 +42,18 @@ export interface MemberCaptchaKey {
42
42
  siteKeyId: string;
43
43
  }
44
44
  export interface WixConsumerAuthConfig {
45
- /** Per-site Wix Headless OAuth client id. */
46
- clientId: string;
45
+ /** Per-site Wix Headless OAuth client id. Required unless `visitorSource` is `"one-app"`;
46
+ * there it is optional and only enables member sign-in. */
47
+ clientId?: string;
48
+ /** Where the anonymous visitor credential comes from. `"oauth"` (default) mints
49
+ * `POST /oauth2/token {clientId, grantType:"anonymous"}` and needs a Headless OAuth client on
50
+ * the site. `"one-app"` mints the site's One App visitor signed instance
51
+ * (`GET apps.wix.com/_api/one-app-session-web/v3/businesses/<metaSiteId>/signed-instance
52
+ * ?signed_instance_type=Visitor`), the same identity a Branded One App visitor uses, so a
53
+ * migrated One App binds to its site WITHOUT creating anything on it. Requires `metaSiteId`. */
54
+ visitorSource?: "oauth" | "one-app";
55
+ /** The site's MetaSite ID. Required when `visitorSource` is `"one-app"`. */
56
+ metaSiteId?: string;
47
57
  /** Wix site binding for native CAPTCHA configuration. */
48
58
  siteId?: string;
49
59
  /** Public identifiers only. Never supply the server app secret here. */
@@ -53,8 +63,8 @@ export interface WixConsumerAuthConfig {
53
63
  };
54
64
  /** Site root URL — e.g. "https://example.wix.com/cafe". */
55
65
  siteUrl: string;
56
- /** Custom URL scheme for the member-login redirect. */
57
- redirectUri: string;
66
+ /** Custom URL scheme for the member-login redirect. Required whenever `clientId` is set. */
67
+ redirectUri?: string;
58
68
  /**
59
69
  * Where the password-reset email's link lands. Must be an http(s) WEB url:
60
70
  * IAM recovery shortens it into the mail body, so `redirectUri` — an app scheme
@@ -1194,14 +1194,22 @@ function isWebUrl(value) {
1194
1194
  return false;
1195
1195
  }
1196
1196
  }
1197
+ var META_SITE_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1197
1198
  function WixConsumerAuthProvider(config) {
1198
- if (!config.clientId) {
1199
+ const oneApp = config.visitorSource === "one-app";
1200
+ if (config.visitorSource !== void 0 && config.visitorSource !== "oauth" && !oneApp) {
1201
+ throw new Error('WixConsumerAuthProvider: visitorSource must be "oauth" or "one-app".');
1202
+ }
1203
+ if (oneApp && !META_SITE_ID.test(config.metaSiteId ?? "")) {
1204
+ throw new Error(`WixConsumerAuthProvider: visitorSource "one-app" requires metaSiteId (the site's MetaSite ID).`);
1205
+ }
1206
+ if (!oneApp && !config.clientId) {
1199
1207
  throw new Error("WixConsumerAuthProvider: clientId is required.");
1200
1208
  }
1201
1209
  if (!config.siteUrl) {
1202
1210
  throw new Error("WixConsumerAuthProvider: siteUrl is required.");
1203
1211
  }
1204
- if (!config.redirectUri) {
1212
+ if (config.clientId && !config.redirectUri) {
1205
1213
  throw new Error("WixConsumerAuthProvider: redirectUri is required.");
1206
1214
  }
1207
1215
  if (config.passwordResetUrl && !isWebUrl(config.passwordResetUrl)) {
@@ -1209,16 +1217,17 @@ function WixConsumerAuthProvider(config) {
1209
1217
  `WixConsumerAuthProvider: passwordResetUrl must be an http(s) web URL with a host (got "${config.passwordResetUrl}") \u2014 the reset email's link cannot be an app scheme.`
1210
1218
  );
1211
1219
  }
1212
- if (!config.siteId) {
1220
+ if (!config.siteId && config.clientId) {
1213
1221
  const siteId = pairedEnvSiteId(config.clientId);
1214
1222
  if (siteId) config = { ...config, siteId };
1215
1223
  }
1216
1224
  return {
1217
1225
  providerId: "wix-consumer",
1218
1226
  config: {
1219
- clientId: config.clientId,
1227
+ ...config.clientId ? { clientId: config.clientId } : {},
1228
+ ...oneApp ? { visitorSource: "one-app", metaSiteId: config.metaSiteId.toLowerCase() } : {},
1220
1229
  siteUrl: config.siteUrl,
1221
- redirectUri: config.redirectUri,
1230
+ ...config.redirectUri ? { redirectUri: config.redirectUri } : {},
1222
1231
  bootAsVisitor: config.bootAsVisitor ?? true,
1223
1232
  ...config.passwordResetUrl ? { passwordResetUrl: config.passwordResetUrl } : {},
1224
1233
  preserveVisitorOnSignOut: config.preserveVisitorOnSignOut ?? true,
package/dist/cli.mjs CHANGED
@@ -10189,7 +10189,6 @@ function resolveTranslation(value2, catalog4, sourceCatalog) {
10189
10189
  var BINDING_SIGILS, COLON_SIGILS, BINDING_SIGIL_RE, APP_BINDING_PREFIX, APP_BINDING_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
10190
10190
  var init_bindings = __esm({
10191
10191
  "../../core/ts/src/bindings.ts"() {
10192
- "use strict";
10193
10192
  BINDING_SIGILS = ["service", "flag", "item", "t"];
10194
10193
  COLON_SIGILS = /* @__PURE__ */ new Set(["t"]);
10195
10194
  BINDING_SIGIL_RE = new RegExp(
@@ -12711,7 +12710,6 @@ function webViewOriginAllowed(url, origins) {
12711
12710
  }
12712
12711
  var init_webview_origin = __esm({
12713
12712
  "../../core/ts/src/webview-origin.ts"() {
12714
- "use strict";
12715
12713
  }
12716
12714
  });
12717
12715
 
@@ -27918,6 +27916,39 @@ async function mintAnonymousVisitor(clientId, fetchImpl = fetch) {
27918
27916
  if (res.status !== 200 || !j2.access_token) throw new Error(`visitor mint failed (${res.status})`);
27919
27917
  return j2.access_token;
27920
27918
  }
27919
+ async function mintOneAppVisitor(msid, fetchImpl = fetch, timeoutMs = ONE_APP_VISITOR_MINT_TIMEOUT_MS) {
27920
+ if (!isSafeMsid(msid)) throw new Error("visitor mint failed (bad msid)");
27921
+ const res = await fetchImpl(`${ONE_APP_SESSION}/${encodeURIComponent(msid)}/signed-instance?signed_instance_type=Visitor`, {
27922
+ method: "GET",
27923
+ headers: { Accept: "application/json" },
27924
+ credentials: "omit",
27925
+ redirect: "error",
27926
+ signal: AbortSignal.timeout(timeoutMs)
27927
+ });
27928
+ const text11 = await res.text();
27929
+ let j2 = {};
27930
+ try {
27931
+ j2 = text11 ? JSON.parse(text11) : {};
27932
+ } catch {
27933
+ }
27934
+ const expiresAt = typeof j2.validUntil === "string" ? Date.parse(j2.validUntil) : NaN;
27935
+ if (res.status !== 200 || typeof j2.signedInstance !== "string" || !j2.signedInstance || j2.signedInstanceType !== "Visitor" || !Number.isFinite(expiresAt)) {
27936
+ throw new Error(`visitor mint failed (${res.status})`);
27937
+ }
27938
+ return { instance: j2.signedInstance, expiresAt };
27939
+ }
27940
+ function oneAppMetaSiteIdOf(auth) {
27941
+ const config = auth?.config;
27942
+ if (auth?.providerId !== "wix-consumer" || config?.visitorSource !== "one-app") return null;
27943
+ return typeof config.metaSiteId === "string" && isSafeMsid(config.metaSiteId) ? config.metaSiteId : null;
27944
+ }
27945
+ function oneAppVisitorMsidOf(appConfigJson) {
27946
+ try {
27947
+ return oneAppMetaSiteIdOf(JSON.parse(appConfigJson)?.authConfig);
27948
+ } catch {
27949
+ return null;
27950
+ }
27951
+ }
27921
27952
  async function wixVisitorCall(method, path2, body, token, fetchImpl = fetch, forwardedHeaders = {}) {
27922
27953
  if (/^[a-z][a-z0-9+.-]*:\/\//i.test(path2)) throw new Error("absolute URLs are not allowed");
27923
27954
  const url = `${WIX_API}${path2.startsWith("/") ? path2 : `/${path2}`}`;
@@ -28176,13 +28207,14 @@ async function resolveInviteShortLink(shortId, fetchImpl = fetch, timeoutMs = 15
28176
28207
  }
28177
28208
  return null;
28178
28209
  }
28179
- 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, ACCOUNT_FORWARD_ALLOWLIST, ACCOUNT_JOIN_PATHS, NotSiteMember, AccountSessionExpired, SiteInstanceUnavailable, MEMBER_REFRESH_MARGIN_MS, MEMBER_NEGATIVE_TTL_MS, MEMBER_TRANSIENT_TTL_MS, MemberInstanceCache, MEMBER_SESSION_URL, MemberSessionRefused, INVITE_MAX_HOPS;
28210
+ var WIX_API, ONE_APP_SESSION, OWNER_SCOPED_WIX_HOST, ONE_APP_VISITOR_MINT_TIMEOUT_MS, 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, ACCOUNT_FORWARD_ALLOWLIST, ACCOUNT_JOIN_PATHS, NotSiteMember, AccountSessionExpired, SiteInstanceUnavailable, MEMBER_REFRESH_MARGIN_MS, MEMBER_NEGATIVE_TTL_MS, MEMBER_TRANSIENT_TTL_MS, MemberInstanceCache, MEMBER_SESSION_URL, MemberSessionRefused, INVITE_MAX_HOPS;
28180
28211
  var init_wix_bridge = __esm({
28181
28212
  "../../core/serve-runtime/src/wix-bridge.ts"() {
28182
28213
  init_sha256();
28183
28214
  WIX_API = "https://www.wixapis.com";
28184
28215
  ONE_APP_SESSION = "https://apps.wix.com/_api/one-app-session-web/v3/businesses";
28185
28216
  OWNER_SCOPED_WIX_HOST = /(^|\.)wix\.com$/i;
28217
+ ONE_APP_VISITOR_MINT_TIMEOUT_MS = 8e3;
28186
28218
  WIX_FORWARDABLE_HEADERS = /* @__PURE__ */ new Set([
28187
28219
  "x-wix-language",
28188
28220
  "x-wix-linguist",
@@ -28532,6 +28564,7 @@ __export(wix_member_login_exports, {
28532
28564
  isAllowedConsumerStreamTarget: () => isAllowedConsumerStreamTarget,
28533
28565
  memberDirectLogin: () => memberDirectLogin,
28534
28566
  memberDirectRegister: () => memberDirectRegister,
28567
+ mintOneAppVisitorToken: () => mintOneAppVisitorToken,
28535
28568
  mintVisitor: () => mintVisitor,
28536
28569
  readMemberId: () => readMemberId,
28537
28570
  webWixCall: () => webWixCall,
@@ -28555,6 +28588,9 @@ async function mintVisitor(clientId) {
28555
28588
  if (r3.status !== 200 || !r3.json.access_token) throw new Error(`visitor mint failed (${r3.status})`);
28556
28589
  return r3.json.access_token;
28557
28590
  }
28591
+ async function mintOneAppVisitorToken(metaSiteId) {
28592
+ return (await mintOneAppVisitor(metaSiteId)).instance;
28593
+ }
28558
28594
  function isRedirectCallback(url, redirectUri) {
28559
28595
  if (url.startsWith(redirectUri)) return true;
28560
28596
  const path2 = (u2) => u2.pathname.replace(/\/+$/, "") || "/";
@@ -28862,7 +28898,7 @@ function parseTarget(target) {
28862
28898
  return { host: "", path: path2, query };
28863
28899
  }
28864
28900
  }
28865
- async function handleWixGateway(gw, app, adminUrl, req, res, wixClientId) {
28901
+ async function handleWixGateway(gw, app, adminUrl, req, res, wixClientId, oneAppMetaSiteId) {
28866
28902
  const url = req.url ?? "";
28867
28903
  const path2 = url.split("?")[0];
28868
28904
  const scope2 = path2.startsWith("/__dev/wix/") ? "wix" : path2.startsWith("/__dev/net/") ? "net" : null;
@@ -29064,7 +29100,7 @@ data: ${JSON.stringify({ mode: gw.mode })}
29064
29100
  status = 0;
29065
29101
  respText = JSON.stringify({ gatewayError: String(e2?.message ?? e2) });
29066
29102
  }
29067
- if (scope2 === "wix" && (status === 401 || status === 403)) {
29103
+ if (scope2 === "wix" && (status === 401 || status === 403) && !oneAppMetaSiteId) {
29068
29104
  try {
29069
29105
  const vt2 = await mintVisitor(wixClientId ?? WIX_DEV_CLIENT_ID);
29070
29106
  const retryHeaders = {};
@@ -129977,9 +130013,10 @@ function webWixSession(req, res, state) {
129977
130013
  if (id !== requestedId) {
129978
130014
  res.setHeader("set-cookie", `${WEBWIX_COOKIE}=${id}; Path=/; HttpOnly; SameSite=Lax`);
129979
130015
  }
130016
+ const binding2 = wixBindingOf(state.app);
129980
130017
  let session = state.wixWebSessions.get(id);
129981
- if (!session) {
129982
- session = {};
130018
+ if (!session || session.binding !== binding2) {
130019
+ session = { binding: binding2 };
129983
130020
  state.wixWebSessions.set(id, session);
129984
130021
  }
129985
130022
  return session;
@@ -130157,14 +130194,15 @@ async function handleWebWix(req, res, state) {
130157
130194
  await pipeWebWixStream(upstream2, res, abort.signal, recordStream);
130158
130195
  return;
130159
130196
  }
130160
- if (!session.visitorToken && !session.memberToken) {
130197
+ const live3 = currentBindingSession(session, state);
130198
+ if (!live3.visitorToken && !live3.memberToken) {
130161
130199
  try {
130162
- session.visitorToken = await mintVisitor(resolveWixClientId(state.app) ?? WEBWIX_CLIENT_ID);
130200
+ live3.visitorToken = await mintAppVisitor(state.app, live3);
130163
130201
  } catch {
130164
130202
  }
130165
130203
  }
130166
- const isMember = !!session.memberToken;
130167
- let token = session.memberToken ?? session.visitorToken ?? "";
130204
+ const isMember = !!live3.memberToken;
130205
+ let token = live3.memberToken ?? live3.visitorToken ?? "";
130168
130206
  let upstream = await webWixStream(method, target.toString(), body, token, void 0, forwardedHeaders, abort.signal);
130169
130207
  if ((upstream.status === 401 || upstream.status === 403) && !isMember && !abort.signal.aborted) {
130170
130208
  try {
@@ -130172,7 +130210,8 @@ async function handleWebWix(req, res, state) {
130172
130210
  } catch {
130173
130211
  }
130174
130212
  try {
130175
- token = session.visitorToken = await mintVisitor(resolveWixClientId(state.app) ?? WEBWIX_CLIENT_ID);
130213
+ const again = currentBindingSession(live3, state);
130214
+ token = again.visitorToken = await mintAppVisitor(state.app, again);
130176
130215
  upstream = await webWixStream(method, target.toString(), body, token, void 0, forwardedHeaders, abort.signal);
130177
130216
  } catch {
130178
130217
  }
@@ -130195,6 +130234,9 @@ async function handleWebWix(req, res, state) {
130195
130234
  return;
130196
130235
  }
130197
130236
  if (path2 === "/v1/__webwix/login" && req.method === "POST") {
130237
+ if (oneAppMetaSiteIdOf(state.app?.meta.auth) && !resolveWixClientId(state.app)) {
130238
+ return reply(200, { ok: false, code: "unavailable", error: "member_login_unavailable" });
130239
+ }
130198
130240
  const b2 = await readJson10();
130199
130241
  try {
130200
130242
  const { memberToken, visitorToken } = await memberDirectLogin(
@@ -130204,8 +130246,8 @@ async function handleWebWix(req, res, state) {
130204
130246
  String(b2.password ?? "")
130205
130247
  );
130206
130248
  session.memberToken = memberToken;
130207
- session.visitorToken = visitorToken;
130208
130249
  session.email = String(b2.email ?? "");
130250
+ if (!oneAppMetaSiteIdOf(state.app?.meta.auth)) session.visitorToken = visitorToken;
130209
130251
  if (session.account) webAccountMemberInstances.forgetSession(session.account.cookie);
130210
130252
  session.account = void 0;
130211
130253
  return reply(200, { ok: true, email: session.email });
@@ -130460,19 +130502,21 @@ async function handleWebWix(req, res, state) {
130460
130502
  return reply(status, { error: auth2 ? "webwix_owner_mint_failed" : "webwix_bridge_upstream_failed" });
130461
130503
  }
130462
130504
  }
130463
- if (!session.visitorToken && !session.memberToken) {
130505
+ const live3 = currentBindingSession(session, state);
130506
+ if (!live3.visitorToken && !live3.memberToken) {
130464
130507
  try {
130465
- session.visitorToken = await mintVisitor(resolveWixClientId(state.app) ?? WEBWIX_CLIENT_ID);
130508
+ live3.visitorToken = await mintAppVisitor(state.app, live3);
130466
130509
  } catch {
130467
130510
  }
130468
130511
  }
130469
- const token = session.memberToken ?? session.visitorToken ?? "";
130512
+ const token = live3.memberToken ?? live3.visitorToken ?? "";
130470
130513
  try {
130471
130514
  let r3 = await webWixCall(method, requestedPath, body, token, void 0, forwardedHeaders);
130472
- if ((r3.status === 401 || r3.status === 403) && !session.memberToken) {
130515
+ if ((r3.status === 401 || r3.status === 403) && !live3.memberToken) {
130473
130516
  try {
130474
- session.visitorToken = await mintVisitor(resolveWixClientId(state.app) ?? WEBWIX_CLIENT_ID);
130475
- r3 = await webWixCall(method, requestedPath, body, session.visitorToken, void 0, forwardedHeaders);
130517
+ const again = currentBindingSession(live3, state);
130518
+ again.visitorToken = await mintAppVisitor(state.app, again);
130519
+ r3 = await webWixCall(method, requestedPath, body, again.visitorToken, void 0, forwardedHeaders);
130476
130520
  } catch {
130477
130521
  }
130478
130522
  }
@@ -130511,6 +130555,9 @@ async function handleWebWix(req, res, state) {
130511
130555
  });
130512
130556
  }
130513
130557
  if (path2 === "/v1/__webwix/register" && req.method === "POST") {
130558
+ if (oneAppMetaSiteIdOf(state.app?.meta.auth) && !resolveWixClientId(state.app)) {
130559
+ return reply(200, { ok: false, code: "unavailable", error: "member_login_unavailable" });
130560
+ }
130514
130561
  const b2 = await readJson10();
130515
130562
  try {
130516
130563
  const { memberToken, visitorToken } = await memberDirectRegister(
@@ -130522,8 +130569,8 @@ async function handleWebWix(req, res, state) {
130522
130569
  b2.lastName ? String(b2.lastName) : void 0
130523
130570
  );
130524
130571
  session.memberToken = memberToken;
130525
- session.visitorToken = visitorToken;
130526
130572
  session.email = String(b2.email ?? "");
130573
+ if (!oneAppMetaSiteIdOf(state.app?.meta.auth)) session.visitorToken = visitorToken;
130527
130574
  if (session.account) webAccountMemberInstances.forgetSession(session.account.cookie);
130528
130575
  session.account = void 0;
130529
130576
  return reply(200, { ok: true, email: session.email });
@@ -130535,7 +130582,7 @@ async function handleWebWix(req, res, state) {
130535
130582
  }
130536
130583
  async function handleDev(req, res, state) {
130537
130584
  const url = req.url ?? "";
130538
- if (await handleWixGateway(state.wix, state.appName, state.adminUrl, req, res, resolveWixClientId(state.app))) return;
130585
+ if (await handleWixGateway(state.wix, state.appName, state.adminUrl, req, res, resolveWixClientId(state.app), oneAppMetaSiteIdOf(state.app?.meta.auth) ?? void 0)) return;
130539
130586
  if (url === "/__dev/health") {
130540
130587
  return sendJson(res, 200, {
130541
130588
  status: "ok",
@@ -132130,7 +132177,7 @@ ${err.message}`);
132130
132177
  });
132131
132178
  return httpServer;
132132
132179
  }
132133
- var ROOT6, TIER3_ROOT, TIER4_ROOT, tier4Verifier, TIER5_ROOT2, ACTION_HANDLERS_ROOT, SAMPLES_ROOT, TELEMETRY_BUFFER_CAP, overrideHistorySeq, CACHE_CONTROL, DescriptorDepthRefusal, TIER5_SRC_ROOT, HMR_TMP_DIR, appReloadSeq, appReloadChain, WEBWIX_CLIENT_ID, WEBWIX_REDIRECT, WEBWIX_COOKIE, webOwnerPreviewInstances, webAccountMemberInstances, MIME, widgetOverrides;
132180
+ var ROOT6, TIER3_ROOT, TIER4_ROOT, tier4Verifier, TIER5_ROOT2, ACTION_HANDLERS_ROOT, SAMPLES_ROOT, TELEMETRY_BUFFER_CAP, overrideHistorySeq, CACHE_CONTROL, DescriptorDepthRefusal, TIER5_SRC_ROOT, HMR_TMP_DIR, appReloadSeq, appReloadChain, WEBWIX_CLIENT_ID, mintAppVisitor, wixBindingOf, currentBindingSession, WEBWIX_REDIRECT, WEBWIX_COOKIE, webOwnerPreviewInstances, webAccountMemberInstances, MIME, widgetOverrides;
132134
132181
  var init_src5 = __esm({
132135
132182
  "../../core/dev-server/src/index.ts"() {
132136
132183
  init_inject();
@@ -132144,6 +132191,7 @@ var init_src5 = __esm({
132144
132191
  init_aria_realtime_dev();
132145
132192
  init_wix_member_login();
132146
132193
  init_wix_bridge();
132194
+ init_wix_bridge();
132147
132195
  init_wix_account_session();
132148
132196
  init_flag_assignments();
132149
132197
  init_images();
@@ -132202,6 +132250,19 @@ var init_src5 = __esm({
132202
132250
  appReloadSeq = 0;
132203
132251
  appReloadChain = Promise.resolve();
132204
132252
  WEBWIX_CLIENT_ID = process.env.DEMO_APP_WIX_CLIENT_ID ?? "4f58d461-c1f5-4a5d-a467-62cc2329e4dd";
132253
+ mintAppVisitor = async (app, session) => {
132254
+ const metaSiteId = oneAppMetaSiteIdOf(app?.meta.auth);
132255
+ if (!metaSiteId) return mintVisitor(resolveWixClientId(app) ?? WEBWIX_CLIENT_ID);
132256
+ if (session.binding !== wixBindingOf(app)) return (await mintOneAppVisitor(metaSiteId)).instance;
132257
+ const held = session.oneAppVisitor;
132258
+ if (held && held.expiresAt - 6e4 > Date.now()) return held.instance;
132259
+ session.oneAppVisitorMint ??= mintOneAppVisitor(metaSiteId).then((visitor) => session.oneAppVisitor = visitor).finally(() => {
132260
+ session.oneAppVisitorMint = void 0;
132261
+ });
132262
+ return (await session.oneAppVisitorMint).instance;
132263
+ };
132264
+ wixBindingOf = (app) => JSON.stringify(app?.meta.auth ?? null);
132265
+ currentBindingSession = (session, state) => session.binding === wixBindingOf(state.app) ? session : { binding: wixBindingOf(state.app) };
132205
132266
  WEBWIX_REDIRECT = "himalaya-demo-app://oauth/callback";
132206
132267
  WEBWIX_COOKIE = "himi_webwix_session";
132207
132268
  webOwnerPreviewInstances = new OwnerInstanceCache(fetch);
@@ -137856,12 +137917,13 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
137856
137917
  if (liveWixCall) return liveWixCall;
137857
137918
  const auth = config.auth;
137858
137919
  const clientId = auth?.config?.clientId;
137859
- if (auth?.providerId !== "wix-consumer" || typeof clientId !== "string" || !clientId) {
137920
+ const oneAppMsid = oneAppMetaSiteIdOf(auth);
137921
+ if (!oneAppMsid && (auth?.providerId !== "wix-consumer" || typeof clientId !== "string" || !clientId)) {
137860
137922
  throw new Error(
137861
137923
  "`himi render --live` requires a WixConsumerAuthProvider clientId in config.ts; none found" + (auth?.providerId ? ` (this app's auth provider is "${auth.providerId}", not "wix-consumer")` : "") + ". Only a Wix Headless consumer client can mint the visitor token that backs a live read. Add `auth: WixConsumerAuthProvider({ clientId, siteUrl, redirectUri })`, or render without --live (initial state only)."
137862
137924
  );
137863
137925
  }
137864
- if (clientId === PLACEHOLDER_CLIENT_ID) {
137926
+ if (!oneAppMsid && clientId === PLACEHOLDER_CLIENT_ID) {
137865
137927
  throw Object.assign(
137866
137928
  new Error(
137867
137929
  `\`himi render --live\` found the scaffolded placeholder clientId "${PLACEHOLDER_CLIENT_ID}" in config.ts \u2014 it cannot mint a visitor token, so every Wix call would fail and the render would show the initial state. Set a real Wix Headless (wix-consumer) clientId in config.ts, or export WIX_CLIENT_ID. Drop --live to render the initial state deliberately.`
@@ -137869,7 +137931,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
137869
137931
  { exitCode: 2 }
137870
137932
  );
137871
137933
  }
137872
- const token = await mintVisitor(clientId);
137934
+ const token = oneAppMsid ? await mintOneAppVisitorToken(oneAppMsid) : await mintVisitor(clientId);
137873
137935
  liveWixCall = async (method, path2, body) => {
137874
137936
  const bodyStr = body === void 0 ? void 0 : typeof body === "string" ? body : JSON.stringify(body);
137875
137937
  const r3 = await webWixCall(method, path2, bodyStr, token);
@@ -138664,7 +138726,12 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
138664
138726
  auth: (() => {
138665
138727
  const a2 = config.auth;
138666
138728
  const cid = a2?.config?.clientId;
138667
- return { ...a2?.providerId ? { providerId: a2.providerId } : {}, ...typeof cid === "string" && cid ? { clientId: cid } : {} };
138729
+ const oneAppMetaSiteId = oneAppMetaSiteIdOf(a2);
138730
+ return {
138731
+ ...a2?.providerId ? { providerId: a2.providerId } : {},
138732
+ ...typeof cid === "string" && cid ? { clientId: cid } : {},
138733
+ ...oneAppMetaSiteId ? { oneAppMetaSiteId } : {}
138734
+ };
138668
138735
  })()
138669
138736
  };
138670
138737
  }
@@ -138738,6 +138805,7 @@ var init_build3 = __esm({
138738
138805
  init_screen_views();
138739
138806
  init_validate_descriptor();
138740
138807
  init_wix_member_login();
138808
+ init_wix_bridge();
138741
138809
  init_wix_placeholders();
138742
138810
  init_render_descriptor();
138743
138811
  init_render_fonts();
@@ -140776,6 +140844,7 @@ async function loadAuthoring() {
140776
140844
  crawlSignature: crawl.crawlSignature,
140777
140845
  recordScreenTraffic: crawl.recordScreenTraffic,
140778
140846
  mintVisitor: wml.mintVisitor,
140847
+ mintOneAppVisitorToken: wml.mintOneAppVisitorToken,
140779
140848
  webWixCall: wml.webWixCall,
140780
140849
  freezeTrafficToMocks: nf2.freezeTrafficToMocks,
140781
140850
  bootAndSnapshotState: crawl.bootAndSnapshotState,
@@ -151053,19 +151122,19 @@ function isSymlink2(path2) {
151053
151122
  async function introducedErrors(dir, validate5, file2, isOwnFinding) {
151054
151123
  const edited = await validate5(dir, { fresh: true });
151055
151124
  if (edited.code === 0) return void 0;
151056
- if (!comparable(edited)) return `himi validate failed and its report could not be read: ${edited.tail ?? "no output"}`;
151125
+ const { comparable: comparable2, compareErrors: compareErrors2 } = await Promise.resolve().then(() => (init_template_trim(), template_trim_exports));
151126
+ if (!comparable2(edited)) return `himi validate failed and its report could not be read: ${edited.tail ?? "no output"}`;
151057
151127
  if (edited.errors.every((e2) => isOwnFinding(e2.ruleCode))) return void 0;
151058
151128
  file2.restore();
151059
151129
  const baseline = await validate5(dir, { fresh: true });
151060
151130
  file2.reapply();
151061
- if (!comparable(baseline)) return "himi validate could not check the original config.ts to compare against";
151062
- const introduced = compareErrors(edited.errors, baseline.errors ?? []).introduced.filter((e2) => !isOwnFinding(e2.ruleCode));
151131
+ if (!comparable2(baseline)) return "himi validate could not check the original config.ts to compare against";
151132
+ const introduced = compareErrors2(edited.errors, baseline.errors ?? []).introduced.filter((e2) => !isOwnFinding(e2.ruleCode));
151063
151133
  return introduced.length ? `the edit introduced ${introduced.length === 1 ? "an error" : `${introduced.length} errors`}: ` + introduced.map((e2) => e2.message).join("; ") : void 0;
151064
151134
  }
151065
151135
  var init_config_source_edit = __esm({
151066
151136
  "src/config-source-edit.ts"() {
151067
151137
  init_progress();
151068
- init_template_trim();
151069
151138
  }
151070
151139
  });
151071
151140
 
@@ -168052,6 +168121,57 @@ var init_package_share = __esm({
168052
168121
  }
168053
168122
  });
168054
168123
 
168124
+ // ../../core/serve-runtime/src/rate-limit.ts
168125
+ var FixedWindowRateLimiter;
168126
+ var init_rate_limit = __esm({
168127
+ "../../core/serve-runtime/src/rate-limit.ts"() {
168128
+ FixedWindowRateLimiter = class {
168129
+ max;
168130
+ windowMs;
168131
+ now;
168132
+ /** Cap on distinct keys tracked, so a flood of unique keys cannot grow the map without
168133
+ * bound. When exceeded, the soonest-to-reset entry is dropped (expired ones first — they are
168134
+ * the soonest) — in O(1): see `hits`. */
168135
+ maxKeys;
168136
+ /** Kept in `resetAt` order: a window is (re)inserted at the END when it opens, and every window
168137
+ * is `windowMs` long, so the FIRST entry is always the soonest to reset. That is what makes
168138
+ * eviction O(1) — a scan of the whole map per new key, once it is full, was an O(maxKeys) cost
168139
+ * a flood of unique keys could make this pod pay on every request. */
168140
+ hits = /* @__PURE__ */ new Map();
168141
+ constructor(opts) {
168142
+ this.max = Math.max(1, opts.max);
168143
+ this.windowMs = Math.max(1, opts.windowMs);
168144
+ this.now = opts.now ?? Date.now;
168145
+ this.maxKeys = Math.max(1, opts.maxKeys ?? 1e5);
168146
+ }
168147
+ /** Count one request against `key`. Does NOT mutate on refusal past the first over-limit hit
168148
+ * count — a refused caller cannot push their own reset further out by hammering. */
168149
+ check(key3) {
168150
+ const t2 = this.now();
168151
+ let entry = this.hits.get(key3);
168152
+ if (!entry || t2 >= entry.resetAt) {
168153
+ if (entry) this.hits.delete(key3);
168154
+ else if (this.hits.size >= this.maxKeys) this.evictOne();
168155
+ entry = { count: 0, resetAt: t2 + this.windowMs };
168156
+ this.hits.set(key3, entry);
168157
+ }
168158
+ if (entry.count >= this.max) {
168159
+ return { ok: false, retryAfterSec: Math.max(1, Math.ceil((entry.resetAt - t2) / 1e3)) };
168160
+ }
168161
+ entry.count += 1;
168162
+ return { ok: true, retryAfterSec: 0 };
168163
+ }
168164
+ /** Evict the soonest-to-reset entry — the first, by the ordering `hits` keeps. O(1). An expired
168165
+ * entry left elsewhere in the map is harmless: `check` treats it as absent, and it reaches the
168166
+ * front in its turn. */
168167
+ evictOne() {
168168
+ const first = this.hits.keys().next();
168169
+ if (!first.done) this.hits.delete(first.value);
168170
+ }
168171
+ };
168172
+ }
168173
+ });
168174
+
168055
168175
  // ../../core/serve-runtime/src/wix-member-auth.ts
168056
168176
  function wixMemberAuthOf(appConfigJson, callbackUrl) {
168057
168177
  let cfg;
@@ -168394,6 +168514,10 @@ var init_account_rung = __esm({
168394
168514
  function json5(status, body, headers2 = {}) {
168395
168515
  return new Response(JSON.stringify(body), { status, headers: { "content-type": JSON_CT3, ...headers2 } });
168396
168516
  }
168517
+ function visitorMintCaller(request) {
168518
+ const hops = (request.headers.get("x-forwarded-for") ?? "").split(",").map((h2) => h2.trim()).filter(Boolean);
168519
+ return hops.at(-1) ?? "direct";
168520
+ }
168397
168521
  function isCookieAuthorizedPath(path2) {
168398
168522
  return path2 === "/v1/__webwix/call" || path2 === "/v1/__webwix/stream" || path2 === "/v1/owner" || path2.startsWith("/v1/owner/") || path2 === "/v1/__webwix/identity" || path2 === "/v1/__webwix/login" || path2 === "/v1/__webwix/register" || path2 === "/v1/__webwix/logout" || path2 === MEMBER_CALLBACK_PATH || ACCOUNT_RUNG_PATHS.has(path2);
168399
168523
  }
@@ -168417,6 +168541,7 @@ function makeServeHandler(opts) {
168417
168541
  })();
168418
168542
  const webwixFetch = opts.webwixFetch ?? fetch;
168419
168543
  const webwixOwnerInstances = new OwnerInstanceCache(webwixFetch);
168544
+ const visitorMintLimiter = new FixedWindowRateLimiter({ max: opts.visitorMintRatePerMin ?? 30, windowMs: 6e4 });
168420
168545
  const webwixOwnerSites = new OwnerSitesCache(webwixFetch);
168421
168546
  const webwixAccountInstances = new MemberInstanceCache(webwixFetch);
168422
168547
  const webwixOwnerRungOn = () => opts.webwixOwnerRung !== false;
@@ -168546,6 +168671,17 @@ ${releaseId}`;
168546
168671
  function resolveApp(request, url) {
168547
168672
  return request.headers.get("x-himalaya-app") || url.searchParams.get("app") || opts.defaultApp || null;
168548
168673
  }
168674
+ async function visitorMintTarget(request, url) {
168675
+ const mintFetch = opts.oneAppVisitorFetch ?? (opts.webwixBridge === false ? null : webwixFetch);
168676
+ if (!mintFetch) return json5(503, { error: "webwix_bridge_disabled" });
168677
+ const app = resolveApp(request, url);
168678
+ if (!app) return json5(400, { error: "missing_app" });
168679
+ const cfg = await appConfigFor(request, url, app);
168680
+ if (!cfg.ok) return cfg.response;
168681
+ const msid = oneAppVisitorMsidOf(utf8Decode(cfg.bytes));
168682
+ if (!msid) return json5(404, { error: "visitor_instance_not_configured" });
168683
+ return { app, msid, mintFetch };
168684
+ }
168549
168685
  function sendDoc(request, body, pinned = false) {
168550
168686
  const etag = strongEtag(body);
168551
168687
  const cache = pinned ? PINNED_CACHE_CONTROL : DOC_CACHE_CONTROL;
@@ -168622,7 +168758,7 @@ ${releaseId}`;
168622
168758
  const origin = request.headers.get("origin");
168623
168759
  if (!origin) return {};
168624
168760
  const path2 = new URL(request.url).pathname;
168625
- if (isCookieAuthorizedPath(path2)) return {};
168761
+ if (isCookieAuthorizedPath(path2) || path2 === VISITOR_INSTANCE_PATH) return {};
168626
168762
  return {
168627
168763
  "access-control-allow-origin": origin,
168628
168764
  vary: "Origin",
@@ -168799,6 +168935,11 @@ ${releaseId}`;
168799
168935
  }
168800
168936
  });
168801
168937
  }
168938
+ if (request.method === "HEAD" && path2 === VISITOR_INSTANCE_PATH) {
168939
+ const target = await visitorMintTarget(request, url);
168940
+ if (target instanceof Response) return new Response(null, { status: target.status, headers: target.headers });
168941
+ return new Response(null, { status: 200, headers: { "content-type": JSON_CT3, "cache-control": "no-store" } });
168942
+ }
168802
168943
  if ((request.method === "GET" || request.method === "HEAD") && path2 === "/v1/__webwix/identity") {
168803
168944
  const headers2 = { "content-type": JSON_CT3, "cache-control": "no-store" };
168804
168945
  if (request.method === "HEAD") return new Response(null, { status: 200, headers: headers2 });
@@ -169066,6 +169207,19 @@ ${releaseId}`;
169066
169207
  return json5(403, { error: "webwix_owner_mint_failed" });
169067
169208
  }
169068
169209
  }
169210
+ if (path2 === VISITOR_INSTANCE_PATH) {
169211
+ const target = await visitorMintTarget(request, url);
169212
+ if (target instanceof Response) return target;
169213
+ const { app: app2, msid, mintFetch } = target;
169214
+ const rate = visitorMintLimiter.check(`${app2}|${visitorMintCaller(request)}`);
169215
+ if (!rate.ok) return json5(429, { error: "visitor_instance_rate_limited" }, { "retry-after": String(rate.retryAfterSec) });
169216
+ try {
169217
+ const entry = await mintOneAppVisitor(msid, mintFetch);
169218
+ return json5(200, { ...entry, expiresInMs: Math.max(0, entry.expiresAt - Date.now()) }, { "cache-control": "no-store" });
169219
+ } catch {
169220
+ return json5(502, { error: "webwix_bridge_upstream_failed" });
169221
+ }
169222
+ }
169069
169223
  if (path2 === "/v1/owner/sites") {
169070
169224
  if (!webwixOwnerRungOn()) return json5(503, { error: "webwix_owner_disabled" });
169071
169225
  const cookie = request.headers.get("cookie") ?? "";
@@ -169542,7 +169696,7 @@ ${releaseId}`;
169542
169696
  return withCors(request, response);
169543
169697
  };
169544
169698
  }
169545
- var JSON_CT3;
169699
+ var JSON_CT3, VISITOR_INSTANCE_PATH;
169546
169700
  var init_server2 = __esm({
169547
169701
  "../../core/serve/src/server.ts"() {
169548
169702
  init_sha256();
@@ -169553,10 +169707,12 @@ var init_server2 = __esm({
169553
169707
  init_member_exchange();
169554
169708
  init_member_forward();
169555
169709
  init_package_share();
169710
+ init_rate_limit();
169556
169711
  init_wix_bridge();
169557
169712
  init_account_rung();
169558
169713
  init_wix_member_auth();
169559
169714
  JSON_CT3 = "application/json; charset=utf-8";
169715
+ VISITOR_INSTANCE_PATH = "/v1/visitor/instance";
169560
169716
  }
169561
169717
  });
169562
169718
 
@@ -169964,6 +170120,11 @@ function liveWixClientId(appConfig) {
169964
170120
  const clientId = appConfigWixClientId(appConfig);
169965
170121
  return clientId && clientId !== PLACEHOLDER_CLIENT_ID ? clientId : void 0;
169966
170122
  }
170123
+ function liveWixBinding(appConfig) {
170124
+ if (liveWixClientId(appConfig) !== void 0) return true;
170125
+ const auth = authConfigOf(appConfig);
170126
+ return auth?.providerId === "wix-consumer" && auth.config?.visitorSource === "one-app" && typeof auth.config.metaSiteId === "string" && auth.config.metaSiteId.length > 0;
170127
+ }
169967
170128
  var init_wix_client_id = __esm({
169968
170129
  "src/wix-client-id.ts"() {
169969
170130
  init_wix_placeholders();
@@ -170011,38 +170172,38 @@ var init_preview_assets_generated = __esm({
170011
170172
  "../../packages/serve/src/preview-assets.generated.ts"() {
170012
170173
  init_preview_assets_format();
170013
170174
  PREVIEW_ASSET_MANIFEST = [
170014
- { key: "assets/DashboardHost-5wf0y6ol.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 2916, sha256: "546fee4e3168812aba2ab98e7fbb62e7d707a8c90e84336f51c0baf0902186f4" },
170015
- { key: "assets/DevDrawer-CQGmhbIs.js", contentType: "application/javascript; charset=utf-8", offset: 2924, length: 16744, sha256: "3b37c8bbe8fcfef63066c97c53eab384c96c0db989ef6026cac53c3d87416228" },
170016
- { key: "assets/IdiomCompare-Iuvv8Rlj.js", contentType: "application/javascript; charset=utf-8", offset: 19668, length: 1892, sha256: "34a2df21726dacbb47d85a9fd471b4fd2733de325e9178034904bfaa182c8e29" },
170017
- { key: "assets/LightboxViewer-fHwveX-i.js", contentType: "application/javascript; charset=utf-8", offset: 21560, length: 8132, sha256: "a43c88fd1ab25dab31e649bec5b2837c029c9f1d2f6d7542bca90c8be7b9c354" },
170018
- { key: "assets/PhonePreviewControl-BSsfEWOn.js", contentType: "application/javascript; charset=utf-8", offset: 29692, length: 37729, sha256: "312fd178c95f4284589f216b4a7cbc948028eee9eeb16ffcf3d9b0801b8547ba" },
170019
- { key: "assets/SchemeCompare-DXtTgPI6.js", contentType: "application/javascript; charset=utf-8", offset: 67421, length: 1824, sha256: "d4120f73b44a15965268c926c8da522a12f80faf00711ce89aa9b54d88ef54b0" },
170175
+ { key: "assets/DashboardHost-D5EVbc2F.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 2916, sha256: "2f182ad05cc79b7f2da3f70cf51c0b1c86e8432b02e6e38965cd1d4099c9fdc6" },
170176
+ { key: "assets/DevDrawer-BK3Vg-Y2.js", contentType: "application/javascript; charset=utf-8", offset: 2924, length: 16744, sha256: "197a32bfcf8120e32bddb02699547aa4cf3199b22f0e3d4d73efecdef9a52051" },
170177
+ { key: "assets/IdiomCompare-BFXQ1M5s.js", contentType: "application/javascript; charset=utf-8", offset: 19668, length: 1892, sha256: "b81a659bfc6b8e6190cdd259302402f0388ab2536e44ca9223bd9b3b9e39f0bd" },
170178
+ { key: "assets/LightboxViewer-nAaLa1ml.js", contentType: "application/javascript; charset=utf-8", offset: 21560, length: 8132, sha256: "e85aa0c290afacd74031bd18f9dd1db2cd7acfc50b0d9b041156f482ab066d0d" },
170179
+ { key: "assets/PhonePreviewControl-B5H1rgoN.js", contentType: "application/javascript; charset=utf-8", offset: 29692, length: 37729, sha256: "a24d2a30b7d1aef5ef5797bf4f3df71cfba60c9f26f2cfcdd1986c41cda172ef" },
170180
+ { key: "assets/SchemeCompare-DJKQL41W.js", contentType: "application/javascript; charset=utf-8", offset: 67421, length: 1824, sha256: "248e3af4523b33ab3acbb17fae089a5854f9936d1679a7ff72389c6f21379b94" },
170020
170181
  { key: "assets/glassPreviewBrowser-Bt5ZFmG4.js", contentType: "application/javascript; charset=utf-8", offset: 69245, length: 342, sha256: "20d73f97d38f6d9a0b79e68e24954cd6bbfe66833a6e6aecae00a9102e64cab3" },
170021
- { key: "assets/index-DxXULrki.js", contentType: "application/javascript; charset=utf-8", offset: 69587, length: 1344114, sha256: "e8c56c448a052fd93491c0030e7ac00bed1cbd14142efe297556812a783bde10" },
170022
- { key: "assets/pdf-CdYoBtlC.js", contentType: "application/javascript; charset=utf-8", offset: 1413701, length: 488199, sha256: "41a0c995fb20f5a2dc4abdd47f283b4fa4cc5eec3cabe146b0e01cf86143f27f" },
170023
- { key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset: 1901900, length: 73, sha256: "41bcfda4f3c8c0a81c785ea87c69afc8e7d0ed8c333324aee94c273d881bb6aa" },
170024
- { key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset: 1901973, length: 1317034, sha256: "a33cfe728c584fdba4fcc1fd54bcdc2f9f2f13889ddbb5b2bd1d0f8cbe49b84e" },
170025
- { key: "assets/pdfDocument-BMhHjlqg.js", contentType: "application/javascript; charset=utf-8", offset: 3219007, length: 3379, sha256: "0588a47454ed1787b2373dd097bc3ce32705f0f9c2c263c27cd3c8c2dc09a0fd" },
170026
- { key: "assets/pdfFetch-Cc8i1I1h.js", contentType: "application/javascript; charset=utf-8", offset: 3222386, length: 2266, sha256: "1d21ad008921942217c9eac0c35b1713773b9d89c71e3ab4412781f7bb88f463" },
170027
- { key: "assets/webviewBridgeHost-D0zOUOdW.js", contentType: "application/javascript; charset=utf-8", offset: 3224652, length: 9849, sha256: "58d93339322d6084df15033f9c2445577430178efe2d1cd8b7a7fec2d75714cf" },
170028
- { key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 3234501, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
170029
- { key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 3239111, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
170030
- { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 3727695, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
170031
- { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 3818619, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
170032
- { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 3909603, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
170033
- { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 4000583, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
170034
- { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 4091455, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
170035
- { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 4182435, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
170036
- { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 4291071, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
170037
- { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 4400155, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
170038
- { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 4509203, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
170039
- { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 4616903, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
170040
- { key: "himi-sw.js", contentType: "application/javascript; charset=utf-8", offset: 4705011, length: 6748, sha256: "4a92459977d7cefa1a6a7e020c3a63509737f083b3f2773557c1a5771665811a" },
170041
- { key: "index.html", contentType: "text/html; charset=utf-8", offset: 4711759, length: 4947, sha256: "be9d960987b43b3e0bf73db51329ec433fe6ed5eefe0a7cc32bc2e33f1fad21f" },
170042
- { key: "ios-glass-preview.css", contentType: "text/css; charset=utf-8", offset: 4716706, length: 7193, sha256: "a482f4796147c2a3893942e10ab225bd3b6f749f7125fe0330680d4c20ea0212" },
170043
- { key: "ios-glass-preview.svg", contentType: "image/svg+xml", offset: 4723899, length: 423, sha256: "b9cd5989d31464a0422f260a332af6be5add0b04de2148944de35158f3b75efc" },
170044
- { key: "kit-tab-bar.css", contentType: "text/css; charset=utf-8", offset: 4724322, length: 1171, sha256: "9e2c3a0faaf05d5471badf167a4d3bdf1c4e6dd65c432eea6d254158bfd99585" },
170045
- { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 4725493, length: 18778, sha256: "ba734d58c88281c71c01d9a2842a991d06f3ed91bf03449427ef11c7f6d1605d" }
170182
+ { key: "assets/index-OGlXUsSh.js", contentType: "application/javascript; charset=utf-8", offset: 69587, length: 1346613, sha256: "39df48514d225b66a41c34eb937e6cdd485a4490b8b6e9d271f6dcea53ca06a5" },
170183
+ { key: "assets/pdf-BLYfkY1C.js", contentType: "application/javascript; charset=utf-8", offset: 1416200, length: 488199, sha256: "3f1ac8017be9bf7de66589ec2a4859a06eba02962a34c9167f4da208792bf0f2" },
170184
+ { key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset: 1904399, length: 73, sha256: "41bcfda4f3c8c0a81c785ea87c69afc8e7d0ed8c333324aee94c273d881bb6aa" },
170185
+ { key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset: 1904472, length: 1317034, sha256: "a33cfe728c584fdba4fcc1fd54bcdc2f9f2f13889ddbb5b2bd1d0f8cbe49b84e" },
170186
+ { key: "assets/pdfDocument-8MxOHwUZ.js", contentType: "application/javascript; charset=utf-8", offset: 3221506, length: 3379, sha256: "503a8fde785394352aed2b87dee68d1b940513efb24726dbfc31be155d0ca9aa" },
170187
+ { key: "assets/pdfFetch-Cc8i1I1h.js", contentType: "application/javascript; charset=utf-8", offset: 3224885, length: 2266, sha256: "1d21ad008921942217c9eac0c35b1713773b9d89c71e3ab4412781f7bb88f463" },
170188
+ { key: "assets/webviewBridgeHost-u1DlT1Hn.js", contentType: "application/javascript; charset=utf-8", offset: 3227151, length: 9849, sha256: "a7b2309a785ded4a2cabd9016a5daa60229c7e470a28b81592d431ac462b43b2" },
170189
+ { key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 3237e3, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
170190
+ { key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 3241610, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
170191
+ { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 3730194, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
170192
+ { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 3821118, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
170193
+ { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 3912102, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
170194
+ { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 4003082, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
170195
+ { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 4093954, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
170196
+ { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 4184934, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
170197
+ { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 4293570, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
170198
+ { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 4402654, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
170199
+ { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 4511702, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
170200
+ { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 4619402, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
170201
+ { key: "himi-sw.js", contentType: "application/javascript; charset=utf-8", offset: 4707510, length: 6748, sha256: "4a92459977d7cefa1a6a7e020c3a63509737f083b3f2773557c1a5771665811a" },
170202
+ { key: "index.html", contentType: "text/html; charset=utf-8", offset: 4714258, length: 4947, sha256: "48b12d2dabe7e76a3ca777acd531bc1a85d19d913c2d85b39dd85c5096130b48" },
170203
+ { key: "ios-glass-preview.css", contentType: "text/css; charset=utf-8", offset: 4719205, length: 7193, sha256: "a482f4796147c2a3893942e10ab225bd3b6f749f7125fe0330680d4c20ea0212" },
170204
+ { key: "ios-glass-preview.svg", contentType: "image/svg+xml", offset: 4726398, length: 423, sha256: "b9cd5989d31464a0422f260a332af6be5add0b04de2148944de35158f3b75efc" },
170205
+ { key: "kit-tab-bar.css", contentType: "text/css; charset=utf-8", offset: 4726821, length: 1171, sha256: "9e2c3a0faaf05d5471badf167a4d3bdf1c4e6dd65c432eea6d254158bfd99585" },
170206
+ { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 4727992, length: 18778, sha256: "ba734d58c88281c71c01d9a2842a991d06f3ed91bf03449427ef11c7f6d1605d" }
170046
170207
  ];
170047
170208
  }
170048
170209
  });
@@ -170069,7 +170230,7 @@ function makePackageRunHandler(opts) {
170069
170230
  const store = new FileReleaseStore(opts.releaseRoot);
170070
170231
  const webwixDirect = async () => {
170071
170232
  try {
170072
- return liveWixClientId(await store.getAppConfig(opts.app)) !== void 0;
170233
+ return liveWixBinding(await store.getAppConfig(opts.app));
170073
170234
  } catch {
170074
170235
  return false;
170075
170236
  }
@@ -170081,7 +170242,9 @@ function makePackageRunHandler(opts) {
170081
170242
  ...opts.chrome ? { chrome: opts.chrome } : {},
170082
170243
  header: opts.header ?? null,
170083
170244
  ...opts.screenEvents ? { screenEvents: opts.screenEvents } : {},
170084
- ...opts.liveWix ? { serve: { webwixDirect } } : {}
170245
+ // A One App-bound app's visitor instance is minted HERE, in Node: the tab cannot reach that
170246
+ // endpoint (no CORS), and this plane has no bridge to do it.
170247
+ ...opts.liveWix ? { serve: { webwixDirect, oneAppVisitorFetch: fetch } } : {}
170085
170248
  });
170086
170249
  }
170087
170250
  async function fetchBytes(url) {
@@ -196508,7 +196671,7 @@ async function testCommand(ctx) {
196508
196671
  return results.every((result2) => result2.ok) ? 0 : 1;
196509
196672
  }
196510
196673
  const app = await appId(dir);
196511
- const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2, crawlScreen: crawlScreen2, crawlScreenJourney: crawlScreenJourney2, crawlScreenHostile: crawlScreenHostile2, crawlScreenRelations: crawlScreenRelations2, crawlScreenCapabilitySuccess: crawlScreenCapabilitySuccess2, findingKey: findingKey2, startWorkerCoverage: startWorkerCoverage2, uncoveredFunctions: uncoveredFunctions2, crawlScreenDeep: crawlScreenDeep2, crawlSignature: crawlSignature2, recordScreenTraffic: recordScreenTraffic2, mintVisitor: mintVisitor2, webWixCall: webWixCall2, freezeTrafficToMocks: freezeTrafficToMocks2, bootAndSnapshotState: bootAndSnapshotState2, isUnservedRequest: isUnservedRequest2, renderDescriptorWeb: renderDescriptorWeb2, renderPngBatch: renderPngBatch2, pngAvailable: pngAvailable2, crawlBlockingPasses } = await loadAuthoring();
196674
+ const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2, crawlScreen: crawlScreen2, crawlScreenJourney: crawlScreenJourney2, crawlScreenHostile: crawlScreenHostile2, crawlScreenRelations: crawlScreenRelations2, crawlScreenCapabilitySuccess: crawlScreenCapabilitySuccess2, findingKey: findingKey2, startWorkerCoverage: startWorkerCoverage2, uncoveredFunctions: uncoveredFunctions2, crawlScreenDeep: crawlScreenDeep2, crawlSignature: crawlSignature2, recordScreenTraffic: recordScreenTraffic2, mintVisitor: mintVisitor2, mintOneAppVisitorToken: mintOneAppVisitorToken2, webWixCall: webWixCall2, freezeTrafficToMocks: freezeTrafficToMocks2, bootAndSnapshotState: bootAndSnapshotState2, isUnservedRequest: isUnservedRequest2, renderDescriptorWeb: renderDescriptorWeb2, renderPngBatch: renderPngBatch2, pngAvailable: pngAvailable2, crawlBlockingPasses } = await loadAuthoring();
196512
196675
  const { readTestConfig: readTestConfig2, runCrawl: runCrawl2, formatReport: formatReport2, readCannedResponses: readCannedResponses2, makeRecordingWixCall: makeRecordingWixCall2, runRecordPass: runRecordPass2, runShotsPass: runShotsPass2, defaultNetRules: defaultNetRules2, readNetRules: readNetRules2, scopeDescriptors: scopeDescriptors2, writeRecordedMocks: writeRecordedMocks2 } = await Promise.resolve().then(() => (init_test(), test_exports));
196513
196676
  let config;
196514
196677
  try {
@@ -196697,13 +196860,14 @@ async function testCommand(ctx) {
196697
196860
  let recorded;
196698
196861
  if (record3) {
196699
196862
  const a2 = outcome.auth;
196700
- if (a2?.providerId !== "wix-consumer" || !a2.clientId) {
196863
+ const oneAppMsid = a2?.oneAppMetaSiteId;
196864
+ if (!oneAppMsid && (a2?.providerId !== "wix-consumer" || !a2.clientId)) {
196701
196865
  io2.error(JSON.stringify({
196702
196866
  error: "`himi test --record` requires a WixConsumerAuthProvider clientId in config.ts; none found" + (a2?.providerId ? ` (this app's auth provider is "${a2.providerId}", not "wix-consumer")` : "") + ". Only a Wix Headless consumer client can mint the visitor token that backs the recording reads."
196703
196867
  }));
196704
196868
  return 2;
196705
196869
  }
196706
- if (a2.clientId === PLACEHOLDER_CLIENT_ID) {
196870
+ if (!oneAppMsid && a2?.clientId === PLACEHOLDER_CLIENT_ID) {
196707
196871
  io2.error(JSON.stringify({
196708
196872
  error: `\`himi test --record\` found the scaffolded placeholder clientId "${PLACEHOLDER_CLIENT_ID}" in config.ts \u2014 it cannot mint a visitor token, so every recorded read would fail and the frozen mocks would capture the failures rather than the site. Set a real Wix Headless (wix-consumer) clientId in config.ts, or export WIX_CLIENT_ID. Drop --record to crawl on the existing fixtures.`
196709
196873
  }));
@@ -196711,7 +196875,7 @@ async function testCommand(ctx) {
196711
196875
  }
196712
196876
  let token;
196713
196877
  try {
196714
- token = await mintVisitor2(a2.clientId);
196878
+ token = oneAppMsid ? await mintOneAppVisitorToken2(oneAppMsid) : await mintVisitor2(a2.clientId);
196715
196879
  } catch (e2) {
196716
196880
  io2.error(JSON.stringify({ error: `--record could not mint a visitor token: ${e2.message}. Recording needs network access and a valid Wix Headless clientId.` }));
196717
196881
  return 1;
Binary file
@@ -65,7 +65,7 @@ partial artifacts are diagnostics for recovery, never a usable empty fallback.
65
65
  the complete-manifest check or provide a resume command.
66
66
 
67
67
  The migration invocation authorizes this scoped continuation: plan, local app
68
- implementation, necessary same-site OAuth client reconciliation, validation, and
68
+ implementation, the same-site One App visitor binding, validation, and
69
69
  an authenticated hosted draft. Do not restart generic product discovery or add a
70
70
  generic plan-approval pause. Carry this scope through installed agent instructions
71
71
  and resume sessions. It does not authorize live promotion, native distribution,
@@ -395,7 +395,31 @@ not share mutable filters accidentally. Keep static authored content in the app,
395
395
  and products, services, availability, posts and member records live on the same site.
396
396
  Refresh data after operations without reconnecting layout to the One App editor.
397
397
 
398
- Resolve the same site's mobile OAuth client using the existing idempotent command:
398
+ Bind the app to the same site through its **One App visitor identity**. It is the
399
+ identity a visitor of the source Branded app already has, so it needs no OAuth client
400
+ and creates nothing on the customer's site. The `branded-lite` template does not supply `provisioning.json`:
401
+ bind it directly in the generated app's `config.ts`, with its existing
402
+ `WixConsumerAuthProvider` import and the [Wix auth configuration contract](https://apps.wix.com/_api/himi-serve/docs/wix-api-usage.md).
403
+ Replace the template's placeholders and environment fallbacks so an unrelated local
404
+ `WIX_CLIENT_ID` cannot repoint the build:
405
+
406
+ ```ts
407
+ auth: WixConsumerAuthProvider({
408
+ visitorSource: "one-app",
409
+ metaSiteId: "<source-msid>",
410
+ siteUrl: "<verified-source-website-publicUrl>",
411
+ bootAsVisitor: true,
412
+ preserveVisitorOnSignOut: true,
413
+ }),
414
+ ```
415
+
416
+ Every surface reads the site with it: the native apps, the hosted draft preview, and
417
+ `himi run`, `himi render --live` and `himi test --record`. It is a visitor: member
418
+ sign-in still needs a Headless OAuth client.
419
+
420
+ **Only when the site owner wants member sign-in now**, and with their agreement,
421
+ resolve the site's mobile OAuth client with the existing idempotent command (it is
422
+ an owner-scoped write to the customer's site):
399
423
 
400
424
  ```sh
401
425
  himi site client ensure --site <source-msid> --name <stable-migration-client-name> \
@@ -404,17 +428,13 @@ himi site client ensure --site <source-msid> --name <stable-migration-client-nam
404
428
 
405
429
  Reuse a compatible client first; create or update only as necessary. Preserve its
406
430
  existing redirect URIs when adding the app's redirect. Require a successful,
407
- non-dry-run result and verify its `siteId`, public `clientId` and `redirectUri`.
408
- This command reconciles the OAuth client; it does not configure the generated app.
409
-
410
- The `branded-lite` template does not supply `provisioning.json`. Bind the result
411
- directly in the generated app's `config.ts`, using its existing
412
- `WixConsumerAuthProvider` import and the [Wix auth configuration contract](https://apps.wix.com/_api/himi-serve/docs/wix-api-usage.md).
413
- Replace the template's placeholders and environment fallbacks with this app's
414
- verified binding so an unrelated local `WIX_CLIENT_ID` cannot repoint the build:
431
+ non-dry-run result and verify its `siteId`, public `clientId` and `redirectUri`, then
432
+ add them beside the One App binding:
415
433
 
416
434
  ```ts
417
435
  auth: WixConsumerAuthProvider({
436
+ visitorSource: "one-app",
437
+ metaSiteId: "<source-msid>",
418
438
  clientId: "<returned-public-client-id>",
419
439
  siteUrl: "<verified-source-website-publicUrl>",
420
440
  redirectUri: "<returned-registered-app-redirect-uri>",
@@ -427,8 +447,9 @@ The site URL comes from the verified `website.publicUrl` in the collected Busine
427
447
  context or an existing verified binding; `site client ensure` does not return it.
428
448
  Keep visitor/member gates from the reconstruction plan and resolve a missing site
429
449
  URL against the auth contract instead of shipping a template URL. Verify that the
430
- built app uses the intended client and the exact registered redirect. The public
431
- client ID is app configuration; the collection credential is not.
450
+ built app reads the intended site (and, with a client, uses the exact registered
451
+ redirect). The MetaSite and a public client ID are app configuration; the collection
452
+ credential is not.
432
453
 
433
454
  Use `--write-provisioning <path>` only when a valid adoption manifest already
434
455
  exists, including its identity, branding and installed verticals. That option
@@ -65,11 +65,11 @@ export default defineApp({
65
65
  // …
66
66
  auth: WixConsumerAuthProvider({
67
67
  clientId: "4f58d461-…", // the site's headless clientId — THIS is the site binding
68
- // (metaSiteId is implied by it; there is no separate field)
68
+ // (metaSiteId is implied by it; `metaSiteId` is only for one-app mode below)
69
69
  siteUrl: "https://<site>.wixsite.com/<slug>",
70
- redirectUri: "himalaya-<app>://oauth/callback", // REQUIRED — the provider throws
70
+ redirectUri: "himalaya-<app>://oauth/callback", // REQUIRED with a clientId — the provider throws
71
71
  // "WixConsumerAuthProvider: redirectUri is required." without it,
72
- // even when bootAsVisitor is true (the check fires unconditionally).
72
+ // even when bootAsVisitor is true.
73
73
  // Use your app's URL scheme; the scaffolds ship this exact shape.
74
74
  bootAsVisitor: true, // mint an anonymous visitor token at boot
75
75
  }),
@@ -85,6 +85,28 @@ members, etc. Scope is **visitor**: reads a site exposes anonymously work; owner
85
85
  live at `@himalaya/wix-auth` in-repo / `@wix/himalaya/wix-auth` off-repo — `himi sdk` lists the runtime
86
86
  data clients, not these config-time providers).
87
87
 
88
+ **No OAuth client on the site? Bind by MetaSite instead (`visitorSource: "one-app"`).** A Headless
89
+ OAuth client can only be created by the site's owner. An app migrated from a Branded One App reads its
90
+ site the way that app's visitors already do — the site's **One App visitor signed instance** — so it
91
+ needs no client and creates nothing on the site:
92
+
93
+ ```ts
94
+ auth: WixConsumerAuthProvider({
95
+ visitorSource: "one-app",
96
+ metaSiteId: "0c55162c-…", // the site's MetaSite ID
97
+ siteUrl: "https://www.<site>.com/",
98
+ bootAsVisitor: true,
99
+ }),
100
+ ```
101
+
102
+ The instance comes from `GET apps.wix.com/_api/one-app-session-web/v3/businesses/<metaSiteId>/signed-instance?signed_instance_type=Visitor`
103
+ (no credentials) and is sent as a bare `Authorization` header (`Bearer <instance>` is a 400). Native
104
+ mints it directly; the browser cannot (no CORS), so the app's own origin mints it at `/v1/visitor/instance`;
105
+ `himi run`, `render --live` and `test --record` mint it in Node. Each mint is a new visitor, so it is
106
+ kept until its `validUntil` (~4h) and re-minted only once expired — a 401 on an unexpired instance is
107
+ the endpoint's answer (members-only reads refuse every visitor). Scope is visitor: member sign-in still
108
+ needs a `clientId` (+ `redirectUri`), which you may add beside it.
109
+
88
110
  Monorepo / native Branded Lite (env overrides, auth bake, shareable binary with icon/splash):
89
111
  [branded-lite-site-binding.md](branded-lite-site-binding.md).
90
112
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.1541.0",
3
+ "version": "0.1543.0",
4
4
  "type": "module",
5
5
  "description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
6
6
  "keywords": [
@@ -71,5 +71,5 @@
71
71
  "artifactId": "himalaya-cli"
72
72
  }
73
73
  },
74
- "falconPackageHash": "77f49a0fa384b30d68adfb678fda491e11084dd3f66b62764b113aaf"
74
+ "falconPackageHash": "09228c43934e4e9f2b68984330c9830359aca30af7bd2c96c0073572"
75
75
  }
@@ -200,8 +200,11 @@ const memberKey = (member: { email: string; scope?: string }) => member.email ?
200
200
  let cacheWrite = Promise.resolve();
201
201
  const svc = defineBackendCollection("himiBrandedOrders", {
202
202
  restorePagesOnLoad: true,
203
+ // `nextCursor` and `filterOptions` are bound by himi_orders (pagination cursor, filter sheet), so they are
204
+ // seeded here: `himi validate --strict` refuses a binding the initial state cannot resolve.
203
205
  state: derive({ status: "loading", rows: [], identityLine: "", emptyText: "", isLoading: true,
204
- notLoading: false, isErrored: false, notErrored: true, noEmpty: true, hideList: true, siteHint: "" }),
206
+ notLoading: false, isErrored: false, notErrored: true, noEmpty: true, hideList: true, siteHint: "",
207
+ nextCursor: "", filterOptions: [] }),
205
208
  source: {
206
209
  id: (row: OrderRow) => row.id,
207
210
  clearOnError: orderAccessDenied,
@@ -200,8 +200,11 @@ const memberKey = (member: { email: string; scope?: string }) => member.email ?
200
200
  let cacheWrite = Promise.resolve();
201
201
  const svc = defineBackendCollection("himiBrandedOrders", {
202
202
  restorePagesOnLoad: true,
203
+ // `nextCursor` and `filterOptions` are bound by himi_orders (pagination cursor, filter sheet), so they are
204
+ // seeded here: `himi validate --strict` refuses a binding the initial state cannot resolve.
203
205
  state: derive({ status: "loading", rows: [], identityLine: "", emptyText: "", isLoading: true,
204
- notLoading: false, isErrored: false, notErrored: true, noEmpty: true, hideList: true, siteHint: "" }),
206
+ notLoading: false, isErrored: false, notErrored: true, noEmpty: true, hideList: true, siteHint: "",
207
+ nextCursor: "", filterOptions: [] }),
205
208
  source: {
206
209
  id: (row: OrderRow) => row.id,
207
210
  clearOnError: orderAccessDenied,
@@ -200,8 +200,11 @@ const memberKey = (member: { email: string; scope?: string }) => member.email ?
200
200
  let cacheWrite = Promise.resolve();
201
201
  const svc = defineBackendCollection("himiBrandedOrders", {
202
202
  restorePagesOnLoad: true,
203
+ // `nextCursor` and `filterOptions` are bound by himi_orders (pagination cursor, filter sheet), so they are
204
+ // seeded here: `himi validate --strict` refuses a binding the initial state cannot resolve.
203
205
  state: derive({ status: "loading", rows: [], identityLine: "", emptyText: "", isLoading: true,
204
- notLoading: false, isErrored: false, notErrored: true, noEmpty: true, hideList: true, siteHint: "" }),
206
+ notLoading: false, isErrored: false, notErrored: true, noEmpty: true, hideList: true, siteHint: "",
207
+ nextCursor: "", filterOptions: [] }),
205
208
  source: {
206
209
  id: (row: OrderRow) => row.id,
207
210
  clearOnError: orderAccessDenied,
@@ -200,8 +200,11 @@ const memberKey = (member: { email: string; scope?: string }) => member.email ?
200
200
  let cacheWrite = Promise.resolve();
201
201
  const svc = defineBackendCollection("himiBrandedOrders", {
202
202
  restorePagesOnLoad: true,
203
+ // `nextCursor` and `filterOptions` are bound by himi_orders (pagination cursor, filter sheet), so they are
204
+ // seeded here: `himi validate --strict` refuses a binding the initial state cannot resolve.
203
205
  state: derive({ status: "loading", rows: [], identityLine: "", emptyText: "", isLoading: true,
204
- notLoading: false, isErrored: false, notErrored: true, noEmpty: true, hideList: true, siteHint: "" }),
206
+ notLoading: false, isErrored: false, notErrored: true, noEmpty: true, hideList: true, siteHint: "",
207
+ nextCursor: "", filterOptions: [] }),
205
208
  source: {
206
209
  id: (row: OrderRow) => row.id,
207
210
  clearOnError: orderAccessDenied,
@@ -200,8 +200,11 @@ const memberKey = (member: { email: string; scope?: string }) => member.email ?
200
200
  let cacheWrite = Promise.resolve();
201
201
  const svc = defineBackendCollection("himiBrandedOrders", {
202
202
  restorePagesOnLoad: true,
203
+ // `nextCursor` and `filterOptions` are bound by himi_orders (pagination cursor, filter sheet), so they are
204
+ // seeded here: `himi validate --strict` refuses a binding the initial state cannot resolve.
203
205
  state: derive({ status: "loading", rows: [], identityLine: "", emptyText: "", isLoading: true,
204
- notLoading: false, isErrored: false, notErrored: true, noEmpty: true, hideList: true, siteHint: "" }),
206
+ notLoading: false, isErrored: false, notErrored: true, noEmpty: true, hideList: true, siteHint: "",
207
+ nextCursor: "", filterOptions: [] }),
205
208
  source: {
206
209
  id: (row: OrderRow) => row.id,
207
210
  clearOnError: orderAccessDenied,