@wix/himalaya-cli 0.1002.0 → 0.1004.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -74,36 +74,36 @@ __export(config_exports, {
74
74
  import { homedir } from "node:os";
75
75
  import { join, dirname } from "node:path";
76
76
  import { readFileSync, writeFileSync, mkdirSync, chmodSync } from "node:fs";
77
- function loadTargetsFile(path = defaultTargetsPath()) {
77
+ function loadTargetsFile(path2 = defaultTargetsPath()) {
78
78
  try {
79
- return JSON.parse(readFileSync(path, "utf8"));
79
+ return JSON.parse(readFileSync(path2, "utf8"));
80
80
  } catch {
81
81
  return {};
82
82
  }
83
83
  }
84
- function saveControlToken(target, token, path = defaultTargetsPath()) {
85
- const file = loadTargetsFile(path);
84
+ function saveControlToken(target, token, path2 = defaultTargetsPath()) {
85
+ const file = loadTargetsFile(path2);
86
86
  file.targets = file.targets ?? {};
87
87
  file.targets[target] = { ...file.targets[target], controlToken: token };
88
- writeTargetsFilePrivate(path, file);
89
- return path;
88
+ writeTargetsFilePrivate(path2, file);
89
+ return path2;
90
90
  }
91
- function writeTargetsFilePrivate(path, file) {
92
- mkdirSync(dirname(path), { recursive: true, mode: 448 });
93
- writeFileSync(path, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
91
+ function writeTargetsFilePrivate(path2, file) {
92
+ mkdirSync(dirname(path2), { recursive: true, mode: 448 });
93
+ writeFileSync(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
94
94
  try {
95
- chmodSync(dirname(path), 448);
96
- chmodSync(path, 384);
95
+ chmodSync(dirname(path2), 448);
96
+ chmodSync(path2, 384);
97
97
  } catch {
98
98
  }
99
99
  }
100
- function clearControlToken(target, path = defaultTargetsPath()) {
101
- const file = loadTargetsFile(path);
100
+ function clearControlToken(target, path2 = defaultTargetsPath()) {
101
+ const file = loadTargetsFile(path2);
102
102
  if (file.targets?.[target]?.controlToken) {
103
103
  delete file.targets[target].controlToken;
104
- writeFileSync(path, JSON.stringify(file, null, 2) + "\n");
104
+ writeFileSync(path2, JSON.stringify(file, null, 2) + "\n");
105
105
  }
106
- return path;
106
+ return path2;
107
107
  }
108
108
  function resolveTargetName(opts = {}) {
109
109
  const env = opts.env ?? process.env;
@@ -2306,6 +2306,17 @@ var init_cms_schema = __esm({
2306
2306
  });
2307
2307
 
2308
2308
  // src/wix-owner.ts
2309
+ var wix_owner_exports = {};
2310
+ __export(wix_owner_exports, {
2311
+ WixApiError: () => WixApiError,
2312
+ accountToken: () => accountToken,
2313
+ mapLimit: () => mapLimit,
2314
+ ownerTransport: () => ownerTransport,
2315
+ redactForError: () => redactForError,
2316
+ resolveSiteId: () => resolveSiteId,
2317
+ siteToken: () => siteToken,
2318
+ withRetry: () => withRetry
2319
+ });
2309
2320
  import { spawn } from "node:child_process";
2310
2321
  function resolveSiteId(flag) {
2311
2322
  const id = flag?.trim() || process.env.WIX_SITE_ID?.trim();
@@ -2384,7 +2395,7 @@ function mintHelp(label2, detail) {
2384
2395
  return `could not run \`${label2}\` (${detail}). Install the Wix CLI and log in (\`npm i -g @wix/cli && wix login\`), or set WIX_TEST_TOKEN.`;
2385
2396
  }
2386
2397
  function ownerTransport(msid, fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS2) {
2387
- return async (method, path, body) => {
2398
+ return async (method, path2, body) => {
2388
2399
  const headers2 = {
2389
2400
  Authorization: await siteToken(msid),
2390
2401
  "wix-site-id": msid,
@@ -2394,7 +2405,7 @@ function ownerTransport(msid, fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS2
2394
2405
  const started = Date.now();
2395
2406
  let res;
2396
2407
  try {
2397
- res = await fetchImpl(`${API_BASE}${path}`, {
2408
+ res = await fetchImpl(`${API_BASE}${path2}`, {
2398
2409
  method,
2399
2410
  headers: headers2,
2400
2411
  body: body === void 0 ? void 0 : JSON.stringify(body),
@@ -2404,10 +2415,10 @@ function ownerTransport(msid, fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS2
2404
2415
  const err = e;
2405
2416
  if (err?.name === "TimeoutError" || /aborted due to timeout/i.test(err?.message ?? "")) {
2406
2417
  throw new Error(
2407
- `${method} ${path} timed out after ${Date.now() - started}ms (limit ${timeoutMs}ms). Wix REST over a VPN'd link is slow and a large site's collection list can be ~1MB. Raise the ceiling with HIMI_WIX_TIMEOUT_MS=<ms>, or check the VPN.`
2418
+ `${method} ${path2} timed out after ${Date.now() - started}ms (limit ${timeoutMs}ms). Wix REST over a VPN'd link is slow and a large site's collection list can be ~1MB. Raise the ceiling with HIMI_WIX_TIMEOUT_MS=<ms>, or check the VPN.`
2408
2419
  );
2409
2420
  }
2410
- throw new Error(`${method} ${path} failed: ${err?.message ?? String(e)}`);
2421
+ throw new Error(`${method} ${path2} failed: ${err?.message ?? String(e)}`);
2411
2422
  }
2412
2423
  const text4 = await res.text();
2413
2424
  let parsed = text4;
@@ -2415,7 +2426,7 @@ function ownerTransport(msid, fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS2
2415
2426
  parsed = text4 ? JSON.parse(text4) : null;
2416
2427
  } catch {
2417
2428
  }
2418
- if (!res.ok) throw new WixApiError(res.status, method, path, parsed);
2429
+ if (!res.ok) throw new WixApiError(res.status, method, path2, parsed);
2419
2430
  return parsed;
2420
2431
  };
2421
2432
  }
@@ -2457,12 +2468,12 @@ var init_wix_owner = __esm({
2457
2468
  TOKEN_MINT_TIMEOUT_MS = 3e4;
2458
2469
  ACCOUNT_TOKEN_KEY = "account:*";
2459
2470
  WixApiError = class extends Error {
2460
- constructor(status, method, path, body) {
2471
+ constructor(status, method, path2, body) {
2461
2472
  const detail = typeof body === "string" ? body.slice(0, 300) : JSON.stringify(body)?.slice(0, 300);
2462
- super(`${method} ${path} -> ${status}: ${detail}`);
2473
+ super(`${method} ${path2} -> ${status}: ${detail}`);
2463
2474
  this.status = status;
2464
2475
  this.method = method;
2465
- this.path = path;
2476
+ this.path = path2;
2466
2477
  this.body = body;
2467
2478
  this.name = "WixApiError";
2468
2479
  }
@@ -2542,8 +2553,8 @@ function homeRefreshActionId(name) {
2542
2553
  function committedProvisioningPath(name) {
2543
2554
  return `${shellAppDir(name)}/provisioning.json`;
2544
2555
  }
2545
- function committedShellFor(path) {
2546
- const normalized = path.replace(/\\/g, "/");
2556
+ function committedShellFor(path2) {
2557
+ const normalized = path2.replace(/\\/g, "/");
2547
2558
  return SHELL_NAMES2.find((name) => {
2548
2559
  const relative9 = committedProvisioningPath(name);
2549
2560
  return normalized === relative9 || normalized.endsWith(`/${relative9}`);
@@ -3197,9 +3208,9 @@ function umbrellaRewritePlugin({ external = false } = {}) {
3197
3208
  name: "himalaya-umbrella-rewrite",
3198
3209
  setup(b) {
3199
3210
  b.onResolve({ filter: /^@himalaya\// }, async (args) => {
3200
- const path = args.path.replace(/^@himalaya\//, "@wix/himalaya/");
3201
- if (external) return { path, external: true };
3202
- return b.resolve(path, { resolveDir: args.resolveDir, kind: args.kind });
3211
+ const path2 = args.path.replace(/^@himalaya\//, "@wix/himalaya/");
3212
+ if (external) return { path: path2, external: true };
3213
+ return b.resolve(path2, { resolveDir: args.resolveDir, kind: args.kind });
3203
3214
  });
3204
3215
  }
3205
3216
  };
@@ -3232,8 +3243,8 @@ function tsExtResolvePlugin() {
3232
3243
  setup(b) {
3233
3244
  b.onResolve({ filter: /\.js$/ }, (args) => {
3234
3245
  if (args.kind === "entry-point" || !args.path.startsWith(".")) return void 0;
3235
- const ts = resolve8(args.resolveDir, args.path.replace(/\.js$/, ".ts"));
3236
- return existsSync8(ts) ? { path: ts } : void 0;
3246
+ const ts2 = resolve8(args.resolveDir, args.path.replace(/\.js$/, ".ts"));
3247
+ return existsSync8(ts2) ? { path: ts2 } : void 0;
3237
3248
  });
3238
3249
  }
3239
3250
  };
@@ -3949,7 +3960,7 @@ function bundleFor(file) {
3949
3960
  const match = /^tier5-src\/([^/]+)\//.exec(file);
3950
3961
  return match?.[1] ?? "_shared";
3951
3962
  }
3952
- function toIssue(ts, contentDir2, diagnostic) {
3963
+ function toIssue(ts2, contentDir2, diagnostic) {
3953
3964
  const file = diagnostic.file ? relativeFile(contentDir2, diagnostic.file.fileName) : void 0;
3954
3965
  const position = diagnostic.file && diagnostic.start !== void 0 ? diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start) : void 0;
3955
3966
  return {
@@ -3957,13 +3968,13 @@ function toIssue(ts, contentDir2, diagnostic) {
3957
3968
  ...file ? { file } : {},
3958
3969
  ...position ? { line: position.line + 1, column: position.character + 1 } : {},
3959
3970
  code: `TS${diagnostic.code}`,
3960
- message: ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
3971
+ message: ts2.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
3961
3972
  };
3962
3973
  }
3963
- function confinedHost(ts, contentDir2, options) {
3974
+ function confinedHost(ts2, contentDir2, options) {
3964
3975
  if (!buildConfinementRequired()) return void 0;
3965
- const host = ts.createCompilerHost(options);
3966
- const libDir = resolve10(ts.getDefaultLibFilePath(options), "..");
3976
+ const host = ts2.createCompilerHost(options);
3977
+ const libDir = resolve10(ts2.getDefaultLibFilePath(options), "..");
3967
3978
  const allows = confinementMatcher(contentDir2, [libDir]);
3968
3979
  const getSourceFile = host.getSourceFile.bind(host);
3969
3980
  const readFile3 = host.readFile.bind(host);
@@ -3991,7 +4002,7 @@ function confinedHost(ts, contentDir2, options) {
3991
4002
  }
3992
4003
  async function typecheckContentWorkers(contentDir2, options) {
3993
4004
  if (!existsSync9(resolve10(contentDir2, "tier5-src"))) return [];
3994
- const ts = await compiler2();
4005
+ const ts2 = await compiler2();
3995
4006
  const config = {
3996
4007
  compilerOptions: {
3997
4008
  ...CONTENT_WORKER_COMPILER_OPTIONS,
@@ -4000,18 +4011,18 @@ async function typecheckContentWorkers(contentDir2, options) {
4000
4011
  // The deployed authoring runtime stages TypeScript 6, which requires an explicit
4001
4012
  // acknowledgement for this compatibility `baseUrl`; the repository's TypeScript 5 lane
4002
4013
  // rejects that 6.0 value, so keep it specific to the compiler that needs it.
4003
- ...Number.parseInt(ts.versionMajorMinor, 10) >= 6 ? { ignoreDeprecations: "6.0" } : {}
4014
+ ...Number.parseInt(ts2.versionMajorMinor, 10) >= 6 ? { ignoreDeprecations: "6.0" } : {}
4004
4015
  },
4005
4016
  include: ["tier5-src/*/index.ts", "tier5-src/_shared/**/*.ts"]
4006
4017
  };
4007
- const parsed = ts.parseJsonConfigFileContent(config, ts.sys, contentDir2);
4018
+ const parsed = ts2.parseJsonConfigFileContent(config, ts2.sys, contentDir2);
4008
4019
  if (parsed.fileNames.length === 0) return [];
4009
- const program = ts.createProgram({
4020
+ const program = ts2.createProgram({
4010
4021
  rootNames: parsed.fileNames,
4011
4022
  options: parsed.options,
4012
- host: confinedHost(ts, contentDir2, parsed.options)
4023
+ host: confinedHost(ts2, contentDir2, parsed.options)
4013
4024
  });
4014
- return [...parsed.errors, ...ts.getPreEmitDiagnostics(program)].filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error && belongsToContentWorkers(contentDir2, diagnostic)).map((diagnostic) => toIssue(ts, contentDir2, diagnostic));
4025
+ return [...parsed.errors, ...ts2.getPreEmitDiagnostics(program)].filter((diagnostic) => diagnostic.category === ts2.DiagnosticCategory.Error && belongsToContentWorkers(contentDir2, diagnostic)).map((diagnostic) => toIssue(ts2, contentDir2, diagnostic));
4015
4026
  }
4016
4027
  var compilerPromise;
4017
4028
  var init_tier5_typecheck = __esm({
@@ -5267,41 +5278,41 @@ function buildTokenRegistry(tokens) {
5267
5278
  materials: new Set(Object.keys(tokens.materials ?? {}))
5268
5279
  };
5269
5280
  }
5270
- function findTokenViolations(payload, registry, path = "$") {
5281
+ function findTokenViolations(payload, registry, path2 = "$") {
5271
5282
  const out = [];
5272
- walk(payload, registry, path, out);
5283
+ walk(payload, registry, path2, out);
5273
5284
  return out;
5274
5285
  }
5275
- function walk(node, registry, path, out) {
5286
+ function walk(node, registry, path2, out) {
5276
5287
  if (node === null || typeof node !== "object") return;
5277
5288
  if (Array.isArray(node)) {
5278
- node.forEach((item, i) => walk(item, registry, `${path}[${i}]`, out));
5289
+ node.forEach((item, i) => walk(item, registry, `${path2}[${i}]`, out));
5279
5290
  return;
5280
5291
  }
5281
5292
  const obj2 = node;
5282
5293
  const bg = obj2.background;
5283
5294
  if (bg && typeof bg.token === "string" && !registry.colors.has(bg.token)) {
5284
- out.push({ path: `${path}.background.token`, kind: "color", name: bg.token });
5295
+ out.push({ path: `${path2}.background.token`, kind: "color", name: bg.token });
5285
5296
  }
5286
5297
  if (obj2.type === "Text") {
5287
5298
  const props = obj2.props;
5288
5299
  if (props && typeof props.style === "string" && !registry.typography.has(props.style)) {
5289
5300
  out.push({
5290
- path: `${path}.props.style`,
5301
+ path: `${path2}.props.style`,
5291
5302
  kind: "typography",
5292
5303
  name: props.style
5293
5304
  });
5294
5305
  }
5295
5306
  if (props && typeof props.color === "string" && !registry.colors.has(props.color)) {
5296
5307
  out.push({
5297
- path: `${path}.props.color`,
5308
+ path: `${path2}.props.color`,
5298
5309
  kind: "color",
5299
5310
  name: props.color
5300
5311
  });
5301
5312
  }
5302
5313
  }
5303
5314
  for (const [key2, value] of Object.entries(obj2)) {
5304
- walk(value, registry, `${path}.${key2}`, out);
5315
+ walk(value, registry, `${path2}.${key2}`, out);
5305
5316
  }
5306
5317
  }
5307
5318
  var SYSTEM_FONT_FAMILY;
@@ -5346,11 +5357,11 @@ var init_bindings = __esm({
5346
5357
  // ../../core/ts/src/validator.ts
5347
5358
  import Ajv from "ajv";
5348
5359
  import addFormats from "ajv-formats";
5349
- function findUnknownComponents(node, allowed2, path = "$", out = []) {
5360
+ function findUnknownComponents(node, allowed2, path2 = "$", out = []) {
5350
5361
  if (node === null || typeof node !== "object") return out;
5351
5362
  if (Array.isArray(node)) {
5352
5363
  node.forEach(
5353
- (item, i) => findUnknownComponents(item, allowed2, `${path}[${i}]`, out)
5364
+ (item, i) => findUnknownComponents(item, allowed2, `${path2}[${i}]`, out)
5354
5365
  );
5355
5366
  return out;
5356
5367
  }
@@ -5359,11 +5370,11 @@ function findUnknownComponents(node, allowed2, path = "$", out = []) {
5359
5370
  if (body && typeof body.package === "string" && typeof body.type === "string") {
5360
5371
  const key2 = `${body.package}.${body.type}`;
5361
5372
  if (!allowed2.has(key2)) {
5362
- out.push({ path, package: body.package, type: body.type });
5373
+ out.push({ path: path2, package: body.package, type: body.type });
5363
5374
  }
5364
5375
  }
5365
5376
  for (const [key2, value] of Object.entries(obj2)) {
5366
- findUnknownComponents(value, allowed2, `${path}.${key2}`, out);
5377
+ findUnknownComponents(value, allowed2, `${path2}.${key2}`, out);
5367
5378
  }
5368
5379
  return out;
5369
5380
  }
@@ -5375,9 +5386,9 @@ function compileWidgetSchema() {
5375
5386
  }
5376
5387
  return widgetValidateFn;
5377
5388
  }
5378
- function validateWidgetActionRef(action, path, intents) {
5389
+ function validateWidgetActionRef(action, path2, intents) {
5379
5390
  if (typeof action !== "object" || action === null || Array.isArray(action)) {
5380
- intents.push({ path, reason: "must be an object { actionId, params? }" });
5391
+ intents.push({ path: path2, reason: "must be an object { actionId, params? }" });
5381
5392
  return;
5382
5393
  }
5383
5394
  const actionId = action.actionId;
@@ -5386,48 +5397,48 @@ function validateWidgetActionRef(action, path, intents) {
5386
5397
  const unsupportedFields = Object.keys(action).filter((key2) => !WIDGET_ACTION_FIELDS.has(key2));
5387
5398
  if (unsupportedFields.length > 0) {
5388
5399
  intents.push({
5389
- path,
5400
+ path: path2,
5390
5401
  reason: `unsupported field(s) on a widget action: ${unsupportedFields.sort().join(", ")} \u2014 a frozen widget action carries only \`actionId\` and literal \`params\``
5391
5402
  });
5392
5403
  }
5393
5404
  const knownAction = typeof actionId === "string" && Object.prototype.hasOwnProperty.call(WIDGET_INTENT_RULES, actionId);
5394
5405
  if (typeof actionId !== "string" || actionId.length === 0) {
5395
- intents.push({ path, reason: "`actionId` must be a non-empty string" });
5406
+ intents.push({ path: path2, reason: "`actionId` must be a non-empty string" });
5396
5407
  } else if (!knownAction) {
5397
- intents.push({ path, reason: `unsupported widget actionId "${actionId}"` });
5408
+ intents.push({ path: path2, reason: `unsupported widget actionId "${actionId}"` });
5398
5409
  }
5399
5410
  if (params !== void 0 && (typeof params !== "object" || params === null || Array.isArray(params) || !Object.values(params).every((value) => typeof value === "string"))) {
5400
- intents.push({ path, reason: "`params` must be a { string: string } map of literals" });
5411
+ intents.push({ path: path2, reason: "`params` must be a { string: string } map of literals" });
5401
5412
  } else if (knownAction) {
5402
5413
  const rule = WIDGET_INTENT_RULES[actionId];
5403
5414
  const literalParams = params ?? {};
5404
5415
  if (Object.keys(literalParams).length > 8 || utf8ByteLength(JSON.stringify(literalParams)) > 1024 || Object.entries(literalParams).some(([key2, value]) => utf8ByteLength(key2) > 64 || utf8ByteLength(value) > 512)) {
5405
- intents.push({ path, reason: "parameters exceed the widget action size limit" });
5416
+ intents.push({ path: path2, reason: "parameters exceed the widget action size limit" });
5406
5417
  }
5407
5418
  const allowed2 = /* @__PURE__ */ new Set([...rule.required, ...rule.optional ?? []]);
5408
5419
  const unknown = Object.keys(literalParams).filter((key2) => !allowed2.has(key2));
5409
5420
  const missing = rule.required.filter((key2) => !literalParams[key2]);
5410
5421
  if (unknown.length > 0) {
5411
- intents.push({ path, reason: `unsupported parameter(s): ${unknown.join(", ")}` });
5422
+ intents.push({ path: path2, reason: `unsupported parameter(s): ${unknown.join(", ")}` });
5412
5423
  }
5413
5424
  if (missing.length > 0) {
5414
- intents.push({ path, reason: `missing required parameter(s): ${missing.join(", ")}` });
5425
+ intents.push({ path: path2, reason: `missing required parameter(s): ${missing.join(", ")}` });
5415
5426
  }
5416
5427
  for (const [key2, values] of Object.entries(rule.values ?? {})) {
5417
5428
  const value = literalParams[key2];
5418
5429
  if (value !== void 0 && !values.includes(value)) {
5419
- intents.push({ path, reason: `invalid ${key2} "${value}"` });
5430
+ intents.push({ path: path2, reason: `invalid ${key2} "${value}"` });
5420
5431
  }
5421
5432
  }
5422
5433
  }
5423
5434
  }
5424
- function scanWidgetPayload(node, family, path, bindings, disallowed, timeRefs, intents, actionSites2) {
5435
+ function scanWidgetPayload(node, family, path2, bindings, disallowed, timeRefs, intents, actionSites2) {
5425
5436
  if (typeof node === "string") {
5426
- if (WIDGET_BINDING.test(node)) bindings.push({ path, value: node });
5437
+ if (WIDGET_BINDING.test(node)) bindings.push({ path: path2, value: node });
5427
5438
  return;
5428
5439
  }
5429
5440
  if (Array.isArray(node)) {
5430
- node.forEach((item, i) => scanWidgetPayload(item, family, `${path}[${i}]`, bindings, disallowed, timeRefs, intents, actionSites2));
5441
+ node.forEach((item, i) => scanWidgetPayload(item, family, `${path2}[${i}]`, bindings, disallowed, timeRefs, intents, actionSites2));
5431
5442
  return;
5432
5443
  }
5433
5444
  if (node === null || typeof node !== "object") return;
@@ -5436,46 +5447,46 @@ function scanWidgetPayload(node, family, path, bindings, disallowed, timeRefs, i
5436
5447
  if (body && typeof body.package === "string" && typeof body.type === "string") {
5437
5448
  const key2 = `${body.package}.${body.type}`;
5438
5449
  if (family && !isComponentAllowedForFamily(key2, family)) {
5439
- disallowed.push({ path, package: body.package, type: body.type, family });
5450
+ disallowed.push({ path: path2, package: body.package, type: body.type, family });
5440
5451
  }
5441
5452
  if (key2 === "himalaya.Button") {
5442
5453
  const props = body.props;
5443
5454
  if (!props || typeof props !== "object" || Array.isArray(props)) {
5444
- intents.push({ path: `${path}.body.props`, reason: "widget Button props must be an object" });
5455
+ intents.push({ path: `${path2}.body.props`, reason: "widget Button props must be an object" });
5445
5456
  } else if (family === "ios_home" || family === "android_home") {
5446
5457
  const button = props;
5447
5458
  if (button.intent !== void 0) {
5448
- intents.push({ path: `${path}.body.props.intent`, reason: "widget Button commands use the required `action` field" });
5459
+ intents.push({ path: `${path2}.body.props.intent`, reason: "widget Button commands use the required `action` field" });
5449
5460
  }
5450
- validateWidgetActionRef(button.action, `${path}.body.props.action`, intents);
5461
+ validateWidgetActionRef(button.action, `${path2}.body.props.action`, intents);
5451
5462
  const componentId = obj2.id;
5452
5463
  if (typeof componentId !== "string" || !WIDGET_ACTION_IDENTIFIER.test(componentId)) {
5453
5464
  intents.push({
5454
- path: `${path}.id`,
5465
+ path: `${path2}.id`,
5455
5466
  reason: "a widget Button carrying an action needs an id matching ^[A-Za-z0-9_.:-]{1,128}$, or the runtimes attach no handler to it"
5456
5467
  });
5457
5468
  }
5458
- actionSites2.push(`${path}.body.props.action`);
5469
+ actionSites2.push(`${path2}.body.props.action`);
5459
5470
  }
5460
5471
  }
5461
5472
  }
5462
5473
  if (obj2.timeRef !== void 0 && obj2.timeRef !== null) {
5463
5474
  const tr = obj2.timeRef;
5464
5475
  if (typeof tr !== "object" || Array.isArray(tr)) {
5465
- timeRefs.push({ path: `${path}.timeRef`, reason: "must be an object { at, style? }" });
5476
+ timeRefs.push({ path: `${path2}.timeRef`, reason: "must be an object { at, style? }" });
5466
5477
  } else {
5467
5478
  const at = tr.at;
5468
5479
  const style = tr.style;
5469
5480
  if (typeof at !== "number" || !Number.isFinite(at)) {
5470
- timeRefs.push({ path: `${path}.timeRef`, reason: "`at` must be a finite epoch-seconds number" });
5481
+ timeRefs.push({ path: `${path2}.timeRef`, reason: "`at` must be a finite epoch-seconds number" });
5471
5482
  }
5472
5483
  if (style !== void 0 && (typeof style !== "string" || !VALID_TIMEREF_STYLES.has(style))) {
5473
- timeRefs.push({ path: `${path}.timeRef`, reason: `invalid style "${String(style)}" (expected ${[...VALID_TIMEREF_STYLES].join("|")})` });
5484
+ timeRefs.push({ path: `${path2}.timeRef`, reason: `invalid style "${String(style)}" (expected ${[...VALID_TIMEREF_STYLES].join("|")})` });
5474
5485
  }
5475
5486
  }
5476
5487
  }
5477
5488
  for (const [k, v] of Object.entries(obj2)) {
5478
- scanWidgetPayload(v, family, `${path}.${k}`, bindings, disallowed, timeRefs, intents, actionSites2);
5489
+ scanWidgetPayload(v, family, `${path2}.${k}`, bindings, disallowed, timeRefs, intents, actionSites2);
5479
5490
  }
5480
5491
  }
5481
5492
  function validateWidget(snapshot2) {
@@ -6392,9 +6403,9 @@ function collectDescriptorStrings(descriptor) {
6392
6403
  seen.add(key2);
6393
6404
  out.push(f);
6394
6405
  };
6395
- const visit = (node, path) => {
6406
+ const visit = (node, path2) => {
6396
6407
  if (Array.isArray(node)) {
6397
- node.forEach((n, i) => visit(n, `${path}[${i}]`));
6408
+ node.forEach((n, i) => visit(n, `${path2}[${i}]`));
6398
6409
  return;
6399
6410
  }
6400
6411
  if (!node || typeof node !== "object") return;
@@ -6407,7 +6418,7 @@ function collectDescriptorStrings(descriptor) {
6407
6418
  for (const [prop, v] of Object.entries(props)) {
6408
6419
  if (typeof v !== "string" || BINDING_SIGIL.test(v)) continue;
6409
6420
  if (!isUserVisibleCopy(v)) continue;
6410
- const at = `${path}.body.props.${prop}`;
6421
+ const at = `${path2}.body.props.${prop}`;
6411
6422
  if (mapped.includes(prop) || SECONDARY_FIELDS.has(prop)) {
6412
6423
  push({ value: v, bucket: "reachable", type, prop, path: at });
6413
6424
  } else if (UNREACHED_VISIBLE_FIELDS.has(prop)) {
@@ -6421,19 +6432,19 @@ function collectDescriptorStrings(descriptor) {
6421
6432
  bucket: "reachable",
6422
6433
  type,
6423
6434
  prop: "template.template",
6424
- path: `${path}.body.props.template.template`
6435
+ path: `${path2}.body.props.template.template`
6425
6436
  });
6426
6437
  }
6427
6438
  }
6428
6439
  for (const [k, v] of Object.entries(obj2)) {
6429
6440
  if (k === "body") continue;
6430
6441
  if (typeof v === "string" && SECONDARY_FIELDS.has(k) && !BINDING_SIGIL.test(v) && isUserVisibleCopy(v)) {
6431
- push({ value: v, bucket: "reachable", type, prop: k, path: `${path}.${k}` });
6442
+ push({ value: v, bucket: "reachable", type, prop: k, path: `${path2}.${k}` });
6432
6443
  }
6433
6444
  }
6434
6445
  for (const [k, v] of Object.entries(obj2)) {
6435
- if (path === "" && k === "input" && v !== null && typeof v === "object") continue;
6436
- if (v && typeof v === "object") visit(v, path ? `${path}.${k}` : k);
6446
+ if (path2 === "" && k === "input" && v !== null && typeof v === "object") continue;
6447
+ if (v && typeof v === "object") visit(v, path2 ? `${path2}.${k}` : k);
6437
6448
  }
6438
6449
  };
6439
6450
  visit(descriptor, "");
@@ -6907,10 +6918,10 @@ async function bootBundleWorker(bundleJs, opts) {
6907
6918
  // `headers` is forwarded, not swallowed: it is how one call addresses a business other
6908
6919
  // than the ambient one (`site.forSite(msid)` → `wix-site-id`), and a wrapper that drops
6909
6920
  // it answers for the wrong business while every caller renders the result as correct.
6910
- call: (method, path, body, headers2) => {
6911
- const label2 = `${String(method)} ${String(path)}`;
6921
+ call: (method, path2, body, headers2) => {
6922
+ const label2 = `${String(method)} ${String(path2)}`;
6912
6923
  calls.push(label2);
6913
- return Promise.resolve(opts.wixCall(method, path, body, headers2)).then((value) => {
6924
+ return Promise.resolve(opts.wixCall(method, path2, body, headers2)).then((value) => {
6914
6925
  const bytes2 = responseBytes(value);
6915
6926
  if (bytes2 > MAX_FRAME_MESSAGE_BYTES) {
6916
6927
  oversizeWixResponses.push({ call: label2, bytes: bytes2 });
@@ -7148,11 +7159,11 @@ async function bootBundleWorker(bundleJs, opts) {
7148
7159
  }
7149
7160
  message = typeof asJson === "string" ? asJson : String(raw);
7150
7161
  } else message = String(raw);
7151
- const failed = { ...prev, _error: message };
7152
- if (prev.status === "loading") failed.status = "error";
7153
- if (prev.loading === true) failed.loading = false;
7154
- if (typeof prev.error === "string") failed.error = message;
7155
- def.state = failed;
7162
+ const failed2 = { ...prev, _error: message };
7163
+ if (prev.status === "loading") failed2.status = "error";
7164
+ if (prev.loading === true) failed2.loading = false;
7165
+ if (typeof prev.error === "string") failed2.error = message;
7166
+ def.state = failed2;
7156
7167
  };
7157
7168
  const runAction = async (def, label2, fn, args) => {
7158
7169
  let timer;
@@ -7349,9 +7360,9 @@ function validateDescriptorAction(action, context) {
7349
7360
  function validateDescriptorActions(actions, context) {
7350
7361
  return actions.map((action) => validateDescriptorAction(action, context)).filter((issue2) => issue2 !== null);
7351
7362
  }
7352
- function pathValue(state, path) {
7363
+ function pathValue(state, path2) {
7353
7364
  let cur = state;
7354
- for (const part of path.replace(/\[(\d+)\]/g, ".$1").split(".")) {
7365
+ for (const part of path2.replace(/\[(\d+)\]/g, ".$1").split(".")) {
7355
7366
  if (cur == null || typeof cur !== "object") return void 0;
7356
7367
  if (Array.isArray(cur)) {
7357
7368
  const idx = Number(part);
@@ -7364,9 +7375,9 @@ function pathValue(state, path) {
7364
7375
  }
7365
7376
  return cur;
7366
7377
  }
7367
- function pathResolves(state, path) {
7378
+ function pathResolves(state, path2) {
7368
7379
  let cur = state;
7369
- for (const part of path.replace(/\[(\d+)\]/g, ".$1").split(".")) {
7380
+ for (const part of path2.replace(/\[(\d+)\]/g, ".$1").split(".")) {
7370
7381
  if (cur == null || typeof cur !== "object") return false;
7371
7382
  if (Array.isArray(cur)) {
7372
7383
  const idx = Number(part);
@@ -7383,9 +7394,9 @@ function pathResolves(state, path) {
7383
7394
  }
7384
7395
  return true;
7385
7396
  }
7386
- function serviceFieldDeclared(state, path) {
7397
+ function serviceFieldDeclared(state, path2) {
7387
7398
  if (state == null || typeof state !== "object" || Array.isArray(state)) return false;
7388
- const first = path.replace(/\[(\d+)\]/g, ".$1").split(".")[0];
7399
+ const first = path2.replace(/\[(\d+)\]/g, ".$1").split(".")[0];
7389
7400
  return first in state;
7390
7401
  }
7391
7402
  function ellipsis(value, max) {
@@ -7398,70 +7409,70 @@ function isOpaqueAuthorJson(key2, value, atRoot) {
7398
7409
  if (value === null || typeof value !== "object") return false;
7399
7410
  return key2 === "args" || atRoot && key2 === "input";
7400
7411
  }
7401
- function pathCrossesOpaqueAuthorJson(path) {
7402
- if (typeof path !== "string") return false;
7403
- return /^\$\.input(?:[.[]|$)/.test(path) || /\.args(?:[.[]|$)/.test(path);
7412
+ function pathCrossesOpaqueAuthorJson(path2) {
7413
+ if (typeof path2 !== "string") return false;
7414
+ return /^\$\.input(?:[.[]|$)/.test(path2) || /\.args(?:[.[]|$)/.test(path2);
7404
7415
  }
7405
7416
  function nativeRequiredFindings(descriptor) {
7406
7417
  const out = [];
7407
7418
  const shapeOf = (ref) => ref.startsWith("list:") ? "an array" : ref.startsWith("map:") ? "an object keyed by name" : "an object";
7408
7419
  const kindOf = (value) => Array.isArray(value) ? "an array" : value === null ? "null" : typeof value === "object" ? "an object" : `a ${typeof value} (${JSON.stringify(value)})`;
7409
- const reportKind = (ref, value, path, from) => {
7420
+ const reportKind = (ref, value, path2, from) => {
7410
7421
  const cls = bareNestedClass(ref);
7411
7422
  const got = kindOf(value);
7412
7423
  const expected = ref.startsWith("list:") ? "Expected JsonArray" : `Expected JsonObject for type with serial name 'io.himalaya.core.${cls}'`;
7413
7424
  out.push({
7414
- path,
7425
+ path: path2,
7415
7426
  message: `${cls} is what the native decoder expects here \u2014 ${shapeOf(ref)} \u2014 but the descriptor has ${got}. Native decode rejects it ("${expected}") and drops the WHOLE screen from the seed, while web renders it fine (reached from ${from})`
7416
7427
  });
7417
7428
  };
7418
- const checkNested = (value, cls, path, from) => {
7429
+ const checkNested = (value, cls, path2, from) => {
7419
7430
  if (cls.startsWith("map:")) {
7420
7431
  if (!value || typeof value !== "object" || Array.isArray(value)) {
7421
- reportKind(cls, value, path, from);
7432
+ reportKind(cls, value, path2, from);
7422
7433
  return;
7423
7434
  }
7424
7435
  const of = cls.slice("map:".length);
7425
7436
  for (const [key2, v] of Object.entries(value)) {
7426
- checkNested(v, of, `${path}.${key2}`, from);
7437
+ checkNested(v, of, `${path2}.${key2}`, from);
7427
7438
  }
7428
7439
  return;
7429
7440
  }
7430
7441
  if (cls.startsWith("list:")) {
7431
7442
  if (!Array.isArray(value)) {
7432
- reportKind(cls, value, path, from);
7443
+ reportKind(cls, value, path2, from);
7433
7444
  return;
7434
7445
  }
7435
7446
  const of = cls.slice("list:".length);
7436
- value.forEach((v, i) => checkNested(v, of, `${path}[${i}]`, from));
7447
+ value.forEach((v, i) => checkNested(v, of, `${path2}[${i}]`, from));
7437
7448
  return;
7438
7449
  }
7439
7450
  const rule = own(NATIVE_NESTED_CLASSES, cls);
7440
7451
  if (!rule) return;
7441
7452
  if (Array.isArray(value) || !value || typeof value !== "object") {
7442
- reportKind(cls, value, path, from);
7453
+ reportKind(cls, value, path2, from);
7443
7454
  return;
7444
7455
  }
7445
7456
  const bag = value;
7446
7457
  for (const name of rule.required) {
7447
7458
  if (own(bag, name) !== void 0 && bag[name] !== null) continue;
7448
7459
  out.push({
7449
- path: `${path}.${name}`,
7460
+ path: `${path2}.${name}`,
7450
7461
  message: `${cls}.${name} is REQUIRED by the native decoder but is missing \u2014 native decode rejects it ("Field '${name}' is required for type with serial name 'io.himalaya.core.${cls}', but it was missing") and drops the WHOLE screen from the seed, while web renders it fine (reached from ${from})`
7451
7462
  });
7452
7463
  }
7453
7464
  for (const [name, sub] of Object.entries(rule.nested)) {
7454
7465
  const inner = own(bag, name);
7455
- if (inner !== void 0 && inner !== null) checkNested(inner, sub, `${path}.${name}`, from);
7466
+ if (inner !== void 0 && inner !== null) checkNested(inner, sub, `${path2}.${name}`, from);
7456
7467
  }
7457
- if (cls === "Action") checkActionParams(own(bag, "params"), `${path}.params`, from);
7468
+ if (cls === "Action") checkActionParams(own(bag, "params"), `${path2}.params`, from);
7458
7469
  };
7459
- const checkActionParams = (params, path, from) => {
7470
+ const checkActionParams = (params, path2, from) => {
7460
7471
  if (params === void 0 || params === null) return;
7461
7472
  const cost = "Native decode rejects it and drops the WHOLE screen from the seed, while web renders it fine";
7462
7473
  if (typeof params !== "object" || Array.isArray(params)) {
7463
7474
  out.push({
7464
- path,
7475
+ path: path2,
7465
7476
  message: `Action.params must be an object of strings, but the descriptor has ${kindOf(params)} ("Expected JsonObject"). ${cost} (reached from ${from})`
7466
7477
  });
7467
7478
  return;
@@ -7469,7 +7480,7 @@ function nativeRequiredFindings(descriptor) {
7469
7480
  for (const [key2, value] of Object.entries(params)) {
7470
7481
  if (typeof value === "string" || value === void 0) continue;
7471
7482
  out.push({
7472
- path: `${path}.${key2}`,
7483
+ path: `${path2}.${key2}`,
7473
7484
  message: `Action.params values must be strings, but params.${key2} is ${kindOf(value)} ("Expected JsonPrimitive at ${key2}" on Android, typeMismatch on iOS). ${cost}. Flatten it into string keys of params, or move structured data to Action.args (reached from ${from})`
7474
7485
  });
7475
7486
  }
@@ -7552,13 +7563,13 @@ function componentPropFindings(descriptor) {
7552
7563
  const bag = props;
7553
7564
  const base = at ? `${at}.body.props` : "body.props";
7554
7565
  for (const name of Object.keys(bag)) {
7555
- const path = `${base}.${name}`;
7566
+ const path2 = `${base}.${name}`;
7556
7567
  const kind = own(declared, name);
7557
7568
  if (kind === void 0) {
7558
7569
  if (LEGACY_UNSCORED_KEYS.has(`${type}.${name}`)) continue;
7559
7570
  const hint = MODIFIER_KEYS.has(name) ? ` \u2014 \`${name}\` is a MODIFIER, not a prop: move it out of \`props\` and into the node's \`modifiers\` bag (\`{ id, body, modifiers: { ${name}: \u2026 } }\`)` : "";
7560
7571
  out.push({
7561
- path,
7572
+ path: path2,
7562
7573
  kind: "hygiene",
7563
7574
  message: `${type} has no prop \`${name}\` \u2014 the native decoders are built with \`ignoreUnknownKeys = true\`, so this key is SILENTLY DROPPED on iOS and Android and the value never reaches the screen (web, whose props are \`any\`, may still show it). Declared props: ${Object.keys(declared).sort().join(", ") || "(none)"}${hint}`
7564
7575
  });
@@ -7572,7 +7583,7 @@ function componentPropFindings(descriptor) {
7572
7583
  const twin = own(declared, `${name}Path`) !== void 0 ? `${name}Path` : void 0;
7573
7584
  const inArray = IN_ARRAY_BINDING_PROPS.has(`${type}.${name}`) && value.startsWith(SERVICE_SIGIL);
7574
7585
  out.push({
7575
- path,
7586
+ path: path2,
7576
7587
  kind: "decode",
7577
7588
  ...inArray ? { authoringOnly: true } : {},
7578
7589
  // TWO different defects share this branch, and they need DIFFERENT prose.
@@ -7588,7 +7599,7 @@ function componentPropFindings(descriptor) {
7588
7599
  // copy-pasteable line that silently truncated a long path, so following the advice
7589
7600
  // bound to missing state; it stays truncated only in the diagnostic prose, where it
7590
7601
  // is describing rather than prescribing.
7591
- message: inArray ? `${type}.${name} is declared ${kind}, and a bare \`${ellipsis(value, 32)}\` does not satisfy it: the authoring contract types this prop as an array (see core/ts/src/schema.ts and the generated component.schema.json), so a typed author cannot write the scalar even though the native decoders would accept it. Put the sentinel INSIDE the array \u2014 \`${name}: ["${value}"]\` \u2014 which is the form the renderers read and the authoring schema accepts. At ${jsonPointer(path)}` : `${type}.${name} is declared ${kind}, and a binding does NOT satisfy it \u2014 a \`${ellipsis(value, 32)}\` sentinel is a plain STRING on the wire and is resolved AFTER native decode, so kotlinx sees a string where it wants a ${kind}, REJECTS the document and drops the WHOLE screen from the seed (web renders it fine). ` + (twin ? `Bind \`${twin}\` instead \u2014 it is declared string exactly so a sentinel survives decode.` : `Bind this prop's \`\u2026Path\` twin if it has one; a typed slot cannot carry a sentinel.`) + ` At ${jsonPointer(path)}`
7602
+ message: inArray ? `${type}.${name} is declared ${kind}, and a bare \`${ellipsis(value, 32)}\` does not satisfy it: the authoring contract types this prop as an array (see core/ts/src/schema.ts and the generated component.schema.json), so a typed author cannot write the scalar even though the native decoders would accept it. Put the sentinel INSIDE the array \u2014 \`${name}: ["${value}"]\` \u2014 which is the form the renderers read and the authoring schema accepts. At ${jsonPointer(path2)}` : `${type}.${name} is declared ${kind}, and a binding does NOT satisfy it \u2014 a \`${ellipsis(value, 32)}\` sentinel is a plain STRING on the wire and is resolved AFTER native decode, so kotlinx sees a string where it wants a ${kind}, REJECTS the document and drops the WHOLE screen from the seed (web renders it fine). ` + (twin ? `Bind \`${twin}\` instead \u2014 it is declared string exactly so a sentinel survives decode.` : `Bind this prop's \`\u2026Path\` twin if it has one; a typed slot cannot carry a sentinel.`) + ` At ${jsonPointer(path2)}`
7592
7603
  });
7593
7604
  continue;
7594
7605
  }
@@ -7597,17 +7608,17 @@ function componentPropFindings(descriptor) {
7597
7608
  if (actual === kind) {
7598
7609
  if (kind === "number" && typeof value === "number" && !Number.isInteger(value) && own(INTEGER_PROPS, type)?.includes(name)) {
7599
7610
  out.push({
7600
- path,
7611
+ path: path2,
7601
7612
  kind: "decode",
7602
- message: `${type}.${name} is declared an INTEGER by the native decoders but this descriptor carries ${value} \u2014 a fraction is not representable in an \`Int\` field, so decode REJECTS the document and drops the WHOLE screen from the seed, while web renders it fine. Round it. At ${jsonPointer(path)}`
7613
+ message: `${type}.${name} is declared an INTEGER by the native decoders but this descriptor carries ${value} \u2014 a fraction is not representable in an \`Int\` field, so decode REJECTS the document and drops the WHOLE screen from the seed, while web renders it fine. Round it. At ${jsonPointer(path2)}`
7603
7614
  });
7604
7615
  }
7605
7616
  continue;
7606
7617
  }
7607
7618
  out.push({
7608
- path,
7619
+ path: path2,
7609
7620
  kind: "decode",
7610
- message: `${type}.${name} is declared ${kind} but this descriptor carries a ${actual} (${JSON.stringify(value)?.slice(0, 40)}) \u2014 native decode REJECTS the document ("Unexpected JSON token ... expected ${kind}") and drops the WHOLE screen from the seed, while web renders it fine. At ${jsonPointer(path)}`
7621
+ message: `${type}.${name} is declared ${kind} but this descriptor carries a ${actual} (${JSON.stringify(value)?.slice(0, 40)}) \u2014 native decode REJECTS the document ("Unexpected JSON token ... expected ${kind}") and drops the WHOLE screen from the seed, while web renders it fine. At ${jsonPointer(path2)}`
7611
7622
  });
7612
7623
  }
7613
7624
  }
@@ -7870,15 +7881,15 @@ function workerSubtreeAllowed(screenId, allowlist) {
7870
7881
  }
7871
7882
  return false;
7872
7883
  }
7873
- function collectWixMediaReferences(value, path, found, mediaContext = false, bareIdContext = false, componentType = "", atRoot = false) {
7884
+ function collectWixMediaReferences(value, path2, found, mediaContext = false, bareIdContext = false, componentType = "", atRoot = false) {
7874
7885
  const unresolvedMedia = mediaContext && unresolvedWixMediaReference(value, bareIdContext);
7875
7886
  if (unresolvedMedia) {
7876
- found.push({ path, value: unresolvedMedia });
7887
+ found.push({ path: path2, value: unresolvedMedia });
7877
7888
  return;
7878
7889
  }
7879
7890
  if (Array.isArray(value)) {
7880
7891
  value.forEach((item, index) => {
7881
- collectWixMediaReferences(item, `${path}[${index}]`, found, mediaContext, bareIdContext);
7892
+ collectWixMediaReferences(item, `${path2}[${index}]`, found, mediaContext, bareIdContext);
7882
7893
  });
7883
7894
  return;
7884
7895
  }
@@ -7890,7 +7901,7 @@ function collectWixMediaReferences(value, path, found, mediaContext = false, bar
7890
7901
  const childComponentType = key2 === "props" && typeof record2.type === "string" ? record2.type : "";
7891
7902
  collectWixMediaReferences(
7892
7903
  child,
7893
- path ? `${path}.${key2}` : key2,
7904
+ path2 ? `${path2}.${key2}` : key2,
7894
7905
  found,
7895
7906
  mediaContext || isComponentMediaValueProperty(componentType, key2),
7896
7907
  bareIdContext || isMediaLocationProperty(key2),
@@ -7936,16 +7947,16 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
7936
7947
  };
7937
7948
  for (const e of v.schemaErrors) {
7938
7949
  const err = e;
7939
- const path = err.instancePath;
7940
- if (path === "/logicBundle/integrity" && lbIntegrity === "") continue;
7950
+ const path2 = err.instancePath;
7951
+ if (path2 === "/logicBundle/integrity" && lbIntegrity === "") continue;
7941
7952
  const issue2 = {
7942
7953
  severity: hygiene,
7943
7954
  pass: "schema",
7944
- path,
7955
+ path: path2,
7945
7956
  message: err.message ?? "schema violation"
7946
7957
  };
7947
7958
  issues.push(issue2);
7948
- for (const at of dottedCandidates(path ?? "")) {
7959
+ for (const at of dottedCandidates(path2 ?? "")) {
7949
7960
  if (err.keyword === "required" && err.params?.missingProperty) {
7950
7961
  indexIssue(at ? `${at}.${err.params.missingProperty}` : err.params.missingProperty, issue2);
7951
7962
  }
@@ -8355,11 +8366,11 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
8355
8366
  {
8356
8367
  const NAMED_ICON_PROPS = /* @__PURE__ */ new Set(["icon", "selectedIcon", "leadingIcon", "trailingIcon", "badgeIcon"]);
8357
8368
  const shape = (v2) => Array.isArray(v2) ? "an array" : typeof v2;
8358
- const flagNonString = (k, v2, path) => {
8369
+ const flagNonString = (k, v2, path2) => {
8359
8370
  issues.push({
8360
8371
  severity: "error",
8361
8372
  pass: "icons",
8362
- path,
8373
+ path: path2,
8363
8374
  message: `icon prop "${k}" is ${shape(v2)} (${JSON.stringify(v2)}) \u2014 IconRef is an icon-name STRING (or a "$service:"/"$item." binding), never an object. The native decoders reject the descriptor and drop the whole screen; web degrades to the unknown-icon marker. Pass the name directly, e.g. ${k}: "cart".`
8364
8375
  });
8365
8376
  };
@@ -8390,12 +8401,12 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
8390
8401
  const normIcon = (n) => n.toLowerCase().replace(/[_.\s-]/g, "");
8391
8402
  const ICON_NAME_PROPS = /* @__PURE__ */ new Set(["icon", "selectedIcon", "leadingIcon", "trailingIcon", "badgeIcon"]);
8392
8403
  const judgeable = (v2) => typeof v2 === "string" && v2.length > 0 && !v2.startsWith("$") && !v2.includes("/") && !v2.includes(":") && !/\.(png|jpe?g|svg|webp|gif)$/i.test(v2);
8393
- const flagIcon = (name, path) => {
8404
+ const flagIcon = (name, path2) => {
8394
8405
  if (allowedIcons.has(name) || allowedIcons.has(normIcon(name))) return;
8395
8406
  issues.push({
8396
8407
  severity: hygiene,
8397
8408
  pass: "icons",
8398
- path,
8409
+ path: path2,
8399
8410
  message: `unknown icon "${name}" \u2014 renders the _unknown marker on device. Run \`himi icons\` for the valid names, or add a row to core/schema/icon-sources.json + \`yarn icons:gen\`. Already an ERROR under --strict; becomes an error by default one release after the catalog ships (docs/icons.md \xA72.6).`
8400
8411
  });
8401
8412
  };
@@ -10675,14 +10686,14 @@ function tokenColorProblems(colors) {
10675
10686
  const problems = [];
10676
10687
  for (const [name, value] of Object.entries(colors ?? {})) {
10677
10688
  const leaves = typeof value === "object" && value !== null && !Array.isArray(value) ? Object.entries(value).map(([variant, raw]) => [`${name}.${variant}`, raw]) : [[name, value]];
10678
- for (const [path, raw] of leaves) {
10689
+ for (const [path2, raw] of leaves) {
10679
10690
  if (typeof raw !== "string") {
10680
- problems.push({ path, value: JSON.stringify(raw) ?? String(raw) });
10691
+ problems.push({ path: path2, value: JSON.stringify(raw) ?? String(raw) });
10681
10692
  continue;
10682
10693
  }
10683
10694
  if (isCanonicalHex(raw)) continue;
10684
10695
  const suggestion = canonicalHex(raw);
10685
- problems.push(suggestion ? { path, value: raw, suggestion } : { path, value: raw });
10696
+ problems.push(suggestion ? { path: path2, value: raw, suggestion } : { path: path2, value: raw });
10686
10697
  }
10687
10698
  }
10688
10699
  return problems;
@@ -11345,10 +11356,10 @@ function resolveAppDirIcon(appDir2) {
11345
11356
  return findContentIconPath(appDir2) ?? findAppIconPath(appDir2);
11346
11357
  }
11347
11358
  function readIconFromDir(appDir2) {
11348
- const path = resolveAppDirIcon(appDir2);
11349
- if (!path) return null;
11359
+ const path2 = resolveAppDirIcon(appDir2);
11360
+ if (!path2) return null;
11350
11361
  try {
11351
- return readFileSync15(path);
11362
+ return readFileSync15(path2);
11352
11363
  } catch {
11353
11364
  return null;
11354
11365
  }
@@ -11698,11 +11709,11 @@ function playState(dir) {
11698
11709
  }
11699
11710
  async function iconStatus(dir) {
11700
11711
  const declared = declaredIconName(dir);
11701
- const path = resolveAppDirIcon(dir);
11712
+ const path2 = resolveAppDirIcon(dir);
11702
11713
  const play = playState(dir);
11703
11714
  const base = {
11704
11715
  declared,
11705
- path,
11716
+ path: path2,
11706
11717
  play,
11707
11718
  bytes: null,
11708
11719
  sha256: null,
@@ -11714,21 +11725,21 @@ async function iconStatus(dir) {
11714
11725
  verdict: "missing",
11715
11726
  policyChecklist: POLICY_CHECKLIST
11716
11727
  };
11717
- if (!path || !existsSync15(path)) return base;
11728
+ if (!path2 || !existsSync15(path2)) return base;
11718
11729
  let png;
11719
11730
  try {
11720
- if (!statSync4(path).isFile()) {
11731
+ if (!statSync4(path2).isFile()) {
11721
11732
  return {
11722
11733
  ...base,
11723
- byteIssues: [`at ${path} is a directory, not a PNG file`],
11734
+ byteIssues: [`at ${path2} is a directory, not a PNG file`],
11724
11735
  verdict: "blocked"
11725
11736
  };
11726
11737
  }
11727
- png = readFileSync16(path);
11738
+ png = readFileSync16(path2);
11728
11739
  } catch (err) {
11729
11740
  return {
11730
11741
  ...base,
11731
- byteIssues: [`at ${path} could not be read (${err.message.split("\n")[0]})`],
11742
+ byteIssues: [`at ${path2} could not be read (${err.message.split("\n")[0]})`],
11732
11743
  verdict: "blocked"
11733
11744
  };
11734
11745
  }
@@ -11766,7 +11777,7 @@ async function iconStatus(dir) {
11766
11777
  ...status,
11767
11778
  pixelFindings: [{
11768
11779
  level: "error",
11769
- message: `App icon at ${path} could not be decoded as an image (${err.message.split("\n")[0]}) \u2014 it is not a usable PNG. Replace it with \`himi icon set <file.png>\`.`
11780
+ message: `App icon at ${path2} could not be decoded as an image (${err.message.split("\n")[0]}) \u2014 it is not a usable PNG. Replace it with \`himi icon set <file.png>\`.`
11770
11781
  }],
11771
11782
  pixelsChecked: false,
11772
11783
  verdict: "blocked"
@@ -11951,15 +11962,15 @@ function loadCatalog() {
11951
11962
  cached = JSON.parse(readFileSync17(override, "utf8"));
11952
11963
  return cached;
11953
11964
  }
11954
- const path = CATALOG_CANDIDATES.find((p) => existsSync17(p));
11955
- if (!path) {
11965
+ const path2 = CATALOG_CANDIDATES.find((p) => existsSync17(p));
11966
+ if (!path2) {
11956
11967
  throw new Error(
11957
11968
  `font catalog not found. Looked in:
11958
11969
  ${CATALOG_CANDIDATES.join("\n ")}
11959
11970
  In the repo, run \`npm run fonts:catalog\`. In a published @wix/himalaya-cli this is a packaging bug \u2014 the catalog should ship under the package's stdlib/fonts/.`
11960
11971
  );
11961
11972
  }
11962
- cached = JSON.parse(readFileSync17(path, "utf8"));
11973
+ cached = JSON.parse(readFileSync17(path2, "utf8"));
11963
11974
  return cached;
11964
11975
  }
11965
11976
  function renderableFamilies(catalog = loadCatalog()) {
@@ -12242,9 +12253,9 @@ async function offRepoFontBytes(plan, opts = {}) {
12242
12253
  out.hostProvided.push(r.family);
12243
12254
  continue;
12244
12255
  }
12245
- const failed = r.faces.find((f) => !f.got.ok);
12246
- if (failed && !failed.got.ok) {
12247
- out.unavailable.push({ family: r.family, reason: failed.got.reason });
12256
+ const failed2 = r.faces.find((f) => !f.got.ok);
12257
+ if (failed2 && !failed2.got.ok) {
12258
+ out.unavailable.push({ family: r.family, reason: failed2.got.reason });
12248
12259
  continue;
12249
12260
  }
12250
12261
  out.ready.push({
@@ -12719,9 +12730,9 @@ __export(fonts_exports, {
12719
12730
  });
12720
12731
  import { existsSync as existsSync19, readFileSync as readFileSync19 } from "node:fs";
12721
12732
  import { join as join22 } from "node:path";
12722
- function readJson(path, fallback) {
12733
+ function readJson(path2, fallback) {
12723
12734
  try {
12724
- return JSON.parse(readFileSync19(path, "utf8"));
12735
+ return JSON.parse(readFileSync19(path2, "utf8"));
12725
12736
  } catch {
12726
12737
  return fallback;
12727
12738
  }
@@ -12999,22 +13010,22 @@ function lc(h) {
12999
13010
  for (const [k, v] of Object.entries(h ?? {})) o[k.toLowerCase()] = v;
13000
13011
  return o;
13001
13012
  }
13002
- function matchRuleEx(rules, method, path, ctx = {}) {
13013
+ function matchRuleEx(rules, method, path2, ctx = {}) {
13003
13014
  for (const r of rules) {
13004
13015
  if (!r.enabled) continue;
13005
13016
  const m = r.matcher;
13006
13017
  if (m.method && m.method.toUpperCase() !== method.toUpperCase()) continue;
13007
13018
  if (m.host && ctx.host && !globToRegExp(m.host).test(ctx.host)) continue;
13008
13019
  if (m.host && !ctx.host) continue;
13009
- const captures = { path, host: ctx.host ?? "" };
13020
+ const captures = { path: path2, host: ctx.host ?? "" };
13010
13021
  if (m.pathRegex) {
13011
- const mm = new RegExp(m.pathRegex).exec(path);
13022
+ const mm = new RegExp(m.pathRegex).exec(path2);
13012
13023
  if (!mm) continue;
13013
13024
  mm.forEach((g, i) => {
13014
13025
  captures[String(i)] = g ?? "";
13015
13026
  });
13016
13027
  } else if (m.pathGlob) {
13017
- if (!globToRegExp(m.pathGlob).test(path)) continue;
13028
+ if (!globToRegExp(m.pathGlob).test(path2)) continue;
13018
13029
  }
13019
13030
  if (m.query) {
13020
13031
  const q = ctx.query ?? {};
@@ -13090,15 +13101,15 @@ function isNativePlatform(value) {
13090
13101
  function isNativeAuditStatus(value) {
13091
13102
  return typeof value === "string" && NATIVE_AUDIT_STATUSES.includes(value);
13092
13103
  }
13093
- function readText(path) {
13104
+ function readText(path2) {
13094
13105
  try {
13095
- return existsSync21(path) ? readFileSync21(path, "utf8") : null;
13106
+ return existsSync21(path2) ? readFileSync21(path2, "utf8") : null;
13096
13107
  } catch {
13097
13108
  return null;
13098
13109
  }
13099
13110
  }
13100
- function parseEvidence(path) {
13101
- const raw = readText(path);
13111
+ function parseEvidence(path2) {
13112
+ const raw = readText(path2);
13102
13113
  if (raw === null) return { evidence: null };
13103
13114
  try {
13104
13115
  const value = JSON.parse(raw);
@@ -13126,9 +13137,9 @@ function recordedRenderWidths(content) {
13126
13137
  const { evidence } = parseEvidence(uxEvidencePath(content));
13127
13138
  return renderEvidenceEntries(evidence).map((entry) => entry.width);
13128
13139
  }
13129
- function writeEvidence(path, evidence) {
13130
- mkdirSync10(dirname13(path), { recursive: true });
13131
- writeFileSync9(path, JSON.stringify(evidence, null, 2) + "\n");
13140
+ function writeEvidence(path2, evidence) {
13141
+ mkdirSync10(dirname13(path2), { recursive: true });
13142
+ writeFileSync9(path2, JSON.stringify(evidence, null, 2) + "\n");
13132
13143
  }
13133
13144
  function recordedFilePath(dir, file) {
13134
13145
  const rel = relative3(dir, resolve15(file));
@@ -13138,8 +13149,8 @@ function recordRenderWidth(content, entry) {
13138
13149
  try {
13139
13150
  if (!entry.screenId || !Number.isFinite(entry.width) || entry.width <= 0) return null;
13140
13151
  const dir = resolve15(content);
13141
- const path = join24(dir, UX_EVIDENCE_PATH);
13142
- const parsed = parseEvidence(path);
13152
+ const path2 = join24(dir, UX_EVIDENCE_PATH);
13153
+ const parsed = parseEvidence(path2);
13143
13154
  if (parsed.error) return null;
13144
13155
  const evidence = parsed.evidence ?? { version: 1, platforms: {} };
13145
13156
  const width = entry.width;
@@ -13155,7 +13166,7 @@ function recordRenderWidth(content, entry) {
13155
13166
  if (at >= 0) renders[at] = written;
13156
13167
  else renders.push(written);
13157
13168
  evidence.renders = renders;
13158
- writeEvidence(path, evidence);
13169
+ writeEvidence(path2, evidence);
13159
13170
  return written;
13160
13171
  } catch {
13161
13172
  return null;
@@ -13168,8 +13179,8 @@ function recordNativeAudit(content, platform, status, checks, reason, release) {
13168
13179
  }
13169
13180
  if (status === "unavailable" && !reason?.trim()) throw new Error("--reason is required when --status unavailable");
13170
13181
  const dir = resolve15(content);
13171
- const path = join24(dir, UX_EVIDENCE_PATH);
13172
- const parsed = parseEvidence(path);
13182
+ const path2 = join24(dir, UX_EVIDENCE_PATH);
13183
+ const parsed = parseEvidence(path2);
13173
13184
  if (parsed.error) throw new Error(`${UX_EVIDENCE_PATH} ${parsed.error}`);
13174
13185
  const evidence = parsed.evidence ?? { version: 1, platforms: {} };
13175
13186
  evidence.platforms[platform] = {
@@ -13179,12 +13190,12 @@ function recordNativeAudit(content, platform, status, checks, reason, release) {
13179
13190
  ...release?.releaseId && release.releaseHash ? { releaseId: release.releaseId, releaseHash: release.releaseHash } : {},
13180
13191
  recordedAt: (/* @__PURE__ */ new Date()).toISOString()
13181
13192
  };
13182
- writeEvidence(path, evidence);
13193
+ writeEvidence(path2, evidence);
13183
13194
  return evidence;
13184
13195
  }
13185
13196
  function uxEvidenceForRelease(content, release) {
13186
13197
  const { releaseId, releaseHash } = release;
13187
- const path = uxEvidencePath(content);
13198
+ const path2 = uxEvidencePath(content);
13188
13199
  const base = {
13189
13200
  path: UX_EVIDENCE_PATH,
13190
13201
  platforms: [],
@@ -13194,8 +13205,8 @@ function uxEvidenceForRelease(content, release) {
13194
13205
  inheritedScreens: [],
13195
13206
  malformed: []
13196
13207
  };
13197
- if (!existsSync21(path)) return { ...base, state: "absent" };
13198
- const parsed = parseEvidence(path);
13208
+ if (!existsSync21(path2)) return { ...base, state: "absent" };
13209
+ const parsed = parseEvidence(path2);
13199
13210
  if (parsed.error) return { ...base, state: "unreadable", error: parsed.error };
13200
13211
  if (!parsed.evidence) return { ...base, state: "absent" };
13201
13212
  const recorded = [];
@@ -14248,9 +14259,9 @@ function placeholderHashes() {
14248
14259
  const current = templateIconSha256();
14249
14260
  return current ? [LEGACY_PLACEHOLDER_SHA256, current] : [LEGACY_PLACEHOLDER_SHA256];
14250
14261
  }
14251
- function fileSha256(path) {
14262
+ function fileSha256(path2) {
14252
14263
  try {
14253
- return createHash7("sha256").update(readFileSync24(path)).digest("hex");
14264
+ return createHash7("sha256").update(readFileSync24(path2)).digest("hex");
14254
14265
  } catch {
14255
14266
  return null;
14256
14267
  }
@@ -14699,12 +14710,12 @@ function hostAppliesDeferredWidgetActions(app) {
14699
14710
  const dir = stack.pop();
14700
14711
  for (const entry of readdirSync13(dir, { withFileTypes: true })) {
14701
14712
  if (entry.name.startsWith(".") || entry.name === "GeneratedLiveActivity") continue;
14702
- const path = join29(dir, entry.name);
14713
+ const path2 = join29(dir, entry.name);
14703
14714
  if (entry.isDirectory()) {
14704
14715
  if (entry.name.endsWith(".xcodeproj") || entry.name === "build") continue;
14705
- stack.push(path);
14716
+ stack.push(path2);
14706
14717
  } else if (entry.name.endsWith(".swift")) {
14707
- if (readFileSync26(path, "utf8").includes("WidgetActionRelay.drain(")) return true;
14718
+ if (readFileSync26(path2, "utf8").includes("WidgetActionRelay.drain(")) return true;
14708
14719
  }
14709
14720
  }
14710
14721
  }
@@ -14735,29 +14746,29 @@ function androidManifestPath2(app) {
14735
14746
  function automotiveAppDescPath(app) {
14736
14747
  return join29(dirname16(androidManifestPath2(app)), "res", "xml", "automotive_app_desc.xml");
14737
14748
  }
14738
- function applyToFile(path, kind, label2, render, check) {
14739
- if (!existsSync26(path)) return { path, outcome: "skipped" };
14740
- const before = readFileSync26(path, "utf8");
14741
- if (!hasMarkers(before, kind, label2)) return { path, outcome: "skipped" };
14749
+ function applyToFile(path2, kind, label2, render, check) {
14750
+ if (!existsSync26(path2)) return { path: path2, outcome: "skipped" };
14751
+ const before = readFileSync26(path2, "utf8");
14752
+ if (!hasMarkers(before, kind, label2)) return { path: path2, outcome: "skipped" };
14742
14753
  const after = injectBlock(before, kind, label2, render);
14743
- if (after === before) return { path, outcome: "unchanged" };
14744
- if (check) return { path, outcome: "drift" };
14745
- writeFileSync11(path, after);
14746
- return { path, outcome: "written" };
14747
- }
14748
- function applyWholeFile(path, content, check) {
14749
- const current = existsSync26(path) ? readFileSync26(path, "utf8") : null;
14750
- if (current === content) return { path, outcome: "unchanged" };
14751
- if (check) return { path, outcome: "drift" };
14752
- mkdirSync12(dirname16(path), { recursive: true });
14753
- writeFileSync11(path, content);
14754
- return { path, outcome: "written" };
14755
- }
14756
- function removeWholeFile(path, check) {
14757
- if (!existsSync26(path)) return { path, outcome: "skipped" };
14758
- if (check) return { path, outcome: "drift" };
14759
- rmSync4(path);
14760
- return { path, outcome: "removed" };
14754
+ if (after === before) return { path: path2, outcome: "unchanged" };
14755
+ if (check) return { path: path2, outcome: "drift" };
14756
+ writeFileSync11(path2, after);
14757
+ return { path: path2, outcome: "written" };
14758
+ }
14759
+ function applyWholeFile(path2, content, check) {
14760
+ const current = existsSync26(path2) ? readFileSync26(path2, "utf8") : null;
14761
+ if (current === content) return { path: path2, outcome: "unchanged" };
14762
+ if (check) return { path: path2, outcome: "drift" };
14763
+ mkdirSync12(dirname16(path2), { recursive: true });
14764
+ writeFileSync11(path2, content);
14765
+ return { path: path2, outcome: "written" };
14766
+ }
14767
+ function removeWholeFile(path2, check) {
14768
+ if (!existsSync26(path2)) return { path: path2, outcome: "skipped" };
14769
+ if (check) return { path: path2, outcome: "drift" };
14770
+ rmSync4(path2);
14771
+ return { path: path2, outcome: "removed" };
14761
14772
  }
14762
14773
  function genNativeConfig(app, opts = {}) {
14763
14774
  const check = opts.check ?? false;
@@ -15003,15 +15014,15 @@ function collectBrandFonts(appDir2) {
15003
15014
  const rel = typeof raw?.file === "string" ? raw.file : "";
15004
15015
  if (!family || !postscriptName || !rel) continue;
15005
15016
  if (rel.startsWith("/") || rel.split("/").includes("..")) continue;
15006
- const path = join30(appDir2, rel);
15017
+ const path2 = join30(appDir2, rel);
15007
15018
  try {
15008
- if (!lstatSync4(path).isFile()) continue;
15019
+ if (!lstatSync4(path2).isFile()) continue;
15009
15020
  const root = realpathSync3(appDir2);
15010
- if (!realpathSync3(path).startsWith(root + sep6)) continue;
15021
+ if (!realpathSync3(path2).startsWith(root + sep6)) continue;
15011
15022
  } catch {
15012
15023
  continue;
15013
15024
  }
15014
- out.push({ family, postscriptName, weight, path });
15025
+ out.push({ family, postscriptName, weight, path: path2 });
15015
15026
  }
15016
15027
  return out;
15017
15028
  }
@@ -15200,7 +15211,7 @@ async function loadContainedDevModule(name, entry, dir) {
15200
15211
  // Both throw synchronously; `handleWant` awaits them inside its own try, so the guest sees an
15201
15212
  // ordinary rejection exactly as it would from any failing transport — while the host keeps the
15202
15213
  // record the guest's `catch` cannot erase.
15203
- wixCall: (method, path) => refuseHost("himalaya.wixApi.call", `${method} ${path}`),
15214
+ wixCall: (method, path2) => refuseHost("himalaya.wixApi.call", `${method} ${path2}`),
15204
15215
  dispatch: (action) => refuseHost("himalaya.dispatch", action)
15205
15216
  });
15206
15217
  const session = ran.session;
@@ -15303,7 +15314,7 @@ async function loadContainedDevModule(name, entry, dir) {
15303
15314
  createStore: () => storeStub,
15304
15315
  ...meta.dataRoutes?.length ? {
15305
15316
  dataRoutes: Object.fromEntries(
15306
- meta.dataRoutes.map((path) => [path, () => refuse(name, `the app data route ${JSON.stringify(path)}`)])
15317
+ meta.dataRoutes.map((path2) => [path2, () => refuse(name, `the app data route ${JSON.stringify(path2)}`)])
15307
15318
  )
15308
15319
  } : {},
15309
15320
  // NOT defaulted. An absent seed crosses as absent and the proxy carries `undefined`, which is
@@ -16095,8 +16106,8 @@ import { createHash as createHash9, randomBytes as randomBytes3 } from "node:cry
16095
16106
  function b64url(buf) {
16096
16107
  return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
16097
16108
  }
16098
- async function postJson(path, body, auth) {
16099
- const res = await fetch(`${API}${path}`, {
16109
+ async function postJson(path2, body, auth) {
16110
+ const res = await fetch(`${API}${path2}`, {
16100
16111
  method: "POST",
16101
16112
  headers: { "Content-Type": "application/json", ...auth ? { Authorization: auth } : {} },
16102
16113
  body: JSON.stringify(body)
@@ -16111,11 +16122,11 @@ async function mintVisitor(clientId) {
16111
16122
  }
16112
16123
  function isRedirectCallback(url, redirectUri) {
16113
16124
  if (url.startsWith(redirectUri)) return true;
16114
- const path = (u) => u.pathname.replace(/\/+$/, "") || "/";
16125
+ const path2 = (u) => u.pathname.replace(/\/+$/, "") || "/";
16115
16126
  try {
16116
16127
  const got = new URL(url);
16117
16128
  const want = new URL(redirectUri);
16118
- return got.protocol === want.protocol && got.host === want.host && path(got) === path(want);
16129
+ return got.protocol === want.protocol && got.host === want.host && path2(got) === path2(want);
16119
16130
  } catch {
16120
16131
  return false;
16121
16132
  }
@@ -16205,8 +16216,8 @@ async function memberDirectRegister(clientId, redirectUri, email, password, firs
16205
16216
  const memberToken = await exchangeSessionToken(clientId, redirectUri, visitorToken, sessionToken);
16206
16217
  return { memberToken, visitorToken };
16207
16218
  }
16208
- async function webWixCall(method, path, body, token, cookie, forwardedHeaders = {}) {
16209
- const url = /^https?:\/\//i.test(path) ? path : `${API}${path.startsWith("/") ? path : "/" + path}`;
16219
+ async function webWixCall(method, path2, body, token, cookie, forwardedHeaders = {}) {
16220
+ const url = /^https?:\/\//i.test(path2) ? path2 : `${API}${path2.startsWith("/") ? path2 : "/" + path2}`;
16210
16221
  if (!isWixTarget(url)) {
16211
16222
  throw new Error(`refusing to send Wix credentials to a non-Wix host (${targetHost(url) || "no host"})`);
16212
16223
  }
@@ -16276,10 +16287,10 @@ function resolveNetMocks(fileMocks, appDeclared) {
16276
16287
  if (declared.length > 0) return { mocks: { mode: appDeclared?.mode, rules: declared }, source: "app" };
16277
16288
  return null;
16278
16289
  }
16279
- function readNetMocksFile(path) {
16290
+ function readNetMocksFile(path2) {
16280
16291
  try {
16281
- if (!existsSync30(path)) return null;
16282
- const raw = JSON.parse(readFileSync30(path, "utf-8"));
16292
+ if (!existsSync30(path2)) return null;
16293
+ const raw = JSON.parse(readFileSync30(path2, "utf-8"));
16283
16294
  if (Array.isArray(raw)) return wixMockRuleErrors(raw).length ? null : { rules: raw };
16284
16295
  if (raw && typeof raw === "object") {
16285
16296
  const o = raw;
@@ -16357,20 +16368,20 @@ function parseTarget(target) {
16357
16368
  });
16358
16369
  return { host: u.host, path: u.pathname, query };
16359
16370
  } catch {
16360
- const path = target.split("?")[0];
16371
+ const path2 = target.split("?")[0];
16361
16372
  const query = {};
16362
16373
  new URLSearchParams(target.split("?")[1] ?? "").forEach((v, k) => {
16363
16374
  query[k] = v;
16364
16375
  });
16365
- return { host: "", path, query };
16376
+ return { host: "", path: path2, query };
16366
16377
  }
16367
16378
  }
16368
16379
  async function handleWixGateway(gw, app, adminUrl, req, res, wixClientId) {
16369
16380
  const url = req.url ?? "";
16370
- const path = url.split("?")[0];
16371
- const scope = path.startsWith("/__dev/wix/") ? "wix" : path.startsWith("/__dev/net/") ? "net" : null;
16381
+ const path2 = url.split("?")[0];
16382
+ const scope = path2.startsWith("/__dev/wix/") ? "wix" : path2.startsWith("/__dev/net/") ? "net" : null;
16372
16383
  if (!scope) return false;
16373
- const suffix = path.slice(scope === "wix" ? "/__dev/wix/".length : "/__dev/net/".length);
16384
+ const suffix = path2.slice(scope === "wix" ? "/__dev/wix/".length : "/__dev/net/".length);
16374
16385
  const method = (req.method ?? "GET").toUpperCase();
16375
16386
  if (suffix === "events" && method === "GET") {
16376
16387
  res.writeHead(200, {
@@ -16784,17 +16795,17 @@ var init_sha256 = __esm({
16784
16795
  });
16785
16796
 
16786
16797
  // ../../core/serve-runtime/src/wix-bridge.ts
16787
- function absoluteUrlRejection(path) {
16798
+ function absoluteUrlRejection(path2) {
16788
16799
  let host = "";
16789
16800
  try {
16790
- host = new URL(path).host;
16801
+ host = new URL(path2).host;
16791
16802
  } catch {
16792
16803
  }
16793
16804
  return OWNER_SCOPED_WIX_HOST.test(host) ? "owner-only" : "open-proxy";
16794
16805
  }
16795
- async function wixVisitorCall(method, path, body, token, fetchImpl = fetch, forwardedHeaders = {}) {
16796
- if (/^[a-z][a-z0-9+.-]*:\/\//i.test(path)) throw new Error("absolute URLs are not allowed");
16797
- const url = `${WIX_API}${path.startsWith("/") ? path : `/${path}`}`;
16806
+ async function wixVisitorCall(method, path2, body, token, fetchImpl = fetch, forwardedHeaders = {}) {
16807
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(path2)) throw new Error("absolute URLs are not allowed");
16808
+ const url = `${WIX_API}${path2.startsWith("/") ? path2 : `/${path2}`}`;
16798
16809
  const res = await fetchImpl(url, {
16799
16810
  method,
16800
16811
  // Same header shape the dev-server bridge has always sent (wixapis accepts the
@@ -16825,13 +16836,13 @@ function normalizeWixForwardedHeaders(input) {
16825
16836
  function isSafeMsid(msid) {
16826
16837
  return /^[0-9a-fA-F-]{10,64}$/.test(msid);
16827
16838
  }
16828
- function isOwnerSitesPath(path) {
16829
- return path === OWNER_SITES_QUERY_PATH || path === OWNER_SITES_COUNT_PATH;
16839
+ function isOwnerSitesPath(path2) {
16840
+ return path2 === OWNER_SITES_QUERY_PATH || path2 === OWNER_SITES_COUNT_PATH;
16830
16841
  }
16831
- async function wixOwnerSitesCall(path, cookieHeader, body, fetchImpl = fetch) {
16832
- if (!isOwnerSitesPath(path)) throw new Error("not an owner-sites path");
16842
+ async function wixOwnerSitesCall(path2, cookieHeader, body, fetchImpl = fetch) {
16843
+ if (!isOwnerSitesPath(path2)) throw new Error("not an owner-sites path");
16833
16844
  const xsrf = /(?:^|;\s*)XSRF-TOKEN=([^;]+)/.exec(cookieHeader)?.[1];
16834
- const res = await fetchImpl(`${WIX_API}${path}`, {
16845
+ const res = await fetchImpl(`${WIX_API}${path2}`, {
16835
16846
  method: "POST",
16836
16847
  headers: {
16837
16848
  Cookie: cookieHeader,
@@ -17106,8 +17117,8 @@ import { resolve as resolve24 } from "node:path";
17106
17117
  import { fileURLToPath as fileURLToPath14 } from "node:url";
17107
17118
  function loadCatalog2(tag) {
17108
17119
  if (catalogCache.has(tag)) return catalogCache.get(tag);
17109
- const path = resolve24(ROOT4, `tools/l10n/catalog.${tag}.json`);
17110
- const map = existsSync31(path) ? sourceMap(parseCatalog(readFileSync31(path, "utf8"))) : /* @__PURE__ */ new Map();
17120
+ const path2 = resolve24(ROOT4, `tools/l10n/catalog.${tag}.json`);
17121
+ const map = existsSync31(path2) ? sourceMap(parseCatalog(readFileSync31(path2, "utf8"))) : /* @__PURE__ */ new Map();
17111
17122
  catalogCache.set(tag, map);
17112
17123
  return map;
17113
17124
  }
@@ -17116,8 +17127,8 @@ function pickLocale(acceptLanguage) {
17116
17127
  const tags = acceptLanguage.split(",").map((s) => s.split(";")[0].trim().toLowerCase()).map((s) => s.split("-")[0]).filter((s) => s.length > 0);
17117
17128
  for (const tag of tags) {
17118
17129
  if (tag === "en") continue;
17119
- const path = resolve24(ROOT4, `tools/l10n/catalog.${tag}.json`);
17120
- if (existsSync31(path)) return tag;
17130
+ const path2 = resolve24(ROOT4, `tools/l10n/catalog.${tag}.json`);
17131
+ if (existsSync31(path2)) return tag;
17121
17132
  }
17122
17133
  return null;
17123
17134
  }
@@ -17213,8 +17224,8 @@ function assignStableIds(descriptor) {
17213
17224
  used.add(out);
17214
17225
  return out;
17215
17226
  };
17216
- const assign2 = (node, path) => {
17217
- const base = node.id && node.id.length > 0 ? node.id : path;
17227
+ const assign2 = (node, path2) => {
17228
+ const base = node.id && node.id.length > 0 ? node.id : path2;
17218
17229
  node.id = uniquify(base);
17219
17230
  const typeCounts = {};
17220
17231
  forEachChildComponent(node, (child) => {
@@ -17222,7 +17233,7 @@ function assignStableIds(descriptor) {
17222
17233
  const n = typeCounts[t] ?? 0;
17223
17234
  typeCounts[t] = n + 1;
17224
17235
  const seg = n === 0 ? t : `${t}.${n}`;
17225
- assign2(child, `${path}/${seg}`);
17236
+ assign2(child, `${path2}/${seg}`);
17226
17237
  });
17227
17238
  };
17228
17239
  if (isNode(descriptor.payload)) assign2(descriptor.payload, descriptor.screenId);
@@ -18142,8 +18153,8 @@ var init_tier4_verifier = __esm({
18142
18153
  async verifyServedFile(bundleId, relPath, providedBytes) {
18143
18154
  const expected = this.expectedSri(bundleId, relPath);
18144
18155
  if (!expected) return { ok: true };
18145
- const path = resolve25(this.tier4Root, bundleId, relPath);
18146
- const bytes2 = providedBytes ?? (existsSync33(path) ? readFileSync33(path) : null);
18156
+ const path2 = resolve25(this.tier4Root, bundleId, relPath);
18157
+ const bytes2 = providedBytes ?? (existsSync33(path2) ? readFileSync33(path2) : null);
18147
18158
  if (!bytes2) return { ok: false, reason: "file not found" };
18148
18159
  if (computeSri(bytes2) !== expected) return { ok: false, reason: "sri mismatch" };
18149
18160
  return { ok: true };
@@ -18235,9 +18246,9 @@ function targetTenant(url, headers2, hostApp) {
18235
18246
  const hdr = headers2["x-himalaya-app"];
18236
18247
  const headerApp = Array.isArray(hdr) ? hdr[0] : hdr;
18237
18248
  let app = headerApp && headerApp.trim() ? headerApp.trim() : void 0;
18238
- const [path, query] = url.split("?");
18249
+ const [path2, query] = url.split("?");
18239
18250
  if (!app) {
18240
- const m = /^\/v1\/(?:app-config|action-handlers)\/([^/?]+)/.exec(path);
18251
+ const m = /^\/v1\/(?:app-config|action-handlers)\/([^/?]+)/.exec(path2);
18241
18252
  if (m) app = decodeURIComponent(m[1]);
18242
18253
  }
18243
18254
  if (!app && query) {
@@ -18249,9 +18260,9 @@ function targetTenant(url, headers2, hostApp) {
18249
18260
  return app;
18250
18261
  }
18251
18262
  function shouldServeFromPlane(url, headers2, hostApp) {
18252
- const path = url.split("?")[0];
18253
- if (path === "/v1/apps" || path === "/v1/templates") return true;
18254
- if (!path.startsWith("/v1/")) return false;
18263
+ const path2 = url.split("?")[0];
18264
+ if (path2 === "/v1/apps" || path2 === "/v1/templates") return true;
18265
+ if (!path2.startsWith("/v1/")) return false;
18255
18266
  return targetTenant(url, headers2, hostApp) !== null;
18256
18267
  }
18257
18268
  async function proxyToServe(base, req, res) {
@@ -18511,8 +18522,8 @@ var init_FakeServiceProvider = __esm({
18511
18522
  constructor(services) {
18512
18523
  this.services = services;
18513
18524
  }
18514
- value(path) {
18515
- const raw = path.startsWith("$service:") ? path.slice("$service:".length) : path;
18525
+ value(path2) {
18526
+ const raw = path2.startsWith("$service:") ? path2.slice("$service:".length) : path2;
18516
18527
  const dot = raw.indexOf(".");
18517
18528
  const name = dot < 0 ? raw : raw.slice(0, dot);
18518
18529
  const tail = dot < 0 ? "" : raw.slice(dot + 1);
@@ -18524,8 +18535,8 @@ var init_FakeServiceProvider = __esm({
18524
18535
  }
18525
18536
  return cur;
18526
18537
  }
18527
- subscribe(path, cb) {
18528
- cb(this.value(path));
18538
+ subscribe(path2, cb) {
18539
+ cb(this.value(path2));
18529
18540
  return () => {
18530
18541
  };
18531
18542
  }
@@ -19025,21 +19036,21 @@ function useResolvedScalar(v, ctx) {
19025
19036
  return bound ?? void 0;
19026
19037
  }
19027
19038
  function useBoundValue(ctx, binding2) {
19028
- const path = servicePath(binding2);
19039
+ const path2 = servicePath(binding2);
19029
19040
  const active = !!ctx.provider && !!binding2;
19030
19041
  const [state, setState] = useState(() => ({
19031
- path,
19032
- v: active ? ctx.provider.value(path) : void 0
19042
+ path: path2,
19043
+ v: active ? ctx.provider.value(path2) : void 0
19033
19044
  }));
19034
- const current = state.path === path ? state.v : active ? ctx.provider.value(path) : void 0;
19035
- if (state.path !== path) setState({ path, v: current });
19045
+ const current = state.path === path2 ? state.v : active ? ctx.provider.value(path2) : void 0;
19046
+ if (state.path !== path2) setState({ path: path2, v: current });
19036
19047
  useEffect(() => {
19037
19048
  if (!ctx.provider || !binding2) return;
19038
19049
  return ctx.provider.subscribe(
19039
- path,
19040
- (nv) => setState((prev) => prev.path === path && Object.is(prev.v, nv) ? prev : { path, v: nv })
19050
+ path2,
19051
+ (nv) => setState((prev) => prev.path === path2 && Object.is(prev.v, nv) ? prev : { path: path2, v: nv })
19041
19052
  );
19042
- }, [ctx.provider, path, binding2]);
19053
+ }, [ctx.provider, path2, binding2]);
19043
19054
  return active ? current : void 0;
19044
19055
  }
19045
19056
  function useBoundValues(ctx, bindings) {
@@ -19050,16 +19061,16 @@ function useBoundValues(ctx, bindings) {
19050
19061
  [key2]
19051
19062
  );
19052
19063
  const [values, setValues] = useState(
19053
- () => paths.map((path) => ctx.provider && path ? ctx.provider.value(path) : void 0)
19064
+ () => paths.map((path2) => ctx.provider && path2 ? ctx.provider.value(path2) : void 0)
19054
19065
  );
19055
19066
  useEffect(() => {
19056
19067
  if (!ctx.provider) {
19057
19068
  setValues(paths.map(() => void 0));
19058
19069
  return;
19059
19070
  }
19060
- setValues(paths.map((path) => path ? ctx.provider.value(path) : void 0));
19071
+ setValues(paths.map((path2) => path2 ? ctx.provider.value(path2) : void 0));
19061
19072
  const disposers = paths.map(
19062
- (path, i) => path ? ctx.provider.subscribe(path, (v) => setValues((prev) => {
19073
+ (path2, i) => path2 ? ctx.provider.subscribe(path2, (v) => setValues((prev) => {
19063
19074
  const next = prev.slice();
19064
19075
  next[i] = v;
19065
19076
  return next;
@@ -19450,7 +19461,6 @@ function shouldRevealError(args) {
19450
19461
  var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
19451
19462
  var init_validation = __esm({
19452
19463
  "../../core/ts/src/validation.ts"() {
19453
- "use strict";
19454
19464
  EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
19455
19465
  URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
19456
19466
  INTEGER_RE = /^[+-]?[0-9]+$/;
@@ -22623,9 +22633,9 @@ var init_worker_subtree_safe_types_generated = __esm({
22623
22633
  function isRecord(value) {
22624
22634
  return typeof value === "object" && value !== null && !Array.isArray(value);
22625
22635
  }
22626
- function valueAtPath(value, path) {
22636
+ function valueAtPath(value, path2) {
22627
22637
  let current = value;
22628
- for (const segment of path.split(".")) {
22638
+ for (const segment of path2.split(".")) {
22629
22639
  if (!isRecord(current)) return void 0;
22630
22640
  current = current[segment];
22631
22641
  }
@@ -22839,8 +22849,8 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
22839
22849
  return;
22840
22850
  }
22841
22851
  const props = node.body.props;
22842
- for (const path of rule.actions) checkAction(valueAtPath(props, path));
22843
- for (const path of WORKER_SUBTREE_COMMON_ACTION_PATHS) checkAction(valueAtPath(node, path));
22852
+ for (const path2 of rule.actions) checkAction(valueAtPath(props, path2));
22853
+ for (const path2 of WORKER_SUBTREE_COMMON_ACTION_PATHS) checkAction(valueAtPath(node, path2));
22844
22854
  for (const childRule of rule.children) {
22845
22855
  const value = valueAtPath(props, childRule.path);
22846
22856
  if (value === void 0 || value === null) {
@@ -22875,7 +22885,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
22875
22885
  var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
22876
22886
  var init_worker_subtree = __esm({
22877
22887
  "../../core/ts/src/worker-subtree.ts"() {
22878
- "use strict";
22879
22888
  init_worker_subtree_safe_types_generated();
22880
22889
  WORKER_SUBTREE_CEILINGS = Object.freeze({
22881
22890
  maxEncodedBytes: 65536,
@@ -22893,9 +22902,9 @@ var init_worker_subtree = __esm({
22893
22902
  // ../../core/web-renderer/src/renderNode.tsx
22894
22903
  import React5 from "react";
22895
22904
  import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
22896
- function boundTokenName(path, fallback, ctx) {
22897
- if (typeof path === "string" && path) {
22898
- const r = resolveScalarStatic(path, ctx);
22905
+ function boundTokenName(path2, fallback, ctx) {
22906
+ if (typeof path2 === "string" && path2) {
22907
+ const r = resolveScalarStatic(path2, ctx);
22899
22908
  if (typeof r === "string" && r) return r;
22900
22909
  }
22901
22910
  return fallback;
@@ -24201,8 +24210,8 @@ function renderNodeInner(node, ctx) {
24201
24210
  }
24202
24211
  }
24203
24212
  const bind = {};
24204
- const addBind = (cssProp, path) => {
24205
- const k = measureKey(path);
24213
+ const addBind = (cssProp, path2) => {
24214
+ const k = measureKey(path2);
24206
24215
  if (k) bind[cssProp] = k;
24207
24216
  };
24208
24217
  addBind("height", m?.heightPath ?? m?.height_path);
@@ -24293,9 +24302,9 @@ function renderNodeInner(node, ctx) {
24293
24302
  }
24294
24303
  return out;
24295
24304
  }
24296
- function boundModNumber(path, ctx) {
24297
- if (typeof path !== "string" || !path || measureKey(path) != null || !isBinding(path)) return void 0;
24298
- const r = resolveScalarStatic(path, ctx);
24305
+ function boundModNumber(path2, ctx) {
24306
+ if (typeof path2 !== "string" || !path2 || measureKey(path2) != null || !isBinding(path2)) return void 0;
24307
+ const r = resolveScalarStatic(path2, ctx);
24299
24308
  const n = typeof r === "number" ? r : typeof r === "string" && r.trim() !== "" ? Number(r) : NaN;
24300
24309
  return Number.isFinite(n) ? n : void 0;
24301
24310
  }
@@ -25242,8 +25251,8 @@ var init_renderNode = __esm({
25242
25251
  WorkerSubtreeNode = withExtras("WorkerSubtreeNode", ({ props, ctx, wrap, nodeId }) => {
25243
25252
  const slotId = nodeId;
25244
25253
  const extra = wrap;
25245
- const path = props.treeJsonPath ?? props.tree_json_path;
25246
- const value = useBoundValue(ctx, typeof path === "string" ? path : "");
25254
+ const path2 = props.treeJsonPath ?? props.tree_json_path;
25255
+ const value = useBoundValue(ctx, typeof path2 === "string" ? path2 : "");
25247
25256
  const policy = props.policy;
25248
25257
  const catalog = ctx.provider && typeof ctx.provider.listActions === "function" ? ctx.provider : null;
25249
25258
  const validation = React5.useMemo(() => {
@@ -25672,8 +25681,8 @@ var init_renderNode = __esm({
25672
25681
  this.state = state;
25673
25682
  for (const cb of this.listeners) cb(this.value("media"));
25674
25683
  }
25675
- value(path) {
25676
- const bare = path.replace(/^\$service:/, "");
25684
+ value(path2) {
25685
+ const bare = path2.replace(/^\$service:/, "");
25677
25686
  const parts = bare.split(".").filter(Boolean);
25678
25687
  if (parts[0] === "media") parts.shift();
25679
25688
  let value = this.state;
@@ -25683,8 +25692,8 @@ var init_renderNode = __esm({
25683
25692
  }
25684
25693
  return value;
25685
25694
  }
25686
- subscribe(path, cb) {
25687
- const wrapped = () => cb(this.value(path));
25695
+ subscribe(path2, cb) {
25696
+ const wrapped = () => cb(this.value(path2));
25688
25697
  this.listeners.add(wrapped);
25689
25698
  wrapped();
25690
25699
  return () => this.listeners.delete(wrapped);
@@ -26935,9 +26944,9 @@ var init_renderNode = __esm({
26935
26944
  });
26936
26945
  AvatarStripNode = withExtras("AvatarStripNode", ({ props, ctx, wrap }) => {
26937
26946
  const C = ctx.color;
26938
- const path = props.avatarsPath ?? props.avatars_path;
26939
- const bound = useResolvedScalar(path, ctx);
26940
- const raw = path != null ? bound : props.avatars;
26947
+ const path2 = props.avatarsPath ?? props.avatars_path;
26948
+ const bound = useResolvedScalar(path2, ctx);
26949
+ const raw = path2 != null ? bound : props.avatars;
26941
26950
  const avatars = Array.isArray(raw) ? raw : [];
26942
26951
  const size = props.size ?? 36;
26943
26952
  const maxVisible = props.maxVisible ?? 4;
@@ -28568,27 +28577,27 @@ function resolveTreeScalar(v, provider, itemScope) {
28568
28577
  if (v.startsWith("$service:")) return provider.value(v) ?? void 0;
28569
28578
  return v;
28570
28579
  }
28571
- function collectResolvedMediaRecord(record2, path, context) {
28572
- if (typeof record2.actionId === "string" || path && typeof record2.body === "object") return;
28580
+ function collectResolvedMediaRecord(record2, path2, context) {
28581
+ if (typeof record2.actionId === "string" || path2 && typeof record2.body === "object") return;
28573
28582
  for (const [key2, child] of Object.entries(record2)) {
28574
- collectResolvedMediaValues(child, path ? `${path}.${key2}` : key2, {
28583
+ collectResolvedMediaValues(child, path2 ? `${path2}.${key2}` : key2, {
28575
28584
  ...context,
28576
28585
  insideMediaProperty: context.insideMediaProperty || isMediaValueProperty(key2)
28577
28586
  });
28578
28587
  }
28579
28588
  }
28580
- function collectResolvedMediaValues(value, path, context) {
28589
+ function collectResolvedMediaValues(value, path2, context) {
28581
28590
  const resolved2 = typeof value === "string" ? resolveTreeScalar(value, context.provider, context.itemScope) : value;
28582
28591
  if (typeof resolved2 === "string") {
28583
- if (context.insideMediaProperty) context.values[path] = resolved2;
28592
+ if (context.insideMediaProperty) context.values[path2] = resolved2;
28584
28593
  return;
28585
28594
  }
28586
28595
  if (Array.isArray(resolved2)) {
28587
- resolved2.forEach((item, index) => collectResolvedMediaValues(item, `${path}[${index}]`, context));
28596
+ resolved2.forEach((item, index) => collectResolvedMediaValues(item, `${path2}[${index}]`, context));
28588
28597
  return;
28589
28598
  }
28590
28599
  if (resolved2 && typeof resolved2 === "object") {
28591
- collectResolvedMediaRecord(resolved2, path, context);
28600
+ collectResolvedMediaRecord(resolved2, path2, context);
28592
28601
  }
28593
28602
  }
28594
28603
  function collectComponentMediaValues(type, props, context) {
@@ -28609,12 +28618,12 @@ function collectNativeOnly(node) {
28609
28618
  walk2(node);
28610
28619
  return [...found].sort();
28611
28620
  }
28612
- function buildRenderTree(node, path = "$", provider = null, itemScope = void 0, includeRawProps = false, env = null) {
28621
+ function buildRenderTree(node, path2 = "$", provider = null, itemScope = void 0, includeRawProps = false, env = null) {
28613
28622
  if (!node || typeof node !== "object") return null;
28614
28623
  const obj2 = node;
28615
28624
  const body = obj2.body ?? {};
28616
28625
  const type = typeof body.type === "string" ? body.type : "Unknown";
28617
- const id = typeof obj2.id === "string" && obj2.id ? obj2.id : path;
28626
+ const id = typeof obj2.id === "string" && obj2.id ? obj2.id : path2;
28618
28627
  const out = { id, type };
28619
28628
  if (typeof body.package === "string") out.package = body.package;
28620
28629
  const props = body.props ?? {};
@@ -28723,7 +28732,7 @@ async function renderDescriptorWeb(descriptor, tokens, scheme, wantPng, services
28723
28732
  const stickyHeader = isSduiNode(desc.stickyHeader) ? desc.stickyHeader : void 0;
28724
28733
  const stickyFooter = isSduiNode(desc.stickyFooter) ? desc.stickyFooter : void 0;
28725
28734
  const clientEnv = clientEnvFor(scheme, width, isRTL);
28726
- const treeOf = (node, path, prov) => buildRenderTree(node, path, prov, void 0, true, clientEnv);
28735
+ const treeOf = (node, path2, prov) => buildRenderTree(node, path2, prov, void 0, true, clientEnv);
28727
28736
  const renderTree = composeStickyTree(
28728
28737
  treeOf(payload, "$", null) ?? void 0,
28729
28738
  stickyHeader ? treeOf(stickyHeader, "$.stickyHeader", null) : null,
@@ -28923,8 +28932,8 @@ function declaredFamilies(tokens) {
28923
28932
  async function faceBytes(face, catalog, opts) {
28924
28933
  try {
28925
28934
  if (opts.source) {
28926
- const path = opts.source(face.file, face.sha256);
28927
- return path ? readFileSync34(path) : null;
28935
+ const path2 = opts.source(face.file, face.sha256);
28936
+ return path2 ? readFileSync34(path2) : null;
28928
28937
  }
28929
28938
  const bytes2 = await catalogFaceBytes(face.sha256, { catalog, ...opts.fetchFace ? { fetchFace: opts.fetchFace } : {} });
28930
28939
  return bytes2 ?? null;
@@ -29431,13 +29440,13 @@ function validateName(name) {
29431
29440
  if (typeof name !== "string") fail("name must be a string");
29432
29441
  if (!/^[a-z][a-z0-9]*(?:[-_.][a-z0-9]+)*$/.test(name)) fail(`name must be lowercase kebab-case: "${name}"`);
29433
29442
  }
29434
- function validateFunctionRoute(method, path) {
29443
+ function validateFunctionRoute(method, path2) {
29435
29444
  if (!HTTP_METHODS.includes(method)) fail(`method must be one of ${HTTP_METHODS.join(", ")}`);
29436
- if (path !== "/" && (!/^\/[A-Za-z0-9._~!$&'()*+,;=:@%/-]+$/.test(path) || path.includes("//") || path.endsWith("/"))) {
29437
- fail(`path must be an absolute, normalized route without query syntax: "${path}"`);
29445
+ if (path2 !== "/" && (!/^\/[A-Za-z0-9._~!$&'()*+,;=:@%/-]+$/.test(path2) || path2.includes("//") || path2.endsWith("/"))) {
29446
+ fail(`path must be an absolute, normalized route without query syntax: "${path2}"`);
29438
29447
  }
29439
- const params = [...path.matchAll(/:([A-Za-z][A-Za-z0-9_]*)/g)].map((match) => match[1]);
29440
- if (new Set(params).size !== params.length) fail(`path contains duplicate parameter names: "${path}"`);
29448
+ const params = [...path2.matchAll(/:([A-Za-z][A-Za-z0-9_]*)/g)].map((match) => match[1]);
29449
+ if (new Set(params).size !== params.length) fail(`path contains duplicate parameter names: "${path2}"`);
29441
29450
  }
29442
29451
  function validateFunctionDefinition(definition) {
29443
29452
  validateName(definition.name);
@@ -30846,9 +30855,9 @@ function nativeSourceFiles(directory, extension, buildDirMaxDepth, depth = 1) {
30846
30855
  return entries.flatMap((entry) => {
30847
30856
  if (NATIVE_SCRATCH_DIRS.has(entry.name)) return [];
30848
30857
  if (entry.name === BUILD_OUTPUT_DIR && depth <= buildDirMaxDepth) return [];
30849
- const path = resolve28(directory, entry.name);
30850
- if (entry.isDirectory()) return nativeSourceFiles(path, extension, buildDirMaxDepth, depth + 1);
30851
- return entry.name.endsWith(extension) ? [path] : [];
30858
+ const path2 = resolve28(directory, entry.name);
30859
+ if (entry.isDirectory()) return nativeSourceFiles(path2, extension, buildDirMaxDepth, depth + 1);
30860
+ return entry.name.endsWith(extension) ? [path2] : [];
30852
30861
  });
30853
30862
  }
30854
30863
  function registeredActions(source) {
@@ -31111,10 +31120,10 @@ function readJsonAt(app, file, root) {
31111
31120
  }
31112
31121
  }
31113
31122
  function writeJsonAt(app, file, root, value) {
31114
- const path = appConfigPath(app, file, root);
31115
- mkdirSync15(dirname20(path), { recursive: true });
31116
- writeFileSync12(path, JSON.stringify(value, null, 2) + "\n");
31117
- return path;
31123
+ const path2 = appConfigPath(app, file, root);
31124
+ mkdirSync15(dirname20(path2), { recursive: true });
31125
+ writeFileSync12(path2, JSON.stringify(value, null, 2) + "\n");
31126
+ return path2;
31118
31127
  }
31119
31128
  function sanitizeOverlay(raw) {
31120
31129
  if (!("appIconBadgeSources" in raw)) return raw;
@@ -31350,8 +31359,8 @@ function handleL10nRequest(req, res, state) {
31350
31359
  if (!state.app || app !== state.app.name) {
31351
31360
  return sendJson(res, 404, { error: "unknown_app", app }, cors);
31352
31361
  }
31353
- const path = resolve30(state.app.dir, "l10n", `${tag}.json`);
31354
- if (!existsSync36(path)) {
31362
+ const path2 = resolve30(state.app.dir, "l10n", `${tag}.json`);
31363
+ if (!existsSync36(path2)) {
31355
31364
  res.writeHead(204, cors);
31356
31365
  res.end();
31357
31366
  return;
@@ -31360,7 +31369,7 @@ function handleL10nRequest(req, res, state) {
31360
31369
  let messages;
31361
31370
  try {
31362
31371
  messages = Object.fromEntries(
31363
- keyMap(parseCatalog(readFileSync39(path, "utf8")), { sourceFallback: tag === sourceLocale })
31372
+ keyMap(parseCatalog(readFileSync39(path2, "utf8")), { sourceFallback: tag === sourceLocale })
31364
31373
  );
31365
31374
  } catch {
31366
31375
  return sendJson(res, 500, { error: "catalog_unreadable", app, tag }, cors);
@@ -31590,16 +31599,16 @@ async function handleOwnerSitesRequest(req, res) {
31590
31599
  async function handleOwnerChatRequest(req, res) {
31591
31600
  const cors = { "access-control-allow-origin": "*" };
31592
31601
  const u = new URL(req.url ?? "", "http://localhost");
31593
- const path = u.pathname;
31602
+ const path2 = u.pathname;
31594
31603
  const { resolveMetaSiteId, listChatroomsLive, sendChatMessageLive } = await import("./apps/wix-owner-clone-live.js");
31595
- if (path === "/v1/owner-chat/chatrooms" && req.method === "GET") {
31604
+ if (path2 === "/v1/owner-chat/chatrooms" && req.method === "GET") {
31596
31605
  const metaSiteId = u.searchParams.get("metaSiteId") || await resolveMetaSiteId();
31597
31606
  if (!metaSiteId) return sendJson(res, 400, { error: "no_meta_site" }, cors);
31598
31607
  const rooms = await listChatroomsLive(metaSiteId);
31599
31608
  if (rooms == null) return sendJson(res, 502, { error: "chatrooms_unavailable" }, cors);
31600
31609
  return sendJson(res, 200, { chatrooms: rooms }, cors);
31601
31610
  }
31602
- if (path === "/v1/owner-chat/send" && req.method === "POST") {
31611
+ if (path2 === "/v1/owner-chat/send" && req.method === "POST") {
31603
31612
  let parsed;
31604
31613
  try {
31605
31614
  parsed = JSON.parse(await readBody2(req) || "{}");
@@ -32318,7 +32327,7 @@ function webWixSession(req, res, state) {
32318
32327
  async function handleWebWix(req, res, state) {
32319
32328
  const session = webWixSession(req, res, state);
32320
32329
  const auth = resolveWebWixAuth(state.app);
32321
- const path = new URL(req.url ?? "", "http://localhost").pathname;
32330
+ const path2 = new URL(req.url ?? "", "http://localhost").pathname;
32322
32331
  const readJson3 = async () => {
32323
32332
  const chunks = [];
32324
32333
  for await (const c of req) chunks.push(c);
@@ -32335,7 +32344,7 @@ async function handleWebWix(req, res, state) {
32335
32344
  res.setHeader("access-control-allow-origin", "*");
32336
32345
  res.end(JSON.stringify(obj2));
32337
32346
  };
32338
- if (path === "/v1/__webwix/login" && req.method === "POST") {
32347
+ if (path2 === "/v1/__webwix/login" && req.method === "POST") {
32339
32348
  const b = await readJson3();
32340
32349
  try {
32341
32350
  const { memberToken, visitorToken } = await memberDirectLogin(
@@ -32352,7 +32361,7 @@ async function handleWebWix(req, res, state) {
32352
32361
  return reply(200, { ok: false, error: String(e?.message ?? e) });
32353
32362
  }
32354
32363
  }
32355
- if (path === "/v1/__webwix/call" && req.method === "POST") {
32364
+ if (path2 === "/v1/__webwix/call" && req.method === "POST") {
32356
32365
  const b = await readJson3();
32357
32366
  if (b.ownerMsid !== void 0 || b.checkOwnerSession === true) {
32358
32367
  const msid = String(b.ownerMsid ?? "");
@@ -32439,12 +32448,12 @@ async function handleWebWix(req, res, state) {
32439
32448
  return reply(200, { status: 0, body: JSON.stringify({ error: String(e?.message ?? e) }) });
32440
32449
  }
32441
32450
  }
32442
- if (path === "/v1/__webwix/logout" && req.method === "POST") {
32451
+ if (path2 === "/v1/__webwix/logout" && req.method === "POST") {
32443
32452
  session.memberToken = void 0;
32444
32453
  session.email = void 0;
32445
32454
  return reply(200, { ok: true });
32446
32455
  }
32447
- if (path === "/v1/__webwix/identity" && (req.method === "GET" || req.method === "POST")) {
32456
+ if (path2 === "/v1/__webwix/identity" && (req.method === "GET" || req.method === "POST")) {
32448
32457
  if (!session.memberToken) return reply(200, { authenticated: false, userId: null, email: "" });
32449
32458
  let userId = null;
32450
32459
  try {
@@ -32468,7 +32477,7 @@ async function handleWebWix(req, res, state) {
32468
32477
  } : null
32469
32478
  });
32470
32479
  }
32471
- if (path === "/v1/__webwix/register" && req.method === "POST") {
32480
+ if (path2 === "/v1/__webwix/register" && req.method === "POST") {
32472
32481
  const b = await readJson3();
32473
32482
  try {
32474
32483
  const { memberToken, visitorToken } = await memberDirectRegister(
@@ -32885,8 +32894,8 @@ async function handleDev(req, res, state) {
32885
32894
  }
32886
32895
  async function handleAdminPlayground(req, res, state) {
32887
32896
  const url = req.url ?? "";
32888
- const path = url.split("?")[0];
32889
- const sampleMatch = /^\/v1\/admin\/sdui-samples\/([^/]+)$/.exec(path);
32897
+ const path2 = url.split("?")[0];
32898
+ const sampleMatch = /^\/v1\/admin\/sdui-samples\/([^/]+)$/.exec(path2);
32890
32899
  if (sampleMatch && req.method === "GET") {
32891
32900
  const name = decodeURIComponent(sampleMatch[1]);
32892
32901
  if (!/^[a-zA-Z0-9._-]+$/.test(name)) return sendJson(res, 400, { error: "bad_name" });
@@ -32897,7 +32906,7 @@ async function handleAdminPlayground(req, res, state) {
32897
32906
  return sendJson(res, 404, { error: "sample_not_found", name });
32898
32907
  }
32899
32908
  }
32900
- if (path === "/v1/admin/sdui-samples" && req.method === "GET") {
32909
+ if (path2 === "/v1/admin/sdui-samples" && req.method === "GET") {
32901
32910
  try {
32902
32911
  const { readdir } = await import("node:fs/promises");
32903
32912
  const files = (await readdir(SAMPLES_ROOT)).filter((f) => f.endsWith(".json"));
@@ -32906,7 +32915,7 @@ async function handleAdminPlayground(req, res, state) {
32906
32915
  return sendJson(res, 500, { error: err.message });
32907
32916
  }
32908
32917
  }
32909
- if (path === "/v1/admin/screens" && req.method === "GET") {
32918
+ if (path2 === "/v1/admin/screens" && req.method === "GET") {
32910
32919
  const meta = state.app.meta;
32911
32920
  const fixedIds = meta.screenIds;
32912
32921
  const fixedSet = new Set(fixedIds);
@@ -32955,12 +32964,12 @@ async function handleAdminPlayground(req, res, state) {
32955
32964
  templatedPatterns: meta.templatedPatterns
32956
32965
  });
32957
32966
  }
32958
- const historyMatch = /^\/v1\/admin\/screens\/(.+?)\/history(?:\?|$)/.exec(path);
32967
+ const historyMatch = /^\/v1\/admin\/screens\/(.+?)\/history(?:\?|$)/.exec(path2);
32959
32968
  if (historyMatch && req.method === "GET") {
32960
32969
  const screenId = decodeURIComponent(historyMatch[1]);
32961
32970
  return sendJson(res, 200, { screenId, history: state.localOverrideHistory.get(screenId) ?? [] });
32962
32971
  }
32963
- const revertMatch = /^\/v1\/admin\/screens\/(.+?)\/revert(?:\?|$)/.exec(path);
32972
+ const revertMatch = /^\/v1\/admin\/screens\/(.+?)\/revert(?:\?|$)/.exec(path2);
32964
32973
  if (revertMatch && req.method === "POST") {
32965
32974
  const screenId = decodeURIComponent(revertMatch[1]);
32966
32975
  const historyId = Number(new URLSearchParams(url.split("?")[1] ?? "").get("historyId"));
@@ -32976,7 +32985,7 @@ async function handleAdminPlayground(req, res, state) {
32976
32985
  invalidate(state, screenId);
32977
32986
  return sendJson(res, 200, { status: "ok", screenId, revertedTo: historyId });
32978
32987
  }
32979
- if (path === "/v1/admin/tab-badge" && req.method === "POST") {
32988
+ if (path2 === "/v1/admin/tab-badge" && req.method === "POST") {
32980
32989
  let body;
32981
32990
  try {
32982
32991
  body = JSON.parse(await readBody2(req));
@@ -32995,7 +33004,7 @@ async function handleAdminPlayground(req, res, state) {
32995
33004
  );
32996
33005
  return sendJson(res, 200, { status: "ok", tabId: body.tabId, count: clearing ? null : body.count });
32997
33006
  }
32998
- const validateMatch = /^\/v1\/admin\/screens\/(.+?)\/validate(?:\?|$)/.exec(path);
33007
+ const validateMatch = /^\/v1\/admin\/screens\/(.+?)\/validate(?:\?|$)/.exec(path2);
32999
33008
  if (validateMatch && req.method === "GET") {
33000
33009
  const screenId = decodeURIComponent(validateMatch[1]);
33001
33010
  const strict = /[?&]strict=1(?:&|$)/.test(url);
@@ -33023,7 +33032,7 @@ async function handleAdminPlayground(req, res, state) {
33023
33032
  });
33024
33033
  return sendJson(res, report2.ok ? 200 : 422, report2);
33025
33034
  }
33026
- const detailMatch = /^\/v1\/admin\/screens\/([^/]+)$/.exec(path);
33035
+ const detailMatch = /^\/v1\/admin\/screens\/([^/]+)$/.exec(path2);
33027
33036
  if (detailMatch && req.method === "GET") {
33028
33037
  const screenId = decodeURIComponent(detailMatch[1]);
33029
33038
  const wantBuilt = /[?&]source=built(?:&|$)/.test(url);
@@ -33060,7 +33069,7 @@ async function handleAdminPlayground(req, res, state) {
33060
33069
  invalidate(state, screenId);
33061
33070
  return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
33062
33071
  }
33063
- if (path === "/v1/admin/app-config" && state.app) {
33072
+ if (path2 === "/v1/admin/app-config" && state.app) {
33064
33073
  const built = deriveNavigationConfig(state.app.meta);
33065
33074
  if (req.method === "GET") {
33066
33075
  const effective = state.appConfigOverride ? deepMerge3(built, state.appConfigOverride) : built;
@@ -33085,7 +33094,7 @@ async function handleAdminPlayground(req, res, state) {
33085
33094
  return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
33086
33095
  }
33087
33096
  }
33088
- if (path === "/v1/admin/tokens" && state.app) {
33097
+ if (path2 === "/v1/admin/tokens" && state.app) {
33089
33098
  const built = readAppTokens(state) ?? {};
33090
33099
  if (req.method === "GET") {
33091
33100
  const effective = state.tokensOverride ? deepMerge3(built, state.tokensOverride) : built;
@@ -33110,7 +33119,7 @@ async function handleAdminPlayground(req, res, state) {
33110
33119
  return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
33111
33120
  }
33112
33121
  }
33113
- return sendJson(res, 404, { error: "unknown_admin_route", path });
33122
+ return sendJson(res, 404, { error: "unknown_admin_route", path: path2 });
33114
33123
  }
33115
33124
  function isNavControlPatch(patch) {
33116
33125
  if (!patch || typeof patch !== "object") return false;
@@ -33165,10 +33174,10 @@ async function readBundleFile(name, dir) {
33165
33174
  resolve30(root, `${name}.js`),
33166
33175
  resolve30(root, name)
33167
33176
  ]);
33168
- for (const path of candidates) {
33169
- if (!roots.some((root) => path.startsWith(root))) continue;
33177
+ for (const path2 of candidates) {
33178
+ if (!roots.some((root) => path2.startsWith(root))) continue;
33170
33179
  try {
33171
- const bytes2 = await readFile(path);
33180
+ const bytes2 = await readFile(path2);
33172
33181
  const integrity2 = "sha256-" + createHash15("sha256").update(bytes2).digest("base64");
33173
33182
  return { bytes: bytes2, integrity: integrity2 };
33174
33183
  } catch {
@@ -33348,10 +33357,10 @@ function handleActionHandlersManifest(res, app) {
33348
33357
  }
33349
33358
  async function handleActionHandlerBundleGet(res, app) {
33350
33359
  if (!/^[A-Za-z0-9_.\-]+$/.test(app)) return sendJson(res, 404, { error: "not_found" });
33351
- const path = resolve30(ACTION_HANDLERS_ROOT, `${app}.handlers.js`);
33352
- if (!path.startsWith(ACTION_HANDLERS_ROOT)) return sendJson(res, 404, { error: "not_found" });
33360
+ const path2 = resolve30(ACTION_HANDLERS_ROOT, `${app}.handlers.js`);
33361
+ if (!path2.startsWith(ACTION_HANDLERS_ROOT)) return sendJson(res, 404, { error: "not_found" });
33353
33362
  try {
33354
- const bytes2 = await readFile(path);
33363
+ const bytes2 = await readFile(path2);
33355
33364
  const integrity2 = "sha256-" + createHash15("sha256").update(bytes2).digest("base64");
33356
33365
  res.setHeader("content-type", "application/javascript; charset=utf-8");
33357
33366
  res.setHeader("cache-control", "max-age=300");
@@ -34125,13 +34134,13 @@ var init_capability_fixtures = __esm({
34125
34134
  };
34126
34135
  MEDIA_EXT = (url) => {
34127
34136
  if (typeof url !== "string") return null;
34128
- let path;
34137
+ let path2;
34129
34138
  try {
34130
- path = new URL(url).pathname;
34139
+ path2 = new URL(url).pathname;
34131
34140
  } catch {
34132
- path = url.split("#")[0].split("?")[0];
34141
+ path2 = url.split("#")[0].split("?")[0];
34133
34142
  }
34134
- const segment = path.split("/").pop() ?? "";
34143
+ const segment = path2.split("/").pop() ?? "";
34135
34144
  const m = /\.([a-z0-9]{2,5})$/i.exec(segment);
34136
34145
  return m ? m[1].toLowerCase() : null;
34137
34146
  };
@@ -34292,9 +34301,9 @@ var init_capability_fixtures = __esm({
34292
34301
  // made every write resolve to the same file, and a consumer passing that handle onward (an export
34293
34302
  // writing `exports/<id>.gpx`) referenced something that does not exist.
34294
34303
  "capability.files.write": (p, ctx) => {
34295
- const path = typeof p.path === "string" && p.path ? p.path : "crawl/written.txt";
34296
- const name = path.split("/").pop() || path;
34297
- return { uri: `file:///${path.replace(/^\/+/, "")}`, name, mimeType: typeof p.mimeType === "string" ? p.mimeType : "application/octet-stream", sizeBytes: 1024, modifiedAt: ctx.clock };
34304
+ const path2 = typeof p.path === "string" && p.path ? p.path : "crawl/written.txt";
34305
+ const name = path2.split("/").pop() || path2;
34306
+ return { uri: `file:///${path2.replace(/^\/+/, "")}`, name, mimeType: typeof p.mimeType === "string" ? p.mimeType : "application/octet-stream", sizeBytes: 1024, modifiedAt: ctx.clock };
34298
34307
  },
34299
34308
  "capability.files.remove": () => ({ removed: true })
34300
34309
  };
@@ -34581,14 +34590,14 @@ function relationalSignature(state) {
34581
34590
  }
34582
34591
  function listLengths(state, depth = 4) {
34583
34592
  const out = {};
34584
- const walk2 = (node, path, left) => {
34593
+ const walk2 = (node, path2, left) => {
34585
34594
  if (left < 0 || node === null || typeof node !== "object") return;
34586
34595
  if (Array.isArray(node)) {
34587
- out[path] = node.length;
34596
+ out[path2] = node.length;
34588
34597
  return;
34589
34598
  }
34590
34599
  for (const [k, v] of Object.entries(node)) {
34591
- walk2(v, path ? `${path}.${k}` : k, left - 1);
34600
+ walk2(v, path2 ? `${path2}.${k}` : k, left - 1);
34592
34601
  }
34593
34602
  };
34594
34603
  walk2(state, "", depth);
@@ -34609,26 +34618,26 @@ function summarizeDiff(aSig, bSig, limit = 3) {
34609
34618
  if (t === void 0) return "undefined";
34610
34619
  return t.length > 80 ? `${t.slice(0, 77)}\u2026` : t;
34611
34620
  };
34612
- const walk2 = (x, y, path) => {
34621
+ const walk2 = (x, y, path2) => {
34613
34622
  if (diffs.length >= limit) return;
34614
34623
  const bothObjects = x !== null && y !== null && typeof x === "object" && typeof y === "object" && !Array.isArray(x) && !Array.isArray(y);
34615
34624
  if (bothObjects) {
34616
34625
  for (const k of /* @__PURE__ */ new Set([...Object.keys(x), ...Object.keys(y)])) {
34617
- walk2(x[k], y[k], path ? `${path}.${k}` : k);
34626
+ walk2(x[k], y[k], path2 ? `${path2}.${k}` : k);
34618
34627
  }
34619
34628
  return;
34620
34629
  }
34621
34630
  if (Array.isArray(x) && Array.isArray(y)) {
34622
34631
  if (x.length !== y.length) {
34623
- diffs.push(`${path || "state"}: ${x.length} \u2192 ${y.length} items`);
34632
+ diffs.push(`${path2 || "state"}: ${x.length} \u2192 ${y.length} items`);
34624
34633
  return;
34625
34634
  }
34626
- for (let i = 0; i < x.length && diffs.length < limit; i++) walk2(x[i], y[i], `${path}[${i}]`);
34635
+ for (let i = 0; i < x.length && diffs.length < limit; i++) walk2(x[i], y[i], `${path2}[${i}]`);
34627
34636
  return;
34628
34637
  }
34629
34638
  const xs = brief(x);
34630
34639
  const ys = brief(y);
34631
- if (xs !== ys) diffs.push(`${path || "state"}: ${xs} \u2192 ${ys}`);
34640
+ if (xs !== ys) diffs.push(`${path2 || "state"}: ${xs} \u2192 ${ys}`);
34632
34641
  };
34633
34642
  walk2(a, b, "");
34634
34643
  return diffs.slice(0, limit).join("; ");
@@ -34717,6 +34726,7 @@ function actionSites(payload) {
34717
34726
  actionId: a.actionId,
34718
34727
  params: a.params ?? {},
34719
34728
  ...a.args ? { args: a.args } : {},
34729
+ ...a.presentation ? { presentation: a.presentation } : {},
34720
34730
  ...ambient ? { itemsPath: ambient } : {},
34721
34731
  // `rec` IS the prop bag that carries this callback — for a plain node that is
34722
34732
  // `body.props`, and for a FormField variant the nested `text`/`picker`/… object, which
@@ -34835,8 +34845,8 @@ function sourceOfStack(stack, bundleMap) {
34835
34845
  return mapBundleFrame(bundleMap, Number(m[1]), Number(m[2]) - 1) ?? void 0;
34836
34846
  }
34837
34847
  function netTransport(rules) {
34838
- return async (method, path, body) => {
34839
- const [bare, search] = String(path).split("?", 2);
34848
+ return async (method, path2, body) => {
34849
+ const [bare, search] = String(path2).split("?", 2);
34840
34850
  const query = {};
34841
34851
  if (search) for (const [k, v] of new URLSearchParams(search)) query[k] = v;
34842
34852
  const res = resolveScenario(rules, {
@@ -34883,9 +34893,9 @@ function layeredTransport(layers) {
34883
34893
  const cms = layers.cmsSeed && Object.keys(layers.cmsSeed).length ? layers.cmsSeed : null;
34884
34894
  const canned = layers.canned && Object.keys(layers.canned).length ? layers.canned : null;
34885
34895
  const label2 = [rules && "mocked", cms && "cms", canned && "canned"].filter(Boolean).join("+") || "offline";
34886
- const call = async (method, path, body) => {
34896
+ const call = async (method, path2, body) => {
34887
34897
  const m = String(method).toUpperCase();
34888
- const p = String(path);
34898
+ const p = String(path2);
34889
34899
  const [bare, search] = p.split("?", 2);
34890
34900
  if (rules) {
34891
34901
  const query = {};
@@ -35364,9 +35374,9 @@ async function crawlScreenInner(opts) {
35364
35374
  const resolveItem = (v) => {
35365
35375
  if (typeof v !== "string" || !v.startsWith("$item")) return v;
35366
35376
  if (!row0) return v;
35367
- const path = v === "$item" ? "" : v.startsWith("$item.") ? v.slice("$item.".length) : "";
35368
- if (!path) return v;
35369
- return pathValue(row0, path);
35377
+ const path2 = v === "$item" ? "" : v.startsWith("$item.") ? v.slice("$item.".length) : "";
35378
+ if (!path2) return v;
35379
+ return pathValue(row0, path2);
35370
35380
  };
35371
35381
  const target = resolveItem(merged.screenId);
35372
35382
  if (typeof target !== "string" || !target || target.includes("$")) continue;
@@ -35466,6 +35476,23 @@ async function crawlScreenInner(opts) {
35466
35476
  actionsSkipped.push({ action: s.actionId, why: "embedded-preview" });
35467
35477
  return false;
35468
35478
  });
35479
+ if (!opts.capabilitySuccess) {
35480
+ for (const site of sites) {
35481
+ if (site.actionId !== "himi.open") continue;
35482
+ if (["back", "dismiss", "alert", "snackbar"].includes(site.presentation ?? "")) continue;
35483
+ const target = site.args?.screenId ?? site.params.screenId;
35484
+ if (target != null && target !== "") continue;
35485
+ findings.push({
35486
+ screen: screenId,
35487
+ trigger: "boot",
35488
+ invariant: "nav-target-absent",
35489
+ severity: "error",
35490
+ at: site.componentId ?? void 0,
35491
+ message: '"himi.open" has no screenId \u2014 the tap opens nothing',
35492
+ hint: 'Pass { screenId: "detail", id: "selected-id" } in params. "screen" is not a routing key; put destination input alongside screenId.'
35493
+ });
35494
+ }
35495
+ }
35469
35496
  const boot = (skipAppear = false) => bundleJs ? bootScreenWorker({ bundleJs, descriptor, wixCall, screenId, inputOverride: opts.inputOverride, budgetMs: opts.budgetMs, clock: opts.clock, seed: opts.seed, skipAppear, localDbSchema: opts.localDbSchema, capabilitySuccess: opts.capabilitySuccess === true, ...opts.evaluator ? { evaluator: opts.evaluator } : {} }) : null;
35470
35497
  const check = (trigger, state, errors, defects = {}) => {
35471
35498
  for (const [svc, paths] of Object.entries(defects)) {
@@ -35787,8 +35814,8 @@ async function crawlScreenHostileInner(opts, variant) {
35787
35814
  const base = layeredTransport({ rules: opts.rules, cmsSeed: opts.cmsSeed, canned: opts.canned });
35788
35815
  if (base.label === "offline") return [];
35789
35816
  const axis = `hostile:${variant}`;
35790
- const wixCall = variant === "empty" ? async (method, path, body) => emptiedArrays(await base.call(method, path, body)) : async (method, path) => {
35791
- throw new Error(`Wix 500 for ${String(method).toUpperCase()} ${String(path).split("?")[0]}`);
35817
+ const wixCall = variant === "empty" ? async (method, path2, body) => emptiedArrays(await base.call(method, path2, body)) : async (method, path2) => {
35818
+ throw new Error(`Wix 500 for ${String(method).toUpperCase()} ${String(path2).split("?")[0]}`);
35792
35819
  };
35793
35820
  let w;
35794
35821
  try {
@@ -35991,17 +36018,17 @@ async function crawlScreenDeep(opts, deep) {
35991
36018
  localDbSchema: opts.localDbSchema,
35992
36019
  capabilitySuccess: opts.capabilitySuccess === true
35993
36020
  });
35994
- const pathLabel = (path) => path.map((i) => sites[i].actionId.replace(/^tier5\./, "")).join(" \u2192 ");
36021
+ const pathLabel = (path2) => path2.map((i) => sites[i].actionId.replace(/^tier5\./, "")).join(" \u2192 ");
35995
36022
  while (queue.length) {
35996
36023
  if (visited.size >= maxNodes || dispatches >= maxDispatches) {
35997
36024
  capped = true;
35998
36025
  break;
35999
36026
  }
36000
- const path = queue.shift();
36027
+ const path2 = queue.shift();
36001
36028
  const w = await boot();
36002
36029
  try {
36003
36030
  let threwAt = null;
36004
- for (const [step, siteIdx] of path.entries()) {
36031
+ for (const [step, siteIdx] of path2.entries()) {
36005
36032
  const site = sites[siteIdx];
36006
36033
  const parsed = parseWorkerAction(site.actionId);
36007
36034
  const handle = w.handles[parsed.service];
@@ -36023,7 +36050,7 @@ async function crawlScreenDeep(opts, deep) {
36023
36050
  try {
36024
36051
  await handle.dispatch(parsed.action, ...workerArgs(effective));
36025
36052
  } catch (e) {
36026
- if (step === path.length - 1 && path.length >= 2) {
36053
+ if (step === path2.length - 1 && path2.length >= 2) {
36027
36054
  const source = sourceOfStack(e.stack, opts.bundleMap);
36028
36055
  findings.push({
36029
36056
  screen: screenId,
@@ -36032,7 +36059,7 @@ async function crawlScreenDeep(opts, deep) {
36032
36059
  severity: "error",
36033
36060
  axis: "deep",
36034
36061
  ...source ? { source } : {},
36035
- message: `after ${pathLabel(path)}: ${parsed.action}: ${errText(e)}`,
36062
+ message: `after ${pathLabel(path2)}: ${parsed.action}: ${errText(e)}`,
36036
36063
  hint: "this chain of taps crashes the worker \u2014 each step passed alone, the SEQUENCE is the bug"
36037
36064
  });
36038
36065
  }
@@ -36046,8 +36073,8 @@ async function crawlScreenDeep(opts, deep) {
36046
36073
  const hash = deepStateSignature(state, defects);
36047
36074
  if (visited.has(hash)) continue;
36048
36075
  visited.add(hash);
36049
- if (path.length >= 2) {
36050
- const last = sites[path[path.length - 1]];
36076
+ if (path2.length >= 2) {
36077
+ const last = sites[path2[path2.length - 1]];
36051
36078
  const lastTrigger = { tap: last.componentId, key: last.key, action: last.actionId };
36052
36079
  for (const [svc, paths] of Object.entries(defects)) {
36053
36080
  for (const p of paths) {
@@ -36057,7 +36084,7 @@ async function crawlScreenDeep(opts, deep) {
36057
36084
  invariant: "non-finite-number",
36058
36085
  severity: "error",
36059
36086
  axis: "deep",
36060
- message: `after ${pathLabel(path)}: ${svc} state holds a non-finite number: ${p}`,
36087
+ message: `after ${pathLabel(path2)}: ${svc} state holds a non-finite number: ${p}`,
36061
36088
  at: `${svc}.${p.split(" = ")[0]}`,
36062
36089
  hint: "a chain of taps produced the bad arithmetic \u2014 each step alone was fine; check what the SEQUENCE accumulates"
36063
36090
  });
@@ -36071,7 +36098,7 @@ async function crawlScreenDeep(opts, deep) {
36071
36098
  invariant: d.kind,
36072
36099
  severity: "error",
36073
36100
  axis: "deep",
36074
- message: `after ${pathLabel(path)}: ${resolvedDefectMessage(d)}`,
36101
+ message: `after ${pathLabel(path2)}: ${resolvedDefectMessage(d)}`,
36075
36102
  at,
36076
36103
  field,
36077
36104
  hint: resolvedDefectHint(d)
@@ -36079,8 +36106,8 @@ async function crawlScreenDeep(opts, deep) {
36079
36106
  });
36080
36107
  }
36081
36108
  }
36082
- if (path.length < deep.depth) {
36083
- for (let i = 0; i < sites.length; i++) queue.push([...path, i]);
36109
+ if (path2.length < deep.depth) {
36110
+ for (let i = 0; i < sites.length; i++) queue.push([...path2, i]);
36084
36111
  }
36085
36112
  } finally {
36086
36113
  w.dispose();
@@ -36171,13 +36198,13 @@ async function crawlScreenRelations(opts) {
36171
36198
  capabilitySuccess: opts.capabilitySuccess === true,
36172
36199
  ...opts.evaluator ? { evaluator: opts.evaluator } : {}
36173
36200
  });
36174
- const replay = async (path, rowFor = () => null) => {
36201
+ const replay = async (path2, rowFor = () => null) => {
36175
36202
  const w = await boot();
36176
36203
  try {
36177
36204
  if (w.errors.length) return null;
36178
36205
  let prev = snapshot(w).state;
36179
36206
  const bootState = prev;
36180
- for (const [i, site] of path.entries()) {
36207
+ for (const [i, site] of path2.entries()) {
36181
36208
  const parsed = parseWorkerAction(site.actionId);
36182
36209
  const h = w.handles[parsed.service];
36183
36210
  if (!h || !h.actionNames().includes(parsed.action)) return null;
@@ -36533,9 +36560,9 @@ function routesOverlap(left, right) {
36533
36560
  return segment.startsWith(":") || other.startsWith(":") || segment === other;
36534
36561
  });
36535
36562
  }
36536
- function validateRouteConflicts(definitions) {
36563
+ function validateRouteConflicts(definitions2) {
36537
36564
  const seen = [];
36538
- for (const definition of definitions) {
36565
+ for (const definition of definitions2) {
36539
36566
  validateFunctionDefinition(definition);
36540
36567
  const previous = seen.find((route) => route.method === definition.method && routesOverlap(route.path, definition.path));
36541
36568
  if (previous) throw new Error(`duplicate or ambiguous function route: ${definition.name} conflicts with ${previous.name} at ${definition.method} ${definition.path}`);
@@ -36589,13 +36616,13 @@ function rejectUnsafeSource(name, source) {
36589
36616
  throw new Error(`function ${name} must export handler`);
36590
36617
  }
36591
36618
  }
36592
- async function buildFunctions(definitions, sources, options = {}) {
36593
- validateRouteConflicts(definitions);
36619
+ async function buildFunctions(definitions2, sources, options = {}) {
36620
+ validateRouteConflicts(definitions2);
36594
36621
  validateDependencyPolicy(options.dependencies ?? [], options.dependencyPolicy);
36595
36622
  const sbom = createFunctionSbom(options.dependencies ?? []);
36596
36623
  const runBuild = await (_buildP ??= loadBuild());
36597
36624
  const built = [];
36598
- for (const definition of definitions) {
36625
+ for (const definition of definitions2) {
36599
36626
  const source = sources[definition.name];
36600
36627
  if (typeof source !== "string") throw new Error(`missing source for function ${definition.name}`);
36601
36628
  assertStaticDependencySource(source);
@@ -36747,10 +36774,10 @@ function l10nLintOptions(locale, appDir2) {
36747
36774
  const tags = (locale.translations ?? []).filter((t) => t !== locale.default);
36748
36775
  const catalog = /* @__PURE__ */ new Set();
36749
36776
  for (const tag of tags) {
36750
- const path = join34(appDir2, "l10n", `${tag}.json`);
36751
- if (!existsSync37(path)) continue;
36777
+ const path2 = join34(appDir2, "l10n", `${tag}.json`);
36778
+ if (!existsSync37(path2)) continue;
36752
36779
  try {
36753
- const parsed = JSON.parse(readFileSync40(path, "utf8"));
36780
+ const parsed = JSON.parse(readFileSync40(path2, "utf8"));
36754
36781
  for (const m of Object.values(parsed.messages ?? {})) {
36755
36782
  if (typeof m?.source === "string" && typeof m.translation === "string" && m.translation.length > 0) {
36756
36783
  catalog.add(m.source);
@@ -37020,8 +37047,8 @@ async function buildRelease(app, dest, opts = {}) {
37020
37047
  function countingWixCall(base) {
37021
37048
  let returned = 0;
37022
37049
  return {
37023
- call: async (method, path, body) => {
37024
- const out = await base(method, path, body);
37050
+ call: async (method, path2, body) => {
37051
+ const out = await base(method, path2, body);
37025
37052
  returned += 1;
37026
37053
  return out;
37027
37054
  },
@@ -37112,9 +37139,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
37112
37139
  );
37113
37140
  }
37114
37141
  const token = await mintVisitor(clientId);
37115
- liveWixCall = async (method, path, body) => {
37142
+ liveWixCall = async (method, path2, body) => {
37116
37143
  const bodyStr = body === void 0 ? void 0 : typeof body === "string" ? body : JSON.stringify(body);
37117
- const r = await webWixCall(method, path, bodyStr, token);
37144
+ const r = await webWixCall(method, path2, bodyStr, token);
37118
37145
  if (r.status < 200 || r.status >= 300) throw new Error(`HTTP ${r.status}: ${String(r.body).slice(0, 300)}`);
37119
37146
  try {
37120
37147
  return r.body ? JSON.parse(r.body) : {};
@@ -37211,9 +37238,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
37211
37238
  const MAX_AUTHORING_DOC_BYTES = 128 * 1024;
37212
37239
  if (store.putDoc) {
37213
37240
  for (const [name, file] of [["spec", "SPEC.md"], ["mobile-ux", "MOBILE-UX.md"]]) {
37214
- const path = join34(preloaded.dir, file);
37215
- if (!existsSync37(path)) continue;
37216
- const bytes2 = readFileSync40(path);
37241
+ const path2 = join34(preloaded.dir, file);
37242
+ if (!existsSync37(path2)) continue;
37243
+ const bytes2 = readFileSync40(path2);
37217
37244
  if (bytes2.length === 0 || bytes2.length > MAX_AUTHORING_DOC_BYTES) {
37218
37245
  throw new Error(`${file} must be non-empty and at most ${MAX_AUTHORING_DOC_BYTES} bytes to ship with a release.`);
37219
37246
  }
@@ -37641,7 +37668,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
37641
37668
  }
37642
37669
  if (store.putWidget) {
37643
37670
  const bakedWidgets = await bakeWidgets(
37644
- (path) => devFetch(`${base}${path}`, { headers: { "X-Himalaya-App": app } }),
37671
+ (path2) => devFetch(`${base}${path2}`, { headers: { "X-Himalaya-App": app } }),
37645
37672
  (widgetId, json5) => store.putWidget(app, widgetId, json5),
37646
37673
  // `opts.tier5Dir`, NOT the `tier5Dir` local — that one falls back to the
37647
37674
  // repo-global dir, where this package's widgets cannot be told from anyone
@@ -38400,8 +38427,8 @@ async function captchaRequest(options) {
38400
38427
  }
38401
38428
  const setup = options.operation === "setup";
38402
38429
  const base = options.target.control.replace(/\/+$/, "");
38403
- const path = setup ? "/v1/admin/captcha/setup" : `/v1/admin/captcha?app=${encodeURIComponent(options.input.app)}`;
38404
- const response = await (options.fetchImpl ?? fetch)(base + path, {
38430
+ const path2 = setup ? "/v1/admin/captcha/setup" : `/v1/admin/captcha?app=${encodeURIComponent(options.input.app)}`;
38431
+ const response = await (options.fetchImpl ?? fetch)(base + path2, {
38405
38432
  method: setup ? "POST" : "GET",
38406
38433
  redirect: "error",
38407
38434
  signal: AbortSignal.timeout(6e4),
@@ -38453,9 +38480,9 @@ __export(captcha_exports, {
38453
38480
  });
38454
38481
  import { readFileSync as readFileSync41 } from "node:fs";
38455
38482
  import { resolve as resolve32 } from "node:path";
38456
- function readObject(path) {
38483
+ function readObject(path2) {
38457
38484
  try {
38458
- return JSON.parse(readFileSync41(path, "utf8"));
38485
+ return JSON.parse(readFileSync41(path2, "utf8"));
38459
38486
  } catch {
38460
38487
  return {};
38461
38488
  }
@@ -38533,11 +38560,11 @@ async function pushSetupRequest(options) {
38533
38560
  return refuse3("push_setup_body_too_large");
38534
38561
  }
38535
38562
  const base = options.target.control.replace(/\/+$/, "");
38536
- let path = "/v1/admin/push/setup";
38563
+ let path2 = "/v1/admin/push/setup";
38537
38564
  if (!setup) {
38538
38565
  const q = new URLSearchParams({ app: options.query.app, site: options.query.site });
38539
38566
  if (options.query.verify) q.set("verify", options.query.verify);
38540
- path += `?${q.toString()}`;
38567
+ path2 += `?${q.toString()}`;
38541
38568
  }
38542
38569
  const headers2 = {
38543
38570
  "x-control-token": options.target.controlToken,
@@ -38548,7 +38575,7 @@ async function pushSetupRequest(options) {
38548
38575
  ...options.previewTag ? { "x-wix-route-serve": options.previewTag } : {}
38549
38576
  };
38550
38577
  try {
38551
- const response = await (options.fetchImpl ?? fetch)(base + path, {
38578
+ const response = await (options.fetchImpl ?? fetch)(base + path2, {
38552
38579
  method: setup ? "POST" : "GET",
38553
38580
  headers: headers2,
38554
38581
  redirect: "error",
@@ -38601,9 +38628,9 @@ var init_push_setup_apple_credentials = __esm({
38601
38628
  // src/push-onboarding.ts
38602
38629
  import { existsSync as existsSync38, mkdirSync as mkdirSync17, readFileSync as readFileSync42, statSync as statSync7, writeFileSync as writeFileSync13, chmodSync as chmodSync2 } from "node:fs";
38603
38630
  import { basename as basename9, dirname as dirname22, join as join35, resolve as resolve33 } from "node:path";
38604
- function readJson2(path) {
38631
+ function readJson2(path2) {
38605
38632
  try {
38606
- const parsed = JSON.parse(readFileSync42(path, "utf8"));
38633
+ const parsed = JSON.parse(readFileSync42(path2, "utf8"));
38607
38634
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
38608
38635
  } catch {
38609
38636
  return {};
@@ -38676,10 +38703,10 @@ function localIdentityRefusal(i) {
38676
38703
  }
38677
38704
  return null;
38678
38705
  }
38679
- function readKeyFile(path) {
38706
+ function readKeyFile(path2) {
38680
38707
  let size;
38681
38708
  try {
38682
- size = statSync7(path).size;
38709
+ size = statSync7(path2).size;
38683
38710
  } catch {
38684
38711
  return { ok: false, code: "key_file_unreadable", reason: "cannot read the selected key file; check its path and file permissions" };
38685
38712
  }
@@ -38688,7 +38715,7 @@ function readKeyFile(path) {
38688
38715
  }
38689
38716
  let body;
38690
38717
  try {
38691
- body = readFileSync42(path, "utf8");
38718
+ body = readFileSync42(path2, "utf8");
38692
38719
  } catch {
38693
38720
  return { ok: false, code: "key_file_unreadable", reason: "cannot read the selected key file; check its path and file permissions" };
38694
38721
  }
@@ -38742,20 +38769,20 @@ function buildPushSetupBody(i, keys) {
38742
38769
  };
38743
38770
  }
38744
38771
  function readPushOnboarding(dir) {
38745
- const path = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
38746
- if (!existsSync38(path)) return { version: 1 };
38747
- const parsed = readJson2(path);
38772
+ const path2 = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
38773
+ if (!existsSync38(path2)) return { version: 1 };
38774
+ const parsed = readJson2(path2);
38748
38775
  return { version: 1, ...parsed };
38749
38776
  }
38750
38777
  function writeFile(dir, file) {
38751
- const path = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
38752
- mkdirSync17(dirname22(path), { recursive: true, mode: 448 });
38753
- writeFileSync13(path, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
38778
+ const path2 = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
38779
+ mkdirSync17(dirname22(path2), { recursive: true, mode: 448 });
38780
+ writeFileSync13(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
38754
38781
  try {
38755
- chmodSync2(path, 384);
38782
+ chmodSync2(path2, 384);
38756
38783
  } catch {
38757
38784
  }
38758
- return path;
38785
+ return path2;
38759
38786
  }
38760
38787
  function recordPushDeferral(dir, d) {
38761
38788
  const identity = {};
@@ -38777,8 +38804,8 @@ function recordPushDeferral(dir, d) {
38777
38804
  return push;
38778
38805
  }
38779
38806
  function clearPushDeferral(dir) {
38780
- const path = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
38781
- if (!existsSync38(path)) return;
38807
+ const path2 = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
38808
+ if (!existsSync38(path2)) return;
38782
38809
  const { push: _dropped, ...rest } = readPushOnboarding(dir);
38783
38810
  writeFile(dir, { ...rest, version: 1 });
38784
38811
  }
@@ -39405,13 +39432,13 @@ function packagePathFor(pathname) {
39405
39432
  }
39406
39433
  return UNSUPPORTED;
39407
39434
  }
39408
- function parseJson(read, path, errors) {
39409
- const bytes2 = read(path);
39435
+ function parseJson(read, path2, errors) {
39436
+ const bytes2 = read(path2);
39410
39437
  if (!bytes2) return null;
39411
39438
  try {
39412
39439
  return JSON.parse(utf82(bytes2));
39413
39440
  } catch (e) {
39414
- errors.push(`${path} is not valid JSON: ${e.message}`);
39441
+ errors.push(`${path2} is not valid JSON: ${e.message}`);
39415
39442
  return null;
39416
39443
  }
39417
39444
  }
@@ -39832,8 +39859,8 @@ function inflateEntry(buf, entry) {
39832
39859
  verifyZipEntry(entry, bytes2);
39833
39860
  return bytes2;
39834
39861
  }
39835
- function readIf(path) {
39836
- return existsSync39(path) && statSync8(path).isFile() ? readFileSync43(path) : null;
39862
+ function readIf(path2) {
39863
+ return existsSync39(path2) && statSync8(path2).isFile() ? readFileSync43(path2) : null;
39837
39864
  }
39838
39865
  function listDir(dir) {
39839
39866
  return existsSync39(dir) ? readdirSync20(dir).filter((f) => statSync8(join36(dir, f)).isFile()) : [];
@@ -39969,7 +39996,7 @@ function packReleaseToDir(releaseRoot, app, outDir, opts = {}) {
39969
39996
  }
39970
39997
  function openFromEntries(entries, opts) {
39971
39998
  const read = (p) => entries.get(p) ?? null;
39972
- const contentHash = computeContentHash(Array.from(entries, ([path, bytes2]) => ({ path, bytes: bytes2 })));
39999
+ const contentHash = computeContentHash(Array.from(entries, ([path2, bytes2]) => ({ path: path2, bytes: bytes2 })));
39973
40000
  const validation = validatePackage(read, { requireHeader: opts.requireHeader, contentHash });
39974
40001
  return {
39975
40002
  header: validation.header,
@@ -40140,7 +40167,7 @@ function zipAppSource(entries) {
40140
40167
  return writeZip(entries.map((e) => ({ path: e.path, bytes: e.bytes })));
40141
40168
  }
40142
40169
  function readAppSource(zip) {
40143
- return [...readZip(zip)].map(([path, bytes2]) => ({ path, bytes: bytes2 }));
40170
+ return [...readZip(zip)].map(([path2, bytes2]) => ({ path: path2, bytes: bytes2 }));
40144
40171
  }
40145
40172
  function pathKind(p) {
40146
40173
  try {
@@ -40453,24 +40480,24 @@ function readTestConfig(dir) {
40453
40480
  }
40454
40481
  return { ...skip ? { skip } : {}, ...journeys ? { journeys } : {} };
40455
40482
  }
40456
- function readNetRules(path) {
40483
+ function readNetRules(path2) {
40457
40484
  let parsed;
40458
40485
  try {
40459
- parsed = JSON.parse(readFileSync46(path, "utf8"));
40486
+ parsed = JSON.parse(readFileSync46(path2, "utf8"));
40460
40487
  } catch (e) {
40461
- throw new Error(`--net ${path} could not be read as JSON \u2014 ${e.message}`);
40488
+ throw new Error(`--net ${path2} could not be read as JSON \u2014 ${e.message}`);
40462
40489
  }
40463
40490
  const rules = parsed?.rules;
40464
40491
  if (!Array.isArray(rules)) {
40465
- throw new Error(`--net ${path} has no "rules" array \u2014 expected the net-mocks shape { "rules": [ { "matcher": {...}, "response": {...} } ] }`);
40492
+ throw new Error(`--net ${path2} has no "rules" array \u2014 expected the net-mocks shape { "rules": [ { "matcher": {...}, "response": {...} } ] }`);
40466
40493
  }
40467
40494
  const active = rules.filter((r) => r.enabled !== false);
40468
40495
  const shapeErrors = wixMockRuleErrors(active);
40469
40496
  if (shapeErrors.length) {
40470
- throw new Error(`${path}: invalid net-mocks fixture \u2014 ${shapeErrors.join("; ")}`);
40497
+ throw new Error(`${path2}: invalid net-mocks fixture \u2014 ${shapeErrors.join("; ")}`);
40471
40498
  }
40472
40499
  if (active.length && !active.some((r) => r.matcher && typeof r.matcher === "object")) {
40473
- throw new Error(`${path}: none of the ${active.length} rule(s) has a "matcher" \u2014 the net-mocks shape is { "rules": [ { "matcher": {...}, "response": {...} } ] }; a file that matches nothing must not report as "mocked"`);
40500
+ throw new Error(`${path2}: none of the ${active.length} rule(s) has a "matcher" \u2014 the net-mocks shape is { "rules": [ { "matcher": {...}, "response": {...} } ] }; a file that matches nothing must not report as "mocked"`);
40474
40501
  }
40475
40502
  return active;
40476
40503
  }
@@ -40509,21 +40536,21 @@ function makeRecordingWixCall(send2, token, app) {
40509
40536
  const events = [];
40510
40537
  const refused = [];
40511
40538
  let id = 0;
40512
- const call = async (method, path, body) => {
40539
+ const call = async (method, path2, body) => {
40513
40540
  const verb = method.toUpperCase();
40514
- if (/[#\x00-\x1F\x7F]/.test(path)) {
40515
- refused.push(`${verb} ${path}`);
40516
- throw new Error(`--record refused ${verb} ${path}: the path carries a fragment or control character \u2014 not a provable read`);
40541
+ if (/[#\x00-\x1F\x7F]/.test(path2)) {
40542
+ refused.push(`${verb} ${path2}`);
40543
+ throw new Error(`--record refused ${verb} ${path2}: the path carries a fragment or control character \u2014 not a provable read`);
40517
40544
  }
40518
- const bare = path.split("?")[0].replace(/\/+$/, "");
40545
+ const bare = path2.split("?")[0].replace(/\/+$/, "");
40519
40546
  const readShaped = verb === "GET" || verb === "POST" && /\/(query|search|list[^/]*|get[^/]*|count|aggregate|facets|connections)$/i.test(bare);
40520
40547
  if (!readShaped) {
40521
- refused.push(`${verb} ${path}`);
40522
- throw new Error(`--record refused ${verb} ${path}: recording sends only proven reads (GET, or POST ending in /query, /search, /list*, /get*, /count, /aggregate, /facets, /connections) \u2014 if this IS a read, add its rule to dev/net-mocks.json by hand`);
40548
+ refused.push(`${verb} ${path2}`);
40549
+ throw new Error(`--record refused ${verb} ${path2}: recording sends only proven reads (GET, or POST ending in /query, /search, /list*, /get*, /count, /aggregate, /facets, /connections) \u2014 if this IS a read, add its rule to dev/net-mocks.json by hand`);
40523
40550
  }
40524
40551
  const bodyStr = body === void 0 ? void 0 : typeof body === "string" ? body : JSON.stringify(body);
40525
40552
  const started = Date.now();
40526
- const r = await send2(method, path, bodyStr, token);
40553
+ const r = await send2(method, path2, bodyStr, token);
40527
40554
  events.push({
40528
40555
  id: ++id,
40529
40556
  ts: started,
@@ -40531,8 +40558,8 @@ function makeRecordingWixCall(send2, token, app) {
40531
40558
  source: "observe",
40532
40559
  host: "www.wixapis.com",
40533
40560
  method,
40534
- url: `https://www.wixapis.com${path}`,
40535
- path,
40561
+ url: `https://www.wixapis.com${path2}`,
40562
+ path: path2,
40536
40563
  status: r.status,
40537
40564
  durationMs: Date.now() - started,
40538
40565
  ...bodyStr !== void 0 ? { reqBody: bodyStr } : {},
@@ -41079,6 +41106,15 @@ var init_mobile_ux_lint = __esm({
41079
41106
  }
41080
41107
  });
41081
41108
 
41109
+ // ../../core/serve-runtime/src/site-lease.ts
41110
+ var SITE_CONTROL_TTL_SECONDS, SITE_AUTHORIZATION_TTL_SECONDS;
41111
+ var init_site_lease = __esm({
41112
+ "../../core/serve-runtime/src/site-lease.ts"() {
41113
+ SITE_CONTROL_TTL_SECONDS = 15 * 60;
41114
+ SITE_AUTHORIZATION_TTL_SECONDS = SITE_CONTROL_TTL_SECONDS + 45 * 60;
41115
+ }
41116
+ });
41117
+
41082
41118
  // ../../core/serve-runtime/src/preview-token.ts
41083
41119
  async function hmacKey(secret) {
41084
41120
  return crypto.subtle.importKey("raw", new TextEncoder().encode(secret), SUBTLE_ALGO, false, ["sign"]);
@@ -41119,6 +41155,7 @@ async function verifyPreviewToken(input) {
41119
41155
  var SUBTLE_ALGO, PREVIEW_TOKEN_VERSION, DEFAULT_PREVIEW_TOKEN_TTL_SECONDS, WEB_PREVIEW_TOKEN_TTL_SECONDS;
41120
41156
  var init_preview_token = __esm({
41121
41157
  "../../core/serve-runtime/src/preview-token.ts"() {
41158
+ init_site_lease();
41122
41159
  init_base64();
41123
41160
  SUBTLE_ALGO = { name: "HMAC", hash: "SHA-256" };
41124
41161
  PREVIEW_TOKEN_VERSION = 1;
@@ -41163,9 +41200,9 @@ var init_auth = __esm({
41163
41200
  });
41164
41201
 
41165
41202
  // ../../core/functions-runtime/src/wix-transport.ts
41166
- function rejectSiteOverride(path) {
41203
+ function rejectSiteOverride(path2) {
41167
41204
  try {
41168
- if (new URL(path, "https://wix.invalid").searchParams.has("msid")) {
41205
+ if (new URL(path2, "https://wix.invalid").searchParams.has("msid")) {
41169
41206
  throw new Error("request cannot override the bound Wix site identity");
41170
41207
  }
41171
41208
  } catch (error) {
@@ -41176,8 +41213,8 @@ function createWixApiCapability(options) {
41176
41213
  const permissions = [...options.permissions ?? []].sort();
41177
41214
  let installation;
41178
41215
  return {
41179
- async call(method, path, body) {
41180
- rejectSiteOverride(path);
41216
+ async call(method, path2, body) {
41217
+ rejectSiteOverride(path2);
41181
41218
  let identity;
41182
41219
  if (options.identity.kind === "caller") {
41183
41220
  identity = { ...options.identity };
@@ -41188,9 +41225,9 @@ function createWixApiCapability(options) {
41188
41225
  throw new Error("installation identity is not authorized for the configured Wix site");
41189
41226
  }
41190
41227
  identity = { kind: "installation", installationId: installation.installationId };
41191
- options.audit?.({ app: options.app, siteId: options.siteId, identity: "installation", method, path });
41228
+ options.audit?.({ app: options.app, siteId: options.siteId, identity: "installation", method, path: path2 });
41192
41229
  }
41193
- return options.transport.call({ app: options.app, siteId: options.siteId, identity, ...permissions.length ? { permissions } : {}, method, path, ...body === void 0 ? {} : { body } });
41230
+ return options.transport.call({ app: options.app, siteId: options.siteId, identity, ...permissions.length ? { permissions } : {}, method, path: path2, ...body === void 0 ? {} : { body } });
41194
41231
  }
41195
41232
  };
41196
41233
  }
@@ -41782,11 +41819,11 @@ var init_sandbox = __esm({
41782
41819
  });
41783
41820
 
41784
41821
  // ../../core/functions-runtime/src/openapi.ts
41785
- function makeFunctionsOpenApi(manifest, definitions = []) {
41822
+ function makeFunctionsOpenApi(manifest, definitions2 = []) {
41786
41823
  const paths = {};
41787
41824
  for (const record2 of manifest.functions ?? []) {
41788
41825
  if (record2.internal) continue;
41789
- const definition = definitions.find((item) => item.name === record2.name);
41826
+ const definition = definitions2.find((item) => item.name === record2.name);
41790
41827
  const method = record2.method.toLowerCase();
41791
41828
  paths[record2.path] = {
41792
41829
  ...paths[record2.path] ?? {},
@@ -42413,9 +42450,9 @@ function resolveTarget2(pathname) {
42413
42450
  return null;
42414
42451
  }
42415
42452
  }
42416
- function chooseFunction(records, method, path) {
42453
+ function chooseFunction(records, method, path2) {
42417
42454
  for (const record2 of records) {
42418
- const params = routeMatch(record2.path, path);
42455
+ const params = routeMatch(record2.path, path2);
42419
42456
  if (params && record2.method === method) return { record: record2, params };
42420
42457
  }
42421
42458
  return null;
@@ -42424,8 +42461,8 @@ async function contentFromBundle(bytes2, record2) {
42424
42461
  const actual = await integrity(bytes2);
42425
42462
  return actual.hash === record2.bundleHash && actual.sri === record2.sri ? utf8Decode(bytes2) : null;
42426
42463
  }
42427
- function definitionFor(definitions, name) {
42428
- return definitions?.find((definition) => definition.name === name);
42464
+ function definitionFor(definitions2, name) {
42465
+ return definitions2?.find((definition) => definition.name === name);
42429
42466
  }
42430
42467
  async function bodyValue(request, record2) {
42431
42468
  const length = Number(request.headers.get("content-length") ?? "0");
@@ -42468,6 +42505,7 @@ function makeFunctionsHandler(options) {
42468
42505
  const token = request.headers.get("x-himalaya-preview-token") || new URL(request.url).searchParams.get("pvt");
42469
42506
  const verified = token ? await verifyPreviewToken({ token, secret: options.previewTokenSecret, app: target.app, releaseId: pin, nowSeconds: options.nowSeconds }) : { ok: false, error: "malformed" };
42470
42507
  if (!verified.ok || verified.claims.source !== "functions") return errorResponse(401, `preview_token_${verified.ok ? "scope_mismatch" : verified.error}`, "a valid function preview token is required", id);
42508
+ if (options.authorizePreview ? !await options.authorizePreview(verified.claims) : !!verified.claims.siteLease) return errorResponse(403, "site_preview_forbidden", "site authorization expired or changed", id);
42471
42509
  previewClaims = verified.claims;
42472
42510
  }
42473
42511
  if (pin) selected = options.store.getManifestById ? await options.store.getManifestById(target.app, pin) : null;
@@ -42676,8 +42714,8 @@ function makeFunctionsHandler(options) {
42676
42714
  }
42677
42715
  };
42678
42716
  }
42679
- function functionsOpenApi(manifest, definitions = []) {
42680
- return makeFunctionsOpenApi(manifest, definitions);
42717
+ function functionsOpenApi(manifest, definitions2 = []) {
42718
+ return makeFunctionsOpenApi(manifest, definitions2);
42681
42719
  }
42682
42720
  var MAX_LOG_MESSAGE;
42683
42721
  var init_gateway = __esm({
@@ -42743,19 +42781,19 @@ async function loadFunctionsApp(dir) {
42743
42781
  if (dataErrors.length) throw new Error(`invalid data declaration: ${dataErrors.map((issue2) => issue2.message).join("; ")}`);
42744
42782
  return { app: loaded.name, dir: loaded.dir, definitions: config.functions.functions, sources, siteBinding: config.functions.siteBinding, schedules: config.functions.schedules, ...data ? { data } : {} };
42745
42783
  }
42746
- function listFunctions(definitions) {
42747
- return definitions.map((definition) => ({ name: definition.name, method: definition.method, path: definition.path, auth: definition.auth, internal: definition.internal, limits: definition.limits }));
42784
+ function listFunctions(definitions2) {
42785
+ return definitions2.map((definition) => ({ name: definition.name, method: definition.method, path: definition.path, auth: definition.auth, internal: definition.internal, limits: definition.limits }));
42748
42786
  }
42749
- function describeFunction(definitions, name) {
42750
- const definition = definitions.find((item) => item.name === name);
42787
+ function describeFunction(definitions2, name) {
42788
+ const definition = definitions2.find((item) => item.name === name);
42751
42789
  return definition ? { ...listFunctions([definition])[0], wixIdentity: definition.wixIdentity, wixPermissions: [...definition.wixPermissions], capabilities: [...definition.capabilities], secrets: [...definition.secrets], outboundHosts: [...definition.outboundHosts], inputSchema: definition.input?.kind ?? null, outputSchema: definition.output?.kind ?? null } : null;
42752
42790
  }
42753
- function materializeFunctionPath(path, params = {}) {
42754
- const names = [...path.matchAll(/:([A-Za-z][A-Za-z0-9_]*)/g)].map((match) => match[1]);
42791
+ function materializeFunctionPath(path2, params = {}) {
42792
+ const names = [...path2.matchAll(/:([A-Za-z][A-Za-z0-9_]*)/g)].map((match) => match[1]);
42755
42793
  for (const name of names) {
42756
42794
  if (typeof params[name] !== "string" || params[name] === "") throw new Error(`missing route parameter "${name}"; pass --params {"${name}":"value"}`);
42757
42795
  }
42758
- return path.replace(/:([A-Za-z][A-Za-z0-9_]*)/g, (_match, name) => encodeURIComponent(params[name]));
42796
+ return path2.replace(/:([A-Za-z][A-Za-z0-9_]*)/g, (_match, name) => encodeURIComponent(params[name]));
42759
42797
  }
42760
42798
  function memoryStore(manifest, built) {
42761
42799
  const bytes2 = new Map(built.map((item) => [item.bundleHash, item.bytes]));
@@ -42839,8 +42877,8 @@ async function invokeRemoteFunction(input) {
42839
42877
  });
42840
42878
  return { response, url: url.toString() };
42841
42879
  }
42842
- function openApiForFunctions(manifest, definitions) {
42843
- return functionsOpenApi(manifest, definitions);
42880
+ function openApiForFunctions(manifest, definitions2) {
42881
+ return functionsOpenApi(manifest, definitions2);
42844
42882
  }
42845
42883
  async function runRemoteFunctionOperation(input) {
42846
42884
  const environment2 = input.environment ?? "production";
@@ -43092,9 +43130,9 @@ function runAndroidNativeDecode(options) {
43092
43130
  rmSync8(descriptorDir, { recursive: true, force: true });
43093
43131
  }
43094
43132
  }
43095
- function fieldAt(path) {
43096
- if (path === null) return void 0;
43097
- return path.match(/\.([^.[\]]+)$/)?.[1];
43133
+ function fieldAt(path2) {
43134
+ if (path2 === null) return void 0;
43135
+ return path2.match(/\.([^.[\]]+)$/)?.[1];
43098
43136
  }
43099
43137
  function mergeNativeDecode(report2, run2) {
43100
43138
  const platformLabel = run2.platform === "ios" ? "iOS" : "Android";
@@ -44084,8 +44122,8 @@ var init_wix_member_auth = __esm({
44084
44122
  function json3(status, body, headers2 = {}) {
44085
44123
  return new Response(JSON.stringify(body), { status, headers: { "content-type": JSON_CT, ...headers2 } });
44086
44124
  }
44087
- function isCookieAuthorizedPath(path) {
44088
- return path === "/v1/__webwix/call" || path === "/v1/owner" || path.startsWith("/v1/owner/") || path === "/v1/__webwix/identity" || path === "/v1/__webwix/login" || path === "/v1/__webwix/register" || path === "/v1/__webwix/logout" || path === MEMBER_CALLBACK_PATH;
44125
+ function isCookieAuthorizedPath(path2) {
44126
+ return path2 === "/v1/__webwix/call" || 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;
44089
44127
  }
44090
44128
  function makeServeHandler(opts) {
44091
44129
  let storePromise = null;
@@ -44214,13 +44252,16 @@ ${releaseId}`;
44214
44252
  }
44215
44253
  async function authorizePinnedRead(request, url, app, releaseId, screenId) {
44216
44254
  const secret = opts.previewTokenSecret;
44217
- if (!secret) return null;
44255
+ if (!secret) return opts.authorizePreview ? json3(503, { error: "preview_token_unavailable" }) : null;
44218
44256
  const token = resolvePreviewToken(request, url);
44219
44257
  const live2 = await manifest(app);
44220
44258
  const isLive = live2?.releaseId === releaseId;
44221
44259
  if (!token) return isLive ? null : json3(401, { error: "preview_token_required", app, releaseId });
44222
44260
  const verified = await verifyPreviewToken({ token, secret, app, releaseId, screenId });
44223
- if (verified.ok) return null;
44261
+ if (verified.ok) {
44262
+ if (opts.authorizePreview ? !await opts.authorizePreview(verified.claims) : !!verified.claims.siteLease) return json3(403, { error: "site_preview_forbidden" });
44263
+ return null;
44264
+ }
44224
44265
  return json3(verified.error === "scope_mismatch" ? 403 : 401, {
44225
44266
  error: `preview_token_${verified.error}`,
44226
44267
  app,
@@ -44265,9 +44306,9 @@ ${releaseId}`;
44265
44306
  const handle = async (request) => {
44266
44307
  try {
44267
44308
  const url = new URL(request.url);
44268
- const path = url.pathname;
44309
+ const path2 = url.pathname;
44269
44310
  if (opts.devControl && request.method === "PUT") {
44270
- const dcMatch = /^\/v1\/dev-control\/([^/]+)$/.exec(path);
44311
+ const dcMatch = /^\/v1\/dev-control\/([^/]+)$/.exec(path2);
44271
44312
  if (dcMatch) {
44272
44313
  const dcApp = dcMatch[1];
44273
44314
  let body = {};
@@ -44283,16 +44324,16 @@ ${releaseId}`;
44283
44324
  }
44284
44325
  }
44285
44326
  const memberRungApp = memberAuthOn() ? memberApp(request) : null;
44286
- if (memberRungApp && (path === "/v1/__webwix/login" || path === "/v1/__webwix/register" || path === MEMBER_CALLBACK_PATH || path === "/v1/__webwix/logout")) {
44327
+ if (memberRungApp && (path2 === "/v1/__webwix/login" || path2 === "/v1/__webwix/register" || path2 === MEMBER_CALLBACK_PATH || path2 === "/v1/__webwix/logout")) {
44287
44328
  const store2 = memberSessions();
44288
44329
  if (!store2) return json3(503, { error: "member_auth_unconfigured" });
44289
44330
  const sessionId = readSessionCookie(request.headers.get("cookie"));
44290
- if (path === "/v1/__webwix/logout") {
44331
+ if (path2 === "/v1/__webwix/logout") {
44291
44332
  if (request.method !== "POST") return json3(405, { error: "method_not_allowed" });
44292
44333
  if (sessionId) await store2.delete(sessionId);
44293
44334
  return json3(200, { ok: true }, { "set-cookie": clearSessionCookie(), "cache-control": "no-store" });
44294
44335
  }
44295
- if (path === MEMBER_CALLBACK_PATH) {
44336
+ if (path2 === MEMBER_CALLBACK_PATH) {
44296
44337
  if (request.method !== "GET") return json3(405, { error: "method_not_allowed" });
44297
44338
  const code = url.searchParams.get("code");
44298
44339
  const state2 = url.searchParams.get("state");
@@ -44352,7 +44393,7 @@ ${releaseId}`;
44352
44393
  try {
44353
44394
  const visitor = await webwixTokens.token(resolved2.config.clientId);
44354
44395
  authUrl = await hostedAuthUrl(
44355
- { ...resolved2.config, mode: path.endsWith("/register") ? "signup" : "login", state, challenge: pkce.challenge },
44396
+ { ...resolved2.config, mode: path2.endsWith("/register") ? "signup" : "login", state, challenge: pkce.challenge },
44356
44397
  visitor,
44357
44398
  webwixFetch
44358
44399
  );
@@ -44379,7 +44420,7 @@ ${releaseId}`;
44379
44420
  }
44380
44421
  });
44381
44422
  }
44382
- if ((request.method === "GET" || request.method === "HEAD") && path === "/v1/__webwix/identity") {
44423
+ if ((request.method === "GET" || request.method === "HEAD") && path2 === "/v1/__webwix/identity") {
44383
44424
  const headers2 = { "content-type": JSON_CT, "cache-control": "no-store" };
44384
44425
  if (request.method === "HEAD") return new Response(null, { status: 200, headers: headers2 });
44385
44426
  const webwixDirect = opts.webwixBridge !== false;
@@ -44393,7 +44434,7 @@ ${releaseId}`;
44393
44434
  }
44394
44435
  return json3(200, { authenticated: false, userId: null, email: null, webwixDirect }, { "cache-control": "no-store" });
44395
44436
  }
44396
- if (request.method === "POST" && path === "/v1/__webwix/call") {
44437
+ if (request.method === "POST" && path2 === "/v1/__webwix/call") {
44397
44438
  if (opts.webwixBridge === false) {
44398
44439
  return json3(503, { error: "webwix_bridge_disabled" });
44399
44440
  }
@@ -44496,8 +44537,8 @@ ${releaseId}`;
44496
44537
  }
44497
44538
  }
44498
44539
  if (request.method !== "GET") return json3(405, { error: "method_not_allowed" });
44499
- if (path === "/__health") return json3(200, { ok: true });
44500
- const packageShare = /^\/p\/([a-f0-9]{64})$/.exec(path);
44540
+ if (path2 === "/__health") return json3(200, { ok: true });
44541
+ const packageShare = /^\/p\/([a-f0-9]{64})$/.exec(path2);
44501
44542
  if (packageShare) {
44502
44543
  const shareId = packageShare[1];
44503
44544
  const wantsMetadata = url.searchParams.get("metadata") === "1";
@@ -44526,7 +44567,7 @@ ${releaseId}`;
44526
44567
  }
44527
44568
  });
44528
44569
  }
44529
- if (path === "/v1/owner/instance") {
44570
+ if (path2 === "/v1/owner/instance") {
44530
44571
  if (opts.webwixBridge === false) return json3(503, { error: "webwix_bridge_disabled" });
44531
44572
  if (!webwixOwnerRungOn()) return json3(503, { error: "webwix_owner_disabled" });
44532
44573
  const msid = url.searchParams.get("msid") ?? "";
@@ -44542,7 +44583,7 @@ ${releaseId}`;
44542
44583
  return json3(403, { error: "webwix_owner_mint_failed" });
44543
44584
  }
44544
44585
  }
44545
- if (path === "/v1/owner/sites") {
44586
+ if (path2 === "/v1/owner/sites") {
44546
44587
  if (!webwixOwnerRungOn()) return json3(503, { error: "webwix_owner_disabled" });
44547
44588
  const cookie = request.headers.get("cookie") ?? "";
44548
44589
  if (!/wixSession2=/.test(cookie)) return json3(200, { sites: [] });
@@ -44556,7 +44597,7 @@ ${releaseId}`;
44556
44597
  }
44557
44598
  }
44558
44599
  const store = await getStore();
44559
- if (path === "/v1/apps") {
44600
+ if (path2 === "/v1/apps") {
44560
44601
  if (opts.authorizeList && !await opts.authorizeList(request)) {
44561
44602
  return json3(401, { error: "unauthorized" });
44562
44603
  }
@@ -44620,7 +44661,7 @@ ${releaseId}`;
44620
44661
  headers: { "content-type": JSON_CT, ...listHeaders }
44621
44662
  });
44622
44663
  }
44623
- if (path === "/v1/templates") {
44664
+ if (path2 === "/v1/templates") {
44624
44665
  if (opts.authorizeList && !await opts.authorizeList(request)) {
44625
44666
  return json3(401, { error: "unauthorized" });
44626
44667
  }
@@ -44653,9 +44694,10 @@ ${releaseId}`;
44653
44694
  templates.sort((a, b) => String(a.name).localeCompare(String(b.name)));
44654
44695
  return json3(200, { templates });
44655
44696
  }
44656
- const app = resolveApp(request, url);
44697
+ const cfgMatch = /^\/v1\/app-config\/([^/]+)$/.exec(path2);
44698
+ const app = cfgMatch?.[1] ?? resolveApp(request, url);
44657
44699
  const pin = resolvePin(request, url);
44658
- if (path === "/v1/template-source") {
44700
+ if (path2 === "/v1/template-source") {
44659
44701
  if (!app) return json3(400, { error: "missing_app" });
44660
44702
  if (!store.getSource) return json3(501, { error: "templates_unsupported" });
44661
44703
  const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
@@ -44675,12 +44717,12 @@ ${releaseId}`;
44675
44717
  const denied = await authorizePinnedRead(request, url, app, pin);
44676
44718
  if (denied) return denied;
44677
44719
  }
44678
- if (path === "/v1/authoring-docs" || /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.test(path)) {
44720
+ if (path2 === "/v1/authoring-docs" || /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.test(path2)) {
44679
44721
  if (!app) return json3(400, { error: "missing_app" });
44680
44722
  const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
44681
44723
  if (!m) return json3(404, { error: pin ? "release_not_found" : "no_release", app });
44682
44724
  const docs = m.authoringDocs ?? {};
44683
- const match = /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.exec(path);
44725
+ const match = /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.exec(path2);
44684
44726
  if (!match) {
44685
44727
  return json3(200, {
44686
44728
  app,
@@ -44708,7 +44750,7 @@ ${releaseId}`;
44708
44750
  }
44709
44751
  });
44710
44752
  }
44711
- if (path === "/v1/release/current") {
44753
+ if (path2 === "/v1/release/current") {
44712
44754
  if (pin) {
44713
44755
  const m2 = app ? await pinnedManifest(app, pin) : null;
44714
44756
  if (!m2) return json3(404, { error: "release_not_found", app, releaseId: pin });
@@ -44718,7 +44760,7 @@ ${releaseId}`;
44718
44760
  if (!m) return json3(404, { error: "no_release", app });
44719
44761
  return json3(200, { releaseId: m.releaseId, app: m.app, ...m.minBinaryVersion ? { minBinaryVersion: m.minBinaryVersion } : {}, ...m.playerRequirements ? { playerRequirements: m.playerRequirements } : {}, ...m.platforms ? { platforms: m.platforms } : {} });
44720
44762
  }
44721
- const bundleMatch = /^\/v1\/bundles\/([a-f0-9]{64})\.bundle\.js$/.exec(path);
44763
+ const bundleMatch = /^\/v1\/bundles\/([a-f0-9]{64})\.bundle\.js$/.exec(path2);
44722
44764
  if (bundleMatch) {
44723
44765
  const hash = bundleMatch[1];
44724
44766
  const m = app ? pin ? await pinnedManifest(app, pin) : await manifest(app) : null;
@@ -44735,7 +44777,7 @@ ${releaseId}`;
44735
44777
  }
44736
44778
  });
44737
44779
  }
44738
- if (path === "/v1/boot") {
44780
+ if (path2 === "/v1/boot") {
44739
44781
  if (!app) return json3(400, { error: "missing_app" });
44740
44782
  let m;
44741
44783
  if (pin) {
@@ -44804,7 +44846,7 @@ ${releaseId}`;
44804
44846
  }
44805
44847
  return json3(200, { releaseId: mm.releaseId, app, appConfig, tokens, homeScreenId, screen, homeBundle }, { etag, "cache-control": cache, ...vary });
44806
44848
  }
44807
- if (path === "/v1/tokens") {
44849
+ if (path2 === "/v1/tokens") {
44808
44850
  if (!app) return json3(400, { error: "missing_app" });
44809
44851
  if (pin) {
44810
44852
  const m = await pinnedManifest(app, pin);
@@ -44817,7 +44859,7 @@ ${releaseId}`;
44817
44859
  if (!bytes2) return json3(404, { error: "tokens_not_found", app });
44818
44860
  return sendDoc(request, bytes2);
44819
44861
  }
44820
- if (path === "/v1/l10n") {
44862
+ if (path2 === "/v1/l10n") {
44821
44863
  if (!app) return json3(400, { error: "missing_app" });
44822
44864
  const tag = (url.searchParams.get("tag") ?? "").trim();
44823
44865
  if (!/^[a-z]{2}(-[A-Za-z0-9]+)?$/.test(tag)) {
@@ -44832,7 +44874,7 @@ ${releaseId}`;
44832
44874
  if (!bytes2) return new Response(null, { status: 204 });
44833
44875
  return sendDoc(request, bytes2, Boolean(pin));
44834
44876
  }
44835
- if (path === "/v1/app-icon") {
44877
+ if (path2 === "/v1/app-icon") {
44836
44878
  if (!app) return json3(400, { error: "missing_app" });
44837
44879
  if (!store.getIcon) return json3(501, { error: "icons_unsupported" });
44838
44880
  const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
@@ -44849,7 +44891,7 @@ ${releaseId}`;
44849
44891
  headers: { "content-type": "image/png", etag, "cache-control": BUNDLE_CACHE_CONTROL, "x-himalaya-app": app }
44850
44892
  });
44851
44893
  }
44852
- const assetMatch = /^\/v1\/asset\/([^/?]+)$/.exec(path);
44894
+ const assetMatch = /^\/v1\/asset\/([^/?]+)$/.exec(path2);
44853
44895
  if (assetMatch) {
44854
44896
  if (!app) return json3(400, { error: "missing_app" });
44855
44897
  if (!store.getAsset) return json3(501, { error: "assets_unsupported" });
@@ -44878,7 +44920,7 @@ ${releaseId}`;
44878
44920
  }
44879
44921
  });
44880
44922
  }
44881
- const ahMatch = /^\/v1\/action-handlers\/([^/]+)$/.exec(path);
44923
+ const ahMatch = /^\/v1\/action-handlers\/([^/]+)$/.exec(path2);
44882
44924
  if (ahMatch) {
44883
44925
  const ahApp = ahMatch[1];
44884
44926
  const m = await manifest(ahApp);
@@ -44891,7 +44933,6 @@ ${releaseId}`;
44891
44933
  }));
44892
44934
  return json3(200, { handlers });
44893
44935
  }
44894
- const cfgMatch = /^\/v1\/app-config\/([^/]+)$/.exec(path);
44895
44936
  if (cfgMatch) {
44896
44937
  const cfgApp = cfgMatch[1];
44897
44938
  if (pin) {
@@ -44911,7 +44952,7 @@ ${releaseId}`;
44911
44952
  }
44912
44953
  return sendDoc(request, bytes2);
44913
44954
  }
44914
- const screenMatch = /^\/v1\/screen\/([^/]+)$/.exec(path);
44955
+ const screenMatch = /^\/v1\/screen\/([^/]+)$/.exec(path2);
44915
44956
  if (screenMatch) {
44916
44957
  const screenId = screenMatch[1];
44917
44958
  if (!app || !isSafeSegment(screenId)) return json3(404, { error: "screen_not_found", screenId });
@@ -44943,14 +44984,14 @@ ${releaseId}`;
44943
44984
  headers: { "content-type": JSON_CT, etag, "cache-control": DOC_CACHE_CONTROL, "x-himalaya-app": app }
44944
44985
  });
44945
44986
  }
44946
- if (path === "/v1/widgets") {
44987
+ if (path2 === "/v1/widgets") {
44947
44988
  if (!app) return json3(400, { error: "missing_app" });
44948
44989
  const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
44949
44990
  if (!m) return json3(404, { error: pin ? "release_not_found" : "no_release", app });
44950
44991
  const widgets = Object.entries(m.widgets ?? {}).map(([widgetId, meta]) => ({ widgetId, contentEtag: meta.contentEtag }));
44951
44992
  return json3(200, { widgets });
44952
44993
  }
44953
- const widgetMatch = /^\/v1\/widget\/([^/]+)$/.exec(path);
44994
+ const widgetMatch = /^\/v1\/widget\/([^/]+)$/.exec(path2);
44954
44995
  if (widgetMatch) {
44955
44996
  const widgetId = widgetMatch[1];
44956
44997
  if (!app || !isSafeSegment(widgetId)) return json3(404, { error: "widget_not_found", widgetId });
@@ -44980,7 +45021,12 @@ ${releaseId}`;
44980
45021
  if (request.method === "OPTIONS") {
44981
45022
  return new Response(null, { status: 204, headers: { ...corsHeaders(request), "content-length": "0" } });
44982
45023
  }
44983
- return withCors(request, await handle(request));
45024
+ const response = await handle(request);
45025
+ if (resolvePreviewToken(request, new URL(request.url))) {
45026
+ response.headers.set("cache-control", "private, no-store");
45027
+ response.headers.set("vary", "x-himalaya-preview-token, x-himalaya-release");
45028
+ }
45029
+ return withCors(request, response);
44984
45030
  };
44985
45031
  }
44986
45032
  var JSON_CT;
@@ -45151,25 +45197,25 @@ function makeRunHandler(opts) {
45151
45197
  });
45152
45198
  return async (request) => {
45153
45199
  const url = new URL(request.url);
45154
- const path = url.pathname;
45155
- if (path === "/v1/release/resolve") {
45200
+ const path2 = url.pathname;
45201
+ if (path2 === "/v1/release/resolve") {
45156
45202
  return json4(
45157
45203
  200,
45158
45204
  { app: opts.app, releaseId: opts.header?.releaseId ?? null, source: "local" },
45159
45205
  { "cache-control": "no-store" }
45160
45206
  );
45161
45207
  }
45162
- if (path === "/v1/revocations") {
45208
+ if (path2 === "/v1/revocations") {
45163
45209
  return json4(
45164
45210
  200,
45165
45211
  { app: opts.app, revokedIntegrities: [], version: 0, ttlSeconds: 30 },
45166
45212
  { "cache-control": "max-age=30" }
45167
45213
  );
45168
45214
  }
45169
- if (path.startsWith("/v1/flags/")) {
45215
+ if (path2.startsWith("/v1/flags/")) {
45170
45216
  return json4(200, { app: opts.app, definitions: {} }, { "cache-control": "no-store" });
45171
45217
  }
45172
- if (path === "/v1/telemetry/ingest") {
45218
+ if (path2 === "/v1/telemetry/ingest") {
45173
45219
  if (request.method !== "POST") return json4(405, { error: "method_not_allowed" });
45174
45220
  try {
45175
45221
  const body = await request.json();
@@ -45179,33 +45225,33 @@ function makeRunHandler(opts) {
45179
45225
  }
45180
45226
  return new Response(null, { status: 204 });
45181
45227
  }
45182
- if (path === "/v1/screen-events") {
45228
+ if (path2 === "/v1/screen-events") {
45183
45229
  return new Response(new ReadableStream({ start() {
45184
45230
  } }), {
45185
45231
  status: 200,
45186
45232
  headers: { "content-type": "text/event-stream", "cache-control": "no-store", connection: "keep-alive" }
45187
45233
  });
45188
45234
  }
45189
- if (path.startsWith("/v1/__webwix/") && path !== "/v1/__webwix/call" && path !== "/v1/__webwix/identity" && !(opts.serve?.webwixMemberAuth === true && opts.serve?.webwixMemberSessions)) {
45235
+ if (path2.startsWith("/v1/__webwix/") && path2 !== "/v1/__webwix/call" && path2 !== "/v1/__webwix/identity" && !(opts.serve?.webwixMemberAuth === true && opts.serve?.webwixMemberSessions)) {
45190
45236
  return json4(501, { error: "webwix_member_auth_unavailable" });
45191
45237
  }
45192
- if (path === "/v1/app-config" || path.startsWith("/v1/app-config/")) {
45238
+ if (path2 === "/v1/app-config" || path2.startsWith("/v1/app-config/")) {
45193
45239
  return localizeConfigResponse(await serve(request), "app-config", opts.header ?? null);
45194
45240
  }
45195
- if (path === "/v1/boot") {
45241
+ if (path2 === "/v1/boot") {
45196
45242
  return localizeConfigResponse(await serve(request), "boot", opts.header ?? null);
45197
45243
  }
45198
- if (path === "/v1" || path.startsWith("/v1/") || path === "/__health") {
45244
+ if (path2 === "/v1" || path2.startsWith("/v1/") || path2 === "/__health") {
45199
45245
  return serve(request);
45200
45246
  }
45201
- if (path === "/" || path === "") {
45247
+ if (path2 === "/" || path2 === "") {
45202
45248
  const target = `${mount}/a/${encodeURIComponent(opts.app)}${url.search}`;
45203
45249
  return new Response(null, { status: 302, headers: { location: target } });
45204
45250
  }
45205
- if (path === mount || path.startsWith(`${mount}/`)) {
45206
- return previewResponse(path, opts.assets, mount);
45251
+ if (path2 === mount || path2.startsWith(`${mount}/`)) {
45252
+ return previewResponse(path2, opts.assets, mount);
45207
45253
  }
45208
- return json4(404, { error: "not_found", path });
45254
+ return json4(404, { error: "not_found", path: path2 });
45209
45255
  };
45210
45256
  }
45211
45257
  var json4;
@@ -45414,9 +45460,9 @@ async function loadPreviewAssets() {
45414
45460
  join46(here, "../../../packages/serve/src/preview-assets.generated.bin")
45415
45461
  // in-repo checkout
45416
45462
  ];
45417
- for (const path of candidates) {
45418
- if (!existsSync49(path)) continue;
45419
- const blob = readFileSync54(path);
45463
+ for (const path2 of candidates) {
45464
+ if (!existsSync49(path2)) continue;
45465
+ const blob = readFileSync54(path2);
45420
45466
  return mod.assemblePreviewAssetsFromBlob(new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength));
45421
45467
  }
45422
45468
  return /* @__PURE__ */ new Map();
@@ -45426,9 +45472,9 @@ async function loadPreviewAssets() {
45426
45472
  }
45427
45473
  function packageUrl(origin, app, opts = {}) {
45428
45474
  const mount = opts.chrome === "app" ? "/app" : "/preview";
45429
- const path = `${mount}/a/${encodeURIComponent(app)}${opts.screen ? `/screen/${encodeURIComponent(opts.screen)}` : ""}`;
45475
+ const path2 = `${mount}/a/${encodeURIComponent(app)}${opts.screen ? `/screen/${encodeURIComponent(opts.screen)}` : ""}`;
45430
45476
  const query = opts.surface ? `?surface=${encodeURIComponent(opts.surface)}` : "";
45431
- return `${origin.replace(/\/$/, "")}${path}${query}`;
45477
+ return `${origin.replace(/\/$/, "")}${path2}${query}`;
45432
45478
  }
45433
45479
  function openBrowser(url) {
45434
45480
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
@@ -45588,13 +45634,13 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
45588
45634
  const body = JSON.stringify(payload);
45589
45635
  const missed = [];
45590
45636
  const server = createServer5((req, res) => {
45591
- const path = (req.url ?? "/").split("?")[0];
45592
- if (path === "/release.json") {
45637
+ const path2 = (req.url ?? "/").split("?")[0];
45638
+ if (path2 === "/release.json") {
45593
45639
  res.writeHead(200, { "content-type": "application/json", "cache-control": "no-store" });
45594
45640
  res.end(body);
45595
45641
  return;
45596
45642
  }
45597
- const name = path === "/" || path === "/index.html" ? "host.html" : path.slice(1);
45643
+ const name = path2 === "/" || path2 === "/index.html" ? "host.html" : path2.slice(1);
45598
45644
  if (SERVED.has(name)) {
45599
45645
  if (!existsSync50(resolve40(stagedDir(), name))) {
45600
45646
  const restaged = ensureBrowserPlaneStaged();
@@ -45621,9 +45667,9 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
45621
45667
  res.end(bytes2);
45622
45668
  return;
45623
45669
  }
45624
- missed.push(path);
45670
+ missed.push(path2);
45625
45671
  res.writeHead(404, { "content-type": "application/json" });
45626
- res.end(JSON.stringify({ error: "reached_the_cli_not_the_worker", path }));
45672
+ res.end(JSON.stringify({ error: "reached_the_cli_not_the_worker", path: path2 }));
45627
45673
  });
45628
45674
  await new Promise((r) => server.listen(opts.port ?? 0, "127.0.0.1", () => r()));
45629
45675
  const port = server.address().port;
@@ -46833,8 +46879,8 @@ function client(creds) {
46833
46879
  const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
46834
46880
  assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
46835
46881
  const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync61(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
46836
- return async (path) => {
46837
- const r = await fetch(`${ASC}${path}`, { headers: { Authorization: `Bearer ${jwt}` } });
46882
+ return async (path2) => {
46883
+ const r = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
46838
46884
  return { status: r.status, json: await r.json().catch(() => ({})) };
46839
46885
  };
46840
46886
  }
@@ -47094,24 +47140,24 @@ import { dirname as dirname29, join as join49 } from "node:path";
47094
47140
  function defaultSessionsPath() {
47095
47141
  return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join49(homedir6(), ".himalaya", "admin-sessions.json");
47096
47142
  }
47097
- function loadSessionsFile(path = defaultSessionsPath()) {
47143
+ function loadSessionsFile(path2 = defaultSessionsPath()) {
47098
47144
  try {
47099
- return JSON.parse(readFileSync63(path, "utf8"));
47145
+ return JSON.parse(readFileSync63(path2, "utf8"));
47100
47146
  } catch {
47101
47147
  return {};
47102
47148
  }
47103
47149
  }
47104
- function saveAdminSession(adminUrl, session, path = defaultSessionsPath()) {
47105
- const file = loadSessionsFile(path);
47150
+ function saveAdminSession(adminUrl, session, path2 = defaultSessionsPath()) {
47151
+ const file = loadSessionsFile(path2);
47106
47152
  file.sessions = { ...file.sessions, [adminUrl]: session };
47107
- mkdirSync24(dirname29(path), { recursive: true, mode: 448 });
47108
- writeFileSync21(path, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
47153
+ mkdirSync24(dirname29(path2), { recursive: true, mode: 448 });
47154
+ writeFileSync21(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
47109
47155
  try {
47110
- chmodSync3(dirname29(path), 448);
47111
- chmodSync3(path, 384);
47156
+ chmodSync3(dirname29(path2), 448);
47157
+ chmodSync3(path2, 384);
47112
47158
  } catch {
47113
47159
  }
47114
- return path;
47160
+ return path2;
47115
47161
  }
47116
47162
  function resolveAuth(opts = {}) {
47117
47163
  const env = opts.env ?? process.env;
@@ -47417,9 +47463,9 @@ var init_types2 = __esm({
47417
47463
  });
47418
47464
 
47419
47465
  // src/site-analyze/rest.ts
47420
- function resolveWixUrl(path) {
47421
- if (/^https?:\/\//i.test(path)) return path;
47422
- return `${WIX_API3}${path}`;
47466
+ function resolveWixUrl(path2) {
47467
+ if (/^https?:\/\//i.test(path2)) return path2;
47468
+ return `${WIX_API3}${path2}`;
47423
47469
  }
47424
47470
  function classifyHttp(status, count) {
47425
47471
  if (status === 428) return "not-installed";
@@ -47428,12 +47474,12 @@ function classifyHttp(status, count) {
47428
47474
  return count > 0 ? "ok" : "empty";
47429
47475
  }
47430
47476
  function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS4) {
47431
- return async (method, path, body) => {
47477
+ return async (method, path2, body) => {
47432
47478
  const headers2 = { Accept: "application/json" };
47433
47479
  if (auth?.token) headers2.Authorization = auth.token;
47434
47480
  if (auth?.msid) headers2["wix-site-id"] = auth.msid;
47435
47481
  if (body !== void 0) headers2["Content-Type"] = "application/json";
47436
- const res = await fetchImpl(resolveWixUrl(path), {
47482
+ const res = await fetchImpl(resolveWixUrl(path2), {
47437
47483
  method,
47438
47484
  headers: headers2,
47439
47485
  body: body === void 0 ? void 0 : JSON.stringify(body),
@@ -47445,7 +47491,7 @@ function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS4) {
47445
47491
  parsed = text4 ? JSON.parse(text4) : null;
47446
47492
  } catch {
47447
47493
  }
47448
- if (!res.ok) throw new WixApiError2(res.status, method, path, parsed);
47494
+ if (!res.ok) throw new WixApiError2(res.status, method, path2, parsed);
47449
47495
  return parsed;
47450
47496
  };
47451
47497
  }
@@ -47455,9 +47501,9 @@ function ownerTransportFrom(fetchImpl, owner) {
47455
47501
  function visitorTransportFrom(fetchImpl, token, msid) {
47456
47502
  return makeTransport(fetchImpl, { token, msid });
47457
47503
  }
47458
- async function probeCall(call, method, path, body) {
47504
+ async function probeCall(call, method, path2, body) {
47459
47505
  try {
47460
- return { data: await call(method, path, body), err: null };
47506
+ return { data: await call(method, path2, body), err: null };
47461
47507
  } catch (e) {
47462
47508
  if (e instanceof WixApiError2) return { data: null, err: e };
47463
47509
  throw e;
@@ -47519,11 +47565,11 @@ var init_rest = __esm({
47519
47565
  WIX_API3 = "https://www.wixapis.com";
47520
47566
  DEFAULT_TIMEOUT_MS4 = 8e3;
47521
47567
  WixApiError2 = class extends Error {
47522
- constructor(status, method, path, body) {
47523
- super(`${method} ${path} \u2192 ${status}`);
47568
+ constructor(status, method, path2, body) {
47569
+ super(`${method} ${path2} \u2192 ${status}`);
47524
47570
  this.status = status;
47525
47571
  this.method = method;
47526
- this.path = path;
47572
+ this.path = path2;
47527
47573
  this.body = body;
47528
47574
  this.name = "WixApiError";
47529
47575
  }
@@ -47731,8 +47777,8 @@ function toItems(def, raw) {
47731
47777
  description: copyOrDrop(def.descriptionOf ? def.descriptionOf(it) : genericDescription(it), 240) || void 0
47732
47778
  }));
47733
47779
  }
47734
- async function runDualProbes(owner, visitor) {
47735
- const rows = await Promise.all(ALL.map(async (def) => {
47780
+ async function runDualProbes(owner, visitor, definitions2 = ALL) {
47781
+ const rows = await Promise.all(definitions2.map(async (def) => {
47736
47782
  const [o, vis] = await Promise.all([side(owner, def), side(visitor, def)]);
47737
47783
  const imageless = def.imageOf ? o.items.filter((it) => !def.imageOf(it)).length : void 0;
47738
47784
  return {
@@ -47794,7 +47840,7 @@ function sampleTitle(data) {
47794
47840
  }
47795
47841
  return void 0;
47796
47842
  }
47797
- async function readCms(call) {
47843
+ async function readCms(call, opts = {}) {
47798
47844
  if (!call) return { collections: [], status: "skipped" };
47799
47845
  const { data, err } = await probeCall(call, "GET", "/data/v2/collections");
47800
47846
  if (err) {
@@ -47819,7 +47865,7 @@ async function readCms(call) {
47819
47865
  ...f.encrypted === true ? { encrypted: true } : {}
47820
47866
  })).filter((f) => f.key);
47821
47867
  const perms = c.permissions && typeof c.permissions === "object" ? c.permissions : void 0;
47822
- const q = await probeCall(call, "POST", "/wix-data/v2/items/query", {
47868
+ const q = opts.samples === false ? { data: null, err: null } : await probeCall(call, "POST", "/wix-data/v2/items/query", {
47823
47869
  dataCollectionId: id,
47824
47870
  query: { paging: { limit: 5 } }
47825
47871
  });
@@ -47856,8 +47902,8 @@ async function readInstalledApps(call) {
47856
47902
  "/site-apps/v1/apps",
47857
47903
  "/devcenter/v1/apps"
47858
47904
  ];
47859
- for (const path of paths) {
47860
- const { data } = await probeCall(call, "GET", path);
47905
+ for (const path2 of paths) {
47906
+ const { data } = await probeCall(call, "GET", path2);
47861
47907
  if (!data) continue;
47862
47908
  const raw = asArr(data.apps ?? data.siteApps ?? data.items);
47863
47909
  const apps = raw.map((a) => ({
@@ -47873,8 +47919,8 @@ async function readMemberRoles(call) {
47873
47919
  const paths = ["/members/v1/roles", "/members/v2/roles", "/authorization/v1/roles"];
47874
47920
  let sawAuthError = false;
47875
47921
  let sawEmptyPayload = false;
47876
- for (const path of paths) {
47877
- const { data, err } = await probeCall(call, "GET", path);
47922
+ for (const path2 of paths) {
47923
+ const { data, err } = await probeCall(call, "GET", path2);
47878
47924
  if (err) {
47879
47925
  if (err.status === 401 || err.status === 403 || err.status >= 500) sawAuthError = true;
47880
47926
  continue;
@@ -48345,15 +48391,15 @@ function pagePathForRole(url) {
48345
48391
  }
48346
48392
  }
48347
48393
  function classifyPageRole(url, title, _nav = "") {
48348
- const { path, isHome } = pagePathForRole(url);
48394
+ const { path: path2, isHome } = pagePathForRole(url);
48349
48395
  if (isHome) return "home";
48350
- const hay = `${path} ${title}`.toLowerCase();
48396
+ const hay = `${path2} ${title}`.toLowerCase();
48351
48397
  if (/\b(faq|help|support)\b/.test(hay)) return "faq";
48352
48398
  if (/\b(pricing|membership|member-plan|plans?)\b/.test(hay)) return "plans";
48353
48399
  if (/\b(drill|library|resource|session-builder|session-generator)\b/.test(hay)) return "library";
48354
48400
  if (/\b(members?|account|login|profile)\b/.test(hay) && !/\bmembership\b/.test(hay)) return "members";
48355
48401
  if (/\b(shop|store|product|cart)\b/.test(hay)) return "shop";
48356
- if (/(^|\/)(book|book-online|bookings?)(\/|$)/.test(path) || /\b(book-online|bookings?|appoint)\b/.test(hay)) return "book";
48402
+ if (/(^|\/)(book|book-online|bookings?)(\/|$)/.test(path2) || /\b(book-online|bookings?|appoint)\b/.test(hay)) return "book";
48357
48403
  if (/\b(menu|dining|restaurant)\b/.test(hay)) return "menu";
48358
48404
  if (/\b(blog|journal|news|posts?|ebooks?|insight)\b/.test(hay)) return "blog";
48359
48405
  if (/\b(about|story|our-story)\b/.test(hay)) return "about";
@@ -49007,12 +49053,12 @@ function veloListFilesPath(gridAppId, layout) {
49007
49053
  async function gridAppIdFromSiteHtml(fetchImpl, siteUrl) {
49008
49054
  return (await readPublishedHtml(fetchImpl, siteUrl)).gridAppId;
49009
49055
  }
49010
- function assertSafeVeloPath(path, method = "GET") {
49011
- if (VELO_INVOKE_RE.test(path)) {
49012
- throw new Error(`refusing to call Velo invoke path: ${path}`);
49056
+ function assertSafeVeloPath(path2, method = "GET") {
49057
+ if (VELO_INVOKE_RE.test(path2)) {
49058
+ throw new Error(`refusing to call Velo invoke path: ${path2}`);
49013
49059
  }
49014
- if (method !== "GET" && VELO_WRITE_RE.test(path.split("?")[0] ?? path)) {
49015
- throw new Error(`refusing to call Velo write path: ${method} ${path}`);
49060
+ if (method !== "GET" && VELO_WRITE_RE.test(path2.split("?")[0] ?? path2)) {
49061
+ throw new Error(`refusing to call Velo write path: ${method} ${path2}`);
49016
49062
  }
49017
49063
  }
49018
49064
  function parseHttpFunctions(source) {
@@ -49031,8 +49077,8 @@ function parseHttpFunctions(source) {
49031
49077
  }
49032
49078
  return out;
49033
49079
  }
49034
- function classifyVeloFile(path) {
49035
- const p = path.replace(/\\/g, "/").toLowerCase();
49080
+ function classifyVeloFile(path2) {
49081
+ const p = path2.replace(/\\/g, "/").toLowerCase();
49036
49082
  const base = p.split("/").pop() ?? p;
49037
49083
  if (base === "http-functions.js" || base === "http-functions.ts") return "http-functions";
49038
49084
  if (base === "data.js" || base === "data.ts") return "data-hooks";
@@ -49044,8 +49090,8 @@ function classifyVeloFile(path) {
49044
49090
  if (/(^|\/)public\//.test(p)) return "public";
49045
49091
  return "other";
49046
49092
  }
49047
- function isSecretVeloPath(path) {
49048
- const p = path.replace(/\\/g, "/").toLowerCase();
49093
+ function isSecretVeloPath(path2) {
49094
+ const p = path2.replace(/\\/g, "/").toLowerCase();
49049
49095
  return /secrets-backend|\/secrets\/|\.env(?:\.|$)/.test(p);
49050
49096
  }
49051
49097
  function redactSecrets(source) {
@@ -49075,7 +49121,7 @@ function str4(x) {
49075
49121
  function asArr2(x) {
49076
49122
  return Array.isArray(x) ? x : [];
49077
49123
  }
49078
- function filesFromOwnerPayload(data) {
49124
+ function filesFromOwnerPayload(data, redact = redactSecrets) {
49079
49125
  if (!data || typeof data !== "object") return [];
49080
49126
  const root = data;
49081
49127
  const raw = [
@@ -49087,17 +49133,17 @@ function filesFromOwnerPayload(data) {
49087
49133
  for (const item of raw) {
49088
49134
  if (!item || typeof item !== "object") continue;
49089
49135
  const f = item;
49090
- const path = str4(f.path || f.relativePath || f.fileName || f.name);
49091
- if (!path || isSecretVeloPath(path)) continue;
49136
+ const path2 = str4(f.path || f.relativePath || f.fileName || f.name);
49137
+ if (!path2 || isSecretVeloPath(path2)) continue;
49092
49138
  const content = str4(f.content ?? f.source ?? f.code ?? f.body);
49093
49139
  const bytes2 = typeof f.bytes === "number" ? f.bytes : typeof f.size === "number" ? f.size : content.length;
49094
- const redacted = content ? redactSecrets(content) : "";
49140
+ const redacted = content ? redact(content) : "";
49095
49141
  const forDisk = redacted.length > VELO_FILE_CAP ? redacted.slice(0, VELO_FILE_CAP) + "\n/* \u2026truncated */" : redacted;
49096
49142
  out.push({
49097
- path,
49098
- kind: classifyVeloFile(path),
49143
+ path: path2,
49144
+ kind: classifyVeloFile(path2),
49099
49145
  bytes: bytes2,
49100
- excerpt: content ? redactExcerpt(content) : void 0,
49146
+ excerpt: content ? redactExcerpt(redacted) : void 0,
49101
49147
  ...forDisk ? { content: forDisk } : {}
49102
49148
  });
49103
49149
  }
@@ -49140,8 +49186,8 @@ function veloHintFromEval(evaled, page) {
49140
49186
  pages: [{ url: page.url, title: page.title, hasCode: wixRendered && hasCode, ...pageId ? { pageId } : {} }]
49141
49187
  };
49142
49188
  }
49143
- function pageIdFromVeloPath(path) {
49144
- const m = path.replace(/\\/g, "/").match(/\/pages\/([A-Za-z0-9_-]+)\.(js|ts|jsx|tsx)$/i);
49189
+ function pageIdFromVeloPath(path2) {
49190
+ const m = path2.replace(/\\/g, "/").match(/\/pages\/([A-Za-z0-9_-]+)\.(js|ts|jsx|tsx)$/i);
49145
49191
  return m?.[1];
49146
49192
  }
49147
49193
  function bindVeloFiles(files, pages) {
@@ -49186,13 +49232,13 @@ function gridAppIdsFromPayload(data) {
49186
49232
  }
49187
49233
  return ids;
49188
49234
  }
49189
- async function listFilesForApp(call, gridAppId) {
49235
+ async function listFilesForApp(call, gridAppId, redact) {
49190
49236
  for (const layout of VELO_LAYOUTS) {
49191
- const path = veloListFilesPath(gridAppId, layout);
49192
- assertSafeVeloPath(path, "GET");
49193
- const { data } = await probeCall(call, "GET", path);
49237
+ const path2 = veloListFilesPath(gridAppId, layout);
49238
+ assertSafeVeloPath(path2, "GET");
49239
+ const { data } = await probeCall(call, "GET", path2);
49194
49240
  if (!data) continue;
49195
- const files = filesFromOwnerPayload(data);
49241
+ const files = filesFromOwnerPayload(data, redact);
49196
49242
  if (files.length) return files;
49197
49243
  }
49198
49244
  return [];
@@ -49214,7 +49260,7 @@ async function readOwnerVelo(call, opts) {
49214
49260
  if (probe.path.includes("git-repo") && (data.repo || data.repository || data.gitRepo || data.url)) git2 = true;
49215
49261
  }
49216
49262
  for (const id of ids) {
49217
- const listed = await listFilesForApp(call, id);
49263
+ const listed = await listFilesForApp(call, id, opts?.redact);
49218
49264
  for (const f of listed) {
49219
49265
  if (!files.some((x) => x.path === f.path)) files.push(f);
49220
49266
  }
@@ -49551,14 +49597,14 @@ function parseAuthorizationConfig(source) {
49551
49597
  const defaultAnonymousInvoke = invokeFlag(starDefault, "anonymous") ?? true;
49552
49598
  const defaultSiteMemberInvoke = invokeFlag(starDefault, "siteMember") ?? true;
49553
49599
  const modules = [];
49554
- for (const [path, entry] of Object.entries(web)) {
49555
- if (path === "*") continue;
49600
+ for (const [path2, entry] of Object.entries(web)) {
49601
+ if (path2 === "*") continue;
49556
49602
  const star = methodStar(entry);
49557
49603
  const anonymousInvoke = invokeFlag(star, "anonymous") ?? defaultAnonymousInvoke;
49558
49604
  const siteMemberInvoke = invokeFlag(star, "siteMember") ?? defaultSiteMemberInvoke;
49559
- const jsw = /\.(jsw|web\.js)$/i.test(path);
49605
+ const jsw = /\.(jsw|web\.js)$/i.test(path2);
49560
49606
  modules.push({
49561
- path,
49607
+ path: path2,
49562
49608
  anonymousInvoke,
49563
49609
  siteMemberInvoke,
49564
49610
  ...jsw ? { note: "worker-unreachable" } : {}
@@ -50697,12 +50743,12 @@ function attachVeloSources(book, sources, put) {
50697
50743
  }
50698
50744
  }
50699
50745
  function extOf2(url) {
50700
- const path = url.split("?")[0] ?? url;
50701
- if (/\.png$/i.test(path)) return "png";
50702
- if (/\.webp$/i.test(path)) return "webp";
50703
- if (/\.gif$/i.test(path)) return "gif";
50704
- if (/\.svg$/i.test(path)) return "svg";
50705
- if (/\.ico$/i.test(path)) return "ico";
50746
+ const path2 = url.split("?")[0] ?? url;
50747
+ if (/\.png$/i.test(path2)) return "png";
50748
+ if (/\.webp$/i.test(path2)) return "webp";
50749
+ if (/\.gif$/i.test(path2)) return "gif";
50750
+ if (/\.svg$/i.test(path2)) return "svg";
50751
+ if (/\.ico$/i.test(path2)) return "ico";
50706
50752
  return "jpg";
50707
50753
  }
50708
50754
  async function readCapped(res, cap) {
@@ -51273,8 +51319,8 @@ function unpairedRedirectNote(overlay) {
51273
51319
  function posix2(p) {
51274
51320
  return resolve42(p).replace(/\\/g, "/");
51275
51321
  }
51276
- function committedShellProvisioning(path) {
51277
- return committedShellFor(posix2(path));
51322
+ function committedShellProvisioning(path2) {
51323
+ return committedShellFor(posix2(path2));
51278
51324
  }
51279
51325
  function findRepoRoot(cwd) {
51280
51326
  let dir = cwd;
@@ -51298,14 +51344,14 @@ function deepMerge4(a, b) {
51298
51344
  }
51299
51345
  return out;
51300
51346
  }
51301
- function assertNotCommitted(path, forbidden) {
51302
- const committed = committedShellProvisioning(path);
51347
+ function assertNotCommitted(path2, forbidden) {
51348
+ const committed = committedShellProvisioning(path2);
51303
51349
  if (committed) {
51304
51350
  throw new Error(
51305
51351
  `refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
51306
51352
  );
51307
51353
  }
51308
- if (forbidden && resolve42(path) === resolve42(forbidden)) {
51354
+ if (forbidden && resolve42(path2) === resolve42(forbidden)) {
51309
51355
  const named = committedShellProvisioning(forbidden);
51310
51356
  throw new Error(
51311
51357
  `refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
@@ -51411,13 +51457,13 @@ function buildMergedContract(options) {
51411
51457
  merged.branding = branding;
51412
51458
  const body = `${JSON.stringify(merged, null, 2)}
51413
51459
  `;
51414
- const path = join51(packageDir, "provisioning.contract.json");
51415
- writeFileSync23(path, body);
51460
+ const path2 = join51(packageDir, "provisioning.contract.json");
51461
+ writeFileSync23(path2, body);
51416
51462
  const localPath = join51(appDir2, LOCAL_CONTRACT_REL);
51417
51463
  mkdirSync26(dirname30(localPath), { recursive: true });
51418
51464
  writeFileSync23(localPath, body);
51419
51465
  staged.push(localPath);
51420
- return { path, staged };
51466
+ return { path: path2, staged };
51421
51467
  }
51422
51468
  async function applyOverlays(input) {
51423
51469
  const cwd = resolve42(input.cwd);
@@ -52849,18 +52895,18 @@ function cookieCompare(a, b) {
52849
52895
  cmp = (a.creationIndex || 0) - (b.creationIndex || 0);
52850
52896
  return cmp;
52851
52897
  }
52852
- function defaultPath(path) {
52853
- if (!path || path.slice(0, 1) !== "/") {
52898
+ function defaultPath(path2) {
52899
+ if (!path2 || path2.slice(0, 1) !== "/") {
52854
52900
  return "/";
52855
52901
  }
52856
- if (path === "/") {
52857
- return path;
52902
+ if (path2 === "/") {
52903
+ return path2;
52858
52904
  }
52859
- const rightSlash = path.lastIndexOf("/");
52905
+ const rightSlash = path2.lastIndexOf("/");
52860
52906
  if (rightSlash === 0) {
52861
52907
  return "/";
52862
52908
  }
52863
- return path.slice(0, rightSlash);
52909
+ return path2.slice(0, rightSlash);
52864
52910
  }
52865
52911
  function domainMatch(domain, cookieDomain, canonicalize) {
52866
52912
  if (domain == null || cookieDomain == null) {
@@ -53088,18 +53134,18 @@ var init_dist = __esm({
53088
53134
  /**
53089
53135
  * @internal No doc because this is an overload that supports the implementation
53090
53136
  */
53091
- findCookie(domain, path, key2, callback) {
53137
+ findCookie(domain, path2, key2, callback) {
53092
53138
  const promiseCallback = createPromiseCallback(callback);
53093
- if (domain == null || path == null || key2 == null) {
53139
+ if (domain == null || path2 == null || key2 == null) {
53094
53140
  return promiseCallback.resolve(void 0);
53095
53141
  }
53096
- const result = this.idx[domain]?.[path]?.[key2];
53142
+ const result = this.idx[domain]?.[path2]?.[key2];
53097
53143
  return promiseCallback.resolve(result);
53098
53144
  }
53099
53145
  /**
53100
53146
  * @internal No doc because this is an overload that supports the implementation
53101
53147
  */
53102
- findCookies(domain, path, allowSpecialUseDomain = false, callback) {
53148
+ findCookies(domain, path2, allowSpecialUseDomain = false, callback) {
53103
53149
  if (typeof allowSpecialUseDomain === "function") {
53104
53150
  callback = allowSpecialUseDomain;
53105
53151
  allowSpecialUseDomain = true;
@@ -53110,7 +53156,7 @@ var init_dist = __esm({
53110
53156
  return promiseCallback.resolve([]);
53111
53157
  }
53112
53158
  let pathMatcher;
53113
- if (!path) {
53159
+ if (!path2) {
53114
53160
  pathMatcher = function matchAll(domainIndex) {
53115
53161
  for (const curPath in domainIndex) {
53116
53162
  const pathIndex = domainIndex[curPath];
@@ -53125,7 +53171,7 @@ var init_dist = __esm({
53125
53171
  } else {
53126
53172
  pathMatcher = function matchRFC(domainIndex) {
53127
53173
  for (const cookiePath in domainIndex) {
53128
- if (pathMatch(path, cookiePath)) {
53174
+ if (pathMatch(path2, cookiePath)) {
53129
53175
  const pathIndex = domainIndex[cookiePath];
53130
53176
  for (const key2 in pathIndex) {
53131
53177
  const value = pathIndex[key2];
@@ -53153,14 +53199,14 @@ var init_dist = __esm({
53153
53199
  */
53154
53200
  putCookie(cookie, callback) {
53155
53201
  const promiseCallback = createPromiseCallback(callback);
53156
- const { domain, path, key: key2 } = cookie;
53157
- if (domain == null || path == null || key2 == null) {
53202
+ const { domain, path: path2, key: key2 } = cookie;
53203
+ if (domain == null || path2 == null || key2 == null) {
53158
53204
  return promiseCallback.resolve(void 0);
53159
53205
  }
53160
53206
  const domainEntry = this.idx[domain] ?? /* @__PURE__ */ Object.create(null);
53161
53207
  this.idx[domain] = domainEntry;
53162
- const pathEntry = domainEntry[path] ?? /* @__PURE__ */ Object.create(null);
53163
- domainEntry[path] = pathEntry;
53208
+ const pathEntry = domainEntry[path2] ?? /* @__PURE__ */ Object.create(null);
53209
+ domainEntry[path2] = pathEntry;
53164
53210
  pathEntry[key2] = cookie;
53165
53211
  return promiseCallback.resolve(void 0);
53166
53212
  }
@@ -53174,20 +53220,20 @@ var init_dist = __esm({
53174
53220
  /**
53175
53221
  * @internal No doc because this is an overload that supports the implementation
53176
53222
  */
53177
- removeCookie(domain, path, key2, callback) {
53223
+ removeCookie(domain, path2, key2, callback) {
53178
53224
  const promiseCallback = createPromiseCallback(callback);
53179
- delete this.idx[domain]?.[path]?.[key2];
53225
+ delete this.idx[domain]?.[path2]?.[key2];
53180
53226
  return promiseCallback.resolve(void 0);
53181
53227
  }
53182
53228
  /**
53183
53229
  * @internal No doc because this is an overload that supports the implementation
53184
53230
  */
53185
- removeCookies(domain, path, callback) {
53231
+ removeCookies(domain, path2, callback) {
53186
53232
  const promiseCallback = createPromiseCallback(callback);
53187
53233
  const domainEntry = this.idx[domain];
53188
53234
  if (domainEntry) {
53189
- if (path) {
53190
- delete domainEntry[path];
53235
+ if (path2) {
53236
+ delete domainEntry[path2];
53191
53237
  } else {
53192
53238
  delete this.idx[domain];
53193
53239
  }
@@ -53213,8 +53259,8 @@ var init_dist = __esm({
53213
53259
  domains.forEach((domain) => {
53214
53260
  const domainEntry = idx[domain] ?? {};
53215
53261
  const paths = Object.keys(domainEntry);
53216
- paths.forEach((path) => {
53217
- const pathEntry = domainEntry[path] ?? {};
53262
+ paths.forEach((path2) => {
53263
+ const pathEntry = domainEntry[path2] ?? {};
53218
53264
  const keys = Object.keys(pathEntry);
53219
53265
  keys.forEach((key2) => {
53220
53266
  const keyEntry = pathEntry[key2];
@@ -53982,7 +54028,7 @@ var init_dist = __esm({
53982
54028
  return promiseCallback.reject(parameterError);
53983
54029
  }
53984
54030
  const host = canonicalDomain(context.hostname);
53985
- const path = context.pathname || "/";
54031
+ const path2 = context.pathname || "/";
53986
54032
  const potentiallyTrustworthy = isPotentiallyTrustworthy(
53987
54033
  url,
53988
54034
  this.allowSecureOnLocal
@@ -54013,7 +54059,7 @@ var init_dist = __esm({
54013
54059
  return false;
54014
54060
  }
54015
54061
  }
54016
- if (!allPaths && typeof c.path === "string" && !pathMatch(path, c.path)) {
54062
+ if (!allPaths && typeof c.path === "string" && !pathMatch(path2, c.path)) {
54017
54063
  return false;
54018
54064
  }
54019
54065
  if (c.secure && !potentiallyTrustworthy) {
@@ -54045,7 +54091,7 @@ var init_dist = __esm({
54045
54091
  }
54046
54092
  store.findCookies(
54047
54093
  host,
54048
- allPaths ? null : path,
54094
+ allPaths ? null : path2,
54049
54095
  this.allowSpecialUseDomain,
54050
54096
  (err, cookies) => {
54051
54097
  if (err) {
@@ -55423,9 +55469,9 @@ function filesFromList(data) {
55423
55469
  if (!Array.isArray(files)) return [];
55424
55470
  return files.flatMap((f) => {
55425
55471
  if (!f || typeof f !== "object") return [];
55426
- const path = String(f.path ?? "");
55472
+ const path2 = String(f.path ?? "");
55427
55473
  const content = String(f.content ?? "");
55428
- return path ? [{ path, content }] : [];
55474
+ return path2 ? [{ path: path2, content }] : [];
55429
55475
  });
55430
55476
  }
55431
55477
  async function resolveGridAppId(fetchImpl, token, msid, siteUrl) {
@@ -55852,14 +55898,14 @@ function apiKeyAuth(env = process.env) {
55852
55898
  return key2 && accountId ? { key: key2, accountId } : void 0;
55853
55899
  }
55854
55900
  function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, spawnImpl = spawn4) {
55855
- return async (method, path, body) => {
55901
+ return async (method, path2, body) => {
55856
55902
  const viaKey = apiKeyAuth();
55857
55903
  const headers2 = viaKey ? { Authorization: viaKey.key, "wix-account-id": viaKey.accountId, Accept: "application/json" } : { Authorization: await accountToken2(spawnImpl), Accept: "application/json" };
55858
55904
  if (body !== void 0) headers2["Content-Type"] = "application/json";
55859
55905
  const started = Date.now();
55860
55906
  let res;
55861
55907
  try {
55862
- res = await fetchImpl(`${API_BASE2}${path}`, {
55908
+ res = await fetchImpl(`${API_BASE2}${path2}`, {
55863
55909
  method,
55864
55910
  headers: headers2,
55865
55911
  body: body === void 0 ? void 0 : JSON.stringify(body),
@@ -55869,10 +55915,10 @@ function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, sp
55869
55915
  const err = e;
55870
55916
  if (err?.name === "TimeoutError" || /aborted due to timeout/i.test(err?.message ?? "")) {
55871
55917
  throw new Error(
55872
- `${method} ${path} timed out after ${Date.now() - started}ms (limit ${timeoutMs}ms). Raise the ceiling with HIMI_WIX_TIMEOUT_MS=<ms>, or check the VPN.`
55918
+ `${method} ${path2} timed out after ${Date.now() - started}ms (limit ${timeoutMs}ms). Raise the ceiling with HIMI_WIX_TIMEOUT_MS=<ms>, or check the VPN.`
55873
55919
  );
55874
55920
  }
55875
- throw new Error(`${method} ${path} failed: ${err?.message ?? String(e)}`);
55921
+ throw new Error(`${method} ${path2} failed: ${err?.message ?? String(e)}`);
55876
55922
  }
55877
55923
  const text4 = await res.text();
55878
55924
  let parsed = text4;
@@ -55880,7 +55926,7 @@ function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, sp
55880
55926
  parsed = text4 ? JSON.parse(text4) : null;
55881
55927
  } catch {
55882
55928
  }
55883
- if (!res.ok) throw new WixApiError(res.status, method, path, parsed);
55929
+ if (!res.ok) throw new WixApiError(res.status, method, path2, parsed);
55884
55930
  return parsed;
55885
55931
  };
55886
55932
  }
@@ -56159,27 +56205,27 @@ async function runSiteCreate(opts) {
56159
56205
  }
56160
56206
  function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync55, readFileSync: readFileSync66, writeFileSync: writeFileSync24 }) {
56161
56207
  const msid = binding2.siteId;
56162
- const path = resolvePath2(target);
56163
- const committed = committedShellProvisioning(path);
56208
+ const path2 = resolvePath2(target);
56209
+ const committed = committedShellProvisioning(path2);
56164
56210
  if (committed) {
56165
56211
  throw new Error(
56166
56212
  `refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 pass a content-package provisioning.json, or use \`prepare:customer --contract\``
56167
56213
  );
56168
56214
  }
56169
- if (!fs.existsSync(path)) {
56215
+ if (!fs.existsSync(path2)) {
56170
56216
  throw new Error(
56171
- `no provisioning.json at ${path}. --write-provisioning updates an EXISTING manifest (it needs identity/branding/installedVerticals, which this command cannot invent). Run it from a content package, or pass --write-provisioning <path>.`
56217
+ `no provisioning.json at ${path2}. --write-provisioning updates an EXISTING manifest (it needs identity/branding/installedVerticals, which this command cannot invent). Run it from a content package, or pass --write-provisioning <path>.`
56172
56218
  );
56173
56219
  }
56174
- const raw = fs.readFileSync(path, "utf8");
56220
+ const raw = fs.readFileSync(path2, "utf8");
56175
56221
  let manifest;
56176
56222
  try {
56177
56223
  manifest = JSON.parse(raw);
56178
56224
  } catch (e) {
56179
- throw new Error(`${path} is not valid JSON (${e?.message ?? e}) \u2014 not touching it`);
56225
+ throw new Error(`${path2} is not valid JSON (${e?.message ?? e}) \u2014 not touching it`);
56180
56226
  }
56181
56227
  if (manifest === null || typeof manifest !== "object" || Array.isArray(manifest)) {
56182
- throw new Error(`${path} must contain a JSON object \u2014 not touching it`);
56228
+ throw new Error(`${path2} must contain a JSON object \u2014 not touching it`);
56183
56229
  }
56184
56230
  if (binding2.siteUrl !== void 0) assertAbsoluteHttpUrl(binding2.siteUrl);
56185
56231
  if (binding2.redirectUri !== void 0) assertRedirectUri(binding2.redirectUri);
@@ -56197,9 +56243,9 @@ function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSyn
56197
56243
  const indentMatch = /^[ \t]*[{[][\r\n]+([ \t]+)/.exec(raw);
56198
56244
  const indent = indentMatch ? indentMatch[1] : " ";
56199
56245
  const trailingNewline = /\n$/.test(raw) ? "\n" : "";
56200
- fs.writeFileSync(path, `${JSON.stringify(manifest, null, indent)}${trailingNewline}`, "utf8");
56246
+ fs.writeFileSync(path2, `${JSON.stringify(manifest, null, indent)}${trailingNewline}`, "utf8");
56201
56247
  return {
56202
- path,
56248
+ path: path2,
56203
56249
  siteId: msid,
56204
56250
  ...binding2.clientId ? { clientId: binding2.clientId } : {},
56205
56251
  ...binding2.siteUrl ? { siteUrl: binding2.siteUrl } : {},
@@ -56488,9 +56534,350 @@ var init_site_oauth_client = __esm({
56488
56534
  }
56489
56535
  });
56490
56536
 
56537
+ // src/site-analyze/velo-source.ts
56538
+ import path from "node:path";
56539
+ import ts from "typescript";
56540
+ function applySourceEdits(source, edits) {
56541
+ const chunks = [];
56542
+ let cursor = 0;
56543
+ for (const edit of edits.sort((a, b) => a.start - b.start || b.end - a.end)) {
56544
+ if (edit.start < cursor) continue;
56545
+ chunks.push(source.slice(cursor, edit.start), edit.text);
56546
+ cursor = edit.end;
56547
+ }
56548
+ chunks.push(source.slice(cursor));
56549
+ return chunks.join("");
56550
+ }
56551
+ function redactVeloSource(source, knownSecrets = []) {
56552
+ for (const secret of knownSecrets.filter(Boolean)) source = source.split(secret).join(REDACTED2);
56553
+ source = source.replace(/-----BEGIN [^-]*PRIVATE KEY-----[\s\S]*?-----END [^-]*PRIVATE KEY-----/g, REDACTED2).replace(
56554
+ /\b(?:IST\.[\w.-]+|eyJ[\w-]+\.[\w-]+\.[\w-]+|(?:sk|rk)_(?:live|test)_[\w-]+|gh[pousr]_[\w]+|github_pat_[\w]+|AKIA[A-Z0-9]{16})\b/g,
56555
+ REDACTED2
56556
+ ).replace(/\b(?:Bearer|Basic)\s+[A-Za-z0-9._~+/=-]+/gi, REDACTED2).replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/'"`]+:[^\s/'"`]+@/gi, "$1[REDACTED]@").replace(/([?&](?:api[-_]?key|token|secret|password|signature)=)[^&#\s'"`]+/gi, "$1[REDACTED]");
56557
+ const parsed = ts.createSourceFile("backend.ts", source, ts.ScriptTarget.Latest, true);
56558
+ const comments = /* @__PURE__ */ new Map();
56559
+ const visitComments = (node) => {
56560
+ for (const range of [
56561
+ ...ts.getLeadingCommentRanges(source, node.pos) ?? [],
56562
+ ...ts.getTrailingCommentRanges(source, node.pos) ?? [],
56563
+ ...ts.getTrailingCommentRanges(source, node.end) ?? []
56564
+ ]) comments.set(range.pos, range.end);
56565
+ for (const child of node.getChildren(parsed)) visitComments(child);
56566
+ };
56567
+ visitComments(parsed);
56568
+ source = applySourceEdits(source, [...comments].map(([start, end]) => ({ start, end, text: " " })));
56569
+ const redactLiteral = (token, offset) => {
56570
+ const before = assignmentContext.slice(Math.max(0, offset - 200), offset);
56571
+ if (/^\s*:/.test(source.slice(offset + token.length)) && /[{,]\s*$/.test(before)) return token;
56572
+ const statement = before.slice(before.lastIndexOf(";") + 1);
56573
+ const sensitiveAssignment = [
56574
+ ...statement.matchAll(/([\w$-]+|"[^"\n]+"|'[^'\n]+')\s*(?:\]\s*)?[:=]/g)
56575
+ ].some((match) => sensitiveName.test(match[1]));
56576
+ const headerArgument = /(?:set|append)\s*\(\s*["']([^"']+)["']\s*,\s*$/.exec(before);
56577
+ if (sensitiveAssignment || sensitiveName.test(headerArgument?.[1] ?? ""))
56578
+ return JSON.stringify(REDACTED2);
56579
+ if (/^["'`][A-Za-z0-9_+/=-]{24,}["'`]$/.test(token)) return JSON.stringify(REDACTED2);
56580
+ return token;
56581
+ };
56582
+ const clean2 = ts.createSourceFile("backend.ts", source, ts.ScriptTarget.Latest, true);
56583
+ const masks = [];
56584
+ const collectMasks = (node) => {
56585
+ const start = node.getStart(clean2);
56586
+ if (ts.isRegularExpressionLiteral(node)) {
56587
+ masks.push({ start, end: node.end, text: " ".repeat(node.end - start) });
56588
+ } else if (ts.isStringLiteral(node) || ts.isTemplateLiteralToken(node)) {
56589
+ masks.push({ start, end: node.end, text: source.slice(start, node.end).replace(/;/g, " ") });
56590
+ }
56591
+ ts.forEachChild(node, collectMasks);
56592
+ };
56593
+ collectMasks(clean2);
56594
+ const assignmentContext = applySourceEdits(source, masks);
56595
+ const edits = [];
56596
+ const visitLiterals = (node) => {
56597
+ if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node) || ts.isTemplateExpression(node)) {
56598
+ const start = node.getStart(clean2);
56599
+ const text4 = source.slice(start, node.end);
56600
+ const redacted = redactLiteral(text4, start);
56601
+ if (redacted !== text4) {
56602
+ edits.push({ start, end: node.end, text: redacted });
56603
+ return;
56604
+ }
56605
+ }
56606
+ ts.forEachChild(node, visitLiterals);
56607
+ };
56608
+ visitLiterals(clean2);
56609
+ return applySourceEdits(source, edits);
56610
+ }
56611
+ function backendSourcePath(filename) {
56612
+ const normalized = filename.replace(/\\/g, "/").replace(/^\.\//, "");
56613
+ if (!/^(?:src\/)?backend\//.test(normalized) || normalized.split("/").includes("..")) return;
56614
+ if (/(?:secret|credential|\.env|\.pem|\.key|node_modules|__tests__|\.test\.|\.spec\.)/i.test(
56615
+ normalized
56616
+ ))
56617
+ return;
56618
+ return /\.(?:js|ts|jsw)$/.test(normalized) ? normalized : void 0;
56619
+ }
56620
+ function selectVeloSource(files, request, knownSecrets = []) {
56621
+ const candidates = files.flatMap((file) => {
56622
+ const normalized = backendSourcePath(file.path);
56623
+ return normalized && file.content.trim() ? [{ ...file, path: normalized }] : [];
56624
+ });
56625
+ const byPath = new Map(candidates.map((file) => [file.path, file]));
56626
+ const words = [...new Set(request.toLowerCase().match(/[a-z][a-z0-9_]{3,}/g) ?? [])].filter(
56627
+ (word) => !["with", "that", "this", "from", "have", "want", "app", "site", "backend"].includes(word)
56628
+ ).slice(0, 80);
56629
+ const score = (file) => {
56630
+ const names = file.path + " " + [...file.content.matchAll(/export\s+(?:async\s+)?(?:function|const)\s+(\w+)/g)].map((m) => m[1]).join(" ");
56631
+ return words.reduce((sum, word) => sum + (names.toLowerCase().includes(word) ? 10 : 0), 0) + (/http-functions\.[jt]s$|\.web\.[jt]s$|\.jsw$/.test(file.path) ? 1 : 0);
56632
+ };
56633
+ const queue = candidates.filter((file) => score(file) > 0).sort((a, b) => score(b) - score(a) || a.path.localeCompare(b.path));
56634
+ const selected = /* @__PURE__ */ new Map();
56635
+ let remaining = MAX_TOTAL_CHARS;
56636
+ while (queue.length && selected.size < MAX_FILES && remaining > 0) {
56637
+ const file = queue.shift();
56638
+ if (!file) break;
56639
+ if (selected.has(file.path)) continue;
56640
+ const redacted = redactVeloSource(file.content, knownSecrets);
56641
+ const excerpt = redacted.slice(0, Math.min(MAX_FILE_CHARS, remaining));
56642
+ selected.set(file.path, { source: excerpt, sourceTruncated: excerpt.length < redacted.length });
56643
+ remaining -= excerpt.length;
56644
+ const dependencies = [];
56645
+ const parsed = ts.createSourceFile(file.path, file.content, ts.ScriptTarget.Latest, true);
56646
+ const specifiers = [];
56647
+ const collectImports = (node) => {
56648
+ let specifier;
56649
+ if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
56650
+ specifier = node.moduleSpecifier;
56651
+ } else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference)) {
56652
+ specifier = node.moduleReference.expression;
56653
+ } else if (ts.isCallExpression(node) && (node.expression.kind === ts.SyntaxKind.ImportKeyword || ts.isIdentifier(node.expression) && node.expression.text === "require")) {
56654
+ specifier = node.arguments[0];
56655
+ }
56656
+ if (specifier && ts.isStringLiteralLike(specifier)) specifiers.push(specifier.text);
56657
+ ts.forEachChild(node, collectImports);
56658
+ };
56659
+ collectImports(parsed);
56660
+ for (const specifier of specifiers) {
56661
+ const target = specifier.startsWith(".") ? path.posix.join(path.posix.dirname(file.path), specifier) : specifier.startsWith("backend/") ? (file.path.startsWith("src/") ? "src/" : "") + specifier : "";
56662
+ const dependency = [
56663
+ target,
56664
+ target + ".js",
56665
+ target + ".ts",
56666
+ target + ".jsw",
56667
+ target + "/index.js",
56668
+ target + "/index.ts"
56669
+ ].map((name) => byPath.get(name)).find(Boolean);
56670
+ if (dependency) dependencies.push(dependency);
56671
+ }
56672
+ queue.unshift(...dependencies);
56673
+ }
56674
+ return selected;
56675
+ }
56676
+ var MAX_FILES, MAX_FILE_CHARS, MAX_TOTAL_CHARS, REDACTED2, sensitiveName;
56677
+ var init_velo_source = __esm({
56678
+ "src/site-analyze/velo-source.ts"() {
56679
+ MAX_FILES = 6;
56680
+ MAX_FILE_CHARS = 8e3;
56681
+ MAX_TOTAL_CHARS = 24e3;
56682
+ REDACTED2 = "[REDACTED]";
56683
+ sensitiveName = /(?:secret|password|passwd|token|authorization|cookie|api[-_]?key|private[-_]?key|access[-_]?key|credential)/i;
56684
+ }
56685
+ });
56686
+
56687
+ // src/site-analyze/context.ts
56688
+ var context_exports = {};
56689
+ __export(context_exports, {
56690
+ collectSiteContext: () => collectSiteContext,
56691
+ contextFetch: () => contextFetch
56692
+ });
56693
+ function contextFetch(fetchImpl, signal) {
56694
+ return async (input, init) => {
56695
+ const url = new URL(String(input));
56696
+ const method = init?.method ?? "GET";
56697
+ const apiRead = url.origin === "https://www.wixapis.com" && reads.has(`${method} ${url.pathname}`);
56698
+ const veloRead = url.origin === new URL(VELO_IDE_ORIGIN).origin && method === "GET" && /^\/_api\/wix-code-ide-server-ng\/v1\/apps\/[\w-]+\/files$/.test(url.pathname) && ["ONLINE", "GITHUB"].includes(url.searchParams.get("layout") ?? "");
56699
+ if (!apiRead && !veloRead || url.username || url.password) throw new Error("Not a site-analysis read");
56700
+ if (url.pathname === "/oauth2/token" && JSON.parse(String(init?.body)).grantType !== "anonymous") {
56701
+ throw new Error("Only anonymous visitor authentication is allowed");
56702
+ }
56703
+ const response = await fetchImpl(input, { ...init, redirect: "error", signal });
56704
+ const reader = response.body?.getReader();
56705
+ if (!reader) return response;
56706
+ const chunks = [];
56707
+ let size = 0;
56708
+ for (; ; ) {
56709
+ const chunk = await reader.read();
56710
+ if (chunk.done) break;
56711
+ size += chunk.value.byteLength;
56712
+ if (size > 2e6) {
56713
+ await reader.cancel();
56714
+ throw new Error("Site-analysis response exceeds 2 MB");
56715
+ }
56716
+ chunks.push(chunk.value);
56717
+ }
56718
+ return new Response(Buffer.concat(chunks), { status: response.status, headers: response.headers });
56719
+ };
56720
+ }
56721
+ async function collectSiteContext(opts) {
56722
+ const fetcher = contextFetch(opts.fetchImpl ?? fetch, AbortSignal.timeout(opts.timeoutMs ?? 15e3));
56723
+ const owner = opts.ownerToken ? makeTransport(fetcher, { token: opts.ownerToken, msid: opts.siteId }) : void 0;
56724
+ let visitorToken;
56725
+ let visitorAuth = { status: "skipped" };
56726
+ if (opts.clientId) {
56727
+ try {
56728
+ visitorToken = await mintVisitorToken(fetcher, opts.clientId);
56729
+ visitorAuth = { status: "ok" };
56730
+ } catch (e) {
56731
+ visitorAuth = failed(e);
56732
+ }
56733
+ }
56734
+ const visitor = visitorToken ? makeTransport(fetcher, { token: visitorToken, msid: opts.siteId }) : void 0;
56735
+ const identityRead = async () => {
56736
+ if (!owner) return { status: "skipped" };
56737
+ try {
56738
+ const identity2 = parseSiteProperties(await owner("GET", "/site-properties/v4/properties"), "");
56739
+ return { status: "ok", values: {
56740
+ businessName: identity2.businessName,
56741
+ siteDisplayName: identity2.siteDisplayName,
56742
+ description: identity2.description,
56743
+ logo: identity2.logoUrl,
56744
+ language: identity2.locale.languageCode,
56745
+ currency: identity2.locale.currency
56746
+ } };
56747
+ } catch (e) {
56748
+ return failed(e);
56749
+ }
56750
+ };
56751
+ const cmsRead = async () => {
56752
+ try {
56753
+ let failure;
56754
+ const observed = owner ? async (method, path2, body) => {
56755
+ try {
56756
+ const data = await owner(method, path2, body);
56757
+ if (!Array.isArray(data?.collections)) throw new Error("Malformed CMS inventory");
56758
+ return data;
56759
+ } catch (e) {
56760
+ const code = e instanceof WixApiError2 ? e.body?.details?.applicationError?.code : void 0;
56761
+ failure = code === "WDE0110" ? { status: "unavailable", httpStatus: 400 } : failed(e);
56762
+ throw e;
56763
+ }
56764
+ } : void 0;
56765
+ const cms2 = await readCms(observed, { samples: false });
56766
+ return { ...cms2, ...failure, collections: cms2.collections.map((c) => ({
56767
+ id: c.id,
56768
+ readRole: c.readRole,
56769
+ visitorReadable: c.readRole === "ANYONE",
56770
+ ownership: "existing"
56771
+ })) };
56772
+ } catch {
56773
+ return { status: "error", collections: [] };
56774
+ }
56775
+ };
56776
+ const veloRead = async () => {
56777
+ if (!owner) return { status: "skipped", files: [], sourceIncluded: false };
56778
+ let readFailure;
56779
+ const observed = async (method, path2, body) => {
56780
+ try {
56781
+ return await owner(method, path2, body);
56782
+ } catch (e) {
56783
+ readFailure = failed(e);
56784
+ throw e;
56785
+ }
56786
+ };
56787
+ try {
56788
+ const velo2 = await readOwnerVelo(observed, { redact: (source) => redactVeloSource(source, [opts.ownerToken ?? "", visitorToken ?? ""]) });
56789
+ const files = velo2.files.flatMap((f) => {
56790
+ const normalized = backendSourcePath(f.path);
56791
+ return normalized ? [{ ...f, path: normalized }] : [];
56792
+ });
56793
+ const selected = selectVeloSource(
56794
+ files.map((f) => ({ path: f.path, content: f.content ?? "" })),
56795
+ opts.request ?? "",
56796
+ [opts.ownerToken ?? "", visitorToken ?? ""]
56797
+ );
56798
+ return {
56799
+ ...files.length ? { status: "ok" } : readFailure ?? { status: "unavailable" },
56800
+ files: files.map((f) => ({
56801
+ path: f.path,
56802
+ kind: f.kind,
56803
+ exports: [...(f.content ?? "").matchAll(/export\s+(?:async\s+)?(?:function|const)\s+([A-Za-z_$][\w$]*)/g)].slice(0, 20).map((m) => m[1]),
56804
+ ...selected.get(f.path)
56805
+ })),
56806
+ sourceIncluded: selected.size > 0,
56807
+ truncated: files.length > selected.size || [...selected.values()].some((f) => f.sourceTruncated)
56808
+ };
56809
+ } catch (e) {
56810
+ return { ...failed(e), files: [], sourceIncluded: false };
56811
+ }
56812
+ };
56813
+ const [identity, cms, velo, probes] = await Promise.all([
56814
+ identityRead(),
56815
+ cmsRead(),
56816
+ veloRead(),
56817
+ runDualProbes(owner, visitor, definitions)
56818
+ ]);
56819
+ const probeRead = (p, available, auth) => {
56820
+ if (!available) return auth;
56821
+ if (p.httpStatus) return { ...failed(new WixApiError2(p.httpStatus, "", "", null)), count: p.count };
56822
+ return { status: p.status === "ok" || p.status === "empty" ? p.status : "error", count: p.count };
56823
+ };
56824
+ return {
56825
+ schemaVersion: 1,
56826
+ mode: "read-only",
56827
+ identity,
56828
+ cms,
56829
+ velo,
56830
+ verticals: probes.map((p) => ({
56831
+ name: p.vertical,
56832
+ owner: probeRead(p.owner, !!owner, { status: "skipped" }),
56833
+ visitor: probeRead(p.visitor, !!visitor, visitorAuth)
56834
+ }))
56835
+ };
56836
+ }
56837
+ var responseKeys, definitions, reads, failed;
56838
+ var init_context = __esm({
56839
+ "src/site-analyze/context.ts"() {
56840
+ init_probes();
56841
+ init_rest();
56842
+ init_site_properties();
56843
+ init_visitor_auth();
56844
+ init_velo();
56845
+ init_velo_source();
56846
+ responseKeys = {
56847
+ store: "products",
56848
+ bookings: "services",
56849
+ events: "events",
56850
+ blog: "posts"
56851
+ };
56852
+ definitions = [...CORE_PROBES, ...OPTIONAL_PROBES].filter((p) => p.vertical in responseKeys).map((p) => {
56853
+ const checked = (read, path2) => (data) => {
56854
+ const rows = path2 === "/catalog/v1/products/query" ? data.products ?? data.items : data[responseKeys[p.vertical]];
56855
+ if (!Array.isArray(rows)) throw new Error("Malformed catalog response");
56856
+ return read(data);
56857
+ };
56858
+ return {
56859
+ ...p,
56860
+ itemsOf: checked(p.itemsOf, p.path),
56861
+ fallbacks: p.fallbacks?.map((f) => ({ ...f, itemsOf: checked(f.itemsOf ?? p.itemsOf, f.path) }))
56862
+ };
56863
+ });
56864
+ reads = /* @__PURE__ */ new Set([
56865
+ "POST /oauth2/token",
56866
+ "GET /site-properties/v4/properties",
56867
+ "GET /data/v2/collections",
56868
+ ...OWNER_VELO_PROBES.map((p) => `${p.method} ${p.path}`),
56869
+ ...definitions.flatMap((p) => [p, ...p.fallbacks ?? []].map((a) => `${a.method} ${a.path}`))
56870
+ ]);
56871
+ failed = (e) => {
56872
+ const httpStatus = e instanceof WixApiError2 ? e.status : void 0;
56873
+ return { status: httpStatus === 401 ? "unauthorized" : httpStatus === 403 ? "forbidden" : httpStatus === 404 || httpStatus === 428 ? "unavailable" : "error", ...httpStatus ? { httpStatus } : {} };
56874
+ };
56875
+ }
56876
+ });
56877
+
56491
56878
  // src/cli.ts
56492
56879
  import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync67, mkdirSync as mkdirSync27, writeFileSync as writeFileSync25, existsSync as existsSync56, rmSync as rmSync10, readdirSync as readdirSync25, statSync as statSync13, lstatSync as lstatSync6, accessSync, constants } from "node:fs";
56493
- import { execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn5 } from "node:child_process";
56880
+ import { execFile as execFile4, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn5 } from "node:child_process";
56494
56881
  import { createHash as createHash24, randomUUID as randomUUID3 } from "node:crypto";
56495
56882
  import { tmpdir as tmpdir5, homedir as homedir7, hostname } from "node:os";
56496
56883
  import { join as join52, resolve as resolve44, relative as relative8, basename as basename12, dirname as dirname31 } from "node:path";
@@ -56520,11 +56907,11 @@ var ServeCliClient = class {
56520
56907
  if (!url) throw new Error(`no ${plane} URL configured for this target`);
56521
56908
  return url.replace(/\/+$/, "");
56522
56909
  }
56523
- async request(plane, method, path, opts = {}) {
56910
+ async request(plane, method, path2, opts = {}) {
56524
56911
  const headers2 = { ...opts.headers };
56525
56912
  if (opts.body !== void 0) headers2["content-type"] = "application/json";
56526
56913
  const carriesCredential = Object.keys(headers2).some((h2) => CREDENTIAL_HEADERS.has(h2.toLowerCase()));
56527
- const res = await this.fetchImpl(this.baseFor(plane) + path, {
56914
+ const res = await this.fetchImpl(this.baseFor(plane) + path2, {
56528
56915
  method,
56529
56916
  headers: headers2,
56530
56917
  ...carriesCredential ? { redirect: "error" } : {},
@@ -56737,12 +57124,12 @@ var ServeCliClient = class {
56737
57124
  if (o.since !== void 0) q.set("since", String(o.since));
56738
57125
  if (o.limit) q.set("limit", String(o.limit));
56739
57126
  if (o.crashesOnly) q.set("crashesOnly", "1");
56740
- const path = `/v1/telemetry/events?${q}`;
56741
- return this.request("telemetry", "GET", path, { headers: this.telHeaders() }).then(async (res) => {
57127
+ const path2 = `/v1/telemetry/events?${q}`;
57128
+ return this.request("telemetry", "GET", path2, { headers: this.telHeaders() }).then(async (res) => {
56742
57129
  if (res.status !== 404 || this.target.telemetry.replace(/\/+$/, "") === this.target.serve.replace(/\/+$/, "")) {
56743
57130
  return res;
56744
57131
  }
56745
- return this.request("serve", "GET", path, { headers: this.telHeaders() });
57132
+ return this.request("serve", "GET", path2, { headers: this.telHeaders() });
56746
57133
  });
56747
57134
  }
56748
57135
  /** Retained worker console lines (oldest first; `since` = seq cursor for tailing). */
@@ -56752,12 +57139,12 @@ var ServeCliClient = class {
56752
57139
  if (o.screenId) q.set("screen", o.screenId);
56753
57140
  if (o.since !== void 0) q.set("since", String(o.since));
56754
57141
  if (o.limit) q.set("limit", String(o.limit));
56755
- const path = `/v1/telemetry/logs?${q}`;
56756
- return this.request("telemetry", "GET", path, { headers: this.telHeaders() }).then(async (res) => {
57142
+ const path2 = `/v1/telemetry/logs?${q}`;
57143
+ return this.request("telemetry", "GET", path2, { headers: this.telHeaders() }).then(async (res) => {
56757
57144
  if (res.status !== 404 || this.target.telemetry.replace(/\/+$/, "") === this.target.serve.replace(/\/+$/, "")) {
56758
57145
  return res;
56759
57146
  }
56760
- return this.request("serve", "GET", path, { headers: this.telHeaders() });
57147
+ return this.request("serve", "GET", path2, { headers: this.telHeaders() });
56761
57148
  });
56762
57149
  }
56763
57150
  // ---- serve-control (publish / rollout / kill-switch — the mutable plane) ----
@@ -56815,8 +57202,8 @@ var ServeCliClient = class {
56815
57202
  }
56816
57203
  /** RFC 0012 release history: list the ledger (GET /v1/releases) or one manifest (…/{releaseId}). */
56817
57204
  releases(app, releaseId) {
56818
- const path = releaseId ? `/v1/releases/${encodeURIComponent(releaseId)}?app=${encodeURIComponent(app)}` : `/v1/releases?app=${encodeURIComponent(app)}`;
56819
- return this.request("control", "GET", path, { headers: this.ctrlHeaders() });
57205
+ const path2 = releaseId ? `/v1/releases/${encodeURIComponent(releaseId)}?app=${encodeURIComponent(app)}` : `/v1/releases?app=${encodeURIComponent(app)}`;
57206
+ return this.request("control", "GET", path2, { headers: this.ctrlHeaders() });
56820
57207
  }
56821
57208
  /** Select a published releaseId for a ring (POST /v1/admin/promote); optional rollout %. */
56822
57209
  promote(app, ring, releaseId, percent, force = false) {
@@ -57173,8 +57560,8 @@ var VALIDATION_METADATA = /* @__PURE__ */ new Set([
57173
57560
  ".claude/.validation-baseline.json",
57174
57561
  ".claude/.validation-evidence.json"
57175
57562
  ]);
57176
- function isValidationMetadata(path) {
57177
- return VALIDATION_METADATA.has(path) || /(^|[\\/])\.himi([\\/]|$)/.test(path);
57563
+ function isValidationMetadata(path2) {
57564
+ return VALIDATION_METADATA.has(path2) || /(^|[\\/])\.himi([\\/]|$)/.test(path2);
57178
57565
  }
57179
57566
  function tryGit(args, root) {
57180
57567
  try {
@@ -57190,10 +57577,10 @@ function committedRecords(raw) {
57190
57577
  const records = [];
57191
57578
  for (let i = 0; i < fields.length; i += 2) {
57192
57579
  const metadata2 = fields[i];
57193
- const path = fields[i + 1];
57194
- if (!metadata2.startsWith(":") || path === "") return null;
57195
- if (isValidationMetadata(path)) continue;
57196
- records.push(`${Buffer.byteLength(path)}:${path}\0${metadata2}\0`);
57580
+ const path2 = fields[i + 1];
57581
+ if (!metadata2.startsWith(":") || path2 === "") return null;
57582
+ if (isValidationMetadata(path2)) continue;
57583
+ records.push(`${Buffer.byteLength(path2)}:${path2}\0${metadata2}\0`);
57197
57584
  }
57198
57585
  return records.sort().join("");
57199
57586
  }
@@ -57253,12 +57640,12 @@ function validationDiffHash(cwd = process.cwd()) {
57253
57640
  trustFilesystemMode = git(["config", "--bool", "--get", "core.fileMode"], { cwd: root }).trim() !== "false";
57254
57641
  } catch {
57255
57642
  }
57256
- const paths = [.../* @__PURE__ */ new Set([...staged, ...unstaged, ...untracked])].filter((path) => !isValidationMetadata(path)).sort();
57257
- const identity = paths.map((path) => {
57258
- const absolute = resolve5(root, path);
57259
- const headEntry = headEntries.get(path);
57260
- const indexEntry = indexEntries.get(path);
57261
- const deletedRecord = () => [`${Buffer.byteLength(path)}:${path}`, "deleted", stagedIdentity(headEntry, indexEntry, void 0), ""].join("\0");
57643
+ const paths = [.../* @__PURE__ */ new Set([...staged, ...unstaged, ...untracked])].filter((path2) => !isValidationMetadata(path2)).sort();
57644
+ const identity = paths.map((path2) => {
57645
+ const absolute = resolve5(root, path2);
57646
+ const headEntry = headEntries.get(path2);
57647
+ const indexEntry = indexEntries.get(path2);
57648
+ const deletedRecord = () => [`${Buffer.byteLength(path2)}:${path2}`, "deleted", stagedIdentity(headEntry, indexEntry, void 0), ""].join("\0");
57262
57649
  let stat2;
57263
57650
  try {
57264
57651
  stat2 = lstatSync2(absolute);
@@ -57272,7 +57659,7 @@ function validationDiffHash(cwd = process.cwd()) {
57272
57659
  const worktreeEntry = { mode: "120000", oid: blobOid(target, objectAlgorithm) };
57273
57660
  const stagedState2 = stagedIdentity(headEntry, indexEntry, worktreeEntry);
57274
57661
  return [
57275
- `${Buffer.byteLength(path)}:${path}`,
57662
+ `${Buffer.byteLength(path2)}:${path2}`,
57276
57663
  "symlink",
57277
57664
  "120000",
57278
57665
  diffHash(target),
@@ -57283,11 +57670,11 @@ function validationDiffHash(cwd = process.cwd()) {
57283
57670
  if (stat2.isFile()) {
57284
57671
  const filesystemMode = stat2.mode & 73 ? "100755" : "100644";
57285
57672
  const worktreeMode = trustFilesystemMode ? filesystemMode : indexEntry?.mode ?? headEntry?.mode ?? "100644";
57286
- const worktreeOid = git(["hash-object", `--path=${path}`, "--", path], { cwd: root }).trim();
57673
+ const worktreeOid = git(["hash-object", `--path=${path2}`, "--", path2], { cwd: root }).trim();
57287
57674
  const worktreeEntry = { mode: worktreeMode, oid: worktreeOid };
57288
57675
  const stagedState2 = stagedIdentity(headEntry, indexEntry, worktreeEntry);
57289
57676
  return [
57290
- `${Buffer.byteLength(path)}:${path}`,
57677
+ `${Buffer.byteLength(path2)}:${path2}`,
57291
57678
  "file",
57292
57679
  worktreeMode,
57293
57680
  diffHash(readFileSync4(absolute)),
@@ -57306,7 +57693,7 @@ function validationDiffHash(cwd = process.cwd()) {
57306
57693
  const type = stat2.isDirectory() ? "directory" : "other";
57307
57694
  const stagedState = stagedIdentity(headEntry, indexEntry, void 0);
57308
57695
  return [
57309
- `${Buffer.byteLength(path)}:${path}`,
57696
+ `${Buffer.byteLength(path2)}:${path2}`,
57310
57697
  type,
57311
57698
  stat2.mode.toString(8),
57312
57699
  stagedState,
@@ -57413,7 +57800,7 @@ var SELF_TEST_CASES = [
57413
57800
  }
57414
57801
  ];
57415
57802
  function runSelfTest() {
57416
- let failed = 0;
57803
+ let failed2 = 0;
57417
57804
  for (const testCase of SELF_TEST_CASES) {
57418
57805
  let ok = false;
57419
57806
  let thrown = null;
@@ -57427,20 +57814,20 @@ function runSelfTest() {
57427
57814
  `);
57428
57815
  continue;
57429
57816
  }
57430
- failed++;
57817
+ failed2++;
57431
57818
  process.stderr.write(` \u2717 ${testCase.name}
57432
57819
  ${thrown ?? testCase.reason}
57433
57820
  `);
57434
57821
  }
57435
- return failed;
57822
+ return failed2;
57436
57823
  }
57437
57824
  if (process.argv[1] && basename(process.argv[1]) === "diff-hash.mjs" && import.meta.url === pathToFileURL(process.argv[1]).href) {
57438
57825
  if (process.argv.slice(2).includes("--self-test")) {
57439
57826
  process.stdout.write("\u25B8 diff-hash --self-test: proving the identity can change, and can hold\n");
57440
- const failed = runSelfTest();
57441
- if (failed) {
57827
+ const failed2 = runSelfTest();
57828
+ if (failed2) {
57442
57829
  process.stderr.write(
57443
- `\u2717 diff-hash self-test FAILED (${failed} case(s)) \u2014 the evidence record's diff identity cannot be trusted
57830
+ `\u2717 diff-hash self-test FAILED (${failed2} case(s)) \u2014 the evidence record's diff identity cannot be trusted
57444
57831
  `
57445
57832
  );
57446
57833
  process.exit(1);
@@ -57533,16 +57920,16 @@ function currentGitUntrackedHash(contentDir2) {
57533
57920
  maxBuffer: GIT_HASH_MAX_BUFFER
57534
57921
  });
57535
57922
  const hash = createHash3("sha256");
57536
- for (const path of listed.split("\0").filter(Boolean).sort()) {
57537
- const local = relative(absolute, join6(root, path));
57923
+ for (const path2 of listed.split("\0").filter(Boolean).sort()) {
57924
+ const local = relative(absolute, join6(root, path2));
57538
57925
  if (local.split(/[\\/]/)[0] === ".himi") continue;
57539
- const full = join6(root, path);
57926
+ const full = join6(root, path2);
57540
57927
  const stats = lstatSync3(full, { throwIfNoEntry: false });
57541
57928
  if (!stats) continue;
57542
57929
  const kind = stats.isSymbolicLink() ? "link" : stats.isDirectory() ? "dir" : stats.isFile() ? "file" : null;
57543
57930
  if (!kind) continue;
57544
57931
  const payload = kind === "link" ? Buffer.from(readlinkSync2(full)) : kind === "file" ? readFileSync5(full) : Buffer.alloc(0);
57545
- const pathBytes = Buffer.from(path);
57932
+ const pathBytes = Buffer.from(path2);
57546
57933
  hash.update(`${kind} ${pathBytes.length} ${payload.length}
57547
57934
  `).update(pathBytes).update(payload);
57548
57935
  }
@@ -57553,11 +57940,11 @@ function sourceTreeHash(root) {
57553
57940
  const visit = (dir) => {
57554
57941
  for (const entry of readdirSync3(dir, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
57555
57942
  if (entry.isDirectory() && [".git", ".himi", "node_modules"].includes(entry.name)) continue;
57556
- const path = join6(dir, entry.name);
57557
- const local = relative(root, path);
57558
- if (entry.isDirectory()) visit(path);
57559
- else if (entry.isFile()) hash.update(local).update("\0").update(readFileSync5(path)).update("\0");
57560
- else if (entry.isSymbolicLink()) hash.update(local).update("\0link\0").update(readlinkSync2(path)).update("\0");
57943
+ const path2 = join6(dir, entry.name);
57944
+ const local = relative(root, path2);
57945
+ if (entry.isDirectory()) visit(path2);
57946
+ else if (entry.isFile()) hash.update(local).update("\0").update(readFileSync5(path2)).update("\0");
57947
+ else if (entry.isSymbolicLink()) hash.update(local).update("\0link\0").update(readlinkSync2(path2)).update("\0");
57561
57948
  }
57562
57949
  };
57563
57950
  visit(root);
@@ -57605,9 +57992,9 @@ function readRetainedAttestations(contentDir2) {
57605
57992
  for (const run2 of parsedRuns) {
57606
57993
  if (selfHashFor(run2) !== run2.selfHash) errors.push(`selfHash does not match retained run ${run2.runId}`);
57607
57994
  for (const expected of Object.values(run2.screenshots)) {
57608
- const path = screenshotArtifactPath(contentDir2, expected);
57609
- if (!existsSync3(path)) errors.push(`missing screenshot for retained run ${run2.runId}: ${basename2(path)}`);
57610
- else if (sha256(readFileSync5(path)) !== expected) errors.push(`screenshot hash does not match retained run ${run2.runId}: ${basename2(path)}`);
57995
+ const path2 = screenshotArtifactPath(contentDir2, expected);
57996
+ if (!existsSync3(path2)) errors.push(`missing screenshot for retained run ${run2.runId}: ${basename2(path2)}`);
57997
+ else if (sha256(readFileSync5(path2)) !== expected) errors.push(`screenshot hash does not match retained run ${run2.runId}: ${basename2(path2)}`);
57611
57998
  }
57612
57999
  }
57613
58000
  const runs = [];
@@ -57668,8 +58055,8 @@ function writeAttestation(input, opts = {}) {
57668
58055
  const descriptorHashes = Object.fromEntries(
57669
58056
  Object.entries(input.descriptors).sort(([a], [b]) => a.localeCompare(b)).map(([screen, bytes2]) => [screen, sha256(bytes2)])
57670
58057
  );
57671
- const screenshotEntries = Object.entries(input.screenshots ?? {}).sort(([a], [b]) => a.localeCompare(b)).filter(([, path]) => existsSync3(path)).map(([screen, path]) => {
57672
- const bytes2 = readFileSync5(path);
58058
+ const screenshotEntries = Object.entries(input.screenshots ?? {}).sort(([a], [b]) => a.localeCompare(b)).filter(([, path2]) => existsSync3(path2)).map(([screen, path2]) => {
58059
+ const bytes2 = readFileSync5(path2);
57673
58060
  return { screen, bytes: bytes2, hash: sha256(bytes2) };
57674
58061
  });
57675
58062
  const screenshots = Object.fromEntries(screenshotEntries.map(({ screen, hash }) => [screen, hash]));
@@ -57796,12 +58183,12 @@ function verifyAttestation(attestation, contentDir2, descriptors, expectedApp, r
57796
58183
  if (sha256(bytes2) !== expected) errors.push(`descriptor hash does not match for ${screen}`);
57797
58184
  }
57798
58185
  for (const [screen, expected] of Object.entries(attestation.screenshots)) {
57799
- const path = screenshotArtifactPath(contentDir2, expected);
57800
- if (!existsSync3(path)) {
57801
- errors.push(`missing screenshot for ${screen}: ${basename2(path)}`);
58186
+ const path2 = screenshotArtifactPath(contentDir2, expected);
58187
+ if (!existsSync3(path2)) {
58188
+ errors.push(`missing screenshot for ${screen}: ${basename2(path2)}`);
57802
58189
  continue;
57803
58190
  }
57804
- if (sha256(readFileSync5(path)) !== expected) errors.push(`screenshot hash does not match for ${screen}: ${basename2(path)}`);
58191
+ if (sha256(readFileSync5(path2)) !== expected) errors.push(`screenshot hash does not match for ${screen}: ${basename2(path2)}`);
57805
58192
  }
57806
58193
  return { ok: errors.length === 0, errors };
57807
58194
  }
@@ -58128,9 +58515,9 @@ function dpxSessionTokenPath() {
58128
58515
  return process.env.HIMI_DPX_TOKEN ?? join7(homedir2(), ".dpx", "session", "token");
58129
58516
  }
58130
58517
  var DPX_SESSION_PORT = 5151;
58131
- function dpxSessionPresent(path = dpxSessionTokenPath()) {
58518
+ function dpxSessionPresent(path2 = dpxSessionTokenPath()) {
58132
58519
  try {
58133
- return existsSync4(path) && readFileSync6(path, "utf8").trim().length > 0;
58520
+ return existsSync4(path2) && readFileSync6(path2, "utf8").trim().length > 0;
58134
58521
  } catch {
58135
58522
  return false;
58136
58523
  }
@@ -58309,10 +58696,10 @@ async function listCollections(call) {
58309
58696
  let total;
58310
58697
  let reachedEnd = false;
58311
58698
  for (let page = 0; page < MAX_COLLECTION_PAGES; page++) {
58312
- const path = offset ? `/data/v2/collections?paging.offset=${offset}` : "/data/v2/collections";
58699
+ const path2 = offset ? `/data/v2/collections?paging.offset=${offset}` : "/data/v2/collections";
58313
58700
  const r = await withRetry(
58314
58701
  "list collections",
58315
- () => call("GET", path)
58702
+ () => call("GET", path2)
58316
58703
  );
58317
58704
  const batch = r.collections ?? [];
58318
58705
  const t = r.pagingMetadata?.total;
@@ -59302,9 +59689,9 @@ function storesV1Issues(contentDir2, strict) {
59302
59689
  const files = [];
59303
59690
  const visit = (dir) => {
59304
59691
  for (const entry of readdirSync10(dir, { withFileTypes: true })) {
59305
- const path = join23(dir, entry.name);
59306
- if (entry.isDirectory()) visit(path);
59307
- else if (/\.(?:[cm]?[jt]sx?)$/i.test(entry.name)) files.push(path);
59692
+ const path2 = join23(dir, entry.name);
59693
+ if (entry.isDirectory()) visit(path2);
59694
+ else if (/\.(?:[cm]?[jt]sx?)$/i.test(entry.name)) files.push(path2);
59308
59695
  }
59309
59696
  };
59310
59697
  roots.forEach(visit);
@@ -59328,12 +59715,12 @@ import { existsSync as existsSync22, readFileSync as readFileSync22, readdirSync
59328
59715
  import { join as join25, relative as relative4, resolve as resolve16 } from "node:path";
59329
59716
  var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".json"]);
59330
59717
  var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules", "dist", ".himi", "coverage"]);
59331
- function issue(issues, strict, code, message, path) {
59332
- issues.push({ code, message, ...path ? { path } : {}, severity: strict ? "error" : "warning" });
59718
+ function issue(issues, strict, code, message, path2) {
59719
+ issues.push({ code, message, ...path2 ? { path: path2 } : {}, severity: strict ? "error" : "warning" });
59333
59720
  }
59334
- function readText2(path) {
59721
+ function readText2(path2) {
59335
59722
  try {
59336
- return existsSync22(path) ? readFileSync22(path, "utf8") : null;
59723
+ return existsSync22(path2) ? readFileSync22(path2, "utf8") : null;
59337
59724
  } catch {
59338
59725
  return null;
59339
59726
  }
@@ -59643,6 +60030,7 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
59643
60030
  "json",
59644
60031
  "deep",
59645
60032
  "quiet",
60033
+ "read-only",
59646
60034
  "force",
59647
60035
  "replace",
59648
60036
  "watch",
@@ -59770,10 +60158,10 @@ var str5 = (v) => typeof v === "string" ? v : void 0;
59770
60158
  var num = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
59771
60159
  function embeddedTemplateCatalog() {
59772
60160
  return availableTemplates().map((name) => {
59773
- const path = join52(templateSourceDir(name), TEMPLATE_META_FILE);
59774
- const meta = JSON.parse(readFileSync67(path, "utf8"));
60161
+ const path2 = join52(templateSourceDir(name), TEMPLATE_META_FILE);
60162
+ const meta = JSON.parse(readFileSync67(path2, "utf8"));
59775
60163
  if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
59776
- throw new Error(`${path} must be { title: string, description: string, tags: string[], category?: string }`);
60164
+ throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
59777
60165
  }
59778
60166
  return { name, ...meta, source: "embedded" };
59779
60167
  });
@@ -60260,6 +60648,7 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
60260
60648
  also requires a MOBILE applicationType, because ensure
60261
60649
  refuses a WEB client \u2014 so a WEB one carrying your
60262
60650
  redirect looks right and is not a candidate.
60651
+ himi site analyze --read-only --site <msid> [--client-id <id>] [--json]
60263
60652
  himi site analyze --client-id <id> --url <https://\u2026> [--site <msid>] [--out <dir>] [--apply]
60264
60653
  [--shell ${SHELL_ENUM}]
60265
60654
  collect a Wix business book (APIs + Playwright look) and
@@ -60373,7 +60762,7 @@ var COMMANDS = [
60373
60762
  { name: "login", summary: "obtain a scoped serve-control token from Wix identity and store it in ~/.himalaya/serve-targets.json (so push/promote need no hand-pasted token). Three modes: --browser (your own Wix account, no VPN/BO), --wix (HEADLESS \u2014 the machine's own Wix CLI credential; the mode a CI pod or agent container can satisfy), --dpx (Wix employee, reads ~/.dpx/session/token). RFC 0026 WS3.", required: "[--browser|--wix|--dpx] [--target <t>] [--issue-url <url>]" },
60374
60763
  { name: "logout", summary: "remove the stored control token for a target", required: "[--target <t>]" },
60375
60764
  { name: "notify", summary: "`setup` optionally configures Branded/Ping from local customer key files; `status --refresh` reads live backend readiness. Setup may be deferred while building. These use serve-control and require owner plus Wix account authentication. `send`, `tokens`, `doctor`: send a REAL push notification to registered devices (RFC 0036 WS5) \u2014 APNs .p8 over HTTP/2 for iOS, FCM v1 for Android. `send` targets one device (--token / --device <registry id>) or fans out to the whole app (--all), reporting a per-device result; a token the provider says is uninstalled (APNs 410 Unregistered / FCM UNREGISTERED) is auto-disabled, while a merely wrong one (BadDeviceToken \u2014 usually a sandbox/production mismatch) is recorded and left enabled. `tokens` lists the registry. `doctor` reports which credentials resolve and which sender each platform picks. Talks to the admin-server via --admin-url/HIMALAYA_ADMIN_URL, authenticated with --admin-session/HIMALAYA_ADMIN_SESSION. NOT `himi push`, which publishes a release.", required: "setup|status [--content <dir>] [--target <t>] [--refresh] [--yes] [--no-push-setup] | send|tokens|doctor [--app <a>] [--token <t> | --device <id> | --all] [--title <s>] [--body <s>] [--link <url>] [--platform ios|android] [--badge <n>] [--channel <id>] [--silent] [--dry-run] [--json]" },
60376
- { name: "site", summary: "PROVISION a Wix project, then analyze or extend it. `create` is the one door that makes a site instead of adopting one: POST /funnel/projects/v1/create (a WIX site, a HEADLESS backend, a BRANDED_APP, or a VIBE site), and for headless it also mints the OAuth app whose id IS the `WIX_CLIENT_ID` \u2014 with --redirect-uri already registered, because an unregistered redirect makes native signInDirect fail at redirect-session. `--verticals` REQUIRES `--template` and reports only what Wix confirmed: measured, installing onto a project created from the BLANK template returns 200 while the vertical's API answers 428 forever, because there is no site for it to attach to (the install asks for CREATE_SITE). A real template ships its verticals installed and populated, and installing further ones onto it then works. It MUTATES your Wix account and needs --yes; without it you get the payload and nothing is sent. `list` is the read-only site inventory (with each site's premium flag, which is what explains an installed-but-428 vertical). Auth is the account-scoped `wix token` (no --site), falling back to WIX_API_KEY + WIX_ACCOUNT_ID. `client` is the same OAuth step for a site that ALREADY exists \u2014 the one himi adopts rather than makes \u2014 so a clientId no longer means a manual trip to the dashboard: `client ensure` reconciles rather than mints, because a site can already carry a client with NO registered redirect and shipping that one fails signInDirect at runtime; it reuses a client that carries --redirect-uri, PATCHes one that matches --name but lacks it (unioning, so another app's redirect survives), and creates only when there is nothing to reuse (--new forces a fresh one). --name IS the idempotency key. `client` auth is SITE-scoped (`wix token --site <msid>`) because minting is owner-of-that-site, and --yes gates every mutation: a site that already has a usable client resolves WITHOUT it, but --write-provisioning needs --yes even then because it rewrites a manifest on disk (the dry run's planned.provisioning names the file). That query endpoint IGNORES paging (measured: query.paging, cursorPaging and a top-level paging all return the full set at offset 0), so when pagingMetadata reports more clients than came back, `ensure` REFUSES EVERY outcome \u2014 create, patch AND reuse. Reuse is refused too because pickClient breaks ties on the OLDEST createdDate, so an omitted older same-named MOBILE client with the same redirect would win a later complete read and the resolved clientId would MOVE between runs \u2014 and it gets written into provisioning.json; convergence is what makes a stray duplicate untidy rather than harmful. --name cannot narrow the query (no filter is sent; the name is applied to the rows after they arrive), so the recovery is the dashboard; --new skips the query entirely. A `patched` result is verified against what Wix STORED \u2014 the redirect list is read off the PATCH response, and re-read via GET when the response omits it, because falling back to the list himi just sent would make the guard pass vacuously on exactly the silent no-op it exists to catch. `client list` is the read-only inventory of a site's clients: act on its `shippable` column rather than `hasRedirect`, because shippable ALSO requires a MOBILE applicationType and `ensure` refuses a WEB client \u2014 a WEB one carrying your redirect looks right and is not a candidate \u2014 and it sets truncated:true rather than presenting a partial inventory as the whole one. `analyze` reads a site into a business-book folder (REST + Playwright, GET-only); `site function` list/get/put/publish/invokes that site's Velo HTTP functions and is not `himi functions` (serve-plane jobs). `--apply` bakes into a brandable shell; `--shell` takes the same names `himi dist --shell` does and defaults to branded-lite, and a shell that ships no prepare:customer is refused by name rather than half-built. It never overwrites any shell's committed apps/<shell>/provisioning.json.", required: "create <name> [--type wix|headless|branded-app|vibe] [--template <guid>] [--verticals stores,bookings,\u2026] [--folder <guid>] [--redirect-uri <uri>] [--no-oauth-app] [--write-provisioning [path]] [--site-url <url>] [--json] --yes | list | client ensure|list --site <msid> [--name <name>] [--redirect-uri <uri>] [--new] [--write-provisioning [path]] [--site-url <url>] [--json] --yes | analyze --client-id <id> --url <https> [--site <msid>] [--out <dir>] [--redirect-uri <uri>] [--apply] [--shell " + SHELL_ENUM + "] | function list|get|put|publish|invoke [--site <msid>] [--url <https>] [--method GET|POST|PUT|DELETE] [--source <file>] [--body <json>] [--publish] [--invoke]" },
60765
+ { name: "site", summary: "PROVISION a Wix project, then analyze or extend it. `create` is the one door that makes a site instead of adopting one: POST /funnel/projects/v1/create (a WIX site, a HEADLESS backend, a BRANDED_APP, or a VIBE site), and for headless it also mints the OAuth app whose id IS the `WIX_CLIENT_ID` \u2014 with --redirect-uri already registered, because an unregistered redirect makes native signInDirect fail at redirect-session. `--verticals` REQUIRES `--template` and reports only what Wix confirmed: measured, installing onto a project created from the BLANK template returns 200 while the vertical's API answers 428 forever, because there is no site for it to attach to (the install asks for CREATE_SITE). A real template ships its verticals installed and populated, and installing further ones onto it then works. It MUTATES your Wix account and needs --yes; without it you get the payload and nothing is sent. `list` is the read-only site inventory (with each site's premium flag, which is what explains an installed-but-428 vertical). Auth is the account-scoped `wix token` (no --site), falling back to WIX_API_KEY + WIX_ACCOUNT_ID. `client` is the same OAuth step for a site that ALREADY exists \u2014 the one himi adopts rather than makes \u2014 so a clientId no longer means a manual trip to the dashboard: `client ensure` reconciles rather than mints, because a site can already carry a client with NO registered redirect and shipping that one fails signInDirect at runtime; it reuses a client that carries --redirect-uri, PATCHes one that matches --name but lacks it (unioning, so another app's redirect survives), and creates only when there is nothing to reuse (--new forces a fresh one). --name IS the idempotency key. `client` auth is SITE-scoped (`wix token --site <msid>`) because minting is owner-of-that-site, and --yes gates every mutation: a site that already has a usable client resolves WITHOUT it, but --write-provisioning needs --yes even then because it rewrites a manifest on disk (the dry run's planned.provisioning names the file). That query endpoint IGNORES paging (measured: query.paging, cursorPaging and a top-level paging all return the full set at offset 0), so when pagingMetadata reports more clients than came back, `ensure` REFUSES EVERY outcome \u2014 create, patch AND reuse. Reuse is refused too because pickClient breaks ties on the OLDEST createdDate, so an omitted older same-named MOBILE client with the same redirect would win a later complete read and the resolved clientId would MOVE between runs \u2014 and it gets written into provisioning.json; convergence is what makes a stray duplicate untidy rather than harmful. --name cannot narrow the query (no filter is sent; the name is applied to the rows after they arrive), so the recovery is the dashboard; --new skips the query entirely. A `patched` result is verified against what Wix STORED \u2014 the redirect list is read off the PATCH response, and re-read via GET when the response omits it, because falling back to the list himi just sent would make the guard pass vacuously on exactly the silent no-op it exists to catch. `client list` is the read-only inventory of a site's clients: act on its `shippable` column rather than `hasRedirect`, because shippable ALSO requires a MOBILE applicationType and `ensure` refuses a WEB client \u2014 a WEB one carrying your redirect looks right and is not a candidate \u2014 and it sets truncated:true rather than presenting a partial inventory as the whole one. `analyze --read-only` returns API-only generation context as JSON (identity, access probes, CMS permissions and selected redacted Velo source); it needs no URL/browser and never uploads or applies anything. `analyze` reads a site into a business-book folder (REST + Playwright, GET-only); `site function` list/get/put/publish/invokes that site's Velo HTTP functions and is not `himi functions` (serve-plane jobs). `--apply` bakes into a brandable shell; `--shell` takes the same names `himi dist --shell` does and defaults to branded-lite, and a shell that ships no prepare:customer is refused by name rather than half-built. It never overwrites any shell's committed apps/<shell>/provisioning.json.", required: "create <name> [--type wix|headless|branded-app|vibe] [--template <guid>] [--verticals stores,bookings,\u2026] [--folder <guid>] [--redirect-uri <uri>] [--no-oauth-app] [--write-provisioning [path]] [--site-url <url>] [--json] --yes | list | client ensure|list --site <msid> [--name <name>] [--redirect-uri <uri>] [--new] [--write-provisioning [path]] [--site-url <url>] [--json] --yes | analyze --read-only [--site <msid>] [--client-id <id>] [--json] | analyze --client-id <id> --url <https> [--site <msid>] [--out <dir>] [--redirect-uri <uri>] [--apply] [--shell " + SHELL_ENUM + "] | function list|get|put|publish|invoke [--site <msid>] [--url <https>] [--method GET|POST|PUT|DELETE] [--source <file>] [--body <json>] [--publish] [--invoke]" },
60377
60766
  { name: "doctor", summary: 'off-VPN preflight in one shot: probe the PUBLIC data plane (www.wixapis.com \u2014 reachable off-VPN), the INTERNAL serve/control plane for the selected target (VPN-gated), and report auth state (dpx session on disk + stored control token). --dpx additionally runs a live, EADDRINUSE-safe `dpx whoami`. Machine-readable with --json (an unreachable internal plane carries a stable code:"needs_vpn" so an agent branches on the code, not the prose); human-readable otherwise. Never loads the authoring runtime \u2014 works off-repo.', required: "[--target <t>] [--dpx] [--json] [--data-url <url>] [--timeout <ms>]" },
60378
60767
  { name: "upgrade", summary: "install the newest published CLI (`npm i -g @wix/himalaya-cli@latest`) and report what moved. This is the explicit door: himi also updates itself when the running build is more than a week old \u2014 unattended it just does it and re-runs your command, at a terminal it asks first \u2014 and `HIMI_NO_UPDATE_CHECK=1` turns that off, leaving this command as the way to catch up. Reports `unchanged` rather than claiming success when npm exits 0 without moving the version, which is what a registry mirror serving its own pinned copy looks like.", required: "[--json]" },
60379
60768
  { name: "push", summary: "lint + build + publish a release (default --draft: servable via ?release= but NOT live). REFUSES to publish on any error unless --force; --strict promotes warnings. Prints preview + agent-context links. The published slug is NAMESPACED per owner \u2014 `<ownerPrefix>.<name>`, composed offline from the control token's ownerPrefix claim, so the CLI and the server derive the identical string and himalaya.content.json is NOT rewritten (a legacy token with no ownerPrefix publishes the declared name unchanged). An app claimed BEFORE namespacing is stored under its FLAT slug, so the claim route answers `alreadyYours` naming that slug and the push adopts it \u2014 reported as `adoptedSlug`, since it is the one case where the published `app` differs from what the declared name composes to. `--no-claim` skips the route that knows this, so a pre-namespacing app pushed with it still fails 403. --visibility public|unlisted decides whether /v1/apps + the Himi Player picker LIST the app (also declarable as `visibility` in himalaya.content.json; omitted, a brand-new app defaults to unlisted \u2014 share by link \u2014 and an existing setting is kept). --account-id names which account owns the app when your Wix session resolves to several (the auto-claim of a brand-new slug cannot guess \u2014 without it a multi-account caller is told to name one). An unforced push of a release that carries SCREENS also refuses when `.himi/ux-audit.json` holds no mobile-UX drive recorded against that release id, or holds one that FAILED (#2955) \u2014 a published draft IS the owner-private preview a customer is handed; `himi ux record` clears it and `--force` overrides it, which the success envelope then says out loud. `--only <selector>` publishes ONLY the named items as a release derived from the app's live release (or `--from-release <id>`), running the identical build + lint gate and simply publishing less; it requires an explicit `--draft` or `--live` because a partial publish has no safe default, never claims a slug, and carries neither attestation nor a source archive (both named in the output). Selectors are comma-separated in ONE `--only`: `changed` (every item whose bytes differ from the base), `screen:<id|glob>`, `bundle:<name>`, `tokens`, `app-config` \u2014 a selected screen drags its logic bundle and a selected bundle drags the screens that reference it, or the bytes land under a key nothing reads.", required: "[--content <dir>] [--draft] [--live] [--force] [--strict] [--label] [--notes] [--visibility public|unlisted] [--no-claim] [--account-id <id>] [--only <selector>] [--from-release <id>] [--accept-regressions] [--accept-partial] [--app <slug>] (--control-token)" },
@@ -60442,30 +60831,48 @@ function trustedConfiguredRegistry(env) {
60442
60831
  const configured = normalizeRegistry(env.npm_config_registry ?? env.NPM_CONFIG_REGISTRY);
60443
60832
  return isTrustedRegistry(configured) ? configured : void 0;
60444
60833
  }
60445
- function createScopedRegistryResolver(exec = execFileSync7) {
60834
+ function createScopedRegistryResolver(exec = execNpmConfig) {
60446
60835
  let resolved2;
60447
- return () => {
60836
+ return async (budgetMs = SCOPED_REGISTRY_TIMEOUT_MS) => {
60448
60837
  if (resolved2) return resolved2.value;
60449
- let value;
60838
+ const deadline = Date.now() + Math.min(budgetMs, SCOPED_REGISTRY_TIMEOUT_MS);
60450
60839
  try {
60451
- const configured = (key2) => {
60452
- const raw = exec("npm", ["config", "get", key2], {
60453
- cwd: homedir7(),
60454
- timeout: 5e3,
60455
- stdio: ["ignore", "pipe", "ignore"]
60456
- }).toString().trim();
60840
+ const configured = async (key2) => {
60841
+ const timeout = deadline - Date.now();
60842
+ if (timeout <= 0) throw new Error("npm config: out of budget");
60843
+ const raw = String(await exec("npm", ["config", "get", key2], { cwd: homedir7(), timeout })).trim();
60457
60844
  return raw && raw !== "undefined" ? raw : void 0;
60458
60845
  };
60459
- const effective = normalizeRegistry(configured("@wix:registry") ?? configured("registry"));
60460
- value = isTrustedRegistry(effective) ? effective : void 0;
60846
+ const effective = normalizeRegistry(await configured("@wix:registry") ?? await configured("registry"));
60847
+ resolved2 = { value: isTrustedRegistry(effective) ? effective : void 0 };
60848
+ return resolved2.value;
60461
60849
  } catch {
60462
- value = void 0;
60850
+ return void 0;
60463
60851
  }
60464
- resolved2 = { value };
60465
- return value;
60466
60852
  };
60467
60853
  }
60854
+ var SCOPED_REGISTRY_TIMEOUT_MS = 5e3;
60855
+ function execNpmConfig(file, args, options) {
60856
+ return new Promise((resolve45, reject) => {
60857
+ execFile4(file, args, { ...options, windowsHide: true }, (error, stdout) => error ? reject(error) : resolve45(String(stdout)));
60858
+ });
60859
+ }
60468
60860
  var npmScopedWixRegistry = createScopedRegistryResolver();
60861
+ async function scopedRegistryBefore(lookup2, deadline) {
60862
+ let cancel = () => {
60863
+ };
60864
+ const expired = new Promise((resolve45) => {
60865
+ const timer = setTimeout(() => resolve45(void 0), Math.max(0, deadline - Date.now()));
60866
+ cancel = () => clearTimeout(timer);
60867
+ });
60868
+ try {
60869
+ return await Promise.race([Promise.resolve().then(() => lookup2(Math.max(0, deadline - Date.now()))), expired]);
60870
+ } catch {
60871
+ return void 0;
60872
+ } finally {
60873
+ cancel();
60874
+ }
60875
+ }
60469
60876
  function registryCandidates(env, scoped) {
60470
60877
  const ordered = [isTrustedRegistry(scoped) ? normalizeRegistry(scoped) : void 0, trustedConfiguredRegistry(env), PUBLIC_NPM_REGISTRY];
60471
60878
  return [...new Set(ordered.filter((r) => r !== void 0))];
@@ -60492,7 +60899,8 @@ async function fetchPackumentFrom(registry, fetchImpl, timeoutMs) {
60492
60899
  }
60493
60900
  async function fetchCliPackument(fetchImpl = fetch, timeoutMs = DOCTOR_TIMEOUT_MS, env = process.env, scopedRegistry = npmScopedWixRegistry) {
60494
60901
  const deadline = Date.now() + timeoutMs;
60495
- for (const registry of registryCandidates(env, scopedRegistry())) {
60902
+ const scoped = await scopedRegistryBefore(scopedRegistry, deadline);
60903
+ for (const registry of registryCandidates(env, scoped)) {
60496
60904
  const remaining = deadline - Date.now();
60497
60905
  if (remaining <= 0) break;
60498
60906
  const packument = await fetchPackumentFrom(registry, fetchImpl, remaining);
@@ -60506,9 +60914,9 @@ function ageInDays(publishedAt, now = Date.now()) {
60506
60914
  if (!Number.isFinite(at)) return void 0;
60507
60915
  return Math.max(0, (now - at) / 864e5);
60508
60916
  }
60509
- function packageVersion(path) {
60917
+ function packageVersion(path2) {
60510
60918
  try {
60511
- const version2 = JSON.parse(readFileSync67(path, "utf8")).version;
60919
+ const version2 = JSON.parse(readFileSync67(path2, "utf8")).version;
60512
60920
  return typeof version2 === "string" && version2 ? version2 : void 0;
60513
60921
  } catch {
60514
60922
  return void 0;
@@ -60576,18 +60984,18 @@ var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
60576
60984
  function updateCachePath(env = process.env) {
60577
60985
  return env.HIMI_UPDATE_CACHE_FILE ?? join52(homedir7(), ".himalaya", "update-check.json");
60578
60986
  }
60579
- function readUpdateCache(path) {
60987
+ function readUpdateCache(path2) {
60580
60988
  try {
60581
- const parsed = JSON.parse(readFileSync67(path, "utf8"));
60989
+ const parsed = JSON.parse(readFileSync67(path2, "utf8"));
60582
60990
  return parsed && typeof parsed === "object" ? parsed : {};
60583
60991
  } catch {
60584
60992
  return {};
60585
60993
  }
60586
60994
  }
60587
- function writeUpdateCache(path, cache) {
60995
+ function writeUpdateCache(path2, cache) {
60588
60996
  try {
60589
- mkdirSync27(dirname31(path), { recursive: true, mode: 448 });
60590
- writeFileSync25(path, JSON.stringify(cache, null, 2) + "\n", { mode: 384 });
60997
+ mkdirSync27(dirname31(path2), { recursive: true, mode: 448 });
60998
+ writeFileSync25(path2, JSON.stringify(cache, null, 2) + "\n", { mode: 384 });
60591
60999
  } catch {
60592
61000
  }
60593
61001
  }
@@ -60695,10 +61103,10 @@ function isAbandoned(content) {
60695
61103
  return Number.isFinite(owner) && owner > 0 && host === thisHost() && !processAlive(owner);
60696
61104
  }
60697
61105
  function staleUpdateLockFile(cachePath, now) {
60698
- for (const path of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
61106
+ for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
60699
61107
  let content;
60700
61108
  try {
60701
- content = readFileSync67(path, "utf8");
61109
+ content = readFileSync67(path2, "utf8");
60702
61110
  } catch {
60703
61111
  continue;
60704
61112
  }
@@ -60706,12 +61114,12 @@ function staleUpdateLockFile(cachePath, now) {
60706
61114
  let since = stamped;
60707
61115
  if (!Number.isFinite(since)) {
60708
61116
  try {
60709
- since = statSync13(path).mtimeMs;
61117
+ since = statSync13(path2).mtimeMs;
60710
61118
  } catch {
60711
61119
  continue;
60712
61120
  }
60713
61121
  }
60714
- if (now - since >= UPDATE_LOCK_REPORT_AFTER_MS) return path;
61122
+ if (now - since >= UPDATE_LOCK_REPORT_AFTER_MS) return path2;
60715
61123
  }
60716
61124
  return void 0;
60717
61125
  }
@@ -60719,24 +61127,24 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
60719
61127
  const lockPath = `${cachePath}.lock`;
60720
61128
  const breakPath = `${cachePath}.lock.break`;
60721
61129
  const mine = lockStamp(now);
60722
- const readLock = (path) => {
61130
+ const readLock = (path2) => {
60723
61131
  try {
60724
- return readFileSync67(path, "utf8");
61132
+ return readFileSync67(path2, "utf8");
60725
61133
  } catch {
60726
61134
  return void 0;
60727
61135
  }
60728
61136
  };
60729
- const tryCreate = (path) => {
61137
+ const tryCreate = (path2) => {
60730
61138
  try {
60731
- writeFileSync25(path, mine, { flag: "wx", mode: 384 });
61139
+ writeFileSync25(path2, mine, { flag: "wx", mode: 384 });
60732
61140
  return true;
60733
61141
  } catch {
60734
61142
  return false;
60735
61143
  }
60736
61144
  };
60737
- const removeIfMine = (path) => {
61145
+ const removeIfMine = (path2) => {
60738
61146
  try {
60739
- if (readLock(path) === mine) rmSync10(path, { force: true });
61147
+ if (readLock(path2) === mine) rmSync10(path2, { force: true });
60740
61148
  } catch {
60741
61149
  }
60742
61150
  };
@@ -60790,8 +61198,10 @@ async function refreshUpdateCache(opts = {}) {
60790
61198
  const packument = await fetchCliPackument(opts.fetchImpl ?? fetch, UPDATE_BACKGROUND_BUDGET_MS, env, opts.scopedRegistry);
60791
61199
  if (!packument) return false;
60792
61200
  const now = opts.now ?? Date.now();
61201
+ const current = readUpdateCache(cachePath);
61202
+ if (supersededInCache(current, packument.latest, now)) return true;
60793
61203
  writeUpdateCache(cachePath, {
60794
- ...readUpdateCache(cachePath),
61204
+ ...current,
60795
61205
  running,
60796
61206
  latest: packument.latest,
60797
61207
  runningPublishedAt: packument.time[running],
@@ -60799,6 +61209,11 @@ async function refreshUpdateCache(opts = {}) {
60799
61209
  });
60800
61210
  return true;
60801
61211
  }
61212
+ function supersededInCache(current, latest, now) {
61213
+ if (!current.latest || !latest || compareVersions2(latest, current.latest) >= 0) return false;
61214
+ const checkedAt = current.checkedAt ? Date.parse(current.checkedAt) : Number.NaN;
61215
+ return Number.isFinite(checkedAt) && now - checkedAt < UPDATE_CHECK_INTERVAL_MS;
61216
+ }
60802
61217
  function createUpdateRefreshSpawner(spawnFn = spawn5, execArgv = process.execArgv) {
60803
61218
  return () => {
60804
61219
  try {
@@ -60957,9 +61372,9 @@ function helpJson() {
60957
61372
  }
60958
61373
  function previewWebUrl(serveBase, app, release, screenId, surface, previewToken, handover) {
60959
61374
  const base = serveBase.replace(/\/$/, "");
60960
- const path = screenId ? `/preview/a/${app}/screen/${screenId}` : `/preview/a/${app}`;
61375
+ const path2 = screenId ? `/preview/a/${app}/screen/${screenId}` : `/preview/a/${app}`;
60961
61376
  const query = handover ? `?h=${encodeURIComponent(handover)}` : `?release=${encodeURIComponent(release)}`;
60962
- return `${base}${path}${query}${surface ? `&surface=${encodeURIComponent(surface)}` : ""}${!handover && previewToken ? `&pvt=${encodeURIComponent(previewToken)}` : ""}`;
61377
+ return `${base}${path2}${query}${surface ? `&surface=${encodeURIComponent(surface)}` : ""}${!handover && previewToken ? `&pvt=${encodeURIComponent(previewToken)}` : ""}`;
60963
61378
  }
60964
61379
  function renderDeviceWidths() {
60965
61380
  return {
@@ -61380,10 +61795,10 @@ function readConfigSource(dir) {
61380
61795
  return null;
61381
61796
  }
61382
61797
  }
61383
- function writePngFile(path, base64) {
61384
- mkdirSync27(dirname31(path), { recursive: true });
61385
- writeFileSync25(path, Buffer.from(base64, "base64"));
61386
- return path;
61798
+ function writePngFile(path2, base64) {
61799
+ mkdirSync27(dirname31(path2), { recursive: true });
61800
+ writeFileSync25(path2, Buffer.from(base64, "base64"));
61801
+ return path2;
61387
61802
  }
61388
61803
  async function initFromRemoteTemplate(name, parentDir, template, c) {
61389
61804
  const dir = resolve44(parentDir, name);
@@ -61577,9 +61992,9 @@ async function loadCms(dir) {
61577
61992
  return data ? { collections: data.collections ?? [], ...data.memberGated ? { memberGated: true } : {} } : void 0;
61578
61993
  }
61579
61994
  var ConfigLoadError = class extends Error {
61580
- constructor(path, cause) {
61581
- super(`could not load ${path}: ${cause.message}`);
61582
- this.path = path;
61995
+ constructor(path2, cause) {
61996
+ super(`could not load ${path2}: ${cause.message}`);
61997
+ this.path = path2;
61583
61998
  this.cause = cause;
61584
61999
  this.name = "ConfigLoadError";
61585
62000
  }
@@ -62553,17 +62968,17 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
62553
62968
  const dir = contentDir(flags);
62554
62969
  const { buildContentBundles: buildContentBundles2 } = await loadAuthoring();
62555
62970
  const res = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
62556
- const failed = res.compileErrors;
62971
+ const failed2 = res.compileErrors;
62557
62972
  print({
62558
- ok: failed.length === 0,
62973
+ ok: failed2.length === 0,
62559
62974
  outDir: res.outDir,
62560
62975
  built: res.built,
62561
- ...failed.length ? { compileErrors: failed } : {},
62976
+ ...failed2.length ? { compileErrors: failed2 } : {},
62562
62977
  // #642.1b — a stale @wix/himalaya is advisory on `build` (the bundles may
62563
62978
  // still compile); `validate --strict` is where it hard-fails.
62564
62979
  ...res.sdkVersionIssue ? { warnings: [res.sdkVersionIssue] } : {}
62565
62980
  });
62566
- return failed.length ? 1 : 0;
62981
+ return failed2.length ? 1 : 0;
62567
62982
  }
62568
62983
  case "eject": {
62569
62984
  const mod = String(pos[1] ?? "");
@@ -62644,12 +63059,12 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
62644
63059
  const { buildLocalFunctions: buildLocalFunctions2, describeFunction: describeFunction2, invokeLocalFunction: invokeLocalFunction2, invokeRemoteFunction: invokeRemoteFunction2, listFunctions: listFunctions2, loadFunctionsApp: loadFunctionsApp2, openApiForFunctions: openApiForFunctions2, resolveFunctionsTarget: resolveFunctionsTarget2, runRemoteFunctionOperation: runRemoteFunctionOperation2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
62645
63060
  const remoteTarget = str5(flags.target);
62646
63061
  const boCookie = () => {
62647
- const path = dpxSessionTokenPath();
63062
+ const path2 = dpxSessionTokenPath();
62648
63063
  let raw;
62649
63064
  try {
62650
- raw = readFileSync67(path, "utf8");
63065
+ raw = readFileSync67(path2, "utf8");
62651
63066
  } catch {
62652
- throw new Error(`no DPX BO session at ${path}; run dpx auth login, write dpx auth token to that path, then himi login --dpx --target bo`);
63067
+ throw new Error(`no DPX BO session at ${path2}; run dpx auth login, write dpx auth token to that path, then himi login --dpx --target bo`);
62653
63068
  }
62654
63069
  return dpxCookieHeader(raw);
62655
63070
  };
@@ -63119,7 +63534,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63119
63534
  bootAndSnapshotState: bootAndSnapshotState2,
63120
63535
  renderDescriptorWeb: renderDescriptorWeb2,
63121
63536
  renderPngBatch: renderPngBatch2,
63122
- writePng: (path, base64) => writePngFile(path, base64),
63537
+ writePng: (path2, base64) => writePngFile(path2, base64),
63123
63538
  clearDir: (d) => rmSync10(d, { recursive: true, force: true })
63124
63539
  }
63125
63540
  });
@@ -65619,7 +66034,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
65619
66034
  const { iosProjectYml: iosYmlPath, hasRepoCheckout: hasRepoCheckout2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
65620
66035
  const { ascStatus: ascStatus2 } = await Promise.resolve().then(() => (init_asc_status(), asc_status_exports));
65621
66036
  const { readFileSync: rf, readdirSync: rd, existsSync: ex, statSync: st } = await import("node:fs");
65622
- const { execFile: execFile4 } = await import("node:child_process");
66037
+ const { execFile: execFile5 } = await import("node:child_process");
65623
66038
  const { homedir: hd } = await import("node:os");
65624
66039
  const { join: pj, dirname: pd } = await import("node:path");
65625
66040
  const { fileURLToPath: f2p } = await import("node:url");
@@ -65634,7 +66049,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
65634
66049
  return ipas[0];
65635
66050
  };
65636
66051
  const sh = (cmd, args, opts) => new Promise((res) => {
65637
- const child = execFile4(
66052
+ const child = execFile5(
65638
66053
  cmd,
65639
66054
  args,
65640
66055
  { cwd: opts.cwd, env: { ...process.env, ...opts.env }, maxBuffer: 64 * 1024 * 1024 },
@@ -66405,7 +66820,7 @@ ${label2}`);
66405
66820
  try {
66406
66821
  const scoped = up.scopedRegistry ?? npmScopedWixRegistry;
66407
66822
  const answered = await fetchCliPackument(up.fetchImpl ?? fetch, UPDATE_EXPLICIT_BUDGET_MS, env, scoped);
66408
- const registry = answered?.registry ?? registryCandidates(env, scoped())[0];
66823
+ const registry = answered?.registry ?? registryCandidates(env, await scoped(UPDATE_EXPLICIT_BUDGET_MS))[0];
66409
66824
  if (answered?.latest && compareVersions2(answered.latest, before) <= 0) {
66410
66825
  if (flags.json) print({ ok: true, running: before, installed: before, changed: false, registry, latest: answered.latest });
66411
66826
  else io.log(`himi ${before} (unchanged \u2014 ${registry} has nothing newer; its latest is ${answered.latest})`);
@@ -66554,12 +66969,12 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
66554
66969
  return 1;
66555
66970
  }
66556
66971
  if (secretTarget.mode === "remote") {
66557
- const path = dpxSessionTokenPath();
66972
+ const path2 = dpxSessionTokenPath();
66558
66973
  let raw;
66559
66974
  try {
66560
- raw = readFileSync67(path, "utf8");
66975
+ raw = readFileSync67(path2, "utf8");
66561
66976
  } catch {
66562
- io.error(JSON.stringify({ error: `no DPX BO session at ${path}` }));
66977
+ io.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
66563
66978
  return 1;
66564
66979
  }
66565
66980
  const { runRemoteSecretsCommand: runRemoteSecretsCommand2 } = await Promise.resolve().then(() => (init_secrets2(), secrets_exports));
@@ -66829,6 +67244,34 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
66829
67244
  }
66830
67245
  const clientId = str5(flags["client-id"]) ?? process.env.WIX_CLIENT_ID;
66831
67246
  const siteUrl = str5(flags.url) ?? str5(flags["site-url"]);
67247
+ if (flags["read-only"] === true) {
67248
+ if (flags.apply || flags.out || flags.shell || flags["redirect-uri"]) {
67249
+ io.error(JSON.stringify({ error: "--read-only returns API context only; it cannot be combined with --apply, --out, --shell, or --redirect-uri" }));
67250
+ return 2;
67251
+ }
67252
+ const siteId = str5(flags.site) ?? process.env.WIX_SITE_ID;
67253
+ if (!clientId && !siteId && !process.env.WIX_TEST_TOKEN?.trim()) {
67254
+ io.error(JSON.stringify({ error: "--read-only needs --site, --client-id, or a site-scoped WIX_TEST_TOKEN" }));
67255
+ return 2;
67256
+ }
67257
+ const { collectSiteContext: collectSiteContext2 } = await Promise.resolve().then(() => (init_context(), context_exports));
67258
+ const { siteToken: siteToken2 } = await Promise.resolve().then(() => (init_wix_owner(), wix_owner_exports));
67259
+ let ownerToken = process.env.WIX_TEST_TOKEN?.trim() || void 0;
67260
+ if (!ownerToken && siteId) {
67261
+ try {
67262
+ ownerToken = await siteToken2(siteId);
67263
+ } catch {
67264
+ }
67265
+ }
67266
+ const context = await collectSiteContext2({
67267
+ siteId,
67268
+ clientId,
67269
+ ownerToken,
67270
+ request: process.env.HIMI_ANALYZE_REQUEST
67271
+ });
67272
+ print({ ok: true, context });
67273
+ return 0;
67274
+ }
66832
67275
  if (!clientId || !siteUrl) {
66833
67276
  io.error(JSON.stringify({
66834
67277
  error: "himi site analyze needs --client-id and --url",