@guidelytech/shared 0.4.1 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -21,12 +21,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  ADVANCE_ON: () => ADVANCE_ON,
24
+ ANNOTATION_COLORS: () => ANNOTATION_COLORS,
24
25
  AUTOCAPTURE_EVENTS: () => AUTOCAPTURE_EVENTS,
25
26
  AppearanceSchema: () => AppearanceSchema,
26
27
  AuthoringPickSchema: () => AuthoringPickSchema,
27
28
  AutocaptureSettingsSchema: () => AutocaptureSettingsSchema,
28
29
  BUTTON_ACTIONS: () => BUTTON_ACTIONS,
29
30
  ButtonSchema: () => ButtonSchema,
31
+ CAPTURE_PARAM: () => CAPTURE_PARAM,
32
+ CAPTURE_SCREENSHOT_MAX_BYTES: () => CAPTURE_SCREENSHOT_MAX_BYTES,
33
+ CaptureStepSchema: () => CaptureStepSchema,
34
+ CapturedElementSchema: () => CapturedElementSchema,
30
35
  ChecklistConfigSchema: () => ChecklistConfigSchema,
31
36
  ChecklistProgressRequestSchema: () => ChecklistProgressRequestSchema,
32
37
  ChecklistTaskSchema: () => ChecklistTaskSchema,
@@ -34,9 +39,11 @@ __export(index_exports, {
34
39
  ConversationRatingSchema: () => ConversationRatingSchema,
35
40
  DEFAULT_CAPTURE_SETTINGS: () => DEFAULT_CAPTURE_SETTINGS,
36
41
  DEFAULT_PLATFORMS: () => DEFAULT_PLATFORMS,
42
+ EMBED_IFRAME_ATTRS: () => EMBED_IFRAME_ATTRS,
37
43
  EVENT_NAMES: () => EVENT_NAMES,
38
44
  ErrorTrackingSettingsSchema: () => ErrorTrackingSettingsSchema,
39
45
  EventBatchSchema: () => EventBatchSchema,
46
+ FILE_LINK_CLASS: () => FILE_LINK_CLASS,
40
47
  FrequencySchema: () => FrequencySchema,
41
48
  GUIDELY_ID_ATTRIBUTE: () => GUIDELY_ID_ATTRIBUTE,
42
49
  GUIDE_KINDS: () => GUIDE_KINDS,
@@ -46,12 +53,31 @@ __export(index_exports, {
46
53
  GuideConfigSchema: () => GuideConfigSchema,
47
54
  GuideStateUpdateSchema: () => GuideStateUpdateSchema,
48
55
  HEATMAP_VIEWPORTS: () => HEATMAP_VIEWPORTS,
56
+ HOWTO_ACTIONS: () => HOWTO_ACTIONS,
57
+ HOWTO_STEP_KINDS: () => HOWTO_STEP_KINDS,
58
+ HowToAnnotationSchema: () => HowToAnnotationSchema,
49
59
  IdentifyRequestSchema: () => IdentifyRequestSchema,
60
+ MAX_ANNOTATIONS: () => MAX_ANNOTATIONS,
61
+ MAX_COLLECTION_DEPTH: () => MAX_COLLECTION_DEPTH,
50
62
  MAX_MESSAGE_LENGTH: () => MAX_MESSAGE_LENGTH,
51
63
  MAX_PROPERTY_BYTES: () => MAX_PROPERTY_BYTES,
52
64
  MAX_STACK_FRAMES: () => MAX_STACK_FRAMES,
65
+ MEDIA_FILE_MAX_BYTES: () => MEDIA_FILE_MAX_BYTES,
66
+ MEDIA_FILE_TYPES: () => MEDIA_FILE_TYPES,
67
+ MEDIA_IMAGE_MAX_BYTES: () => MEDIA_IMAGE_MAX_BYTES,
68
+ MEDIA_IMAGE_TYPES: () => MEDIA_IMAGE_TYPES,
69
+ MEDIA_MAX_BYTES: () => MEDIA_MAX_BYTES,
70
+ MEDIA_VIDEO_MAX_BYTES: () => MEDIA_VIDEO_MAX_BYTES,
71
+ MEDIA_VIDEO_TYPES: () => MEDIA_VIDEO_TYPES,
53
72
  MESSAGE_AUTHORS: () => MESSAGE_AUTHORS,
73
+ MessengerPageRequestSchema: () => MessengerPageRequestSchema,
54
74
  NETWORK_PLUGIN: () => NETWORK_PLUGIN,
75
+ NormalizedPointSchema: () => NormalizedPointSchema,
76
+ NormalizedRectSchema: () => NormalizedRectSchema,
77
+ PATH_ID_PATTERN: () => PATH_ID_PATTERN,
78
+ PDF_BLOCK_CLASS: () => PDF_BLOCK_CLASS,
79
+ PDF_MAX_PAGES: () => PDF_MAX_PAGES,
80
+ PDF_PAGES_CLASS: () => PDF_PAGES_CLASS,
55
81
  PLACEMENTS: () => PLACEMENTS,
56
82
  PLATFORMS: () => PLATFORMS,
57
83
  PostMessageSchema: () => PostMessageSchema,
@@ -59,6 +85,7 @@ __export(index_exports, {
59
85
  PublishedGuideSchema: () => PublishedGuideSchema,
60
86
  REPLAY_MAX_COMPRESSED_BYTES: () => REPLAY_MAX_COMPRESSED_BYTES,
61
87
  REPLAY_MAX_RAW_BYTES: () => REPLAY_MAX_RAW_BYTES,
88
+ REPLY_TIMES: () => REPLY_TIMES,
62
89
  RULE_FIELDS: () => RULE_FIELDS,
63
90
  RULE_OPERATORS: () => RULE_OPERATORS,
64
91
  ReplayChunkSchema: () => ReplayChunkSchema,
@@ -74,6 +101,7 @@ __export(index_exports, {
74
101
  SHARED_VERSION: () => SHARED_VERSION,
75
102
  SOURCEMAP_MAX_FILES_PER_UPLOAD: () => SOURCEMAP_MAX_FILES_PER_UPLOAD,
76
103
  SOURCEMAP_MAX_FILE_BYTES: () => SOURCEMAP_MAX_FILE_BYTES,
104
+ STATUS_LEVELS: () => STATUS_LEVELS,
77
105
  STEP_TYPES: () => STEP_TYPES,
78
106
  SURVEY_QUESTION_TYPES: () => SURVEY_QUESTION_TYPES,
79
107
  SdkEventSchema: () => SdkEventSchema,
@@ -87,32 +115,50 @@ __export(index_exports, {
87
115
  TRIGGER_TYPES: () => TRIGGER_TYPES,
88
116
  TargetSchema: () => TargetSchema,
89
117
  TriggerSchema: () => TriggerSchema,
118
+ VIDEO_ATTRS: () => VIDEO_ATTRS,
90
119
  WS_MAX_MESSAGES_PER_SOCKET: () => WS_MAX_MESSAGES_PER_SOCKET,
91
120
  WS_MAX_MESSAGE_BYTES: () => WS_MAX_MESSAGE_BYTES,
92
121
  clamp: () => clamp,
122
+ cleanLabel: () => cleanLabel,
93
123
  compare: () => compare,
94
124
  compareVersions: () => compareVersions,
95
125
  defaultGuideConfig: () => defaultGuideConfig,
96
126
  defaultStep: () => defaultStep,
127
+ describeCaptureStep: () => describeCaptureStep,
97
128
  describeRule: () => describeRule,
98
129
  emptyRuleGroup: () => emptyRuleGroup,
99
130
  evaluateRule: () => evaluateRule,
100
131
  evaluateRules: () => evaluateRules,
101
132
  fingerprintError: () => fingerprintError,
133
+ firstNameFromTraits: () => firstNameFromTraits,
102
134
  fnv1a: () => fnv1a,
135
+ foldPathIds: () => foldPathIds,
103
136
  getPath: () => getPath,
104
137
  guidePlatforms: () => guidePlatforms,
105
138
  guidelyIdFromSelector: () => guidelyIdFromSelector,
139
+ isAllowedEmbedSrc: () => isAllowedEmbedSrc,
140
+ isArticleListed: () => isArticleListed,
106
141
  isChecklistComplete: () => isChecklistComplete,
142
+ isFileLink: () => isFileLink,
143
+ isMediaContentType: () => isMediaContentType,
107
144
  isPlainObject: () => isPlainObject,
108
145
  isQuestionVisible: () => isQuestionVisible,
109
146
  isRuleGroup: () => isRuleGroup,
147
+ isSafeMediaUrl: () => isSafeMediaUrl,
148
+ isVideoContentType: () => isVideoContentType,
110
149
  matchUrlPattern: () => matchUrlPattern,
150
+ matchesAudiences: () => matchesAudiences,
151
+ mediaKind: () => mediaKind,
152
+ mediaMaxBytes: () => mediaMaxBytes,
111
153
  normalizeErrorMessage: () => normalizeErrorMessage,
112
154
  normalizeFrameFile: () => normalizeFrameFile,
155
+ pageLabel: () => pageLabel,
156
+ pageName: () => pageName,
157
+ pageTerms: () => pageTerms,
113
158
  parseStack: () => parseStack,
114
159
  randomId: () => randomId,
115
160
  resolveCaptureSettings: () => resolveCaptureSettings,
161
+ resourceCenterSections: () => resourceCenterSections,
116
162
  rolloutBucket: () => rolloutBucket,
117
163
  safeRegExp: () => safeRegExp,
118
164
  sanitizeProperties: () => sanitizeProperties,
@@ -121,7 +167,9 @@ __export(index_exports, {
121
167
  stripOrigin: () => stripOrigin,
122
168
  supportsPlatform: () => supportsPlatform,
123
169
  templateConfig: () => templateConfig,
170
+ toEmbedUrl: () => toEmbedUrl,
124
171
  validateGuideConfig: () => validateGuideConfig,
172
+ visibleArticleIds: () => visibleArticleIds,
125
173
  visibleButtons: () => visibleButtons
126
174
  });
127
175
  module.exports = __toCommonJS(index_exports);
@@ -938,6 +986,14 @@ var PublishedGuideSchema = import_zod4.z.object({
938
986
 
939
987
  // src/messenger.ts
940
988
  var import_zod5 = require("zod");
989
+ var REPLY_TIMES = ["minutes", "hour", "hours", "day"];
990
+ var STATUS_LEVELS = ["operational", "degraded", "outage", "maintenance"];
991
+ var MessengerPageRequestSchema = import_zod5.z.object({
992
+ anonymousId: import_zod5.z.string().min(1).max(128),
993
+ userId: import_zod5.z.string().max(256).optional().nullable(),
994
+ /** Pathname only: query strings and fragments are never sent. */
995
+ path: import_zod5.z.string().min(1).max(1e3)
996
+ });
941
997
  var MESSAGE_AUTHORS = ["user", "scout", "agent", "system"];
942
998
  var MAX_MESSAGE_LENGTH = 4e3;
943
999
  var messageText = import_zod5.z.string().trim().min(1).max(MAX_MESSAGE_LENGTH);
@@ -950,7 +1006,11 @@ var StartConversationSchema = import_zod5.z.object({
950
1006
  var ConversationLookupSchema = import_zod5.z.object({
951
1007
  tokens: import_zod5.z.array(import_zod5.z.string().min(16).max(128)).max(50)
952
1008
  });
953
- var PostMessageSchema = import_zod5.z.object({ message: messageText });
1009
+ var PostMessageSchema = import_zod5.z.object({
1010
+ message: messageText,
1011
+ /** The page the user is on now (omitted when URL collection is off and by older SDKs), so Scout answers for that page. */
1012
+ pageUrl: import_zod5.z.string().max(2e3).optional()
1013
+ });
954
1014
  var ConversationRatingSchema = import_zod5.z.object({
955
1015
  rating: import_zod5.z.number().int().min(1).max(5),
956
1016
  comment: import_zod5.z.string().max(1e3).optional()
@@ -1190,18 +1250,357 @@ function templateConfig(id) {
1190
1250
  return { template: t, config: GuideConfigSchema.parse(t.config) };
1191
1251
  }
1192
1252
 
1253
+ // src/media.ts
1254
+ var MEDIA_IMAGE_TYPES = ["image/png", "image/jpeg", "image/gif", "image/webp"];
1255
+ var MEDIA_VIDEO_TYPES = ["video/mp4", "video/webm"];
1256
+ var MEDIA_FILE_TYPES = ["application/pdf"];
1257
+ var MEDIA_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
1258
+ var MEDIA_VIDEO_MAX_BYTES = 200 * 1024 * 1024;
1259
+ var MEDIA_FILE_MAX_BYTES = 50 * 1024 * 1024;
1260
+ var MEDIA_MAX_BYTES = Math.max(MEDIA_IMAGE_MAX_BYTES, MEDIA_VIDEO_MAX_BYTES, MEDIA_FILE_MAX_BYTES);
1261
+ function isMediaContentType(type) {
1262
+ return mediaKind(type) !== null;
1263
+ }
1264
+ function isVideoContentType(type) {
1265
+ return MEDIA_VIDEO_TYPES.includes(type);
1266
+ }
1267
+ function mediaKind(type) {
1268
+ if (MEDIA_IMAGE_TYPES.includes(type)) return "image";
1269
+ if (MEDIA_VIDEO_TYPES.includes(type)) return "video";
1270
+ if (MEDIA_FILE_TYPES.includes(type)) return "file";
1271
+ return null;
1272
+ }
1273
+ function mediaMaxBytes(type) {
1274
+ const kind = mediaKind(type);
1275
+ return kind === "video" ? MEDIA_VIDEO_MAX_BYTES : kind === "file" ? MEDIA_FILE_MAX_BYTES : MEDIA_IMAGE_MAX_BYTES;
1276
+ }
1277
+ var FILE_LINK_CLASS = "gd-file";
1278
+ var PDF_BLOCK_CLASS = "gd-pdf";
1279
+ var PDF_PAGES_CLASS = "gd-pdf-pages";
1280
+ var PDF_MAX_PAGES = 40;
1281
+ function isFileLink(className, href) {
1282
+ return !!className && className.split(/\s+/).includes(FILE_LINK_CLASS) && isSafeMediaUrl(href);
1283
+ }
1284
+ var YOUTUBE_ID = /^[A-Za-z0-9_-]{11}$/;
1285
+ var VIMEO_ID = /^\d{1,12}$/;
1286
+ var VIMEO_HASH = /^[0-9a-f]{6,20}$/i;
1287
+ var LOOM_ID = /^[0-9a-f]{32}$/i;
1288
+ var WISTIA_ID = /^[a-z0-9]{10}$/i;
1289
+ function parseUrl(input) {
1290
+ const s = input.trim();
1291
+ if (!s) return null;
1292
+ try {
1293
+ const u = new URL(/^[a-z][a-z0-9+.-]*:/i.test(s) ? s : `https://${s}`);
1294
+ if (u.protocol !== "https:" && u.protocol !== "http:") return null;
1295
+ if (u.username || u.password || u.port && u.port !== "443" && u.port !== "80") return null;
1296
+ return u;
1297
+ } catch {
1298
+ return null;
1299
+ }
1300
+ }
1301
+ function parseStart(v) {
1302
+ if (!v) return 0;
1303
+ if (/^\d+$/.test(v)) return Math.min(Number(v), 86400);
1304
+ const m = /^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/.exec(v);
1305
+ if (!m || !m[0]) return 0;
1306
+ return Math.min(Number(m[1] ?? 0) * 3600 + Number(m[2] ?? 0) * 60 + Number(m[3] ?? 0), 86400);
1307
+ }
1308
+ function youtube(id, start) {
1309
+ if (!YOUTUBE_ID.test(id)) return null;
1310
+ return {
1311
+ provider: "youtube",
1312
+ src: `https://www.youtube-nocookie.com/embed/${id}${start ? `?start=${start}` : ""}`,
1313
+ watchUrl: `https://www.youtube.com/watch?v=${id}${start ? `&t=${start}s` : ""}`,
1314
+ title: "YouTube video"
1315
+ };
1316
+ }
1317
+ function vimeo(id, hash) {
1318
+ if (!VIMEO_ID.test(id) || hash !== null && !VIMEO_HASH.test(hash)) return null;
1319
+ const h = hash ? hash.toLowerCase() : null;
1320
+ return { provider: "vimeo", src: `https://player.vimeo.com/video/${id}${h ? `?h=${h}` : ""}`, watchUrl: `https://vimeo.com/${id}${h ? `/${h}` : ""}`, title: "Vimeo video" };
1321
+ }
1322
+ function toEmbedUrl(input) {
1323
+ const u = parseUrl(input);
1324
+ if (!u) return null;
1325
+ const host = u.hostname.toLowerCase().replace(/^www\./, "");
1326
+ const parts = u.pathname.split("/").filter(Boolean);
1327
+ switch (host) {
1328
+ case "youtube.com":
1329
+ case "m.youtube.com":
1330
+ case "youtube-nocookie.com": {
1331
+ const start = parseStart(u.searchParams.get("start") ?? u.searchParams.get("t"));
1332
+ if (parts[0] === "watch" && parts.length === 1) return youtube(u.searchParams.get("v") ?? "", start);
1333
+ if ((parts[0] === "embed" || parts[0] === "shorts" || parts[0] === "live") && parts.length === 2) return youtube(parts[1], start);
1334
+ return null;
1335
+ }
1336
+ case "youtu.be":
1337
+ return parts.length === 1 ? youtube(parts[0], parseStart(u.searchParams.get("t") ?? u.searchParams.get("start"))) : null;
1338
+ case "vimeo.com":
1339
+ if (parts.length === 1) return vimeo(parts[0], null);
1340
+ if (parts.length === 2 && VIMEO_ID.test(parts[0])) return vimeo(parts[0], parts[1]);
1341
+ return null;
1342
+ case "player.vimeo.com":
1343
+ return parts[0] === "video" && parts.length === 2 ? vimeo(parts[1], u.searchParams.get("h")) : null;
1344
+ case "loom.com":
1345
+ if ((parts[0] === "share" || parts[0] === "embed") && parts.length === 2 && LOOM_ID.test(parts[1])) {
1346
+ const id = parts[1].toLowerCase();
1347
+ return { provider: "loom", src: `https://www.loom.com/embed/${id}`, watchUrl: `https://www.loom.com/share/${id}`, title: "Loom video" };
1348
+ }
1349
+ return null;
1350
+ default: {
1351
+ let id;
1352
+ if (host === "fast.wistia.net" || host === "fast.wistia.com") id = parts[0] === "embed" && parts[1] === "iframe" && parts.length === 3 ? parts[2] : void 0;
1353
+ else if (host === "wi.st" || host === "wistia.com" || /^[a-z0-9-]+\.wistia\.com$/.test(host)) id = parts[0] === "medias" && parts.length === 2 ? parts[1] : void 0;
1354
+ if (!id || !WISTIA_ID.test(id)) return null;
1355
+ return { provider: "wistia", src: `https://fast.wistia.net/embed/iframe/${id}`, watchUrl: `https://fast.wistia.net/embed/iframe/${id}`, title: "Wistia video" };
1356
+ }
1357
+ }
1358
+ }
1359
+ function isAllowedEmbedSrc(src) {
1360
+ if (!src) return false;
1361
+ return toEmbedUrl(src)?.src === src;
1362
+ }
1363
+ var EMBED_IFRAME_ATTRS = {
1364
+ allow: "fullscreen; picture-in-picture; encrypted-media",
1365
+ allowfullscreen: "",
1366
+ loading: "lazy",
1367
+ referrerpolicy: "strict-origin-when-cross-origin",
1368
+ sandbox: "allow-scripts allow-same-origin allow-presentation allow-popups allow-popups-to-escape-sandbox"
1369
+ };
1370
+ var VIDEO_ATTRS = { controls: "", preload: "metadata", playsinline: "" };
1371
+ function isSafeMediaUrl(url) {
1372
+ if (!url) return false;
1373
+ try {
1374
+ const u = new URL(url);
1375
+ return (u.protocol === "https:" || u.protocol === "http:") && !u.username && !u.password;
1376
+ } catch {
1377
+ return false;
1378
+ }
1379
+ }
1380
+
1381
+ // src/resource-center.ts
1382
+ var MAX_COLLECTION_DEPTH = 3;
1383
+ function matchesAudiences(required, member) {
1384
+ if (!required || required.length === 0) return true;
1385
+ if (!member) return false;
1386
+ const has2 = member instanceof Set ? (id) => member.has(id) : (id) => member.includes(id);
1387
+ return required.some(has2);
1388
+ }
1389
+ function resourceCenterSections(collections, articles, member) {
1390
+ const byId = new Map(collections.map((c) => [c.id, c]));
1391
+ const children = /* @__PURE__ */ new Map();
1392
+ for (const c of collections) {
1393
+ const parent = c.parentId && c.parentId !== c.id && byId.has(c.parentId) ? c.parentId : null;
1394
+ const list = children.get(parent) ?? [];
1395
+ list.push(c);
1396
+ children.set(parent, list);
1397
+ }
1398
+ for (const list of children.values()) list.sort((a, b) => a.order - b.order || a.name.localeCompare(b.name));
1399
+ const direct = /* @__PURE__ */ new Map();
1400
+ const uncategorized = [];
1401
+ for (const a of articles) {
1402
+ if (!matchesAudiences(a.audienceIds, member)) continue;
1403
+ if (a.collectionId && byId.has(a.collectionId)) {
1404
+ const list = direct.get(a.collectionId) ?? [];
1405
+ list.push(a);
1406
+ direct.set(a.collectionId, list);
1407
+ } else uncategorized.push(a);
1408
+ }
1409
+ const sections = [];
1410
+ const seen = /* @__PURE__ */ new Set();
1411
+ const visit = (c, path) => {
1412
+ if (seen.has(c.id)) return;
1413
+ seen.add(c.id);
1414
+ if (!matchesAudiences(c.audienceIds, member)) return;
1415
+ const here = [...path, c.name];
1416
+ const list = direct.get(c.id);
1417
+ if (list?.length) sections.push({ collection: c, path: here, depth: here.length - 1, articles: list });
1418
+ for (const child of children.get(c.id) ?? []) visit(child, here);
1419
+ };
1420
+ for (const root of children.get(null) ?? []) visit(root, []);
1421
+ if (uncategorized.length) sections.push({ collection: null, path: [], depth: 0, articles: uncategorized });
1422
+ return sections;
1423
+ }
1424
+ function isArticleListed(collections, article, member) {
1425
+ if (!matchesAudiences(article.audienceIds, member)) return false;
1426
+ const byId = new Map(collections.map((c) => [c.id, c]));
1427
+ let cur = article.collectionId ? byId.get(article.collectionId) : void 0;
1428
+ for (let guard = 0; cur && guard <= MAX_COLLECTION_DEPTH * 4; guard++) {
1429
+ if (!matchesAudiences(cur.audienceIds, member)) return false;
1430
+ cur = cur.parentId ? byId.get(cur.parentId) : void 0;
1431
+ }
1432
+ return true;
1433
+ }
1434
+ function visibleArticleIds(collections, articles, member) {
1435
+ return new Set(resourceCenterSections(collections, articles, member).flatMap((s) => s.articles.map((a) => a.id)));
1436
+ }
1437
+
1438
+ // src/howto.ts
1439
+ var import_zod7 = require("zod");
1440
+
1441
+ // src/howto-limits.ts
1442
+ var CAPTURE_PARAM = "guidely_capture";
1443
+ var CAPTURE_SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;
1444
+
1445
+ // src/howto.ts
1446
+ var HOWTO_STEP_KINDS = ["action", "text", "heading", "tip", "alert"];
1447
+ var HOWTO_ACTIONS = ["click", "type", "select", "navigate"];
1448
+ var NormalizedRectSchema = import_zod7.z.object({
1449
+ x: import_zod7.z.number().min(0).max(1),
1450
+ y: import_zod7.z.number().min(0).max(1),
1451
+ width: import_zod7.z.number().min(0).max(1),
1452
+ height: import_zod7.z.number().min(0).max(1)
1453
+ });
1454
+ var CapturedElementSchema = import_zod7.z.object({
1455
+ /** Visible name: aria-label, associated label, text, placeholder, alt or title. */
1456
+ label: import_zod7.z.string().max(200).default(""),
1457
+ /** button, link, tab, menuitem, checkbox, radio, field, dropdown, option, element… */
1458
+ role: import_zod7.z.string().max(40).default("element"),
1459
+ tag: import_zod7.z.string().max(40).default("")
1460
+ });
1461
+ var CaptureStepSchema = import_zod7.z.object({
1462
+ /** Random id from the SDK; a retried upload with the same id is stored once. */
1463
+ clientId: import_zod7.z.string().min(1).max(64),
1464
+ action: import_zod7.z.enum(HOWTO_ACTIONS),
1465
+ url: import_zod7.z.string().max(2e3),
1466
+ pageTitle: import_zod7.z.string().max(300).default(""),
1467
+ element: CapturedElementSchema.optional(),
1468
+ /** Typed text or chosen option; absent when it was sensitive (`valueRedacted`). */
1469
+ value: import_zod7.z.string().max(200).optional(),
1470
+ valueRedacted: import_zod7.z.boolean().default(false),
1471
+ /** Selectors for the element, so the step can later become an interactive tour step. */
1472
+ selectors: import_zod7.z.array(SelectorStrategySchema).max(10).default([]),
1473
+ /** Where the element sits in the screenshot. */
1474
+ highlight: NormalizedRectSchema.optional(),
1475
+ /** Number of regions the SDK blurred in the screenshot before upload. */
1476
+ redactions: import_zod7.z.number().int().min(0).max(1e3).default(0),
1477
+ occurredAt: import_zod7.z.string().datetime().optional()
1478
+ });
1479
+ function quoted(s) {
1480
+ const t = (s ?? "").replace(/\s+/g, " ").trim();
1481
+ return t.length > 60 ? `\u201C${t.slice(0, 57)}\u2026\u201D` : `\u201C${t}\u201D`;
1482
+ }
1483
+ function cleanLabel(label) {
1484
+ const raw = (label ?? "").replace(/\s+/g, " ").trim();
1485
+ const cleaned = raw.replace(/^[^\p{L}\p{N}“"'(]+/u, "").replace(/[\s:*]+$/u, "").replace(/[^\p{L}\p{N})”"'?!.%]+$/u, "").trim();
1486
+ return cleaned || raw;
1487
+ }
1488
+ var SEPARATORS = /\s+[·|•–—-]\s+|\s*[|·•]\s*/;
1489
+ var ID_SEGMENT = /^(?:\d+|[0-9a-f]{8,}(?:-[0-9a-f]{4,})*|[A-Za-z0-9_-]{20,})$/i;
1490
+ function humanize(segment) {
1491
+ const words = decodeURIComponent(segment).replace(/[-_+]+/g, " ").trim();
1492
+ return words ? words.charAt(0).toUpperCase() + words.slice(1) : "";
1493
+ }
1494
+ function pageName(url, pageTitle) {
1495
+ const title = (pageTitle ?? "").replace(/\s+/g, " ").trim();
1496
+ const parts = title.split(SEPARATORS).map((p) => p.trim()).filter(Boolean);
1497
+ if (parts.length > 1) return parts[0];
1498
+ let segments = [];
1499
+ try {
1500
+ segments = new URL(url).pathname.split("/").filter((p) => p && !ID_SEGMENT.test(p));
1501
+ } catch {
1502
+ segments = [];
1503
+ }
1504
+ const fromPath = segments.slice(-2).map(humanize).filter(Boolean).join(" \u203A ");
1505
+ if (!fromPath) return title || hostAndPath(url);
1506
+ if (!title) return fromPath;
1507
+ const lower = title.toLowerCase();
1508
+ const mentionsPath = segments.some((seg) => humanize(seg).toLowerCase().split(" ").some((w) => w.length > 2 && lower.includes(w)));
1509
+ return mentionsPath ? title : fromPath;
1510
+ }
1511
+ var ROLE_NOUN = { tab: "tab", menuitem: "menu item", field: "field", dropdown: "dropdown", option: "option" };
1512
+ function describeCaptureStep(step) {
1513
+ const label = cleanLabel(step.element?.label);
1514
+ const role = step.element?.role ?? "";
1515
+ switch (step.action) {
1516
+ case "navigate": {
1517
+ const where = pageName(step.url, step.pageTitle);
1518
+ return where ? `Go to ${quoted(where)}` : "Open the page";
1519
+ }
1520
+ case "type": {
1521
+ const field = label ? quoted(label) : "the field";
1522
+ if (step.valueRedacted || !step.value) return `Fill in ${field}`;
1523
+ return `Type ${quoted(step.value)} into ${field}`;
1524
+ }
1525
+ case "select":
1526
+ if (step.value && label) return `Select ${quoted(step.value)} from ${quoted(label)}`;
1527
+ if (step.value) return `Select ${quoted(step.value)}`;
1528
+ return label ? `Choose an option in ${quoted(label)}` : "Choose an option";
1529
+ case "click":
1530
+ default:
1531
+ if (role === "checkbox") return label ? `Check ${quoted(label)}` : "Check the box";
1532
+ if (role === "switch") return label ? `Turn ${quoted(label)} on or off` : "Flip the switch";
1533
+ if (role === "radio") return label ? `Select ${quoted(label)}` : "Select the option";
1534
+ if (role === "menuitem") return label ? `Choose ${quoted(label)} from the menu` : "Choose the menu item";
1535
+ if (role === "tab") return label ? `Open the ${quoted(label)} tab` : "Open the tab";
1536
+ if (label) return `Click ${quoted(label)}`;
1537
+ return ROLE_NOUN[role] ? `Click the ${ROLE_NOUN[role]}` : role === "link" ? "Click the link" : "Click the button";
1538
+ }
1539
+ }
1540
+ function hostAndPath(url) {
1541
+ try {
1542
+ const u = new URL(url);
1543
+ return `${u.host}${u.pathname === "/" ? "" : u.pathname}`;
1544
+ } catch {
1545
+ return url.slice(0, 80);
1546
+ }
1547
+ }
1548
+ var NormalizedPointSchema = import_zod7.z.object({ x: import_zod7.z.number().min(0).max(1), y: import_zod7.z.number().min(0).max(1) });
1549
+ var ANNOTATION_COLORS = ["brand", "red", "amber", "green", "black", "white"];
1550
+ var HowToAnnotationSchema = import_zod7.z.discriminatedUnion("type", [
1551
+ import_zod7.z.object({ id: import_zod7.z.string().min(1).max(32), type: import_zod7.z.literal("arrow"), from: NormalizedPointSchema, to: NormalizedPointSchema, color: import_zod7.z.enum(ANNOTATION_COLORS).default("brand") }),
1552
+ import_zod7.z.object({ id: import_zod7.z.string().min(1).max(32), type: import_zod7.z.literal("text"), at: NormalizedPointSchema, text: import_zod7.z.string().trim().min(1).max(120), color: import_zod7.z.enum(ANNOTATION_COLORS).default("brand") }),
1553
+ import_zod7.z.object({ id: import_zod7.z.string().min(1).max(32), type: import_zod7.z.literal("box"), rect: NormalizedRectSchema, color: import_zod7.z.enum(ANNOTATION_COLORS).default("brand") })
1554
+ ]);
1555
+ var MAX_ANNOTATIONS = 30;
1556
+
1557
+ // src/page.ts
1558
+ var PATH_ID_PATTERN = "/([0-9]+|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[0-9a-f]{12,})(?=/|$)";
1559
+ function foldPathIds(path) {
1560
+ return path.replace(new RegExp(PATH_ID_PATTERN, "gi"), "/:id");
1561
+ }
1562
+ var GENERIC_SEGMENTS = /* @__PURE__ */ new Set(["", ":id", "app", "apps", "dashboard", "home", "index", "main", "new", "edit", "view", "show", "details", "detail", "overview", "list", "all", "page", "pages", "en", "v1", "v2"]);
1563
+ function segmentsOf(path) {
1564
+ const clean = foldPathIds((path.split(/[?#]/)[0] || "/").toLowerCase());
1565
+ return clean.split("/").map((s) => s.replace(/\.(html?|php|aspx?)$/, "")).filter((s) => !GENERIC_SEGMENTS.has(s) && /[a-z]/.test(s) && s.length <= 40);
1566
+ }
1567
+ function pageTerms(path) {
1568
+ const words = segmentsOf(path).flatMap((s) => s.split(/[-_.+\s]+/).filter((w) => w.length > 1 && /[a-z]/.test(w)));
1569
+ return [...new Set(words)].slice(0, 8);
1570
+ }
1571
+ function pageLabel(path) {
1572
+ const last = segmentsOf(path).at(-1);
1573
+ if (!last) return null;
1574
+ const words = last.split(/[-_.+\s]+/).filter(Boolean);
1575
+ if (!words.length) return null;
1576
+ const label = words.join(" ");
1577
+ return label.charAt(0).toUpperCase() + label.slice(1);
1578
+ }
1579
+ function firstNameFromTraits(traits) {
1580
+ if (!traits) return null;
1581
+ const pick = (v) => typeof v === "string" ? v.trim() : "";
1582
+ const first = pick(traits.firstName) || pick(traits.first_name) || pick(traits.firstname) || pick(traits.name).split(/\s+/)[0] || "";
1583
+ if (!first || first.length > 40 || first.includes("@") || !/\p{L}/u.test(first)) return null;
1584
+ return first;
1585
+ }
1586
+
1193
1587
  // src/index.ts
1194
1588
  var SDK_API_VERSION = "v1";
1195
- var SHARED_VERSION = "0.4.1";
1589
+ var SHARED_VERSION = "0.6.1";
1196
1590
  // Annotate the CommonJS export names for ESM import in node:
1197
1591
  0 && (module.exports = {
1198
1592
  ADVANCE_ON,
1593
+ ANNOTATION_COLORS,
1199
1594
  AUTOCAPTURE_EVENTS,
1200
1595
  AppearanceSchema,
1201
1596
  AuthoringPickSchema,
1202
1597
  AutocaptureSettingsSchema,
1203
1598
  BUTTON_ACTIONS,
1204
1599
  ButtonSchema,
1600
+ CAPTURE_PARAM,
1601
+ CAPTURE_SCREENSHOT_MAX_BYTES,
1602
+ CaptureStepSchema,
1603
+ CapturedElementSchema,
1205
1604
  ChecklistConfigSchema,
1206
1605
  ChecklistProgressRequestSchema,
1207
1606
  ChecklistTaskSchema,
@@ -1209,9 +1608,11 @@ var SHARED_VERSION = "0.4.1";
1209
1608
  ConversationRatingSchema,
1210
1609
  DEFAULT_CAPTURE_SETTINGS,
1211
1610
  DEFAULT_PLATFORMS,
1611
+ EMBED_IFRAME_ATTRS,
1212
1612
  EVENT_NAMES,
1213
1613
  ErrorTrackingSettingsSchema,
1214
1614
  EventBatchSchema,
1615
+ FILE_LINK_CLASS,
1215
1616
  FrequencySchema,
1216
1617
  GUIDELY_ID_ATTRIBUTE,
1217
1618
  GUIDE_KINDS,
@@ -1221,12 +1622,31 @@ var SHARED_VERSION = "0.4.1";
1221
1622
  GuideConfigSchema,
1222
1623
  GuideStateUpdateSchema,
1223
1624
  HEATMAP_VIEWPORTS,
1625
+ HOWTO_ACTIONS,
1626
+ HOWTO_STEP_KINDS,
1627
+ HowToAnnotationSchema,
1224
1628
  IdentifyRequestSchema,
1629
+ MAX_ANNOTATIONS,
1630
+ MAX_COLLECTION_DEPTH,
1225
1631
  MAX_MESSAGE_LENGTH,
1226
1632
  MAX_PROPERTY_BYTES,
1227
1633
  MAX_STACK_FRAMES,
1634
+ MEDIA_FILE_MAX_BYTES,
1635
+ MEDIA_FILE_TYPES,
1636
+ MEDIA_IMAGE_MAX_BYTES,
1637
+ MEDIA_IMAGE_TYPES,
1638
+ MEDIA_MAX_BYTES,
1639
+ MEDIA_VIDEO_MAX_BYTES,
1640
+ MEDIA_VIDEO_TYPES,
1228
1641
  MESSAGE_AUTHORS,
1642
+ MessengerPageRequestSchema,
1229
1643
  NETWORK_PLUGIN,
1644
+ NormalizedPointSchema,
1645
+ NormalizedRectSchema,
1646
+ PATH_ID_PATTERN,
1647
+ PDF_BLOCK_CLASS,
1648
+ PDF_MAX_PAGES,
1649
+ PDF_PAGES_CLASS,
1230
1650
  PLACEMENTS,
1231
1651
  PLATFORMS,
1232
1652
  PostMessageSchema,
@@ -1234,6 +1654,7 @@ var SHARED_VERSION = "0.4.1";
1234
1654
  PublishedGuideSchema,
1235
1655
  REPLAY_MAX_COMPRESSED_BYTES,
1236
1656
  REPLAY_MAX_RAW_BYTES,
1657
+ REPLY_TIMES,
1237
1658
  RULE_FIELDS,
1238
1659
  RULE_OPERATORS,
1239
1660
  ReplayChunkSchema,
@@ -1249,6 +1670,7 @@ var SHARED_VERSION = "0.4.1";
1249
1670
  SHARED_VERSION,
1250
1671
  SOURCEMAP_MAX_FILES_PER_UPLOAD,
1251
1672
  SOURCEMAP_MAX_FILE_BYTES,
1673
+ STATUS_LEVELS,
1252
1674
  STEP_TYPES,
1253
1675
  SURVEY_QUESTION_TYPES,
1254
1676
  SdkEventSchema,
@@ -1262,32 +1684,50 @@ var SHARED_VERSION = "0.4.1";
1262
1684
  TRIGGER_TYPES,
1263
1685
  TargetSchema,
1264
1686
  TriggerSchema,
1687
+ VIDEO_ATTRS,
1265
1688
  WS_MAX_MESSAGES_PER_SOCKET,
1266
1689
  WS_MAX_MESSAGE_BYTES,
1267
1690
  clamp,
1691
+ cleanLabel,
1268
1692
  compare,
1269
1693
  compareVersions,
1270
1694
  defaultGuideConfig,
1271
1695
  defaultStep,
1696
+ describeCaptureStep,
1272
1697
  describeRule,
1273
1698
  emptyRuleGroup,
1274
1699
  evaluateRule,
1275
1700
  evaluateRules,
1276
1701
  fingerprintError,
1702
+ firstNameFromTraits,
1277
1703
  fnv1a,
1704
+ foldPathIds,
1278
1705
  getPath,
1279
1706
  guidePlatforms,
1280
1707
  guidelyIdFromSelector,
1708
+ isAllowedEmbedSrc,
1709
+ isArticleListed,
1281
1710
  isChecklistComplete,
1711
+ isFileLink,
1712
+ isMediaContentType,
1282
1713
  isPlainObject,
1283
1714
  isQuestionVisible,
1284
1715
  isRuleGroup,
1716
+ isSafeMediaUrl,
1717
+ isVideoContentType,
1285
1718
  matchUrlPattern,
1719
+ matchesAudiences,
1720
+ mediaKind,
1721
+ mediaMaxBytes,
1286
1722
  normalizeErrorMessage,
1287
1723
  normalizeFrameFile,
1724
+ pageLabel,
1725
+ pageName,
1726
+ pageTerms,
1288
1727
  parseStack,
1289
1728
  randomId,
1290
1729
  resolveCaptureSettings,
1730
+ resourceCenterSections,
1291
1731
  rolloutBucket,
1292
1732
  safeRegExp,
1293
1733
  sanitizeProperties,
@@ -1296,7 +1736,9 @@ var SHARED_VERSION = "0.4.1";
1296
1736
  stripOrigin,
1297
1737
  supportsPlatform,
1298
1738
  templateConfig,
1739
+ toEmbedUrl,
1299
1740
  validateGuideConfig,
1741
+ visibleArticleIds,
1300
1742
  visibleButtons
1301
1743
  });
1302
1744
  //# sourceMappingURL=index.cjs.map