@wix/himalaya-cli 0.1438.0 → 0.1439.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 (2) hide show
  1. package/dist/cli.mjs +345 -64
  2. package/package.json +2 -2
package/dist/cli.mjs CHANGED
@@ -8078,7 +8078,6 @@ function resolveTranslation(value, catalog3, sourceCatalog) {
8078
8078
  var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
8079
8079
  var init_bindings = __esm({
8080
8080
  "../../core/ts/src/bindings.ts"() {
8081
- "use strict";
8082
8081
  BINDING_SIGILS = ["service", "flag", "item", "t"];
8083
8082
  BINDING_SIGIL_RE = new RegExp(
8084
8083
  `^\\$(?:${BINDING_SIGILS.filter((s2) => s2 !== "t").join("|")})\\b|^\\$t:`
@@ -17852,6 +17851,7 @@ function resolveIdiom(tokens2, ctx = {}) {
17852
17851
  var IDIOM_CONTEXTS, UNSAFE_KEYS;
17853
17852
  var init_idiom = __esm({
17854
17853
  "../../core/ts/src/idiom.ts"() {
17854
+ "use strict";
17855
17855
  IDIOM_CONTEXTS = {
17856
17856
  ios: { native: ["ios"] },
17857
17857
  android: { native: ["material"] },
@@ -131234,12 +131234,14 @@ __export(render_descriptor_exports, {
131234
131234
  clientEnvFor: () => clientEnvFor,
131235
131235
  collectNativeOnly: () => collectNativeOnly,
131236
131236
  isMissingPlaywrightExecutable: () => isMissingPlaywrightExecutable,
131237
+ launchPngBrowser: () => launchPngBrowser,
131237
131238
  nodeHidden: () => nodeHidden,
131238
131239
  pngAvailable: () => pngAvailable,
131239
131240
  pngPageHtml: () => pngPageHtml,
131240
131241
  renderDescriptorWeb: () => renderDescriptorWeb,
131241
131242
  renderPngBatch: () => renderPngBatch,
131242
131243
  renderSchemeFor: () => renderSchemeFor,
131244
+ setPngEgress: () => setPngEgress,
131243
131245
  setPngFontCss: () => setPngFontCss,
131244
131246
  stabilizePngPage: () => stabilizePngPage,
131245
131247
  withRetry: () => withRetry2
@@ -131630,8 +131632,24 @@ async function stabilizePngPage(page, scheme) {
131630
131632
  await new Promise((resolve66) => browser.requestAnimationFrame(() => browser.requestAnimationFrame(() => resolve66())));
131631
131633
  }, scheme);
131632
131634
  }
131633
- async function renderPngBatch(items) {
131634
- if (!items.length) return [];
131635
+ function setPngEgress(start) {
131636
+ const prev = pngEgress;
131637
+ pngEgress = start;
131638
+ return prev;
131639
+ }
131640
+ async function pngEgressStart() {
131641
+ if (pngEgress !== void 0) return pngEgress;
131642
+ const spec = "./png-egress.js";
131643
+ try {
131644
+ return (await import(
131645
+ /* @vite-ignore */
131646
+ spec
131647
+ )).startEgressProxy;
131648
+ } catch {
131649
+ return null;
131650
+ }
131651
+ }
131652
+ async function launchPngBrowser() {
131635
131653
  let chromium;
131636
131654
  try {
131637
131655
  ({ chromium } = await import("playwright"));
@@ -131639,13 +131657,41 @@ async function renderPngBatch(items) {
131639
131657
  return null;
131640
131658
  }
131641
131659
  if (!chromium) return null;
131660
+ const start = await pngEgressStart();
131661
+ if (!start) return null;
131662
+ let egress;
131663
+ try {
131664
+ egress = await start();
131665
+ } catch {
131666
+ return null;
131667
+ }
131642
131668
  const launch = chromium.launch.bind(chromium);
131643
131669
  let browser;
131644
131670
  try {
131645
- browser = await withRetry2(() => launch(), 3);
131671
+ browser = await withRetry2(() => launch({
131672
+ proxy: { server: egress.url, bypass: "<-loopback>" },
131673
+ args: ["--force-webrtc-ip-handling-policy=disable_non_proxied_udp", "--webrtc-ip-handling-policy=disable_non_proxied_udp"]
131674
+ }), 3);
131646
131675
  } catch {
131676
+ await egress.close().catch(() => {
131677
+ });
131647
131678
  return null;
131648
131679
  }
131680
+ return {
131681
+ browser,
131682
+ close: async () => {
131683
+ await browser.close().catch(() => {
131684
+ });
131685
+ await egress.close().catch(() => {
131686
+ });
131687
+ }
131688
+ };
131689
+ }
131690
+ async function renderPngBatch(items) {
131691
+ if (!items.length) return [];
131692
+ const launched = await launchPngBrowser();
131693
+ if (!launched) return null;
131694
+ const { browser } = launched;
131649
131695
  try {
131650
131696
  const out2 = [];
131651
131697
  for (const it2 of items) {
@@ -131666,11 +131712,10 @@ async function renderPngBatch(items) {
131666
131712
  }
131667
131713
  return out2;
131668
131714
  } finally {
131669
- await browser.close().catch(() => {
131670
- });
131715
+ await launched.close();
131671
131716
  }
131672
131717
  }
131673
- var A11Y_MODIFIER_KEYS, TREE_TEXT_VALUE_PROPS, asStringOrNumber, asStringOnly, asOtpCode, VALUE_PATH_TEXT, MEDIA_PLAYER_QUEUE_PROPERTIES, NATIVE_ONLY_TYPES, HOST_PAGE_FONT, pngFontCss;
131718
+ var A11Y_MODIFIER_KEYS, TREE_TEXT_VALUE_PROPS, asStringOrNumber, asStringOnly, asOtpCode, VALUE_PATH_TEXT, MEDIA_PLAYER_QUEUE_PROPERTIES, NATIVE_ONLY_TYPES, HOST_PAGE_FONT, pngFontCss, pngEgress;
131674
131719
  var init_render_descriptor = __esm({
131675
131720
  "../../core/dev-server/src/render-descriptor.ts"() {
131676
131721
  init_tokens2();
@@ -131714,6 +131759,229 @@ var init_render_descriptor = __esm({
131714
131759
  }
131715
131760
  });
131716
131761
 
131762
+ // ../../core/dev-server/src/png-egress.ts
131763
+ import http from "node:http";
131764
+ import net from "node:net";
131765
+ import { lookup as lookup2 } from "node:dns/promises";
131766
+ function isPublicAddress(ip) {
131767
+ const family = net.isIP(ip);
131768
+ if (family === 0) return false;
131769
+ return family === 4 ? !BLOCKED_V4.check(ip, "ipv4") : !BLOCKED_V6.check(ip, "ipv6");
131770
+ }
131771
+ function originKey(origin) {
131772
+ try {
131773
+ const u2 = new URL(origin);
131774
+ return hostPortKey(u2.hostname, u2.port || (u2.protocol === "https:" ? "443" : "80"));
131775
+ } catch {
131776
+ return null;
131777
+ }
131778
+ }
131779
+ function hostPortKey(host, port) {
131780
+ return `${host.replace(/^\[|\]$/g, "").replace(/\.$/, "").toLowerCase()}:${port}`;
131781
+ }
131782
+ function allowPngOrigins(origins) {
131783
+ const keys = origins.map(originKey).filter((k2) => !!k2);
131784
+ for (const k2 of keys) allowedOrigins.set(k2, (allowedOrigins.get(k2) ?? 0) + 1);
131785
+ return () => {
131786
+ for (const k2 of keys) {
131787
+ const n2 = (allowedOrigins.get(k2) ?? 1) - 1;
131788
+ if (n2 <= 0) allowedOrigins.delete(k2);
131789
+ else allowedOrigins.set(k2, n2);
131790
+ }
131791
+ };
131792
+ }
131793
+ function ownOrigins(port, publicBase) {
131794
+ return [`http://localhost:${port}`, `http://127.0.0.1:${port}`, `http://[::1]:${port}`, ...publicBase ? [publicBase] : []];
131795
+ }
131796
+ async function resolveEgress(host, port, allow = allowedOrigins) {
131797
+ const bare = host.replace(/^\[|\]$/g, "");
131798
+ let addrs;
131799
+ try {
131800
+ addrs = net.isIP(bare) ? [{ address: bare, family: net.isIP(bare) }] : await lookup2(bare.replace(/\.$/, ""), { all: true, order: "ipv4first" });
131801
+ } catch {
131802
+ return null;
131803
+ }
131804
+ if (!addrs.length) return null;
131805
+ if (allow.has(hostPortKey(host, port))) return addrs;
131806
+ return addrs.every((a2) => isPublicAddress(a2.address)) ? addrs : null;
131807
+ }
131808
+ function connectFirst(addrs, port, track) {
131809
+ return new Promise((resolve66, reject) => {
131810
+ const tryAt = (i2) => {
131811
+ if (i2 >= addrs.length) return reject(new Error("no address answered"));
131812
+ const s2 = net.connect({ host: addrs[i2].address, family: addrs[i2].family, port });
131813
+ track(s2);
131814
+ s2.setTimeout(CONNECT_TIMEOUT_MS, () => s2.destroy(new Error("connect timeout")));
131815
+ const onFail = () => {
131816
+ s2.destroy();
131817
+ tryAt(i2 + 1);
131818
+ };
131819
+ s2.once("error", onFail);
131820
+ s2.once("connect", () => {
131821
+ s2.off("error", onFail);
131822
+ s2.setTimeout(0);
131823
+ resolve66(s2);
131824
+ });
131825
+ };
131826
+ tryAt(0);
131827
+ });
131828
+ }
131829
+ async function startEgressProxy() {
131830
+ const blocked = [];
131831
+ const sockets = /* @__PURE__ */ new Set();
131832
+ const track = (s2) => {
131833
+ sockets.add(s2);
131834
+ s2.once("close", () => sockets.delete(s2));
131835
+ };
131836
+ const guard = (s2) => {
131837
+ track(s2);
131838
+ s2.on("error", () => s2.destroy());
131839
+ };
131840
+ const server = http.createServer(async (req, res) => {
131841
+ let u2;
131842
+ try {
131843
+ u2 = new URL(req.url ?? "");
131844
+ } catch {
131845
+ res.writeHead(400).end();
131846
+ return;
131847
+ }
131848
+ const port2 = Number(u2.port || 80);
131849
+ const addrs = u2.protocol === "http:" ? await resolveEgress(u2.hostname, port2) : null;
131850
+ if (!addrs) {
131851
+ blocked.push(hostPortKey(u2.hostname, port2));
131852
+ res.writeHead(403).end();
131853
+ return;
131854
+ }
131855
+ let sock;
131856
+ try {
131857
+ sock = await connectFirst(addrs, port2, guard);
131858
+ } catch {
131859
+ res.writeHead(502).end();
131860
+ return;
131861
+ }
131862
+ const headers2 = { ...req.headers, host: u2.host };
131863
+ delete headers2["proxy-connection"];
131864
+ const upstream = http.request({ createConnection: () => sock, method: req.method, path: `${u2.pathname}${u2.search}`, headers: headers2 }, (up) => {
131865
+ res.writeHead(up.statusCode ?? 502, up.headers);
131866
+ up.pipe(res);
131867
+ });
131868
+ upstream.on("error", () => {
131869
+ if (!res.headersSent) res.writeHead(502);
131870
+ res.end();
131871
+ });
131872
+ req.pipe(upstream);
131873
+ });
131874
+ server.on("connection", guard);
131875
+ server.on("clientError", (_e2, socket) => socket.destroy());
131876
+ server.on("connect", async (req, socket, head) => {
131877
+ guard(socket);
131878
+ const m2 = /^\[?([^\]]+?)\]?:(\d+)$/.exec(req.url ?? "");
131879
+ const addrs = m2 ? await resolveEgress(m2[1], Number(m2[2])) : null;
131880
+ if (!m2 || !addrs) {
131881
+ blocked.push(m2 ? hostPortKey(m2[1], m2[2]) : String(req.url));
131882
+ socket.end("HTTP/1.1 403 Forbidden\r\n\r\n");
131883
+ return;
131884
+ }
131885
+ let upstream;
131886
+ try {
131887
+ upstream = await connectFirst(addrs, Number(m2[2]), guard);
131888
+ } catch {
131889
+ socket.end("HTTP/1.1 502 Bad Gateway\r\n\r\n");
131890
+ return;
131891
+ }
131892
+ socket.write("HTTP/1.1 200 Connection Established\r\n\r\n");
131893
+ if (head.length) upstream.write(head);
131894
+ upstream.pipe(socket);
131895
+ socket.pipe(upstream);
131896
+ });
131897
+ server.on("upgrade", async (req, socket, head) => {
131898
+ guard(socket);
131899
+ let u2;
131900
+ try {
131901
+ u2 = new URL(req.url ?? "");
131902
+ } catch {
131903
+ socket.destroy();
131904
+ return;
131905
+ }
131906
+ const port2 = Number(u2.port || 80);
131907
+ const addrs = await resolveEgress(u2.hostname, port2);
131908
+ if (!addrs) {
131909
+ blocked.push(hostPortKey(u2.hostname, port2));
131910
+ socket.end("HTTP/1.1 403 Forbidden\r\n\r\n");
131911
+ return;
131912
+ }
131913
+ let upstream;
131914
+ try {
131915
+ upstream = await connectFirst(addrs, port2, guard);
131916
+ } catch {
131917
+ socket.end("HTTP/1.1 502 Bad Gateway\r\n\r\n");
131918
+ return;
131919
+ }
131920
+ const lines = [`${req.method} ${u2.pathname}${u2.search} HTTP/1.1`];
131921
+ for (let i2 = 0; i2 < req.rawHeaders.length; i2 += 2) lines.push(`${req.rawHeaders[i2]}: ${req.rawHeaders[i2 + 1]}`);
131922
+ upstream.write(`${lines.join("\r\n")}\r
131923
+ \r
131924
+ `);
131925
+ if (head.length) upstream.write(head);
131926
+ upstream.pipe(socket);
131927
+ socket.pipe(upstream);
131928
+ });
131929
+ await new Promise((resolve66, reject) => {
131930
+ server.once("error", reject);
131931
+ server.listen(0, "127.0.0.1", () => resolve66());
131932
+ });
131933
+ const { port } = server.address();
131934
+ return {
131935
+ url: `http://127.0.0.1:${port}`,
131936
+ blocked,
131937
+ close: () => new Promise((resolve66) => {
131938
+ server.close(() => resolve66());
131939
+ for (const s2 of sockets) s2.destroy();
131940
+ server.closeAllConnections?.();
131941
+ })
131942
+ };
131943
+ }
131944
+ var BLOCKED_V4, BLOCKED_V6, CONNECT_TIMEOUT_MS, allowedOrigins;
131945
+ var init_png_egress = __esm({
131946
+ "../../core/dev-server/src/png-egress.ts"() {
131947
+ BLOCKED_V4 = new net.BlockList();
131948
+ BLOCKED_V6 = new net.BlockList();
131949
+ for (const [addr, prefix] of [
131950
+ ["0.0.0.0", 8],
131951
+ ["10.0.0.0", 8],
131952
+ ["100.64.0.0", 10],
131953
+ ["127.0.0.0", 8],
131954
+ ["169.254.0.0", 16],
131955
+ ["172.16.0.0", 12],
131956
+ ["192.0.0.0", 24],
131957
+ ["192.0.2.0", 24],
131958
+ ["192.88.99.0", 24],
131959
+ ["192.168.0.0", 16],
131960
+ ["198.18.0.0", 15],
131961
+ ["198.51.100.0", 24],
131962
+ ["203.0.113.0", 24],
131963
+ ["224.0.0.0", 4],
131964
+ ["240.0.0.0", 4]
131965
+ ]) BLOCKED_V4.addSubnet(addr, prefix, "ipv4");
131966
+ for (const [addr, prefix] of [
131967
+ ["::", 96],
131968
+ ["::ffff:0:0", 96],
131969
+ ["64:ff9b::", 96],
131970
+ ["64:ff9b:1::", 48],
131971
+ ["100::", 64],
131972
+ ["2001::", 23],
131973
+ ["2001:db8::", 32],
131974
+ ["2002::", 16],
131975
+ ["fc00::", 7],
131976
+ ["fe80::", 10],
131977
+ ["fec0::", 10],
131978
+ ["ff00::", 8]
131979
+ ]) BLOCKED_V6.addSubnet(addr, prefix, "ipv6");
131980
+ CONNECT_TIMEOUT_MS = 1e4;
131981
+ allowedOrigins = /* @__PURE__ */ new Map();
131982
+ }
131983
+ });
131984
+
131717
131985
  // ../../core/dev-server/src/render-fonts.ts
131718
131986
  import { existsSync as existsSync45, readFileSync as readFileSync49 } from "node:fs";
131719
131987
  import { extname, join as join44 } from "node:path";
@@ -136304,6 +136572,17 @@ function createDevServer(opts = {}) {
136304
136572
  })();
136305
136573
  };
136306
136574
  const httpServer = createServer3(handleRequest);
136575
+ let disallowOwnOrigins;
136576
+ httpServer.on("listening", () => {
136577
+ const addr = httpServer.address();
136578
+ if (!addr || typeof addr === "string") return;
136579
+ disallowOwnOrigins?.();
136580
+ disallowOwnOrigins = allowPngOrigins(ownOrigins(addr.port, process.env.HIMALAYA_DEV_PUBLIC_URL));
136581
+ });
136582
+ httpServer.on("close", () => {
136583
+ disallowOwnOrigins?.();
136584
+ disallowOwnOrigins = void 0;
136585
+ });
136307
136586
  httpServer.inject = (request) => injectRequest(handleRequest, request);
136308
136587
  httpServer.on("clientError", (err, socket) => {
136309
136588
  console.error(`[himalaya-dev] malformed request rejected by the HTTP parser: ${err.code ?? ""} ${err.message}`);
@@ -136379,6 +136658,7 @@ var init_src6 = __esm({
136379
136658
  init_check();
136380
136659
  init_openapi();
136381
136660
  init_render_descriptor();
136661
+ init_png_egress();
136382
136662
  init_render_fonts();
136383
136663
  init_app_config();
136384
136664
  init_tier();
@@ -136390,6 +136670,7 @@ var init_src6 = __esm({
136390
136670
  init_descriptor_postprocess();
136391
136671
  ROOT6 = resolve38(fileURLToPath22(new URL("../../..", import.meta.url)));
136392
136672
  setPngFontCss(async (tokens2, idiomContext) => await pngFontFaceCss(tokens2) + (idiomContext ? await idiomFontFaceCss(idiomContext) : ""));
136673
+ setPngEgress(startEgressProxy);
136393
136674
  TIER3_ROOT = resolve38(ROOT6, "core/dev-server/web");
136394
136675
  TIER4_ROOT = resolve38(ROOT6, "core/dev-server/tier4-bundles");
136395
136676
  tier4Verifier = new TierFourVerifier(TIER4_ROOT);
@@ -150279,7 +150560,7 @@ function defineAppLiteral(file2) {
150279
150560
  return void 0;
150280
150561
  }
150281
150562
  function loginOf(app) {
150282
- const auth = lookup2(app, "auth");
150563
+ const auth = lookup3(app, "auth");
150283
150564
  if (auth.kind !== "written") return { kind: auth.kind === "absent" ? "other" : "opaque" };
150284
150565
  const value = unwrap(auth.node.initializer);
150285
150566
  if (ts5.isObjectLiteralExpression(value)) return { kind: "other" };
@@ -150307,7 +150588,7 @@ function unwrap(node) {
150307
150588
  }
150308
150589
  return current;
150309
150590
  }
150310
- function lookup2(literal, name) {
150591
+ function lookup3(literal, name) {
150311
150592
  let found = { kind: "absent" };
150312
150593
  for (const p2 of literal.properties) {
150313
150594
  const key3 = p2.name && (ts5.isIdentifier(p2.name) || ts5.isStringLiteral(p2.name)) ? p2.name.text : void 0;
@@ -150318,7 +150599,7 @@ function lookup2(literal, name) {
150318
150599
  }
150319
150600
  function stringValue(node, name) {
150320
150601
  const literal = unwrap(node);
150321
- const found = ts5.isObjectLiteralExpression(literal) ? lookup2(literal, name) : void 0;
150602
+ const found = ts5.isObjectLiteralExpression(literal) ? lookup3(literal, name) : void 0;
150322
150603
  const value = found?.kind === "written" ? found.node.initializer : void 0;
150323
150604
  return value && ts5.isStringLiteralLike(value) ? value.text : void 0;
150324
150605
  }
@@ -150430,7 +150711,7 @@ function enablePushInConfig(source, options) {
150430
150711
  };
150431
150712
  }
150432
150713
  function planPush(app, pingAppName, plan) {
150433
- const push = lookup2(app, "push");
150714
+ const push = lookup3(app, "push");
150434
150715
  if (push.kind === "absent") {
150435
150716
  plan.appended.push([
150436
150717
  ROUTES_COMMENT,
@@ -150461,7 +150742,7 @@ function planPush(app, pingAppName, plan) {
150461
150742
  }
150462
150743
  function planRetiredFamily(block, plan) {
150463
150744
  const literal = unwrap(block);
150464
- const found = ts6.isObjectLiteralExpression(literal) ? lookup2(literal, "pingAppName") : void 0;
150745
+ const found = ts6.isObjectLiteralExpression(literal) ? lookup3(literal, "pingAppName") : void 0;
150465
150746
  const value = found?.kind === "written" ? unwrap(found.node.initializer) : void 0;
150466
150747
  const replacement = value && ts6.isStringLiteralLike(value) ? replacementPingFamily(value.text) : void 0;
150467
150748
  if (!value || !replacement) return;
@@ -150469,7 +150750,7 @@ function planRetiredFamily(block, plan) {
150469
150750
  plan.applied.push(`pingAppName ${JSON.stringify(replacement)} in place of ${value.getText()}`);
150470
150751
  }
150471
150752
  function planCapability(app, plan) {
150472
- const capabilities = lookup2(app, "capabilities");
150753
+ const capabilities = lookup3(app, "capabilities");
150473
150754
  if (capabilities.kind === "absent") {
150474
150755
  plan.appended.push(['capabilities: ["push"],']);
150475
150756
  plan.applied.push("push capability");
@@ -150499,7 +150780,7 @@ function planAuthSite(login, file2, site, plan) {
150499
150780
  );
150500
150781
  return;
150501
150782
  }
150502
- const siteId = lookup2(login.literal, "siteId");
150783
+ const siteId = lookup3(login.literal, "siteId");
150503
150784
  if (siteId.kind === "absent") {
150504
150785
  plan.splices.push(appendProperties(login.literal, file2, [`${wanted},`]));
150505
150786
  plan.applied.push("auth siteId");
@@ -150586,8 +150867,8 @@ async function ask(question, deps) {
150586
150867
  function defer(dir, input, scope, reason) {
150587
150868
  return recordPushDeferral(dir, { reason, scope, missing: missingPushInputs(input, scope), identity: input, resume: resume(dir) });
150588
150869
  }
150589
- function renderPushStatus(http, refresh = false) {
150590
- const body = http.body ?? {};
150870
+ function renderPushStatus(http2, refresh = false) {
150871
+ const body = http2.body ?? {};
150591
150872
  const verification = obj2(body.verification);
150592
150873
  const state = typeof body.state === "string" && STATES.has(body.state) ? body.state : "unknown";
150593
150874
  const mode = verification.mode === "live" ? "live" : verification.mode === "cached" ? "cached" : "unavailable";
@@ -150596,10 +150877,10 @@ function renderPushStatus(http, refresh = false) {
150596
150877
  return [name, typeof value === "string" && CHECK_STATES.has(value) ? value : "unknown"];
150597
150878
  }));
150598
150879
  const rawCode = typeof body.error === "string" ? body.error.split(":")[0] : void 0;
150599
- const responseError = http.error ?? (rawCode ? ERROR_CODES.has(rawCode) ? rawCode : "push_setup_failed" : void 0);
150600
- const error = responseError ?? (!http.ok ? "push_setup_failed" : refresh && mode !== "live" ? "live_verification_unavailable" : void 0);
150880
+ const responseError = http2.error ?? (rawCode ? ERROR_CODES.has(rawCode) ? rawCode : "push_setup_failed" : void 0);
150881
+ const error = responseError ?? (!http2.ok ? "push_setup_failed" : refresh && mode !== "live" ? "live_verification_unavailable" : void 0);
150601
150882
  return {
150602
- ok: http.ok && state === "ready" && !error && (!refresh || verification.backendConfigurationReady === true),
150883
+ ok: http2.ok && state === "ready" && !error && (!refresh || verification.backendConfigurationReady === true),
150603
150884
  state,
150604
150885
  verificationMode: mode,
150605
150886
  backendConfigurationReady: verification.backendConfigurationReady === true,
@@ -150611,8 +150892,8 @@ function renderPushStatus(http, refresh = false) {
150611
150892
  note: "Backend setup is separate from building the app, device registration and notification delivery."
150612
150893
  };
150613
150894
  }
150614
- function report(http, flags, io2, dir, config) {
150615
- const status = renderPushStatus(http, flags.refresh === true);
150895
+ function report(http2, flags, io2, dir, config) {
150896
+ const status = renderPushStatus(http2, flags.refresh === true);
150616
150897
  const result = config && !config.pushOn ? { ...status, ok: false, error: status.error ?? (config.rolledBack ? "config_edit_rolled_back" : "config_push_not_on") } : status;
150617
150898
  const local = readPushOnboarding(dir).push;
150618
150899
  io2.log(JSON.stringify({ ...result, ...local ? { localOnboarding: "deferred" } : {}, ...config ? { config } : {} }, null, 2));
@@ -154729,7 +155010,7 @@ async function runCrawl(opts) {
154729
155010
  for (const d2 of list) if (d2.screenId !== rep.screenId) coveredBy.set(d2.screenId, rep.screenId);
154730
155011
  }
154731
155012
  }
154732
- const net = opts.offline ? null : opts.netPath ? { rules: readNetRules(resolve51(opts.netPath)), from: opts.netPath } : defaultNetRules(opts.dir);
155013
+ const net2 = opts.offline ? null : opts.netPath ? { rules: readNetRules(resolve51(opts.netPath)), from: opts.netPath } : defaultNetRules(opts.dir);
154733
155014
  const suppressions = opts.config?.skip ?? [];
154734
155015
  const suppressed = [];
154735
155016
  const matchSuppression = (screen, actionId, componentId, invariant) => suppressions.find((s2) => (s2.screen === void 0 || s2.screen === screen) && (s2.action === void 0 || s2.action === actionId) && (s2.component === void 0 || s2.component === componentId) && (s2.invariant === void 0 || s2.invariant === invariant));
@@ -154757,7 +155038,7 @@ async function runCrawl(opts) {
154757
155038
  bundleMap: baked.bundleMap ?? null,
154758
155039
  knownScreenIds,
154759
155040
  ...opts.linkableScreenIds?.size ? { linkableScreenIds: opts.linkableScreenIds } : {},
154760
- rules: net?.rules ?? null,
155041
+ rules: net2?.rules ?? null,
154761
155042
  ...opts.cmsSeed && Object.keys(opts.cmsSeed).length ? { cmsSeed: opts.cmsSeed } : {},
154762
155043
  ...opts.canned?.count ? { canned: opts.canned.byKey } : {},
154763
155044
  ...localDbSchema?.length ? { localDbSchema } : {},
@@ -154899,7 +155180,7 @@ async function runCrawl(opts) {
154899
155180
  bundleJs: baked.bundleJs,
154900
155181
  bundleMap: baked.bundleMap ?? null,
154901
155182
  knownScreenIds,
154902
- rules: net?.rules ?? null,
155183
+ rules: net2?.rules ?? null,
154903
155184
  ...opts.cmsSeed && Object.keys(opts.cmsSeed).length ? { cmsSeed: opts.cmsSeed } : {},
154904
155185
  ...opts.canned?.count ? { canned: opts.canned.byKey } : {},
154905
155186
  ...localDbSchema?.length ? { localDbSchema } : {},
@@ -154966,7 +155247,7 @@ async function runCrawl(opts) {
154966
155247
  // so a run over static or bundle-less screens injects the dependency and replays nothing —
154967
155248
  // and the label then advertised "+ relations" beside `relations.checked: 0`. This is the
154968
155249
  // second time this line has overstated itself: it first claimed the axis unconditionally.
154969
- transport: describeTransport(net, opts, {
155250
+ transport: describeTransport(net2, opts, {
154970
155251
  relations: relationsChecked > 0,
154971
155252
  hostile: opts.hostile !== false && Boolean(deps.crawlScreenHostile),
154972
155253
  deep: Boolean(opts.deep && opts.deep >= 2 && deps.crawlScreenDeep)
@@ -155004,9 +155285,9 @@ async function runCrawl(opts) {
155004
155285
  ...results.some((r2) => r2.observations) ? { observations: Object.fromEntries(results.filter((r2) => r2.observations).map((r2) => [r2.screen, r2.observations])) } : {}
155005
155286
  };
155006
155287
  }
155007
- function describeTransport(net, opts, ran) {
155288
+ function describeTransport(net2, opts, ran) {
155008
155289
  const layers3 = [];
155009
- if (net) layers3.push(`mocked (${net.from})`);
155290
+ if (net2) layers3.push(`mocked (${net2.from})`);
155010
155291
  const cmsCount = Object.keys(opts.cmsSeed ?? {}).length;
155011
155292
  if (cmsCount) layers3.push(`cms (${cmsCount} seeded collection${cmsCount === 1 ? "" : "s"})`);
155012
155293
  if (opts.canned?.count) layers3.push(`canned (${opts.canned.count} frozen endpoints, ${opts.canned.from} \u2014 exercises code paths, not API-contract truth)`);
@@ -164083,7 +164364,7 @@ function siteFinding(app, siteId, fileName) {
164083
164364
  const check = `make sure the app's member login uses siteId ${JSON.stringify(siteId)}: a build bakes the purchases app only for the site its login resolves to.`;
164084
164365
  const login = loginOf(app);
164085
164366
  if (login.kind !== "member") return { instruction: `${fileName} does not write auth as a WixConsumerAuthProvider({ \u2026 }) call it can read, so ${check}` };
164086
- const found = lookup2(login.literal, "siteId");
164367
+ const found = lookup3(login.literal, "siteId");
164087
164368
  const value = found.kind === "written" ? unwrap(found.node.initializer) : void 0;
164088
164369
  if (!value || !ts8.isStringLiteralLike(value)) return { instruction: `auth's siteId is not written as a literal, so ${check}` };
164089
164370
  if (value.text.toLowerCase() === siteId.toLowerCase()) return {};
@@ -164094,7 +164375,7 @@ function bundleFinding(app, { bundleId, storeBundleId }, fileName) {
164094
164375
  if (storeBundleId === bundleId) return {};
164095
164376
  return { conflict: `store/store.config.yaml builds bundle "${storeBundleId}", but the purchases app is registered for "${bundleId}". ${fileName} was not edited.` };
164096
164377
  }
164097
- const found = lookup2(app, "bundleId");
164378
+ const found = lookup3(app, "bundleId");
164098
164379
  const value = found.kind === "written" ? unwrap(found.node.initializer) : void 0;
164099
164380
  if (!value || !ts8.isStringLiteralLike(value)) {
164100
164381
  return { instruction: `${fileName} does not write bundleId as a literal: make sure this app builds bundle ${JSON.stringify(bundleId)}, the one the purchases app is registered for.` };
@@ -164103,11 +164384,11 @@ function bundleFinding(app, { bundleId, storeBundleId }, fileName) {
164103
164384
  return { conflict: `${fileName} builds bundle "${value.text}", but the purchases app is registered for "${bundleId}". This is another app's config, so it was not edited.` };
164104
164385
  }
164105
164386
  function bindingFinding(app, file2, purchasesAppId, wanted, fileName) {
164106
- const wixIap = lookup2(app, "wixIap");
164387
+ const wixIap = lookup3(app, "wixIap");
164107
164388
  if (wixIap.kind === "absent") return { splice: appendProperties(app, file2, [`${wanted},`]), applied: "wixIap.purchasesAppId" };
164108
164389
  const literal = wixIap.kind === "written" ? unwrap(wixIap.node.initializer) : void 0;
164109
164390
  if (!literal || !ts8.isObjectLiteralExpression(literal)) return { instruction: `${fileName} computes wixIap, so it was not edited: it must evaluate to ${wanted}.` };
164110
- const current = lookup2(literal, "purchasesAppId");
164391
+ const current = lookup3(literal, "purchasesAppId");
164111
164392
  if (current.kind === "absent") return { splice: appendProperties(literal, file2, [`purchasesAppId: ${JSON.stringify(purchasesAppId)},`]), applied: "wixIap.purchasesAppId" };
164112
164393
  const value = current.kind === "written" ? unwrap(current.node.initializer) : void 0;
164113
164394
  if (!value || !ts8.isStringLiteralLike(value)) return { instruction: `${fileName} computes wixIap.purchasesAppId, so it was not edited: it must evaluate to ${JSON.stringify(purchasesAppId)}.` };
@@ -164115,7 +164396,7 @@ function bindingFinding(app, file2, purchasesAppId, wanted, fileName) {
164115
164396
  return { conflict: `${fileName} already binds purchases app "${value.text}", but this site's purchases app for the bundle is "${purchasesAppId}". Nothing was changed; fix whichever is stale.` };
164116
164397
  }
164117
164398
  function capabilityFinding(app, fileName) {
164118
- const capabilities = lookup2(app, "capabilities");
164399
+ const capabilities = lookup3(app, "capabilities");
164119
164400
  const list = capabilities.kind === "written" ? unwrap(capabilities.node.initializer) : void 0;
164120
164401
  if (capabilities.kind !== "absent" && (!list || !ts8.isArrayLiteralExpression(list))) {
164121
164402
  return { instruction: `Add "iap" to capabilities: the purchases app is baked only into a build that declares it, and ${fileName} does not list capabilities inline.` };
@@ -164815,14 +165096,13 @@ function createReviewScreenRenderer() {
164815
165096
  }
164816
165097
  return built;
164817
165098
  }
165099
+ let closeLaunched;
164818
165100
  async function launch() {
164819
- let chromium;
164820
- try {
164821
- ({ chromium } = await import("playwright"));
164822
- } catch {
164823
- throw new Error("taking a screenshot needs Playwright's Chromium: run `npx playwright install chromium`");
164824
- }
164825
- return chromium.launch();
165101
+ const { launchPngBrowser: launchPngBrowser2 } = await Promise.resolve().then(() => (init_render_descriptor(), render_descriptor_exports));
165102
+ const launched = await launchPngBrowser2();
165103
+ if (!launched) throw new Error("taking a screenshot needs Playwright's Chromium: run `npx playwright install chromium`");
165104
+ closeLaunched = launched.close;
165105
+ return launched.browser;
164826
165106
  }
164827
165107
  return {
164828
165108
  async render({ contentDir: contentDir2, screenId, input, host, entityId }) {
@@ -164865,7 +165145,8 @@ function createReviewScreenRenderer() {
164865
165145
  return pngAvailable2();
164866
165146
  },
164867
165147
  async close() {
164868
- if (browser) await (await browser.catch(() => void 0))?.close().catch(() => {
165148
+ if (browser) await browser.catch(() => void 0);
165149
+ await closeLaunched?.().catch(() => {
164869
165150
  });
164870
165151
  }
164871
165152
  };
@@ -167173,8 +167454,8 @@ async function runNotifyPing(flags, io2, deps = {}) {
167173
167454
  requestId: requestId2,
167174
167455
  ...flags["dry-run"] === true ? { dryRun: true } : {}
167175
167456
  };
167176
- const http = await pushSendRequest({ target: session.target, wixToken: session.wixToken, siteToken: siteToken2, body, previewTag: session.previewTag, fetchImpl: deps.fetchImpl });
167177
- return report2(http, body, flags, io2);
167457
+ const http2 = await pushSendRequest({ target: session.target, wixToken: session.wixToken, siteToken: siteToken2, body, previewTag: session.previewTag, fetchImpl: deps.fetchImpl });
167458
+ return report2(http2, body, flags, io2);
167178
167459
  }
167179
167460
  async function runAllMembers(args) {
167180
167461
  const { input, siteToken: siteToken2, session, requestId: requestId2, flags, io: io2, deps } = args;
@@ -167263,25 +167544,25 @@ function flagRefusal(flags) {
167263
167544
  if (SWITCHES.some((f2) => flags[f2] !== void 0 && typeof flags[f2] !== "boolean")) return "invalid_boolean_flag";
167264
167545
  return void 0;
167265
167546
  }
167266
- function report2(http, sent, flags, io2) {
167267
- const code = refusalCode2(http);
167547
+ function report2(http2, sent, flags, io2) {
167548
+ const code = refusalCode2(http2);
167268
167549
  if (code === "send_outcome_unknown") {
167269
167550
  return refuse6(io2, code, `Ping may have accepted it. Re-run the same command with --request-id ${sent.requestId}: Ping runs one request at most once per site for 24 hours.`, 1, { requestId: sent.requestId });
167270
167551
  }
167271
- if (code === "rate_limited" && http.retryAfterSec) {
167272
- return refuse6(io2, code, `Test sends are limited per owner; retry in ${http.retryAfterSec} seconds.`, 1, { retryAfterSec: http.retryAfterSec });
167552
+ if (code === "rate_limited" && http2.retryAfterSec) {
167553
+ return refuse6(io2, code, `Test sends are limited per owner; retry in ${http2.retryAfterSec} seconds.`, 1, { retryAfterSec: http2.retryAfterSec });
167273
167554
  }
167274
167555
  if (code) return refuse6(io2, code, HINTS[code], 1);
167275
- if (flags.json === true) io2.log(JSON.stringify(http.body, null, 2));
167276
- else io2.log(summary(http.body ?? {}, sent));
167556
+ if (flags.json === true) io2.log(JSON.stringify(http2.body, null, 2));
167557
+ else io2.log(summary(http2.body ?? {}, sent));
167277
167558
  return 0;
167278
167559
  }
167279
- function refusalCode2(http) {
167280
- if (http.error) return http.error === "push_send_unreachable" ? "send_outcome_unknown" : http.error;
167281
- if (http.ok && (http.body?.state === "accepted" || http.body?.state === "dry_run")) return void 0;
167282
- const code = String(http.body?.error ?? "");
167560
+ function refusalCode2(http2) {
167561
+ if (http2.error) return http2.error === "push_send_unreachable" ? "send_outcome_unknown" : http2.error;
167562
+ if (http2.ok && (http2.body?.state === "accepted" || http2.body?.state === "dry_run")) return void 0;
167563
+ const code = String(http2.body?.error ?? "");
167283
167564
  if (KNOWN_CODES.has(code)) return code;
167284
- return http.ok || http.status >= 500 ? "send_outcome_unknown" : "push_send_failed";
167565
+ return http2.ok || http2.status >= 500 ? "send_outcome_unknown" : "push_send_failed";
167285
167566
  }
167286
167567
  function summary(result, sent) {
167287
167568
  if (result.state === "dry_run") {
@@ -168844,8 +169125,8 @@ function readEntities(files, dirs) {
168844
169125
  function functionSignature(code) {
168845
169126
  if (code === void 0) return { kind: "unknown" };
168846
169127
  const methods = [...new Set([...code.matchAll(/\b(?:req|request)\.method\s*[!=]==?\s*["'](GET|POST|PUT|PATCH|DELETE)["']/g)].map((m2) => m2[1]))];
168847
- const http = /\bDeno\.serve\s*\(|\bserve\s*\(\s*(?:async\s*)?\(?\s*req/.test(code);
168848
- return { kind: http ? "http" : "invoke", ...methods.length ? { methods } : {} };
169128
+ const http2 = /\bDeno\.serve\s*\(|\bserve\s*\(\s*(?:async\s*)?\(?\s*req/.test(code);
169129
+ return { kind: http2 ? "http" : "invoke", ...methods.length ? { methods } : {} };
168849
169130
  }
168850
169131
  function automationsOf(v2) {
168851
169132
  if (!Array.isArray(v2)) return void 0;
@@ -170836,9 +171117,9 @@ function cmsStatusNote(taxonomy) {
170836
171117
  bits.push("skipped: no owner token \u2014 re-run with `--site <msid>` (owner auth) to list the site's collections");
170837
171118
  break;
170838
171119
  case "error": {
170839
- const http = taxonomy.cmsErrorStatus;
170840
- const remedy = http === 429 ? "the site rate-limited the listing \u2014 wait and re-run" : http != null && http >= 500 ? "Wix Data failed upstream \u2014 retry later, and investigate the service if it persists" : http === 401 || http === 403 ? "check the owner token is current and carries the Wix Data read permission, then re-run" : "check the owner token and the `--site <msid>` you passed, then re-run";
170841
- bits.push(`error${http ? ` HTTP ${http}` : ""}: the listing call failed \u2014 ${remedy}`);
171120
+ const http2 = taxonomy.cmsErrorStatus;
171121
+ const remedy = http2 === 429 ? "the site rate-limited the listing \u2014 wait and re-run" : http2 != null && http2 >= 500 ? "Wix Data failed upstream \u2014 retry later, and investigate the service if it persists" : http2 === 401 || http2 === 403 ? "check the owner token is current and carries the Wix Data read permission, then re-run" : "check the owner token and the `--site <msid>` you passed, then re-run";
171122
+ bits.push(`error${http2 ? ` HTTP ${http2}` : ""}: the listing call failed \u2014 ${remedy}`);
170842
171123
  break;
170843
171124
  }
170844
171125
  default:
@@ -175055,7 +175336,7 @@ var init_dist = __esm({
175055
175336
  return promiseCallback.reject(new Error(SAME_SITE_CONTEXT_VAL_ERR));
175056
175337
  }
175057
175338
  }
175058
- const http = options.http ?? true;
175339
+ const http2 = options.http ?? true;
175059
175340
  const now = Date.now();
175060
175341
  const expireCheck = options.expire ?? true;
175061
175342
  const allPaths = options.allPaths ?? false;
@@ -175076,7 +175357,7 @@ var init_dist = __esm({
175076
175357
  if (c2.secure && !potentiallyTrustworthy) {
175077
175358
  return false;
175078
175359
  }
175079
- if (c2.httpOnly && !http) {
175360
+ if (c2.httpOnly && !http2) {
175080
175361
  return false;
175081
175362
  }
175082
175363
  if (sameSiteLevel) {
@@ -185123,7 +185404,7 @@ function execNpmConfig(file2, args, options) {
185123
185404
  });
185124
185405
  }
185125
185406
  var npmScopedWixRegistry = createScopedRegistryResolver();
185126
- async function scopedRegistryBefore(lookup3, deadline, onTimeout) {
185407
+ async function scopedRegistryBefore(lookup4, deadline, onTimeout) {
185127
185408
  let cancel = () => {
185128
185409
  };
185129
185410
  const expired = new Promise((resolve66) => {
@@ -185134,16 +185415,16 @@ async function scopedRegistryBefore(lookup3, deadline, onTimeout) {
185134
185415
  cancel = () => clearTimeout(timer);
185135
185416
  });
185136
185417
  try {
185137
- return await Promise.race([Promise.resolve().then(() => lookup3(Math.max(0, deadline - Date.now()))), expired]);
185418
+ return await Promise.race([Promise.resolve().then(() => lookup4(Math.max(0, deadline - Date.now()))), expired]);
185138
185419
  } catch {
185139
185420
  return void 0;
185140
185421
  } finally {
185141
185422
  cancel();
185142
185423
  }
185143
185424
  }
185144
- function lookupOnce(lookup3) {
185425
+ function lookupOnce(lookup4) {
185145
185426
  let first;
185146
- return (budgetMs) => first ??= Promise.resolve().then(() => lookup3(budgetMs));
185427
+ return (budgetMs) => first ??= Promise.resolve().then(() => lookup4(budgetMs));
185147
185428
  }
185148
185429
  function registryCandidates(env, scoped) {
185149
185430
  const ordered = [isTrustedRegistry(scoped) ? normalizeRegistry(scoped) : void 0, trustedConfiguredRegistry(env), PUBLIC_NPM_REGISTRY];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.1438.0",
3
+ "version": "0.1439.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": "ecadfa529dda6d1f49570340c04988f711cb239a5209ce8c69e31e86"
74
+ "falconPackageHash": "517214ad79ba1f66fcc679a54a5edf1e5242a258037728e41501f8ce"
75
75
  }