@wix/himalaya-cli 0.963.0 → 0.965.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.
Files changed (21) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/auth-providers/wix/src/engine-timers.d.ts +17 -0
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/auth-providers/wix/src/index.d.ts +1 -0
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/auth-providers/wix/src/worker-safe.d.ts +1 -0
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/time.mjs +1 -1
  5. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-auth/worker.mjs +24 -2
  6. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-auth.mjs +24 -2
  7. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-stores.mjs +121 -7
  8. package/dist/cli.mjs +13 -15
  9. package/dist/preview-assets.generated.bin +0 -0
  10. package/package.json +2 -2
  11. package/templates/beauty-salon-owner/tier5-src/_shared/aria-chat.ts +14 -1
  12. package/templates/community-club-owner/tier5-src/_shared/aria-chat.ts +14 -1
  13. package/templates/events-meetups-owner/tier5-src/_shared/aria-chat.ts +14 -1
  14. package/templates/gym-fitness-owner/tier5-src/_shared/aria-chat.ts +14 -1
  15. package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-chat.ts +14 -1
  16. package/templates/owner-lite/tier5-src/_shared/aria-chat.ts +14 -1
  17. package/templates/podcast-creator-owner/tier5-src/_shared/aria-chat.ts +14 -1
  18. package/templates/portfolio-creative-owner/tier5-src/_shared/aria-chat.ts +14 -1
  19. package/templates/restaurant-owner/tier5-src/_shared/aria-chat.ts +14 -1
  20. package/templates/retail-store-owner/tier5-src/_shared/aria-chat.ts +14 -1
  21. package/templates/yoga-studio-owner/tier5-src/_shared/aria-chat.ts +14 -1
@@ -0,0 +1,17 @@
1
+ /** Thrown by the default `sleep` on an engine with no timers, instead of a bare `ReferenceError`
2
+ * escaping a Promise executor. Named so a caller can tell a missing seam from a network fault. */
3
+ export declare class NoTimerError extends Error {
4
+ constructor(what: string);
5
+ }
6
+ /**
7
+ * The default pacing seam for the polling ceremonies: a real timed wait where the engine has
8
+ * timers, a named rejection where it does not.
9
+ *
10
+ * `what` names the caller so the message points at the config that needs a `sleep`.
11
+ *
12
+ * The global is read as a PROPERTY of `globalThis` — `undefined` on an engine that lacks it —
13
+ * rather than as the bare identifier that throws, and it is invoked with `globalThis` as its
14
+ * receiver: a DETACHED browser `setTimeout` raises "Illegal invocation", so `timer(fn, ms)`
15
+ * would have traded one engine's failure for another's.
16
+ */
17
+ export declare function engineSleep(what: string): (ms: number) => Promise<void>;
@@ -8,6 +8,7 @@ export { SessionIDService, InMemorySessionIDStore, bsiShouldRotate, localDayInde
8
8
  export { policyFor as wixRequestPolicy, isFirstPartyWixHost, isSignedUploadTarget, type MobileRequestKind, type RequestPolicy, } from "./request-policy.js";
9
9
  export { METASITE_HEADER, SIGNED_INSTANCE_EXP_HEADER, AUTH_PROXY_PREFIX, authProxyHeaders, authProxyPseudoInstance, isAuthProxyInstance, authProxyBusinessId, parseSignedInstanceExp, isSignedInstanceExpired, } from "./auth-proxy.js";
10
10
  export { DeviceAuthClient, DeviceAuthError, parseDeviceQr, type DeviceAuthorization, type DeviceAuthTokens, type DeviceAuthResult, type DeviceAuthConfig, type DeviceAuthTerminal, } from "./device-auth.js";
11
+ export { NoTimerError, engineSleep } from "./engine-timers.js";
11
12
  export { buildRegistrationOptions, buildAuthenticationOptions, authenticatorDataCounter, assertSignCountAdvanced, PasskeyCloneError, type RegistrationOptions, type AuthenticationOptions, } from "./passkey-ceremony.js";
12
13
  export { WixAuthModalities, classifyAuthErrorCode, type PushApprovalState, type AuthModalitiesConfig, } from "./auth-modalities.js";
13
14
  export { shouldEscalateCaptcha, captchaResponseFields, CaptchaEscalation, CAPTCHA_ESCALATION_CODES, type CaptchaTier, } from "./captcha-escalation.js";
@@ -1,5 +1,6 @@
1
1
  export * from "./device-auth.js";
2
2
  export * from "./auth-modalities.js";
3
+ export * from "./engine-timers.js";
3
4
  export * from "./captcha-escalation.js";
4
5
  export * from "./passkey-ceremony.js";
5
6
  export * from "./session-id.js";
@@ -57,7 +57,7 @@ function relativeDayWord(diff, opts) {
57
57
  const RTF = globalThis.Intl?.RelativeTimeFormat;
58
58
  if (typeof RTF === "function") {
59
59
  try {
60
- const words = new Intl.RelativeTimeFormat(opts.locale, { numeric: "auto" }).format(diff, "day");
60
+ const words = new RTF(opts.locale, { numeric: "auto" }).format(diff, "day");
61
61
  if (words) return words.charAt(0).toUpperCase() + words.slice(1);
62
62
  } catch {
63
63
  }
@@ -2,6 +2,26 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
 
5
+ // ../../stdlib/auth-providers/wix/src/engine-timers.ts
6
+ var NoTimerError = class extends Error {
7
+ constructor(what) {
8
+ super(
9
+ `${what} needs to pace its polling, but this engine has no setTimeout (JSC worker scopes and QuickJS-ng have none). Pass a \`sleep\` in the config.`
10
+ );
11
+ this.name = "NoTimerError";
12
+ }
13
+ };
14
+ function engineSleep(what) {
15
+ return (ms) => {
16
+ const host = globalThis;
17
+ const timer = host.setTimeout;
18
+ if (typeof timer !== "function") return Promise.reject(new NoTimerError(what));
19
+ return new Promise((resolve) => {
20
+ timer.call(host, () => resolve(), ms);
21
+ });
22
+ };
23
+ }
24
+
5
25
  // ../../stdlib/auth-providers/wix/src/device-auth.ts
6
26
  var DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
7
27
  var DeviceAuthError = class extends Error {
@@ -47,7 +67,7 @@ var DeviceAuthClient = class {
47
67
  this.baseURL = config.baseURL ?? "https://www.wixapis.com";
48
68
  this.fetchImpl = config.fetchImpl ?? globalThis.fetch;
49
69
  this.now = config.now ?? Date.now;
50
- this.sleep = config.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
70
+ this.sleep = config.sleep ?? engineSleep("DeviceAuthClient");
51
71
  this.devMode = config.devMode ?? false;
52
72
  }
53
73
  /** Constrained-device side: request a device_code + user_code (show as QR). */
@@ -457,7 +477,7 @@ var WixAuthModalities = class {
457
477
  __publicField(this, "devMode");
458
478
  this.baseURL = config.baseURL ?? "https://users.wix.com";
459
479
  this.fetchImpl = config.fetchImpl ?? globalThis.fetch;
460
- this.sleep = config.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
480
+ this.sleep = config.sleep ?? engineSleep("WixAuthModalities");
461
481
  this.devMode = config.devMode ?? false;
462
482
  }
463
483
  /** Passwordless: email the user a magic sign-in link. Always "succeeds" for
@@ -1016,6 +1036,7 @@ export {
1016
1036
  InMemorySignedInstanceStorage,
1017
1037
  METASITE_HEADER,
1018
1038
  NativeAuthError,
1039
+ NoTimerError,
1019
1040
  OAUTH_AUTHORIZE_ENDPOINT,
1020
1041
  PasskeyCloneError,
1021
1042
  REDACTED,
@@ -1040,6 +1061,7 @@ export {
1040
1061
  captchaResponseFields,
1041
1062
  classifyAuthErrorCode,
1042
1063
  dualDomainAuthorizeUrls,
1064
+ engineSleep,
1043
1065
  isAuthProxyInstance,
1044
1066
  isFirstPartyWixHost,
1045
1067
  isSensitiveFreeTextName,
@@ -682,6 +682,26 @@ function pickHeader(headers, name) {
682
682
  return void 0;
683
683
  }
684
684
 
685
+ // ../../stdlib/auth-providers/wix/src/engine-timers.ts
686
+ var NoTimerError = class extends Error {
687
+ constructor(what) {
688
+ super(
689
+ `${what} needs to pace its polling, but this engine has no setTimeout (JSC worker scopes and QuickJS-ng have none). Pass a \`sleep\` in the config.`
690
+ );
691
+ this.name = "NoTimerError";
692
+ }
693
+ };
694
+ function engineSleep(what) {
695
+ return (ms) => {
696
+ const host = globalThis;
697
+ const timer = host.setTimeout;
698
+ if (typeof timer !== "function") return Promise.reject(new NoTimerError(what));
699
+ return new Promise((resolve) => {
700
+ timer.call(host, () => resolve(), ms);
701
+ });
702
+ };
703
+ }
704
+
685
705
  // ../../stdlib/auth-providers/wix/src/device-auth.ts
686
706
  var DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
687
707
  var DeviceAuthError = class extends Error {
@@ -727,7 +747,7 @@ var DeviceAuthClient = class {
727
747
  this.baseURL = config.baseURL ?? "https://www.wixapis.com";
728
748
  this.fetchImpl = config.fetchImpl ?? globalThis.fetch;
729
749
  this.now = config.now ?? Date.now;
730
- this.sleep = config.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
750
+ this.sleep = config.sleep ?? engineSleep("DeviceAuthClient");
731
751
  this.devMode = config.devMode ?? false;
732
752
  }
733
753
  /** Constrained-device side: request a device_code + user_code (show as QR). */
@@ -890,7 +910,7 @@ var WixAuthModalities = class {
890
910
  __publicField(this, "devMode");
891
911
  this.baseURL = config.baseURL ?? "https://users.wix.com";
892
912
  this.fetchImpl = config.fetchImpl ?? globalThis.fetch;
893
- this.sleep = config.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
913
+ this.sleep = config.sleep ?? engineSleep("WixAuthModalities");
894
914
  this.devMode = config.devMode ?? false;
895
915
  }
896
916
  /** Passwordless: email the user a magic sign-in link. Always "succeeds" for
@@ -1173,6 +1193,7 @@ export {
1173
1193
  METASITE_HEADER,
1174
1194
  MemberCaptchaPolicyStore,
1175
1195
  NativeAuthError,
1196
+ NoTimerError,
1176
1197
  OAUTH_AUTHORIZE_ENDPOINT,
1177
1198
  PasskeyCloneError,
1178
1199
  REDACTED,
@@ -1204,6 +1225,7 @@ export {
1204
1225
  captchaTokensField,
1205
1226
  classifyAuthErrorCode,
1206
1227
  dualDomainAuthorizeUrls,
1228
+ engineSleep,
1207
1229
  isAuthProxyInstance,
1208
1230
  isCaptchaDemandState,
1209
1231
  isFirstPartyWixHost,
@@ -428,24 +428,138 @@ var CURRENCY_SYMBOL = {
428
428
  GBP: "\xA3",
429
429
  ILS: "\u20AA",
430
430
  AUD: "A$",
431
- CAD: "C$",
431
+ CAD: "CA$",
432
432
  JPY: "\xA5",
433
- INR: "\u20B9"
433
+ INR: "\u20B9",
434
+ KRW: "\u20A9",
435
+ CNY: "CN\xA5",
436
+ HKD: "HK$",
437
+ TWD: "NT$",
438
+ NZD: "NZ$",
439
+ MXN: "MX$",
440
+ BRL: "R$",
441
+ PHP: "\u20B1",
442
+ VND: "\u20AB",
443
+ XCD: "EC$",
444
+ XAF: "FCFA\xA0",
445
+ XOF: "F\u202FCFA\xA0",
446
+ XPF: "CFPF\xA0",
447
+ XCG: "Cg.\xA0",
448
+ // XXX is ISO 4217's "no currency", and ICU renders it with the GENERIC CURRENCY SIGN rather
449
+ // than the code. It is the one well-formed code that is not a currency, so it is exactly the
450
+ // one a hand-written table forgets — a catalog that returns `currency: "XXX"` for an unpriced
451
+ // item rendered "¤25.00" with Intl and "XXX 25.00" without it. The whole-alphabet sweep in
452
+ // `display-engine-floor.test.ts` is what found it, and is what keeps this table complete.
453
+ XXX: "\xA4"
434
454
  };
435
- function productCurrency(p) {
436
- return p.currency || p.priceData?.currency || p.price?.currency || p.actualPriceRange?.minValue?.currency || "";
455
+ var ZERO_DECIMAL_CURRENCY = {
456
+ AFN: true,
457
+ ALL: true,
458
+ BIF: true,
459
+ CLP: true,
460
+ COP: true,
461
+ DJF: true,
462
+ GNF: true,
463
+ HUF: true,
464
+ IDR: true,
465
+ IQD: true,
466
+ IRR: true,
467
+ ISK: true,
468
+ JPY: true,
469
+ KMF: true,
470
+ KPW: true,
471
+ KRW: true,
472
+ LAK: true,
473
+ LBP: true,
474
+ MGA: true,
475
+ MMK: true,
476
+ PKR: true,
477
+ PYG: true,
478
+ RWF: true,
479
+ SLL: true,
480
+ SOS: true,
481
+ SYP: true,
482
+ UGX: true,
483
+ VND: true,
484
+ VUV: true,
485
+ XAF: true,
486
+ XOF: true,
487
+ XPF: true,
488
+ YER: true,
489
+ // WITHDRAWN codes, every one found by the sweep rather than by reading a list. A catalog that
490
+ // has not been touched since the euro changeover still returns ESP or ITL, and ICU still
491
+ // formats them — so "obsolete" is not the same as "unreachable", and each was a live
492
+ // divergence ("ESP 25" with Intl, "ESP 25.00" without).
493
+ ADP: true,
494
+ BYR: true,
495
+ ESP: true,
496
+ ITL: true,
497
+ LUF: true,
498
+ MGF: true,
499
+ MRO: true,
500
+ STD: true,
501
+ TMM: true,
502
+ TRL: true,
503
+ UYI: true,
504
+ ZMK: true,
505
+ ZWD: true
506
+ };
507
+ function hasIntl() {
508
+ return typeof Intl !== "undefined" && typeof Intl.NumberFormat === "function";
509
+ }
510
+ function groupThousands(fixed) {
511
+ const parts = fixed.split(".");
512
+ const whole = parts[0];
513
+ let out = "";
514
+ for (let i = 0; i < whole.length; i++) {
515
+ if (i > 0 && (whole.length - i) % 3 === 0) out += ",";
516
+ out += whole[i];
517
+ }
518
+ return parts.length > 1 ? `${out}.${parts[1]}` : out;
437
519
  }
520
+ function roundHalfExpand(abs, digits) {
521
+ const shifted = Number(`${abs}e${digits}`);
522
+ if (!Number.isFinite(shifted)) return abs;
523
+ const back = Number(`${Math.round(shifted)}e-${digits}`);
524
+ return Number.isFinite(back) ? back : abs;
525
+ }
526
+ var MAX_PRICE_DIGITS = 2;
438
527
  function formatMoney(amount, currency) {
439
528
  const num = typeof amount === "number" ? amount : Number(amount);
440
529
  if (currency && Number.isFinite(num)) {
441
- try {
442
- return new Intl.NumberFormat("en", { style: "currency", currency, maximumFractionDigits: 2 }).format(num);
443
- } catch {
530
+ if (hasIntl()) {
531
+ try {
532
+ return new Intl.NumberFormat("en", { style: "currency", currency, maximumFractionDigits: MAX_PRICE_DIGITS }).format(num);
533
+ } catch {
534
+ }
535
+ } else {
536
+ const code = currency.toUpperCase();
537
+ if (/^[A-Z]{3}$/.test(code)) return fallbackMoney(num, code);
444
538
  }
445
539
  }
446
540
  const symbol = currency ? CURRENCY_SYMBOL[currency] ?? "" : "";
447
541
  return symbol ? `${symbol}${amount}` : `${amount}`;
448
542
  }
543
+ function fallbackMoney(num, code) {
544
+ const sign = num < 0 ? "-" : "";
545
+ const abs = Math.abs(num);
546
+ let body = roundHalfExpand(abs, MAX_PRICE_DIGITS).toFixed(MAX_PRICE_DIGITS);
547
+ if (body.indexOf("e") >= 0 || body.indexOf("E") >= 0) {
548
+ body = String(abs);
549
+ } else {
550
+ const minDigits = ZERO_DECIMAL_CURRENCY[code] ? 0 : MAX_PRICE_DIGITS;
551
+ while (body.indexOf(".") >= 0 && body.length - body.indexOf(".") - 1 > minDigits && body.charAt(body.length - 1) === "0") {
552
+ body = body.slice(0, -1);
553
+ }
554
+ if (body.charAt(body.length - 1) === ".") body = body.slice(0, -1);
555
+ body = groupThousands(body);
556
+ }
557
+ const symbol = CURRENCY_SYMBOL[code];
558
+ return symbol ? `${sign}${symbol}${body}` : `${sign}${code}\xA0${body}`;
559
+ }
560
+ function productCurrency(p) {
561
+ return p.currency || p.priceData?.currency || p.price?.currency || p.actualPriceRange?.minValue?.currency || "";
562
+ }
449
563
  function productPrice(p) {
450
564
  const preformatted = p.priceData?.formatted?.price || p.price?.formatted?.price || p.actualPriceRange?.minValue?.formattedAmount;
451
565
  if (preformatted) return preformatted;
package/dist/cli.mjs CHANGED
@@ -18547,7 +18547,6 @@ function shouldRevealError(args) {
18547
18547
  var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
18548
18548
  var init_validation = __esm({
18549
18549
  "../../core/ts/src/validation.ts"() {
18550
- "use strict";
18551
18550
  EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
18552
18551
  URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
18553
18552
  INTEGER_RE = /^[+-]?[0-9]+$/;
@@ -21972,7 +21971,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
21972
21971
  var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
21973
21972
  var init_worker_subtree = __esm({
21974
21973
  "../../core/ts/src/worker-subtree.ts"() {
21975
- "use strict";
21976
21974
  init_worker_subtree_safe_types_generated();
21977
21975
  WORKER_SUBTREE_CEILINGS = Object.freeze({
21978
21976
  maxEncodedBytes: 65536,
@@ -43359,19 +43357,19 @@ var init_preview_assets_generated = __esm({
43359
43357
  "../../packages/serve/src/preview-assets.generated.ts"() {
43360
43358
  init_preview_assets_format();
43361
43359
  PREVIEW_ASSET_MANIFEST = [
43362
- { key: "assets/index-BdjUMoXo.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 985049, sha256: "f401b5ebead76d81b1f3d1d401b77925b53123856ababfc4d2d407656c10601d" },
43363
- { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 985057, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
43364
- { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1075981, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
43365
- { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1166965, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
43366
- { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1257945, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
43367
- { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1348817, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
43368
- { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 1439797, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
43369
- { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 1548433, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
43370
- { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 1657517, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
43371
- { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 1766565, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
43372
- { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 1874265, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
43373
- { key: "index.html", contentType: "text/html; charset=utf-8", offset: 1962373, length: 4448, sha256: "03bf2b6c0fec31fec522df8100cdc53a195a5fe4b792d9dc2888476cb5226624" },
43374
- { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 1966821, length: 13784, sha256: "cfb9465254fab84f0e084bb4542c282758ea29774b5f172840cc0b9e4194ef89" }
43360
+ { key: "assets/index-BlqJ6MkY.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 985027, sha256: "1db151e9d0c547283501228ad0e7f6edd9ef257b04ae911ce939080b8eb66de9" },
43361
+ { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 985035, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
43362
+ { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1075959, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
43363
+ { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1166943, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
43364
+ { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1257923, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
43365
+ { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1348795, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
43366
+ { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 1439775, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
43367
+ { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 1548411, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
43368
+ { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 1657495, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
43369
+ { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 1766543, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
43370
+ { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 1874243, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
43371
+ { key: "index.html", contentType: "text/html; charset=utf-8", offset: 1962351, length: 4448, sha256: "b53a1165bdc4d5bbad25d8707e51f94d2928807521df4b01498d4bc32d7c46b8" },
43372
+ { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 1966799, length: 13784, sha256: "cfb9465254fab84f0e084bb4542c282758ea29774b5f172840cc0b9e4194ef89" }
43375
43373
  ];
43376
43374
  }
43377
43375
  });
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.963.0",
3
+ "version": "0.965.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": [
@@ -64,5 +64,5 @@
64
64
  "artifactId": "himalaya-cli"
65
65
  }
66
66
  },
67
- "falconPackageHash": "dbb3eeb010fcbce0f61b1efca974a99bfaa2c93d927b5d5405c8c34c"
67
+ "falconPackageHash": "070f35e7248854d18a4d539ddbf96c1e282ed1f644a96db961470496"
68
68
  }
@@ -1891,7 +1891,20 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
1891
1891
  if (!url) return s;
1892
1892
  const target = o.resolveEntity?.(url) ?? null;
1893
1893
  if (target) return navigate(s, target);
1894
- if (o.openLink) { try { await o.openLink(url); } catch { /* best-effort */ } }
1894
+ // THE SINK, and it had no scheme check until now — measured against the
1895
+ // built bundle, `openLink` handed `tel:`, `myapp://` and `javascript:`
1896
+ // straight to `capability.open_url.open`.
1897
+ //
1898
+ // The in-app resolution ABOVE is deliberately left alone: it matches
1899
+ // dashboard paths and answers null for anything else, so it cannot be
1900
+ // steered by a scheme, and guarding earlier would also reject the `id`
1901
+ // form this action still accepts.
1902
+ //
1903
+ // Not currently exploitable — `extractLinks` only matches `https?://`, so
1904
+ // nothing reaches here with another scheme today. That is exactly why it
1905
+ // is worth adding: the widget footer already refuses a second time at its
1906
+ // own sink, and this path was relying on a single filter for the same rule.
1907
+ if (o.openLink && isWebUrl(url)) { try { await o.openLink(url); } catch { /* best-effort */ } }
1895
1908
  return s;
1896
1909
  },
1897
1910
 
@@ -1891,7 +1891,20 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
1891
1891
  if (!url) return s;
1892
1892
  const target = o.resolveEntity?.(url) ?? null;
1893
1893
  if (target) return navigate(s, target);
1894
- if (o.openLink) { try { await o.openLink(url); } catch { /* best-effort */ } }
1894
+ // THE SINK, and it had no scheme check until now — measured against the
1895
+ // built bundle, `openLink` handed `tel:`, `myapp://` and `javascript:`
1896
+ // straight to `capability.open_url.open`.
1897
+ //
1898
+ // The in-app resolution ABOVE is deliberately left alone: it matches
1899
+ // dashboard paths and answers null for anything else, so it cannot be
1900
+ // steered by a scheme, and guarding earlier would also reject the `id`
1901
+ // form this action still accepts.
1902
+ //
1903
+ // Not currently exploitable — `extractLinks` only matches `https?://`, so
1904
+ // nothing reaches here with another scheme today. That is exactly why it
1905
+ // is worth adding: the widget footer already refuses a second time at its
1906
+ // own sink, and this path was relying on a single filter for the same rule.
1907
+ if (o.openLink && isWebUrl(url)) { try { await o.openLink(url); } catch { /* best-effort */ } }
1895
1908
  return s;
1896
1909
  },
1897
1910
 
@@ -1891,7 +1891,20 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
1891
1891
  if (!url) return s;
1892
1892
  const target = o.resolveEntity?.(url) ?? null;
1893
1893
  if (target) return navigate(s, target);
1894
- if (o.openLink) { try { await o.openLink(url); } catch { /* best-effort */ } }
1894
+ // THE SINK, and it had no scheme check until now — measured against the
1895
+ // built bundle, `openLink` handed `tel:`, `myapp://` and `javascript:`
1896
+ // straight to `capability.open_url.open`.
1897
+ //
1898
+ // The in-app resolution ABOVE is deliberately left alone: it matches
1899
+ // dashboard paths and answers null for anything else, so it cannot be
1900
+ // steered by a scheme, and guarding earlier would also reject the `id`
1901
+ // form this action still accepts.
1902
+ //
1903
+ // Not currently exploitable — `extractLinks` only matches `https?://`, so
1904
+ // nothing reaches here with another scheme today. That is exactly why it
1905
+ // is worth adding: the widget footer already refuses a second time at its
1906
+ // own sink, and this path was relying on a single filter for the same rule.
1907
+ if (o.openLink && isWebUrl(url)) { try { await o.openLink(url); } catch { /* best-effort */ } }
1895
1908
  return s;
1896
1909
  },
1897
1910
 
@@ -1891,7 +1891,20 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
1891
1891
  if (!url) return s;
1892
1892
  const target = o.resolveEntity?.(url) ?? null;
1893
1893
  if (target) return navigate(s, target);
1894
- if (o.openLink) { try { await o.openLink(url); } catch { /* best-effort */ } }
1894
+ // THE SINK, and it had no scheme check until now — measured against the
1895
+ // built bundle, `openLink` handed `tel:`, `myapp://` and `javascript:`
1896
+ // straight to `capability.open_url.open`.
1897
+ //
1898
+ // The in-app resolution ABOVE is deliberately left alone: it matches
1899
+ // dashboard paths and answers null for anything else, so it cannot be
1900
+ // steered by a scheme, and guarding earlier would also reject the `id`
1901
+ // form this action still accepts.
1902
+ //
1903
+ // Not currently exploitable — `extractLinks` only matches `https?://`, so
1904
+ // nothing reaches here with another scheme today. That is exactly why it
1905
+ // is worth adding: the widget footer already refuses a second time at its
1906
+ // own sink, and this path was relying on a single filter for the same rule.
1907
+ if (o.openLink && isWebUrl(url)) { try { await o.openLink(url); } catch { /* best-effort */ } }
1895
1908
  return s;
1896
1909
  },
1897
1910
 
@@ -1891,7 +1891,20 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
1891
1891
  if (!url) return s;
1892
1892
  const target = o.resolveEntity?.(url) ?? null;
1893
1893
  if (target) return navigate(s, target);
1894
- if (o.openLink) { try { await o.openLink(url); } catch { /* best-effort */ } }
1894
+ // THE SINK, and it had no scheme check until now — measured against the
1895
+ // built bundle, `openLink` handed `tel:`, `myapp://` and `javascript:`
1896
+ // straight to `capability.open_url.open`.
1897
+ //
1898
+ // The in-app resolution ABOVE is deliberately left alone: it matches
1899
+ // dashboard paths and answers null for anything else, so it cannot be
1900
+ // steered by a scheme, and guarding earlier would also reject the `id`
1901
+ // form this action still accepts.
1902
+ //
1903
+ // Not currently exploitable — `extractLinks` only matches `https?://`, so
1904
+ // nothing reaches here with another scheme today. That is exactly why it
1905
+ // is worth adding: the widget footer already refuses a second time at its
1906
+ // own sink, and this path was relying on a single filter for the same rule.
1907
+ if (o.openLink && isWebUrl(url)) { try { await o.openLink(url); } catch { /* best-effort */ } }
1895
1908
  return s;
1896
1909
  },
1897
1910
 
@@ -1891,7 +1891,20 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
1891
1891
  if (!url) return s;
1892
1892
  const target = o.resolveEntity?.(url) ?? null;
1893
1893
  if (target) return navigate(s, target);
1894
- if (o.openLink) { try { await o.openLink(url); } catch { /* best-effort */ } }
1894
+ // THE SINK, and it had no scheme check until now — measured against the
1895
+ // built bundle, `openLink` handed `tel:`, `myapp://` and `javascript:`
1896
+ // straight to `capability.open_url.open`.
1897
+ //
1898
+ // The in-app resolution ABOVE is deliberately left alone: it matches
1899
+ // dashboard paths and answers null for anything else, so it cannot be
1900
+ // steered by a scheme, and guarding earlier would also reject the `id`
1901
+ // form this action still accepts.
1902
+ //
1903
+ // Not currently exploitable — `extractLinks` only matches `https?://`, so
1904
+ // nothing reaches here with another scheme today. That is exactly why it
1905
+ // is worth adding: the widget footer already refuses a second time at its
1906
+ // own sink, and this path was relying on a single filter for the same rule.
1907
+ if (o.openLink && isWebUrl(url)) { try { await o.openLink(url); } catch { /* best-effort */ } }
1895
1908
  return s;
1896
1909
  },
1897
1910
 
@@ -1891,7 +1891,20 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
1891
1891
  if (!url) return s;
1892
1892
  const target = o.resolveEntity?.(url) ?? null;
1893
1893
  if (target) return navigate(s, target);
1894
- if (o.openLink) { try { await o.openLink(url); } catch { /* best-effort */ } }
1894
+ // THE SINK, and it had no scheme check until now — measured against the
1895
+ // built bundle, `openLink` handed `tel:`, `myapp://` and `javascript:`
1896
+ // straight to `capability.open_url.open`.
1897
+ //
1898
+ // The in-app resolution ABOVE is deliberately left alone: it matches
1899
+ // dashboard paths and answers null for anything else, so it cannot be
1900
+ // steered by a scheme, and guarding earlier would also reject the `id`
1901
+ // form this action still accepts.
1902
+ //
1903
+ // Not currently exploitable — `extractLinks` only matches `https?://`, so
1904
+ // nothing reaches here with another scheme today. That is exactly why it
1905
+ // is worth adding: the widget footer already refuses a second time at its
1906
+ // own sink, and this path was relying on a single filter for the same rule.
1907
+ if (o.openLink && isWebUrl(url)) { try { await o.openLink(url); } catch { /* best-effort */ } }
1895
1908
  return s;
1896
1909
  },
1897
1910
 
@@ -1891,7 +1891,20 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
1891
1891
  if (!url) return s;
1892
1892
  const target = o.resolveEntity?.(url) ?? null;
1893
1893
  if (target) return navigate(s, target);
1894
- if (o.openLink) { try { await o.openLink(url); } catch { /* best-effort */ } }
1894
+ // THE SINK, and it had no scheme check until now — measured against the
1895
+ // built bundle, `openLink` handed `tel:`, `myapp://` and `javascript:`
1896
+ // straight to `capability.open_url.open`.
1897
+ //
1898
+ // The in-app resolution ABOVE is deliberately left alone: it matches
1899
+ // dashboard paths and answers null for anything else, so it cannot be
1900
+ // steered by a scheme, and guarding earlier would also reject the `id`
1901
+ // form this action still accepts.
1902
+ //
1903
+ // Not currently exploitable — `extractLinks` only matches `https?://`, so
1904
+ // nothing reaches here with another scheme today. That is exactly why it
1905
+ // is worth adding: the widget footer already refuses a second time at its
1906
+ // own sink, and this path was relying on a single filter for the same rule.
1907
+ if (o.openLink && isWebUrl(url)) { try { await o.openLink(url); } catch { /* best-effort */ } }
1895
1908
  return s;
1896
1909
  },
1897
1910
 
@@ -1891,7 +1891,20 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
1891
1891
  if (!url) return s;
1892
1892
  const target = o.resolveEntity?.(url) ?? null;
1893
1893
  if (target) return navigate(s, target);
1894
- if (o.openLink) { try { await o.openLink(url); } catch { /* best-effort */ } }
1894
+ // THE SINK, and it had no scheme check until now — measured against the
1895
+ // built bundle, `openLink` handed `tel:`, `myapp://` and `javascript:`
1896
+ // straight to `capability.open_url.open`.
1897
+ //
1898
+ // The in-app resolution ABOVE is deliberately left alone: it matches
1899
+ // dashboard paths and answers null for anything else, so it cannot be
1900
+ // steered by a scheme, and guarding earlier would also reject the `id`
1901
+ // form this action still accepts.
1902
+ //
1903
+ // Not currently exploitable — `extractLinks` only matches `https?://`, so
1904
+ // nothing reaches here with another scheme today. That is exactly why it
1905
+ // is worth adding: the widget footer already refuses a second time at its
1906
+ // own sink, and this path was relying on a single filter for the same rule.
1907
+ if (o.openLink && isWebUrl(url)) { try { await o.openLink(url); } catch { /* best-effort */ } }
1895
1908
  return s;
1896
1909
  },
1897
1910
 
@@ -1891,7 +1891,20 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
1891
1891
  if (!url) return s;
1892
1892
  const target = o.resolveEntity?.(url) ?? null;
1893
1893
  if (target) return navigate(s, target);
1894
- if (o.openLink) { try { await o.openLink(url); } catch { /* best-effort */ } }
1894
+ // THE SINK, and it had no scheme check until now — measured against the
1895
+ // built bundle, `openLink` handed `tel:`, `myapp://` and `javascript:`
1896
+ // straight to `capability.open_url.open`.
1897
+ //
1898
+ // The in-app resolution ABOVE is deliberately left alone: it matches
1899
+ // dashboard paths and answers null for anything else, so it cannot be
1900
+ // steered by a scheme, and guarding earlier would also reject the `id`
1901
+ // form this action still accepts.
1902
+ //
1903
+ // Not currently exploitable — `extractLinks` only matches `https?://`, so
1904
+ // nothing reaches here with another scheme today. That is exactly why it
1905
+ // is worth adding: the widget footer already refuses a second time at its
1906
+ // own sink, and this path was relying on a single filter for the same rule.
1907
+ if (o.openLink && isWebUrl(url)) { try { await o.openLink(url); } catch { /* best-effort */ } }
1895
1908
  return s;
1896
1909
  },
1897
1910
 
@@ -1891,7 +1891,20 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
1891
1891
  if (!url) return s;
1892
1892
  const target = o.resolveEntity?.(url) ?? null;
1893
1893
  if (target) return navigate(s, target);
1894
- if (o.openLink) { try { await o.openLink(url); } catch { /* best-effort */ } }
1894
+ // THE SINK, and it had no scheme check until now — measured against the
1895
+ // built bundle, `openLink` handed `tel:`, `myapp://` and `javascript:`
1896
+ // straight to `capability.open_url.open`.
1897
+ //
1898
+ // The in-app resolution ABOVE is deliberately left alone: it matches
1899
+ // dashboard paths and answers null for anything else, so it cannot be
1900
+ // steered by a scheme, and guarding earlier would also reject the `id`
1901
+ // form this action still accepts.
1902
+ //
1903
+ // Not currently exploitable — `extractLinks` only matches `https?://`, so
1904
+ // nothing reaches here with another scheme today. That is exactly why it
1905
+ // is worth adding: the widget footer already refuses a second time at its
1906
+ // own sink, and this path was relying on a single filter for the same rule.
1907
+ if (o.openLink && isWebUrl(url)) { try { await o.openLink(url); } catch { /* best-effort */ } }
1895
1908
  return s;
1896
1909
  },
1897
1910