@guidelytech/shared 0.8.0 → 0.9.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.
@@ -78,7 +78,7 @@ declare function isChecklistComplete(config: {
78
78
 
79
79
  declare const RULE_OPERATORS: readonly ["equals", "not_equals", "contains", "not_contains", "starts_with", "ends_with", "exists", "not_exists", "gt", "gte", "lt", "lte", "in", "not_in", "regex", "is_true", "is_false", "before", "after"];
80
80
  type RuleOperator = (typeof RULE_OPERATORS)[number];
81
- declare const RULE_FIELDS: readonly ["user.attribute", "account.attribute", "user.role", "user.plan", "url.path", "url.full", "url.query", "device.type", "device.browser", "device.os", "visitor.firstVisit", "visitor.returning", "event.seen", "guide.completed", "guide.dismissed", "guide.seen", "checklist.completed", "audience.member", "datetime.now", "datetime.dayOfWeek", "datetime.hour", "rollout.percentage", "environment", "locale", "app.platform", "app.screen", "app.version"];
81
+ declare const RULE_FIELDS: readonly ["user.attribute", "account.attribute", "user.role", "user.plan", "user.identified", "url.path", "url.full", "url.query", "device.type", "device.browser", "device.os", "visitor.firstVisit", "visitor.returning", "event.seen", "guide.completed", "guide.dismissed", "guide.seen", "checklist.completed", "audience.member", "datetime.now", "datetime.dayOfWeek", "datetime.hour", "rollout.percentage", "environment", "locale", "app.platform", "app.screen", "app.version"];
82
82
  type RuleField = (typeof RULE_FIELDS)[number];
83
83
  interface Rule {
84
84
  id: string;
@@ -137,6 +137,15 @@ declare function evaluateRule(rule: Rule, ctx: TargetingContext): boolean;
137
137
  declare function evaluateRules(group: RuleGroup | null | undefined, ctx: TargetingContext): boolean;
138
138
  /** Fields whose evaluation requires server-held data. Used by docs/UI to annotate rules. */
139
139
  declare const SERVER_ASSISTED_FIELDS: RuleField[];
140
+ /** Who a guide is shown to, before its targeting rules: everyone, only signed-in (identified) users, or only anonymous visitors. */
141
+ declare const GUIDE_VISIBILITIES: readonly ["everyone", "identified", "anonymous"];
142
+ type GuideVisibility = (typeof GUIDE_VISIBILITIES)[number];
143
+ /**
144
+ * Targeting with the visibility folded in as a `user.identified` rule. The server sends guides to SDKs
145
+ * this way, so every SDK applies it through the rules it already evaluates (SDKs that predate the field
146
+ * resolve it as undefined and show the guide to nobody rather than to everyone).
147
+ */
148
+ declare function withVisibility(targeting: RuleGroup, visibility: GuideVisibility | undefined): RuleGroup;
140
149
  declare function describeRule(rule: Rule): string;
141
150
 
142
151
  /** Reserved property names that are stripped from `properties` to avoid collecting sensitive data. */
@@ -196,6 +205,61 @@ declare const CAPTURE_PARAM = "guidely_capture";
196
205
  /** Largest screenshot the capture endpoint accepts. */
197
206
  declare const CAPTURE_SCREENSHOT_MAX_BYTES: number;
198
207
 
208
+ /** Complaint types and limits shared by the server and the messenger runtime (zod-free). */
209
+ /** Where a complaint is in its handling; the messenger shows it as Received → In review → Resolved. */
210
+ declare const COMPLAINT_STATUSES: readonly ["open", "in_review", "resolved"];
211
+ type ComplaintStatus = (typeof COMPLAINT_STATUSES)[number];
212
+ /** Events a complaint webhook can fire on. */
213
+ declare const COMPLAINT_EVENTS: readonly ["complaint.filed", "complaint.status_changed", "complaint.replied", "complaint.resolved"];
214
+ type ComplaintEvent = (typeof COMPLAINT_EVENTS)[number];
215
+ /** Extra questions a category asks for. */
216
+ declare const COMPLAINT_FIELD_TYPES: readonly ["text", "choice"];
217
+ type ComplaintFieldType = (typeof COMPLAINT_FIELD_TYPES)[number];
218
+ declare const MAX_COMPLAINT_FIELDS = 8;
219
+ declare const MAX_COMPLAINT_CHOICES = 12;
220
+ declare const MAX_COMPLAINT_LENGTH = 4000;
221
+ declare const MAX_COMPLAINT_ANSWER_LENGTH = 500;
222
+ /** Largest screenshot the messenger may attach (after it scales the image down). */
223
+ declare const MAX_COMPLAINT_ATTACHMENT_BYTES: number;
224
+ interface ComplaintField {
225
+ /** Stable id (`invoice_number`), used as the answer's key in webhook payloads. */
226
+ id: string;
227
+ label: string;
228
+ type: ComplaintFieldType;
229
+ /** Choices for `choice` questions. */
230
+ options?: string[];
231
+ required: boolean;
232
+ }
233
+ /** "CMP-1042" for complaint number 1042. */
234
+ declare const complaintReference: (number: number) => string;
235
+ /** A category as the messenger offers it. */
236
+ interface MessengerComplaintCategory {
237
+ id: string;
238
+ name: string;
239
+ description: string;
240
+ color: string;
241
+ fields: ComplaintField[];
242
+ }
243
+ /** Complaints block of `MessengerConfig`; absent when the project doesn't take complaints. */
244
+ interface MessengerComplaintsConfig {
245
+ categories: MessengerComplaintCategory[];
246
+ /** Visitors the app hasn't identified may file one (with an email address). */
247
+ anonymous: boolean;
248
+ }
249
+ /** A complaint as the person who filed it sees it (on its conversation). */
250
+ interface MessengerComplaint {
251
+ id: string;
252
+ reference: string;
253
+ status: ComplaintStatus;
254
+ categoryName: string;
255
+ createdAt: string;
256
+ }
257
+ /** Scout offered the complaint form in a reply, with this category picked. */
258
+ interface MessengerComplaintOffer {
259
+ categoryId: string;
260
+ name: string;
261
+ }
262
+
199
263
  /** rrweb plugin name for network events in recordings (event type 6, `data.plugin`). */
200
264
  declare const NETWORK_PLUGIN = "guidely/network@1";
201
265
  /** Request kinds, from `fetch`/`XMLHttpRequest` patching or `PerformanceResourceTiming.initiatorType`. */
@@ -385,8 +449,44 @@ declare function resourceCenterSections<C extends RcCollectionLike, A extends Rc
385
449
  * it must match. For articles outside a loaded list (e.g. server search results).
386
450
  */
387
451
  declare function isArticleListed(collections: readonly RcCollectionLike[], article: RcArticleLike, member?: Membership): boolean;
452
+ /** Who an article is listed for, besides its audiences: everyone, or logged-in (identified) visitors only. */
453
+ declare const ARTICLE_VISIBILITIES: readonly ["everyone", "identified"];
454
+ type ArticleVisibility = (typeof ARTICLE_VISIBILITIES)[number];
455
+ /**
456
+ * Reserved audience every logged-in visitor belongs to. The server folds an article's visibility into
457
+ * the audiences it serves and adds this one to identified visitors' memberships, so every SDK (old ones
458
+ * too) applies "logged-in only" through the audience matching it already does. Anonymous visitors never
459
+ * identify, so their membership is empty and these articles stay hidden.
460
+ */
461
+ declare const LOGGED_IN_AUDIENCE = "$identified";
462
+ /**
463
+ * The audiences an article is served with. Logged-in only with no audiences becomes the reserved
464
+ * audience; with audiences it is already implied, since audience membership only comes from identify.
465
+ */
466
+ declare function servedArticleAudiences(audienceIds: readonly string[], visibility: ArticleVisibility | string | null | undefined): string[];
467
+ /** A visitor's memberships as matched against served articles: logged-in visitors are also in `LOGGED_IN_AUDIENCE`. */
468
+ declare function visitorAudiences(audienceIds: readonly string[], identified: boolean): string[];
388
469
  /** Ids of the articles a viewer sees (for filtering server search results the same way). */
389
470
  declare function visibleArticleIds(collections: readonly RcCollectionLike[], articles: readonly RcArticleLike[], member?: Membership): Set<string>;
471
+ /**
472
+ * A "Show me" prompt in an article body is a plain link, `<p class="gd-show-me"><a href="#guidely-show-me:<guide key>">Show me how</a></p>`,
473
+ * so it survives every sanitizer and reads as a harmless link anywhere else. The widgets turn it into a
474
+ * button that starts the walkthrough (a live flow guide), or hide it when that guide isn't available.
475
+ */
476
+ declare const SHOW_ME_CLASS = "gd-show-me";
477
+ declare const SHOW_ME_HREF_PREFIX = "#guidely-show-me:";
478
+ declare function showMeHref(guideKey: string): string;
479
+ /** The guide key of a Show me link's `href`, or null. */
480
+ declare function showMeKeyFromHref(href: string | null | undefined): string | null;
481
+ /** Guide keys of the Show me prompts in an article body, in order, without repeats (at most 10). */
482
+ declare function showMeKeys(html: string | null | undefined): string[];
483
+ /** The article body plays a video (uploaded, or embedded from YouTube, Vimeo, Loom or Wistia). */
484
+ declare function hasVideoMedia(html: string | null | undefined): boolean;
485
+ /**
486
+ * Help search on the device: every word of the query starts a word of the text, in any order, or the
487
+ * query appears as typed. "add user" finds "Add a new user" and "Users › Add".
488
+ */
489
+ declare function matchesHelpQuery(text: string, query: string): boolean;
390
490
 
391
491
  /**
392
492
  * Page helpers shared by the SDK (page-aware messenger) and the server (page matching, analytics).
@@ -395,10 +495,11 @@ declare function visibleArticleIds(collections: readonly RcCollectionLike[], art
395
495
  /**
396
496
  * One path segment that looks like an identifier: digits, a UUID, or a long hex string (hashes,
397
497
  * Mongo ids). Written so the same source works as a JS RegExp and a Postgres ARE (`regexp_replace`
398
- * with flags `gi`), which keeps id folding identical in SQL and in code.
498
+ * with flags `gi`), which keeps id folding identical in SQL and in code. A segment may be followed
499
+ * by the page query parameters a project keeps in its paths (`/contacts/42?tab=notes`).
399
500
  */
400
- declare const 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,})(?=/|$)";
401
- /** `/contacts/42/notes/9f8e…` → `/contacts/:id/notes/:id`. */
501
+ declare const 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,})(?=[/?]|$)";
502
+ /** `/contacts/42/notes/9f8e…` → `/contacts/:id/notes/:id`; `/contacts/42?tab=notes` → `/contacts/:id?tab=notes`. */
402
503
  declare function foldPathIds(path: string): string;
403
504
  /** Words describing a page, from its path (`/settings/billing-plans/42` → `settings billing plans`). */
404
505
  declare function pageTerms(path: string): string[];
@@ -407,4 +508,4 @@ declare function pageLabel(path: string): string | null;
407
508
  /** The first name in a user's traits (`firstName`, `first_name`, or the first word of `name`), or null. */
408
509
  declare function firstNameFromTraits(traits: Record<string, unknown> | null | undefined): string | null;
409
510
 
410
- export { CAPTURE_PARAM, CAPTURE_SCREENSHOT_MAX_BYTES, DEFAULT_PLATFORMS, EMBED_IFRAME_ATTRS, type EmbedProvider, type ExceptionProperties, FILE_LINK_CLASS, GUIDELY_ID_ATTRIBUTE, MAX_COLLECTION_DEPTH, MAX_PROPERTY_BYTES, MAX_STACK_FRAMES, MEDIA_FILE_MAX_BYTES, MEDIA_FILE_TYPES, MEDIA_IMAGE_MAX_BYTES, MEDIA_IMAGE_TYPES, MEDIA_MAX_BYTES, MEDIA_VIDEO_MAX_BYTES, MEDIA_VIDEO_TYPES, type MediaContentType, type MediaKind, NETWORK_PLUGIN, type NetworkPluginPayload, type NetworkRequest, type NetworkRequestType, PATH_ID_PATTERN, PDF_BLOCK_CLASS, PDF_MAX_PAGES, PDF_PAGES_CLASS, PLATFORMS, type Platform, RULE_FIELDS, RULE_OPERATORS, type RcArticleLike, type RcCollectionLike, type RcSection, type Rule, type RuleField, type RuleGroup, type RuleOperator, SENSITIVE_HEADER_PATTERN, SENSITIVE_PARAM_PATTERN, SENSITIVE_PROPERTY_PATTERN, SERVER_ASSISTED_FIELDS, SOURCEMAP_MAX_FILES_PER_UPLOAD, SOURCEMAP_MAX_FILE_BYTES, type ShowWhen, type StackFrame, type SurveyAnswer, type SurveyAnswers, type TargetingContext, VIDEO_ATTRS, type VideoEmbed, WS_MAX_MESSAGES_PER_SOCKET, WS_MAX_MESSAGE_BYTES, type WebSocketMessage, clamp, compare, compareVersions, describeRule, emptyRuleGroup, evaluateRule, evaluateRules, fingerprintError, firstNameFromTraits, fnv1a, foldPathIds, getPath, guidePlatforms, guidelyIdFromSelector, isAllowedEmbedSrc, isArticleListed, isChecklistComplete, isFileLink, isMediaContentType, isPlainObject, isQuestionVisible, isRuleGroup, isSafeMediaUrl, isVideoContentType, matchUrlPattern, matchesAudiences, mediaKind, mediaMaxBytes, normalizeErrorMessage, normalizeFrameFile, pageLabel, pageTerms, parseStack, randomId, resourceCenterSections, rolloutBucket, safeRegExp, sanitizeProperties, screenPath, slugify, stripOrigin, supportsPlatform, toEmbedUrl, visibleArticleIds };
511
+ export { ARTICLE_VISIBILITIES, type ArticleVisibility, CAPTURE_PARAM, CAPTURE_SCREENSHOT_MAX_BYTES, COMPLAINT_EVENTS, COMPLAINT_FIELD_TYPES, COMPLAINT_STATUSES, type ComplaintEvent, type ComplaintField, type ComplaintFieldType, type ComplaintStatus, DEFAULT_PLATFORMS, EMBED_IFRAME_ATTRS, type EmbedProvider, type ExceptionProperties, FILE_LINK_CLASS, GUIDELY_ID_ATTRIBUTE, GUIDE_VISIBILITIES, type GuideVisibility, LOGGED_IN_AUDIENCE, MAX_COLLECTION_DEPTH, MAX_COMPLAINT_ANSWER_LENGTH, MAX_COMPLAINT_ATTACHMENT_BYTES, MAX_COMPLAINT_CHOICES, MAX_COMPLAINT_FIELDS, MAX_COMPLAINT_LENGTH, MAX_PROPERTY_BYTES, MAX_STACK_FRAMES, MEDIA_FILE_MAX_BYTES, MEDIA_FILE_TYPES, MEDIA_IMAGE_MAX_BYTES, MEDIA_IMAGE_TYPES, MEDIA_MAX_BYTES, MEDIA_VIDEO_MAX_BYTES, MEDIA_VIDEO_TYPES, type MediaContentType, type MediaKind, type MessengerComplaint, type MessengerComplaintCategory, type MessengerComplaintOffer, type MessengerComplaintsConfig, NETWORK_PLUGIN, type NetworkPluginPayload, type NetworkRequest, type NetworkRequestType, PATH_ID_PATTERN, PDF_BLOCK_CLASS, PDF_MAX_PAGES, PDF_PAGES_CLASS, PLATFORMS, type Platform, RULE_FIELDS, RULE_OPERATORS, type RcArticleLike, type RcCollectionLike, type RcSection, type Rule, type RuleField, type RuleGroup, type RuleOperator, SENSITIVE_HEADER_PATTERN, SENSITIVE_PARAM_PATTERN, SENSITIVE_PROPERTY_PATTERN, SERVER_ASSISTED_FIELDS, SHOW_ME_CLASS, SHOW_ME_HREF_PREFIX, SOURCEMAP_MAX_FILES_PER_UPLOAD, SOURCEMAP_MAX_FILE_BYTES, type ShowWhen, type StackFrame, type SurveyAnswer, type SurveyAnswers, type TargetingContext, VIDEO_ATTRS, type VideoEmbed, WS_MAX_MESSAGES_PER_SOCKET, WS_MAX_MESSAGE_BYTES, type WebSocketMessage, clamp, compare, compareVersions, complaintReference, describeRule, emptyRuleGroup, evaluateRule, evaluateRules, fingerprintError, firstNameFromTraits, fnv1a, foldPathIds, getPath, guidePlatforms, guidelyIdFromSelector, hasVideoMedia, isAllowedEmbedSrc, isArticleListed, isChecklistComplete, isFileLink, isMediaContentType, isPlainObject, isQuestionVisible, isRuleGroup, isSafeMediaUrl, isVideoContentType, matchUrlPattern, matchesAudiences, matchesHelpQuery, mediaKind, mediaMaxBytes, normalizeErrorMessage, normalizeFrameFile, pageLabel, pageTerms, parseStack, randomId, resourceCenterSections, rolloutBucket, safeRegExp, sanitizeProperties, screenPath, servedArticleAudiences, showMeHref, showMeKeyFromHref, showMeKeys, slugify, stripOrigin, supportsPlatform, toEmbedUrl, visibleArticleIds, visitorAudiences, withVisibility };
package/dist/runtime.d.ts CHANGED
@@ -78,7 +78,7 @@ declare function isChecklistComplete(config: {
78
78
 
79
79
  declare const RULE_OPERATORS: readonly ["equals", "not_equals", "contains", "not_contains", "starts_with", "ends_with", "exists", "not_exists", "gt", "gte", "lt", "lte", "in", "not_in", "regex", "is_true", "is_false", "before", "after"];
80
80
  type RuleOperator = (typeof RULE_OPERATORS)[number];
81
- declare const RULE_FIELDS: readonly ["user.attribute", "account.attribute", "user.role", "user.plan", "url.path", "url.full", "url.query", "device.type", "device.browser", "device.os", "visitor.firstVisit", "visitor.returning", "event.seen", "guide.completed", "guide.dismissed", "guide.seen", "checklist.completed", "audience.member", "datetime.now", "datetime.dayOfWeek", "datetime.hour", "rollout.percentage", "environment", "locale", "app.platform", "app.screen", "app.version"];
81
+ declare const RULE_FIELDS: readonly ["user.attribute", "account.attribute", "user.role", "user.plan", "user.identified", "url.path", "url.full", "url.query", "device.type", "device.browser", "device.os", "visitor.firstVisit", "visitor.returning", "event.seen", "guide.completed", "guide.dismissed", "guide.seen", "checklist.completed", "audience.member", "datetime.now", "datetime.dayOfWeek", "datetime.hour", "rollout.percentage", "environment", "locale", "app.platform", "app.screen", "app.version"];
82
82
  type RuleField = (typeof RULE_FIELDS)[number];
83
83
  interface Rule {
84
84
  id: string;
@@ -137,6 +137,15 @@ declare function evaluateRule(rule: Rule, ctx: TargetingContext): boolean;
137
137
  declare function evaluateRules(group: RuleGroup | null | undefined, ctx: TargetingContext): boolean;
138
138
  /** Fields whose evaluation requires server-held data. Used by docs/UI to annotate rules. */
139
139
  declare const SERVER_ASSISTED_FIELDS: RuleField[];
140
+ /** Who a guide is shown to, before its targeting rules: everyone, only signed-in (identified) users, or only anonymous visitors. */
141
+ declare const GUIDE_VISIBILITIES: readonly ["everyone", "identified", "anonymous"];
142
+ type GuideVisibility = (typeof GUIDE_VISIBILITIES)[number];
143
+ /**
144
+ * Targeting with the visibility folded in as a `user.identified` rule. The server sends guides to SDKs
145
+ * this way, so every SDK applies it through the rules it already evaluates (SDKs that predate the field
146
+ * resolve it as undefined and show the guide to nobody rather than to everyone).
147
+ */
148
+ declare function withVisibility(targeting: RuleGroup, visibility: GuideVisibility | undefined): RuleGroup;
140
149
  declare function describeRule(rule: Rule): string;
141
150
 
142
151
  /** Reserved property names that are stripped from `properties` to avoid collecting sensitive data. */
@@ -196,6 +205,61 @@ declare const CAPTURE_PARAM = "guidely_capture";
196
205
  /** Largest screenshot the capture endpoint accepts. */
197
206
  declare const CAPTURE_SCREENSHOT_MAX_BYTES: number;
198
207
 
208
+ /** Complaint types and limits shared by the server and the messenger runtime (zod-free). */
209
+ /** Where a complaint is in its handling; the messenger shows it as Received → In review → Resolved. */
210
+ declare const COMPLAINT_STATUSES: readonly ["open", "in_review", "resolved"];
211
+ type ComplaintStatus = (typeof COMPLAINT_STATUSES)[number];
212
+ /** Events a complaint webhook can fire on. */
213
+ declare const COMPLAINT_EVENTS: readonly ["complaint.filed", "complaint.status_changed", "complaint.replied", "complaint.resolved"];
214
+ type ComplaintEvent = (typeof COMPLAINT_EVENTS)[number];
215
+ /** Extra questions a category asks for. */
216
+ declare const COMPLAINT_FIELD_TYPES: readonly ["text", "choice"];
217
+ type ComplaintFieldType = (typeof COMPLAINT_FIELD_TYPES)[number];
218
+ declare const MAX_COMPLAINT_FIELDS = 8;
219
+ declare const MAX_COMPLAINT_CHOICES = 12;
220
+ declare const MAX_COMPLAINT_LENGTH = 4000;
221
+ declare const MAX_COMPLAINT_ANSWER_LENGTH = 500;
222
+ /** Largest screenshot the messenger may attach (after it scales the image down). */
223
+ declare const MAX_COMPLAINT_ATTACHMENT_BYTES: number;
224
+ interface ComplaintField {
225
+ /** Stable id (`invoice_number`), used as the answer's key in webhook payloads. */
226
+ id: string;
227
+ label: string;
228
+ type: ComplaintFieldType;
229
+ /** Choices for `choice` questions. */
230
+ options?: string[];
231
+ required: boolean;
232
+ }
233
+ /** "CMP-1042" for complaint number 1042. */
234
+ declare const complaintReference: (number: number) => string;
235
+ /** A category as the messenger offers it. */
236
+ interface MessengerComplaintCategory {
237
+ id: string;
238
+ name: string;
239
+ description: string;
240
+ color: string;
241
+ fields: ComplaintField[];
242
+ }
243
+ /** Complaints block of `MessengerConfig`; absent when the project doesn't take complaints. */
244
+ interface MessengerComplaintsConfig {
245
+ categories: MessengerComplaintCategory[];
246
+ /** Visitors the app hasn't identified may file one (with an email address). */
247
+ anonymous: boolean;
248
+ }
249
+ /** A complaint as the person who filed it sees it (on its conversation). */
250
+ interface MessengerComplaint {
251
+ id: string;
252
+ reference: string;
253
+ status: ComplaintStatus;
254
+ categoryName: string;
255
+ createdAt: string;
256
+ }
257
+ /** Scout offered the complaint form in a reply, with this category picked. */
258
+ interface MessengerComplaintOffer {
259
+ categoryId: string;
260
+ name: string;
261
+ }
262
+
199
263
  /** rrweb plugin name for network events in recordings (event type 6, `data.plugin`). */
200
264
  declare const NETWORK_PLUGIN = "guidely/network@1";
201
265
  /** Request kinds, from `fetch`/`XMLHttpRequest` patching or `PerformanceResourceTiming.initiatorType`. */
@@ -385,8 +449,44 @@ declare function resourceCenterSections<C extends RcCollectionLike, A extends Rc
385
449
  * it must match. For articles outside a loaded list (e.g. server search results).
386
450
  */
387
451
  declare function isArticleListed(collections: readonly RcCollectionLike[], article: RcArticleLike, member?: Membership): boolean;
452
+ /** Who an article is listed for, besides its audiences: everyone, or logged-in (identified) visitors only. */
453
+ declare const ARTICLE_VISIBILITIES: readonly ["everyone", "identified"];
454
+ type ArticleVisibility = (typeof ARTICLE_VISIBILITIES)[number];
455
+ /**
456
+ * Reserved audience every logged-in visitor belongs to. The server folds an article's visibility into
457
+ * the audiences it serves and adds this one to identified visitors' memberships, so every SDK (old ones
458
+ * too) applies "logged-in only" through the audience matching it already does. Anonymous visitors never
459
+ * identify, so their membership is empty and these articles stay hidden.
460
+ */
461
+ declare const LOGGED_IN_AUDIENCE = "$identified";
462
+ /**
463
+ * The audiences an article is served with. Logged-in only with no audiences becomes the reserved
464
+ * audience; with audiences it is already implied, since audience membership only comes from identify.
465
+ */
466
+ declare function servedArticleAudiences(audienceIds: readonly string[], visibility: ArticleVisibility | string | null | undefined): string[];
467
+ /** A visitor's memberships as matched against served articles: logged-in visitors are also in `LOGGED_IN_AUDIENCE`. */
468
+ declare function visitorAudiences(audienceIds: readonly string[], identified: boolean): string[];
388
469
  /** Ids of the articles a viewer sees (for filtering server search results the same way). */
389
470
  declare function visibleArticleIds(collections: readonly RcCollectionLike[], articles: readonly RcArticleLike[], member?: Membership): Set<string>;
471
+ /**
472
+ * A "Show me" prompt in an article body is a plain link, `<p class="gd-show-me"><a href="#guidely-show-me:<guide key>">Show me how</a></p>`,
473
+ * so it survives every sanitizer and reads as a harmless link anywhere else. The widgets turn it into a
474
+ * button that starts the walkthrough (a live flow guide), or hide it when that guide isn't available.
475
+ */
476
+ declare const SHOW_ME_CLASS = "gd-show-me";
477
+ declare const SHOW_ME_HREF_PREFIX = "#guidely-show-me:";
478
+ declare function showMeHref(guideKey: string): string;
479
+ /** The guide key of a Show me link's `href`, or null. */
480
+ declare function showMeKeyFromHref(href: string | null | undefined): string | null;
481
+ /** Guide keys of the Show me prompts in an article body, in order, without repeats (at most 10). */
482
+ declare function showMeKeys(html: string | null | undefined): string[];
483
+ /** The article body plays a video (uploaded, or embedded from YouTube, Vimeo, Loom or Wistia). */
484
+ declare function hasVideoMedia(html: string | null | undefined): boolean;
485
+ /**
486
+ * Help search on the device: every word of the query starts a word of the text, in any order, or the
487
+ * query appears as typed. "add user" finds "Add a new user" and "Users › Add".
488
+ */
489
+ declare function matchesHelpQuery(text: string, query: string): boolean;
390
490
 
391
491
  /**
392
492
  * Page helpers shared by the SDK (page-aware messenger) and the server (page matching, analytics).
@@ -395,10 +495,11 @@ declare function visibleArticleIds(collections: readonly RcCollectionLike[], art
395
495
  /**
396
496
  * One path segment that looks like an identifier: digits, a UUID, or a long hex string (hashes,
397
497
  * Mongo ids). Written so the same source works as a JS RegExp and a Postgres ARE (`regexp_replace`
398
- * with flags `gi`), which keeps id folding identical in SQL and in code.
498
+ * with flags `gi`), which keeps id folding identical in SQL and in code. A segment may be followed
499
+ * by the page query parameters a project keeps in its paths (`/contacts/42?tab=notes`).
399
500
  */
400
- declare const 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,})(?=/|$)";
401
- /** `/contacts/42/notes/9f8e…` → `/contacts/:id/notes/:id`. */
501
+ declare const 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,})(?=[/?]|$)";
502
+ /** `/contacts/42/notes/9f8e…` → `/contacts/:id/notes/:id`; `/contacts/42?tab=notes` → `/contacts/:id?tab=notes`. */
402
503
  declare function foldPathIds(path: string): string;
403
504
  /** Words describing a page, from its path (`/settings/billing-plans/42` → `settings billing plans`). */
404
505
  declare function pageTerms(path: string): string[];
@@ -407,4 +508,4 @@ declare function pageLabel(path: string): string | null;
407
508
  /** The first name in a user's traits (`firstName`, `first_name`, or the first word of `name`), or null. */
408
509
  declare function firstNameFromTraits(traits: Record<string, unknown> | null | undefined): string | null;
409
510
 
410
- export { CAPTURE_PARAM, CAPTURE_SCREENSHOT_MAX_BYTES, DEFAULT_PLATFORMS, EMBED_IFRAME_ATTRS, type EmbedProvider, type ExceptionProperties, FILE_LINK_CLASS, GUIDELY_ID_ATTRIBUTE, MAX_COLLECTION_DEPTH, MAX_PROPERTY_BYTES, MAX_STACK_FRAMES, MEDIA_FILE_MAX_BYTES, MEDIA_FILE_TYPES, MEDIA_IMAGE_MAX_BYTES, MEDIA_IMAGE_TYPES, MEDIA_MAX_BYTES, MEDIA_VIDEO_MAX_BYTES, MEDIA_VIDEO_TYPES, type MediaContentType, type MediaKind, NETWORK_PLUGIN, type NetworkPluginPayload, type NetworkRequest, type NetworkRequestType, PATH_ID_PATTERN, PDF_BLOCK_CLASS, PDF_MAX_PAGES, PDF_PAGES_CLASS, PLATFORMS, type Platform, RULE_FIELDS, RULE_OPERATORS, type RcArticleLike, type RcCollectionLike, type RcSection, type Rule, type RuleField, type RuleGroup, type RuleOperator, SENSITIVE_HEADER_PATTERN, SENSITIVE_PARAM_PATTERN, SENSITIVE_PROPERTY_PATTERN, SERVER_ASSISTED_FIELDS, SOURCEMAP_MAX_FILES_PER_UPLOAD, SOURCEMAP_MAX_FILE_BYTES, type ShowWhen, type StackFrame, type SurveyAnswer, type SurveyAnswers, type TargetingContext, VIDEO_ATTRS, type VideoEmbed, WS_MAX_MESSAGES_PER_SOCKET, WS_MAX_MESSAGE_BYTES, type WebSocketMessage, clamp, compare, compareVersions, describeRule, emptyRuleGroup, evaluateRule, evaluateRules, fingerprintError, firstNameFromTraits, fnv1a, foldPathIds, getPath, guidePlatforms, guidelyIdFromSelector, isAllowedEmbedSrc, isArticleListed, isChecklistComplete, isFileLink, isMediaContentType, isPlainObject, isQuestionVisible, isRuleGroup, isSafeMediaUrl, isVideoContentType, matchUrlPattern, matchesAudiences, mediaKind, mediaMaxBytes, normalizeErrorMessage, normalizeFrameFile, pageLabel, pageTerms, parseStack, randomId, resourceCenterSections, rolloutBucket, safeRegExp, sanitizeProperties, screenPath, slugify, stripOrigin, supportsPlatform, toEmbedUrl, visibleArticleIds };
511
+ export { ARTICLE_VISIBILITIES, type ArticleVisibility, CAPTURE_PARAM, CAPTURE_SCREENSHOT_MAX_BYTES, COMPLAINT_EVENTS, COMPLAINT_FIELD_TYPES, COMPLAINT_STATUSES, type ComplaintEvent, type ComplaintField, type ComplaintFieldType, type ComplaintStatus, DEFAULT_PLATFORMS, EMBED_IFRAME_ATTRS, type EmbedProvider, type ExceptionProperties, FILE_LINK_CLASS, GUIDELY_ID_ATTRIBUTE, GUIDE_VISIBILITIES, type GuideVisibility, LOGGED_IN_AUDIENCE, MAX_COLLECTION_DEPTH, MAX_COMPLAINT_ANSWER_LENGTH, MAX_COMPLAINT_ATTACHMENT_BYTES, MAX_COMPLAINT_CHOICES, MAX_COMPLAINT_FIELDS, MAX_COMPLAINT_LENGTH, MAX_PROPERTY_BYTES, MAX_STACK_FRAMES, MEDIA_FILE_MAX_BYTES, MEDIA_FILE_TYPES, MEDIA_IMAGE_MAX_BYTES, MEDIA_IMAGE_TYPES, MEDIA_MAX_BYTES, MEDIA_VIDEO_MAX_BYTES, MEDIA_VIDEO_TYPES, type MediaContentType, type MediaKind, type MessengerComplaint, type MessengerComplaintCategory, type MessengerComplaintOffer, type MessengerComplaintsConfig, NETWORK_PLUGIN, type NetworkPluginPayload, type NetworkRequest, type NetworkRequestType, PATH_ID_PATTERN, PDF_BLOCK_CLASS, PDF_MAX_PAGES, PDF_PAGES_CLASS, PLATFORMS, type Platform, RULE_FIELDS, RULE_OPERATORS, type RcArticleLike, type RcCollectionLike, type RcSection, type Rule, type RuleField, type RuleGroup, type RuleOperator, SENSITIVE_HEADER_PATTERN, SENSITIVE_PARAM_PATTERN, SENSITIVE_PROPERTY_PATTERN, SERVER_ASSISTED_FIELDS, SHOW_ME_CLASS, SHOW_ME_HREF_PREFIX, SOURCEMAP_MAX_FILES_PER_UPLOAD, SOURCEMAP_MAX_FILE_BYTES, type ShowWhen, type StackFrame, type SurveyAnswer, type SurveyAnswers, type TargetingContext, VIDEO_ATTRS, type VideoEmbed, WS_MAX_MESSAGES_PER_SOCKET, WS_MAX_MESSAGE_BYTES, type WebSocketMessage, clamp, compare, compareVersions, complaintReference, describeRule, emptyRuleGroup, evaluateRule, evaluateRules, fingerprintError, firstNameFromTraits, fnv1a, foldPathIds, getPath, guidePlatforms, guidelyIdFromSelector, hasVideoMedia, isAllowedEmbedSrc, isArticleListed, isChecklistComplete, isFileLink, isMediaContentType, isPlainObject, isQuestionVisible, isRuleGroup, isSafeMediaUrl, isVideoContentType, matchUrlPattern, matchesAudiences, matchesHelpQuery, mediaKind, mediaMaxBytes, normalizeErrorMessage, normalizeFrameFile, pageLabel, pageTerms, parseStack, randomId, resourceCenterSections, rolloutBucket, safeRegExp, sanitizeProperties, screenPath, servedArticleAudiences, showMeHref, showMeKeyFromHref, showMeKeys, slugify, stripOrigin, supportsPlatform, toEmbedUrl, visibleArticleIds, visitorAudiences, withVisibility };
package/dist/runtime.js CHANGED
@@ -1,11 +1,22 @@
1
1
  import {
2
+ ARTICLE_VISIBILITIES,
2
3
  CAPTURE_PARAM,
3
4
  CAPTURE_SCREENSHOT_MAX_BYTES,
5
+ COMPLAINT_EVENTS,
6
+ COMPLAINT_FIELD_TYPES,
7
+ COMPLAINT_STATUSES,
4
8
  DEFAULT_PLATFORMS,
5
9
  EMBED_IFRAME_ATTRS,
6
10
  FILE_LINK_CLASS,
7
11
  GUIDELY_ID_ATTRIBUTE,
12
+ GUIDE_VISIBILITIES,
13
+ LOGGED_IN_AUDIENCE,
8
14
  MAX_COLLECTION_DEPTH,
15
+ MAX_COMPLAINT_ANSWER_LENGTH,
16
+ MAX_COMPLAINT_ATTACHMENT_BYTES,
17
+ MAX_COMPLAINT_CHOICES,
18
+ MAX_COMPLAINT_FIELDS,
19
+ MAX_COMPLAINT_LENGTH,
9
20
  MAX_PROPERTY_BYTES,
10
21
  MAX_STACK_FRAMES,
11
22
  MEDIA_FILE_MAX_BYTES,
@@ -27,6 +38,8 @@ import {
27
38
  SENSITIVE_PARAM_PATTERN,
28
39
  SENSITIVE_PROPERTY_PATTERN,
29
40
  SERVER_ASSISTED_FIELDS,
41
+ SHOW_ME_CLASS,
42
+ SHOW_ME_HREF_PREFIX,
30
43
  SOURCEMAP_MAX_FILES_PER_UPLOAD,
31
44
  SOURCEMAP_MAX_FILE_BYTES,
32
45
  VIDEO_ATTRS,
@@ -35,6 +48,7 @@ import {
35
48
  clamp,
36
49
  compare,
37
50
  compareVersions,
51
+ complaintReference,
38
52
  describeRule,
39
53
  emptyRuleGroup,
40
54
  evaluateRule,
@@ -46,6 +60,7 @@ import {
46
60
  getPath,
47
61
  guidePlatforms,
48
62
  guidelyIdFromSelector,
63
+ hasVideoMedia,
49
64
  isAllowedEmbedSrc,
50
65
  isArticleListed,
51
66
  isChecklistComplete,
@@ -58,6 +73,7 @@ import {
58
73
  isVideoContentType,
59
74
  matchUrlPattern,
60
75
  matchesAudiences,
76
+ matchesHelpQuery,
61
77
  mediaKind,
62
78
  mediaMaxBytes,
63
79
  normalizeErrorMessage,
@@ -71,20 +87,37 @@ import {
71
87
  safeRegExp,
72
88
  sanitizeProperties,
73
89
  screenPath,
90
+ servedArticleAudiences,
91
+ showMeHref,
92
+ showMeKeyFromHref,
93
+ showMeKeys,
74
94
  slugify,
75
95
  stripOrigin,
76
96
  supportsPlatform,
77
97
  toEmbedUrl,
78
- visibleArticleIds
79
- } from "./chunk-OLWGMDRX.js";
98
+ visibleArticleIds,
99
+ visitorAudiences,
100
+ withVisibility
101
+ } from "./chunk-UW6NRYRY.js";
80
102
  export {
103
+ ARTICLE_VISIBILITIES,
81
104
  CAPTURE_PARAM,
82
105
  CAPTURE_SCREENSHOT_MAX_BYTES,
106
+ COMPLAINT_EVENTS,
107
+ COMPLAINT_FIELD_TYPES,
108
+ COMPLAINT_STATUSES,
83
109
  DEFAULT_PLATFORMS,
84
110
  EMBED_IFRAME_ATTRS,
85
111
  FILE_LINK_CLASS,
86
112
  GUIDELY_ID_ATTRIBUTE,
113
+ GUIDE_VISIBILITIES,
114
+ LOGGED_IN_AUDIENCE,
87
115
  MAX_COLLECTION_DEPTH,
116
+ MAX_COMPLAINT_ANSWER_LENGTH,
117
+ MAX_COMPLAINT_ATTACHMENT_BYTES,
118
+ MAX_COMPLAINT_CHOICES,
119
+ MAX_COMPLAINT_FIELDS,
120
+ MAX_COMPLAINT_LENGTH,
88
121
  MAX_PROPERTY_BYTES,
89
122
  MAX_STACK_FRAMES,
90
123
  MEDIA_FILE_MAX_BYTES,
@@ -106,6 +139,8 @@ export {
106
139
  SENSITIVE_PARAM_PATTERN,
107
140
  SENSITIVE_PROPERTY_PATTERN,
108
141
  SERVER_ASSISTED_FIELDS,
142
+ SHOW_ME_CLASS,
143
+ SHOW_ME_HREF_PREFIX,
109
144
  SOURCEMAP_MAX_FILES_PER_UPLOAD,
110
145
  SOURCEMAP_MAX_FILE_BYTES,
111
146
  VIDEO_ATTRS,
@@ -114,6 +149,7 @@ export {
114
149
  clamp,
115
150
  compare,
116
151
  compareVersions,
152
+ complaintReference,
117
153
  describeRule,
118
154
  emptyRuleGroup,
119
155
  evaluateRule,
@@ -125,6 +161,7 @@ export {
125
161
  getPath,
126
162
  guidePlatforms,
127
163
  guidelyIdFromSelector,
164
+ hasVideoMedia,
128
165
  isAllowedEmbedSrc,
129
166
  isArticleListed,
130
167
  isChecklistComplete,
@@ -137,6 +174,7 @@ export {
137
174
  isVideoContentType,
138
175
  matchUrlPattern,
139
176
  matchesAudiences,
177
+ matchesHelpQuery,
140
178
  mediaKind,
141
179
  mediaMaxBytes,
142
180
  normalizeErrorMessage,
@@ -150,10 +188,16 @@ export {
150
188
  safeRegExp,
151
189
  sanitizeProperties,
152
190
  screenPath,
191
+ servedArticleAudiences,
192
+ showMeHref,
193
+ showMeKeyFromHref,
194
+ showMeKeys,
153
195
  slugify,
154
196
  stripOrigin,
155
197
  supportsPlatform,
156
198
  toEmbedUrl,
157
- visibleArticleIds
199
+ visibleArticleIds,
200
+ visitorAudiences,
201
+ withVisibility
158
202
  };
159
203
  //# sourceMappingURL=runtime.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guidelytech/shared",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Shared schemas, types and pure utilities for Guidely",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -40,12 +40,12 @@
40
40
  },
41
41
  "repository": {
42
42
  "type": "git",
43
- "url": "git+https://github.com/parmarg/Guidely.git",
43
+ "url": "git+https://github.com/GuidelyTech/Guidely.git",
44
44
  "directory": "packages/shared"
45
45
  },
46
- "homepage": "https://github.com/parmarg/Guidely/tree/main/packages/shared#readme",
46
+ "homepage": "https://github.com/GuidelyTech/Guidely/tree/main/packages/shared#readme",
47
47
  "bugs": {
48
- "url": "https://github.com/parmarg/Guidely/issues"
48
+ "url": "https://github.com/GuidelyTech/Guidely/issues"
49
49
  },
50
50
  "keywords": [
51
51
  "guidely",