@ada-support/embed2 1.13.0 → 1.13.2

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.
@@ -1,13 +1,15 @@
1
1
  import type { StartOptions } from "@ada-support/embed-types";
2
2
  export type HostTelemetrySurface = "mobile" | "browser";
3
- export type HostTelemetryPlatform = "ios" | "android" | "react_native" | "web" | "unknown";
3
+ export type HostTelemetryPlatform = "ios" | "android" | "react-native" | "web" | "unknown";
4
4
  export type HostTelemetryWebSdkOrigin = "legacy" | "messaging";
5
+ export type HostTelemetryMobileShell = "messaging-sdk" | "legacy-sdk";
5
6
  export interface HostTelemetryContext {
6
7
  surface: HostTelemetrySurface;
7
8
  hostPlatform: HostTelemetryPlatform;
8
9
  webSdkOrigin: HostTelemetryWebSdkOrigin;
10
+ mobileShell?: HostTelemetryMobileShell;
9
11
  mobilePackage?: string;
10
- sdkVariant?: string;
12
+ mobileVersion?: string;
11
13
  }
12
14
  export declare const HOST_TELEMETRY_QUERY_PARAM = "ada_host_telemetry";
13
15
  type StartOptionsWithHostTelemetry = StartOptions & {
@@ -15,6 +17,7 @@ type StartOptionsWithHostTelemetry = StartOptions & {
15
17
  };
16
18
  export declare function resolveHostTelemetryFromStartOptions(adaSettings: StartOptionsWithHostTelemetry, options?: {
17
19
  pathname?: string;
20
+ protocol?: string;
18
21
  }): HostTelemetryContext;
19
22
  export declare function serializeHostTelemetry(hostTelemetry: HostTelemetryContext): string;
20
23
  export declare function shouldPropagateHostTelemetry(hostTelemetry: HostTelemetryContext): boolean;
@@ -15919,7 +15919,7 @@ const client = new BrowserClient({
15919
15919
  return event;
15920
15920
  },
15921
15921
  environment: "production",
15922
- release: "1.13.0-a6606d6",
15922
+ release: "1.13.2-ea8e50e",
15923
15923
  sampleRate: 0.25,
15924
15924
  autoSessionTracking: false,
15925
15925
  // Integrations don't seem to work with Sentry: https://github.com/getsentry/sentry-javascript/issues/2541
@@ -16509,7 +16509,7 @@ function getEmbedURL(_ref) {
16509
16509
  } else {
16510
16510
  host = `http://${handle}.localhost:${ports.localhost.default}`;
16511
16511
  }
16512
- return `${host}/embed/${frameName}/${"a6606d6"}/index.html`;
16512
+ return `${host}/embed/${frameName}/${"ea8e50e"}/index.html`;
16513
16513
  }
16514
16514
  function constructQueryString(query) {
16515
16515
  return Object.keys(query).map(key => {
@@ -17697,9 +17697,9 @@ async function log(message, extra, options) {
17697
17697
  service: "embed",
17698
17698
  env: "production",
17699
17699
  embedVersion: 2,
17700
- version: "1.13.0",
17700
+ version: "1.13.2",
17701
17701
  isNpm: true,
17702
- commitHash: "a6606d6"
17702
+ commitHash: "ea8e50e"
17703
17703
  }))
17704
17704
  });
17705
17705
  }
@@ -18465,7 +18465,32 @@ const getChatVersionFromManifest = manifest => {
18465
18465
  dist/* adaLocalStorage */.BB.setItem("ada-embed_chat-manifest-cache", manifestString);
18466
18466
  return hash;
18467
18467
  };
18468
+
18469
+ // Symmetric with embed-loader's `__ada-embed-version` URL param. The regex
18470
+ // approach mirrors embed-loader so behavior stays aligned across the two
18471
+ // loaders; see embed-loader/source/init.ts.
18472
+ const getURLParam = name => {
18473
+ const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
18474
+ const results = new RegExp(`[?&]${escaped}=([^&#]*)`).exec(window.location.href);
18475
+ if (!results) {
18476
+ return null;
18477
+ }
18478
+ try {
18479
+ return decodeURIComponent(results[1]);
18480
+ } catch {
18481
+ // Ignore malformed query overrides instead of breaking embed startup.
18482
+ return null;
18483
+ }
18484
+ };
18468
18485
  const getChatVersion = async adaSettings => {
18486
+ // Allow pinning via URL parameter — mirrors embed-loader's
18487
+ // `?__ada-embed-version=<sha>` mechanism, bypasses the dev/dev2/stage
18488
+ // auto-skip below (same override semantics as `window.__AdaChatVersion`).
18489
+ const versionFromURL = getURLParam("__ada-chat-version");
18490
+ if (versionFromURL) {
18491
+ return versionFromURL;
18492
+ }
18493
+
18469
18494
  // allow versioning using global variable
18470
18495
  if (window.__AdaChatVersion) {
18471
18496
  return window.__AdaChatVersion;
@@ -18475,7 +18500,7 @@ const getChatVersion = async adaSettings => {
18475
18500
  domain
18476
18501
  } = adaSettings;
18477
18502
 
18478
- // Skip automatic versioning for ATT and dev/stage clusters but allow override through __AdaChatVersion
18503
+ // Skip automatic versioning for ATT and dev/stage clusters but allow override through __AdaChatVersion or __ada-chat-version
18479
18504
  if (cluster === "att" || domain !== null && domain !== void 0 && domain.match(/ada-(dev|dev2|stage)/)) {
18480
18505
  return undefined;
18481
18506
  }
@@ -19094,9 +19119,23 @@ const HOST_TELEMETRY_QUERY_PARAM = "ada_host_telemetry";
19094
19119
  const TRUSTED_MOBILE_SDK_PATH = "/mobile-sdk-webview/";
19095
19120
  const MAX_TELEMETRY_TAG_LENGTH = 100;
19096
19121
  const TELEMETRY_TAG_VALUE_PATTERN = /^[a-z0-9_-]+$/;
19122
+ const SEMVER_TAG_VALUE_PATTERN = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
19097
19123
 
19098
19124
  // Private mobile-sdk handshake used only on the trusted /mobile-sdk-webview/ page.
19099
19125
 
19126
+ // `metaFields.sdkType` is a long-standing convention set by every legacy
19127
+ // mobile wrapper — iOS SDK (`"IOS"`), Android SDK (`"ANDROID"`), React Native
19128
+ // SDK (`"REACTNATIVE"`). The new Messaging wrappers pass the richer
19129
+ // `hostTelemetry` handshake instead, so this map is only consulted as a
19130
+ // legacy-attribution fallback.
19131
+ const LEGACY_SDK_TYPE_PLATFORM_MAP = {
19132
+ IOS: "ios",
19133
+ ANDROID: "android",
19134
+ REACTNATIVE: "react-native",
19135
+ "REACT-NATIVE": "react-native",
19136
+ REACT_NATIVE: "react-native"
19137
+ };
19138
+
19100
19139
  // Keep this normalization logic in sync with
19101
19140
  // chat/src/shared/services/host-telemetry.ts. Both sides normalize across the
19102
19141
  // embed/chat iframe boundary on purpose.
@@ -19118,9 +19157,8 @@ function normalizeHostPlatform(value) {
19118
19157
  return "ios";
19119
19158
  case "android":
19120
19159
  return "android";
19121
- case "react_native":
19122
- case "reactnative":
19123
- return "react_native";
19160
+ case "react-native":
19161
+ return "react-native";
19124
19162
  case "web":
19125
19163
  return "web";
19126
19164
  case "unknown":
@@ -19135,6 +19173,24 @@ function normalizeOrigin(value) {
19135
19173
  }
19136
19174
  return undefined;
19137
19175
  }
19176
+ function normalizeMobileShell(value) {
19177
+ if (typeof value !== "string") {
19178
+ return undefined;
19179
+ }
19180
+
19181
+ // Accept both separator styles defensively, but normalize everything this
19182
+ // helper emits back to the canonical kebab-case tags.
19183
+ switch (value.trim().toLowerCase()) {
19184
+ case "messaging_sdk":
19185
+ case "messaging-sdk":
19186
+ return "messaging-sdk";
19187
+ case "legacy_sdk":
19188
+ case "legacy-sdk":
19189
+ return "legacy-sdk";
19190
+ default:
19191
+ return undefined;
19192
+ }
19193
+ }
19138
19194
  function normalizeTelemetryTagValue(value) {
19139
19195
  if (typeof value !== "string") {
19140
19196
  return undefined;
@@ -19145,11 +19201,21 @@ function normalizeTelemetryTagValue(value) {
19145
19201
  }
19146
19202
  return normalizedValue;
19147
19203
  }
19148
- function deriveSdkVariant(mobilePackage, webSdkOrigin) {
19149
- if (!mobilePackage || !webSdkOrigin) {
19204
+ function normalizeMobileVersion(value) {
19205
+ if (typeof value !== "string") {
19206
+ return undefined;
19207
+ }
19208
+ const trimmedValue = value.trim();
19209
+ if (trimmedValue.length > MAX_TELEMETRY_TAG_LENGTH || !SEMVER_TAG_VALUE_PATTERN.test(trimmedValue)) {
19150
19210
  return undefined;
19151
19211
  }
19152
- return `${mobilePackage}-${webSdkOrigin}`;
19212
+ return trimmedValue;
19213
+ }
19214
+ function deriveMessagingMobileShell(mobilePackage) {
19215
+ return mobilePackage ? "messaging-sdk" : undefined;
19216
+ }
19217
+ function deriveLegacyMobileShell(surface, hostPlatform) {
19218
+ return surface === "mobile" && hostPlatform !== "web" ? "legacy-sdk" : undefined;
19153
19219
  }
19154
19220
  function normalizeHostTelemetry(value) {
19155
19221
  const record = asRecord(value);
@@ -19160,58 +19226,108 @@ function normalizeHostTelemetry(value) {
19160
19226
  const hostPlatform = normalizeHostPlatform(record.hostPlatform);
19161
19227
  const webSdkOrigin = normalizeOrigin(record.webSdkOrigin);
19162
19228
  const mobilePackage = normalizeTelemetryTagValue(record.mobilePackage);
19229
+ const mobileVersion = normalizeMobileVersion(record.mobileVersion);
19163
19230
  if (!surface || !hostPlatform || !webSdkOrigin) {
19164
19231
  return undefined;
19165
19232
  }
19166
- const sdkVariant = normalizeTelemetryTagValue(record.sdkVariant) ?? deriveSdkVariant(mobilePackage, webSdkOrigin);
19167
- return host_telemetry_objectSpread(host_telemetry_objectSpread({
19233
+ const mobileShell = deriveMessagingMobileShell(mobilePackage) ?? normalizeMobileShell(record.mobileShell);
19234
+ return host_telemetry_objectSpread(host_telemetry_objectSpread(host_telemetry_objectSpread({
19168
19235
  surface,
19169
19236
  hostPlatform,
19170
19237
  webSdkOrigin
19171
- }, mobilePackage ? {
19238
+ }, mobileShell ? {
19239
+ mobileShell
19240
+ } : {}), mobilePackage ? {
19172
19241
  mobilePackage
19173
- } : {}), sdkVariant ? {
19174
- sdkVariant
19242
+ } : {}), mobileVersion ? {
19243
+ mobileVersion
19175
19244
  } : {});
19176
19245
  }
19177
19246
  function isTrustedMobileSdkHostPage() {
19178
19247
  let pathname = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.location.pathname;
19179
19248
  return pathname === TRUSTED_MOBILE_SDK_PATH || pathname === TRUSTED_MOBILE_SDK_PATH.slice(0, -1);
19180
19249
  }
19250
+ function isHttpOrigin() {
19251
+ let protocol = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.location.protocol;
19252
+ return protocol === "http:" || protocol === "https:";
19253
+ }
19254
+ function resolveLegacySdkTypePlatform(metaFields) {
19255
+ const record = asRecord(metaFields);
19256
+ const raw = record === null || record === void 0 ? void 0 : record.sdkType;
19257
+ if (typeof raw !== "string") {
19258
+ return undefined;
19259
+ }
19260
+ return LEGACY_SDK_TYPE_PLATFORM_MAP[raw.trim().toUpperCase()];
19261
+ }
19262
+ function resolveLegacySdkTypeFingerprint(metaFields, trustedMobileContext) {
19263
+ if (!trustedMobileContext) {
19264
+ return undefined;
19265
+ }
19266
+ const hostPlatform = resolveLegacySdkTypePlatform(metaFields);
19267
+ if (!hostPlatform) {
19268
+ return undefined;
19269
+ }
19270
+ return {
19271
+ surface: "mobile",
19272
+ hostPlatform,
19273
+ webSdkOrigin: "legacy",
19274
+ mobileShell: "legacy-sdk"
19275
+ };
19276
+ }
19181
19277
  function resolveHostTelemetryFromStartOptions(adaSettings) {
19182
19278
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
19183
19279
  const trustedMobileSdkHostPage = isTrustedMobileSdkHostPage(options.pathname);
19184
- const explicit = trustedMobileSdkHostPage ? normalizeHostTelemetry(adaSettings.hostTelemetry) : undefined;
19185
- const webSdkOrigin = (explicit === null || explicit === void 0 ? void 0 : explicit.webSdkOrigin) ?? "legacy";
19186
- const hostPlatform = (explicit === null || explicit === void 0 ? void 0 : explicit.hostPlatform) ?? (trustedMobileSdkHostPage ? "unknown" : "web");
19187
- const surface = (explicit === null || explicit === void 0 ? void 0 : explicit.surface) ?? (trustedMobileSdkHostPage ? "mobile" : "browser");
19280
+ // Non-http origins are assumed to be native WebView hosts (file://,
19281
+ // react-native asset URIs) legacy AndroidSDK and react-native-sdk both
19282
+ // load a bundled `embed.html` from file://, so the trusted-path check alone
19283
+ // misses them. Gating sdkType attribution on this prevents a web customer
19284
+ // from incidentally tagging themselves as mobile via `metaFields.sdkType`.
19285
+ const trustedMobileContext = trustedMobileSdkHostPage || !isHttpOrigin(options.protocol);
19286
+ // Treat the presence of the hostTelemetry property as authoritative, even if
19287
+ // normalization fails, so broken new-wrapper payloads are not downgraded
19288
+ // into the legacy mobile-shell bucket.
19289
+ const hasExplicitHostTelemetry = trustedMobileSdkHostPage && Object.prototype.hasOwnProperty.call(adaSettings, "hostTelemetry");
19290
+ const explicit = hasExplicitHostTelemetry ? normalizeHostTelemetry(adaSettings.hostTelemetry) : undefined;
19291
+ // Legacy wrappers (iOS SDK, AndroidSDK, react-native-sdk) all set
19292
+ // `metaFields.sdkType` before calling `adaEmbed.start(...)`. They do not
19293
+ // know about the newer `hostTelemetry` handshake, so this fingerprint is
19294
+ // the only way to attribute their traffic to the right platform.
19295
+ const legacyFingerprint = !hasExplicitHostTelemetry ? resolveLegacySdkTypeFingerprint(adaSettings.metaFields, trustedMobileContext) : undefined;
19296
+ const webSdkOrigin = (explicit === null || explicit === void 0 ? void 0 : explicit.webSdkOrigin) ?? (legacyFingerprint === null || legacyFingerprint === void 0 ? void 0 : legacyFingerprint.webSdkOrigin) ?? "legacy";
19297
+ const hostPlatform = (explicit === null || explicit === void 0 ? void 0 : explicit.hostPlatform) ?? (legacyFingerprint === null || legacyFingerprint === void 0 ? void 0 : legacyFingerprint.hostPlatform) ?? (trustedMobileSdkHostPage ? "unknown" : "web");
19298
+ const surface = (explicit === null || explicit === void 0 ? void 0 : explicit.surface) ?? (legacyFingerprint === null || legacyFingerprint === void 0 ? void 0 : legacyFingerprint.surface) ?? (trustedMobileSdkHostPage ? "mobile" : "browser");
19188
19299
  const mobilePackage = explicit === null || explicit === void 0 ? void 0 : explicit.mobilePackage;
19189
- const sdkVariant = explicit === null || explicit === void 0 ? void 0 : explicit.sdkVariant;
19190
- return host_telemetry_objectSpread(host_telemetry_objectSpread({
19300
+ const mobileVersion = explicit === null || explicit === void 0 ? void 0 : explicit.mobileVersion;
19301
+ const mobileShell = deriveMessagingMobileShell(mobilePackage) ?? (explicit === null || explicit === void 0 ? void 0 : explicit.mobileShell) ?? (legacyFingerprint === null || legacyFingerprint === void 0 ? void 0 : legacyFingerprint.mobileShell) ?? (!hasExplicitHostTelemetry ? deriveLegacyMobileShell(surface, hostPlatform) : undefined);
19302
+ return host_telemetry_objectSpread(host_telemetry_objectSpread(host_telemetry_objectSpread({
19191
19303
  surface,
19192
19304
  hostPlatform,
19193
19305
  webSdkOrigin
19194
- }, mobilePackage ? {
19306
+ }, mobileShell ? {
19307
+ mobileShell
19308
+ } : {}), mobilePackage ? {
19195
19309
  mobilePackage
19196
- } : {}), sdkVariant ? {
19197
- sdkVariant
19310
+ } : {}), mobileVersion ? {
19311
+ mobileVersion
19198
19312
  } : {});
19199
19313
  }
19200
19314
  function serializeHostTelemetry(hostTelemetry) {
19201
19315
  return JSON.stringify(hostTelemetry);
19202
19316
  }
19203
19317
  function shouldPropagateHostTelemetry(hostTelemetry) {
19204
- return hostTelemetry.surface !== "browser" || hostTelemetry.hostPlatform !== "web" || hostTelemetry.webSdkOrigin !== "legacy" || Boolean(hostTelemetry.mobilePackage) || Boolean(hostTelemetry.sdkVariant);
19318
+ return hostTelemetry.surface !== "browser" || hostTelemetry.hostPlatform !== "web" || hostTelemetry.webSdkOrigin !== "legacy" || Boolean(hostTelemetry.mobileShell) || Boolean(hostTelemetry.mobilePackage) || Boolean(hostTelemetry.mobileVersion);
19205
19319
  }
19206
19320
  function toMonitoringContext(hostTelemetry) {
19207
- return host_telemetry_objectSpread(host_telemetry_objectSpread({
19321
+ return host_telemetry_objectSpread(host_telemetry_objectSpread(host_telemetry_objectSpread({
19208
19322
  surface: hostTelemetry.surface,
19209
19323
  host_platform: hostTelemetry.hostPlatform,
19210
19324
  web_sdk_origin: hostTelemetry.webSdkOrigin
19211
- }, hostTelemetry.mobilePackage ? {
19325
+ }, hostTelemetry.mobileShell ? {
19326
+ mobile_shell: hostTelemetry.mobileShell
19327
+ } : {}), hostTelemetry.mobilePackage ? {
19212
19328
  mobile_package: hostTelemetry.mobilePackage
19213
- } : {}), hostTelemetry.sdkVariant ? {
19214
- sdk_variant: hostTelemetry.sdkVariant
19329
+ } : {}), hostTelemetry.mobileVersion ? {
19330
+ mobile_version: hostTelemetry.mobileVersion
19215
19331
  } : {});
19216
19332
  }
19217
19333
  ;// CONCATENATED MODULE: ./src/common/helpers/is-mobile.ts
@@ -19435,7 +19551,7 @@ class ChatFrame extends preact_module_d {
19435
19551
  log("Chat frame mount", {
19436
19552
  handle,
19437
19553
  chatUrl: this.url,
19438
- embedVersion: "a6606d6".slice(0, 7),
19554
+ embedVersion: "ea8e50e".slice(0, 7),
19439
19555
  embedSettings: adaSettings
19440
19556
  });
19441
19557
 
@@ -19523,7 +19639,7 @@ class ChatFrame extends preact_module_d {
19523
19639
  const hostPageUrlParams = new URL(window.location.href).searchParams;
19524
19640
  const smsToken = hostPageUrlParams.get("adaSMSToken");
19525
19641
  const queryParams = {
19526
- embedVersion: "a6606d6".slice(0, 7),
19642
+ embedVersion: "ea8e50e".slice(0, 7),
19527
19643
  greeting,
19528
19644
  language,
19529
19645
  skipGreeting,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ada-support/embed2",
3
- "version": "1.13.0",
3
+ "version": "1.13.2",
4
4
  "description": "",
5
5
  "main": "dist/npm-entry",
6
6
  "typings": "dist/npm-entry/index-npm.d.ts",