@wix/himalaya-cli 0.1565.0 → 0.1567.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/app-info/src/index.d.ts +4 -0
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/wix-platform/src/business-address.d.ts +24 -0
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/wix-platform/src/index.d.ts +7 -0
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/app-info.mjs +2 -1
  5. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/iap-checkout.mjs +2 -1
  6. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/screens.mjs +2 -1
  7. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-platform.mjs +17 -8
  8. package/dist/cli.mjs +232 -68
  9. package/dist/preview-assets.generated.bin +0 -0
  10. package/guides/himi-json-output.md +2 -0
  11. package/guides/iap-screen-adoption.md +6 -3
  12. package/guides/one-app-to-himi-app.md +40 -1
  13. package/guides/qa-builds.md +5 -1
  14. package/guides/sdk-reference.json +2 -2
  15. package/guides/wix-business-context.md +18 -0
  16. package/package.json +2 -2
  17. package/templates/beauty-salon/tier5-src/himi-store-account/index.ts +6 -3
  18. package/templates/branded-lite/dev/index.ts +3 -0
  19. package/templates/branded-lite/tier5-src/himi-branded-lite-notifications/index.ts +78 -14
  20. package/templates/branded-lite/tier5-src/himi-store-account/index.ts +6 -3
  21. package/templates/community-club/tier5-src/himi-store-account/index.ts +6 -3
  22. package/templates/events-meetups/tier5-src/himi-store-account/index.ts +6 -3
  23. package/templates/gym-fitness/tier5-src/himi-store-account/index.ts +6 -3
  24. package/templates/nonprofit-cause/tier5-src/himi-store-account/index.ts +6 -3
  25. package/templates/podcast-creator/tier5-src/himi-store-account/index.ts +6 -3
  26. package/templates/portfolio-creative/tier5-src/himi-store-account/index.ts +6 -3
  27. package/templates/restaurant/tier5-src/himi-store-account/index.ts +6 -3
  28. package/templates/retail-store/tier5-src/himi-store-account/index.ts +6 -3
  29. package/templates/yoga-studio/tier5-src/himi-store-account/index.ts +6 -3
package/dist/cli.mjs CHANGED
@@ -25762,8 +25762,13 @@ var init_stream_policy = __esm({
25762
25762
  });
25763
25763
 
25764
25764
  // ../../core/ts/src/locale.ts
25765
+ function isSupportedLocale(tag) {
25766
+ return SUPPORTED_LOCALES.includes(tag);
25767
+ }
25768
+ var SUPPORTED_LOCALES;
25765
25769
  var init_locale = __esm({
25766
25770
  "../../core/ts/src/locale.ts"() {
25771
+ SUPPORTED_LOCALES = ["en", "he", "es"];
25767
25772
  }
25768
25773
  });
25769
25774
 
@@ -138916,6 +138921,7 @@ __export(build_exports2, {
138916
138921
  BAKE_OFFLINE_BASE: () => BAKE_OFFLINE_BASE,
138917
138922
  KNOWN_ICON_NAMES: () => KNOWN_ICON_NAMES,
138918
138923
  SOURCEMAP_ON_DEMAND_PATH: () => SOURCEMAP_ON_DEMAND_PATH,
138924
+ SUPPORTED_COMPONENT_MIN_VERSION: () => SUPPORTED_COMPONENT_MIN_VERSION,
138919
138925
  bakeCatalogs: () => bakeCatalogs,
138920
138926
  bakeNeedsLiveOrigin: () => bakeNeedsLiveOrigin,
138921
138927
  bakeWidgets: () => bakeWidgets,
@@ -138928,6 +138934,7 @@ __export(build_exports2, {
138928
138934
  countingHostAnswers: () => countingHostAnswers,
138929
138935
  countingWixCall: () => countingWixCall,
138930
138936
  declaresHostProvidedIdentity: () => declaresHostProvidedIdentity,
138937
+ explicitMinRuntimeVersion: () => explicitMinRuntimeVersion,
138931
138938
  gitSha: () => gitSha,
138932
138939
  isMonorepoCheckout: () => isMonorepoCheckout,
138933
138940
  l10nLintOptions: () => l10nLintOptions,
@@ -138937,6 +138944,7 @@ __export(build_exports2, {
138937
138944
  listBuildableApps: () => listBuildableApps,
138938
138945
  liveRenderServices: () => liveRenderServices,
138939
138946
  maximumBinaryVersion: () => maximumBinaryVersion,
138947
+ navBundleMinBinaryVersion: () => navBundleMinBinaryVersion,
138940
138948
  navLogicBundleUrl: () => navLogicBundleUrl,
138941
138949
  pinBakedServerBaseUrl: () => pinBakedServerBaseUrl,
138942
138950
  pinnedReleaseFromEnv: () => pinnedReleaseFromEnv,
@@ -138947,6 +138955,7 @@ __export(build_exports2, {
138947
138955
  shellSha: () => shellSha,
138948
138956
  snapshotTokens: () => snapshotTokens,
138949
138957
  tokensSnapshotMessage: () => tokensSnapshotMessage,
138958
+ unsupportedComponentMinVersions: () => unsupportedComponentMinVersions,
138950
138959
  withPinnedRelease: () => withPinnedRelease,
138951
138960
  withStoreNavBundle: () => withStoreNavBundle,
138952
138961
  withoutDevOnlyAppConfig: () => withoutDevOnlyAppConfig
@@ -139217,6 +139226,22 @@ function collectComponentTypes(value2, into = /* @__PURE__ */ new Set()) {
139217
139226
  for (const child of Object.values(obj7)) collectComponentTypes(child, into);
139218
139227
  return into;
139219
139228
  }
139229
+ function unsupportedComponentMinVersions(value2, into = []) {
139230
+ if (!value2 || typeof value2 !== "object") return into;
139231
+ const obj7 = value2;
139232
+ const isComponent2 = typeof obj7.id === "string" && (obj7.body !== null && typeof obj7.body === "object" || typeof obj7.package === "string" && typeof obj7.type === "string");
139233
+ if (isComponent2 && typeof obj7.minVersion === "number" && obj7.minVersion > SUPPORTED_COMPONENT_MIN_VERSION) {
139234
+ into.push({ id: obj7.id, minVersion: obj7.minVersion });
139235
+ }
139236
+ for (const child of Object.values(obj7)) unsupportedComponentMinVersions(child, into);
139237
+ return into;
139238
+ }
139239
+ function explicitMinRuntimeVersion(raw) {
139240
+ if (raw === void 0 || raw.trim() === "") return null;
139241
+ const v2 = raw.trim();
139242
+ if (!/^\d+(?:\.\d+){0,2}$/.test(v2)) throw new Error(`invalid --min-runtime-version "${raw}": expected a numeric version like 1.7.0`);
139243
+ return v2;
139244
+ }
139220
139245
  function collectNativeComponents(value2, into) {
139221
139246
  if (!value2 || typeof value2 !== "object") return;
139222
139247
  const obj7 = value2;
@@ -139239,6 +139264,21 @@ function maximumBinaryVersion(current, candidate) {
139239
139264
  }
139240
139265
  return current;
139241
139266
  }
139267
+ function navBundleMinBinaryVersion(text12) {
139268
+ let cfg;
139269
+ try {
139270
+ cfg = JSON.parse(text12);
139271
+ } catch {
139272
+ return null;
139273
+ }
139274
+ let floor2 = null;
139275
+ for (const ref of [cfg?.app?.logicBundle, cfg?.navigation?.navLogicBundle, cfg?.navLogicBundle]) {
139276
+ if (!ref || typeof ref !== "object") continue;
139277
+ floor2 = maximumBinaryVersion(floor2, ref.minBinaryVersion);
139278
+ floor2 = maximumBinaryVersion(floor2, ref.min_binary_version);
139279
+ }
139280
+ return floor2;
139281
+ }
139242
139282
  async function withStoreNavBundle(text12, address) {
139243
139283
  let cfg;
139244
139284
  try {
@@ -139313,7 +139353,8 @@ async function buildRelease(app, dest, opts = {}) {
139313
139353
  return (await buildFromLoaded(loaded, dest, {
139314
139354
  ...tier5Dir ? { tier5Dir } : {},
139315
139355
  ...opts.fetchFace ? { fetchFace: opts.fetchFace } : {},
139316
- ...opts.keepDevOnlyAppConfig ? { keepDevOnlyAppConfig: true } : {}
139356
+ ...opts.keepDevOnlyAppConfig ? { keepDevOnlyAppConfig: true } : {},
139357
+ ...opts.minRuntimeVersion ? { minRuntimeVersion: opts.minRuntimeVersion } : {}
139317
139358
  })).manifest;
139318
139359
  }
139319
139360
  function countingWixCall(base) {
@@ -139444,6 +139485,13 @@ function readTokensForLint(preloaded) {
139444
139485
  }
139445
139486
  async function buildFromLoaded(preloaded, dest, opts = {}) {
139446
139487
  const app = preloaded.name;
139488
+ const assertComponentMinVersions = (screenId, descriptor) => {
139489
+ const bad2 = unsupportedComponentMinVersions(descriptor);
139490
+ if (!bad2.length) return;
139491
+ throw new Error(
139492
+ `screen ${screenId}: component minVersion is not enforced by any runtime (supported: ${SUPPORTED_COMPONENT_MIN_VERSION}) \u2014 ` + bad2.map((c2) => `${c2.id} asks for ${c2.minVersion}`).join(", ") + `. Declare what the release needs from the runtime as its floor instead: min_binary_version on the logic bundle, or release:build --min-runtime-version.`
139493
+ );
139494
+ };
139447
139495
  const tier5Dir = opts.tier5Dir ?? TIER5_DIR;
139448
139496
  const bundlePath = (name) => {
139449
139497
  const own6 = join28(tier5Dir, `${name}.bundle.js`);
@@ -139630,7 +139678,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
139630
139678
  if (input && typeof input === "object" && !Array.isArray(input)) bundleInputs.set(bundleName, input);
139631
139679
  };
139632
139680
  let handlers;
139633
- let minBinaryVersion = null;
139681
+ let minBinaryVersion = explicitMinRuntimeVersion(opts.minRuntimeVersion);
139634
139682
  const requiredCapabilities2 = new Set(config.capabilities ?? []);
139635
139683
  const capabilityUsage = {
139636
139684
  app: [...config.capabilities ?? []],
@@ -139869,6 +139917,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
139869
139917
  continue;
139870
139918
  }
139871
139919
  const descriptor = await res.json();
139920
+ assertComponentMinVersions(screenId, descriptor);
139872
139921
  collectNativeComponents(descriptor, requiredNativeComponents);
139873
139922
  let bundleName = null;
139874
139923
  const lb = logicBundleOf(descriptor);
@@ -140039,6 +140088,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
140039
140088
  continue;
140040
140089
  }
140041
140090
  const descriptor = await res.json();
140091
+ assertComponentMinVersions(screenId, descriptor);
140042
140092
  collectNativeComponents(descriptor, requiredNativeComponents);
140043
140093
  let bundleName = null;
140044
140094
  const lb = logicBundleOf(descriptor);
@@ -140164,6 +140214,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
140164
140214
  });
140165
140215
  await store.putAppConfig(app, text12);
140166
140216
  appConfigHash = sha2563(text12);
140217
+ minBinaryVersion = maximumBinaryVersion(minBinaryVersion, navBundleMinBinaryVersion(text12));
140167
140218
  if (collect2?.descriptors) for (const id of linkableScreenIdsFrom(text12)) linkable.add(id);
140168
140219
  }
140169
140220
  const ahRes = await devFetch(`${base}/v1/action-handlers/${encodeURIComponent(app)}`, { headers: { "X-Himalaya-App": app } });
@@ -140369,7 +140420,7 @@ function declaresHostProvidedIdentity(auth) {
140369
140420
  const config = auth?.config;
140370
140421
  return typeof config === "object" && config !== null && config.hostProvided === true;
140371
140422
  }
140372
- var BAKE_OFFLINE_BASE, KNOWN_ICON_NAMES, KNOWN_ICONS, APP_SERVICES_LINT_SCREEN, REPO_ROOT5, TIER5_DIR, requireFromHere, SOURCEMAP_ON_DEMAND_PATH, BAKED_SERVER_BASE_URL, SETTLE_TURNS;
140423
+ var BAKE_OFFLINE_BASE, KNOWN_ICON_NAMES, KNOWN_ICONS, APP_SERVICES_LINT_SCREEN, REPO_ROOT5, TIER5_DIR, requireFromHere, SOURCEMAP_ON_DEMAND_PATH, BAKED_SERVER_BASE_URL, SUPPORTED_COMPONENT_MIN_VERSION, SETTLE_TURNS;
140373
140424
  var init_build3 = __esm({
140374
140425
  "../release-build/build.ts"() {
140375
140426
  init_site_view_metadata();
@@ -140413,6 +140464,7 @@ var init_build3 = __esm({
140413
140464
  requireFromHere = createRequire3(import.meta.url);
140414
140465
  SOURCEMAP_ON_DEMAND_PATH = join28(REPO_ROOT5, "core/dev-server/tier5-bundles-src/sourcemap-on-demand.mjs");
140415
140466
  BAKED_SERVER_BASE_URL = "http://baked.himalaya.invalid";
140467
+ SUPPORTED_COMPONENT_MIN_VERSION = 1;
140416
140468
  SETTLE_TURNS = 20;
140417
140469
  }
140418
140470
  });
@@ -143006,7 +143058,9 @@ var init_cli_help = __esm({
143006
143058
  signed with the Wix production key (wix-keystore, the
143007
143059
  upload key Branded apps use; any other
143008
143060
  --android-signing is refused), the APK with the QA
143009
- key. The default stays an APK only.
143061
+ key. The default stays an APK only. For a Containers
143062
+ app, --aab --version <x.y.z> makes that the bundle's
143063
+ versionName, which Google Play shows.
143010
143064
  --borrow-ios-id is an
143011
143065
  iOS-only interim: sign under an internal enterprise id the
143012
143066
  pool already has a profile for (e.g. ent.wix.time.dev); the
@@ -143165,14 +143219,14 @@ var init_cli_help = __esm({
143165
143219
  env vars are accepted as flag equivalents. Optional local
143166
143220
  cert/profile flags classify on-disk material without
143167
143221
  replacing stored Branded secrets.
143168
- himi one-app migrate --msid <uuid> [--app-instance branded|free]
143222
+ himi one-app migrate --msid <uuid> [--app-instance branded|free] [--locale en|he|es]
143169
143223
  [--prompt <text> | --prompt-file <file>] [--name <slug>] [--dir <parent>] [--target bo]
143170
143224
  [--top-tabs bottom-tabs|keep] [--json]
143171
143225
  collect One App configuration and hand off to the current coding agent
143172
143226
  for faithful reconstruction and a checked hosted draft. Branded falls
143173
143227
  back to Free (Spaces) only when absent. No model is launched here.
143174
143228
  --dir is a parent; an existing destination is refused. Top tabs become
143175
- bottom tabs unless --top-tabs keep.
143229
+ bottom tabs unless --top-tabs keep. --locale selects the source view (default en).
143176
143230
  himi site create <name> [--type wix|headless|branded-app|vibe] [--template <guid>]
143177
143231
  [--verticals stores,bookings,\u2026] [--folder <guid>] [--redirect-uri <uri>]
143178
143232
  [--no-oauth-app] [--write-provisioning [path]] [--site-url <url>] --yes
@@ -143336,7 +143390,7 @@ Transport: same targets/tokens as himi-serve \u2014 --target <local|prod|bo>, --
143336
143390
  --telemetry-url, --control-token/--telemetry-token, or HIMI_* env.
143337
143391
  Guides: ${DEVELOPER_PORTAL_URL}`;
143338
143392
  COMMANDS = [
143339
- { name: "one-app", summary: "collect One App source configuration and evidence for reconstruction; validate-topbar checks authored settings and resolved platform bars; validate-design compares the source theme's colors, heading/body font families, button shape and accent text contrast with the migrated tokens.json; coverage inventories and verifies source requirements. Branded falls back to Free/Spaces only when absent. Collection does not launch a model or build the app. User-scoped Wix authentication is required; WIX_API_KEY is not used.", required: "migrate --msid <uuid> [--app-instance branded|free] [--prompt <text> | --prompt-file <file>] [--name <slug>] [--dir <parent>] [--target bo] [--top-tabs bottom-tabs|keep] [--json] | validate-topbar --evidence-dir <.himi/one-app> --content <app-dir> [--json] | validate-design --evidence-dir <.himi/one-app> --content <app-dir> [--json] [--fix] [--record --release-hash <sha256>] | coverage init|sync|check|verify --evidence-dir <.himi/one-app> --content <app-dir> [--release-hash <sha256>]" },
143393
+ { name: "one-app", summary: "collect One App source configuration and evidence for reconstruction; validate-topbar checks authored settings and resolved platform bars; validate-design compares the source theme's colors, heading/body font families, button shape and accent text contrast with the migrated tokens.json; coverage inventories and verifies source requirements. Branded falls back to Free/Spaces only when absent. Collection does not launch a model or build the app. User-scoped Wix authentication is required; WIX_API_KEY is not used.", required: "migrate --msid <uuid> [--app-instance branded|free] [--locale en|he|es] [--prompt <text> | --prompt-file <file>] [--name <slug>] [--dir <parent>] [--target bo] [--top-tabs bottom-tabs|keep] [--json] | validate-topbar --evidence-dir <.himi/one-app> --content <app-dir> [--json] | validate-design --evidence-dir <.himi/one-app> --content <app-dir> [--json] [--fix] [--record --release-hash <sha256>] | coverage init|sync|check|verify --evidence-dir <.himi/one-app> --content <app-dir> [--release-hash <sha256>]" },
143340
143394
  { name: "hhp", summary: "author responsive HTML/CSS/TypeScript screens compiled to native SDUI and T5 workers; scaffold, inspect the app profile, lint or compile declared sources", required: "init <screen> | profile | lint | compile [--app <name>|--content <dir>] [--json] [--dry-run]" },
143341
143395
  { name: "captcha", summary: "create and store native CAPTCHA keys in Serve, or inspect setup status; customer setup verifies Wix site ownership; does not enable member CAPTCHA SDKs", required: "setup|status --app <app> [--content <dir>] [--site <msid>] [--ios-bundle-id <id>] [--android-package-name <id>] [--target <t>]" },
143342
143396
  { name: "init", summary: "scaffold a starter content package (OTA-only; no native shells). --template <t> starts from a full reference app (branded-lite = consumer storefront over a Wix site; owner-lite = owner CRUD/management) instead of the minimal counter; --templates lists bundled ones; --remote fetches the template off the serve plane (falls back to the bundled copy offline). The new app also gets its agent files (the same set `himi agent-init` writes: AGENTS.md, CLAUDE.md, the himalaya skill, HIMALAYA.md, a SessionStart hook) so the next session started inside it picks the work up; --no-agent skips them. It also makes the build board (.himi/studio/, exactly as `himi studio --no-open` does \u2014 it never opens a browser), so every later render, test, validate, push and progress entry refreshes it; and, for a template bundled with this CLI, it makes the FIRST PICTURE itself (never for a --remote one: that is its publisher's code, and a render runs it on this machine, so next[] leaves the render to the agent after it has read the code): exactly `himi render <homeScreenId> --png --mocks --device iphone` (offline \u2014 no request; never --live; --mocks loads the app's recorded data when it has any), run as a child it kills after a time budget, writing .himi/shots/<home>.png and journaling it (by: himi) as the STARTING POINT (\"Starting point: the <template> template, before any of your changes\") so the board and the journal hold a picture when init returns. init also records the source it wrote (.himi/init-source.json: a content fingerprint, Markdown left out), and the first home PNG render after the source diverges from it is journaled once as \"First look at your app\" \u2014 reported as `firstLook: {image}` or `{skipped: <reason>}`, never a failed init; `--no-first-look` skips it (for scripts and CI that render themselves). For a bundled template (never a --remote one \u2014 the preview would build and serve its publisher's code) init also STARTS the live preview itself: `himi run --watch --content <dir> --port <p> --no-open --idle-exit 30`, detached in its own process group with its output in .himi/watch.log, never waited for (the url is chosen before it builds), recorded in .himi/watch.json, and reported as `watch: {started, pid, url, board, log}` \u2014 or `{skipped: <reason>}` for a `CI` environment, a test runner, a watch already running, or a start that failed (never a failed init). Nothing else skips it: outside CI it is started, and `watch.note` says an opt-out was ignored. The envelope LEADS with `doNow`: three lines to run now (the consent preflight, the live preview \u2014 its url and board when init started it, else `himi run --watch --content <dir> &` with the board's path \u2014 and the postcard line), and ENDS with the same lines as `doNowAgain`, so an agent that reads only the head or only the tail (`| tail`) gets them; at a terminal they are also printed as plain text on stderr, before the JSON and again after it. Its `next[]` LEADS with the steps for THIS session, in this order for every app \u2014 the offline first render and that picture's `himi progress` postcard (only when init could not make the picture), the skill's consent preflight (authorize or mock any Wix or external startup request; with none, go straight on), and only then the live preview (the running one's url, or `himi run --watch &` when init did not start it) \u2014 ahead of the next-session guidance", required: "<name> [--dir] [--template <t>] [--remote] [--base44-app-id <id>] [--base44-app-url <https://tenant>] [--no-agent] [--no-first-look] | --templates" },
@@ -177116,40 +177170,40 @@ var init_preview_assets_generated = __esm({
177116
177170
  "../../packages/serve/src/preview-assets.generated.ts"() {
177117
177171
  init_preview_assets_format();
177118
177172
  PREVIEW_ASSET_MANIFEST = [
177119
- { key: "assets/DashboardHost-PovpV9S7.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 2955, sha256: "cadcd035072eb408d6a5ff55c5b688a8b7442f39262d5c0e6c94a44397105b5e" },
177120
- { key: "assets/DevDrawer-C-Mo1jWk.js", contentType: "application/javascript; charset=utf-8", offset: 2963, length: 16783, sha256: "d06adc1acc221f90edf241f3761685d9e40b4abf30ce488ef0f1dc4a36f42ae6" },
177121
- { key: "assets/IdiomCompare-hJTsaRqS.js", contentType: "application/javascript; charset=utf-8", offset: 19746, length: 1926, sha256: "0431d4c0d7d10b9064fbe0669c91c8d6c91bc9a100defe914ead48eaf06cd60d" },
177122
- { key: "assets/LightboxViewer-DhCRPTdo.js", contentType: "application/javascript; charset=utf-8", offset: 21672, length: 8171, sha256: "dbe56e2b259d79bec234d3034a856849ea8086bdbee0d26c0ee886b610c3e7e2" },
177123
- { key: "assets/OfflineReadingBar-DaBzb_ID.js", contentType: "application/javascript; charset=utf-8", offset: 29843, length: 1707, sha256: "feed855f3715ddb69792ccf81dcbbc758644de4b53bcfbd0bf5927dd5eb4b829" },
177124
- { key: "assets/PhonePreviewControl-BfGivW6n.js", contentType: "application/javascript; charset=utf-8", offset: 31550, length: 37768, sha256: "ff629080661a3fa48bfc519d0ad6e15e231bf27021740fe580314ec16aabf2a3" },
177125
- { key: "assets/SchemeCompare-9sM1AhQv.js", contentType: "application/javascript; charset=utf-8", offset: 69318, length: 1858, sha256: "c1fda62853fe6318c937371bec32215d8d71d7740eb4e735c5d3818da4d53d25" },
177173
+ { key: "assets/DashboardHost-CYO0B4ZT.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 2955, sha256: "b28a117714edc1ef96df42fa673943f3bdb35086382f595eda486adf3fbe77e3" },
177174
+ { key: "assets/DevDrawer-DpCUNNFN.js", contentType: "application/javascript; charset=utf-8", offset: 2963, length: 16783, sha256: "0a6e63da6064a1af9cde6c8e2b0c76f2136d85059ffc02d90a904bac9223ddcb" },
177175
+ { key: "assets/IdiomCompare-Bx6trAik.js", contentType: "application/javascript; charset=utf-8", offset: 19746, length: 1926, sha256: "104c90f0a56a790fc81c770202c9867c86e30b5e4aa8ed3d317b7e032779c112" },
177176
+ { key: "assets/LightboxViewer-YnNy08Gy.js", contentType: "application/javascript; charset=utf-8", offset: 21672, length: 8171, sha256: "31b347b257759964f9dba0b6d5266caa274d020ce2be4ae86382e19eb98cbaf8" },
177177
+ { key: "assets/OfflineReadingBar-xLsk3emQ.js", contentType: "application/javascript; charset=utf-8", offset: 29843, length: 1707, sha256: "8a23bd4ba010b7835bffa1ee83d0c37da4caf9ebaf15ceacbe94c08cd6882c54" },
177178
+ { key: "assets/PhonePreviewControl-CvM0I0dk.js", contentType: "application/javascript; charset=utf-8", offset: 31550, length: 37768, sha256: "2c37ef34ddc03f112af870971e162079806bd267c3c87afee3d086025d3d8800" },
177179
+ { key: "assets/SchemeCompare-CkjFv_Sd.js", contentType: "application/javascript; charset=utf-8", offset: 69318, length: 1858, sha256: "1a8862d0023ba150206c8f1f7e5bb5cdde733d8f5654ce565b6923694dde84e2" },
177126
177180
  { key: "assets/glassPreviewBrowser-Bt5ZFmG4.js", contentType: "application/javascript; charset=utf-8", offset: 71176, length: 342, sha256: "20d73f97d38f6d9a0b79e68e24954cd6bbfe66833a6e6aecae00a9102e64cab3" },
177127
- { key: "assets/index-DGebBa0y.js", contentType: "application/javascript; charset=utf-8", offset: 71518, length: 1355865, sha256: "9fc116b86e1793b603162b2a7c25f9cd855e15e7bb012543d1f9b8395fc68bd8" },
177128
- { key: "assets/jsx-runtime-CY_jTiqj.js", contentType: "application/javascript; charset=utf-8", offset: 1427383, length: 7624, sha256: "29dfba5b56f79a0b84d6b04d84d87617454baeba03c225f682ab2ab7ae2d5016" },
177129
- { key: "assets/pdf-CC6sbHfN.js", contentType: "application/javascript; charset=utf-8", offset: 1435007, length: 488199, sha256: "257bc98f877e4e6b5fd34c6c7bf73d447765b1bc1ca4f223fa54c7b607c2cde3" },
177130
- { key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset: 1923206, length: 73, sha256: "41bcfda4f3c8c0a81c785ea87c69afc8e7d0ed8c333324aee94c273d881bb6aa" },
177131
- { key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset: 1923279, length: 1317034, sha256: "a33cfe728c584fdba4fcc1fd54bcdc2f9f2f13889ddbb5b2bd1d0f8cbe49b84e" },
177132
- { key: "assets/pdfDocument-Brw2ZBr0.js", contentType: "application/javascript; charset=utf-8", offset: 3240313, length: 3453, sha256: "a476eb74e80066054bced7932be0b5390f3bdd39394b6363394c40a13f947c67" },
177133
- { key: "assets/pdfFetch-Cc8i1I1h.js", contentType: "application/javascript; charset=utf-8", offset: 3243766, length: 2266, sha256: "1d21ad008921942217c9eac0c35b1713773b9d89c71e3ab4412781f7bb88f463" },
177134
- { key: "assets/webviewBridgeHost-CgPzp62r.js", contentType: "application/javascript; charset=utf-8", offset: 3246032, length: 9888, sha256: "674eab3ecaa54efb5cc2d70d5548ff220ea80d9f14574bc7b1390ea365514e8e" },
177135
- { key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 3255920, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
177136
- { key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 3260530, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
177137
- { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 3749114, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
177138
- { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 3840038, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
177139
- { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 3931022, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
177140
- { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 4022002, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
177141
- { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 4112874, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
177142
- { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 4203854, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
177143
- { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 4312490, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
177144
- { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 4421574, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
177145
- { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 4530622, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
177146
- { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 4638322, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
177147
- { key: "himi-sw.js", contentType: "application/javascript; charset=utf-8", offset: 4726430, length: 6748, sha256: "4a92459977d7cefa1a6a7e020c3a63509737f083b3f2773557c1a5771665811a" },
177148
- { key: "index.html", contentType: "text/html; charset=utf-8", offset: 4733178, length: 5037, sha256: "f0e8760a7edc183100caef0efddddb8d81f591c54b5584a968eda6d6004d934d" },
177149
- { key: "ios-glass-preview.css", contentType: "text/css; charset=utf-8", offset: 4738215, length: 7193, sha256: "a482f4796147c2a3893942e10ab225bd3b6f749f7125fe0330680d4c20ea0212" },
177150
- { key: "ios-glass-preview.svg", contentType: "image/svg+xml", offset: 4745408, length: 423, sha256: "b9cd5989d31464a0422f260a332af6be5add0b04de2148944de35158f3b75efc" },
177151
- { key: "kit-tab-bar.css", contentType: "text/css; charset=utf-8", offset: 4745831, length: 1171, sha256: "9e2c3a0faaf05d5471badf167a4d3bdf1c4e6dd65c432eea6d254158bfd99585" },
177152
- { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 4747002, length: 19459, sha256: "760d3263ea56776e60a4808558b32ae20ea2c667c0634573b9fdc5c7694a4f20" }
177181
+ { key: "assets/index-CwvFrtms.js", contentType: "application/javascript; charset=utf-8", offset: 71518, length: 1360541, sha256: "290275d5b28ab14fe757a7abe88772b8a666606b6218efecdfe92e2b78ee4fa7" },
177182
+ { key: "assets/jsx-runtime-CY_jTiqj.js", contentType: "application/javascript; charset=utf-8", offset: 1432059, length: 7624, sha256: "29dfba5b56f79a0b84d6b04d84d87617454baeba03c225f682ab2ab7ae2d5016" },
177183
+ { key: "assets/pdf-CFYLoc3B.js", contentType: "application/javascript; charset=utf-8", offset: 1439683, length: 488199, sha256: "b769c55b16c2e36f30a03fb1c8db7df7b545a573ebaf9017045280ba5c7133a3" },
177184
+ { key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset: 1927882, length: 73, sha256: "41bcfda4f3c8c0a81c785ea87c69afc8e7d0ed8c333324aee94c273d881bb6aa" },
177185
+ { key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset: 1927955, length: 1317034, sha256: "a33cfe728c584fdba4fcc1fd54bcdc2f9f2f13889ddbb5b2bd1d0f8cbe49b84e" },
177186
+ { key: "assets/pdfDocument-D4Yi7k31.js", contentType: "application/javascript; charset=utf-8", offset: 3244989, length: 3453, sha256: "af7e4e92d25430e40588af37be2e9ae77a40407856bfe7730c8449cb6b471b9a" },
177187
+ { key: "assets/pdfFetch-Cc8i1I1h.js", contentType: "application/javascript; charset=utf-8", offset: 3248442, length: 2266, sha256: "1d21ad008921942217c9eac0c35b1713773b9d89c71e3ab4412781f7bb88f463" },
177188
+ { key: "assets/webviewBridgeHost-Cb8_2SDK.js", contentType: "application/javascript; charset=utf-8", offset: 3250708, length: 9888, sha256: "b095fce26dbf3da40a42335506008ece7afb4fed635bc1c2af7b0a02a0621323" },
177189
+ { key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 3260596, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
177190
+ { key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 3265206, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
177191
+ { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 3753790, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
177192
+ { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 3844714, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
177193
+ { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 3935698, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
177194
+ { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 4026678, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
177195
+ { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 4117550, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
177196
+ { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 4208530, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
177197
+ { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 4317166, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
177198
+ { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 4426250, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
177199
+ { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 4535298, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
177200
+ { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 4642998, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
177201
+ { key: "himi-sw.js", contentType: "application/javascript; charset=utf-8", offset: 4731106, length: 6748, sha256: "4a92459977d7cefa1a6a7e020c3a63509737f083b3f2773557c1a5771665811a" },
177202
+ { key: "index.html", contentType: "text/html; charset=utf-8", offset: 4737854, length: 5037, sha256: "ca054e55141a7a48a05bf731651a6c37cc8b19df5e214e5a2225ce9cb51f76c3" },
177203
+ { key: "ios-glass-preview.css", contentType: "text/css; charset=utf-8", offset: 4742891, length: 7193, sha256: "a482f4796147c2a3893942e10ab225bd3b6f749f7125fe0330680d4c20ea0212" },
177204
+ { key: "ios-glass-preview.svg", contentType: "image/svg+xml", offset: 4750084, length: 423, sha256: "b9cd5989d31464a0422f260a332af6be5add0b04de2148944de35158f3b75efc" },
177205
+ { key: "kit-tab-bar.css", contentType: "text/css; charset=utf-8", offset: 4750507, length: 1171, sha256: "9e2c3a0faaf05d5471badf167a4d3bdf1c4e6dd65c432eea6d254158bfd99585" },
177206
+ { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 4751678, length: 19459, sha256: "760d3263ea56776e60a4808558b32ae20ea2c667c0634573b9fdc5c7694a4f20" }
177153
177207
  ];
177154
177208
  }
177155
177209
  });
@@ -185930,7 +185984,9 @@ ${label3}`);
185930
185984
  // silent no-op. Every other multi-word flag here uses the bracket form for the same reason.
185931
185985
  ...str3(flags["borrow-ios-id"]) ? { borrowIosBundleId: str3(flags["borrow-ios-id"]) } : {},
185932
185986
  ...str3(flags.destination) ? { destination: str3(flags.destination) } : {},
185933
- ...customerTestflight || testflight && customerVersion ? { version: customerVersion } : {},
185987
+ // A Play bundle carries it too: a Containers app's bundle takes it as its versionName, and the
185988
+ // plane ignores it on any other bundle.
185989
+ ...customerTestflight || (testflight || flags.aab === true) && customerVersion ? { version: customerVersion } : {},
185934
185990
  ...str3(flags.signing) ? { signing: str3(flags.signing) } : {},
185935
185991
  ...str3(flags.site) ? { site: str3(flags.site) } : {},
185936
185992
  // WHICH KEYSTORE signs the APK. A separate axis from --signing (that one is the Apple
@@ -198342,7 +198398,31 @@ var init_base44 = __esm({
198342
198398
  }
198343
198399
  });
198344
198400
 
198401
+ // ../../core/sdk/wix-platform/src/business-address.ts
198402
+ function businessAddress(address) {
198403
+ const line = address?.googleFormattedAddress?.trim() || [
198404
+ [address?.streetNumber, address?.street].filter(Boolean).join(" ").trim(),
198405
+ [address?.city, [address?.state, address?.zip].filter(Boolean).join(" ").trim(), address?.country].filter(Boolean).join(", ")
198406
+ ].filter(Boolean).join(", ").trim();
198407
+ const latitude = address?.coordinates?.latitude;
198408
+ const longitude = address?.coordinates?.longitude;
198409
+ const validPoint = address?.isPhysical !== false && typeof latitude === "number" && Number.isFinite(latitude) && Math.abs(latitude) <= 90 && typeof longitude === "number" && Number.isFinite(longitude) && Math.abs(longitude) <= 180;
198410
+ return {
198411
+ address: line,
198412
+ ...typeof address?.isPhysical === "boolean" ? { isPhysical: address.isPhysical } : {},
198413
+ ...validPoint ? { coordinates: { latitude, longitude } } : {}
198414
+ };
198415
+ }
198416
+ var init_business_address = __esm({
198417
+ "../../core/sdk/wix-platform/src/business-address.ts"() {
198418
+ }
198419
+ });
198420
+
198345
198421
  // src/one-app/errors.ts
198422
+ var errors_exports = {};
198423
+ __export(errors_exports, {
198424
+ OneAppError: () => OneAppError
198425
+ });
198346
198426
  var OneAppError;
198347
198427
  var init_errors2 = __esm({
198348
198428
  "src/one-app/errors.ts"() {
@@ -198358,6 +198438,11 @@ var init_errors2 = __esm({
198358
198438
  });
198359
198439
 
198360
198440
  // src/one-app/collect.ts
198441
+ var collect_exports = {};
198442
+ __export(collect_exports, {
198443
+ collectOneApp: () => collectOneApp,
198444
+ resolveSourceLocale: () => resolveSourceLocale
198445
+ });
198361
198446
  import { createHash as createHash51 } from "node:crypto";
198362
198447
  function isObject2(value2) {
198363
198448
  return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
@@ -198390,11 +198475,17 @@ function validateStructure(value2, stage, enriched = false) {
198390
198475
  function sourceApp(instance) {
198391
198476
  return instance === "branded" ? "WixBrandedApp" : "WixOneApp";
198392
198477
  }
198393
- function structureUrl(path2, metaSiteId, instance) {
198478
+ function resolveSourceLocale(value2 = "en") {
198479
+ if (typeof value2 !== "string" || !isSupportedLocale(value2)) {
198480
+ throw new OneAppError("invalid_locale", `Choose ${SUPPORTED_LOCALES.join(", ")} for --locale.`);
198481
+ }
198482
+ return value2;
198483
+ }
198484
+ function structureUrl(path2, metaSiteId, instance, locale) {
198394
198485
  const url = new URL(`${MIDDLEWARE}/${path2}`);
198395
198486
  url.searchParams.set("businessId", metaSiteId);
198396
198487
  url.searchParams.set("appInstance", instance === "branded" ? "BRANDED" : "DEFAULT");
198397
- url.searchParams.set("locale", "en");
198488
+ url.searchParams.set("locale", locale);
198398
198489
  url.searchParams.set("forApp", sourceApp(instance));
198399
198490
  return url.href;
198400
198491
  }
@@ -198417,8 +198508,31 @@ function businessProjection(value2, metaSiteId) {
198417
198508
  if (context.services && Object.values(context.services).some((service) => !isObject2(service))) {
198418
198509
  throw invalidResponse("business");
198419
198510
  }
198511
+ if (isObject2(value2.members) && typeof value2.members.count === "number" && Number.isSafeInteger(value2.members.count) && value2.members.count >= 0) context.memberCount = value2.members.count;
198420
198512
  return { context, title: typeof value2.title === "string" ? value2.title : void 0 };
198421
198513
  }
198514
+ function contactProjection(value2, metaSiteId) {
198515
+ if (!isObject2(value2) || typeof value2.metaSiteId !== "string" || !isObject2(value2.properties)) throw invalidResponse("business_contact");
198516
+ if (value2.metaSiteId.toLowerCase() !== metaSiteId.toLowerCase()) {
198517
+ throw new OneAppError("source_site_mismatch", "The returned contact does not match the requested site.", { stage: "business_contact" });
198518
+ }
198519
+ const p2 = value2.properties;
198520
+ for (const field of ["phone", "email"]) {
198521
+ if (p2[field] != null && typeof p2[field] !== "string") throw invalidResponse("business_contact");
198522
+ }
198523
+ if (p2.address != null) {
198524
+ if (!isObject2(p2.address)) throw invalidResponse("business_contact");
198525
+ for (const field of ["googleFormattedAddress", "street", "streetNumber", "city", "state", "zip", "country"]) {
198526
+ if (p2.address[field] != null && typeof p2.address[field] !== "string") throw invalidResponse("business_contact");
198527
+ }
198528
+ if (p2.address.isPhysical != null && typeof p2.address.isPhysical !== "boolean") throw invalidResponse("business_contact");
198529
+ }
198530
+ return {
198531
+ ...businessAddress(p2.address),
198532
+ phone: typeof p2.phone === "string" ? p2.phone.trim() : "",
198533
+ email: typeof p2.email === "string" ? p2.email.trim() : ""
198534
+ };
198535
+ }
198422
198536
  function boundedSetting(value2, ceiling) {
198423
198537
  return value2 !== void 0 && Number.isFinite(value2) && value2 > 0 ? Math.min(value2, ceiling) : ceiling;
198424
198538
  }
@@ -198433,6 +198547,7 @@ function semanticFingerprint(structure) {
198433
198547
  return createHash51("sha256").update(canonical7(structure, true)).digest("hex");
198434
198548
  }
198435
198549
  async function collectOneApp(input, deps = {}) {
198550
+ const locale = resolveSourceLocale(input.locale);
198436
198551
  if (typeof input.metaSiteId !== "string" || !UUID.test(input.metaSiteId)) {
198437
198552
  throw new OneAppError("invalid_msid", "Provide a valid One App metasite ID.");
198438
198553
  }
@@ -198448,6 +198563,7 @@ async function collectOneApp(input, deps = {}) {
198448
198563
  const timeoutMs = boundedSetting(deps.timeoutMs, TIMEOUT_MS3);
198449
198564
  const credentials = /* @__PURE__ */ new Set([input.authorization]);
198450
198565
  let internalBusinessRead = false;
198566
+ let visitorToken;
198451
198567
  function redact(value2) {
198452
198568
  const secrets = [...credentials].sort((a2, b2) => b2.length - a2.length);
198453
198569
  const redactString = (value3) => {
@@ -198587,14 +198703,18 @@ async function collectOneApp(input, deps = {}) {
198587
198703
  return request(visitorUrl.href, "business", void 0, { instance });
198588
198704
  }
198589
198705
  }
198590
- async function enrichmentAuthorization() {
198591
- if (!internalBusinessRead) return input.authorization;
198592
- const session = await request(`${VISITOR_SESSION}${input.metaSiteId}/signed-instance?signed_instance_type=Visitor`, "enrichment_session", void 0, { siteScoped: false });
198593
- if (!isObject2(session) || session.signedInstanceType !== "Visitor" || typeof session.signedInstance !== "string" || !session.signedInstance.trim() || /[\r\n]/.test(session.signedInstance) || typeof session.validUntil !== "string" || !Number.isFinite(Date.parse(session.validUntil)) || Date.parse(session.validUntil) <= (deps.now ?? (() => /* @__PURE__ */ new Date()))().getTime()) throw invalidResponse("enrichment_session");
198706
+ async function visitorAuthorization(stage) {
198707
+ if (visitorToken) return visitorToken;
198708
+ const session = await request(`${VISITOR_SESSION}${input.metaSiteId}/signed-instance?signed_instance_type=Visitor`, stage, void 0, { siteScoped: false });
198709
+ if (!isObject2(session) || session.signedInstanceType !== "Visitor" || typeof session.signedInstance !== "string" || !session.signedInstance.trim() || /[\r\n]/.test(session.signedInstance) || typeof session.validUntil !== "string" || !Number.isFinite(Date.parse(session.validUntil)) || Date.parse(session.validUntil) <= (deps.now ?? (() => /* @__PURE__ */ new Date()))().getTime()) throw invalidResponse(stage);
198594
198710
  credentials.add(session.signedInstance);
198595
- return session.signedInstance;
198711
+ visitorToken = session.signedInstance;
198712
+ return visitorToken;
198596
198713
  }
198597
- const rawUrl = structureUrl("published-structure", input.metaSiteId, requested);
198714
+ async function enrichmentAuthorization() {
198715
+ return internalBusinessRead ? visitorAuthorization("enrichment_session") : input.authorization;
198716
+ }
198717
+ const rawUrl = structureUrl("published-structure", input.metaSiteId, requested, locale);
198598
198718
  const originalRaw = validateStructure(await request(rawUrl, "published", {}), "published");
198599
198719
  const baseline = semanticFingerprint(originalRaw);
198600
198720
  const rawStructure = redact(originalRaw);
@@ -198606,14 +198726,44 @@ async function collectOneApp(input, deps = {}) {
198606
198726
  const businessUrl = new URL(`${BUSINESS}${input.metaSiteId}`);
198607
198727
  businessUrl.searchParams.set("forApp", sourceApp(resolved2));
198608
198728
  const projected = businessProjection(await readBusiness(businessUrl, resolved2), input.metaSiteId);
198609
- const businessContext = redact(projected.context);
198729
+ let businessContext = redact(projected.context);
198730
+ const contextWarnings = [];
198731
+ if (Object.values(rawStructure.sections).some((section3) => {
198732
+ if (!isObject2(section3)) return false;
198733
+ const definition = section3.sectionDefinitionId ?? section3.section_definition_id;
198734
+ return typeof definition === "string" && CONTACT_SECTIONS.has(definition);
198735
+ })) {
198736
+ const requiredVisitor = internalBusinessRead ? await visitorAuthorization("enrichment_session") : void 0;
198737
+ try {
198738
+ const contactAuthorization = requiredVisitor ?? await visitorAuthorization("business_contact_session");
198739
+ businessContext.contact = redact(contactProjection(await request(
198740
+ PUBLIC_CONTACT,
198741
+ "business_contact",
198742
+ void 0,
198743
+ { authorization: contactAuthorization, siteScoped: false }
198744
+ ), input.metaSiteId));
198745
+ } catch (error) {
198746
+ if (!(error instanceof OneAppError) || ![
198747
+ "source_not_found",
198748
+ "source_request_failed",
198749
+ "source_timeout",
198750
+ "source_response_too_large"
198751
+ ].includes(error.code)) throw error;
198752
+ contextWarnings.push({
198753
+ code: "business_contact_unavailable",
198754
+ failureCode: error.code,
198755
+ message: "Public business contact is unavailable. Keep contact sections unresolved until their data can be verified."
198756
+ });
198757
+ }
198758
+ }
198759
+ businessContext = redact(businessContext);
198610
198760
  await progress("business-context", businessContext);
198611
198761
  const enrichBody = {
198612
198762
  productionRules: [],
198613
198763
  ...businessContext.services ? { services: businessContext.services } : {},
198614
198764
  ...projected.title ? { businessTitle: redact(projected.title) } : {}
198615
198765
  };
198616
- const enrichUrl = structureUrl("v2/structure-enriched", input.metaSiteId, resolved2);
198766
+ const enrichUrl = structureUrl("v2/structure-enriched", input.metaSiteId, resolved2, locale);
198617
198767
  const authorization = await enrichmentAuthorization();
198618
198768
  const enrich = async (platform) => {
198619
198769
  const structure = validateStructure(await request(enrichUrl, `enriched_${platform}`, enrichBody, {
@@ -198631,7 +198781,6 @@ async function collectOneApp(input, deps = {}) {
198631
198781
  };
198632
198782
  const snapshots = await Promise.allSettled([enrich("ios"), enrich("android")]);
198633
198783
  const enriched = {};
198634
- const contextWarnings = [];
198635
198784
  for (const [index, platform] of ["ios", "android"].entries()) {
198636
198785
  const snapshot3 = snapshots[index];
198637
198786
  if (snapshot3.status === "fulfilled") {
@@ -198665,21 +198814,23 @@ async function collectOneApp(input, deps = {}) {
198665
198814
  sourceApp: sourceApp(resolved2),
198666
198815
  fallback: requested !== resolved2,
198667
198816
  fetchedAt: (deps.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
198668
- context: { locale: "en", shell: resolved2 === "branded" ? "branded" : "places", platforms: ["ios", "android"], identity: internalBusinessRead ? "visitor" : "user", productionRules: "not-collected" }
198817
+ context: { locale, shell: resolved2 === "branded" ? "branded" : "places", platforms: ["ios", "android"], identity: internalBusinessRead ? "visitor" : "user", productionRules: "not-collected" }
198669
198818
  },
198670
198819
  rawStructure,
198671
198820
  enriched,
198672
198821
  businessContext,
198673
198822
  warnings: [
198674
198823
  { code: "runtime_rules_unavailable", message: "Engine production rules were not collected. Empty rule input does not establish that the source has no restrictions." },
198675
- { code: "viewer_context", message: internalBusinessRead ? "Enrichment shows English iOS and Android visitor views. Preserve authored raw access rules; this view does not establish member or manager access." : "Enrichment shows English iOS and Android views for a Wix user. Preserve authored raw access rules; this view does not establish visitor or member access." },
198824
+ { code: "viewer_context", message: internalBusinessRead ? `Enrichment requests locale ${locale} for iOS and Android visitor views. Preserve authored raw access rules; this view does not establish member or manager access.` : `Enrichment requests locale ${locale} for iOS and Android views for a Wix user. Preserve authored raw access rules; this view does not establish visitor or member access.` },
198676
198825
  ...contextWarnings
198677
198826
  ]
198678
198827
  };
198679
198828
  }
198680
- var MIDDLEWARE, BUSINESS, TOKEN_INFO, IS_PERMITTED, INTERNAL_PERMISSION, VISITOR_SESSION, MAX_RESPONSE_BYTES, TIMEOUT_MS3, UUID, LIFECYCLE_FIELDS;
198829
+ var MIDDLEWARE, BUSINESS, TOKEN_INFO, IS_PERMITTED, INTERNAL_PERMISSION, VISITOR_SESSION, PUBLIC_CONTACT, CONTACT_SECTIONS, MAX_RESPONSE_BYTES, TIMEOUT_MS3, UUID, LIFECYCLE_FIELDS;
198681
198830
  var init_collect = __esm({
198682
198831
  "src/one-app/collect.ts"() {
198832
+ init_locale();
198833
+ init_business_address();
198683
198834
  init_errors2();
198684
198835
  MIDDLEWARE = "https://manage.wix.com/_serverless/mobile-apps-editor-middleware";
198685
198836
  BUSINESS = "https://apps.wix.com/_api/app-state/v1/user/businesses/";
@@ -198687,6 +198838,8 @@ var init_collect = __esm({
198687
198838
  IS_PERMITTED = "https://www.wixapis.com/authorization-server/v1/authorization/is_permitted";
198688
198839
  INTERNAL_PERMISSION = "BRANDED_APPS.MANAGE_INTERNAL";
198689
198840
  VISITOR_SESSION = "https://apps.wix.com/_api/one-app-session-web/v3/businesses/";
198841
+ PUBLIC_CONTACT = "https://apps.wix.com/api/v1/mobile-platform-facade/business/site-properties";
198842
+ CONTACT_SECTIONS = /* @__PURE__ */ new Set(["platform_general_contact_section", "platform_general_contact_section_bp"]);
198690
198843
  MAX_RESPONSE_BYTES = 8e6;
198691
198844
  TIMEOUT_MS3 = 3e4;
198692
198845
  UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -198908,6 +199061,7 @@ function readOptions(argv, cwd, commandIncluded) {
198908
199061
  const metaSiteId = flags.msid?.trim().toLowerCase();
198909
199062
  if (!metaSiteId || !UUID2.test(metaSiteId)) throw new OneAppError("invalid_msid", "Pass a valid MetaSite ID with --msid.");
198910
199063
  const appInstance = flags["app-instance"] ?? "branded";
199064
+ const locale = resolveSourceLocale(flags.locale);
198911
199065
  if (appInstance !== "branded" && appInstance !== "free") {
198912
199066
  throw new OneAppError("invalid_app_instance", "Choose branded or free for --app-instance.");
198913
199067
  }
@@ -198945,7 +199099,7 @@ function readOptions(argv, cwd, commandIncluded) {
198945
199099
  const workspace = join117(parentDir, name);
198946
199100
  assertSafeParents(parentDir);
198947
199101
  if (pathExists(workspace)) throw new OneAppError("output_exists", "The destination already exists. Choose a new --name or --dir.");
198948
- return { metaSiteId, appInstance, prompt, name, parentDir, workspace, target, topTabs };
199102
+ return { metaSiteId, appInstance, locale, prompt, name, parentDir, workspace, target, topTabs };
198949
199103
  }
198950
199104
  function pathExists(path2) {
198951
199105
  try {
@@ -199027,7 +199181,7 @@ async function runOneAppCommand(argv, io2, deps = {}, commandIncluded = false) {
199027
199181
  if (argv.includes("--help")) {
199028
199182
  io2.log(`${ONE_APP_USAGE}
199029
199183
 
199030
- Collect the source mobile app and hand it to the current coding agent. The agent continues with a faithful plan, local generation and a checked hosted draft. Branded falls back to Free (Spaces) only when absent. This command itself does not launch AI or build an app. --dir is the parent directory; an existing destination is refused. --top-tabs bottom-tabs (default) plans bottom tabs, one per visible page, for a source with top tabs; keep retains the top tabs.
199184
+ Collect the source mobile app and hand it to the current coding agent. The agent continues with a faithful plan, local generation and a checked hosted draft. Branded falls back to Free (Spaces) only when absent. This command itself does not launch AI or build an app. --locale selects the source view (en by default); choose the app's actual language before collecting. --dir is the parent directory; an existing destination is refused. --top-tabs bottom-tabs (default) plans bottom tabs, one per visible page, for a source with top tabs; keep retains the top tabs.
199031
199185
 
199032
199186
  validate-topbar checks authored source top-bar controls against the migrated config.ts. validate-design compares the source theme's colors, heading/body font families, button shape and accent text contrast with the migrated tokens.json, repairs the mismatches with --fix, and records a passing check for the coverage ledger with --record. Both are scoped to a One App evidence directory and do not change general himi validate behavior.`);
199033
199187
  return 0;
@@ -199090,7 +199244,7 @@ validate-topbar checks authored source top-bar controls against the migrated con
199090
199244
  manifest2 = {
199091
199245
  schemaVersion: 1,
199092
199246
  workflow: ONE_APP_WORKFLOW,
199093
- requested: { metaSiteId: options.metaSiteId, appInstance: options.appInstance },
199247
+ requested: { metaSiteId: options.metaSiteId, appInstance: options.appInstance, locale: options.locale },
199094
199248
  workspace: options.workspace,
199095
199249
  target: options.target,
199096
199250
  navigation: { topTabs: options.topTabs, plan: "navigation-plan.json" },
@@ -199120,6 +199274,7 @@ validate-topbar checks authored source top-bar controls against the migrated con
199120
199274
  const collected = await (deps.collect ?? collectOneApp)({
199121
199275
  metaSiteId: options.metaSiteId,
199122
199276
  appInstance: options.appInstance,
199277
+ locale: options.locale,
199123
199278
  authorization: token,
199124
199279
  allowInternalBusinessRead: true
199125
199280
  }, {
@@ -199196,17 +199351,18 @@ var init_cli2 = __esm({
199196
199351
  init_graph();
199197
199352
  init_navigation();
199198
199353
  init_version2();
199199
- ONE_APP_USAGE = "himi one-app migrate --msid <uuid> [--app-instance branded|free] [--prompt <text> | --prompt-file <file>] [--name <slug>] [--dir <parent>] [--target bo] [--top-tabs bottom-tabs|keep] [--json]\nhimi one-app validate-topbar --evidence-dir <.himi/one-app> --content <app-dir> [--json]\nhimi one-app validate-design --evidence-dir <.himi/one-app> --content <app-dir> [--json] [--fix] [--record --release-hash <sha256>]\nhimi one-app coverage init|sync|check|verify --evidence-dir <.himi/one-app> --content <app-dir> [--release-hash <sha256>]";
199354
+ ONE_APP_USAGE = "himi one-app migrate --msid <uuid> [--app-instance branded|free] [--locale en|he|es] [--prompt <text> | --prompt-file <file>] [--name <slug>] [--dir <parent>] [--target bo] [--top-tabs bottom-tabs|keep] [--json]\nhimi one-app validate-topbar --evidence-dir <.himi/one-app> --content <app-dir> [--json]\nhimi one-app validate-design --evidence-dir <.himi/one-app> --content <app-dir> [--json] [--fix] [--record --release-hash <sha256>]\nhimi one-app coverage init|sync|check|verify --evidence-dir <.himi/one-app> --content <app-dir> [--release-hash <sha256>]";
199200
199355
  ONE_APP_WORKFLOW = "one-app-to-himi-app";
199201
199356
  UUID2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
199202
199357
  SLUG = /^[a-z0-9][a-z0-9-]{0,62}$/;
199203
- VALUE_FLAGS = /* @__PURE__ */ new Set(["msid", "app-instance", "prompt", "prompt-file", "name", "dir", "target", "top-tabs"]);
199358
+ VALUE_FLAGS = /* @__PURE__ */ new Set(["msid", "app-instance", "locale", "prompt", "prompt-file", "name", "dir", "target", "top-tabs"]);
199204
199359
  GLOBAL_SWITCHES = /* @__PURE__ */ new Set(["--json", "--skip-version-check"]);
199205
199360
  MAX_PROMPT_BYTES = 65536;
199206
199361
  usageCodes = /* @__PURE__ */ new Set([
199207
199362
  "invalid_usage",
199208
199363
  "invalid_msid",
199209
199364
  "invalid_app_instance",
199365
+ "invalid_locale",
199210
199366
  "invalid_prompt",
199211
199367
  "invalid_output_path",
199212
199368
  "invalid_target",
@@ -199722,13 +199878,6 @@ var init_language = __esm({
199722
199878
  });
199723
199879
 
199724
199880
  // src/site-analyze/site-properties.ts
199725
- function formatAddress(a2) {
199726
- if (!a2) return "";
199727
- if (a2.googleFormattedAddress) return a2.googleFormattedAddress.trim();
199728
- const line1 = [a2.streetNumber, a2.street].filter(Boolean).join(" ").trim();
199729
- const cityLine = [a2.city, [a2.state, a2.zip].filter(Boolean).join(" ").trim(), a2.country].filter(Boolean).join(", ");
199730
- return [line1, cityLine].filter(Boolean).join(", ").trim();
199731
- }
199732
199881
  function cats(p2) {
199733
199882
  const c2 = p2.categories;
199734
199883
  if (!c2) return [];
@@ -199754,7 +199903,7 @@ function parseSiteProperties(res, siteUrl) {
199754
199903
  business: normalizeLang(p2.locale?.languageCode ?? p2.language ?? "")
199755
199904
  },
199756
199905
  contact: {
199757
- address: formatAddress(p2.address),
199906
+ ...businessAddress(p2.address),
199758
199907
  email: (p2.email ?? "").trim(),
199759
199908
  phone: (p2.phone ?? "").trim()
199760
199909
  },
@@ -199808,6 +199957,7 @@ function identityFromCrawl(siteUrl, title, description, pageName) {
199808
199957
  var TITLE_SEPARATOR, norm;
199809
199958
  var init_site_properties = __esm({
199810
199959
  "src/site-analyze/site-properties.ts"() {
199960
+ init_business_address();
199811
199961
  init_rest();
199812
199962
  init_language();
199813
199963
  TITLE_SEPARATOR = /(\s+[|·–—-]\s+)/;
@@ -200698,6 +200848,7 @@ async function readMobileApp(fetchImpl, auth, deps = {}) {
200698
200848
  // Without the catalog every section is `Unknown` — not "no equivalent", which would send the
200699
200849
  // next agent to rebuild sections Himi already has.
200700
200850
  ...collected.warnings.filter((w2) => w2.code === "runtime_context_unavailable").map((w2) => `the ${w2.platform} runtime view could not be read (${w2.failureCode}), so its platform-specific access and rendering are unverified`),
200851
+ ...collected.warnings.filter((w2) => w2.code === "business_contact_unavailable").map((w2) => `public business contact could not be read (${w2.failureCode}), so contact sections remain unverified`),
200701
200852
  !catalog4.size && "the section mapping catalog was unavailable, so coverage is `Unknown` throughout \u2014 look each id up in `himi docs one-app-section-mappings`"
200702
200853
  ].filter(Boolean);
200703
200854
  const chapter = {
@@ -200712,6 +200863,7 @@ async function readMobileApp(fetchImpl, auth, deps = {}) {
200712
200863
  chapter,
200713
200864
  evidence: {
200714
200865
  "raw-structure.json": collected.rawStructure,
200866
+ "business-context.json": collected.businessContext,
200715
200867
  ...collected.enriched.ios ? { "enriched-ios.json": collected.enriched.ios } : {},
200716
200868
  ...collected.enriched.android ? { "enriched-android.json": collected.enriched.android } : {},
200717
200869
  "source-graph.json": buildSourceGraph(collected.rawStructure, collected.enriched)
@@ -204938,6 +205090,18 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
204938
205090
  io2.error(JSON.stringify(pushFailure2("invalid_flag_value", { ok: false, error: "invalid_flag_value", problems: flagErrors, hint: "run `himi help` for the flag grammar." })));
204939
205091
  return 2;
204940
205092
  }
205093
+ if (command === "one-app" && pos[1] === "migrate" && flags.locale !== void 0 && flags.help !== true) {
205094
+ const { resolveSourceLocale: resolveSourceLocale2 } = await Promise.resolve().then(() => (init_collect(), collect_exports));
205095
+ const { OneAppError: OneAppError2 } = await Promise.resolve().then(() => (init_errors2(), errors_exports));
205096
+ try {
205097
+ if (typeof flags.locale !== "string") throw new OneAppError2("invalid_usage", "A migration option is missing its value.");
205098
+ resolveSourceLocale2(flags.locale);
205099
+ } catch (error) {
205100
+ if (!(error instanceof OneAppError2)) throw error;
205101
+ io2.error(JSON.stringify({ ok: false, code: error.code, message: error.message, stage: "input" }));
205102
+ return 2;
205103
+ }
205104
+ }
204941
205105
  if (flags["skip-version-check"] !== true && flags["no-network"] !== true) {
204942
205106
  const update = await maybeSelfUpdate(argv, io2, { command, ...deps.selfUpdate });
204943
205107
  if (update?.exitCode !== void 0) return update.exitCode;