@wix/himalaya-cli 0.1002.0 → 0.1003.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,47 +5278,46 @@ 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;
5308
5319
  var init_tokens = __esm({
5309
5320
  "../../core/ts/src/tokens.ts"() {
5310
- "use strict";
5311
5321
  SYSTEM_FONT_FAMILY = "$system";
5312
5322
  }
5313
5323
  });
@@ -5346,11 +5356,11 @@ var init_bindings = __esm({
5346
5356
  // ../../core/ts/src/validator.ts
5347
5357
  import Ajv from "ajv";
5348
5358
  import addFormats from "ajv-formats";
5349
- function findUnknownComponents(node, allowed2, path = "$", out = []) {
5359
+ function findUnknownComponents(node, allowed2, path2 = "$", out = []) {
5350
5360
  if (node === null || typeof node !== "object") return out;
5351
5361
  if (Array.isArray(node)) {
5352
5362
  node.forEach(
5353
- (item, i) => findUnknownComponents(item, allowed2, `${path}[${i}]`, out)
5363
+ (item, i) => findUnknownComponents(item, allowed2, `${path2}[${i}]`, out)
5354
5364
  );
5355
5365
  return out;
5356
5366
  }
@@ -5359,11 +5369,11 @@ function findUnknownComponents(node, allowed2, path = "$", out = []) {
5359
5369
  if (body && typeof body.package === "string" && typeof body.type === "string") {
5360
5370
  const key2 = `${body.package}.${body.type}`;
5361
5371
  if (!allowed2.has(key2)) {
5362
- out.push({ path, package: body.package, type: body.type });
5372
+ out.push({ path: path2, package: body.package, type: body.type });
5363
5373
  }
5364
5374
  }
5365
5375
  for (const [key2, value] of Object.entries(obj2)) {
5366
- findUnknownComponents(value, allowed2, `${path}.${key2}`, out);
5376
+ findUnknownComponents(value, allowed2, `${path2}.${key2}`, out);
5367
5377
  }
5368
5378
  return out;
5369
5379
  }
@@ -5375,9 +5385,9 @@ function compileWidgetSchema() {
5375
5385
  }
5376
5386
  return widgetValidateFn;
5377
5387
  }
5378
- function validateWidgetActionRef(action, path, intents) {
5388
+ function validateWidgetActionRef(action, path2, intents) {
5379
5389
  if (typeof action !== "object" || action === null || Array.isArray(action)) {
5380
- intents.push({ path, reason: "must be an object { actionId, params? }" });
5390
+ intents.push({ path: path2, reason: "must be an object { actionId, params? }" });
5381
5391
  return;
5382
5392
  }
5383
5393
  const actionId = action.actionId;
@@ -5386,48 +5396,48 @@ function validateWidgetActionRef(action, path, intents) {
5386
5396
  const unsupportedFields = Object.keys(action).filter((key2) => !WIDGET_ACTION_FIELDS.has(key2));
5387
5397
  if (unsupportedFields.length > 0) {
5388
5398
  intents.push({
5389
- path,
5399
+ path: path2,
5390
5400
  reason: `unsupported field(s) on a widget action: ${unsupportedFields.sort().join(", ")} \u2014 a frozen widget action carries only \`actionId\` and literal \`params\``
5391
5401
  });
5392
5402
  }
5393
5403
  const knownAction = typeof actionId === "string" && Object.prototype.hasOwnProperty.call(WIDGET_INTENT_RULES, actionId);
5394
5404
  if (typeof actionId !== "string" || actionId.length === 0) {
5395
- intents.push({ path, reason: "`actionId` must be a non-empty string" });
5405
+ intents.push({ path: path2, reason: "`actionId` must be a non-empty string" });
5396
5406
  } else if (!knownAction) {
5397
- intents.push({ path, reason: `unsupported widget actionId "${actionId}"` });
5407
+ intents.push({ path: path2, reason: `unsupported widget actionId "${actionId}"` });
5398
5408
  }
5399
5409
  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" });
5410
+ intents.push({ path: path2, reason: "`params` must be a { string: string } map of literals" });
5401
5411
  } else if (knownAction) {
5402
5412
  const rule = WIDGET_INTENT_RULES[actionId];
5403
5413
  const literalParams = params ?? {};
5404
5414
  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" });
5415
+ intents.push({ path: path2, reason: "parameters exceed the widget action size limit" });
5406
5416
  }
5407
5417
  const allowed2 = /* @__PURE__ */ new Set([...rule.required, ...rule.optional ?? []]);
5408
5418
  const unknown = Object.keys(literalParams).filter((key2) => !allowed2.has(key2));
5409
5419
  const missing = rule.required.filter((key2) => !literalParams[key2]);
5410
5420
  if (unknown.length > 0) {
5411
- intents.push({ path, reason: `unsupported parameter(s): ${unknown.join(", ")}` });
5421
+ intents.push({ path: path2, reason: `unsupported parameter(s): ${unknown.join(", ")}` });
5412
5422
  }
5413
5423
  if (missing.length > 0) {
5414
- intents.push({ path, reason: `missing required parameter(s): ${missing.join(", ")}` });
5424
+ intents.push({ path: path2, reason: `missing required parameter(s): ${missing.join(", ")}` });
5415
5425
  }
5416
5426
  for (const [key2, values] of Object.entries(rule.values ?? {})) {
5417
5427
  const value = literalParams[key2];
5418
5428
  if (value !== void 0 && !values.includes(value)) {
5419
- intents.push({ path, reason: `invalid ${key2} "${value}"` });
5429
+ intents.push({ path: path2, reason: `invalid ${key2} "${value}"` });
5420
5430
  }
5421
5431
  }
5422
5432
  }
5423
5433
  }
5424
- function scanWidgetPayload(node, family, path, bindings, disallowed, timeRefs, intents, actionSites2) {
5434
+ function scanWidgetPayload(node, family, path2, bindings, disallowed, timeRefs, intents, actionSites2) {
5425
5435
  if (typeof node === "string") {
5426
- if (WIDGET_BINDING.test(node)) bindings.push({ path, value: node });
5436
+ if (WIDGET_BINDING.test(node)) bindings.push({ path: path2, value: node });
5427
5437
  return;
5428
5438
  }
5429
5439
  if (Array.isArray(node)) {
5430
- node.forEach((item, i) => scanWidgetPayload(item, family, `${path}[${i}]`, bindings, disallowed, timeRefs, intents, actionSites2));
5440
+ node.forEach((item, i) => scanWidgetPayload(item, family, `${path2}[${i}]`, bindings, disallowed, timeRefs, intents, actionSites2));
5431
5441
  return;
5432
5442
  }
5433
5443
  if (node === null || typeof node !== "object") return;
@@ -5436,46 +5446,46 @@ function scanWidgetPayload(node, family, path, bindings, disallowed, timeRefs, i
5436
5446
  if (body && typeof body.package === "string" && typeof body.type === "string") {
5437
5447
  const key2 = `${body.package}.${body.type}`;
5438
5448
  if (family && !isComponentAllowedForFamily(key2, family)) {
5439
- disallowed.push({ path, package: body.package, type: body.type, family });
5449
+ disallowed.push({ path: path2, package: body.package, type: body.type, family });
5440
5450
  }
5441
5451
  if (key2 === "himalaya.Button") {
5442
5452
  const props = body.props;
5443
5453
  if (!props || typeof props !== "object" || Array.isArray(props)) {
5444
- intents.push({ path: `${path}.body.props`, reason: "widget Button props must be an object" });
5454
+ intents.push({ path: `${path2}.body.props`, reason: "widget Button props must be an object" });
5445
5455
  } else if (family === "ios_home" || family === "android_home") {
5446
5456
  const button = props;
5447
5457
  if (button.intent !== void 0) {
5448
- intents.push({ path: `${path}.body.props.intent`, reason: "widget Button commands use the required `action` field" });
5458
+ intents.push({ path: `${path2}.body.props.intent`, reason: "widget Button commands use the required `action` field" });
5449
5459
  }
5450
- validateWidgetActionRef(button.action, `${path}.body.props.action`, intents);
5460
+ validateWidgetActionRef(button.action, `${path2}.body.props.action`, intents);
5451
5461
  const componentId = obj2.id;
5452
5462
  if (typeof componentId !== "string" || !WIDGET_ACTION_IDENTIFIER.test(componentId)) {
5453
5463
  intents.push({
5454
- path: `${path}.id`,
5464
+ path: `${path2}.id`,
5455
5465
  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
5466
  });
5457
5467
  }
5458
- actionSites2.push(`${path}.body.props.action`);
5468
+ actionSites2.push(`${path2}.body.props.action`);
5459
5469
  }
5460
5470
  }
5461
5471
  }
5462
5472
  if (obj2.timeRef !== void 0 && obj2.timeRef !== null) {
5463
5473
  const tr = obj2.timeRef;
5464
5474
  if (typeof tr !== "object" || Array.isArray(tr)) {
5465
- timeRefs.push({ path: `${path}.timeRef`, reason: "must be an object { at, style? }" });
5475
+ timeRefs.push({ path: `${path2}.timeRef`, reason: "must be an object { at, style? }" });
5466
5476
  } else {
5467
5477
  const at = tr.at;
5468
5478
  const style = tr.style;
5469
5479
  if (typeof at !== "number" || !Number.isFinite(at)) {
5470
- timeRefs.push({ path: `${path}.timeRef`, reason: "`at` must be a finite epoch-seconds number" });
5480
+ timeRefs.push({ path: `${path2}.timeRef`, reason: "`at` must be a finite epoch-seconds number" });
5471
5481
  }
5472
5482
  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("|")})` });
5483
+ timeRefs.push({ path: `${path2}.timeRef`, reason: `invalid style "${String(style)}" (expected ${[...VALID_TIMEREF_STYLES].join("|")})` });
5474
5484
  }
5475
5485
  }
5476
5486
  }
5477
5487
  for (const [k, v] of Object.entries(obj2)) {
5478
- scanWidgetPayload(v, family, `${path}.${k}`, bindings, disallowed, timeRefs, intents, actionSites2);
5488
+ scanWidgetPayload(v, family, `${path2}.${k}`, bindings, disallowed, timeRefs, intents, actionSites2);
5479
5489
  }
5480
5490
  }
5481
5491
  function validateWidget(snapshot2) {
@@ -6392,9 +6402,9 @@ function collectDescriptorStrings(descriptor) {
6392
6402
  seen.add(key2);
6393
6403
  out.push(f);
6394
6404
  };
6395
- const visit = (node, path) => {
6405
+ const visit = (node, path2) => {
6396
6406
  if (Array.isArray(node)) {
6397
- node.forEach((n, i) => visit(n, `${path}[${i}]`));
6407
+ node.forEach((n, i) => visit(n, `${path2}[${i}]`));
6398
6408
  return;
6399
6409
  }
6400
6410
  if (!node || typeof node !== "object") return;
@@ -6407,7 +6417,7 @@ function collectDescriptorStrings(descriptor) {
6407
6417
  for (const [prop, v] of Object.entries(props)) {
6408
6418
  if (typeof v !== "string" || BINDING_SIGIL.test(v)) continue;
6409
6419
  if (!isUserVisibleCopy(v)) continue;
6410
- const at = `${path}.body.props.${prop}`;
6420
+ const at = `${path2}.body.props.${prop}`;
6411
6421
  if (mapped.includes(prop) || SECONDARY_FIELDS.has(prop)) {
6412
6422
  push({ value: v, bucket: "reachable", type, prop, path: at });
6413
6423
  } else if (UNREACHED_VISIBLE_FIELDS.has(prop)) {
@@ -6421,19 +6431,19 @@ function collectDescriptorStrings(descriptor) {
6421
6431
  bucket: "reachable",
6422
6432
  type,
6423
6433
  prop: "template.template",
6424
- path: `${path}.body.props.template.template`
6434
+ path: `${path2}.body.props.template.template`
6425
6435
  });
6426
6436
  }
6427
6437
  }
6428
6438
  for (const [k, v] of Object.entries(obj2)) {
6429
6439
  if (k === "body") continue;
6430
6440
  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}` });
6441
+ push({ value: v, bucket: "reachable", type, prop: k, path: `${path2}.${k}` });
6432
6442
  }
6433
6443
  }
6434
6444
  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);
6445
+ if (path2 === "" && k === "input" && v !== null && typeof v === "object") continue;
6446
+ if (v && typeof v === "object") visit(v, path2 ? `${path2}.${k}` : k);
6437
6447
  }
6438
6448
  };
6439
6449
  visit(descriptor, "");
@@ -6907,10 +6917,10 @@ async function bootBundleWorker(bundleJs, opts) {
6907
6917
  // `headers` is forwarded, not swallowed: it is how one call addresses a business other
6908
6918
  // than the ambient one (`site.forSite(msid)` → `wix-site-id`), and a wrapper that drops
6909
6919
  // 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)}`;
6920
+ call: (method, path2, body, headers2) => {
6921
+ const label2 = `${String(method)} ${String(path2)}`;
6912
6922
  calls.push(label2);
6913
- return Promise.resolve(opts.wixCall(method, path, body, headers2)).then((value) => {
6923
+ return Promise.resolve(opts.wixCall(method, path2, body, headers2)).then((value) => {
6914
6924
  const bytes2 = responseBytes(value);
6915
6925
  if (bytes2 > MAX_FRAME_MESSAGE_BYTES) {
6916
6926
  oversizeWixResponses.push({ call: label2, bytes: bytes2 });
@@ -7148,11 +7158,11 @@ async function bootBundleWorker(bundleJs, opts) {
7148
7158
  }
7149
7159
  message = typeof asJson === "string" ? asJson : String(raw);
7150
7160
  } 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;
7161
+ const failed2 = { ...prev, _error: message };
7162
+ if (prev.status === "loading") failed2.status = "error";
7163
+ if (prev.loading === true) failed2.loading = false;
7164
+ if (typeof prev.error === "string") failed2.error = message;
7165
+ def.state = failed2;
7156
7166
  };
7157
7167
  const runAction = async (def, label2, fn, args) => {
7158
7168
  let timer;
@@ -7349,9 +7359,9 @@ function validateDescriptorAction(action, context) {
7349
7359
  function validateDescriptorActions(actions, context) {
7350
7360
  return actions.map((action) => validateDescriptorAction(action, context)).filter((issue2) => issue2 !== null);
7351
7361
  }
7352
- function pathValue(state, path) {
7362
+ function pathValue(state, path2) {
7353
7363
  let cur = state;
7354
- for (const part of path.replace(/\[(\d+)\]/g, ".$1").split(".")) {
7364
+ for (const part of path2.replace(/\[(\d+)\]/g, ".$1").split(".")) {
7355
7365
  if (cur == null || typeof cur !== "object") return void 0;
7356
7366
  if (Array.isArray(cur)) {
7357
7367
  const idx = Number(part);
@@ -7364,9 +7374,9 @@ function pathValue(state, path) {
7364
7374
  }
7365
7375
  return cur;
7366
7376
  }
7367
- function pathResolves(state, path) {
7377
+ function pathResolves(state, path2) {
7368
7378
  let cur = state;
7369
- for (const part of path.replace(/\[(\d+)\]/g, ".$1").split(".")) {
7379
+ for (const part of path2.replace(/\[(\d+)\]/g, ".$1").split(".")) {
7370
7380
  if (cur == null || typeof cur !== "object") return false;
7371
7381
  if (Array.isArray(cur)) {
7372
7382
  const idx = Number(part);
@@ -7383,9 +7393,9 @@ function pathResolves(state, path) {
7383
7393
  }
7384
7394
  return true;
7385
7395
  }
7386
- function serviceFieldDeclared(state, path) {
7396
+ function serviceFieldDeclared(state, path2) {
7387
7397
  if (state == null || typeof state !== "object" || Array.isArray(state)) return false;
7388
- const first = path.replace(/\[(\d+)\]/g, ".$1").split(".")[0];
7398
+ const first = path2.replace(/\[(\d+)\]/g, ".$1").split(".")[0];
7389
7399
  return first in state;
7390
7400
  }
7391
7401
  function ellipsis(value, max) {
@@ -7398,70 +7408,70 @@ function isOpaqueAuthorJson(key2, value, atRoot) {
7398
7408
  if (value === null || typeof value !== "object") return false;
7399
7409
  return key2 === "args" || atRoot && key2 === "input";
7400
7410
  }
7401
- function pathCrossesOpaqueAuthorJson(path) {
7402
- if (typeof path !== "string") return false;
7403
- return /^\$\.input(?:[.[]|$)/.test(path) || /\.args(?:[.[]|$)/.test(path);
7411
+ function pathCrossesOpaqueAuthorJson(path2) {
7412
+ if (typeof path2 !== "string") return false;
7413
+ return /^\$\.input(?:[.[]|$)/.test(path2) || /\.args(?:[.[]|$)/.test(path2);
7404
7414
  }
7405
7415
  function nativeRequiredFindings(descriptor) {
7406
7416
  const out = [];
7407
7417
  const shapeOf = (ref) => ref.startsWith("list:") ? "an array" : ref.startsWith("map:") ? "an object keyed by name" : "an object";
7408
7418
  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) => {
7419
+ const reportKind = (ref, value, path2, from) => {
7410
7420
  const cls = bareNestedClass(ref);
7411
7421
  const got = kindOf(value);
7412
7422
  const expected = ref.startsWith("list:") ? "Expected JsonArray" : `Expected JsonObject for type with serial name 'io.himalaya.core.${cls}'`;
7413
7423
  out.push({
7414
- path,
7424
+ path: path2,
7415
7425
  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
7426
  });
7417
7427
  };
7418
- const checkNested = (value, cls, path, from) => {
7428
+ const checkNested = (value, cls, path2, from) => {
7419
7429
  if (cls.startsWith("map:")) {
7420
7430
  if (!value || typeof value !== "object" || Array.isArray(value)) {
7421
- reportKind(cls, value, path, from);
7431
+ reportKind(cls, value, path2, from);
7422
7432
  return;
7423
7433
  }
7424
7434
  const of = cls.slice("map:".length);
7425
7435
  for (const [key2, v] of Object.entries(value)) {
7426
- checkNested(v, of, `${path}.${key2}`, from);
7436
+ checkNested(v, of, `${path2}.${key2}`, from);
7427
7437
  }
7428
7438
  return;
7429
7439
  }
7430
7440
  if (cls.startsWith("list:")) {
7431
7441
  if (!Array.isArray(value)) {
7432
- reportKind(cls, value, path, from);
7442
+ reportKind(cls, value, path2, from);
7433
7443
  return;
7434
7444
  }
7435
7445
  const of = cls.slice("list:".length);
7436
- value.forEach((v, i) => checkNested(v, of, `${path}[${i}]`, from));
7446
+ value.forEach((v, i) => checkNested(v, of, `${path2}[${i}]`, from));
7437
7447
  return;
7438
7448
  }
7439
7449
  const rule = own(NATIVE_NESTED_CLASSES, cls);
7440
7450
  if (!rule) return;
7441
7451
  if (Array.isArray(value) || !value || typeof value !== "object") {
7442
- reportKind(cls, value, path, from);
7452
+ reportKind(cls, value, path2, from);
7443
7453
  return;
7444
7454
  }
7445
7455
  const bag = value;
7446
7456
  for (const name of rule.required) {
7447
7457
  if (own(bag, name) !== void 0 && bag[name] !== null) continue;
7448
7458
  out.push({
7449
- path: `${path}.${name}`,
7459
+ path: `${path2}.${name}`,
7450
7460
  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
7461
  });
7452
7462
  }
7453
7463
  for (const [name, sub] of Object.entries(rule.nested)) {
7454
7464
  const inner = own(bag, name);
7455
- if (inner !== void 0 && inner !== null) checkNested(inner, sub, `${path}.${name}`, from);
7465
+ if (inner !== void 0 && inner !== null) checkNested(inner, sub, `${path2}.${name}`, from);
7456
7466
  }
7457
- if (cls === "Action") checkActionParams(own(bag, "params"), `${path}.params`, from);
7467
+ if (cls === "Action") checkActionParams(own(bag, "params"), `${path2}.params`, from);
7458
7468
  };
7459
- const checkActionParams = (params, path, from) => {
7469
+ const checkActionParams = (params, path2, from) => {
7460
7470
  if (params === void 0 || params === null) return;
7461
7471
  const cost = "Native decode rejects it and drops the WHOLE screen from the seed, while web renders it fine";
7462
7472
  if (typeof params !== "object" || Array.isArray(params)) {
7463
7473
  out.push({
7464
- path,
7474
+ path: path2,
7465
7475
  message: `Action.params must be an object of strings, but the descriptor has ${kindOf(params)} ("Expected JsonObject"). ${cost} (reached from ${from})`
7466
7476
  });
7467
7477
  return;
@@ -7469,7 +7479,7 @@ function nativeRequiredFindings(descriptor) {
7469
7479
  for (const [key2, value] of Object.entries(params)) {
7470
7480
  if (typeof value === "string" || value === void 0) continue;
7471
7481
  out.push({
7472
- path: `${path}.${key2}`,
7482
+ path: `${path2}.${key2}`,
7473
7483
  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
7484
  });
7475
7485
  }
@@ -7552,13 +7562,13 @@ function componentPropFindings(descriptor) {
7552
7562
  const bag = props;
7553
7563
  const base = at ? `${at}.body.props` : "body.props";
7554
7564
  for (const name of Object.keys(bag)) {
7555
- const path = `${base}.${name}`;
7565
+ const path2 = `${base}.${name}`;
7556
7566
  const kind = own(declared, name);
7557
7567
  if (kind === void 0) {
7558
7568
  if (LEGACY_UNSCORED_KEYS.has(`${type}.${name}`)) continue;
7559
7569
  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
7570
  out.push({
7561
- path,
7571
+ path: path2,
7562
7572
  kind: "hygiene",
7563
7573
  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
7574
  });
@@ -7572,7 +7582,7 @@ function componentPropFindings(descriptor) {
7572
7582
  const twin = own(declared, `${name}Path`) !== void 0 ? `${name}Path` : void 0;
7573
7583
  const inArray = IN_ARRAY_BINDING_PROPS.has(`${type}.${name}`) && value.startsWith(SERVICE_SIGIL);
7574
7584
  out.push({
7575
- path,
7585
+ path: path2,
7576
7586
  kind: "decode",
7577
7587
  ...inArray ? { authoringOnly: true } : {},
7578
7588
  // TWO different defects share this branch, and they need DIFFERENT prose.
@@ -7588,7 +7598,7 @@ function componentPropFindings(descriptor) {
7588
7598
  // copy-pasteable line that silently truncated a long path, so following the advice
7589
7599
  // bound to missing state; it stays truncated only in the diagnostic prose, where it
7590
7600
  // 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)}`
7601
+ 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
7602
  });
7593
7603
  continue;
7594
7604
  }
@@ -7597,17 +7607,17 @@ function componentPropFindings(descriptor) {
7597
7607
  if (actual === kind) {
7598
7608
  if (kind === "number" && typeof value === "number" && !Number.isInteger(value) && own(INTEGER_PROPS, type)?.includes(name)) {
7599
7609
  out.push({
7600
- path,
7610
+ path: path2,
7601
7611
  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)}`
7612
+ 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
7613
  });
7604
7614
  }
7605
7615
  continue;
7606
7616
  }
7607
7617
  out.push({
7608
- path,
7618
+ path: path2,
7609
7619
  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)}`
7620
+ 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
7621
  });
7612
7622
  }
7613
7623
  }
@@ -7870,15 +7880,15 @@ function workerSubtreeAllowed(screenId, allowlist) {
7870
7880
  }
7871
7881
  return false;
7872
7882
  }
7873
- function collectWixMediaReferences(value, path, found, mediaContext = false, bareIdContext = false, componentType = "", atRoot = false) {
7883
+ function collectWixMediaReferences(value, path2, found, mediaContext = false, bareIdContext = false, componentType = "", atRoot = false) {
7874
7884
  const unresolvedMedia = mediaContext && unresolvedWixMediaReference(value, bareIdContext);
7875
7885
  if (unresolvedMedia) {
7876
- found.push({ path, value: unresolvedMedia });
7886
+ found.push({ path: path2, value: unresolvedMedia });
7877
7887
  return;
7878
7888
  }
7879
7889
  if (Array.isArray(value)) {
7880
7890
  value.forEach((item, index) => {
7881
- collectWixMediaReferences(item, `${path}[${index}]`, found, mediaContext, bareIdContext);
7891
+ collectWixMediaReferences(item, `${path2}[${index}]`, found, mediaContext, bareIdContext);
7882
7892
  });
7883
7893
  return;
7884
7894
  }
@@ -7890,7 +7900,7 @@ function collectWixMediaReferences(value, path, found, mediaContext = false, bar
7890
7900
  const childComponentType = key2 === "props" && typeof record2.type === "string" ? record2.type : "";
7891
7901
  collectWixMediaReferences(
7892
7902
  child,
7893
- path ? `${path}.${key2}` : key2,
7903
+ path2 ? `${path2}.${key2}` : key2,
7894
7904
  found,
7895
7905
  mediaContext || isComponentMediaValueProperty(componentType, key2),
7896
7906
  bareIdContext || isMediaLocationProperty(key2),
@@ -7936,16 +7946,16 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
7936
7946
  };
7937
7947
  for (const e of v.schemaErrors) {
7938
7948
  const err = e;
7939
- const path = err.instancePath;
7940
- if (path === "/logicBundle/integrity" && lbIntegrity === "") continue;
7949
+ const path2 = err.instancePath;
7950
+ if (path2 === "/logicBundle/integrity" && lbIntegrity === "") continue;
7941
7951
  const issue2 = {
7942
7952
  severity: hygiene,
7943
7953
  pass: "schema",
7944
- path,
7954
+ path: path2,
7945
7955
  message: err.message ?? "schema violation"
7946
7956
  };
7947
7957
  issues.push(issue2);
7948
- for (const at of dottedCandidates(path ?? "")) {
7958
+ for (const at of dottedCandidates(path2 ?? "")) {
7949
7959
  if (err.keyword === "required" && err.params?.missingProperty) {
7950
7960
  indexIssue(at ? `${at}.${err.params.missingProperty}` : err.params.missingProperty, issue2);
7951
7961
  }
@@ -8355,11 +8365,11 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
8355
8365
  {
8356
8366
  const NAMED_ICON_PROPS = /* @__PURE__ */ new Set(["icon", "selectedIcon", "leadingIcon", "trailingIcon", "badgeIcon"]);
8357
8367
  const shape = (v2) => Array.isArray(v2) ? "an array" : typeof v2;
8358
- const flagNonString = (k, v2, path) => {
8368
+ const flagNonString = (k, v2, path2) => {
8359
8369
  issues.push({
8360
8370
  severity: "error",
8361
8371
  pass: "icons",
8362
- path,
8372
+ path: path2,
8363
8373
  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
8374
  });
8365
8375
  };
@@ -8390,12 +8400,12 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
8390
8400
  const normIcon = (n) => n.toLowerCase().replace(/[_.\s-]/g, "");
8391
8401
  const ICON_NAME_PROPS = /* @__PURE__ */ new Set(["icon", "selectedIcon", "leadingIcon", "trailingIcon", "badgeIcon"]);
8392
8402
  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) => {
8403
+ const flagIcon = (name, path2) => {
8394
8404
  if (allowedIcons.has(name) || allowedIcons.has(normIcon(name))) return;
8395
8405
  issues.push({
8396
8406
  severity: hygiene,
8397
8407
  pass: "icons",
8398
- path,
8408
+ path: path2,
8399
8409
  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
8410
  });
8401
8411
  };
@@ -10675,14 +10685,14 @@ function tokenColorProblems(colors) {
10675
10685
  const problems = [];
10676
10686
  for (const [name, value] of Object.entries(colors ?? {})) {
10677
10687
  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) {
10688
+ for (const [path2, raw] of leaves) {
10679
10689
  if (typeof raw !== "string") {
10680
- problems.push({ path, value: JSON.stringify(raw) ?? String(raw) });
10690
+ problems.push({ path: path2, value: JSON.stringify(raw) ?? String(raw) });
10681
10691
  continue;
10682
10692
  }
10683
10693
  if (isCanonicalHex(raw)) continue;
10684
10694
  const suggestion = canonicalHex(raw);
10685
- problems.push(suggestion ? { path, value: raw, suggestion } : { path, value: raw });
10695
+ problems.push(suggestion ? { path: path2, value: raw, suggestion } : { path: path2, value: raw });
10686
10696
  }
10687
10697
  }
10688
10698
  return problems;
@@ -11345,10 +11355,10 @@ function resolveAppDirIcon(appDir2) {
11345
11355
  return findContentIconPath(appDir2) ?? findAppIconPath(appDir2);
11346
11356
  }
11347
11357
  function readIconFromDir(appDir2) {
11348
- const path = resolveAppDirIcon(appDir2);
11349
- if (!path) return null;
11358
+ const path2 = resolveAppDirIcon(appDir2);
11359
+ if (!path2) return null;
11350
11360
  try {
11351
- return readFileSync15(path);
11361
+ return readFileSync15(path2);
11352
11362
  } catch {
11353
11363
  return null;
11354
11364
  }
@@ -11698,11 +11708,11 @@ function playState(dir) {
11698
11708
  }
11699
11709
  async function iconStatus(dir) {
11700
11710
  const declared = declaredIconName(dir);
11701
- const path = resolveAppDirIcon(dir);
11711
+ const path2 = resolveAppDirIcon(dir);
11702
11712
  const play = playState(dir);
11703
11713
  const base = {
11704
11714
  declared,
11705
- path,
11715
+ path: path2,
11706
11716
  play,
11707
11717
  bytes: null,
11708
11718
  sha256: null,
@@ -11714,21 +11724,21 @@ async function iconStatus(dir) {
11714
11724
  verdict: "missing",
11715
11725
  policyChecklist: POLICY_CHECKLIST
11716
11726
  };
11717
- if (!path || !existsSync15(path)) return base;
11727
+ if (!path2 || !existsSync15(path2)) return base;
11718
11728
  let png;
11719
11729
  try {
11720
- if (!statSync4(path).isFile()) {
11730
+ if (!statSync4(path2).isFile()) {
11721
11731
  return {
11722
11732
  ...base,
11723
- byteIssues: [`at ${path} is a directory, not a PNG file`],
11733
+ byteIssues: [`at ${path2} is a directory, not a PNG file`],
11724
11734
  verdict: "blocked"
11725
11735
  };
11726
11736
  }
11727
- png = readFileSync16(path);
11737
+ png = readFileSync16(path2);
11728
11738
  } catch (err) {
11729
11739
  return {
11730
11740
  ...base,
11731
- byteIssues: [`at ${path} could not be read (${err.message.split("\n")[0]})`],
11741
+ byteIssues: [`at ${path2} could not be read (${err.message.split("\n")[0]})`],
11732
11742
  verdict: "blocked"
11733
11743
  };
11734
11744
  }
@@ -11766,7 +11776,7 @@ async function iconStatus(dir) {
11766
11776
  ...status,
11767
11777
  pixelFindings: [{
11768
11778
  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>\`.`
11779
+ 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
11780
  }],
11771
11781
  pixelsChecked: false,
11772
11782
  verdict: "blocked"
@@ -11951,15 +11961,15 @@ function loadCatalog() {
11951
11961
  cached = JSON.parse(readFileSync17(override, "utf8"));
11952
11962
  return cached;
11953
11963
  }
11954
- const path = CATALOG_CANDIDATES.find((p) => existsSync17(p));
11955
- if (!path) {
11964
+ const path2 = CATALOG_CANDIDATES.find((p) => existsSync17(p));
11965
+ if (!path2) {
11956
11966
  throw new Error(
11957
11967
  `font catalog not found. Looked in:
11958
11968
  ${CATALOG_CANDIDATES.join("\n ")}
11959
11969
  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
11970
  );
11961
11971
  }
11962
- cached = JSON.parse(readFileSync17(path, "utf8"));
11972
+ cached = JSON.parse(readFileSync17(path2, "utf8"));
11963
11973
  return cached;
11964
11974
  }
11965
11975
  function renderableFamilies(catalog = loadCatalog()) {
@@ -12242,9 +12252,9 @@ async function offRepoFontBytes(plan, opts = {}) {
12242
12252
  out.hostProvided.push(r.family);
12243
12253
  continue;
12244
12254
  }
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 });
12255
+ const failed2 = r.faces.find((f) => !f.got.ok);
12256
+ if (failed2 && !failed2.got.ok) {
12257
+ out.unavailable.push({ family: r.family, reason: failed2.got.reason });
12248
12258
  continue;
12249
12259
  }
12250
12260
  out.ready.push({
@@ -12719,9 +12729,9 @@ __export(fonts_exports, {
12719
12729
  });
12720
12730
  import { existsSync as existsSync19, readFileSync as readFileSync19 } from "node:fs";
12721
12731
  import { join as join22 } from "node:path";
12722
- function readJson(path, fallback) {
12732
+ function readJson(path2, fallback) {
12723
12733
  try {
12724
- return JSON.parse(readFileSync19(path, "utf8"));
12734
+ return JSON.parse(readFileSync19(path2, "utf8"));
12725
12735
  } catch {
12726
12736
  return fallback;
12727
12737
  }
@@ -12999,22 +13009,22 @@ function lc(h) {
12999
13009
  for (const [k, v] of Object.entries(h ?? {})) o[k.toLowerCase()] = v;
13000
13010
  return o;
13001
13011
  }
13002
- function matchRuleEx(rules, method, path, ctx = {}) {
13012
+ function matchRuleEx(rules, method, path2, ctx = {}) {
13003
13013
  for (const r of rules) {
13004
13014
  if (!r.enabled) continue;
13005
13015
  const m = r.matcher;
13006
13016
  if (m.method && m.method.toUpperCase() !== method.toUpperCase()) continue;
13007
13017
  if (m.host && ctx.host && !globToRegExp(m.host).test(ctx.host)) continue;
13008
13018
  if (m.host && !ctx.host) continue;
13009
- const captures = { path, host: ctx.host ?? "" };
13019
+ const captures = { path: path2, host: ctx.host ?? "" };
13010
13020
  if (m.pathRegex) {
13011
- const mm = new RegExp(m.pathRegex).exec(path);
13021
+ const mm = new RegExp(m.pathRegex).exec(path2);
13012
13022
  if (!mm) continue;
13013
13023
  mm.forEach((g, i) => {
13014
13024
  captures[String(i)] = g ?? "";
13015
13025
  });
13016
13026
  } else if (m.pathGlob) {
13017
- if (!globToRegExp(m.pathGlob).test(path)) continue;
13027
+ if (!globToRegExp(m.pathGlob).test(path2)) continue;
13018
13028
  }
13019
13029
  if (m.query) {
13020
13030
  const q = ctx.query ?? {};
@@ -13090,15 +13100,15 @@ function isNativePlatform(value) {
13090
13100
  function isNativeAuditStatus(value) {
13091
13101
  return typeof value === "string" && NATIVE_AUDIT_STATUSES.includes(value);
13092
13102
  }
13093
- function readText(path) {
13103
+ function readText(path2) {
13094
13104
  try {
13095
- return existsSync21(path) ? readFileSync21(path, "utf8") : null;
13105
+ return existsSync21(path2) ? readFileSync21(path2, "utf8") : null;
13096
13106
  } catch {
13097
13107
  return null;
13098
13108
  }
13099
13109
  }
13100
- function parseEvidence(path) {
13101
- const raw = readText(path);
13110
+ function parseEvidence(path2) {
13111
+ const raw = readText(path2);
13102
13112
  if (raw === null) return { evidence: null };
13103
13113
  try {
13104
13114
  const value = JSON.parse(raw);
@@ -13126,9 +13136,9 @@ function recordedRenderWidths(content) {
13126
13136
  const { evidence } = parseEvidence(uxEvidencePath(content));
13127
13137
  return renderEvidenceEntries(evidence).map((entry) => entry.width);
13128
13138
  }
13129
- function writeEvidence(path, evidence) {
13130
- mkdirSync10(dirname13(path), { recursive: true });
13131
- writeFileSync9(path, JSON.stringify(evidence, null, 2) + "\n");
13139
+ function writeEvidence(path2, evidence) {
13140
+ mkdirSync10(dirname13(path2), { recursive: true });
13141
+ writeFileSync9(path2, JSON.stringify(evidence, null, 2) + "\n");
13132
13142
  }
13133
13143
  function recordedFilePath(dir, file) {
13134
13144
  const rel = relative3(dir, resolve15(file));
@@ -13138,8 +13148,8 @@ function recordRenderWidth(content, entry) {
13138
13148
  try {
13139
13149
  if (!entry.screenId || !Number.isFinite(entry.width) || entry.width <= 0) return null;
13140
13150
  const dir = resolve15(content);
13141
- const path = join24(dir, UX_EVIDENCE_PATH);
13142
- const parsed = parseEvidence(path);
13151
+ const path2 = join24(dir, UX_EVIDENCE_PATH);
13152
+ const parsed = parseEvidence(path2);
13143
13153
  if (parsed.error) return null;
13144
13154
  const evidence = parsed.evidence ?? { version: 1, platforms: {} };
13145
13155
  const width = entry.width;
@@ -13155,7 +13165,7 @@ function recordRenderWidth(content, entry) {
13155
13165
  if (at >= 0) renders[at] = written;
13156
13166
  else renders.push(written);
13157
13167
  evidence.renders = renders;
13158
- writeEvidence(path, evidence);
13168
+ writeEvidence(path2, evidence);
13159
13169
  return written;
13160
13170
  } catch {
13161
13171
  return null;
@@ -13168,8 +13178,8 @@ function recordNativeAudit(content, platform, status, checks, reason, release) {
13168
13178
  }
13169
13179
  if (status === "unavailable" && !reason?.trim()) throw new Error("--reason is required when --status unavailable");
13170
13180
  const dir = resolve15(content);
13171
- const path = join24(dir, UX_EVIDENCE_PATH);
13172
- const parsed = parseEvidence(path);
13181
+ const path2 = join24(dir, UX_EVIDENCE_PATH);
13182
+ const parsed = parseEvidence(path2);
13173
13183
  if (parsed.error) throw new Error(`${UX_EVIDENCE_PATH} ${parsed.error}`);
13174
13184
  const evidence = parsed.evidence ?? { version: 1, platforms: {} };
13175
13185
  evidence.platforms[platform] = {
@@ -13179,12 +13189,12 @@ function recordNativeAudit(content, platform, status, checks, reason, release) {
13179
13189
  ...release?.releaseId && release.releaseHash ? { releaseId: release.releaseId, releaseHash: release.releaseHash } : {},
13180
13190
  recordedAt: (/* @__PURE__ */ new Date()).toISOString()
13181
13191
  };
13182
- writeEvidence(path, evidence);
13192
+ writeEvidence(path2, evidence);
13183
13193
  return evidence;
13184
13194
  }
13185
13195
  function uxEvidenceForRelease(content, release) {
13186
13196
  const { releaseId, releaseHash } = release;
13187
- const path = uxEvidencePath(content);
13197
+ const path2 = uxEvidencePath(content);
13188
13198
  const base = {
13189
13199
  path: UX_EVIDENCE_PATH,
13190
13200
  platforms: [],
@@ -13194,8 +13204,8 @@ function uxEvidenceForRelease(content, release) {
13194
13204
  inheritedScreens: [],
13195
13205
  malformed: []
13196
13206
  };
13197
- if (!existsSync21(path)) return { ...base, state: "absent" };
13198
- const parsed = parseEvidence(path);
13207
+ if (!existsSync21(path2)) return { ...base, state: "absent" };
13208
+ const parsed = parseEvidence(path2);
13199
13209
  if (parsed.error) return { ...base, state: "unreadable", error: parsed.error };
13200
13210
  if (!parsed.evidence) return { ...base, state: "absent" };
13201
13211
  const recorded = [];
@@ -14248,9 +14258,9 @@ function placeholderHashes() {
14248
14258
  const current = templateIconSha256();
14249
14259
  return current ? [LEGACY_PLACEHOLDER_SHA256, current] : [LEGACY_PLACEHOLDER_SHA256];
14250
14260
  }
14251
- function fileSha256(path) {
14261
+ function fileSha256(path2) {
14252
14262
  try {
14253
- return createHash7("sha256").update(readFileSync24(path)).digest("hex");
14263
+ return createHash7("sha256").update(readFileSync24(path2)).digest("hex");
14254
14264
  } catch {
14255
14265
  return null;
14256
14266
  }
@@ -14699,12 +14709,12 @@ function hostAppliesDeferredWidgetActions(app) {
14699
14709
  const dir = stack.pop();
14700
14710
  for (const entry of readdirSync13(dir, { withFileTypes: true })) {
14701
14711
  if (entry.name.startsWith(".") || entry.name === "GeneratedLiveActivity") continue;
14702
- const path = join29(dir, entry.name);
14712
+ const path2 = join29(dir, entry.name);
14703
14713
  if (entry.isDirectory()) {
14704
14714
  if (entry.name.endsWith(".xcodeproj") || entry.name === "build") continue;
14705
- stack.push(path);
14715
+ stack.push(path2);
14706
14716
  } else if (entry.name.endsWith(".swift")) {
14707
- if (readFileSync26(path, "utf8").includes("WidgetActionRelay.drain(")) return true;
14717
+ if (readFileSync26(path2, "utf8").includes("WidgetActionRelay.drain(")) return true;
14708
14718
  }
14709
14719
  }
14710
14720
  }
@@ -14735,29 +14745,29 @@ function androidManifestPath2(app) {
14735
14745
  function automotiveAppDescPath(app) {
14736
14746
  return join29(dirname16(androidManifestPath2(app)), "res", "xml", "automotive_app_desc.xml");
14737
14747
  }
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" };
14748
+ function applyToFile(path2, kind, label2, render, check) {
14749
+ if (!existsSync26(path2)) return { path: path2, outcome: "skipped" };
14750
+ const before = readFileSync26(path2, "utf8");
14751
+ if (!hasMarkers(before, kind, label2)) return { path: path2, outcome: "skipped" };
14742
14752
  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" };
14753
+ if (after === before) return { path: path2, outcome: "unchanged" };
14754
+ if (check) return { path: path2, outcome: "drift" };
14755
+ writeFileSync11(path2, after);
14756
+ return { path: path2, outcome: "written" };
14757
+ }
14758
+ function applyWholeFile(path2, content, check) {
14759
+ const current = existsSync26(path2) ? readFileSync26(path2, "utf8") : null;
14760
+ if (current === content) return { path: path2, outcome: "unchanged" };
14761
+ if (check) return { path: path2, outcome: "drift" };
14762
+ mkdirSync12(dirname16(path2), { recursive: true });
14763
+ writeFileSync11(path2, content);
14764
+ return { path: path2, outcome: "written" };
14765
+ }
14766
+ function removeWholeFile(path2, check) {
14767
+ if (!existsSync26(path2)) return { path: path2, outcome: "skipped" };
14768
+ if (check) return { path: path2, outcome: "drift" };
14769
+ rmSync4(path2);
14770
+ return { path: path2, outcome: "removed" };
14761
14771
  }
14762
14772
  function genNativeConfig(app, opts = {}) {
14763
14773
  const check = opts.check ?? false;
@@ -15003,15 +15013,15 @@ function collectBrandFonts(appDir2) {
15003
15013
  const rel = typeof raw?.file === "string" ? raw.file : "";
15004
15014
  if (!family || !postscriptName || !rel) continue;
15005
15015
  if (rel.startsWith("/") || rel.split("/").includes("..")) continue;
15006
- const path = join30(appDir2, rel);
15016
+ const path2 = join30(appDir2, rel);
15007
15017
  try {
15008
- if (!lstatSync4(path).isFile()) continue;
15018
+ if (!lstatSync4(path2).isFile()) continue;
15009
15019
  const root = realpathSync3(appDir2);
15010
- if (!realpathSync3(path).startsWith(root + sep6)) continue;
15020
+ if (!realpathSync3(path2).startsWith(root + sep6)) continue;
15011
15021
  } catch {
15012
15022
  continue;
15013
15023
  }
15014
- out.push({ family, postscriptName, weight, path });
15024
+ out.push({ family, postscriptName, weight, path: path2 });
15015
15025
  }
15016
15026
  return out;
15017
15027
  }
@@ -15200,7 +15210,7 @@ async function loadContainedDevModule(name, entry, dir) {
15200
15210
  // Both throw synchronously; `handleWant` awaits them inside its own try, so the guest sees an
15201
15211
  // ordinary rejection exactly as it would from any failing transport — while the host keeps the
15202
15212
  // record the guest's `catch` cannot erase.
15203
- wixCall: (method, path) => refuseHost("himalaya.wixApi.call", `${method} ${path}`),
15213
+ wixCall: (method, path2) => refuseHost("himalaya.wixApi.call", `${method} ${path2}`),
15204
15214
  dispatch: (action) => refuseHost("himalaya.dispatch", action)
15205
15215
  });
15206
15216
  const session = ran.session;
@@ -15303,7 +15313,7 @@ async function loadContainedDevModule(name, entry, dir) {
15303
15313
  createStore: () => storeStub,
15304
15314
  ...meta.dataRoutes?.length ? {
15305
15315
  dataRoutes: Object.fromEntries(
15306
- meta.dataRoutes.map((path) => [path, () => refuse(name, `the app data route ${JSON.stringify(path)}`)])
15316
+ meta.dataRoutes.map((path2) => [path2, () => refuse(name, `the app data route ${JSON.stringify(path2)}`)])
15307
15317
  )
15308
15318
  } : {},
15309
15319
  // NOT defaulted. An absent seed crosses as absent and the proxy carries `undefined`, which is
@@ -16095,8 +16105,8 @@ import { createHash as createHash9, randomBytes as randomBytes3 } from "node:cry
16095
16105
  function b64url(buf) {
16096
16106
  return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
16097
16107
  }
16098
- async function postJson(path, body, auth) {
16099
- const res = await fetch(`${API}${path}`, {
16108
+ async function postJson(path2, body, auth) {
16109
+ const res = await fetch(`${API}${path2}`, {
16100
16110
  method: "POST",
16101
16111
  headers: { "Content-Type": "application/json", ...auth ? { Authorization: auth } : {} },
16102
16112
  body: JSON.stringify(body)
@@ -16111,11 +16121,11 @@ async function mintVisitor(clientId) {
16111
16121
  }
16112
16122
  function isRedirectCallback(url, redirectUri) {
16113
16123
  if (url.startsWith(redirectUri)) return true;
16114
- const path = (u) => u.pathname.replace(/\/+$/, "") || "/";
16124
+ const path2 = (u) => u.pathname.replace(/\/+$/, "") || "/";
16115
16125
  try {
16116
16126
  const got = new URL(url);
16117
16127
  const want = new URL(redirectUri);
16118
- return got.protocol === want.protocol && got.host === want.host && path(got) === path(want);
16128
+ return got.protocol === want.protocol && got.host === want.host && path2(got) === path2(want);
16119
16129
  } catch {
16120
16130
  return false;
16121
16131
  }
@@ -16205,8 +16215,8 @@ async function memberDirectRegister(clientId, redirectUri, email, password, firs
16205
16215
  const memberToken = await exchangeSessionToken(clientId, redirectUri, visitorToken, sessionToken);
16206
16216
  return { memberToken, visitorToken };
16207
16217
  }
16208
- async function webWixCall(method, path, body, token, cookie, forwardedHeaders = {}) {
16209
- const url = /^https?:\/\//i.test(path) ? path : `${API}${path.startsWith("/") ? path : "/" + path}`;
16218
+ async function webWixCall(method, path2, body, token, cookie, forwardedHeaders = {}) {
16219
+ const url = /^https?:\/\//i.test(path2) ? path2 : `${API}${path2.startsWith("/") ? path2 : "/" + path2}`;
16210
16220
  if (!isWixTarget(url)) {
16211
16221
  throw new Error(`refusing to send Wix credentials to a non-Wix host (${targetHost(url) || "no host"})`);
16212
16222
  }
@@ -16276,10 +16286,10 @@ function resolveNetMocks(fileMocks, appDeclared) {
16276
16286
  if (declared.length > 0) return { mocks: { mode: appDeclared?.mode, rules: declared }, source: "app" };
16277
16287
  return null;
16278
16288
  }
16279
- function readNetMocksFile(path) {
16289
+ function readNetMocksFile(path2) {
16280
16290
  try {
16281
- if (!existsSync30(path)) return null;
16282
- const raw = JSON.parse(readFileSync30(path, "utf-8"));
16291
+ if (!existsSync30(path2)) return null;
16292
+ const raw = JSON.parse(readFileSync30(path2, "utf-8"));
16283
16293
  if (Array.isArray(raw)) return wixMockRuleErrors(raw).length ? null : { rules: raw };
16284
16294
  if (raw && typeof raw === "object") {
16285
16295
  const o = raw;
@@ -16357,20 +16367,20 @@ function parseTarget(target) {
16357
16367
  });
16358
16368
  return { host: u.host, path: u.pathname, query };
16359
16369
  } catch {
16360
- const path = target.split("?")[0];
16370
+ const path2 = target.split("?")[0];
16361
16371
  const query = {};
16362
16372
  new URLSearchParams(target.split("?")[1] ?? "").forEach((v, k) => {
16363
16373
  query[k] = v;
16364
16374
  });
16365
- return { host: "", path, query };
16375
+ return { host: "", path: path2, query };
16366
16376
  }
16367
16377
  }
16368
16378
  async function handleWixGateway(gw, app, adminUrl, req, res, wixClientId) {
16369
16379
  const url = req.url ?? "";
16370
- const path = url.split("?")[0];
16371
- const scope = path.startsWith("/__dev/wix/") ? "wix" : path.startsWith("/__dev/net/") ? "net" : null;
16380
+ const path2 = url.split("?")[0];
16381
+ const scope = path2.startsWith("/__dev/wix/") ? "wix" : path2.startsWith("/__dev/net/") ? "net" : null;
16372
16382
  if (!scope) return false;
16373
- const suffix = path.slice(scope === "wix" ? "/__dev/wix/".length : "/__dev/net/".length);
16383
+ const suffix = path2.slice(scope === "wix" ? "/__dev/wix/".length : "/__dev/net/".length);
16374
16384
  const method = (req.method ?? "GET").toUpperCase();
16375
16385
  if (suffix === "events" && method === "GET") {
16376
16386
  res.writeHead(200, {
@@ -16784,17 +16794,17 @@ var init_sha256 = __esm({
16784
16794
  });
16785
16795
 
16786
16796
  // ../../core/serve-runtime/src/wix-bridge.ts
16787
- function absoluteUrlRejection(path) {
16797
+ function absoluteUrlRejection(path2) {
16788
16798
  let host = "";
16789
16799
  try {
16790
- host = new URL(path).host;
16800
+ host = new URL(path2).host;
16791
16801
  } catch {
16792
16802
  }
16793
16803
  return OWNER_SCOPED_WIX_HOST.test(host) ? "owner-only" : "open-proxy";
16794
16804
  }
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}`}`;
16805
+ async function wixVisitorCall(method, path2, body, token, fetchImpl = fetch, forwardedHeaders = {}) {
16806
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(path2)) throw new Error("absolute URLs are not allowed");
16807
+ const url = `${WIX_API}${path2.startsWith("/") ? path2 : `/${path2}`}`;
16798
16808
  const res = await fetchImpl(url, {
16799
16809
  method,
16800
16810
  // Same header shape the dev-server bridge has always sent (wixapis accepts the
@@ -16825,13 +16835,13 @@ function normalizeWixForwardedHeaders(input) {
16825
16835
  function isSafeMsid(msid) {
16826
16836
  return /^[0-9a-fA-F-]{10,64}$/.test(msid);
16827
16837
  }
16828
- function isOwnerSitesPath(path) {
16829
- return path === OWNER_SITES_QUERY_PATH || path === OWNER_SITES_COUNT_PATH;
16838
+ function isOwnerSitesPath(path2) {
16839
+ return path2 === OWNER_SITES_QUERY_PATH || path2 === OWNER_SITES_COUNT_PATH;
16830
16840
  }
16831
- async function wixOwnerSitesCall(path, cookieHeader, body, fetchImpl = fetch) {
16832
- if (!isOwnerSitesPath(path)) throw new Error("not an owner-sites path");
16841
+ async function wixOwnerSitesCall(path2, cookieHeader, body, fetchImpl = fetch) {
16842
+ if (!isOwnerSitesPath(path2)) throw new Error("not an owner-sites path");
16833
16843
  const xsrf = /(?:^|;\s*)XSRF-TOKEN=([^;]+)/.exec(cookieHeader)?.[1];
16834
- const res = await fetchImpl(`${WIX_API}${path}`, {
16844
+ const res = await fetchImpl(`${WIX_API}${path2}`, {
16835
16845
  method: "POST",
16836
16846
  headers: {
16837
16847
  Cookie: cookieHeader,
@@ -17106,8 +17116,8 @@ import { resolve as resolve24 } from "node:path";
17106
17116
  import { fileURLToPath as fileURLToPath14 } from "node:url";
17107
17117
  function loadCatalog2(tag) {
17108
17118
  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();
17119
+ const path2 = resolve24(ROOT4, `tools/l10n/catalog.${tag}.json`);
17120
+ const map = existsSync31(path2) ? sourceMap(parseCatalog(readFileSync31(path2, "utf8"))) : /* @__PURE__ */ new Map();
17111
17121
  catalogCache.set(tag, map);
17112
17122
  return map;
17113
17123
  }
@@ -17116,8 +17126,8 @@ function pickLocale(acceptLanguage) {
17116
17126
  const tags = acceptLanguage.split(",").map((s) => s.split(";")[0].trim().toLowerCase()).map((s) => s.split("-")[0]).filter((s) => s.length > 0);
17117
17127
  for (const tag of tags) {
17118
17128
  if (tag === "en") continue;
17119
- const path = resolve24(ROOT4, `tools/l10n/catalog.${tag}.json`);
17120
- if (existsSync31(path)) return tag;
17129
+ const path2 = resolve24(ROOT4, `tools/l10n/catalog.${tag}.json`);
17130
+ if (existsSync31(path2)) return tag;
17121
17131
  }
17122
17132
  return null;
17123
17133
  }
@@ -17213,8 +17223,8 @@ function assignStableIds(descriptor) {
17213
17223
  used.add(out);
17214
17224
  return out;
17215
17225
  };
17216
- const assign2 = (node, path) => {
17217
- const base = node.id && node.id.length > 0 ? node.id : path;
17226
+ const assign2 = (node, path2) => {
17227
+ const base = node.id && node.id.length > 0 ? node.id : path2;
17218
17228
  node.id = uniquify(base);
17219
17229
  const typeCounts = {};
17220
17230
  forEachChildComponent(node, (child) => {
@@ -17222,7 +17232,7 @@ function assignStableIds(descriptor) {
17222
17232
  const n = typeCounts[t] ?? 0;
17223
17233
  typeCounts[t] = n + 1;
17224
17234
  const seg = n === 0 ? t : `${t}.${n}`;
17225
- assign2(child, `${path}/${seg}`);
17235
+ assign2(child, `${path2}/${seg}`);
17226
17236
  });
17227
17237
  };
17228
17238
  if (isNode(descriptor.payload)) assign2(descriptor.payload, descriptor.screenId);
@@ -18142,8 +18152,8 @@ var init_tier4_verifier = __esm({
18142
18152
  async verifyServedFile(bundleId, relPath, providedBytes) {
18143
18153
  const expected = this.expectedSri(bundleId, relPath);
18144
18154
  if (!expected) return { ok: true };
18145
- const path = resolve25(this.tier4Root, bundleId, relPath);
18146
- const bytes2 = providedBytes ?? (existsSync33(path) ? readFileSync33(path) : null);
18155
+ const path2 = resolve25(this.tier4Root, bundleId, relPath);
18156
+ const bytes2 = providedBytes ?? (existsSync33(path2) ? readFileSync33(path2) : null);
18147
18157
  if (!bytes2) return { ok: false, reason: "file not found" };
18148
18158
  if (computeSri(bytes2) !== expected) return { ok: false, reason: "sri mismatch" };
18149
18159
  return { ok: true };
@@ -18235,9 +18245,9 @@ function targetTenant(url, headers2, hostApp) {
18235
18245
  const hdr = headers2["x-himalaya-app"];
18236
18246
  const headerApp = Array.isArray(hdr) ? hdr[0] : hdr;
18237
18247
  let app = headerApp && headerApp.trim() ? headerApp.trim() : void 0;
18238
- const [path, query] = url.split("?");
18248
+ const [path2, query] = url.split("?");
18239
18249
  if (!app) {
18240
- const m = /^\/v1\/(?:app-config|action-handlers)\/([^/?]+)/.exec(path);
18250
+ const m = /^\/v1\/(?:app-config|action-handlers)\/([^/?]+)/.exec(path2);
18241
18251
  if (m) app = decodeURIComponent(m[1]);
18242
18252
  }
18243
18253
  if (!app && query) {
@@ -18249,9 +18259,9 @@ function targetTenant(url, headers2, hostApp) {
18249
18259
  return app;
18250
18260
  }
18251
18261
  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;
18262
+ const path2 = url.split("?")[0];
18263
+ if (path2 === "/v1/apps" || path2 === "/v1/templates") return true;
18264
+ if (!path2.startsWith("/v1/")) return false;
18255
18265
  return targetTenant(url, headers2, hostApp) !== null;
18256
18266
  }
18257
18267
  async function proxyToServe(base, req, res) {
@@ -18511,8 +18521,8 @@ var init_FakeServiceProvider = __esm({
18511
18521
  constructor(services) {
18512
18522
  this.services = services;
18513
18523
  }
18514
- value(path) {
18515
- const raw = path.startsWith("$service:") ? path.slice("$service:".length) : path;
18524
+ value(path2) {
18525
+ const raw = path2.startsWith("$service:") ? path2.slice("$service:".length) : path2;
18516
18526
  const dot = raw.indexOf(".");
18517
18527
  const name = dot < 0 ? raw : raw.slice(0, dot);
18518
18528
  const tail = dot < 0 ? "" : raw.slice(dot + 1);
@@ -18524,8 +18534,8 @@ var init_FakeServiceProvider = __esm({
18524
18534
  }
18525
18535
  return cur;
18526
18536
  }
18527
- subscribe(path, cb) {
18528
- cb(this.value(path));
18537
+ subscribe(path2, cb) {
18538
+ cb(this.value(path2));
18529
18539
  return () => {
18530
18540
  };
18531
18541
  }
@@ -19025,21 +19035,21 @@ function useResolvedScalar(v, ctx) {
19025
19035
  return bound ?? void 0;
19026
19036
  }
19027
19037
  function useBoundValue(ctx, binding2) {
19028
- const path = servicePath(binding2);
19038
+ const path2 = servicePath(binding2);
19029
19039
  const active = !!ctx.provider && !!binding2;
19030
19040
  const [state, setState] = useState(() => ({
19031
- path,
19032
- v: active ? ctx.provider.value(path) : void 0
19041
+ path: path2,
19042
+ v: active ? ctx.provider.value(path2) : void 0
19033
19043
  }));
19034
- const current = state.path === path ? state.v : active ? ctx.provider.value(path) : void 0;
19035
- if (state.path !== path) setState({ path, v: current });
19044
+ const current = state.path === path2 ? state.v : active ? ctx.provider.value(path2) : void 0;
19045
+ if (state.path !== path2) setState({ path: path2, v: current });
19036
19046
  useEffect(() => {
19037
19047
  if (!ctx.provider || !binding2) return;
19038
19048
  return ctx.provider.subscribe(
19039
- path,
19040
- (nv) => setState((prev) => prev.path === path && Object.is(prev.v, nv) ? prev : { path, v: nv })
19049
+ path2,
19050
+ (nv) => setState((prev) => prev.path === path2 && Object.is(prev.v, nv) ? prev : { path: path2, v: nv })
19041
19051
  );
19042
- }, [ctx.provider, path, binding2]);
19052
+ }, [ctx.provider, path2, binding2]);
19043
19053
  return active ? current : void 0;
19044
19054
  }
19045
19055
  function useBoundValues(ctx, bindings) {
@@ -19050,16 +19060,16 @@ function useBoundValues(ctx, bindings) {
19050
19060
  [key2]
19051
19061
  );
19052
19062
  const [values, setValues] = useState(
19053
- () => paths.map((path) => ctx.provider && path ? ctx.provider.value(path) : void 0)
19063
+ () => paths.map((path2) => ctx.provider && path2 ? ctx.provider.value(path2) : void 0)
19054
19064
  );
19055
19065
  useEffect(() => {
19056
19066
  if (!ctx.provider) {
19057
19067
  setValues(paths.map(() => void 0));
19058
19068
  return;
19059
19069
  }
19060
- setValues(paths.map((path) => path ? ctx.provider.value(path) : void 0));
19070
+ setValues(paths.map((path2) => path2 ? ctx.provider.value(path2) : void 0));
19061
19071
  const disposers = paths.map(
19062
- (path, i) => path ? ctx.provider.subscribe(path, (v) => setValues((prev) => {
19072
+ (path2, i) => path2 ? ctx.provider.subscribe(path2, (v) => setValues((prev) => {
19063
19073
  const next = prev.slice();
19064
19074
  next[i] = v;
19065
19075
  return next;
@@ -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) {
@@ -22893,9 +22903,9 @@ var init_worker_subtree = __esm({
22893
22903
  // ../../core/web-renderer/src/renderNode.tsx
22894
22904
  import React5 from "react";
22895
22905
  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);
22906
+ function boundTokenName(path2, fallback, ctx) {
22907
+ if (typeof path2 === "string" && path2) {
22908
+ const r = resolveScalarStatic(path2, ctx);
22899
22909
  if (typeof r === "string" && r) return r;
22900
22910
  }
22901
22911
  return fallback;
@@ -24201,8 +24211,8 @@ function renderNodeInner(node, ctx) {
24201
24211
  }
24202
24212
  }
24203
24213
  const bind = {};
24204
- const addBind = (cssProp, path) => {
24205
- const k = measureKey(path);
24214
+ const addBind = (cssProp, path2) => {
24215
+ const k = measureKey(path2);
24206
24216
  if (k) bind[cssProp] = k;
24207
24217
  };
24208
24218
  addBind("height", m?.heightPath ?? m?.height_path);
@@ -24293,9 +24303,9 @@ function renderNodeInner(node, ctx) {
24293
24303
  }
24294
24304
  return out;
24295
24305
  }
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);
24306
+ function boundModNumber(path2, ctx) {
24307
+ if (typeof path2 !== "string" || !path2 || measureKey(path2) != null || !isBinding(path2)) return void 0;
24308
+ const r = resolveScalarStatic(path2, ctx);
24299
24309
  const n = typeof r === "number" ? r : typeof r === "string" && r.trim() !== "" ? Number(r) : NaN;
24300
24310
  return Number.isFinite(n) ? n : void 0;
24301
24311
  }
@@ -25242,8 +25252,8 @@ var init_renderNode = __esm({
25242
25252
  WorkerSubtreeNode = withExtras("WorkerSubtreeNode", ({ props, ctx, wrap, nodeId }) => {
25243
25253
  const slotId = nodeId;
25244
25254
  const extra = wrap;
25245
- const path = props.treeJsonPath ?? props.tree_json_path;
25246
- const value = useBoundValue(ctx, typeof path === "string" ? path : "");
25255
+ const path2 = props.treeJsonPath ?? props.tree_json_path;
25256
+ const value = useBoundValue(ctx, typeof path2 === "string" ? path2 : "");
25247
25257
  const policy = props.policy;
25248
25258
  const catalog = ctx.provider && typeof ctx.provider.listActions === "function" ? ctx.provider : null;
25249
25259
  const validation = React5.useMemo(() => {
@@ -25672,8 +25682,8 @@ var init_renderNode = __esm({
25672
25682
  this.state = state;
25673
25683
  for (const cb of this.listeners) cb(this.value("media"));
25674
25684
  }
25675
- value(path) {
25676
- const bare = path.replace(/^\$service:/, "");
25685
+ value(path2) {
25686
+ const bare = path2.replace(/^\$service:/, "");
25677
25687
  const parts = bare.split(".").filter(Boolean);
25678
25688
  if (parts[0] === "media") parts.shift();
25679
25689
  let value = this.state;
@@ -25683,8 +25693,8 @@ var init_renderNode = __esm({
25683
25693
  }
25684
25694
  return value;
25685
25695
  }
25686
- subscribe(path, cb) {
25687
- const wrapped = () => cb(this.value(path));
25696
+ subscribe(path2, cb) {
25697
+ const wrapped = () => cb(this.value(path2));
25688
25698
  this.listeners.add(wrapped);
25689
25699
  wrapped();
25690
25700
  return () => this.listeners.delete(wrapped);
@@ -26935,9 +26945,9 @@ var init_renderNode = __esm({
26935
26945
  });
26936
26946
  AvatarStripNode = withExtras("AvatarStripNode", ({ props, ctx, wrap }) => {
26937
26947
  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;
26948
+ const path2 = props.avatarsPath ?? props.avatars_path;
26949
+ const bound = useResolvedScalar(path2, ctx);
26950
+ const raw = path2 != null ? bound : props.avatars;
26941
26951
  const avatars = Array.isArray(raw) ? raw : [];
26942
26952
  const size = props.size ?? 36;
26943
26953
  const maxVisible = props.maxVisible ?? 4;
@@ -28568,27 +28578,27 @@ function resolveTreeScalar(v, provider, itemScope) {
28568
28578
  if (v.startsWith("$service:")) return provider.value(v) ?? void 0;
28569
28579
  return v;
28570
28580
  }
28571
- function collectResolvedMediaRecord(record2, path, context) {
28572
- if (typeof record2.actionId === "string" || path && typeof record2.body === "object") return;
28581
+ function collectResolvedMediaRecord(record2, path2, context) {
28582
+ if (typeof record2.actionId === "string" || path2 && typeof record2.body === "object") return;
28573
28583
  for (const [key2, child] of Object.entries(record2)) {
28574
- collectResolvedMediaValues(child, path ? `${path}.${key2}` : key2, {
28584
+ collectResolvedMediaValues(child, path2 ? `${path2}.${key2}` : key2, {
28575
28585
  ...context,
28576
28586
  insideMediaProperty: context.insideMediaProperty || isMediaValueProperty(key2)
28577
28587
  });
28578
28588
  }
28579
28589
  }
28580
- function collectResolvedMediaValues(value, path, context) {
28590
+ function collectResolvedMediaValues(value, path2, context) {
28581
28591
  const resolved2 = typeof value === "string" ? resolveTreeScalar(value, context.provider, context.itemScope) : value;
28582
28592
  if (typeof resolved2 === "string") {
28583
- if (context.insideMediaProperty) context.values[path] = resolved2;
28593
+ if (context.insideMediaProperty) context.values[path2] = resolved2;
28584
28594
  return;
28585
28595
  }
28586
28596
  if (Array.isArray(resolved2)) {
28587
- resolved2.forEach((item, index) => collectResolvedMediaValues(item, `${path}[${index}]`, context));
28597
+ resolved2.forEach((item, index) => collectResolvedMediaValues(item, `${path2}[${index}]`, context));
28588
28598
  return;
28589
28599
  }
28590
28600
  if (resolved2 && typeof resolved2 === "object") {
28591
- collectResolvedMediaRecord(resolved2, path, context);
28601
+ collectResolvedMediaRecord(resolved2, path2, context);
28592
28602
  }
28593
28603
  }
28594
28604
  function collectComponentMediaValues(type, props, context) {
@@ -28609,12 +28619,12 @@ function collectNativeOnly(node) {
28609
28619
  walk2(node);
28610
28620
  return [...found].sort();
28611
28621
  }
28612
- function buildRenderTree(node, path = "$", provider = null, itemScope = void 0, includeRawProps = false, env = null) {
28622
+ function buildRenderTree(node, path2 = "$", provider = null, itemScope = void 0, includeRawProps = false, env = null) {
28613
28623
  if (!node || typeof node !== "object") return null;
28614
28624
  const obj2 = node;
28615
28625
  const body = obj2.body ?? {};
28616
28626
  const type = typeof body.type === "string" ? body.type : "Unknown";
28617
- const id = typeof obj2.id === "string" && obj2.id ? obj2.id : path;
28627
+ const id = typeof obj2.id === "string" && obj2.id ? obj2.id : path2;
28618
28628
  const out = { id, type };
28619
28629
  if (typeof body.package === "string") out.package = body.package;
28620
28630
  const props = body.props ?? {};
@@ -28723,7 +28733,7 @@ async function renderDescriptorWeb(descriptor, tokens, scheme, wantPng, services
28723
28733
  const stickyHeader = isSduiNode(desc.stickyHeader) ? desc.stickyHeader : void 0;
28724
28734
  const stickyFooter = isSduiNode(desc.stickyFooter) ? desc.stickyFooter : void 0;
28725
28735
  const clientEnv = clientEnvFor(scheme, width, isRTL);
28726
- const treeOf = (node, path, prov) => buildRenderTree(node, path, prov, void 0, true, clientEnv);
28736
+ const treeOf = (node, path2, prov) => buildRenderTree(node, path2, prov, void 0, true, clientEnv);
28727
28737
  const renderTree = composeStickyTree(
28728
28738
  treeOf(payload, "$", null) ?? void 0,
28729
28739
  stickyHeader ? treeOf(stickyHeader, "$.stickyHeader", null) : null,
@@ -28923,8 +28933,8 @@ function declaredFamilies(tokens) {
28923
28933
  async function faceBytes(face, catalog, opts) {
28924
28934
  try {
28925
28935
  if (opts.source) {
28926
- const path = opts.source(face.file, face.sha256);
28927
- return path ? readFileSync34(path) : null;
28936
+ const path2 = opts.source(face.file, face.sha256);
28937
+ return path2 ? readFileSync34(path2) : null;
28928
28938
  }
28929
28939
  const bytes2 = await catalogFaceBytes(face.sha256, { catalog, ...opts.fetchFace ? { fetchFace: opts.fetchFace } : {} });
28930
28940
  return bytes2 ?? null;
@@ -29431,13 +29441,13 @@ function validateName(name) {
29431
29441
  if (typeof name !== "string") fail("name must be a string");
29432
29442
  if (!/^[a-z][a-z0-9]*(?:[-_.][a-z0-9]+)*$/.test(name)) fail(`name must be lowercase kebab-case: "${name}"`);
29433
29443
  }
29434
- function validateFunctionRoute(method, path) {
29444
+ function validateFunctionRoute(method, path2) {
29435
29445
  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}"`);
29446
+ if (path2 !== "/" && (!/^\/[A-Za-z0-9._~!$&'()*+,;=:@%/-]+$/.test(path2) || path2.includes("//") || path2.endsWith("/"))) {
29447
+ fail(`path must be an absolute, normalized route without query syntax: "${path2}"`);
29438
29448
  }
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}"`);
29449
+ const params = [...path2.matchAll(/:([A-Za-z][A-Za-z0-9_]*)/g)].map((match) => match[1]);
29450
+ if (new Set(params).size !== params.length) fail(`path contains duplicate parameter names: "${path2}"`);
29441
29451
  }
29442
29452
  function validateFunctionDefinition(definition) {
29443
29453
  validateName(definition.name);
@@ -30846,9 +30856,9 @@ function nativeSourceFiles(directory, extension, buildDirMaxDepth, depth = 1) {
30846
30856
  return entries.flatMap((entry) => {
30847
30857
  if (NATIVE_SCRATCH_DIRS.has(entry.name)) return [];
30848
30858
  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] : [];
30859
+ const path2 = resolve28(directory, entry.name);
30860
+ if (entry.isDirectory()) return nativeSourceFiles(path2, extension, buildDirMaxDepth, depth + 1);
30861
+ return entry.name.endsWith(extension) ? [path2] : [];
30852
30862
  });
30853
30863
  }
30854
30864
  function registeredActions(source) {
@@ -31111,10 +31121,10 @@ function readJsonAt(app, file, root) {
31111
31121
  }
31112
31122
  }
31113
31123
  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;
31124
+ const path2 = appConfigPath(app, file, root);
31125
+ mkdirSync15(dirname20(path2), { recursive: true });
31126
+ writeFileSync12(path2, JSON.stringify(value, null, 2) + "\n");
31127
+ return path2;
31118
31128
  }
31119
31129
  function sanitizeOverlay(raw) {
31120
31130
  if (!("appIconBadgeSources" in raw)) return raw;
@@ -31350,8 +31360,8 @@ function handleL10nRequest(req, res, state) {
31350
31360
  if (!state.app || app !== state.app.name) {
31351
31361
  return sendJson(res, 404, { error: "unknown_app", app }, cors);
31352
31362
  }
31353
- const path = resolve30(state.app.dir, "l10n", `${tag}.json`);
31354
- if (!existsSync36(path)) {
31363
+ const path2 = resolve30(state.app.dir, "l10n", `${tag}.json`);
31364
+ if (!existsSync36(path2)) {
31355
31365
  res.writeHead(204, cors);
31356
31366
  res.end();
31357
31367
  return;
@@ -31360,7 +31370,7 @@ function handleL10nRequest(req, res, state) {
31360
31370
  let messages;
31361
31371
  try {
31362
31372
  messages = Object.fromEntries(
31363
- keyMap(parseCatalog(readFileSync39(path, "utf8")), { sourceFallback: tag === sourceLocale })
31373
+ keyMap(parseCatalog(readFileSync39(path2, "utf8")), { sourceFallback: tag === sourceLocale })
31364
31374
  );
31365
31375
  } catch {
31366
31376
  return sendJson(res, 500, { error: "catalog_unreadable", app, tag }, cors);
@@ -31590,16 +31600,16 @@ async function handleOwnerSitesRequest(req, res) {
31590
31600
  async function handleOwnerChatRequest(req, res) {
31591
31601
  const cors = { "access-control-allow-origin": "*" };
31592
31602
  const u = new URL(req.url ?? "", "http://localhost");
31593
- const path = u.pathname;
31603
+ const path2 = u.pathname;
31594
31604
  const { resolveMetaSiteId, listChatroomsLive, sendChatMessageLive } = await import("./apps/wix-owner-clone-live.js");
31595
- if (path === "/v1/owner-chat/chatrooms" && req.method === "GET") {
31605
+ if (path2 === "/v1/owner-chat/chatrooms" && req.method === "GET") {
31596
31606
  const metaSiteId = u.searchParams.get("metaSiteId") || await resolveMetaSiteId();
31597
31607
  if (!metaSiteId) return sendJson(res, 400, { error: "no_meta_site" }, cors);
31598
31608
  const rooms = await listChatroomsLive(metaSiteId);
31599
31609
  if (rooms == null) return sendJson(res, 502, { error: "chatrooms_unavailable" }, cors);
31600
31610
  return sendJson(res, 200, { chatrooms: rooms }, cors);
31601
31611
  }
31602
- if (path === "/v1/owner-chat/send" && req.method === "POST") {
31612
+ if (path2 === "/v1/owner-chat/send" && req.method === "POST") {
31603
31613
  let parsed;
31604
31614
  try {
31605
31615
  parsed = JSON.parse(await readBody2(req) || "{}");
@@ -32318,7 +32328,7 @@ function webWixSession(req, res, state) {
32318
32328
  async function handleWebWix(req, res, state) {
32319
32329
  const session = webWixSession(req, res, state);
32320
32330
  const auth = resolveWebWixAuth(state.app);
32321
- const path = new URL(req.url ?? "", "http://localhost").pathname;
32331
+ const path2 = new URL(req.url ?? "", "http://localhost").pathname;
32322
32332
  const readJson3 = async () => {
32323
32333
  const chunks = [];
32324
32334
  for await (const c of req) chunks.push(c);
@@ -32335,7 +32345,7 @@ async function handleWebWix(req, res, state) {
32335
32345
  res.setHeader("access-control-allow-origin", "*");
32336
32346
  res.end(JSON.stringify(obj2));
32337
32347
  };
32338
- if (path === "/v1/__webwix/login" && req.method === "POST") {
32348
+ if (path2 === "/v1/__webwix/login" && req.method === "POST") {
32339
32349
  const b = await readJson3();
32340
32350
  try {
32341
32351
  const { memberToken, visitorToken } = await memberDirectLogin(
@@ -32352,7 +32362,7 @@ async function handleWebWix(req, res, state) {
32352
32362
  return reply(200, { ok: false, error: String(e?.message ?? e) });
32353
32363
  }
32354
32364
  }
32355
- if (path === "/v1/__webwix/call" && req.method === "POST") {
32365
+ if (path2 === "/v1/__webwix/call" && req.method === "POST") {
32356
32366
  const b = await readJson3();
32357
32367
  if (b.ownerMsid !== void 0 || b.checkOwnerSession === true) {
32358
32368
  const msid = String(b.ownerMsid ?? "");
@@ -32439,12 +32449,12 @@ async function handleWebWix(req, res, state) {
32439
32449
  return reply(200, { status: 0, body: JSON.stringify({ error: String(e?.message ?? e) }) });
32440
32450
  }
32441
32451
  }
32442
- if (path === "/v1/__webwix/logout" && req.method === "POST") {
32452
+ if (path2 === "/v1/__webwix/logout" && req.method === "POST") {
32443
32453
  session.memberToken = void 0;
32444
32454
  session.email = void 0;
32445
32455
  return reply(200, { ok: true });
32446
32456
  }
32447
- if (path === "/v1/__webwix/identity" && (req.method === "GET" || req.method === "POST")) {
32457
+ if (path2 === "/v1/__webwix/identity" && (req.method === "GET" || req.method === "POST")) {
32448
32458
  if (!session.memberToken) return reply(200, { authenticated: false, userId: null, email: "" });
32449
32459
  let userId = null;
32450
32460
  try {
@@ -32468,7 +32478,7 @@ async function handleWebWix(req, res, state) {
32468
32478
  } : null
32469
32479
  });
32470
32480
  }
32471
- if (path === "/v1/__webwix/register" && req.method === "POST") {
32481
+ if (path2 === "/v1/__webwix/register" && req.method === "POST") {
32472
32482
  const b = await readJson3();
32473
32483
  try {
32474
32484
  const { memberToken, visitorToken } = await memberDirectRegister(
@@ -32885,8 +32895,8 @@ async function handleDev(req, res, state) {
32885
32895
  }
32886
32896
  async function handleAdminPlayground(req, res, state) {
32887
32897
  const url = req.url ?? "";
32888
- const path = url.split("?")[0];
32889
- const sampleMatch = /^\/v1\/admin\/sdui-samples\/([^/]+)$/.exec(path);
32898
+ const path2 = url.split("?")[0];
32899
+ const sampleMatch = /^\/v1\/admin\/sdui-samples\/([^/]+)$/.exec(path2);
32890
32900
  if (sampleMatch && req.method === "GET") {
32891
32901
  const name = decodeURIComponent(sampleMatch[1]);
32892
32902
  if (!/^[a-zA-Z0-9._-]+$/.test(name)) return sendJson(res, 400, { error: "bad_name" });
@@ -32897,7 +32907,7 @@ async function handleAdminPlayground(req, res, state) {
32897
32907
  return sendJson(res, 404, { error: "sample_not_found", name });
32898
32908
  }
32899
32909
  }
32900
- if (path === "/v1/admin/sdui-samples" && req.method === "GET") {
32910
+ if (path2 === "/v1/admin/sdui-samples" && req.method === "GET") {
32901
32911
  try {
32902
32912
  const { readdir } = await import("node:fs/promises");
32903
32913
  const files = (await readdir(SAMPLES_ROOT)).filter((f) => f.endsWith(".json"));
@@ -32906,7 +32916,7 @@ async function handleAdminPlayground(req, res, state) {
32906
32916
  return sendJson(res, 500, { error: err.message });
32907
32917
  }
32908
32918
  }
32909
- if (path === "/v1/admin/screens" && req.method === "GET") {
32919
+ if (path2 === "/v1/admin/screens" && req.method === "GET") {
32910
32920
  const meta = state.app.meta;
32911
32921
  const fixedIds = meta.screenIds;
32912
32922
  const fixedSet = new Set(fixedIds);
@@ -32955,12 +32965,12 @@ async function handleAdminPlayground(req, res, state) {
32955
32965
  templatedPatterns: meta.templatedPatterns
32956
32966
  });
32957
32967
  }
32958
- const historyMatch = /^\/v1\/admin\/screens\/(.+?)\/history(?:\?|$)/.exec(path);
32968
+ const historyMatch = /^\/v1\/admin\/screens\/(.+?)\/history(?:\?|$)/.exec(path2);
32959
32969
  if (historyMatch && req.method === "GET") {
32960
32970
  const screenId = decodeURIComponent(historyMatch[1]);
32961
32971
  return sendJson(res, 200, { screenId, history: state.localOverrideHistory.get(screenId) ?? [] });
32962
32972
  }
32963
- const revertMatch = /^\/v1\/admin\/screens\/(.+?)\/revert(?:\?|$)/.exec(path);
32973
+ const revertMatch = /^\/v1\/admin\/screens\/(.+?)\/revert(?:\?|$)/.exec(path2);
32964
32974
  if (revertMatch && req.method === "POST") {
32965
32975
  const screenId = decodeURIComponent(revertMatch[1]);
32966
32976
  const historyId = Number(new URLSearchParams(url.split("?")[1] ?? "").get("historyId"));
@@ -32976,7 +32986,7 @@ async function handleAdminPlayground(req, res, state) {
32976
32986
  invalidate(state, screenId);
32977
32987
  return sendJson(res, 200, { status: "ok", screenId, revertedTo: historyId });
32978
32988
  }
32979
- if (path === "/v1/admin/tab-badge" && req.method === "POST") {
32989
+ if (path2 === "/v1/admin/tab-badge" && req.method === "POST") {
32980
32990
  let body;
32981
32991
  try {
32982
32992
  body = JSON.parse(await readBody2(req));
@@ -32995,7 +33005,7 @@ async function handleAdminPlayground(req, res, state) {
32995
33005
  );
32996
33006
  return sendJson(res, 200, { status: "ok", tabId: body.tabId, count: clearing ? null : body.count });
32997
33007
  }
32998
- const validateMatch = /^\/v1\/admin\/screens\/(.+?)\/validate(?:\?|$)/.exec(path);
33008
+ const validateMatch = /^\/v1\/admin\/screens\/(.+?)\/validate(?:\?|$)/.exec(path2);
32999
33009
  if (validateMatch && req.method === "GET") {
33000
33010
  const screenId = decodeURIComponent(validateMatch[1]);
33001
33011
  const strict = /[?&]strict=1(?:&|$)/.test(url);
@@ -33023,7 +33033,7 @@ async function handleAdminPlayground(req, res, state) {
33023
33033
  });
33024
33034
  return sendJson(res, report2.ok ? 200 : 422, report2);
33025
33035
  }
33026
- const detailMatch = /^\/v1\/admin\/screens\/([^/]+)$/.exec(path);
33036
+ const detailMatch = /^\/v1\/admin\/screens\/([^/]+)$/.exec(path2);
33027
33037
  if (detailMatch && req.method === "GET") {
33028
33038
  const screenId = decodeURIComponent(detailMatch[1]);
33029
33039
  const wantBuilt = /[?&]source=built(?:&|$)/.test(url);
@@ -33060,7 +33070,7 @@ async function handleAdminPlayground(req, res, state) {
33060
33070
  invalidate(state, screenId);
33061
33071
  return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
33062
33072
  }
33063
- if (path === "/v1/admin/app-config" && state.app) {
33073
+ if (path2 === "/v1/admin/app-config" && state.app) {
33064
33074
  const built = deriveNavigationConfig(state.app.meta);
33065
33075
  if (req.method === "GET") {
33066
33076
  const effective = state.appConfigOverride ? deepMerge3(built, state.appConfigOverride) : built;
@@ -33085,7 +33095,7 @@ async function handleAdminPlayground(req, res, state) {
33085
33095
  return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
33086
33096
  }
33087
33097
  }
33088
- if (path === "/v1/admin/tokens" && state.app) {
33098
+ if (path2 === "/v1/admin/tokens" && state.app) {
33089
33099
  const built = readAppTokens(state) ?? {};
33090
33100
  if (req.method === "GET") {
33091
33101
  const effective = state.tokensOverride ? deepMerge3(built, state.tokensOverride) : built;
@@ -33110,7 +33120,7 @@ async function handleAdminPlayground(req, res, state) {
33110
33120
  return sendJson(res, existed ? 200 : 404, { status: existed ? "ok" : "not_found" });
33111
33121
  }
33112
33122
  }
33113
- return sendJson(res, 404, { error: "unknown_admin_route", path });
33123
+ return sendJson(res, 404, { error: "unknown_admin_route", path: path2 });
33114
33124
  }
33115
33125
  function isNavControlPatch(patch) {
33116
33126
  if (!patch || typeof patch !== "object") return false;
@@ -33165,10 +33175,10 @@ async function readBundleFile(name, dir) {
33165
33175
  resolve30(root, `${name}.js`),
33166
33176
  resolve30(root, name)
33167
33177
  ]);
33168
- for (const path of candidates) {
33169
- if (!roots.some((root) => path.startsWith(root))) continue;
33178
+ for (const path2 of candidates) {
33179
+ if (!roots.some((root) => path2.startsWith(root))) continue;
33170
33180
  try {
33171
- const bytes2 = await readFile(path);
33181
+ const bytes2 = await readFile(path2);
33172
33182
  const integrity2 = "sha256-" + createHash15("sha256").update(bytes2).digest("base64");
33173
33183
  return { bytes: bytes2, integrity: integrity2 };
33174
33184
  } catch {
@@ -33348,10 +33358,10 @@ function handleActionHandlersManifest(res, app) {
33348
33358
  }
33349
33359
  async function handleActionHandlerBundleGet(res, app) {
33350
33360
  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" });
33361
+ const path2 = resolve30(ACTION_HANDLERS_ROOT, `${app}.handlers.js`);
33362
+ if (!path2.startsWith(ACTION_HANDLERS_ROOT)) return sendJson(res, 404, { error: "not_found" });
33353
33363
  try {
33354
- const bytes2 = await readFile(path);
33364
+ const bytes2 = await readFile(path2);
33355
33365
  const integrity2 = "sha256-" + createHash15("sha256").update(bytes2).digest("base64");
33356
33366
  res.setHeader("content-type", "application/javascript; charset=utf-8");
33357
33367
  res.setHeader("cache-control", "max-age=300");
@@ -34125,13 +34135,13 @@ var init_capability_fixtures = __esm({
34125
34135
  };
34126
34136
  MEDIA_EXT = (url) => {
34127
34137
  if (typeof url !== "string") return null;
34128
- let path;
34138
+ let path2;
34129
34139
  try {
34130
- path = new URL(url).pathname;
34140
+ path2 = new URL(url).pathname;
34131
34141
  } catch {
34132
- path = url.split("#")[0].split("?")[0];
34142
+ path2 = url.split("#")[0].split("?")[0];
34133
34143
  }
34134
- const segment = path.split("/").pop() ?? "";
34144
+ const segment = path2.split("/").pop() ?? "";
34135
34145
  const m = /\.([a-z0-9]{2,5})$/i.exec(segment);
34136
34146
  return m ? m[1].toLowerCase() : null;
34137
34147
  };
@@ -34292,9 +34302,9 @@ var init_capability_fixtures = __esm({
34292
34302
  // made every write resolve to the same file, and a consumer passing that handle onward (an export
34293
34303
  // writing `exports/<id>.gpx`) referenced something that does not exist.
34294
34304
  "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 };
34305
+ const path2 = typeof p.path === "string" && p.path ? p.path : "crawl/written.txt";
34306
+ const name = path2.split("/").pop() || path2;
34307
+ return { uri: `file:///${path2.replace(/^\/+/, "")}`, name, mimeType: typeof p.mimeType === "string" ? p.mimeType : "application/octet-stream", sizeBytes: 1024, modifiedAt: ctx.clock };
34298
34308
  },
34299
34309
  "capability.files.remove": () => ({ removed: true })
34300
34310
  };
@@ -34581,14 +34591,14 @@ function relationalSignature(state) {
34581
34591
  }
34582
34592
  function listLengths(state, depth = 4) {
34583
34593
  const out = {};
34584
- const walk2 = (node, path, left) => {
34594
+ const walk2 = (node, path2, left) => {
34585
34595
  if (left < 0 || node === null || typeof node !== "object") return;
34586
34596
  if (Array.isArray(node)) {
34587
- out[path] = node.length;
34597
+ out[path2] = node.length;
34588
34598
  return;
34589
34599
  }
34590
34600
  for (const [k, v] of Object.entries(node)) {
34591
- walk2(v, path ? `${path}.${k}` : k, left - 1);
34601
+ walk2(v, path2 ? `${path2}.${k}` : k, left - 1);
34592
34602
  }
34593
34603
  };
34594
34604
  walk2(state, "", depth);
@@ -34609,26 +34619,26 @@ function summarizeDiff(aSig, bSig, limit = 3) {
34609
34619
  if (t === void 0) return "undefined";
34610
34620
  return t.length > 80 ? `${t.slice(0, 77)}\u2026` : t;
34611
34621
  };
34612
- const walk2 = (x, y, path) => {
34622
+ const walk2 = (x, y, path2) => {
34613
34623
  if (diffs.length >= limit) return;
34614
34624
  const bothObjects = x !== null && y !== null && typeof x === "object" && typeof y === "object" && !Array.isArray(x) && !Array.isArray(y);
34615
34625
  if (bothObjects) {
34616
34626
  for (const k of /* @__PURE__ */ new Set([...Object.keys(x), ...Object.keys(y)])) {
34617
- walk2(x[k], y[k], path ? `${path}.${k}` : k);
34627
+ walk2(x[k], y[k], path2 ? `${path2}.${k}` : k);
34618
34628
  }
34619
34629
  return;
34620
34630
  }
34621
34631
  if (Array.isArray(x) && Array.isArray(y)) {
34622
34632
  if (x.length !== y.length) {
34623
- diffs.push(`${path || "state"}: ${x.length} \u2192 ${y.length} items`);
34633
+ diffs.push(`${path2 || "state"}: ${x.length} \u2192 ${y.length} items`);
34624
34634
  return;
34625
34635
  }
34626
- for (let i = 0; i < x.length && diffs.length < limit; i++) walk2(x[i], y[i], `${path}[${i}]`);
34636
+ for (let i = 0; i < x.length && diffs.length < limit; i++) walk2(x[i], y[i], `${path2}[${i}]`);
34627
34637
  return;
34628
34638
  }
34629
34639
  const xs = brief(x);
34630
34640
  const ys = brief(y);
34631
- if (xs !== ys) diffs.push(`${path || "state"}: ${xs} \u2192 ${ys}`);
34641
+ if (xs !== ys) diffs.push(`${path2 || "state"}: ${xs} \u2192 ${ys}`);
34632
34642
  };
34633
34643
  walk2(a, b, "");
34634
34644
  return diffs.slice(0, limit).join("; ");
@@ -34717,6 +34727,7 @@ function actionSites(payload) {
34717
34727
  actionId: a.actionId,
34718
34728
  params: a.params ?? {},
34719
34729
  ...a.args ? { args: a.args } : {},
34730
+ ...a.presentation ? { presentation: a.presentation } : {},
34720
34731
  ...ambient ? { itemsPath: ambient } : {},
34721
34732
  // `rec` IS the prop bag that carries this callback — for a plain node that is
34722
34733
  // `body.props`, and for a FormField variant the nested `text`/`picker`/… object, which
@@ -34835,8 +34846,8 @@ function sourceOfStack(stack, bundleMap) {
34835
34846
  return mapBundleFrame(bundleMap, Number(m[1]), Number(m[2]) - 1) ?? void 0;
34836
34847
  }
34837
34848
  function netTransport(rules) {
34838
- return async (method, path, body) => {
34839
- const [bare, search] = String(path).split("?", 2);
34849
+ return async (method, path2, body) => {
34850
+ const [bare, search] = String(path2).split("?", 2);
34840
34851
  const query = {};
34841
34852
  if (search) for (const [k, v] of new URLSearchParams(search)) query[k] = v;
34842
34853
  const res = resolveScenario(rules, {
@@ -34883,9 +34894,9 @@ function layeredTransport(layers) {
34883
34894
  const cms = layers.cmsSeed && Object.keys(layers.cmsSeed).length ? layers.cmsSeed : null;
34884
34895
  const canned = layers.canned && Object.keys(layers.canned).length ? layers.canned : null;
34885
34896
  const label2 = [rules && "mocked", cms && "cms", canned && "canned"].filter(Boolean).join("+") || "offline";
34886
- const call = async (method, path, body) => {
34897
+ const call = async (method, path2, body) => {
34887
34898
  const m = String(method).toUpperCase();
34888
- const p = String(path);
34899
+ const p = String(path2);
34889
34900
  const [bare, search] = p.split("?", 2);
34890
34901
  if (rules) {
34891
34902
  const query = {};
@@ -35364,9 +35375,9 @@ async function crawlScreenInner(opts) {
35364
35375
  const resolveItem = (v) => {
35365
35376
  if (typeof v !== "string" || !v.startsWith("$item")) return v;
35366
35377
  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);
35378
+ const path2 = v === "$item" ? "" : v.startsWith("$item.") ? v.slice("$item.".length) : "";
35379
+ if (!path2) return v;
35380
+ return pathValue(row0, path2);
35370
35381
  };
35371
35382
  const target = resolveItem(merged.screenId);
35372
35383
  if (typeof target !== "string" || !target || target.includes("$")) continue;
@@ -35466,6 +35477,23 @@ async function crawlScreenInner(opts) {
35466
35477
  actionsSkipped.push({ action: s.actionId, why: "embedded-preview" });
35467
35478
  return false;
35468
35479
  });
35480
+ if (!opts.capabilitySuccess) {
35481
+ for (const site of sites) {
35482
+ if (site.actionId !== "himi.open") continue;
35483
+ if (["back", "dismiss", "alert", "snackbar"].includes(site.presentation ?? "")) continue;
35484
+ const target = site.args?.screenId ?? site.params.screenId;
35485
+ if (target != null && target !== "") continue;
35486
+ findings.push({
35487
+ screen: screenId,
35488
+ trigger: "boot",
35489
+ invariant: "nav-target-absent",
35490
+ severity: "error",
35491
+ at: site.componentId ?? void 0,
35492
+ message: '"himi.open" has no screenId \u2014 the tap opens nothing',
35493
+ hint: 'Pass { screenId: "detail", id: "selected-id" } in params. "screen" is not a routing key; put destination input alongside screenId.'
35494
+ });
35495
+ }
35496
+ }
35469
35497
  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
35498
  const check = (trigger, state, errors, defects = {}) => {
35471
35499
  for (const [svc, paths] of Object.entries(defects)) {
@@ -35787,8 +35815,8 @@ async function crawlScreenHostileInner(opts, variant) {
35787
35815
  const base = layeredTransport({ rules: opts.rules, cmsSeed: opts.cmsSeed, canned: opts.canned });
35788
35816
  if (base.label === "offline") return [];
35789
35817
  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]}`);
35818
+ const wixCall = variant === "empty" ? async (method, path2, body) => emptiedArrays(await base.call(method, path2, body)) : async (method, path2) => {
35819
+ throw new Error(`Wix 500 for ${String(method).toUpperCase()} ${String(path2).split("?")[0]}`);
35792
35820
  };
35793
35821
  let w;
35794
35822
  try {
@@ -35991,17 +36019,17 @@ async function crawlScreenDeep(opts, deep) {
35991
36019
  localDbSchema: opts.localDbSchema,
35992
36020
  capabilitySuccess: opts.capabilitySuccess === true
35993
36021
  });
35994
- const pathLabel = (path) => path.map((i) => sites[i].actionId.replace(/^tier5\./, "")).join(" \u2192 ");
36022
+ const pathLabel = (path2) => path2.map((i) => sites[i].actionId.replace(/^tier5\./, "")).join(" \u2192 ");
35995
36023
  while (queue.length) {
35996
36024
  if (visited.size >= maxNodes || dispatches >= maxDispatches) {
35997
36025
  capped = true;
35998
36026
  break;
35999
36027
  }
36000
- const path = queue.shift();
36028
+ const path2 = queue.shift();
36001
36029
  const w = await boot();
36002
36030
  try {
36003
36031
  let threwAt = null;
36004
- for (const [step, siteIdx] of path.entries()) {
36032
+ for (const [step, siteIdx] of path2.entries()) {
36005
36033
  const site = sites[siteIdx];
36006
36034
  const parsed = parseWorkerAction(site.actionId);
36007
36035
  const handle = w.handles[parsed.service];
@@ -36023,7 +36051,7 @@ async function crawlScreenDeep(opts, deep) {
36023
36051
  try {
36024
36052
  await handle.dispatch(parsed.action, ...workerArgs(effective));
36025
36053
  } catch (e) {
36026
- if (step === path.length - 1 && path.length >= 2) {
36054
+ if (step === path2.length - 1 && path2.length >= 2) {
36027
36055
  const source = sourceOfStack(e.stack, opts.bundleMap);
36028
36056
  findings.push({
36029
36057
  screen: screenId,
@@ -36032,7 +36060,7 @@ async function crawlScreenDeep(opts, deep) {
36032
36060
  severity: "error",
36033
36061
  axis: "deep",
36034
36062
  ...source ? { source } : {},
36035
- message: `after ${pathLabel(path)}: ${parsed.action}: ${errText(e)}`,
36063
+ message: `after ${pathLabel(path2)}: ${parsed.action}: ${errText(e)}`,
36036
36064
  hint: "this chain of taps crashes the worker \u2014 each step passed alone, the SEQUENCE is the bug"
36037
36065
  });
36038
36066
  }
@@ -36046,8 +36074,8 @@ async function crawlScreenDeep(opts, deep) {
36046
36074
  const hash = deepStateSignature(state, defects);
36047
36075
  if (visited.has(hash)) continue;
36048
36076
  visited.add(hash);
36049
- if (path.length >= 2) {
36050
- const last = sites[path[path.length - 1]];
36077
+ if (path2.length >= 2) {
36078
+ const last = sites[path2[path2.length - 1]];
36051
36079
  const lastTrigger = { tap: last.componentId, key: last.key, action: last.actionId };
36052
36080
  for (const [svc, paths] of Object.entries(defects)) {
36053
36081
  for (const p of paths) {
@@ -36057,7 +36085,7 @@ async function crawlScreenDeep(opts, deep) {
36057
36085
  invariant: "non-finite-number",
36058
36086
  severity: "error",
36059
36087
  axis: "deep",
36060
- message: `after ${pathLabel(path)}: ${svc} state holds a non-finite number: ${p}`,
36088
+ message: `after ${pathLabel(path2)}: ${svc} state holds a non-finite number: ${p}`,
36061
36089
  at: `${svc}.${p.split(" = ")[0]}`,
36062
36090
  hint: "a chain of taps produced the bad arithmetic \u2014 each step alone was fine; check what the SEQUENCE accumulates"
36063
36091
  });
@@ -36071,7 +36099,7 @@ async function crawlScreenDeep(opts, deep) {
36071
36099
  invariant: d.kind,
36072
36100
  severity: "error",
36073
36101
  axis: "deep",
36074
- message: `after ${pathLabel(path)}: ${resolvedDefectMessage(d)}`,
36102
+ message: `after ${pathLabel(path2)}: ${resolvedDefectMessage(d)}`,
36075
36103
  at,
36076
36104
  field,
36077
36105
  hint: resolvedDefectHint(d)
@@ -36079,8 +36107,8 @@ async function crawlScreenDeep(opts, deep) {
36079
36107
  });
36080
36108
  }
36081
36109
  }
36082
- if (path.length < deep.depth) {
36083
- for (let i = 0; i < sites.length; i++) queue.push([...path, i]);
36110
+ if (path2.length < deep.depth) {
36111
+ for (let i = 0; i < sites.length; i++) queue.push([...path2, i]);
36084
36112
  }
36085
36113
  } finally {
36086
36114
  w.dispose();
@@ -36171,13 +36199,13 @@ async function crawlScreenRelations(opts) {
36171
36199
  capabilitySuccess: opts.capabilitySuccess === true,
36172
36200
  ...opts.evaluator ? { evaluator: opts.evaluator } : {}
36173
36201
  });
36174
- const replay = async (path, rowFor = () => null) => {
36202
+ const replay = async (path2, rowFor = () => null) => {
36175
36203
  const w = await boot();
36176
36204
  try {
36177
36205
  if (w.errors.length) return null;
36178
36206
  let prev = snapshot(w).state;
36179
36207
  const bootState = prev;
36180
- for (const [i, site] of path.entries()) {
36208
+ for (const [i, site] of path2.entries()) {
36181
36209
  const parsed = parseWorkerAction(site.actionId);
36182
36210
  const h = w.handles[parsed.service];
36183
36211
  if (!h || !h.actionNames().includes(parsed.action)) return null;
@@ -36533,9 +36561,9 @@ function routesOverlap(left, right) {
36533
36561
  return segment.startsWith(":") || other.startsWith(":") || segment === other;
36534
36562
  });
36535
36563
  }
36536
- function validateRouteConflicts(definitions) {
36564
+ function validateRouteConflicts(definitions2) {
36537
36565
  const seen = [];
36538
- for (const definition of definitions) {
36566
+ for (const definition of definitions2) {
36539
36567
  validateFunctionDefinition(definition);
36540
36568
  const previous = seen.find((route) => route.method === definition.method && routesOverlap(route.path, definition.path));
36541
36569
  if (previous) throw new Error(`duplicate or ambiguous function route: ${definition.name} conflicts with ${previous.name} at ${definition.method} ${definition.path}`);
@@ -36589,13 +36617,13 @@ function rejectUnsafeSource(name, source) {
36589
36617
  throw new Error(`function ${name} must export handler`);
36590
36618
  }
36591
36619
  }
36592
- async function buildFunctions(definitions, sources, options = {}) {
36593
- validateRouteConflicts(definitions);
36620
+ async function buildFunctions(definitions2, sources, options = {}) {
36621
+ validateRouteConflicts(definitions2);
36594
36622
  validateDependencyPolicy(options.dependencies ?? [], options.dependencyPolicy);
36595
36623
  const sbom = createFunctionSbom(options.dependencies ?? []);
36596
36624
  const runBuild = await (_buildP ??= loadBuild());
36597
36625
  const built = [];
36598
- for (const definition of definitions) {
36626
+ for (const definition of definitions2) {
36599
36627
  const source = sources[definition.name];
36600
36628
  if (typeof source !== "string") throw new Error(`missing source for function ${definition.name}`);
36601
36629
  assertStaticDependencySource(source);
@@ -36747,10 +36775,10 @@ function l10nLintOptions(locale, appDir2) {
36747
36775
  const tags = (locale.translations ?? []).filter((t) => t !== locale.default);
36748
36776
  const catalog = /* @__PURE__ */ new Set();
36749
36777
  for (const tag of tags) {
36750
- const path = join34(appDir2, "l10n", `${tag}.json`);
36751
- if (!existsSync37(path)) continue;
36778
+ const path2 = join34(appDir2, "l10n", `${tag}.json`);
36779
+ if (!existsSync37(path2)) continue;
36752
36780
  try {
36753
- const parsed = JSON.parse(readFileSync40(path, "utf8"));
36781
+ const parsed = JSON.parse(readFileSync40(path2, "utf8"));
36754
36782
  for (const m of Object.values(parsed.messages ?? {})) {
36755
36783
  if (typeof m?.source === "string" && typeof m.translation === "string" && m.translation.length > 0) {
36756
36784
  catalog.add(m.source);
@@ -37020,8 +37048,8 @@ async function buildRelease(app, dest, opts = {}) {
37020
37048
  function countingWixCall(base) {
37021
37049
  let returned = 0;
37022
37050
  return {
37023
- call: async (method, path, body) => {
37024
- const out = await base(method, path, body);
37051
+ call: async (method, path2, body) => {
37052
+ const out = await base(method, path2, body);
37025
37053
  returned += 1;
37026
37054
  return out;
37027
37055
  },
@@ -37112,9 +37140,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
37112
37140
  );
37113
37141
  }
37114
37142
  const token = await mintVisitor(clientId);
37115
- liveWixCall = async (method, path, body) => {
37143
+ liveWixCall = async (method, path2, body) => {
37116
37144
  const bodyStr = body === void 0 ? void 0 : typeof body === "string" ? body : JSON.stringify(body);
37117
- const r = await webWixCall(method, path, bodyStr, token);
37145
+ const r = await webWixCall(method, path2, bodyStr, token);
37118
37146
  if (r.status < 200 || r.status >= 300) throw new Error(`HTTP ${r.status}: ${String(r.body).slice(0, 300)}`);
37119
37147
  try {
37120
37148
  return r.body ? JSON.parse(r.body) : {};
@@ -37211,9 +37239,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
37211
37239
  const MAX_AUTHORING_DOC_BYTES = 128 * 1024;
37212
37240
  if (store.putDoc) {
37213
37241
  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);
37242
+ const path2 = join34(preloaded.dir, file);
37243
+ if (!existsSync37(path2)) continue;
37244
+ const bytes2 = readFileSync40(path2);
37217
37245
  if (bytes2.length === 0 || bytes2.length > MAX_AUTHORING_DOC_BYTES) {
37218
37246
  throw new Error(`${file} must be non-empty and at most ${MAX_AUTHORING_DOC_BYTES} bytes to ship with a release.`);
37219
37247
  }
@@ -37641,7 +37669,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
37641
37669
  }
37642
37670
  if (store.putWidget) {
37643
37671
  const bakedWidgets = await bakeWidgets(
37644
- (path) => devFetch(`${base}${path}`, { headers: { "X-Himalaya-App": app } }),
37672
+ (path2) => devFetch(`${base}${path2}`, { headers: { "X-Himalaya-App": app } }),
37645
37673
  (widgetId, json5) => store.putWidget(app, widgetId, json5),
37646
37674
  // `opts.tier5Dir`, NOT the `tier5Dir` local — that one falls back to the
37647
37675
  // repo-global dir, where this package's widgets cannot be told from anyone
@@ -38400,8 +38428,8 @@ async function captchaRequest(options) {
38400
38428
  }
38401
38429
  const setup = options.operation === "setup";
38402
38430
  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, {
38431
+ const path2 = setup ? "/v1/admin/captcha/setup" : `/v1/admin/captcha?app=${encodeURIComponent(options.input.app)}`;
38432
+ const response = await (options.fetchImpl ?? fetch)(base + path2, {
38405
38433
  method: setup ? "POST" : "GET",
38406
38434
  redirect: "error",
38407
38435
  signal: AbortSignal.timeout(6e4),
@@ -38453,9 +38481,9 @@ __export(captcha_exports, {
38453
38481
  });
38454
38482
  import { readFileSync as readFileSync41 } from "node:fs";
38455
38483
  import { resolve as resolve32 } from "node:path";
38456
- function readObject(path) {
38484
+ function readObject(path2) {
38457
38485
  try {
38458
- return JSON.parse(readFileSync41(path, "utf8"));
38486
+ return JSON.parse(readFileSync41(path2, "utf8"));
38459
38487
  } catch {
38460
38488
  return {};
38461
38489
  }
@@ -38533,11 +38561,11 @@ async function pushSetupRequest(options) {
38533
38561
  return refuse3("push_setup_body_too_large");
38534
38562
  }
38535
38563
  const base = options.target.control.replace(/\/+$/, "");
38536
- let path = "/v1/admin/push/setup";
38564
+ let path2 = "/v1/admin/push/setup";
38537
38565
  if (!setup) {
38538
38566
  const q = new URLSearchParams({ app: options.query.app, site: options.query.site });
38539
38567
  if (options.query.verify) q.set("verify", options.query.verify);
38540
- path += `?${q.toString()}`;
38568
+ path2 += `?${q.toString()}`;
38541
38569
  }
38542
38570
  const headers2 = {
38543
38571
  "x-control-token": options.target.controlToken,
@@ -38548,7 +38576,7 @@ async function pushSetupRequest(options) {
38548
38576
  ...options.previewTag ? { "x-wix-route-serve": options.previewTag } : {}
38549
38577
  };
38550
38578
  try {
38551
- const response = await (options.fetchImpl ?? fetch)(base + path, {
38579
+ const response = await (options.fetchImpl ?? fetch)(base + path2, {
38552
38580
  method: setup ? "POST" : "GET",
38553
38581
  headers: headers2,
38554
38582
  redirect: "error",
@@ -38601,9 +38629,9 @@ var init_push_setup_apple_credentials = __esm({
38601
38629
  // src/push-onboarding.ts
38602
38630
  import { existsSync as existsSync38, mkdirSync as mkdirSync17, readFileSync as readFileSync42, statSync as statSync7, writeFileSync as writeFileSync13, chmodSync as chmodSync2 } from "node:fs";
38603
38631
  import { basename as basename9, dirname as dirname22, join as join35, resolve as resolve33 } from "node:path";
38604
- function readJson2(path) {
38632
+ function readJson2(path2) {
38605
38633
  try {
38606
- const parsed = JSON.parse(readFileSync42(path, "utf8"));
38634
+ const parsed = JSON.parse(readFileSync42(path2, "utf8"));
38607
38635
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
38608
38636
  } catch {
38609
38637
  return {};
@@ -38676,10 +38704,10 @@ function localIdentityRefusal(i) {
38676
38704
  }
38677
38705
  return null;
38678
38706
  }
38679
- function readKeyFile(path) {
38707
+ function readKeyFile(path2) {
38680
38708
  let size;
38681
38709
  try {
38682
- size = statSync7(path).size;
38710
+ size = statSync7(path2).size;
38683
38711
  } catch {
38684
38712
  return { ok: false, code: "key_file_unreadable", reason: "cannot read the selected key file; check its path and file permissions" };
38685
38713
  }
@@ -38688,7 +38716,7 @@ function readKeyFile(path) {
38688
38716
  }
38689
38717
  let body;
38690
38718
  try {
38691
- body = readFileSync42(path, "utf8");
38719
+ body = readFileSync42(path2, "utf8");
38692
38720
  } catch {
38693
38721
  return { ok: false, code: "key_file_unreadable", reason: "cannot read the selected key file; check its path and file permissions" };
38694
38722
  }
@@ -38742,20 +38770,20 @@ function buildPushSetupBody(i, keys) {
38742
38770
  };
38743
38771
  }
38744
38772
  function readPushOnboarding(dir) {
38745
- const path = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
38746
- if (!existsSync38(path)) return { version: 1 };
38747
- const parsed = readJson2(path);
38773
+ const path2 = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
38774
+ if (!existsSync38(path2)) return { version: 1 };
38775
+ const parsed = readJson2(path2);
38748
38776
  return { version: 1, ...parsed };
38749
38777
  }
38750
38778
  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 });
38779
+ const path2 = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
38780
+ mkdirSync17(dirname22(path2), { recursive: true, mode: 448 });
38781
+ writeFileSync13(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
38754
38782
  try {
38755
- chmodSync2(path, 384);
38783
+ chmodSync2(path2, 384);
38756
38784
  } catch {
38757
38785
  }
38758
- return path;
38786
+ return path2;
38759
38787
  }
38760
38788
  function recordPushDeferral(dir, d) {
38761
38789
  const identity = {};
@@ -38777,8 +38805,8 @@ function recordPushDeferral(dir, d) {
38777
38805
  return push;
38778
38806
  }
38779
38807
  function clearPushDeferral(dir) {
38780
- const path = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
38781
- if (!existsSync38(path)) return;
38808
+ const path2 = join35(resolve33(dir), PUSH_ONBOARDING_PATH);
38809
+ if (!existsSync38(path2)) return;
38782
38810
  const { push: _dropped, ...rest } = readPushOnboarding(dir);
38783
38811
  writeFile(dir, { ...rest, version: 1 });
38784
38812
  }
@@ -39405,13 +39433,13 @@ function packagePathFor(pathname) {
39405
39433
  }
39406
39434
  return UNSUPPORTED;
39407
39435
  }
39408
- function parseJson(read, path, errors) {
39409
- const bytes2 = read(path);
39436
+ function parseJson(read, path2, errors) {
39437
+ const bytes2 = read(path2);
39410
39438
  if (!bytes2) return null;
39411
39439
  try {
39412
39440
  return JSON.parse(utf82(bytes2));
39413
39441
  } catch (e) {
39414
- errors.push(`${path} is not valid JSON: ${e.message}`);
39442
+ errors.push(`${path2} is not valid JSON: ${e.message}`);
39415
39443
  return null;
39416
39444
  }
39417
39445
  }
@@ -39832,8 +39860,8 @@ function inflateEntry(buf, entry) {
39832
39860
  verifyZipEntry(entry, bytes2);
39833
39861
  return bytes2;
39834
39862
  }
39835
- function readIf(path) {
39836
- return existsSync39(path) && statSync8(path).isFile() ? readFileSync43(path) : null;
39863
+ function readIf(path2) {
39864
+ return existsSync39(path2) && statSync8(path2).isFile() ? readFileSync43(path2) : null;
39837
39865
  }
39838
39866
  function listDir(dir) {
39839
39867
  return existsSync39(dir) ? readdirSync20(dir).filter((f) => statSync8(join36(dir, f)).isFile()) : [];
@@ -39969,7 +39997,7 @@ function packReleaseToDir(releaseRoot, app, outDir, opts = {}) {
39969
39997
  }
39970
39998
  function openFromEntries(entries, opts) {
39971
39999
  const read = (p) => entries.get(p) ?? null;
39972
- const contentHash = computeContentHash(Array.from(entries, ([path, bytes2]) => ({ path, bytes: bytes2 })));
40000
+ const contentHash = computeContentHash(Array.from(entries, ([path2, bytes2]) => ({ path: path2, bytes: bytes2 })));
39973
40001
  const validation = validatePackage(read, { requireHeader: opts.requireHeader, contentHash });
39974
40002
  return {
39975
40003
  header: validation.header,
@@ -40140,7 +40168,7 @@ function zipAppSource(entries) {
40140
40168
  return writeZip(entries.map((e) => ({ path: e.path, bytes: e.bytes })));
40141
40169
  }
40142
40170
  function readAppSource(zip) {
40143
- return [...readZip(zip)].map(([path, bytes2]) => ({ path, bytes: bytes2 }));
40171
+ return [...readZip(zip)].map(([path2, bytes2]) => ({ path: path2, bytes: bytes2 }));
40144
40172
  }
40145
40173
  function pathKind(p) {
40146
40174
  try {
@@ -40453,24 +40481,24 @@ function readTestConfig(dir) {
40453
40481
  }
40454
40482
  return { ...skip ? { skip } : {}, ...journeys ? { journeys } : {} };
40455
40483
  }
40456
- function readNetRules(path) {
40484
+ function readNetRules(path2) {
40457
40485
  let parsed;
40458
40486
  try {
40459
- parsed = JSON.parse(readFileSync46(path, "utf8"));
40487
+ parsed = JSON.parse(readFileSync46(path2, "utf8"));
40460
40488
  } catch (e) {
40461
- throw new Error(`--net ${path} could not be read as JSON \u2014 ${e.message}`);
40489
+ throw new Error(`--net ${path2} could not be read as JSON \u2014 ${e.message}`);
40462
40490
  }
40463
40491
  const rules = parsed?.rules;
40464
40492
  if (!Array.isArray(rules)) {
40465
- throw new Error(`--net ${path} has no "rules" array \u2014 expected the net-mocks shape { "rules": [ { "matcher": {...}, "response": {...} } ] }`);
40493
+ throw new Error(`--net ${path2} has no "rules" array \u2014 expected the net-mocks shape { "rules": [ { "matcher": {...}, "response": {...} } ] }`);
40466
40494
  }
40467
40495
  const active = rules.filter((r) => r.enabled !== false);
40468
40496
  const shapeErrors = wixMockRuleErrors(active);
40469
40497
  if (shapeErrors.length) {
40470
- throw new Error(`${path}: invalid net-mocks fixture \u2014 ${shapeErrors.join("; ")}`);
40498
+ throw new Error(`${path2}: invalid net-mocks fixture \u2014 ${shapeErrors.join("; ")}`);
40471
40499
  }
40472
40500
  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"`);
40501
+ 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
40502
  }
40475
40503
  return active;
40476
40504
  }
@@ -40509,21 +40537,21 @@ function makeRecordingWixCall(send2, token, app) {
40509
40537
  const events = [];
40510
40538
  const refused = [];
40511
40539
  let id = 0;
40512
- const call = async (method, path, body) => {
40540
+ const call = async (method, path2, body) => {
40513
40541
  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`);
40542
+ if (/[#\x00-\x1F\x7F]/.test(path2)) {
40543
+ refused.push(`${verb} ${path2}`);
40544
+ throw new Error(`--record refused ${verb} ${path2}: the path carries a fragment or control character \u2014 not a provable read`);
40517
40545
  }
40518
- const bare = path.split("?")[0].replace(/\/+$/, "");
40546
+ const bare = path2.split("?")[0].replace(/\/+$/, "");
40519
40547
  const readShaped = verb === "GET" || verb === "POST" && /\/(query|search|list[^/]*|get[^/]*|count|aggregate|facets|connections)$/i.test(bare);
40520
40548
  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`);
40549
+ refused.push(`${verb} ${path2}`);
40550
+ 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
40551
  }
40524
40552
  const bodyStr = body === void 0 ? void 0 : typeof body === "string" ? body : JSON.stringify(body);
40525
40553
  const started = Date.now();
40526
- const r = await send2(method, path, bodyStr, token);
40554
+ const r = await send2(method, path2, bodyStr, token);
40527
40555
  events.push({
40528
40556
  id: ++id,
40529
40557
  ts: started,
@@ -40531,8 +40559,8 @@ function makeRecordingWixCall(send2, token, app) {
40531
40559
  source: "observe",
40532
40560
  host: "www.wixapis.com",
40533
40561
  method,
40534
- url: `https://www.wixapis.com${path}`,
40535
- path,
40562
+ url: `https://www.wixapis.com${path2}`,
40563
+ path: path2,
40536
40564
  status: r.status,
40537
40565
  durationMs: Date.now() - started,
40538
40566
  ...bodyStr !== void 0 ? { reqBody: bodyStr } : {},
@@ -41163,9 +41191,9 @@ var init_auth = __esm({
41163
41191
  });
41164
41192
 
41165
41193
  // ../../core/functions-runtime/src/wix-transport.ts
41166
- function rejectSiteOverride(path) {
41194
+ function rejectSiteOverride(path2) {
41167
41195
  try {
41168
- if (new URL(path, "https://wix.invalid").searchParams.has("msid")) {
41196
+ if (new URL(path2, "https://wix.invalid").searchParams.has("msid")) {
41169
41197
  throw new Error("request cannot override the bound Wix site identity");
41170
41198
  }
41171
41199
  } catch (error) {
@@ -41176,8 +41204,8 @@ function createWixApiCapability(options) {
41176
41204
  const permissions = [...options.permissions ?? []].sort();
41177
41205
  let installation;
41178
41206
  return {
41179
- async call(method, path, body) {
41180
- rejectSiteOverride(path);
41207
+ async call(method, path2, body) {
41208
+ rejectSiteOverride(path2);
41181
41209
  let identity;
41182
41210
  if (options.identity.kind === "caller") {
41183
41211
  identity = { ...options.identity };
@@ -41188,9 +41216,9 @@ function createWixApiCapability(options) {
41188
41216
  throw new Error("installation identity is not authorized for the configured Wix site");
41189
41217
  }
41190
41218
  identity = { kind: "installation", installationId: installation.installationId };
41191
- options.audit?.({ app: options.app, siteId: options.siteId, identity: "installation", method, path });
41219
+ options.audit?.({ app: options.app, siteId: options.siteId, identity: "installation", method, path: path2 });
41192
41220
  }
41193
- return options.transport.call({ app: options.app, siteId: options.siteId, identity, ...permissions.length ? { permissions } : {}, method, path, ...body === void 0 ? {} : { body } });
41221
+ return options.transport.call({ app: options.app, siteId: options.siteId, identity, ...permissions.length ? { permissions } : {}, method, path: path2, ...body === void 0 ? {} : { body } });
41194
41222
  }
41195
41223
  };
41196
41224
  }
@@ -41782,11 +41810,11 @@ var init_sandbox = __esm({
41782
41810
  });
41783
41811
 
41784
41812
  // ../../core/functions-runtime/src/openapi.ts
41785
- function makeFunctionsOpenApi(manifest, definitions = []) {
41813
+ function makeFunctionsOpenApi(manifest, definitions2 = []) {
41786
41814
  const paths = {};
41787
41815
  for (const record2 of manifest.functions ?? []) {
41788
41816
  if (record2.internal) continue;
41789
- const definition = definitions.find((item) => item.name === record2.name);
41817
+ const definition = definitions2.find((item) => item.name === record2.name);
41790
41818
  const method = record2.method.toLowerCase();
41791
41819
  paths[record2.path] = {
41792
41820
  ...paths[record2.path] ?? {},
@@ -42413,9 +42441,9 @@ function resolveTarget2(pathname) {
42413
42441
  return null;
42414
42442
  }
42415
42443
  }
42416
- function chooseFunction(records, method, path) {
42444
+ function chooseFunction(records, method, path2) {
42417
42445
  for (const record2 of records) {
42418
- const params = routeMatch(record2.path, path);
42446
+ const params = routeMatch(record2.path, path2);
42419
42447
  if (params && record2.method === method) return { record: record2, params };
42420
42448
  }
42421
42449
  return null;
@@ -42424,8 +42452,8 @@ async function contentFromBundle(bytes2, record2) {
42424
42452
  const actual = await integrity(bytes2);
42425
42453
  return actual.hash === record2.bundleHash && actual.sri === record2.sri ? utf8Decode(bytes2) : null;
42426
42454
  }
42427
- function definitionFor(definitions, name) {
42428
- return definitions?.find((definition) => definition.name === name);
42455
+ function definitionFor(definitions2, name) {
42456
+ return definitions2?.find((definition) => definition.name === name);
42429
42457
  }
42430
42458
  async function bodyValue(request, record2) {
42431
42459
  const length = Number(request.headers.get("content-length") ?? "0");
@@ -42676,8 +42704,8 @@ function makeFunctionsHandler(options) {
42676
42704
  }
42677
42705
  };
42678
42706
  }
42679
- function functionsOpenApi(manifest, definitions = []) {
42680
- return makeFunctionsOpenApi(manifest, definitions);
42707
+ function functionsOpenApi(manifest, definitions2 = []) {
42708
+ return makeFunctionsOpenApi(manifest, definitions2);
42681
42709
  }
42682
42710
  var MAX_LOG_MESSAGE;
42683
42711
  var init_gateway = __esm({
@@ -42743,19 +42771,19 @@ async function loadFunctionsApp(dir) {
42743
42771
  if (dataErrors.length) throw new Error(`invalid data declaration: ${dataErrors.map((issue2) => issue2.message).join("; ")}`);
42744
42772
  return { app: loaded.name, dir: loaded.dir, definitions: config.functions.functions, sources, siteBinding: config.functions.siteBinding, schedules: config.functions.schedules, ...data ? { data } : {} };
42745
42773
  }
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 }));
42774
+ function listFunctions(definitions2) {
42775
+ return definitions2.map((definition) => ({ name: definition.name, method: definition.method, path: definition.path, auth: definition.auth, internal: definition.internal, limits: definition.limits }));
42748
42776
  }
42749
- function describeFunction(definitions, name) {
42750
- const definition = definitions.find((item) => item.name === name);
42777
+ function describeFunction(definitions2, name) {
42778
+ const definition = definitions2.find((item) => item.name === name);
42751
42779
  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
42780
  }
42753
- function materializeFunctionPath(path, params = {}) {
42754
- const names = [...path.matchAll(/:([A-Za-z][A-Za-z0-9_]*)/g)].map((match) => match[1]);
42781
+ function materializeFunctionPath(path2, params = {}) {
42782
+ const names = [...path2.matchAll(/:([A-Za-z][A-Za-z0-9_]*)/g)].map((match) => match[1]);
42755
42783
  for (const name of names) {
42756
42784
  if (typeof params[name] !== "string" || params[name] === "") throw new Error(`missing route parameter "${name}"; pass --params {"${name}":"value"}`);
42757
42785
  }
42758
- return path.replace(/:([A-Za-z][A-Za-z0-9_]*)/g, (_match, name) => encodeURIComponent(params[name]));
42786
+ return path2.replace(/:([A-Za-z][A-Za-z0-9_]*)/g, (_match, name) => encodeURIComponent(params[name]));
42759
42787
  }
42760
42788
  function memoryStore(manifest, built) {
42761
42789
  const bytes2 = new Map(built.map((item) => [item.bundleHash, item.bytes]));
@@ -42839,8 +42867,8 @@ async function invokeRemoteFunction(input) {
42839
42867
  });
42840
42868
  return { response, url: url.toString() };
42841
42869
  }
42842
- function openApiForFunctions(manifest, definitions) {
42843
- return functionsOpenApi(manifest, definitions);
42870
+ function openApiForFunctions(manifest, definitions2) {
42871
+ return functionsOpenApi(manifest, definitions2);
42844
42872
  }
42845
42873
  async function runRemoteFunctionOperation(input) {
42846
42874
  const environment2 = input.environment ?? "production";
@@ -43092,9 +43120,9 @@ function runAndroidNativeDecode(options) {
43092
43120
  rmSync8(descriptorDir, { recursive: true, force: true });
43093
43121
  }
43094
43122
  }
43095
- function fieldAt(path) {
43096
- if (path === null) return void 0;
43097
- return path.match(/\.([^.[\]]+)$/)?.[1];
43123
+ function fieldAt(path2) {
43124
+ if (path2 === null) return void 0;
43125
+ return path2.match(/\.([^.[\]]+)$/)?.[1];
43098
43126
  }
43099
43127
  function mergeNativeDecode(report2, run2) {
43100
43128
  const platformLabel = run2.platform === "ios" ? "iOS" : "Android";
@@ -44084,8 +44112,8 @@ var init_wix_member_auth = __esm({
44084
44112
  function json3(status, body, headers2 = {}) {
44085
44113
  return new Response(JSON.stringify(body), { status, headers: { "content-type": JSON_CT, ...headers2 } });
44086
44114
  }
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;
44115
+ function isCookieAuthorizedPath(path2) {
44116
+ 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
44117
  }
44090
44118
  function makeServeHandler(opts) {
44091
44119
  let storePromise = null;
@@ -44265,9 +44293,9 @@ ${releaseId}`;
44265
44293
  const handle = async (request) => {
44266
44294
  try {
44267
44295
  const url = new URL(request.url);
44268
- const path = url.pathname;
44296
+ const path2 = url.pathname;
44269
44297
  if (opts.devControl && request.method === "PUT") {
44270
- const dcMatch = /^\/v1\/dev-control\/([^/]+)$/.exec(path);
44298
+ const dcMatch = /^\/v1\/dev-control\/([^/]+)$/.exec(path2);
44271
44299
  if (dcMatch) {
44272
44300
  const dcApp = dcMatch[1];
44273
44301
  let body = {};
@@ -44283,16 +44311,16 @@ ${releaseId}`;
44283
44311
  }
44284
44312
  }
44285
44313
  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")) {
44314
+ if (memberRungApp && (path2 === "/v1/__webwix/login" || path2 === "/v1/__webwix/register" || path2 === MEMBER_CALLBACK_PATH || path2 === "/v1/__webwix/logout")) {
44287
44315
  const store2 = memberSessions();
44288
44316
  if (!store2) return json3(503, { error: "member_auth_unconfigured" });
44289
44317
  const sessionId = readSessionCookie(request.headers.get("cookie"));
44290
- if (path === "/v1/__webwix/logout") {
44318
+ if (path2 === "/v1/__webwix/logout") {
44291
44319
  if (request.method !== "POST") return json3(405, { error: "method_not_allowed" });
44292
44320
  if (sessionId) await store2.delete(sessionId);
44293
44321
  return json3(200, { ok: true }, { "set-cookie": clearSessionCookie(), "cache-control": "no-store" });
44294
44322
  }
44295
- if (path === MEMBER_CALLBACK_PATH) {
44323
+ if (path2 === MEMBER_CALLBACK_PATH) {
44296
44324
  if (request.method !== "GET") return json3(405, { error: "method_not_allowed" });
44297
44325
  const code = url.searchParams.get("code");
44298
44326
  const state2 = url.searchParams.get("state");
@@ -44352,7 +44380,7 @@ ${releaseId}`;
44352
44380
  try {
44353
44381
  const visitor = await webwixTokens.token(resolved2.config.clientId);
44354
44382
  authUrl = await hostedAuthUrl(
44355
- { ...resolved2.config, mode: path.endsWith("/register") ? "signup" : "login", state, challenge: pkce.challenge },
44383
+ { ...resolved2.config, mode: path2.endsWith("/register") ? "signup" : "login", state, challenge: pkce.challenge },
44356
44384
  visitor,
44357
44385
  webwixFetch
44358
44386
  );
@@ -44379,7 +44407,7 @@ ${releaseId}`;
44379
44407
  }
44380
44408
  });
44381
44409
  }
44382
- if ((request.method === "GET" || request.method === "HEAD") && path === "/v1/__webwix/identity") {
44410
+ if ((request.method === "GET" || request.method === "HEAD") && path2 === "/v1/__webwix/identity") {
44383
44411
  const headers2 = { "content-type": JSON_CT, "cache-control": "no-store" };
44384
44412
  if (request.method === "HEAD") return new Response(null, { status: 200, headers: headers2 });
44385
44413
  const webwixDirect = opts.webwixBridge !== false;
@@ -44393,7 +44421,7 @@ ${releaseId}`;
44393
44421
  }
44394
44422
  return json3(200, { authenticated: false, userId: null, email: null, webwixDirect }, { "cache-control": "no-store" });
44395
44423
  }
44396
- if (request.method === "POST" && path === "/v1/__webwix/call") {
44424
+ if (request.method === "POST" && path2 === "/v1/__webwix/call") {
44397
44425
  if (opts.webwixBridge === false) {
44398
44426
  return json3(503, { error: "webwix_bridge_disabled" });
44399
44427
  }
@@ -44496,8 +44524,8 @@ ${releaseId}`;
44496
44524
  }
44497
44525
  }
44498
44526
  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);
44527
+ if (path2 === "/__health") return json3(200, { ok: true });
44528
+ const packageShare = /^\/p\/([a-f0-9]{64})$/.exec(path2);
44501
44529
  if (packageShare) {
44502
44530
  const shareId = packageShare[1];
44503
44531
  const wantsMetadata = url.searchParams.get("metadata") === "1";
@@ -44526,7 +44554,7 @@ ${releaseId}`;
44526
44554
  }
44527
44555
  });
44528
44556
  }
44529
- if (path === "/v1/owner/instance") {
44557
+ if (path2 === "/v1/owner/instance") {
44530
44558
  if (opts.webwixBridge === false) return json3(503, { error: "webwix_bridge_disabled" });
44531
44559
  if (!webwixOwnerRungOn()) return json3(503, { error: "webwix_owner_disabled" });
44532
44560
  const msid = url.searchParams.get("msid") ?? "";
@@ -44542,7 +44570,7 @@ ${releaseId}`;
44542
44570
  return json3(403, { error: "webwix_owner_mint_failed" });
44543
44571
  }
44544
44572
  }
44545
- if (path === "/v1/owner/sites") {
44573
+ if (path2 === "/v1/owner/sites") {
44546
44574
  if (!webwixOwnerRungOn()) return json3(503, { error: "webwix_owner_disabled" });
44547
44575
  const cookie = request.headers.get("cookie") ?? "";
44548
44576
  if (!/wixSession2=/.test(cookie)) return json3(200, { sites: [] });
@@ -44556,7 +44584,7 @@ ${releaseId}`;
44556
44584
  }
44557
44585
  }
44558
44586
  const store = await getStore();
44559
- if (path === "/v1/apps") {
44587
+ if (path2 === "/v1/apps") {
44560
44588
  if (opts.authorizeList && !await opts.authorizeList(request)) {
44561
44589
  return json3(401, { error: "unauthorized" });
44562
44590
  }
@@ -44620,7 +44648,7 @@ ${releaseId}`;
44620
44648
  headers: { "content-type": JSON_CT, ...listHeaders }
44621
44649
  });
44622
44650
  }
44623
- if (path === "/v1/templates") {
44651
+ if (path2 === "/v1/templates") {
44624
44652
  if (opts.authorizeList && !await opts.authorizeList(request)) {
44625
44653
  return json3(401, { error: "unauthorized" });
44626
44654
  }
@@ -44655,7 +44683,7 @@ ${releaseId}`;
44655
44683
  }
44656
44684
  const app = resolveApp(request, url);
44657
44685
  const pin = resolvePin(request, url);
44658
- if (path === "/v1/template-source") {
44686
+ if (path2 === "/v1/template-source") {
44659
44687
  if (!app) return json3(400, { error: "missing_app" });
44660
44688
  if (!store.getSource) return json3(501, { error: "templates_unsupported" });
44661
44689
  const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
@@ -44675,12 +44703,12 @@ ${releaseId}`;
44675
44703
  const denied = await authorizePinnedRead(request, url, app, pin);
44676
44704
  if (denied) return denied;
44677
44705
  }
44678
- if (path === "/v1/authoring-docs" || /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.test(path)) {
44706
+ if (path2 === "/v1/authoring-docs" || /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.test(path2)) {
44679
44707
  if (!app) return json3(400, { error: "missing_app" });
44680
44708
  const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
44681
44709
  if (!m) return json3(404, { error: pin ? "release_not_found" : "no_release", app });
44682
44710
  const docs = m.authoringDocs ?? {};
44683
- const match = /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.exec(path);
44711
+ const match = /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.exec(path2);
44684
44712
  if (!match) {
44685
44713
  return json3(200, {
44686
44714
  app,
@@ -44708,7 +44736,7 @@ ${releaseId}`;
44708
44736
  }
44709
44737
  });
44710
44738
  }
44711
- if (path === "/v1/release/current") {
44739
+ if (path2 === "/v1/release/current") {
44712
44740
  if (pin) {
44713
44741
  const m2 = app ? await pinnedManifest(app, pin) : null;
44714
44742
  if (!m2) return json3(404, { error: "release_not_found", app, releaseId: pin });
@@ -44718,7 +44746,7 @@ ${releaseId}`;
44718
44746
  if (!m) return json3(404, { error: "no_release", app });
44719
44747
  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
44748
  }
44721
- const bundleMatch = /^\/v1\/bundles\/([a-f0-9]{64})\.bundle\.js$/.exec(path);
44749
+ const bundleMatch = /^\/v1\/bundles\/([a-f0-9]{64})\.bundle\.js$/.exec(path2);
44722
44750
  if (bundleMatch) {
44723
44751
  const hash = bundleMatch[1];
44724
44752
  const m = app ? pin ? await pinnedManifest(app, pin) : await manifest(app) : null;
@@ -44735,7 +44763,7 @@ ${releaseId}`;
44735
44763
  }
44736
44764
  });
44737
44765
  }
44738
- if (path === "/v1/boot") {
44766
+ if (path2 === "/v1/boot") {
44739
44767
  if (!app) return json3(400, { error: "missing_app" });
44740
44768
  let m;
44741
44769
  if (pin) {
@@ -44804,7 +44832,7 @@ ${releaseId}`;
44804
44832
  }
44805
44833
  return json3(200, { releaseId: mm.releaseId, app, appConfig, tokens, homeScreenId, screen, homeBundle }, { etag, "cache-control": cache, ...vary });
44806
44834
  }
44807
- if (path === "/v1/tokens") {
44835
+ if (path2 === "/v1/tokens") {
44808
44836
  if (!app) return json3(400, { error: "missing_app" });
44809
44837
  if (pin) {
44810
44838
  const m = await pinnedManifest(app, pin);
@@ -44817,7 +44845,7 @@ ${releaseId}`;
44817
44845
  if (!bytes2) return json3(404, { error: "tokens_not_found", app });
44818
44846
  return sendDoc(request, bytes2);
44819
44847
  }
44820
- if (path === "/v1/l10n") {
44848
+ if (path2 === "/v1/l10n") {
44821
44849
  if (!app) return json3(400, { error: "missing_app" });
44822
44850
  const tag = (url.searchParams.get("tag") ?? "").trim();
44823
44851
  if (!/^[a-z]{2}(-[A-Za-z0-9]+)?$/.test(tag)) {
@@ -44832,7 +44860,7 @@ ${releaseId}`;
44832
44860
  if (!bytes2) return new Response(null, { status: 204 });
44833
44861
  return sendDoc(request, bytes2, Boolean(pin));
44834
44862
  }
44835
- if (path === "/v1/app-icon") {
44863
+ if (path2 === "/v1/app-icon") {
44836
44864
  if (!app) return json3(400, { error: "missing_app" });
44837
44865
  if (!store.getIcon) return json3(501, { error: "icons_unsupported" });
44838
44866
  const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
@@ -44849,7 +44877,7 @@ ${releaseId}`;
44849
44877
  headers: { "content-type": "image/png", etag, "cache-control": BUNDLE_CACHE_CONTROL, "x-himalaya-app": app }
44850
44878
  });
44851
44879
  }
44852
- const assetMatch = /^\/v1\/asset\/([^/?]+)$/.exec(path);
44880
+ const assetMatch = /^\/v1\/asset\/([^/?]+)$/.exec(path2);
44853
44881
  if (assetMatch) {
44854
44882
  if (!app) return json3(400, { error: "missing_app" });
44855
44883
  if (!store.getAsset) return json3(501, { error: "assets_unsupported" });
@@ -44878,7 +44906,7 @@ ${releaseId}`;
44878
44906
  }
44879
44907
  });
44880
44908
  }
44881
- const ahMatch = /^\/v1\/action-handlers\/([^/]+)$/.exec(path);
44909
+ const ahMatch = /^\/v1\/action-handlers\/([^/]+)$/.exec(path2);
44882
44910
  if (ahMatch) {
44883
44911
  const ahApp = ahMatch[1];
44884
44912
  const m = await manifest(ahApp);
@@ -44891,7 +44919,7 @@ ${releaseId}`;
44891
44919
  }));
44892
44920
  return json3(200, { handlers });
44893
44921
  }
44894
- const cfgMatch = /^\/v1\/app-config\/([^/]+)$/.exec(path);
44922
+ const cfgMatch = /^\/v1\/app-config\/([^/]+)$/.exec(path2);
44895
44923
  if (cfgMatch) {
44896
44924
  const cfgApp = cfgMatch[1];
44897
44925
  if (pin) {
@@ -44911,7 +44939,7 @@ ${releaseId}`;
44911
44939
  }
44912
44940
  return sendDoc(request, bytes2);
44913
44941
  }
44914
- const screenMatch = /^\/v1\/screen\/([^/]+)$/.exec(path);
44942
+ const screenMatch = /^\/v1\/screen\/([^/]+)$/.exec(path2);
44915
44943
  if (screenMatch) {
44916
44944
  const screenId = screenMatch[1];
44917
44945
  if (!app || !isSafeSegment(screenId)) return json3(404, { error: "screen_not_found", screenId });
@@ -44943,14 +44971,14 @@ ${releaseId}`;
44943
44971
  headers: { "content-type": JSON_CT, etag, "cache-control": DOC_CACHE_CONTROL, "x-himalaya-app": app }
44944
44972
  });
44945
44973
  }
44946
- if (path === "/v1/widgets") {
44974
+ if (path2 === "/v1/widgets") {
44947
44975
  if (!app) return json3(400, { error: "missing_app" });
44948
44976
  const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
44949
44977
  if (!m) return json3(404, { error: pin ? "release_not_found" : "no_release", app });
44950
44978
  const widgets = Object.entries(m.widgets ?? {}).map(([widgetId, meta]) => ({ widgetId, contentEtag: meta.contentEtag }));
44951
44979
  return json3(200, { widgets });
44952
44980
  }
44953
- const widgetMatch = /^\/v1\/widget\/([^/]+)$/.exec(path);
44981
+ const widgetMatch = /^\/v1\/widget\/([^/]+)$/.exec(path2);
44954
44982
  if (widgetMatch) {
44955
44983
  const widgetId = widgetMatch[1];
44956
44984
  if (!app || !isSafeSegment(widgetId)) return json3(404, { error: "widget_not_found", widgetId });
@@ -45151,25 +45179,25 @@ function makeRunHandler(opts) {
45151
45179
  });
45152
45180
  return async (request) => {
45153
45181
  const url = new URL(request.url);
45154
- const path = url.pathname;
45155
- if (path === "/v1/release/resolve") {
45182
+ const path2 = url.pathname;
45183
+ if (path2 === "/v1/release/resolve") {
45156
45184
  return json4(
45157
45185
  200,
45158
45186
  { app: opts.app, releaseId: opts.header?.releaseId ?? null, source: "local" },
45159
45187
  { "cache-control": "no-store" }
45160
45188
  );
45161
45189
  }
45162
- if (path === "/v1/revocations") {
45190
+ if (path2 === "/v1/revocations") {
45163
45191
  return json4(
45164
45192
  200,
45165
45193
  { app: opts.app, revokedIntegrities: [], version: 0, ttlSeconds: 30 },
45166
45194
  { "cache-control": "max-age=30" }
45167
45195
  );
45168
45196
  }
45169
- if (path.startsWith("/v1/flags/")) {
45197
+ if (path2.startsWith("/v1/flags/")) {
45170
45198
  return json4(200, { app: opts.app, definitions: {} }, { "cache-control": "no-store" });
45171
45199
  }
45172
- if (path === "/v1/telemetry/ingest") {
45200
+ if (path2 === "/v1/telemetry/ingest") {
45173
45201
  if (request.method !== "POST") return json4(405, { error: "method_not_allowed" });
45174
45202
  try {
45175
45203
  const body = await request.json();
@@ -45179,33 +45207,33 @@ function makeRunHandler(opts) {
45179
45207
  }
45180
45208
  return new Response(null, { status: 204 });
45181
45209
  }
45182
- if (path === "/v1/screen-events") {
45210
+ if (path2 === "/v1/screen-events") {
45183
45211
  return new Response(new ReadableStream({ start() {
45184
45212
  } }), {
45185
45213
  status: 200,
45186
45214
  headers: { "content-type": "text/event-stream", "cache-control": "no-store", connection: "keep-alive" }
45187
45215
  });
45188
45216
  }
45189
- if (path.startsWith("/v1/__webwix/") && path !== "/v1/__webwix/call" && path !== "/v1/__webwix/identity" && !(opts.serve?.webwixMemberAuth === true && opts.serve?.webwixMemberSessions)) {
45217
+ if (path2.startsWith("/v1/__webwix/") && path2 !== "/v1/__webwix/call" && path2 !== "/v1/__webwix/identity" && !(opts.serve?.webwixMemberAuth === true && opts.serve?.webwixMemberSessions)) {
45190
45218
  return json4(501, { error: "webwix_member_auth_unavailable" });
45191
45219
  }
45192
- if (path === "/v1/app-config" || path.startsWith("/v1/app-config/")) {
45220
+ if (path2 === "/v1/app-config" || path2.startsWith("/v1/app-config/")) {
45193
45221
  return localizeConfigResponse(await serve(request), "app-config", opts.header ?? null);
45194
45222
  }
45195
- if (path === "/v1/boot") {
45223
+ if (path2 === "/v1/boot") {
45196
45224
  return localizeConfigResponse(await serve(request), "boot", opts.header ?? null);
45197
45225
  }
45198
- if (path === "/v1" || path.startsWith("/v1/") || path === "/__health") {
45226
+ if (path2 === "/v1" || path2.startsWith("/v1/") || path2 === "/__health") {
45199
45227
  return serve(request);
45200
45228
  }
45201
- if (path === "/" || path === "") {
45229
+ if (path2 === "/" || path2 === "") {
45202
45230
  const target = `${mount}/a/${encodeURIComponent(opts.app)}${url.search}`;
45203
45231
  return new Response(null, { status: 302, headers: { location: target } });
45204
45232
  }
45205
- if (path === mount || path.startsWith(`${mount}/`)) {
45206
- return previewResponse(path, opts.assets, mount);
45233
+ if (path2 === mount || path2.startsWith(`${mount}/`)) {
45234
+ return previewResponse(path2, opts.assets, mount);
45207
45235
  }
45208
- return json4(404, { error: "not_found", path });
45236
+ return json4(404, { error: "not_found", path: path2 });
45209
45237
  };
45210
45238
  }
45211
45239
  var json4;
@@ -45414,9 +45442,9 @@ async function loadPreviewAssets() {
45414
45442
  join46(here, "../../../packages/serve/src/preview-assets.generated.bin")
45415
45443
  // in-repo checkout
45416
45444
  ];
45417
- for (const path of candidates) {
45418
- if (!existsSync49(path)) continue;
45419
- const blob = readFileSync54(path);
45445
+ for (const path2 of candidates) {
45446
+ if (!existsSync49(path2)) continue;
45447
+ const blob = readFileSync54(path2);
45420
45448
  return mod.assemblePreviewAssetsFromBlob(new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength));
45421
45449
  }
45422
45450
  return /* @__PURE__ */ new Map();
@@ -45426,9 +45454,9 @@ async function loadPreviewAssets() {
45426
45454
  }
45427
45455
  function packageUrl(origin, app, opts = {}) {
45428
45456
  const mount = opts.chrome === "app" ? "/app" : "/preview";
45429
- const path = `${mount}/a/${encodeURIComponent(app)}${opts.screen ? `/screen/${encodeURIComponent(opts.screen)}` : ""}`;
45457
+ const path2 = `${mount}/a/${encodeURIComponent(app)}${opts.screen ? `/screen/${encodeURIComponent(opts.screen)}` : ""}`;
45430
45458
  const query = opts.surface ? `?surface=${encodeURIComponent(opts.surface)}` : "";
45431
- return `${origin.replace(/\/$/, "")}${path}${query}`;
45459
+ return `${origin.replace(/\/$/, "")}${path2}${query}`;
45432
45460
  }
45433
45461
  function openBrowser(url) {
45434
45462
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
@@ -45588,13 +45616,13 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
45588
45616
  const body = JSON.stringify(payload);
45589
45617
  const missed = [];
45590
45618
  const server = createServer5((req, res) => {
45591
- const path = (req.url ?? "/").split("?")[0];
45592
- if (path === "/release.json") {
45619
+ const path2 = (req.url ?? "/").split("?")[0];
45620
+ if (path2 === "/release.json") {
45593
45621
  res.writeHead(200, { "content-type": "application/json", "cache-control": "no-store" });
45594
45622
  res.end(body);
45595
45623
  return;
45596
45624
  }
45597
- const name = path === "/" || path === "/index.html" ? "host.html" : path.slice(1);
45625
+ const name = path2 === "/" || path2 === "/index.html" ? "host.html" : path2.slice(1);
45598
45626
  if (SERVED.has(name)) {
45599
45627
  if (!existsSync50(resolve40(stagedDir(), name))) {
45600
45628
  const restaged = ensureBrowserPlaneStaged();
@@ -45621,9 +45649,9 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
45621
45649
  res.end(bytes2);
45622
45650
  return;
45623
45651
  }
45624
- missed.push(path);
45652
+ missed.push(path2);
45625
45653
  res.writeHead(404, { "content-type": "application/json" });
45626
- res.end(JSON.stringify({ error: "reached_the_cli_not_the_worker", path }));
45654
+ res.end(JSON.stringify({ error: "reached_the_cli_not_the_worker", path: path2 }));
45627
45655
  });
45628
45656
  await new Promise((r) => server.listen(opts.port ?? 0, "127.0.0.1", () => r()));
45629
45657
  const port = server.address().port;
@@ -46833,8 +46861,8 @@ function client(creds) {
46833
46861
  const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
46834
46862
  assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
46835
46863
  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}` } });
46864
+ return async (path2) => {
46865
+ const r = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
46838
46866
  return { status: r.status, json: await r.json().catch(() => ({})) };
46839
46867
  };
46840
46868
  }
@@ -47094,24 +47122,24 @@ import { dirname as dirname29, join as join49 } from "node:path";
47094
47122
  function defaultSessionsPath() {
47095
47123
  return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join49(homedir6(), ".himalaya", "admin-sessions.json");
47096
47124
  }
47097
- function loadSessionsFile(path = defaultSessionsPath()) {
47125
+ function loadSessionsFile(path2 = defaultSessionsPath()) {
47098
47126
  try {
47099
- return JSON.parse(readFileSync63(path, "utf8"));
47127
+ return JSON.parse(readFileSync63(path2, "utf8"));
47100
47128
  } catch {
47101
47129
  return {};
47102
47130
  }
47103
47131
  }
47104
- function saveAdminSession(adminUrl, session, path = defaultSessionsPath()) {
47105
- const file = loadSessionsFile(path);
47132
+ function saveAdminSession(adminUrl, session, path2 = defaultSessionsPath()) {
47133
+ const file = loadSessionsFile(path2);
47106
47134
  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 });
47135
+ mkdirSync24(dirname29(path2), { recursive: true, mode: 448 });
47136
+ writeFileSync21(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
47109
47137
  try {
47110
- chmodSync3(dirname29(path), 448);
47111
- chmodSync3(path, 384);
47138
+ chmodSync3(dirname29(path2), 448);
47139
+ chmodSync3(path2, 384);
47112
47140
  } catch {
47113
47141
  }
47114
- return path;
47142
+ return path2;
47115
47143
  }
47116
47144
  function resolveAuth(opts = {}) {
47117
47145
  const env = opts.env ?? process.env;
@@ -47417,9 +47445,9 @@ var init_types2 = __esm({
47417
47445
  });
47418
47446
 
47419
47447
  // src/site-analyze/rest.ts
47420
- function resolveWixUrl(path) {
47421
- if (/^https?:\/\//i.test(path)) return path;
47422
- return `${WIX_API3}${path}`;
47448
+ function resolveWixUrl(path2) {
47449
+ if (/^https?:\/\//i.test(path2)) return path2;
47450
+ return `${WIX_API3}${path2}`;
47423
47451
  }
47424
47452
  function classifyHttp(status, count) {
47425
47453
  if (status === 428) return "not-installed";
@@ -47428,12 +47456,12 @@ function classifyHttp(status, count) {
47428
47456
  return count > 0 ? "ok" : "empty";
47429
47457
  }
47430
47458
  function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS4) {
47431
- return async (method, path, body) => {
47459
+ return async (method, path2, body) => {
47432
47460
  const headers2 = { Accept: "application/json" };
47433
47461
  if (auth?.token) headers2.Authorization = auth.token;
47434
47462
  if (auth?.msid) headers2["wix-site-id"] = auth.msid;
47435
47463
  if (body !== void 0) headers2["Content-Type"] = "application/json";
47436
- const res = await fetchImpl(resolveWixUrl(path), {
47464
+ const res = await fetchImpl(resolveWixUrl(path2), {
47437
47465
  method,
47438
47466
  headers: headers2,
47439
47467
  body: body === void 0 ? void 0 : JSON.stringify(body),
@@ -47445,7 +47473,7 @@ function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS4) {
47445
47473
  parsed = text4 ? JSON.parse(text4) : null;
47446
47474
  } catch {
47447
47475
  }
47448
- if (!res.ok) throw new WixApiError2(res.status, method, path, parsed);
47476
+ if (!res.ok) throw new WixApiError2(res.status, method, path2, parsed);
47449
47477
  return parsed;
47450
47478
  };
47451
47479
  }
@@ -47455,9 +47483,9 @@ function ownerTransportFrom(fetchImpl, owner) {
47455
47483
  function visitorTransportFrom(fetchImpl, token, msid) {
47456
47484
  return makeTransport(fetchImpl, { token, msid });
47457
47485
  }
47458
- async function probeCall(call, method, path, body) {
47486
+ async function probeCall(call, method, path2, body) {
47459
47487
  try {
47460
- return { data: await call(method, path, body), err: null };
47488
+ return { data: await call(method, path2, body), err: null };
47461
47489
  } catch (e) {
47462
47490
  if (e instanceof WixApiError2) return { data: null, err: e };
47463
47491
  throw e;
@@ -47519,11 +47547,11 @@ var init_rest = __esm({
47519
47547
  WIX_API3 = "https://www.wixapis.com";
47520
47548
  DEFAULT_TIMEOUT_MS4 = 8e3;
47521
47549
  WixApiError2 = class extends Error {
47522
- constructor(status, method, path, body) {
47523
- super(`${method} ${path} \u2192 ${status}`);
47550
+ constructor(status, method, path2, body) {
47551
+ super(`${method} ${path2} \u2192 ${status}`);
47524
47552
  this.status = status;
47525
47553
  this.method = method;
47526
- this.path = path;
47554
+ this.path = path2;
47527
47555
  this.body = body;
47528
47556
  this.name = "WixApiError";
47529
47557
  }
@@ -47731,8 +47759,8 @@ function toItems(def, raw) {
47731
47759
  description: copyOrDrop(def.descriptionOf ? def.descriptionOf(it) : genericDescription(it), 240) || void 0
47732
47760
  }));
47733
47761
  }
47734
- async function runDualProbes(owner, visitor) {
47735
- const rows = await Promise.all(ALL.map(async (def) => {
47762
+ async function runDualProbes(owner, visitor, definitions2 = ALL) {
47763
+ const rows = await Promise.all(definitions2.map(async (def) => {
47736
47764
  const [o, vis] = await Promise.all([side(owner, def), side(visitor, def)]);
47737
47765
  const imageless = def.imageOf ? o.items.filter((it) => !def.imageOf(it)).length : void 0;
47738
47766
  return {
@@ -47794,7 +47822,7 @@ function sampleTitle(data) {
47794
47822
  }
47795
47823
  return void 0;
47796
47824
  }
47797
- async function readCms(call) {
47825
+ async function readCms(call, opts = {}) {
47798
47826
  if (!call) return { collections: [], status: "skipped" };
47799
47827
  const { data, err } = await probeCall(call, "GET", "/data/v2/collections");
47800
47828
  if (err) {
@@ -47819,7 +47847,7 @@ async function readCms(call) {
47819
47847
  ...f.encrypted === true ? { encrypted: true } : {}
47820
47848
  })).filter((f) => f.key);
47821
47849
  const perms = c.permissions && typeof c.permissions === "object" ? c.permissions : void 0;
47822
- const q = await probeCall(call, "POST", "/wix-data/v2/items/query", {
47850
+ const q = opts.samples === false ? { data: null, err: null } : await probeCall(call, "POST", "/wix-data/v2/items/query", {
47823
47851
  dataCollectionId: id,
47824
47852
  query: { paging: { limit: 5 } }
47825
47853
  });
@@ -47856,8 +47884,8 @@ async function readInstalledApps(call) {
47856
47884
  "/site-apps/v1/apps",
47857
47885
  "/devcenter/v1/apps"
47858
47886
  ];
47859
- for (const path of paths) {
47860
- const { data } = await probeCall(call, "GET", path);
47887
+ for (const path2 of paths) {
47888
+ const { data } = await probeCall(call, "GET", path2);
47861
47889
  if (!data) continue;
47862
47890
  const raw = asArr(data.apps ?? data.siteApps ?? data.items);
47863
47891
  const apps = raw.map((a) => ({
@@ -47873,8 +47901,8 @@ async function readMemberRoles(call) {
47873
47901
  const paths = ["/members/v1/roles", "/members/v2/roles", "/authorization/v1/roles"];
47874
47902
  let sawAuthError = false;
47875
47903
  let sawEmptyPayload = false;
47876
- for (const path of paths) {
47877
- const { data, err } = await probeCall(call, "GET", path);
47904
+ for (const path2 of paths) {
47905
+ const { data, err } = await probeCall(call, "GET", path2);
47878
47906
  if (err) {
47879
47907
  if (err.status === 401 || err.status === 403 || err.status >= 500) sawAuthError = true;
47880
47908
  continue;
@@ -48345,15 +48373,15 @@ function pagePathForRole(url) {
48345
48373
  }
48346
48374
  }
48347
48375
  function classifyPageRole(url, title, _nav = "") {
48348
- const { path, isHome } = pagePathForRole(url);
48376
+ const { path: path2, isHome } = pagePathForRole(url);
48349
48377
  if (isHome) return "home";
48350
- const hay = `${path} ${title}`.toLowerCase();
48378
+ const hay = `${path2} ${title}`.toLowerCase();
48351
48379
  if (/\b(faq|help|support)\b/.test(hay)) return "faq";
48352
48380
  if (/\b(pricing|membership|member-plan|plans?)\b/.test(hay)) return "plans";
48353
48381
  if (/\b(drill|library|resource|session-builder|session-generator)\b/.test(hay)) return "library";
48354
48382
  if (/\b(members?|account|login|profile)\b/.test(hay) && !/\bmembership\b/.test(hay)) return "members";
48355
48383
  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";
48384
+ if (/(^|\/)(book|book-online|bookings?)(\/|$)/.test(path2) || /\b(book-online|bookings?|appoint)\b/.test(hay)) return "book";
48357
48385
  if (/\b(menu|dining|restaurant)\b/.test(hay)) return "menu";
48358
48386
  if (/\b(blog|journal|news|posts?|ebooks?|insight)\b/.test(hay)) return "blog";
48359
48387
  if (/\b(about|story|our-story)\b/.test(hay)) return "about";
@@ -49007,12 +49035,12 @@ function veloListFilesPath(gridAppId, layout) {
49007
49035
  async function gridAppIdFromSiteHtml(fetchImpl, siteUrl) {
49008
49036
  return (await readPublishedHtml(fetchImpl, siteUrl)).gridAppId;
49009
49037
  }
49010
- function assertSafeVeloPath(path, method = "GET") {
49011
- if (VELO_INVOKE_RE.test(path)) {
49012
- throw new Error(`refusing to call Velo invoke path: ${path}`);
49038
+ function assertSafeVeloPath(path2, method = "GET") {
49039
+ if (VELO_INVOKE_RE.test(path2)) {
49040
+ throw new Error(`refusing to call Velo invoke path: ${path2}`);
49013
49041
  }
49014
- if (method !== "GET" && VELO_WRITE_RE.test(path.split("?")[0] ?? path)) {
49015
- throw new Error(`refusing to call Velo write path: ${method} ${path}`);
49042
+ if (method !== "GET" && VELO_WRITE_RE.test(path2.split("?")[0] ?? path2)) {
49043
+ throw new Error(`refusing to call Velo write path: ${method} ${path2}`);
49016
49044
  }
49017
49045
  }
49018
49046
  function parseHttpFunctions(source) {
@@ -49031,8 +49059,8 @@ function parseHttpFunctions(source) {
49031
49059
  }
49032
49060
  return out;
49033
49061
  }
49034
- function classifyVeloFile(path) {
49035
- const p = path.replace(/\\/g, "/").toLowerCase();
49062
+ function classifyVeloFile(path2) {
49063
+ const p = path2.replace(/\\/g, "/").toLowerCase();
49036
49064
  const base = p.split("/").pop() ?? p;
49037
49065
  if (base === "http-functions.js" || base === "http-functions.ts") return "http-functions";
49038
49066
  if (base === "data.js" || base === "data.ts") return "data-hooks";
@@ -49044,8 +49072,8 @@ function classifyVeloFile(path) {
49044
49072
  if (/(^|\/)public\//.test(p)) return "public";
49045
49073
  return "other";
49046
49074
  }
49047
- function isSecretVeloPath(path) {
49048
- const p = path.replace(/\\/g, "/").toLowerCase();
49075
+ function isSecretVeloPath(path2) {
49076
+ const p = path2.replace(/\\/g, "/").toLowerCase();
49049
49077
  return /secrets-backend|\/secrets\/|\.env(?:\.|$)/.test(p);
49050
49078
  }
49051
49079
  function redactSecrets(source) {
@@ -49075,7 +49103,7 @@ function str4(x) {
49075
49103
  function asArr2(x) {
49076
49104
  return Array.isArray(x) ? x : [];
49077
49105
  }
49078
- function filesFromOwnerPayload(data) {
49106
+ function filesFromOwnerPayload(data, redact = redactSecrets) {
49079
49107
  if (!data || typeof data !== "object") return [];
49080
49108
  const root = data;
49081
49109
  const raw = [
@@ -49087,17 +49115,17 @@ function filesFromOwnerPayload(data) {
49087
49115
  for (const item of raw) {
49088
49116
  if (!item || typeof item !== "object") continue;
49089
49117
  const f = item;
49090
- const path = str4(f.path || f.relativePath || f.fileName || f.name);
49091
- if (!path || isSecretVeloPath(path)) continue;
49118
+ const path2 = str4(f.path || f.relativePath || f.fileName || f.name);
49119
+ if (!path2 || isSecretVeloPath(path2)) continue;
49092
49120
  const content = str4(f.content ?? f.source ?? f.code ?? f.body);
49093
49121
  const bytes2 = typeof f.bytes === "number" ? f.bytes : typeof f.size === "number" ? f.size : content.length;
49094
- const redacted = content ? redactSecrets(content) : "";
49122
+ const redacted = content ? redact(content) : "";
49095
49123
  const forDisk = redacted.length > VELO_FILE_CAP ? redacted.slice(0, VELO_FILE_CAP) + "\n/* \u2026truncated */" : redacted;
49096
49124
  out.push({
49097
- path,
49098
- kind: classifyVeloFile(path),
49125
+ path: path2,
49126
+ kind: classifyVeloFile(path2),
49099
49127
  bytes: bytes2,
49100
- excerpt: content ? redactExcerpt(content) : void 0,
49128
+ excerpt: content ? redactExcerpt(redacted) : void 0,
49101
49129
  ...forDisk ? { content: forDisk } : {}
49102
49130
  });
49103
49131
  }
@@ -49140,8 +49168,8 @@ function veloHintFromEval(evaled, page) {
49140
49168
  pages: [{ url: page.url, title: page.title, hasCode: wixRendered && hasCode, ...pageId ? { pageId } : {} }]
49141
49169
  };
49142
49170
  }
49143
- function pageIdFromVeloPath(path) {
49144
- const m = path.replace(/\\/g, "/").match(/\/pages\/([A-Za-z0-9_-]+)\.(js|ts|jsx|tsx)$/i);
49171
+ function pageIdFromVeloPath(path2) {
49172
+ const m = path2.replace(/\\/g, "/").match(/\/pages\/([A-Za-z0-9_-]+)\.(js|ts|jsx|tsx)$/i);
49145
49173
  return m?.[1];
49146
49174
  }
49147
49175
  function bindVeloFiles(files, pages) {
@@ -49186,13 +49214,13 @@ function gridAppIdsFromPayload(data) {
49186
49214
  }
49187
49215
  return ids;
49188
49216
  }
49189
- async function listFilesForApp(call, gridAppId) {
49217
+ async function listFilesForApp(call, gridAppId, redact) {
49190
49218
  for (const layout of VELO_LAYOUTS) {
49191
- const path = veloListFilesPath(gridAppId, layout);
49192
- assertSafeVeloPath(path, "GET");
49193
- const { data } = await probeCall(call, "GET", path);
49219
+ const path2 = veloListFilesPath(gridAppId, layout);
49220
+ assertSafeVeloPath(path2, "GET");
49221
+ const { data } = await probeCall(call, "GET", path2);
49194
49222
  if (!data) continue;
49195
- const files = filesFromOwnerPayload(data);
49223
+ const files = filesFromOwnerPayload(data, redact);
49196
49224
  if (files.length) return files;
49197
49225
  }
49198
49226
  return [];
@@ -49214,7 +49242,7 @@ async function readOwnerVelo(call, opts) {
49214
49242
  if (probe.path.includes("git-repo") && (data.repo || data.repository || data.gitRepo || data.url)) git2 = true;
49215
49243
  }
49216
49244
  for (const id of ids) {
49217
- const listed = await listFilesForApp(call, id);
49245
+ const listed = await listFilesForApp(call, id, opts?.redact);
49218
49246
  for (const f of listed) {
49219
49247
  if (!files.some((x) => x.path === f.path)) files.push(f);
49220
49248
  }
@@ -49551,14 +49579,14 @@ function parseAuthorizationConfig(source) {
49551
49579
  const defaultAnonymousInvoke = invokeFlag(starDefault, "anonymous") ?? true;
49552
49580
  const defaultSiteMemberInvoke = invokeFlag(starDefault, "siteMember") ?? true;
49553
49581
  const modules = [];
49554
- for (const [path, entry] of Object.entries(web)) {
49555
- if (path === "*") continue;
49582
+ for (const [path2, entry] of Object.entries(web)) {
49583
+ if (path2 === "*") continue;
49556
49584
  const star = methodStar(entry);
49557
49585
  const anonymousInvoke = invokeFlag(star, "anonymous") ?? defaultAnonymousInvoke;
49558
49586
  const siteMemberInvoke = invokeFlag(star, "siteMember") ?? defaultSiteMemberInvoke;
49559
- const jsw = /\.(jsw|web\.js)$/i.test(path);
49587
+ const jsw = /\.(jsw|web\.js)$/i.test(path2);
49560
49588
  modules.push({
49561
- path,
49589
+ path: path2,
49562
49590
  anonymousInvoke,
49563
49591
  siteMemberInvoke,
49564
49592
  ...jsw ? { note: "worker-unreachable" } : {}
@@ -50697,12 +50725,12 @@ function attachVeloSources(book, sources, put) {
50697
50725
  }
50698
50726
  }
50699
50727
  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";
50728
+ const path2 = url.split("?")[0] ?? url;
50729
+ if (/\.png$/i.test(path2)) return "png";
50730
+ if (/\.webp$/i.test(path2)) return "webp";
50731
+ if (/\.gif$/i.test(path2)) return "gif";
50732
+ if (/\.svg$/i.test(path2)) return "svg";
50733
+ if (/\.ico$/i.test(path2)) return "ico";
50706
50734
  return "jpg";
50707
50735
  }
50708
50736
  async function readCapped(res, cap) {
@@ -51273,8 +51301,8 @@ function unpairedRedirectNote(overlay) {
51273
51301
  function posix2(p) {
51274
51302
  return resolve42(p).replace(/\\/g, "/");
51275
51303
  }
51276
- function committedShellProvisioning(path) {
51277
- return committedShellFor(posix2(path));
51304
+ function committedShellProvisioning(path2) {
51305
+ return committedShellFor(posix2(path2));
51278
51306
  }
51279
51307
  function findRepoRoot(cwd) {
51280
51308
  let dir = cwd;
@@ -51298,14 +51326,14 @@ function deepMerge4(a, b) {
51298
51326
  }
51299
51327
  return out;
51300
51328
  }
51301
- function assertNotCommitted(path, forbidden) {
51302
- const committed = committedShellProvisioning(path);
51329
+ function assertNotCommitted(path2, forbidden) {
51330
+ const committed = committedShellProvisioning(path2);
51303
51331
  if (committed) {
51304
51332
  throw new Error(
51305
51333
  `refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
51306
51334
  );
51307
51335
  }
51308
- if (forbidden && resolve42(path) === resolve42(forbidden)) {
51336
+ if (forbidden && resolve42(path2) === resolve42(forbidden)) {
51309
51337
  const named = committedShellProvisioning(forbidden);
51310
51338
  throw new Error(
51311
51339
  `refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
@@ -51411,13 +51439,13 @@ function buildMergedContract(options) {
51411
51439
  merged.branding = branding;
51412
51440
  const body = `${JSON.stringify(merged, null, 2)}
51413
51441
  `;
51414
- const path = join51(packageDir, "provisioning.contract.json");
51415
- writeFileSync23(path, body);
51442
+ const path2 = join51(packageDir, "provisioning.contract.json");
51443
+ writeFileSync23(path2, body);
51416
51444
  const localPath = join51(appDir2, LOCAL_CONTRACT_REL);
51417
51445
  mkdirSync26(dirname30(localPath), { recursive: true });
51418
51446
  writeFileSync23(localPath, body);
51419
51447
  staged.push(localPath);
51420
- return { path, staged };
51448
+ return { path: path2, staged };
51421
51449
  }
51422
51450
  async function applyOverlays(input) {
51423
51451
  const cwd = resolve42(input.cwd);
@@ -52849,18 +52877,18 @@ function cookieCompare(a, b) {
52849
52877
  cmp = (a.creationIndex || 0) - (b.creationIndex || 0);
52850
52878
  return cmp;
52851
52879
  }
52852
- function defaultPath(path) {
52853
- if (!path || path.slice(0, 1) !== "/") {
52880
+ function defaultPath(path2) {
52881
+ if (!path2 || path2.slice(0, 1) !== "/") {
52854
52882
  return "/";
52855
52883
  }
52856
- if (path === "/") {
52857
- return path;
52884
+ if (path2 === "/") {
52885
+ return path2;
52858
52886
  }
52859
- const rightSlash = path.lastIndexOf("/");
52887
+ const rightSlash = path2.lastIndexOf("/");
52860
52888
  if (rightSlash === 0) {
52861
52889
  return "/";
52862
52890
  }
52863
- return path.slice(0, rightSlash);
52891
+ return path2.slice(0, rightSlash);
52864
52892
  }
52865
52893
  function domainMatch(domain, cookieDomain, canonicalize) {
52866
52894
  if (domain == null || cookieDomain == null) {
@@ -53088,18 +53116,18 @@ var init_dist = __esm({
53088
53116
  /**
53089
53117
  * @internal No doc because this is an overload that supports the implementation
53090
53118
  */
53091
- findCookie(domain, path, key2, callback) {
53119
+ findCookie(domain, path2, key2, callback) {
53092
53120
  const promiseCallback = createPromiseCallback(callback);
53093
- if (domain == null || path == null || key2 == null) {
53121
+ if (domain == null || path2 == null || key2 == null) {
53094
53122
  return promiseCallback.resolve(void 0);
53095
53123
  }
53096
- const result = this.idx[domain]?.[path]?.[key2];
53124
+ const result = this.idx[domain]?.[path2]?.[key2];
53097
53125
  return promiseCallback.resolve(result);
53098
53126
  }
53099
53127
  /**
53100
53128
  * @internal No doc because this is an overload that supports the implementation
53101
53129
  */
53102
- findCookies(domain, path, allowSpecialUseDomain = false, callback) {
53130
+ findCookies(domain, path2, allowSpecialUseDomain = false, callback) {
53103
53131
  if (typeof allowSpecialUseDomain === "function") {
53104
53132
  callback = allowSpecialUseDomain;
53105
53133
  allowSpecialUseDomain = true;
@@ -53110,7 +53138,7 @@ var init_dist = __esm({
53110
53138
  return promiseCallback.resolve([]);
53111
53139
  }
53112
53140
  let pathMatcher;
53113
- if (!path) {
53141
+ if (!path2) {
53114
53142
  pathMatcher = function matchAll(domainIndex) {
53115
53143
  for (const curPath in domainIndex) {
53116
53144
  const pathIndex = domainIndex[curPath];
@@ -53125,7 +53153,7 @@ var init_dist = __esm({
53125
53153
  } else {
53126
53154
  pathMatcher = function matchRFC(domainIndex) {
53127
53155
  for (const cookiePath in domainIndex) {
53128
- if (pathMatch(path, cookiePath)) {
53156
+ if (pathMatch(path2, cookiePath)) {
53129
53157
  const pathIndex = domainIndex[cookiePath];
53130
53158
  for (const key2 in pathIndex) {
53131
53159
  const value = pathIndex[key2];
@@ -53153,14 +53181,14 @@ var init_dist = __esm({
53153
53181
  */
53154
53182
  putCookie(cookie, callback) {
53155
53183
  const promiseCallback = createPromiseCallback(callback);
53156
- const { domain, path, key: key2 } = cookie;
53157
- if (domain == null || path == null || key2 == null) {
53184
+ const { domain, path: path2, key: key2 } = cookie;
53185
+ if (domain == null || path2 == null || key2 == null) {
53158
53186
  return promiseCallback.resolve(void 0);
53159
53187
  }
53160
53188
  const domainEntry = this.idx[domain] ?? /* @__PURE__ */ Object.create(null);
53161
53189
  this.idx[domain] = domainEntry;
53162
- const pathEntry = domainEntry[path] ?? /* @__PURE__ */ Object.create(null);
53163
- domainEntry[path] = pathEntry;
53190
+ const pathEntry = domainEntry[path2] ?? /* @__PURE__ */ Object.create(null);
53191
+ domainEntry[path2] = pathEntry;
53164
53192
  pathEntry[key2] = cookie;
53165
53193
  return promiseCallback.resolve(void 0);
53166
53194
  }
@@ -53174,20 +53202,20 @@ var init_dist = __esm({
53174
53202
  /**
53175
53203
  * @internal No doc because this is an overload that supports the implementation
53176
53204
  */
53177
- removeCookie(domain, path, key2, callback) {
53205
+ removeCookie(domain, path2, key2, callback) {
53178
53206
  const promiseCallback = createPromiseCallback(callback);
53179
- delete this.idx[domain]?.[path]?.[key2];
53207
+ delete this.idx[domain]?.[path2]?.[key2];
53180
53208
  return promiseCallback.resolve(void 0);
53181
53209
  }
53182
53210
  /**
53183
53211
  * @internal No doc because this is an overload that supports the implementation
53184
53212
  */
53185
- removeCookies(domain, path, callback) {
53213
+ removeCookies(domain, path2, callback) {
53186
53214
  const promiseCallback = createPromiseCallback(callback);
53187
53215
  const domainEntry = this.idx[domain];
53188
53216
  if (domainEntry) {
53189
- if (path) {
53190
- delete domainEntry[path];
53217
+ if (path2) {
53218
+ delete domainEntry[path2];
53191
53219
  } else {
53192
53220
  delete this.idx[domain];
53193
53221
  }
@@ -53213,8 +53241,8 @@ var init_dist = __esm({
53213
53241
  domains.forEach((domain) => {
53214
53242
  const domainEntry = idx[domain] ?? {};
53215
53243
  const paths = Object.keys(domainEntry);
53216
- paths.forEach((path) => {
53217
- const pathEntry = domainEntry[path] ?? {};
53244
+ paths.forEach((path2) => {
53245
+ const pathEntry = domainEntry[path2] ?? {};
53218
53246
  const keys = Object.keys(pathEntry);
53219
53247
  keys.forEach((key2) => {
53220
53248
  const keyEntry = pathEntry[key2];
@@ -53982,7 +54010,7 @@ var init_dist = __esm({
53982
54010
  return promiseCallback.reject(parameterError);
53983
54011
  }
53984
54012
  const host = canonicalDomain(context.hostname);
53985
- const path = context.pathname || "/";
54013
+ const path2 = context.pathname || "/";
53986
54014
  const potentiallyTrustworthy = isPotentiallyTrustworthy(
53987
54015
  url,
53988
54016
  this.allowSecureOnLocal
@@ -54013,7 +54041,7 @@ var init_dist = __esm({
54013
54041
  return false;
54014
54042
  }
54015
54043
  }
54016
- if (!allPaths && typeof c.path === "string" && !pathMatch(path, c.path)) {
54044
+ if (!allPaths && typeof c.path === "string" && !pathMatch(path2, c.path)) {
54017
54045
  return false;
54018
54046
  }
54019
54047
  if (c.secure && !potentiallyTrustworthy) {
@@ -54045,7 +54073,7 @@ var init_dist = __esm({
54045
54073
  }
54046
54074
  store.findCookies(
54047
54075
  host,
54048
- allPaths ? null : path,
54076
+ allPaths ? null : path2,
54049
54077
  this.allowSpecialUseDomain,
54050
54078
  (err, cookies) => {
54051
54079
  if (err) {
@@ -55423,9 +55451,9 @@ function filesFromList(data) {
55423
55451
  if (!Array.isArray(files)) return [];
55424
55452
  return files.flatMap((f) => {
55425
55453
  if (!f || typeof f !== "object") return [];
55426
- const path = String(f.path ?? "");
55454
+ const path2 = String(f.path ?? "");
55427
55455
  const content = String(f.content ?? "");
55428
- return path ? [{ path, content }] : [];
55456
+ return path2 ? [{ path: path2, content }] : [];
55429
55457
  });
55430
55458
  }
55431
55459
  async function resolveGridAppId(fetchImpl, token, msid, siteUrl) {
@@ -55852,14 +55880,14 @@ function apiKeyAuth(env = process.env) {
55852
55880
  return key2 && accountId ? { key: key2, accountId } : void 0;
55853
55881
  }
55854
55882
  function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, spawnImpl = spawn4) {
55855
- return async (method, path, body) => {
55883
+ return async (method, path2, body) => {
55856
55884
  const viaKey = apiKeyAuth();
55857
55885
  const headers2 = viaKey ? { Authorization: viaKey.key, "wix-account-id": viaKey.accountId, Accept: "application/json" } : { Authorization: await accountToken2(spawnImpl), Accept: "application/json" };
55858
55886
  if (body !== void 0) headers2["Content-Type"] = "application/json";
55859
55887
  const started = Date.now();
55860
55888
  let res;
55861
55889
  try {
55862
- res = await fetchImpl(`${API_BASE2}${path}`, {
55890
+ res = await fetchImpl(`${API_BASE2}${path2}`, {
55863
55891
  method,
55864
55892
  headers: headers2,
55865
55893
  body: body === void 0 ? void 0 : JSON.stringify(body),
@@ -55869,10 +55897,10 @@ function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, sp
55869
55897
  const err = e;
55870
55898
  if (err?.name === "TimeoutError" || /aborted due to timeout/i.test(err?.message ?? "")) {
55871
55899
  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.`
55900
+ `${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
55901
  );
55874
55902
  }
55875
- throw new Error(`${method} ${path} failed: ${err?.message ?? String(e)}`);
55903
+ throw new Error(`${method} ${path2} failed: ${err?.message ?? String(e)}`);
55876
55904
  }
55877
55905
  const text4 = await res.text();
55878
55906
  let parsed = text4;
@@ -55880,7 +55908,7 @@ function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, sp
55880
55908
  parsed = text4 ? JSON.parse(text4) : null;
55881
55909
  } catch {
55882
55910
  }
55883
- if (!res.ok) throw new WixApiError(res.status, method, path, parsed);
55911
+ if (!res.ok) throw new WixApiError(res.status, method, path2, parsed);
55884
55912
  return parsed;
55885
55913
  };
55886
55914
  }
@@ -56159,27 +56187,27 @@ async function runSiteCreate(opts) {
56159
56187
  }
56160
56188
  function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync55, readFileSync: readFileSync66, writeFileSync: writeFileSync24 }) {
56161
56189
  const msid = binding2.siteId;
56162
- const path = resolvePath2(target);
56163
- const committed = committedShellProvisioning(path);
56190
+ const path2 = resolvePath2(target);
56191
+ const committed = committedShellProvisioning(path2);
56164
56192
  if (committed) {
56165
56193
  throw new Error(
56166
56194
  `refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 pass a content-package provisioning.json, or use \`prepare:customer --contract\``
56167
56195
  );
56168
56196
  }
56169
- if (!fs.existsSync(path)) {
56197
+ if (!fs.existsSync(path2)) {
56170
56198
  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>.`
56199
+ `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
56200
  );
56173
56201
  }
56174
- const raw = fs.readFileSync(path, "utf8");
56202
+ const raw = fs.readFileSync(path2, "utf8");
56175
56203
  let manifest;
56176
56204
  try {
56177
56205
  manifest = JSON.parse(raw);
56178
56206
  } catch (e) {
56179
- throw new Error(`${path} is not valid JSON (${e?.message ?? e}) \u2014 not touching it`);
56207
+ throw new Error(`${path2} is not valid JSON (${e?.message ?? e}) \u2014 not touching it`);
56180
56208
  }
56181
56209
  if (manifest === null || typeof manifest !== "object" || Array.isArray(manifest)) {
56182
- throw new Error(`${path} must contain a JSON object \u2014 not touching it`);
56210
+ throw new Error(`${path2} must contain a JSON object \u2014 not touching it`);
56183
56211
  }
56184
56212
  if (binding2.siteUrl !== void 0) assertAbsoluteHttpUrl(binding2.siteUrl);
56185
56213
  if (binding2.redirectUri !== void 0) assertRedirectUri(binding2.redirectUri);
@@ -56197,9 +56225,9 @@ function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSyn
56197
56225
  const indentMatch = /^[ \t]*[{[][\r\n]+([ \t]+)/.exec(raw);
56198
56226
  const indent = indentMatch ? indentMatch[1] : " ";
56199
56227
  const trailingNewline = /\n$/.test(raw) ? "\n" : "";
56200
- fs.writeFileSync(path, `${JSON.stringify(manifest, null, indent)}${trailingNewline}`, "utf8");
56228
+ fs.writeFileSync(path2, `${JSON.stringify(manifest, null, indent)}${trailingNewline}`, "utf8");
56201
56229
  return {
56202
- path,
56230
+ path: path2,
56203
56231
  siteId: msid,
56204
56232
  ...binding2.clientId ? { clientId: binding2.clientId } : {},
56205
56233
  ...binding2.siteUrl ? { siteUrl: binding2.siteUrl } : {},
@@ -56488,6 +56516,347 @@ var init_site_oauth_client = __esm({
56488
56516
  }
56489
56517
  });
56490
56518
 
56519
+ // src/site-analyze/velo-source.ts
56520
+ import path from "node:path";
56521
+ import ts from "typescript";
56522
+ function applySourceEdits(source, edits) {
56523
+ const chunks = [];
56524
+ let cursor = 0;
56525
+ for (const edit of edits.sort((a, b) => a.start - b.start || b.end - a.end)) {
56526
+ if (edit.start < cursor) continue;
56527
+ chunks.push(source.slice(cursor, edit.start), edit.text);
56528
+ cursor = edit.end;
56529
+ }
56530
+ chunks.push(source.slice(cursor));
56531
+ return chunks.join("");
56532
+ }
56533
+ function redactVeloSource(source, knownSecrets = []) {
56534
+ for (const secret of knownSecrets.filter(Boolean)) source = source.split(secret).join(REDACTED2);
56535
+ source = source.replace(/-----BEGIN [^-]*PRIVATE KEY-----[\s\S]*?-----END [^-]*PRIVATE KEY-----/g, REDACTED2).replace(
56536
+ /\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,
56537
+ REDACTED2
56538
+ ).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]");
56539
+ const parsed = ts.createSourceFile("backend.ts", source, ts.ScriptTarget.Latest, true);
56540
+ const comments = /* @__PURE__ */ new Map();
56541
+ const visitComments = (node) => {
56542
+ for (const range of [
56543
+ ...ts.getLeadingCommentRanges(source, node.pos) ?? [],
56544
+ ...ts.getTrailingCommentRanges(source, node.pos) ?? [],
56545
+ ...ts.getTrailingCommentRanges(source, node.end) ?? []
56546
+ ]) comments.set(range.pos, range.end);
56547
+ for (const child of node.getChildren(parsed)) visitComments(child);
56548
+ };
56549
+ visitComments(parsed);
56550
+ source = applySourceEdits(source, [...comments].map(([start, end]) => ({ start, end, text: " " })));
56551
+ const redactLiteral = (token, offset) => {
56552
+ const before = assignmentContext.slice(Math.max(0, offset - 200), offset);
56553
+ if (/^\s*:/.test(source.slice(offset + token.length)) && /[{,]\s*$/.test(before)) return token;
56554
+ const statement = before.slice(before.lastIndexOf(";") + 1);
56555
+ const sensitiveAssignment = [
56556
+ ...statement.matchAll(/([\w$-]+|"[^"\n]+"|'[^'\n]+')\s*(?:\]\s*)?[:=]/g)
56557
+ ].some((match) => sensitiveName.test(match[1]));
56558
+ const headerArgument = /(?:set|append)\s*\(\s*["']([^"']+)["']\s*,\s*$/.exec(before);
56559
+ if (sensitiveAssignment || sensitiveName.test(headerArgument?.[1] ?? ""))
56560
+ return JSON.stringify(REDACTED2);
56561
+ if (/^["'`][A-Za-z0-9_+/=-]{24,}["'`]$/.test(token)) return JSON.stringify(REDACTED2);
56562
+ return token;
56563
+ };
56564
+ const clean2 = ts.createSourceFile("backend.ts", source, ts.ScriptTarget.Latest, true);
56565
+ const masks = [];
56566
+ const collectMasks = (node) => {
56567
+ const start = node.getStart(clean2);
56568
+ if (ts.isRegularExpressionLiteral(node)) {
56569
+ masks.push({ start, end: node.end, text: " ".repeat(node.end - start) });
56570
+ } else if (ts.isStringLiteral(node) || ts.isTemplateLiteralToken(node)) {
56571
+ masks.push({ start, end: node.end, text: source.slice(start, node.end).replace(/;/g, " ") });
56572
+ }
56573
+ ts.forEachChild(node, collectMasks);
56574
+ };
56575
+ collectMasks(clean2);
56576
+ const assignmentContext = applySourceEdits(source, masks);
56577
+ const edits = [];
56578
+ const visitLiterals = (node) => {
56579
+ if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node) || ts.isTemplateExpression(node)) {
56580
+ const start = node.getStart(clean2);
56581
+ const text4 = source.slice(start, node.end);
56582
+ const redacted = redactLiteral(text4, start);
56583
+ if (redacted !== text4) {
56584
+ edits.push({ start, end: node.end, text: redacted });
56585
+ return;
56586
+ }
56587
+ }
56588
+ ts.forEachChild(node, visitLiterals);
56589
+ };
56590
+ visitLiterals(clean2);
56591
+ return applySourceEdits(source, edits);
56592
+ }
56593
+ function backendSourcePath(filename) {
56594
+ const normalized = filename.replace(/\\/g, "/").replace(/^\.\//, "");
56595
+ if (!/^(?:src\/)?backend\//.test(normalized) || normalized.split("/").includes("..")) return;
56596
+ if (/(?:secret|credential|\.env|\.pem|\.key|node_modules|__tests__|\.test\.|\.spec\.)/i.test(
56597
+ normalized
56598
+ ))
56599
+ return;
56600
+ return /\.(?:js|ts|jsw)$/.test(normalized) ? normalized : void 0;
56601
+ }
56602
+ function selectVeloSource(files, request, knownSecrets = []) {
56603
+ const candidates = files.flatMap((file) => {
56604
+ const normalized = backendSourcePath(file.path);
56605
+ return normalized && file.content.trim() ? [{ ...file, path: normalized }] : [];
56606
+ });
56607
+ const byPath = new Map(candidates.map((file) => [file.path, file]));
56608
+ const words = [...new Set(request.toLowerCase().match(/[a-z][a-z0-9_]{3,}/g) ?? [])].filter(
56609
+ (word) => !["with", "that", "this", "from", "have", "want", "app", "site", "backend"].includes(word)
56610
+ ).slice(0, 80);
56611
+ const score = (file) => {
56612
+ const names = file.path + " " + [...file.content.matchAll(/export\s+(?:async\s+)?(?:function|const)\s+(\w+)/g)].map((m) => m[1]).join(" ");
56613
+ 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);
56614
+ };
56615
+ const queue = candidates.filter((file) => score(file) > 0).sort((a, b) => score(b) - score(a) || a.path.localeCompare(b.path));
56616
+ const selected = /* @__PURE__ */ new Map();
56617
+ let remaining = MAX_TOTAL_CHARS;
56618
+ while (queue.length && selected.size < MAX_FILES && remaining > 0) {
56619
+ const file = queue.shift();
56620
+ if (!file) break;
56621
+ if (selected.has(file.path)) continue;
56622
+ const redacted = redactVeloSource(file.content, knownSecrets);
56623
+ const excerpt = redacted.slice(0, Math.min(MAX_FILE_CHARS, remaining));
56624
+ selected.set(file.path, { source: excerpt, sourceTruncated: excerpt.length < redacted.length });
56625
+ remaining -= excerpt.length;
56626
+ const dependencies = [];
56627
+ const parsed = ts.createSourceFile(file.path, file.content, ts.ScriptTarget.Latest, true);
56628
+ const specifiers = [];
56629
+ const collectImports = (node) => {
56630
+ let specifier;
56631
+ if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
56632
+ specifier = node.moduleSpecifier;
56633
+ } else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference)) {
56634
+ specifier = node.moduleReference.expression;
56635
+ } else if (ts.isCallExpression(node) && (node.expression.kind === ts.SyntaxKind.ImportKeyword || ts.isIdentifier(node.expression) && node.expression.text === "require")) {
56636
+ specifier = node.arguments[0];
56637
+ }
56638
+ if (specifier && ts.isStringLiteralLike(specifier)) specifiers.push(specifier.text);
56639
+ ts.forEachChild(node, collectImports);
56640
+ };
56641
+ collectImports(parsed);
56642
+ for (const specifier of specifiers) {
56643
+ const target = specifier.startsWith(".") ? path.posix.join(path.posix.dirname(file.path), specifier) : specifier.startsWith("backend/") ? (file.path.startsWith("src/") ? "src/" : "") + specifier : "";
56644
+ const dependency = [
56645
+ target,
56646
+ target + ".js",
56647
+ target + ".ts",
56648
+ target + ".jsw",
56649
+ target + "/index.js",
56650
+ target + "/index.ts"
56651
+ ].map((name) => byPath.get(name)).find(Boolean);
56652
+ if (dependency) dependencies.push(dependency);
56653
+ }
56654
+ queue.unshift(...dependencies);
56655
+ }
56656
+ return selected;
56657
+ }
56658
+ var MAX_FILES, MAX_FILE_CHARS, MAX_TOTAL_CHARS, REDACTED2, sensitiveName;
56659
+ var init_velo_source = __esm({
56660
+ "src/site-analyze/velo-source.ts"() {
56661
+ MAX_FILES = 6;
56662
+ MAX_FILE_CHARS = 8e3;
56663
+ MAX_TOTAL_CHARS = 24e3;
56664
+ REDACTED2 = "[REDACTED]";
56665
+ sensitiveName = /(?:secret|password|passwd|token|authorization|cookie|api[-_]?key|private[-_]?key|access[-_]?key|credential)/i;
56666
+ }
56667
+ });
56668
+
56669
+ // src/site-analyze/context.ts
56670
+ var context_exports = {};
56671
+ __export(context_exports, {
56672
+ collectSiteContext: () => collectSiteContext,
56673
+ contextFetch: () => contextFetch
56674
+ });
56675
+ function contextFetch(fetchImpl, signal) {
56676
+ return async (input, init) => {
56677
+ const url = new URL(String(input));
56678
+ const method = init?.method ?? "GET";
56679
+ const apiRead = url.origin === "https://www.wixapis.com" && reads.has(`${method} ${url.pathname}`);
56680
+ 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") ?? "");
56681
+ if (!apiRead && !veloRead || url.username || url.password) throw new Error("Not a site-analysis read");
56682
+ if (url.pathname === "/oauth2/token" && JSON.parse(String(init?.body)).grantType !== "anonymous") {
56683
+ throw new Error("Only anonymous visitor authentication is allowed");
56684
+ }
56685
+ const response = await fetchImpl(input, { ...init, redirect: "error", signal });
56686
+ const reader = response.body?.getReader();
56687
+ if (!reader) return response;
56688
+ const chunks = [];
56689
+ let size = 0;
56690
+ for (; ; ) {
56691
+ const chunk = await reader.read();
56692
+ if (chunk.done) break;
56693
+ size += chunk.value.byteLength;
56694
+ if (size > 2e6) {
56695
+ await reader.cancel();
56696
+ throw new Error("Site-analysis response exceeds 2 MB");
56697
+ }
56698
+ chunks.push(chunk.value);
56699
+ }
56700
+ return new Response(Buffer.concat(chunks), { status: response.status, headers: response.headers });
56701
+ };
56702
+ }
56703
+ async function collectSiteContext(opts) {
56704
+ const fetcher = contextFetch(opts.fetchImpl ?? fetch, AbortSignal.timeout(opts.timeoutMs ?? 15e3));
56705
+ const owner = opts.ownerToken ? makeTransport(fetcher, { token: opts.ownerToken, msid: opts.siteId }) : void 0;
56706
+ let visitorToken;
56707
+ let visitorAuth = { status: "skipped" };
56708
+ if (opts.clientId) {
56709
+ try {
56710
+ visitorToken = await mintVisitorToken(fetcher, opts.clientId);
56711
+ visitorAuth = { status: "ok" };
56712
+ } catch (e) {
56713
+ visitorAuth = failed(e);
56714
+ }
56715
+ }
56716
+ const visitor = visitorToken ? makeTransport(fetcher, { token: visitorToken, msid: opts.siteId }) : void 0;
56717
+ const identityRead = async () => {
56718
+ if (!owner) return { status: "skipped" };
56719
+ try {
56720
+ const identity2 = parseSiteProperties(await owner("GET", "/site-properties/v4/properties"), "");
56721
+ return { status: "ok", values: {
56722
+ businessName: identity2.businessName,
56723
+ siteDisplayName: identity2.siteDisplayName,
56724
+ description: identity2.description,
56725
+ logo: identity2.logoUrl,
56726
+ language: identity2.locale.languageCode,
56727
+ currency: identity2.locale.currency
56728
+ } };
56729
+ } catch (e) {
56730
+ return failed(e);
56731
+ }
56732
+ };
56733
+ const cmsRead = async () => {
56734
+ try {
56735
+ let failure;
56736
+ const observed = owner ? async (method, path2, body) => {
56737
+ try {
56738
+ const data = await owner(method, path2, body);
56739
+ if (!Array.isArray(data?.collections)) throw new Error("Malformed CMS inventory");
56740
+ return data;
56741
+ } catch (e) {
56742
+ const code = e instanceof WixApiError2 ? e.body?.details?.applicationError?.code : void 0;
56743
+ failure = code === "WDE0110" ? { status: "unavailable", httpStatus: 400 } : failed(e);
56744
+ throw e;
56745
+ }
56746
+ } : void 0;
56747
+ const cms2 = await readCms(observed, { samples: false });
56748
+ return { ...cms2, ...failure, collections: cms2.collections.map((c) => ({
56749
+ id: c.id,
56750
+ readRole: c.readRole,
56751
+ visitorReadable: c.readRole === "ANYONE",
56752
+ ownership: "existing"
56753
+ })) };
56754
+ } catch {
56755
+ return { status: "error", collections: [] };
56756
+ }
56757
+ };
56758
+ const veloRead = async () => {
56759
+ if (!owner) return { status: "skipped", files: [], sourceIncluded: false };
56760
+ let readFailure;
56761
+ const observed = async (method, path2, body) => {
56762
+ try {
56763
+ return await owner(method, path2, body);
56764
+ } catch (e) {
56765
+ readFailure = failed(e);
56766
+ throw e;
56767
+ }
56768
+ };
56769
+ try {
56770
+ const velo2 = await readOwnerVelo(observed, { redact: (source) => redactVeloSource(source, [opts.ownerToken ?? "", visitorToken ?? ""]) });
56771
+ const files = velo2.files.flatMap((f) => {
56772
+ const normalized = backendSourcePath(f.path);
56773
+ return normalized ? [{ ...f, path: normalized }] : [];
56774
+ });
56775
+ const selected = selectVeloSource(
56776
+ files.map((f) => ({ path: f.path, content: f.content ?? "" })),
56777
+ opts.request ?? "",
56778
+ [opts.ownerToken ?? "", visitorToken ?? ""]
56779
+ );
56780
+ return {
56781
+ ...files.length ? { status: "ok" } : readFailure ?? { status: "unavailable" },
56782
+ files: files.map((f) => ({
56783
+ path: f.path,
56784
+ kind: f.kind,
56785
+ exports: [...(f.content ?? "").matchAll(/export\s+(?:async\s+)?(?:function|const)\s+([A-Za-z_$][\w$]*)/g)].slice(0, 20).map((m) => m[1]),
56786
+ ...selected.get(f.path)
56787
+ })),
56788
+ sourceIncluded: selected.size > 0,
56789
+ truncated: files.length > selected.size || [...selected.values()].some((f) => f.sourceTruncated)
56790
+ };
56791
+ } catch (e) {
56792
+ return { ...failed(e), files: [], sourceIncluded: false };
56793
+ }
56794
+ };
56795
+ const [identity, cms, velo, probes] = await Promise.all([
56796
+ identityRead(),
56797
+ cmsRead(),
56798
+ veloRead(),
56799
+ runDualProbes(owner, visitor, definitions)
56800
+ ]);
56801
+ const probeRead = (p, available, auth) => {
56802
+ if (!available) return auth;
56803
+ if (p.httpStatus) return { ...failed(new WixApiError2(p.httpStatus, "", "", null)), count: p.count };
56804
+ return { status: p.status === "ok" || p.status === "empty" ? p.status : "error", count: p.count };
56805
+ };
56806
+ return {
56807
+ schemaVersion: 1,
56808
+ mode: "read-only",
56809
+ identity,
56810
+ cms,
56811
+ velo,
56812
+ verticals: probes.map((p) => ({
56813
+ name: p.vertical,
56814
+ owner: probeRead(p.owner, !!owner, { status: "skipped" }),
56815
+ visitor: probeRead(p.visitor, !!visitor, visitorAuth)
56816
+ }))
56817
+ };
56818
+ }
56819
+ var responseKeys, definitions, reads, failed;
56820
+ var init_context = __esm({
56821
+ "src/site-analyze/context.ts"() {
56822
+ init_probes();
56823
+ init_rest();
56824
+ init_site_properties();
56825
+ init_visitor_auth();
56826
+ init_velo();
56827
+ init_velo_source();
56828
+ responseKeys = {
56829
+ store: "products",
56830
+ bookings: "services",
56831
+ events: "events",
56832
+ blog: "posts"
56833
+ };
56834
+ definitions = [...CORE_PROBES, ...OPTIONAL_PROBES].filter((p) => p.vertical in responseKeys).map((p) => {
56835
+ const checked = (read, path2) => (data) => {
56836
+ const rows = path2 === "/catalog/v1/products/query" ? data.products ?? data.items : data[responseKeys[p.vertical]];
56837
+ if (!Array.isArray(rows)) throw new Error("Malformed catalog response");
56838
+ return read(data);
56839
+ };
56840
+ return {
56841
+ ...p,
56842
+ itemsOf: checked(p.itemsOf, p.path),
56843
+ fallbacks: p.fallbacks?.map((f) => ({ ...f, itemsOf: checked(f.itemsOf ?? p.itemsOf, f.path) }))
56844
+ };
56845
+ });
56846
+ reads = /* @__PURE__ */ new Set([
56847
+ "POST /oauth2/token",
56848
+ "GET /site-properties/v4/properties",
56849
+ "GET /data/v2/collections",
56850
+ ...OWNER_VELO_PROBES.map((p) => `${p.method} ${p.path}`),
56851
+ ...definitions.flatMap((p) => [p, ...p.fallbacks ?? []].map((a) => `${a.method} ${a.path}`))
56852
+ ]);
56853
+ failed = (e) => {
56854
+ const httpStatus = e instanceof WixApiError2 ? e.status : void 0;
56855
+ return { status: httpStatus === 401 ? "unauthorized" : httpStatus === 403 ? "forbidden" : httpStatus === 404 || httpStatus === 428 ? "unavailable" : "error", ...httpStatus ? { httpStatus } : {} };
56856
+ };
56857
+ }
56858
+ });
56859
+
56491
56860
  // src/cli.ts
56492
56861
  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
56862
  import { execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn5 } from "node:child_process";
@@ -56520,11 +56889,11 @@ var ServeCliClient = class {
56520
56889
  if (!url) throw new Error(`no ${plane} URL configured for this target`);
56521
56890
  return url.replace(/\/+$/, "");
56522
56891
  }
56523
- async request(plane, method, path, opts = {}) {
56892
+ async request(plane, method, path2, opts = {}) {
56524
56893
  const headers2 = { ...opts.headers };
56525
56894
  if (opts.body !== void 0) headers2["content-type"] = "application/json";
56526
56895
  const carriesCredential = Object.keys(headers2).some((h2) => CREDENTIAL_HEADERS.has(h2.toLowerCase()));
56527
- const res = await this.fetchImpl(this.baseFor(plane) + path, {
56896
+ const res = await this.fetchImpl(this.baseFor(plane) + path2, {
56528
56897
  method,
56529
56898
  headers: headers2,
56530
56899
  ...carriesCredential ? { redirect: "error" } : {},
@@ -56737,12 +57106,12 @@ var ServeCliClient = class {
56737
57106
  if (o.since !== void 0) q.set("since", String(o.since));
56738
57107
  if (o.limit) q.set("limit", String(o.limit));
56739
57108
  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) => {
57109
+ const path2 = `/v1/telemetry/events?${q}`;
57110
+ return this.request("telemetry", "GET", path2, { headers: this.telHeaders() }).then(async (res) => {
56742
57111
  if (res.status !== 404 || this.target.telemetry.replace(/\/+$/, "") === this.target.serve.replace(/\/+$/, "")) {
56743
57112
  return res;
56744
57113
  }
56745
- return this.request("serve", "GET", path, { headers: this.telHeaders() });
57114
+ return this.request("serve", "GET", path2, { headers: this.telHeaders() });
56746
57115
  });
56747
57116
  }
56748
57117
  /** Retained worker console lines (oldest first; `since` = seq cursor for tailing). */
@@ -56752,12 +57121,12 @@ var ServeCliClient = class {
56752
57121
  if (o.screenId) q.set("screen", o.screenId);
56753
57122
  if (o.since !== void 0) q.set("since", String(o.since));
56754
57123
  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) => {
57124
+ const path2 = `/v1/telemetry/logs?${q}`;
57125
+ return this.request("telemetry", "GET", path2, { headers: this.telHeaders() }).then(async (res) => {
56757
57126
  if (res.status !== 404 || this.target.telemetry.replace(/\/+$/, "") === this.target.serve.replace(/\/+$/, "")) {
56758
57127
  return res;
56759
57128
  }
56760
- return this.request("serve", "GET", path, { headers: this.telHeaders() });
57129
+ return this.request("serve", "GET", path2, { headers: this.telHeaders() });
56761
57130
  });
56762
57131
  }
56763
57132
  // ---- serve-control (publish / rollout / kill-switch — the mutable plane) ----
@@ -56815,8 +57184,8 @@ var ServeCliClient = class {
56815
57184
  }
56816
57185
  /** RFC 0012 release history: list the ledger (GET /v1/releases) or one manifest (…/{releaseId}). */
56817
57186
  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() });
57187
+ const path2 = releaseId ? `/v1/releases/${encodeURIComponent(releaseId)}?app=${encodeURIComponent(app)}` : `/v1/releases?app=${encodeURIComponent(app)}`;
57188
+ return this.request("control", "GET", path2, { headers: this.ctrlHeaders() });
56820
57189
  }
56821
57190
  /** Select a published releaseId for a ring (POST /v1/admin/promote); optional rollout %. */
56822
57191
  promote(app, ring, releaseId, percent, force = false) {
@@ -57173,8 +57542,8 @@ var VALIDATION_METADATA = /* @__PURE__ */ new Set([
57173
57542
  ".claude/.validation-baseline.json",
57174
57543
  ".claude/.validation-evidence.json"
57175
57544
  ]);
57176
- function isValidationMetadata(path) {
57177
- return VALIDATION_METADATA.has(path) || /(^|[\\/])\.himi([\\/]|$)/.test(path);
57545
+ function isValidationMetadata(path2) {
57546
+ return VALIDATION_METADATA.has(path2) || /(^|[\\/])\.himi([\\/]|$)/.test(path2);
57178
57547
  }
57179
57548
  function tryGit(args, root) {
57180
57549
  try {
@@ -57190,10 +57559,10 @@ function committedRecords(raw) {
57190
57559
  const records = [];
57191
57560
  for (let i = 0; i < fields.length; i += 2) {
57192
57561
  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`);
57562
+ const path2 = fields[i + 1];
57563
+ if (!metadata2.startsWith(":") || path2 === "") return null;
57564
+ if (isValidationMetadata(path2)) continue;
57565
+ records.push(`${Buffer.byteLength(path2)}:${path2}\0${metadata2}\0`);
57197
57566
  }
57198
57567
  return records.sort().join("");
57199
57568
  }
@@ -57253,12 +57622,12 @@ function validationDiffHash(cwd = process.cwd()) {
57253
57622
  trustFilesystemMode = git(["config", "--bool", "--get", "core.fileMode"], { cwd: root }).trim() !== "false";
57254
57623
  } catch {
57255
57624
  }
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");
57625
+ const paths = [.../* @__PURE__ */ new Set([...staged, ...unstaged, ...untracked])].filter((path2) => !isValidationMetadata(path2)).sort();
57626
+ const identity = paths.map((path2) => {
57627
+ const absolute = resolve5(root, path2);
57628
+ const headEntry = headEntries.get(path2);
57629
+ const indexEntry = indexEntries.get(path2);
57630
+ const deletedRecord = () => [`${Buffer.byteLength(path2)}:${path2}`, "deleted", stagedIdentity(headEntry, indexEntry, void 0), ""].join("\0");
57262
57631
  let stat2;
57263
57632
  try {
57264
57633
  stat2 = lstatSync2(absolute);
@@ -57272,7 +57641,7 @@ function validationDiffHash(cwd = process.cwd()) {
57272
57641
  const worktreeEntry = { mode: "120000", oid: blobOid(target, objectAlgorithm) };
57273
57642
  const stagedState2 = stagedIdentity(headEntry, indexEntry, worktreeEntry);
57274
57643
  return [
57275
- `${Buffer.byteLength(path)}:${path}`,
57644
+ `${Buffer.byteLength(path2)}:${path2}`,
57276
57645
  "symlink",
57277
57646
  "120000",
57278
57647
  diffHash(target),
@@ -57283,11 +57652,11 @@ function validationDiffHash(cwd = process.cwd()) {
57283
57652
  if (stat2.isFile()) {
57284
57653
  const filesystemMode = stat2.mode & 73 ? "100755" : "100644";
57285
57654
  const worktreeMode = trustFilesystemMode ? filesystemMode : indexEntry?.mode ?? headEntry?.mode ?? "100644";
57286
- const worktreeOid = git(["hash-object", `--path=${path}`, "--", path], { cwd: root }).trim();
57655
+ const worktreeOid = git(["hash-object", `--path=${path2}`, "--", path2], { cwd: root }).trim();
57287
57656
  const worktreeEntry = { mode: worktreeMode, oid: worktreeOid };
57288
57657
  const stagedState2 = stagedIdentity(headEntry, indexEntry, worktreeEntry);
57289
57658
  return [
57290
- `${Buffer.byteLength(path)}:${path}`,
57659
+ `${Buffer.byteLength(path2)}:${path2}`,
57291
57660
  "file",
57292
57661
  worktreeMode,
57293
57662
  diffHash(readFileSync4(absolute)),
@@ -57306,7 +57675,7 @@ function validationDiffHash(cwd = process.cwd()) {
57306
57675
  const type = stat2.isDirectory() ? "directory" : "other";
57307
57676
  const stagedState = stagedIdentity(headEntry, indexEntry, void 0);
57308
57677
  return [
57309
- `${Buffer.byteLength(path)}:${path}`,
57678
+ `${Buffer.byteLength(path2)}:${path2}`,
57310
57679
  type,
57311
57680
  stat2.mode.toString(8),
57312
57681
  stagedState,
@@ -57413,7 +57782,7 @@ var SELF_TEST_CASES = [
57413
57782
  }
57414
57783
  ];
57415
57784
  function runSelfTest() {
57416
- let failed = 0;
57785
+ let failed2 = 0;
57417
57786
  for (const testCase of SELF_TEST_CASES) {
57418
57787
  let ok = false;
57419
57788
  let thrown = null;
@@ -57427,20 +57796,20 @@ function runSelfTest() {
57427
57796
  `);
57428
57797
  continue;
57429
57798
  }
57430
- failed++;
57799
+ failed2++;
57431
57800
  process.stderr.write(` \u2717 ${testCase.name}
57432
57801
  ${thrown ?? testCase.reason}
57433
57802
  `);
57434
57803
  }
57435
- return failed;
57804
+ return failed2;
57436
57805
  }
57437
57806
  if (process.argv[1] && basename(process.argv[1]) === "diff-hash.mjs" && import.meta.url === pathToFileURL(process.argv[1]).href) {
57438
57807
  if (process.argv.slice(2).includes("--self-test")) {
57439
57808
  process.stdout.write("\u25B8 diff-hash --self-test: proving the identity can change, and can hold\n");
57440
- const failed = runSelfTest();
57441
- if (failed) {
57809
+ const failed2 = runSelfTest();
57810
+ if (failed2) {
57442
57811
  process.stderr.write(
57443
- `\u2717 diff-hash self-test FAILED (${failed} case(s)) \u2014 the evidence record's diff identity cannot be trusted
57812
+ `\u2717 diff-hash self-test FAILED (${failed2} case(s)) \u2014 the evidence record's diff identity cannot be trusted
57444
57813
  `
57445
57814
  );
57446
57815
  process.exit(1);
@@ -57533,16 +57902,16 @@ function currentGitUntrackedHash(contentDir2) {
57533
57902
  maxBuffer: GIT_HASH_MAX_BUFFER
57534
57903
  });
57535
57904
  const hash = createHash3("sha256");
57536
- for (const path of listed.split("\0").filter(Boolean).sort()) {
57537
- const local = relative(absolute, join6(root, path));
57905
+ for (const path2 of listed.split("\0").filter(Boolean).sort()) {
57906
+ const local = relative(absolute, join6(root, path2));
57538
57907
  if (local.split(/[\\/]/)[0] === ".himi") continue;
57539
- const full = join6(root, path);
57908
+ const full = join6(root, path2);
57540
57909
  const stats = lstatSync3(full, { throwIfNoEntry: false });
57541
57910
  if (!stats) continue;
57542
57911
  const kind = stats.isSymbolicLink() ? "link" : stats.isDirectory() ? "dir" : stats.isFile() ? "file" : null;
57543
57912
  if (!kind) continue;
57544
57913
  const payload = kind === "link" ? Buffer.from(readlinkSync2(full)) : kind === "file" ? readFileSync5(full) : Buffer.alloc(0);
57545
- const pathBytes = Buffer.from(path);
57914
+ const pathBytes = Buffer.from(path2);
57546
57915
  hash.update(`${kind} ${pathBytes.length} ${payload.length}
57547
57916
  `).update(pathBytes).update(payload);
57548
57917
  }
@@ -57553,11 +57922,11 @@ function sourceTreeHash(root) {
57553
57922
  const visit = (dir) => {
57554
57923
  for (const entry of readdirSync3(dir, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
57555
57924
  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");
57925
+ const path2 = join6(dir, entry.name);
57926
+ const local = relative(root, path2);
57927
+ if (entry.isDirectory()) visit(path2);
57928
+ else if (entry.isFile()) hash.update(local).update("\0").update(readFileSync5(path2)).update("\0");
57929
+ else if (entry.isSymbolicLink()) hash.update(local).update("\0link\0").update(readlinkSync2(path2)).update("\0");
57561
57930
  }
57562
57931
  };
57563
57932
  visit(root);
@@ -57605,9 +57974,9 @@ function readRetainedAttestations(contentDir2) {
57605
57974
  for (const run2 of parsedRuns) {
57606
57975
  if (selfHashFor(run2) !== run2.selfHash) errors.push(`selfHash does not match retained run ${run2.runId}`);
57607
57976
  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)}`);
57977
+ const path2 = screenshotArtifactPath(contentDir2, expected);
57978
+ if (!existsSync3(path2)) errors.push(`missing screenshot for retained run ${run2.runId}: ${basename2(path2)}`);
57979
+ else if (sha256(readFileSync5(path2)) !== expected) errors.push(`screenshot hash does not match retained run ${run2.runId}: ${basename2(path2)}`);
57611
57980
  }
57612
57981
  }
57613
57982
  const runs = [];
@@ -57668,8 +58037,8 @@ function writeAttestation(input, opts = {}) {
57668
58037
  const descriptorHashes = Object.fromEntries(
57669
58038
  Object.entries(input.descriptors).sort(([a], [b]) => a.localeCompare(b)).map(([screen, bytes2]) => [screen, sha256(bytes2)])
57670
58039
  );
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);
58040
+ const screenshotEntries = Object.entries(input.screenshots ?? {}).sort(([a], [b]) => a.localeCompare(b)).filter(([, path2]) => existsSync3(path2)).map(([screen, path2]) => {
58041
+ const bytes2 = readFileSync5(path2);
57673
58042
  return { screen, bytes: bytes2, hash: sha256(bytes2) };
57674
58043
  });
57675
58044
  const screenshots = Object.fromEntries(screenshotEntries.map(({ screen, hash }) => [screen, hash]));
@@ -57796,12 +58165,12 @@ function verifyAttestation(attestation, contentDir2, descriptors, expectedApp, r
57796
58165
  if (sha256(bytes2) !== expected) errors.push(`descriptor hash does not match for ${screen}`);
57797
58166
  }
57798
58167
  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)}`);
58168
+ const path2 = screenshotArtifactPath(contentDir2, expected);
58169
+ if (!existsSync3(path2)) {
58170
+ errors.push(`missing screenshot for ${screen}: ${basename2(path2)}`);
57802
58171
  continue;
57803
58172
  }
57804
- if (sha256(readFileSync5(path)) !== expected) errors.push(`screenshot hash does not match for ${screen}: ${basename2(path)}`);
58173
+ if (sha256(readFileSync5(path2)) !== expected) errors.push(`screenshot hash does not match for ${screen}: ${basename2(path2)}`);
57805
58174
  }
57806
58175
  return { ok: errors.length === 0, errors };
57807
58176
  }
@@ -58128,9 +58497,9 @@ function dpxSessionTokenPath() {
58128
58497
  return process.env.HIMI_DPX_TOKEN ?? join7(homedir2(), ".dpx", "session", "token");
58129
58498
  }
58130
58499
  var DPX_SESSION_PORT = 5151;
58131
- function dpxSessionPresent(path = dpxSessionTokenPath()) {
58500
+ function dpxSessionPresent(path2 = dpxSessionTokenPath()) {
58132
58501
  try {
58133
- return existsSync4(path) && readFileSync6(path, "utf8").trim().length > 0;
58502
+ return existsSync4(path2) && readFileSync6(path2, "utf8").trim().length > 0;
58134
58503
  } catch {
58135
58504
  return false;
58136
58505
  }
@@ -58309,10 +58678,10 @@ async function listCollections(call) {
58309
58678
  let total;
58310
58679
  let reachedEnd = false;
58311
58680
  for (let page = 0; page < MAX_COLLECTION_PAGES; page++) {
58312
- const path = offset ? `/data/v2/collections?paging.offset=${offset}` : "/data/v2/collections";
58681
+ const path2 = offset ? `/data/v2/collections?paging.offset=${offset}` : "/data/v2/collections";
58313
58682
  const r = await withRetry(
58314
58683
  "list collections",
58315
- () => call("GET", path)
58684
+ () => call("GET", path2)
58316
58685
  );
58317
58686
  const batch = r.collections ?? [];
58318
58687
  const t = r.pagingMetadata?.total;
@@ -59302,9 +59671,9 @@ function storesV1Issues(contentDir2, strict) {
59302
59671
  const files = [];
59303
59672
  const visit = (dir) => {
59304
59673
  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);
59674
+ const path2 = join23(dir, entry.name);
59675
+ if (entry.isDirectory()) visit(path2);
59676
+ else if (/\.(?:[cm]?[jt]sx?)$/i.test(entry.name)) files.push(path2);
59308
59677
  }
59309
59678
  };
59310
59679
  roots.forEach(visit);
@@ -59328,12 +59697,12 @@ import { existsSync as existsSync22, readFileSync as readFileSync22, readdirSync
59328
59697
  import { join as join25, relative as relative4, resolve as resolve16 } from "node:path";
59329
59698
  var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".json"]);
59330
59699
  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" });
59700
+ function issue(issues, strict, code, message, path2) {
59701
+ issues.push({ code, message, ...path2 ? { path: path2 } : {}, severity: strict ? "error" : "warning" });
59333
59702
  }
59334
- function readText2(path) {
59703
+ function readText2(path2) {
59335
59704
  try {
59336
- return existsSync22(path) ? readFileSync22(path, "utf8") : null;
59705
+ return existsSync22(path2) ? readFileSync22(path2, "utf8") : null;
59337
59706
  } catch {
59338
59707
  return null;
59339
59708
  }
@@ -59643,6 +60012,7 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
59643
60012
  "json",
59644
60013
  "deep",
59645
60014
  "quiet",
60015
+ "read-only",
59646
60016
  "force",
59647
60017
  "replace",
59648
60018
  "watch",
@@ -59770,10 +60140,10 @@ var str5 = (v) => typeof v === "string" ? v : void 0;
59770
60140
  var num = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
59771
60141
  function embeddedTemplateCatalog() {
59772
60142
  return availableTemplates().map((name) => {
59773
- const path = join52(templateSourceDir(name), TEMPLATE_META_FILE);
59774
- const meta = JSON.parse(readFileSync67(path, "utf8"));
60143
+ const path2 = join52(templateSourceDir(name), TEMPLATE_META_FILE);
60144
+ const meta = JSON.parse(readFileSync67(path2, "utf8"));
59775
60145
  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 }`);
60146
+ throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
59777
60147
  }
59778
60148
  return { name, ...meta, source: "embedded" };
59779
60149
  });
@@ -60260,6 +60630,7 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
60260
60630
  also requires a MOBILE applicationType, because ensure
60261
60631
  refuses a WEB client \u2014 so a WEB one carrying your
60262
60632
  redirect looks right and is not a candidate.
60633
+ himi site analyze --read-only --site <msid> [--client-id <id>] [--json]
60263
60634
  himi site analyze --client-id <id> --url <https://\u2026> [--site <msid>] [--out <dir>] [--apply]
60264
60635
  [--shell ${SHELL_ENUM}]
60265
60636
  collect a Wix business book (APIs + Playwright look) and
@@ -60373,7 +60744,7 @@ var COMMANDS = [
60373
60744
  { 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
60745
  { name: "logout", summary: "remove the stored control token for a target", required: "[--target <t>]" },
60375
60746
  { 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]" },
60747
+ { 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
60748
  { 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
60749
  { 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
60750
  { 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)" },
@@ -60506,9 +60877,9 @@ function ageInDays(publishedAt, now = Date.now()) {
60506
60877
  if (!Number.isFinite(at)) return void 0;
60507
60878
  return Math.max(0, (now - at) / 864e5);
60508
60879
  }
60509
- function packageVersion(path) {
60880
+ function packageVersion(path2) {
60510
60881
  try {
60511
- const version2 = JSON.parse(readFileSync67(path, "utf8")).version;
60882
+ const version2 = JSON.parse(readFileSync67(path2, "utf8")).version;
60512
60883
  return typeof version2 === "string" && version2 ? version2 : void 0;
60513
60884
  } catch {
60514
60885
  return void 0;
@@ -60576,18 +60947,18 @@ var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
60576
60947
  function updateCachePath(env = process.env) {
60577
60948
  return env.HIMI_UPDATE_CACHE_FILE ?? join52(homedir7(), ".himalaya", "update-check.json");
60578
60949
  }
60579
- function readUpdateCache(path) {
60950
+ function readUpdateCache(path2) {
60580
60951
  try {
60581
- const parsed = JSON.parse(readFileSync67(path, "utf8"));
60952
+ const parsed = JSON.parse(readFileSync67(path2, "utf8"));
60582
60953
  return parsed && typeof parsed === "object" ? parsed : {};
60583
60954
  } catch {
60584
60955
  return {};
60585
60956
  }
60586
60957
  }
60587
- function writeUpdateCache(path, cache) {
60958
+ function writeUpdateCache(path2, cache) {
60588
60959
  try {
60589
- mkdirSync27(dirname31(path), { recursive: true, mode: 448 });
60590
- writeFileSync25(path, JSON.stringify(cache, null, 2) + "\n", { mode: 384 });
60960
+ mkdirSync27(dirname31(path2), { recursive: true, mode: 448 });
60961
+ writeFileSync25(path2, JSON.stringify(cache, null, 2) + "\n", { mode: 384 });
60591
60962
  } catch {
60592
60963
  }
60593
60964
  }
@@ -60695,10 +61066,10 @@ function isAbandoned(content) {
60695
61066
  return Number.isFinite(owner) && owner > 0 && host === thisHost() && !processAlive(owner);
60696
61067
  }
60697
61068
  function staleUpdateLockFile(cachePath, now) {
60698
- for (const path of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
61069
+ for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
60699
61070
  let content;
60700
61071
  try {
60701
- content = readFileSync67(path, "utf8");
61072
+ content = readFileSync67(path2, "utf8");
60702
61073
  } catch {
60703
61074
  continue;
60704
61075
  }
@@ -60706,12 +61077,12 @@ function staleUpdateLockFile(cachePath, now) {
60706
61077
  let since = stamped;
60707
61078
  if (!Number.isFinite(since)) {
60708
61079
  try {
60709
- since = statSync13(path).mtimeMs;
61080
+ since = statSync13(path2).mtimeMs;
60710
61081
  } catch {
60711
61082
  continue;
60712
61083
  }
60713
61084
  }
60714
- if (now - since >= UPDATE_LOCK_REPORT_AFTER_MS) return path;
61085
+ if (now - since >= UPDATE_LOCK_REPORT_AFTER_MS) return path2;
60715
61086
  }
60716
61087
  return void 0;
60717
61088
  }
@@ -60719,24 +61090,24 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
60719
61090
  const lockPath = `${cachePath}.lock`;
60720
61091
  const breakPath = `${cachePath}.lock.break`;
60721
61092
  const mine = lockStamp(now);
60722
- const readLock = (path) => {
61093
+ const readLock = (path2) => {
60723
61094
  try {
60724
- return readFileSync67(path, "utf8");
61095
+ return readFileSync67(path2, "utf8");
60725
61096
  } catch {
60726
61097
  return void 0;
60727
61098
  }
60728
61099
  };
60729
- const tryCreate = (path) => {
61100
+ const tryCreate = (path2) => {
60730
61101
  try {
60731
- writeFileSync25(path, mine, { flag: "wx", mode: 384 });
61102
+ writeFileSync25(path2, mine, { flag: "wx", mode: 384 });
60732
61103
  return true;
60733
61104
  } catch {
60734
61105
  return false;
60735
61106
  }
60736
61107
  };
60737
- const removeIfMine = (path) => {
61108
+ const removeIfMine = (path2) => {
60738
61109
  try {
60739
- if (readLock(path) === mine) rmSync10(path, { force: true });
61110
+ if (readLock(path2) === mine) rmSync10(path2, { force: true });
60740
61111
  } catch {
60741
61112
  }
60742
61113
  };
@@ -60957,9 +61328,9 @@ function helpJson() {
60957
61328
  }
60958
61329
  function previewWebUrl(serveBase, app, release, screenId, surface, previewToken, handover) {
60959
61330
  const base = serveBase.replace(/\/$/, "");
60960
- const path = screenId ? `/preview/a/${app}/screen/${screenId}` : `/preview/a/${app}`;
61331
+ const path2 = screenId ? `/preview/a/${app}/screen/${screenId}` : `/preview/a/${app}`;
60961
61332
  const query = handover ? `?h=${encodeURIComponent(handover)}` : `?release=${encodeURIComponent(release)}`;
60962
- return `${base}${path}${query}${surface ? `&surface=${encodeURIComponent(surface)}` : ""}${!handover && previewToken ? `&pvt=${encodeURIComponent(previewToken)}` : ""}`;
61333
+ return `${base}${path2}${query}${surface ? `&surface=${encodeURIComponent(surface)}` : ""}${!handover && previewToken ? `&pvt=${encodeURIComponent(previewToken)}` : ""}`;
60963
61334
  }
60964
61335
  function renderDeviceWidths() {
60965
61336
  return {
@@ -61380,10 +61751,10 @@ function readConfigSource(dir) {
61380
61751
  return null;
61381
61752
  }
61382
61753
  }
61383
- function writePngFile(path, base64) {
61384
- mkdirSync27(dirname31(path), { recursive: true });
61385
- writeFileSync25(path, Buffer.from(base64, "base64"));
61386
- return path;
61754
+ function writePngFile(path2, base64) {
61755
+ mkdirSync27(dirname31(path2), { recursive: true });
61756
+ writeFileSync25(path2, Buffer.from(base64, "base64"));
61757
+ return path2;
61387
61758
  }
61388
61759
  async function initFromRemoteTemplate(name, parentDir, template, c) {
61389
61760
  const dir = resolve44(parentDir, name);
@@ -61577,9 +61948,9 @@ async function loadCms(dir) {
61577
61948
  return data ? { collections: data.collections ?? [], ...data.memberGated ? { memberGated: true } : {} } : void 0;
61578
61949
  }
61579
61950
  var ConfigLoadError = class extends Error {
61580
- constructor(path, cause) {
61581
- super(`could not load ${path}: ${cause.message}`);
61582
- this.path = path;
61951
+ constructor(path2, cause) {
61952
+ super(`could not load ${path2}: ${cause.message}`);
61953
+ this.path = path2;
61583
61954
  this.cause = cause;
61584
61955
  this.name = "ConfigLoadError";
61585
61956
  }
@@ -62553,17 +62924,17 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
62553
62924
  const dir = contentDir(flags);
62554
62925
  const { buildContentBundles: buildContentBundles2 } = await loadAuthoring();
62555
62926
  const res = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
62556
- const failed = res.compileErrors;
62927
+ const failed2 = res.compileErrors;
62557
62928
  print({
62558
- ok: failed.length === 0,
62929
+ ok: failed2.length === 0,
62559
62930
  outDir: res.outDir,
62560
62931
  built: res.built,
62561
- ...failed.length ? { compileErrors: failed } : {},
62932
+ ...failed2.length ? { compileErrors: failed2 } : {},
62562
62933
  // #642.1b — a stale @wix/himalaya is advisory on `build` (the bundles may
62563
62934
  // still compile); `validate --strict` is where it hard-fails.
62564
62935
  ...res.sdkVersionIssue ? { warnings: [res.sdkVersionIssue] } : {}
62565
62936
  });
62566
- return failed.length ? 1 : 0;
62937
+ return failed2.length ? 1 : 0;
62567
62938
  }
62568
62939
  case "eject": {
62569
62940
  const mod = String(pos[1] ?? "");
@@ -62644,12 +63015,12 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
62644
63015
  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
63016
  const remoteTarget = str5(flags.target);
62646
63017
  const boCookie = () => {
62647
- const path = dpxSessionTokenPath();
63018
+ const path2 = dpxSessionTokenPath();
62648
63019
  let raw;
62649
63020
  try {
62650
- raw = readFileSync67(path, "utf8");
63021
+ raw = readFileSync67(path2, "utf8");
62651
63022
  } 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`);
63023
+ 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
63024
  }
62654
63025
  return dpxCookieHeader(raw);
62655
63026
  };
@@ -63119,7 +63490,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63119
63490
  bootAndSnapshotState: bootAndSnapshotState2,
63120
63491
  renderDescriptorWeb: renderDescriptorWeb2,
63121
63492
  renderPngBatch: renderPngBatch2,
63122
- writePng: (path, base64) => writePngFile(path, base64),
63493
+ writePng: (path2, base64) => writePngFile(path2, base64),
63123
63494
  clearDir: (d) => rmSync10(d, { recursive: true, force: true })
63124
63495
  }
63125
63496
  });
@@ -66554,12 +66925,12 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
66554
66925
  return 1;
66555
66926
  }
66556
66927
  if (secretTarget.mode === "remote") {
66557
- const path = dpxSessionTokenPath();
66928
+ const path2 = dpxSessionTokenPath();
66558
66929
  let raw;
66559
66930
  try {
66560
- raw = readFileSync67(path, "utf8");
66931
+ raw = readFileSync67(path2, "utf8");
66561
66932
  } catch {
66562
- io.error(JSON.stringify({ error: `no DPX BO session at ${path}` }));
66933
+ io.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
66563
66934
  return 1;
66564
66935
  }
66565
66936
  const { runRemoteSecretsCommand: runRemoteSecretsCommand2 } = await Promise.resolve().then(() => (init_secrets2(), secrets_exports));
@@ -66829,6 +67200,34 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
66829
67200
  }
66830
67201
  const clientId = str5(flags["client-id"]) ?? process.env.WIX_CLIENT_ID;
66831
67202
  const siteUrl = str5(flags.url) ?? str5(flags["site-url"]);
67203
+ if (flags["read-only"] === true) {
67204
+ if (flags.apply || flags.out || flags.shell || flags["redirect-uri"]) {
67205
+ io.error(JSON.stringify({ error: "--read-only returns API context only; it cannot be combined with --apply, --out, --shell, or --redirect-uri" }));
67206
+ return 2;
67207
+ }
67208
+ const siteId = str5(flags.site) ?? process.env.WIX_SITE_ID;
67209
+ if (!clientId && !siteId && !process.env.WIX_TEST_TOKEN?.trim()) {
67210
+ io.error(JSON.stringify({ error: "--read-only needs --site, --client-id, or a site-scoped WIX_TEST_TOKEN" }));
67211
+ return 2;
67212
+ }
67213
+ const { collectSiteContext: collectSiteContext2 } = await Promise.resolve().then(() => (init_context(), context_exports));
67214
+ const { siteToken: siteToken2 } = await Promise.resolve().then(() => (init_wix_owner(), wix_owner_exports));
67215
+ let ownerToken = process.env.WIX_TEST_TOKEN?.trim() || void 0;
67216
+ if (!ownerToken && siteId) {
67217
+ try {
67218
+ ownerToken = await siteToken2(siteId);
67219
+ } catch {
67220
+ }
67221
+ }
67222
+ const context = await collectSiteContext2({
67223
+ siteId,
67224
+ clientId,
67225
+ ownerToken,
67226
+ request: process.env.HIMI_ANALYZE_REQUEST
67227
+ });
67228
+ print({ ok: true, context });
67229
+ return 0;
67230
+ }
66832
67231
  if (!clientId || !siteUrl) {
66833
67232
  io.error(JSON.stringify({
66834
67233
  error: "himi site analyze needs --client-id and --url",