@wix/himalaya-cli 0.1573.0 → 0.1575.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 (112) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/app-config.d.ts +16 -5
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/define-app.d.ts +6 -0
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/message-format.d.ts +59 -0
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/telemetry/wix-bi/src/index.d.ts +15 -0
  5. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/telemetry/wix-bi/src/oneapp.d.ts +90 -0
  6. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +3 -3
  7. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/l10n.mjs +8 -3
  8. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/sdui.mjs +3 -3
  9. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-bi.mjs +165 -5
  10. package/dist/cli.mjs +5261 -2937
  11. package/dist/preview-assets.generated.bin +0 -0
  12. package/guides/designing-himi-screens.md +7 -1
  13. package/guides/hhp.md +2 -2
  14. package/guides/himi-json-output.md +53 -2
  15. package/guides/himi-mcp.md +1 -1
  16. package/guides/himi-test.md +3 -2
  17. package/guides/iap-products.md +1 -1
  18. package/guides/importing-oneapp-translations.md +115 -0
  19. package/guides/index.json +6 -0
  20. package/guides/one-app-section-mappings.md +16 -4
  21. package/guides/one-app-to-himi-app.md +167 -10
  22. package/guides/push-cli-onboarding.md +10 -0
  23. package/guides/qa-builds.md +21 -1
  24. package/guides/templates.md +3 -2
  25. package/guides/testing-himi-apps.md +1 -1
  26. package/package.json +3 -3
  27. package/templates/beauty-salon/dev/index.ts +96 -133
  28. package/templates/beauty-salon/tier5-src/_shared/exclusive-writes.ts +66 -0
  29. package/templates/beauty-salon/tier5-src/himi-branded-lite-cart/index.ts +18 -5
  30. package/templates/beauty-salon-owner/dev/index.ts +27 -6
  31. package/templates/beauty-salon-owner/tier5-src/_shared/exclusive-writes.ts +66 -0
  32. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post-form/index.ts +5 -1
  33. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product-form/index.ts +5 -1
  34. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service-form/index.ts +5 -1
  35. package/templates/branded-lite/dev/index.ts +136 -142
  36. package/templates/branded-lite/l10n/en.json +570 -0
  37. package/templates/branded-lite/l10n/he.json +200 -0
  38. package/templates/branded-lite/tier5-src/_shared/business-chat-copy.ts +40 -0
  39. package/templates/branded-lite/tier5-src/_shared/business-chat-message-model.ts +1 -1
  40. package/templates/branded-lite/tier5-src/_shared/business-chat-model.ts +3 -2
  41. package/templates/branded-lite/tier5-src/_shared/business-chat-presenter.ts +26 -21
  42. package/templates/branded-lite/tier5-src/_shared/exclusive-writes.ts +66 -0
  43. package/templates/branded-lite/tier5-src/business-chat/index.ts +184 -63
  44. package/templates/branded-lite/tier5-src/himi-branded-lite-cart/index.ts +18 -5
  45. package/templates/community-club/dev/index.ts +22 -6
  46. package/templates/community-club-owner/dev/index.ts +27 -6
  47. package/templates/community-club-owner/tier5-src/_shared/exclusive-writes.ts +66 -0
  48. package/templates/community-club-owner/tier5-src/himi-owner-lite-event-form/index.ts +5 -1
  49. package/templates/community-club-owner/tier5-src/himi-owner-lite-post-form/index.ts +5 -1
  50. package/templates/community-club-owner/tier5-src/himi-owner-lite-product-form/index.ts +5 -1
  51. package/templates/events-meetups/dev/index.ts +22 -6
  52. package/templates/events-meetups-owner/dev/index.ts +25 -6
  53. package/templates/events-meetups-owner/tier5-src/_shared/exclusive-writes.ts +66 -0
  54. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event-form/index.ts +5 -1
  55. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post-form/index.ts +5 -1
  56. package/templates/gym-fitness/dev/index.ts +96 -133
  57. package/templates/gym-fitness/tier5-src/_shared/exclusive-writes.ts +66 -0
  58. package/templates/gym-fitness/tier5-src/himi-branded-lite-cart/index.ts +18 -5
  59. package/templates/gym-fitness-owner/dev/index.ts +28 -6
  60. package/templates/gym-fitness-owner/tier5-src/_shared/exclusive-writes.ts +66 -0
  61. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event-form/index.ts +5 -1
  62. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post-form/index.ts +5 -1
  63. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product-form/index.ts +5 -1
  64. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service-form/index.ts +5 -1
  65. package/templates/himi-chat/dev/index.ts +22 -6
  66. package/templates/nonprofit-cause/dev/index.ts +22 -6
  67. package/templates/nonprofit-cause-owner/dev/index.ts +26 -6
  68. package/templates/nonprofit-cause-owner/tier5-src/_shared/exclusive-writes.ts +66 -0
  69. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event-form/index.ts +5 -1
  70. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post-form/index.ts +5 -1
  71. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service-form/index.ts +5 -1
  72. package/templates/owner-lite/dev/index.ts +28 -6
  73. package/templates/owner-lite/tier5-src/_shared/exclusive-writes.ts +66 -0
  74. package/templates/owner-lite/tier5-src/himi-owner-lite-event-form/index.ts +5 -1
  75. package/templates/owner-lite/tier5-src/himi-owner-lite-post-form/index.ts +5 -1
  76. package/templates/owner-lite/tier5-src/himi-owner-lite-product-form/index.ts +5 -1
  77. package/templates/owner-lite/tier5-src/himi-owner-lite-service-form/index.ts +5 -1
  78. package/templates/podcast-creator/dev/index.ts +22 -6
  79. package/templates/podcast-creator-owner/dev/index.ts +27 -6
  80. package/templates/podcast-creator-owner/tier5-src/_shared/exclusive-writes.ts +66 -0
  81. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event-form/index.ts +5 -1
  82. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post-form/index.ts +5 -1
  83. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product-form/index.ts +5 -1
  84. package/templates/portfolio-creative/dev/index.ts +96 -133
  85. package/templates/portfolio-creative/tier5-src/_shared/exclusive-writes.ts +66 -0
  86. package/templates/portfolio-creative/tier5-src/himi-branded-lite-cart/index.ts +18 -5
  87. package/templates/portfolio-creative-owner/dev/index.ts +27 -6
  88. package/templates/portfolio-creative-owner/tier5-src/_shared/exclusive-writes.ts +66 -0
  89. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post-form/index.ts +5 -1
  90. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product-form/index.ts +5 -1
  91. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service-form/index.ts +5 -1
  92. package/templates/restaurant/dev/index.ts +22 -6
  93. package/templates/restaurant-owner/dev/index.ts +28 -6
  94. package/templates/restaurant-owner/tier5-src/_shared/exclusive-writes.ts +66 -0
  95. package/templates/restaurant-owner/tier5-src/himi-owner-lite-event-form/index.ts +5 -1
  96. package/templates/restaurant-owner/tier5-src/himi-owner-lite-post-form/index.ts +5 -1
  97. package/templates/restaurant-owner/tier5-src/himi-owner-lite-product-form/index.ts +5 -1
  98. package/templates/restaurant-owner/tier5-src/himi-owner-lite-service-form/index.ts +5 -1
  99. package/templates/retail-store/dev/index.ts +96 -133
  100. package/templates/retail-store/tier5-src/_shared/exclusive-writes.ts +66 -0
  101. package/templates/retail-store/tier5-src/himi-branded-lite-cart/index.ts +18 -5
  102. package/templates/retail-store-owner/dev/index.ts +26 -6
  103. package/templates/retail-store-owner/tier5-src/_shared/exclusive-writes.ts +66 -0
  104. package/templates/retail-store-owner/tier5-src/himi-owner-lite-post-form/index.ts +5 -1
  105. package/templates/retail-store-owner/tier5-src/himi-owner-lite-product-form/index.ts +5 -1
  106. package/templates/surface-showcase/dev/index.ts +22 -6
  107. package/templates/yoga-studio/dev/index.ts +22 -6
  108. package/templates/yoga-studio-owner/dev/index.ts +26 -6
  109. package/templates/yoga-studio-owner/tier5-src/_shared/exclusive-writes.ts +66 -0
  110. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event-form/index.ts +5 -1
  111. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post-form/index.ts +5 -1
  112. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service-form/index.ts +5 -1
@@ -17,16 +17,20 @@ export interface LinkableScreen {
17
17
  parentScreenId: string;
18
18
  tabId: string;
19
19
  }
20
+ export interface FrogTelemetryConfig {
21
+ src: number;
22
+ variant?: string;
23
+ endpoint?: string;
24
+ commonParams?: "himi" | "oneapp";
25
+ mobileAppId?: string;
26
+ lv?: string;
27
+ }
20
28
  export interface TelemetryConfig {
21
29
  enabled: boolean;
22
30
  samplingRate: number;
23
31
  eventAllowlist?: string[];
24
32
  ingestUrl?: string;
25
- frog?: {
26
- src: number;
27
- variant?: string;
28
- endpoint?: string;
29
- };
33
+ frog?: FrogTelemetryConfig;
30
34
  sentry?: {
31
35
  enabled: boolean;
32
36
  dsn: string;
@@ -127,6 +131,13 @@ export interface WixPlatformConfig {
127
131
  src?: number;
128
132
  endpoint?: string;
129
133
  variant?: string;
134
+ /** `"oneapp"` = stamp the RN one-app engine's common fields and POST its envelope
135
+ * (apps replacing the RN Owner / Spaces / Branded apps). Default `"himi"`. */
136
+ commonParams?: "himi" | "oneapp";
137
+ /** oneapp: RN `mobile_app_id` — `owner`, `spaces`, `brandedLite_{msid}` (`{msid}` is replaced). */
138
+ mobileAppId?: string;
139
+ /** oneapp: logger version `_lv`. Default `1.0.0|Himi`. */
140
+ lv?: string;
130
141
  };
131
142
  /** Petri experiment scope (the conduction namespace for this app). */
132
143
  experiments?: {
@@ -915,6 +915,12 @@ export interface TelemetryConfig {
915
915
  src: number;
916
916
  variant?: string;
917
917
  endpoint?: string;
918
+ /** `"oneapp"` = RN one-app engine common fields + POST envelope (epic #4973). Default `"himi"`. */
919
+ commonParams?: "himi" | "oneapp";
920
+ /** oneapp: RN `mobile_app_id`; `{msid}` is replaced with the bound/active site. */
921
+ mobileAppId?: string;
922
+ /** oneapp: logger version `_lv` (default `1.0.0|Himi`). */
923
+ lv?: string;
918
924
  };
919
925
  /**
920
926
  * Optional Sentry backend (WS-D / RFC 0042 monitoring). When present + `enabled`,
@@ -18,6 +18,36 @@ export declare function pluralCategory(n: number, locale: string): PluralCategor
18
18
  * table arbitrarily wrong — which is how the obsolete Hebrew `many` rule nearly shipped.
19
19
  */
20
20
  export declare function pluralCategoryFallback(n: number, locale: string): PluralCategory;
21
+ /** Split the body of `{...}` on top-level commas into at most 3 parts.
22
+ *
23
+ * Exported for tools/l10n/import-oneapp.ts, which converts foreign catalogs with the SAME
24
+ * tokenizer `formatMessage` renders with — a second brace scanner would be free to disagree
25
+ * about what is an argument, and the disagreement would surface as a corrupted translation.
26
+ *
27
+ * @internal Tokenizer plumbing for the importer, not SDK surface — do not depend on it
28
+ * from app or worker code. */
29
+ export declare function splitArg(body: string): string[];
30
+ /** One parsed branch: its selector, its body, and where the body sits in the spec. */
31
+ export interface BranchEntry {
32
+ key: string;
33
+ body: string;
34
+ /** Offset of the body's first character in the spec (just past the opening brace). */
35
+ bodyStart: number;
36
+ /** Offset one past the body's last character (the closing brace's position). */
37
+ bodyEnd: number;
38
+ }
39
+ /** Parse `one {…} other {…}` into its branches IN SOURCE ORDER, preserving nested braces,
40
+ * with each body's offsets so a caller can rewrite a body in place.
41
+ *
42
+ * A `Record` cannot carry the order: `Object.entries` lists integer-like keys first, so a
43
+ * rebuild from one reorders `other {a} 1 {b}` — which changes the string, and with it any
44
+ * id derived from the string.
45
+ * @internal Tokenizer plumbing for the importer, not SDK surface. */
46
+ export declare function parseBranchEntries(spec: string): BranchEntry[];
47
+ /** Parse `one {…} other {…}` into its branches, preserving nested braces.
48
+ * Exported for the same reason as `splitArg`.
49
+ * @internal Tokenizer plumbing for the importer, not SDK surface. */
50
+ export declare function parseBranches(spec: string): Record<string, string>;
21
51
  /**
22
52
  * Format an ICU pattern.
23
53
  *
@@ -26,3 +56,32 @@ export declare function pluralCategoryFallback(n: number, locale: string): Plura
26
56
  * that makes a `$t:` miss fall back to its key.
27
57
  */
28
58
  export declare function formatMessage(pattern: string, args?: Record<string, unknown>, locale?: string): string;
59
+ /** Whether `formatMessage` can ever select a branch with this selector for a `plural` or
60
+ * `select` argument. Shared with the importer so "reported" and "kept verbatim" agree.
61
+ * @internal Importer plumbing, not SDK surface. */
62
+ export declare function isBranchSelector(kind: "plural" | "select", key: string): boolean;
63
+ /**
64
+ * Every construct in `pattern` that is OUTSIDE the subset `formatMessage` implements —
65
+ * i.e. everything that would hit one of its degradation branches (verbatim text, raw
66
+ * value, empty branch set) instead of being formatted.
67
+ *
68
+ * This exists for importers (RFC 0054, `himi l10n import`): a catalog converted from a
69
+ * richer MessageFormat dialect must KEEP such a message verbatim — degrading to visible
70
+ * text is this module's contract — but the import report has to NAME it, because "renders
71
+ * its raw ICU source to users" is a decision a human should get to veto. Scanning with the
72
+ * same tokenizer `formatMessage` uses (same quoting rules, same balanced-brace scan, same
73
+ * `splitArg`/`parseBranches`) is what keeps "unsupported" synonymous with "formatMessage
74
+ * would not format this", instead of a second opinion that drifts.
75
+ *
76
+ * Returns human-readable descriptions, one per finding, in source order. Empty = the whole
77
+ * pattern is inside the subset (simple arguments, `plural` with `=N`/`#`, `select`, and
78
+ * `select`/plural nesting that `formatMessage` renders correctly). Two shapes that look
79
+ * nested-and-fine are NOT: `formatMessage` replaces every `#` in a chosen plural branch
80
+ * with that plural's number BEFORE it handles quoting or recurses, so a plural nested in a
81
+ * plural has its own `#` clobbered by the outer one, and a quoted `'#'` renders as the
82
+ * number in quotes. Both are reported.
83
+ *
84
+ * @internal Importer plumbing, not SDK surface — a worker has no reason to ask this;
85
+ * `formatMessage` already degrades gracefully at runtime.
86
+ */
87
+ export declare function unsupportedConstructs(pattern: string): string[];
@@ -1,4 +1,6 @@
1
1
  import type { TelemetrySink, TelemetryEvent } from "@wix/himalaya/core";
2
+ import { type FrogCommonParams, type OneAppFrogContext } from "./oneapp.js";
3
+ export * from "./oneapp.js";
2
4
  /**
3
5
  * WixFrogTelemetrySink — forwards canonical Himalaya telemetry to a Wix Frog
4
6
  * endpoint as fire-and-forget BI beacons (RFC 0042, Wix Platform SDK).
@@ -35,6 +37,19 @@ export interface WixFrogTelemetrySinkOptions {
35
37
  * errors (BI is best-effort and must never throw into the emit path). Injected
36
38
  * by tests to capture the constructed URL. */
37
39
  send?: (url: string) => void;
40
+ /** Which common beacon fields to stamp. `"himi"` (default) is the Symphony beacon
41
+ * below; `"oneapp"` reproduces the RN one-app engine (see `./oneapp.ts`). */
42
+ commonParams?: FrogCommonParams;
43
+ /** oneapp: RN `mobile_app_id` (`owner`, `spaces`, `brandedLite_{msid}`). */
44
+ mobileAppId?: string;
45
+ /** oneapp: logger version `_lv`. Default `1.0.0|Himi`. */
46
+ lv?: string;
47
+ /** oneapp: the host state stamped on every event (identity, device, versions). */
48
+ context?: () => OneAppFrogContext;
49
+ /** oneapp: POST transport (`url`, JSON body). Defaults to a keepalive `fetch` POST. */
50
+ sendPost?: (url: string, body: string) => void;
51
+ /** oneapp: clock for the envelope `dt`. Injected by tests. */
52
+ now?: () => number;
38
53
  }
39
54
  /** Frog `evid` codes (mirror of the original SymphonyBI.swift). */
40
55
  export declare const FROG_EVID: {
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The `commonParams: "oneapp"` mode of the Wix frog sink (#4711, #4974, epic #4973).
3
+ *
4
+ * Reproduces what the React Native one-app engine sends, so the Himi apps that replace
5
+ * the RN Owner / Spaces / Branded apps keep feeding the same BI tables and dashboards:
6
+ * the engine's common fields, a per-event `src` + endpoint, and the RN POST envelope
7
+ * `{"dt":0,"g":{},"e":[{"dt":<eventTime-sendTime>,"f":{…}}]}`.
8
+ *
9
+ * The contract is the shared fixture `core/schema/fixtures/bi-oneapp-envelope.json`; the
10
+ * web host (`core/web-host/src/telemetry/WixFrogTelemetrySink.ts`), iOS and Android sinks
11
+ * implement the same rules and are tested against the same cases. Pure — no I/O.
12
+ */
13
+ /** Keys the host always stamps. Removed from event params, then re-stamped from the host,
14
+ * so neither a worker nor a typo can forge them. The first 14 are the adapter-owned
15
+ * names of `wix-private/mobile-native-core` `bi-codegen/src/runtime-fields.js`. */
16
+ export declare const FROG_HOST_STAMPED_FIELDS: readonly string[];
17
+ /** Keys a WORKER may not send through `wixPlatform.bi.track` / `bi.log`: the host-stamped
18
+ * set plus the engine's per-site and per-module fields, which only platform code sets. */
19
+ export declare const FROG_WORKER_RESERVED_FIELDS: readonly string[];
20
+ export declare const ONEAPP_DEFAULT_LV = "1.0.0|Himi";
21
+ export declare const ONEAPP_DEFAULT_ENDPOINT = "oneapp";
22
+ export type FrogCommonParams = "himi" | "oneapp";
23
+ /** The served `telemetryConfig.frog` block, as far as oneapp mode reads it. */
24
+ export interface OneAppFrogConfig {
25
+ /** Fallback src for an event that carries none. */
26
+ src: number;
27
+ /** Fallback endpoint: a bare frog endpoint name (`oneapp`) or a full URL. */
28
+ endpoint?: string;
29
+ /** RN `mobile_app_id` (`owner`, `spaces`, `brandedLite_{msid}`). `{msid}` is replaced. */
30
+ mobileAppId?: string;
31
+ /** Logger version `_lv`. Default `1.0.0|Himi`. */
32
+ lv?: string;
33
+ }
34
+ /** Host state at the moment the event was emitted. Every field is optional except the
35
+ * platform ones; a missing or empty value is omitted from the beacon. */
36
+ export interface OneAppFrogContext {
37
+ os: "ios" | "android" | "web" | string;
38
+ installationId?: string;
39
+ bundleVersion?: string;
40
+ appVersion?: string;
41
+ osVersion?: string;
42
+ deviceModel?: string;
43
+ language?: string;
44
+ bsi?: string;
45
+ /** `undefined` = not known yet: neither `uuid` nor `_visitorId` is stamped. */
46
+ signedIn?: boolean;
47
+ /** The signed-in identity is a site member (Branded / member apps), not a Wix account user. */
48
+ isSiteMember?: boolean;
49
+ /** The Wix account user id (owner apps). Sent as `uuid` unless the user is a site member. */
50
+ userId?: string;
51
+ memberId?: string;
52
+ contactId?: string;
53
+ /** The app's bound site (Branded); wins over an event's own msid. */
54
+ forcedMsid?: string;
55
+ /** The currently selected site; used when the event names none. */
56
+ activeMsid?: string;
57
+ }
58
+ export interface OneAppFrogEventInput {
59
+ type: string;
60
+ screenId?: string;
61
+ payload?: Record<string, unknown>;
62
+ timestampMs: number;
63
+ }
64
+ /** One built event, before envelope encoding. */
65
+ export interface OneAppFrogEvent {
66
+ /** Full POST URL (`https://frog.wix.com/<endpoint>`). */
67
+ url: string;
68
+ /** When the event happened (epoch ms) — becomes `dt` relative to the send time. */
69
+ eventTimeMs: number;
70
+ /** The `f` object, in stamping order. */
71
+ fields: Record<string, string | number>;
72
+ }
73
+ export declare function redactFrogParam(value: string): string;
74
+ export declare function eventEndpoint(eventEndpointValue: string | undefined, configEndpoint: string | undefined): string;
75
+ /** `oneapp` → `https://frog.wix.com/oneapp`; a full URL is kept as-is. */
76
+ export declare function frogEndpointUrl(endpoint: string | undefined): string;
77
+ /** Drop every worker-reserved key from a worker `bi.track` payload. Returns the kept
78
+ * payload and the dropped key names (the caller logs them once in debug). */
79
+ export declare function stripWorkerReservedFields<T extends Record<string, unknown>>(payload: T): {
80
+ payload: T;
81
+ dropped: string[];
82
+ };
83
+ /**
84
+ * Build one oneapp frog event, or `null` for an event oneapp mode does not send.
85
+ * Only explicit `bi` events are sent here; `screen_view` / `action_dispatched` are mapped
86
+ * by the platform screen and action maps (later epic issues), never as generic 501/522.
87
+ */
88
+ export declare function buildOneAppFrogEvent(event: OneAppFrogEventInput, config: OneAppFrogConfig, ctx: OneAppFrogContext): OneAppFrogEvent | null;
89
+ /** The RN `sendEventsV2` POST body for events that share one endpoint URL. */
90
+ export declare function encodeFrogEnvelope(events: ReadonlyArray<Pick<OneAppFrogEvent, "eventTimeMs" | "fields">>, sendTimeMs: number): string;
@@ -10035,9 +10035,9 @@ var PREVIEW_SURFACES = [
10035
10035
  },
10036
10036
  {
10037
10037
  // NOTE: 834 is iPad portrait — six points UNDER the 840 `expanded`
10038
- // breakpoint, so an iPad in portrait resolves to `medium` and gets bottom
10039
- // tabs, becoming a sidebar only in landscape (1112). That is the shipped
10040
- // behaviour of the ladder, not a quirk of this registry.
10038
+ // breakpoint, so an iPad in portrait resolves to `medium`: full-bleed content
10039
+ // and, for responsive navigation, a sidebar (native wide starts at 600).
10040
+ // Landscape (1112) is expanded and applies the readable content measure.
10041
10041
  id: "tablet",
10042
10042
  label: "Tablet",
10043
10043
  chassis: "tablet",
@@ -40,8 +40,8 @@ function splitArg(body) {
40
40
  out.push(body.slice(start));
41
41
  return out;
42
42
  }
43
- function parseBranches(spec) {
44
- const branches = {};
43
+ function parseBranchEntries(spec) {
44
+ const entries = [];
45
45
  let i = 0;
46
46
  while (i < spec.length) {
47
47
  while (i < spec.length && /\s/.test(spec[i])) i++;
@@ -59,9 +59,14 @@ function parseBranches(spec) {
59
59
  depth--;
60
60
  }
61
61
  }
62
- branches[key] = spec.slice(bodyStart, i);
62
+ entries.push({ key, body: spec.slice(bodyStart, i), bodyStart, bodyEnd: i });
63
63
  i++;
64
64
  }
65
+ return entries;
66
+ }
67
+ function parseBranches(spec) {
68
+ const branches = {};
69
+ for (const { key, body } of parseBranchEntries(spec)) branches[key] = body;
65
70
  return branches;
66
71
  }
67
72
  function formatMessage(pattern, args = {}, locale2 = "en") {
@@ -7970,9 +7970,9 @@ var PREVIEW_SURFACES = [
7970
7970
  },
7971
7971
  {
7972
7972
  // NOTE: 834 is iPad portrait — six points UNDER the 840 `expanded`
7973
- // breakpoint, so an iPad in portrait resolves to `medium` and gets bottom
7974
- // tabs, becoming a sidebar only in landscape (1112). That is the shipped
7975
- // behaviour of the ladder, not a quirk of this registry.
7973
+ // breakpoint, so an iPad in portrait resolves to `medium`: full-bleed content
7974
+ // and, for responsive navigation, a sidebar (native wide starts at 600).
7975
+ // Landscape (1112) is expanded and applies the readable content measure.
7976
7976
  id: "tablet",
7977
7977
  label: "Tablet",
7978
7978
  chassis: "tablet",
@@ -1,14 +1,140 @@
1
- // ../../stdlib/telemetry/wix-bi/src/index.ts
2
- var DEFAULT_ENDPOINT = "https://frog.wix.com/scheduling-assistant";
1
+ // ../../stdlib/telemetry/wix-bi/src/oneapp.ts
2
+ var FROG_HOST_STAMPED_FIELDS = Object.freeze([
3
+ "src",
4
+ "evid",
5
+ "installationId",
6
+ "client_id",
7
+ "mobile_app_id",
8
+ "osType",
9
+ "_lv",
10
+ "bundleVersion",
11
+ "appVersion",
12
+ "osVersion",
13
+ "deviceModel",
14
+ "mobile_lng",
15
+ "ct",
16
+ "bsi",
17
+ "uuid",
18
+ "_visitorId",
19
+ "_msid",
20
+ "member_id",
21
+ "contactId",
22
+ "_contactId"
23
+ ]);
24
+ var FROG_WORKER_RESERVED_FIELDS = Object.freeze([
25
+ ...FROG_HOST_STAMPED_FIELDS,
26
+ "ownerId",
27
+ "roles",
28
+ "brand_id",
29
+ "identity_data",
30
+ "moduleName",
31
+ "moduleVersion",
32
+ // Only platform code may attribute an event to a site other than the active one.
33
+ "msid"
34
+ ]);
35
+ var ONEAPP_DEFAULT_LV = "1.0.0|Himi";
36
+ var ONEAPP_DEFAULT_ENDPOINT = "oneapp";
37
+ var FROG_ORIGIN = "https://frog.wix.com";
3
38
  var REDACT_EMAIL = /[^\s@]+@[^\s@]+\.[^\s@]+/;
4
39
  var REDACT_JWT = /\beyJ[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}\b/;
5
- var REDACT_PHONE = /(?:\+|00)\d[\d\s().-]{6,}\d/;
6
- function redactParam(value) {
40
+ var REDACT_PHONE = /(?<![\w-])(?:\+|00)\d[\d\s().-]{6,}\d(?![\w-])/;
41
+ function redactFrogParam(value) {
7
42
  if (REDACT_EMAIL.test(value)) return "[redacted-email]";
8
43
  if (REDACT_JWT.test(value)) return "[redacted-token]";
9
44
  if (REDACT_PHONE.test(value)) return "[redacted-phone]";
10
45
  return value;
11
46
  }
47
+ var BARE_ENDPOINT = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
48
+ function eventEndpoint(eventEndpointValue, configEndpoint) {
49
+ return frogEndpointUrl(eventEndpointValue && BARE_ENDPOINT.test(eventEndpointValue) ? eventEndpointValue : configEndpoint);
50
+ }
51
+ function frogEndpointUrl(endpoint) {
52
+ const e = (endpoint ?? "").trim() || ONEAPP_DEFAULT_ENDPOINT;
53
+ if (e.includes("://")) return e;
54
+ return `${FROG_ORIGIN}/${e.replace(/^\/+/, "")}`;
55
+ }
56
+ var nonEmpty = (v) => typeof v === "string" && v.length > 0;
57
+ function stripWorkerReservedFields(payload) {
58
+ const reserved = new Set(FROG_WORKER_RESERVED_FIELDS);
59
+ reserved.delete("evid");
60
+ reserved.delete("src");
61
+ const out = {};
62
+ const dropped = [];
63
+ for (const [k, v] of Object.entries(payload)) {
64
+ if (reserved.has(k)) dropped.push(k);
65
+ else out[k] = v;
66
+ }
67
+ return { payload: out, dropped };
68
+ }
69
+ function buildOneAppFrogEvent(event, config, ctx) {
70
+ if (event.type !== "bi") return null;
71
+ const p = event.payload ?? {};
72
+ const str = (v) => v === void 0 || v === null ? void 0 : String(v);
73
+ const evid = Number(str(p.evid));
74
+ if (!str(p.evid) || !Number.isFinite(evid)) return null;
75
+ const evSrc = Number(str(p.src));
76
+ const src = str(p.src) && Number.isFinite(evSrc) ? evSrc : config.src;
77
+ const url = eventEndpoint(str(p.endpoint), config.endpoint);
78
+ const f = { src, evid };
79
+ const stamped = new Set(FROG_HOST_STAMPED_FIELDS);
80
+ for (const [k, raw] of Object.entries(p)) {
81
+ if (k === "endpoint" || k === "msid" || stamped.has(k)) continue;
82
+ const v = str(raw);
83
+ if (v !== void 0) f[k] = redactFrogParam(v);
84
+ }
85
+ const msid = [ctx.forcedMsid, str(p.msid), ctx.activeMsid].find(nonEmpty);
86
+ const set = (k, v) => {
87
+ if (typeof v === "number" ? Number.isFinite(v) : nonEmpty(v)) f[k] = v;
88
+ };
89
+ set("installationId", ctx.installationId);
90
+ set("client_id", ctx.installationId);
91
+ const appIdTemplate = config.mobileAppId;
92
+ if (nonEmpty(appIdTemplate)) {
93
+ if (!appIdTemplate.includes("{msid}")) set("mobile_app_id", appIdTemplate);
94
+ else if (msid) set("mobile_app_id", appIdTemplate.split("{msid}").join(msid));
95
+ }
96
+ set("osType", ctx.os);
97
+ set("_lv", nonEmpty(config.lv) ? config.lv : ONEAPP_DEFAULT_LV);
98
+ set("bundleVersion", ctx.bundleVersion);
99
+ set("appVersion", ctx.appVersion);
100
+ set("osVersion", ctx.osVersion);
101
+ set("deviceModel", ctx.deviceModel);
102
+ set("mobile_lng", ctx.language);
103
+ set("ct", event.timestampMs);
104
+ set("bsi", ctx.bsi);
105
+ const signedIn = ctx.signedIn === true;
106
+ if (signedIn && !ctx.isSiteMember) set("uuid", ctx.userId);
107
+ if (ctx.signedIn === false) set("_visitorId", ctx.installationId);
108
+ if (msid) {
109
+ f.msid = msid;
110
+ f._msid = msid;
111
+ }
112
+ if (signedIn && ctx.isSiteMember) {
113
+ set("member_id", ctx.memberId);
114
+ set("contactId", ctx.contactId);
115
+ set("_contactId", ctx.contactId);
116
+ }
117
+ return { url, eventTimeMs: event.timestampMs, fields: f };
118
+ }
119
+ function encodeFrogEnvelope(events, sendTimeMs) {
120
+ return JSON.stringify({
121
+ dt: 0,
122
+ g: {},
123
+ e: events.map((e) => ({ dt: e.eventTimeMs - sendTimeMs, f: e.fields }))
124
+ });
125
+ }
126
+
127
+ // ../../stdlib/telemetry/wix-bi/src/index.ts
128
+ var DEFAULT_ENDPOINT = "https://frog.wix.com/scheduling-assistant";
129
+ var REDACT_EMAIL2 = /[^\s@]+@[^\s@]+\.[^\s@]+/;
130
+ var REDACT_JWT2 = /\beyJ[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}\b/;
131
+ var REDACT_PHONE2 = /(?<![\w-])(?:\+|00)\d[\d\s().-]{6,}\d(?![\w-])/;
132
+ function redactParam(value) {
133
+ if (REDACT_EMAIL2.test(value)) return "[redacted-email]";
134
+ if (REDACT_JWT2.test(value)) return "[redacted-token]";
135
+ if (REDACT_PHONE2.test(value)) return "[redacted-phone]";
136
+ return value;
137
+ }
12
138
  var FROG_EVID = {
13
139
  pageView: 501,
14
140
  click: 522
@@ -65,12 +191,36 @@ function defaultSend(url) {
65
191
  } catch {
66
192
  }
67
193
  }
194
+ function defaultSendPost(url, body) {
195
+ try {
196
+ void globalThis.fetch?.(url, { method: "POST", body, keepalive: true, mode: "no-cors", headers: { "Content-Type": "text/plain;charset=UTF-8" } })?.catch(() => {
197
+ });
198
+ } catch {
199
+ }
200
+ }
68
201
  function WixFrogTelemetrySink(options) {
69
202
  const send = options.send ?? defaultSend;
203
+ const sendPost = options.sendPost ?? defaultSendPost;
204
+ const now = options.now ?? (() => Date.now());
70
205
  return {
71
206
  sinkId: "wix-bi",
72
207
  emit(event) {
73
208
  try {
209
+ if (options.commonParams === "oneapp") {
210
+ const ctx = options.context?.() ?? {
211
+ os: "web",
212
+ installationId: resolve(options.installationId),
213
+ activeMsid: resolve(options.msid),
214
+ language: resolve(options.lang) ?? defaultLocale()
215
+ };
216
+ const built = buildOneAppFrogEvent(
217
+ { type: event.type, screenId: event.screenId, payload: event.payload, timestampMs: event.timestamp ?? now() },
218
+ { src: options.src, endpoint: options.endpoint, mobileAppId: options.mobileAppId, lv: options.lv },
219
+ ctx
220
+ );
221
+ if (built) sendPost(built.url, encodeFrogEnvelope([built], now()));
222
+ return;
223
+ }
74
224
  const url = buildFrogBeacon(event, options);
75
225
  if (url) send(url);
76
226
  } catch {
@@ -80,7 +230,17 @@ function WixFrogTelemetrySink(options) {
80
230
  }
81
231
  export {
82
232
  FROG_EVID,
233
+ FROG_HOST_STAMPED_FIELDS,
234
+ FROG_WORKER_RESERVED_FIELDS,
235
+ ONEAPP_DEFAULT_ENDPOINT,
236
+ ONEAPP_DEFAULT_LV,
83
237
  WixFrogTelemetrySink,
84
- buildFrogBeacon
238
+ buildFrogBeacon,
239
+ buildOneAppFrogEvent,
240
+ encodeFrogEnvelope,
241
+ eventEndpoint,
242
+ frogEndpointUrl,
243
+ redactFrogParam,
244
+ stripWorkerReservedFields
85
245
  };
86
246
  //# sourceMappingURL=wix-bi.mjs.map