@usertour/helpers 0.0.10 → 0.0.11

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,1001 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/conditions.ts
31
- var conditions_exports = {};
32
- __export(conditions_exports, {
33
- PRIORITIES: () => PRIORITIES,
34
- activedContentCondition: () => activedContentCondition,
35
- activedContentRulesConditions: () => activedContentRulesConditions,
36
- activedRulesConditions: () => activedRulesConditions,
37
- checklistIsDimissed: () => checklistIsDimissed,
38
- checklistIsSeen: () => checklistIsSeen,
39
- filterAutoStartContent: () => filterAutoStartContent,
40
- findLatestEvent: () => findLatestEvent,
41
- flowIsDismissed: () => flowIsDismissed,
42
- flowIsSeen: () => flowIsSeen,
43
- isActive: () => isActive,
44
- isActiveContent: () => isActiveContent,
45
- isHasActivedContents: () => isHasActivedContents,
46
- isSameContents: () => isSameContents,
47
- isValidContent: () => isValidContent,
48
- isVisible: () => isVisible,
49
- parseUrlParams: () => parseUrlParams,
50
- wait: () => wait
51
- });
52
- module.exports = __toCommonJS(conditions_exports);
53
- var import_dom = require("@floating-ui/dom");
54
-
55
- // src/finderx.ts
56
- var import_finder = require("@medv/finder");
57
- var finderAttrs = [
58
- "data-for",
59
- "data-id",
60
- "data-testid",
61
- "data-test-id",
62
- "for",
63
- "id",
64
- "name",
65
- "placeholder",
66
- "role"
67
- ];
68
- var defaultConfig = {
69
- idName: () => false,
70
- className: () => false,
71
- tagName: () => false,
72
- attr: () => false,
73
- seedMinLength: 1,
74
- optimizedMinLength: 2,
75
- threshold: 1e3,
76
- maxNumberOfTries: 1e4
77
- };
78
- var finderConfigs = [
79
- {
80
- ...defaultConfig,
81
- tagName: () => true
82
- },
83
- {
84
- ...defaultConfig,
85
- idName: () => true
86
- },
87
- {
88
- ...defaultConfig,
89
- tagName: () => true,
90
- attr: (name) => finderAttrs.includes(name)
91
- },
92
- {
93
- ...defaultConfig,
94
- className: () => true,
95
- attr: (name) => finderAttrs.includes(name)
96
- },
97
- {
98
- ...defaultConfig,
99
- tagName: () => true,
100
- idName: () => true,
101
- className: () => true,
102
- attr: () => false
103
- },
104
- {
105
- ...defaultConfig,
106
- tagName: () => true,
107
- idName: () => true,
108
- className: () => true,
109
- attr: (name) => finderAttrs.includes(name)
110
- }
111
- ];
112
- function getMaxDepth(node) {
113
- if (node.parentNode) {
114
- return getMaxDepth(node.parentNode);
115
- }
116
- return node.depth;
117
- }
118
- function queryNodeListBySelectors(selectors, rootDocument, removeRepeat = true) {
119
- const nodes = [];
120
- if (!selectors) {
121
- return nodes;
122
- }
123
- for (const s of selectors) {
124
- const els = rootDocument.querySelectorAll(s.replace(/\\\\/g, "\\"));
125
- if (els && els.length > 0) {
126
- nodes.push(...Array.from(els));
127
- }
128
- }
129
- return removeRepeat ? [...new Set(nodes)] : nodes;
130
- }
131
- function findMostRecurringNode(nodes) {
132
- const m = /* @__PURE__ */ new Map();
133
- let finalNode = nodes[0];
134
- let count = 0;
135
- for (const node of nodes) {
136
- const i = m.get(node) ? m.get(node) + 1 : 1;
137
- m.set(node, i);
138
- }
139
- m.forEach((value, key) => {
140
- if (value > count) {
141
- count = value;
142
- finalNode = key;
143
- }
144
- });
145
- return finalNode;
146
- }
147
- function compareParentNode(node, el, rootDocument, isCompareSibings = false) {
148
- let nodeParentNode = node.parentNode;
149
- let elParentElement = el.parentElement;
150
- const maxDepth = getMaxDepth(node);
151
- const xresult = {
152
- maxDepth,
153
- failedDepth: 0,
154
- success: true
155
- };
156
- while (nodeParentNode && elParentElement) {
157
- if (elParentElement === rootDocument) {
158
- break;
159
- }
160
- if (elParentElement === document.body || elParentElement === document.documentElement || elParentElement.parentElement === document.body) {
161
- break;
162
- }
163
- const parentNodes = queryNodeListBySelectors(nodeParentNode.selectors, rootDocument);
164
- const isMatchSibings = isCompareSibings ? compareSibingsNode(nodeParentNode, elParentElement, rootDocument) : true;
165
- if (!parentNodes || parentNodes.length === 0 || !parentNodes.includes(elParentElement) || !isMatchSibings) {
166
- xresult.failedDepth = nodeParentNode.depth;
167
- xresult.success = false;
168
- }
169
- nodeParentNode = nodeParentNode.parentNode;
170
- elParentElement = elParentElement.parentElement;
171
- }
172
- return xresult;
173
- }
174
- function compareSibingsNode(node, el, rootDocument) {
175
- let isMatchNext = true;
176
- let isMatchPrevious = true;
177
- const { previousElementSelectors, nextElementSelectors } = node;
178
- if (nextElementSelectors && nextElementSelectors.length > 0) {
179
- const nextElementSiblings = queryNodeListBySelectors(nextElementSelectors, rootDocument);
180
- isMatchNext = el.nextElementSibling && nextElementSiblings.includes(el.nextElementSibling);
181
- }
182
- if (previousElementSelectors && previousElementSelectors.length > 0) {
183
- const previousElementSiblings = queryNodeListBySelectors(
184
- previousElementSelectors,
185
- rootDocument
186
- );
187
- isMatchPrevious = el.previousElementSibling && previousElementSiblings.includes(el.previousElementSibling);
188
- }
189
- return isMatchNext && isMatchPrevious;
190
- }
191
- function finderMostPrecisionElement(elements, node, rootDocument, precision) {
192
- const successEls = [];
193
- let failedData = {
194
- el: null,
195
- failedDepth: 0,
196
- maxDepth: 0
197
- };
198
- for (const el of elements) {
199
- const { success, failedDepth, maxDepth } = compareParentNode(node, el, rootDocument);
200
- if (success) {
201
- successEls.push(el);
202
- } else if (!failedData.el || failedDepth > failedData.failedDepth) {
203
- failedData = { el, failedDepth, maxDepth };
204
- }
205
- }
206
- if (successEls.length === 1) {
207
- return successEls[0];
208
- }
209
- if (successEls.length > 1) {
210
- let tempEl = successEls[0];
211
- let tempFailedDepth = 0;
212
- for (const el of successEls) {
213
- const { success, failedDepth } = compareParentNode(node, el, rootDocument, true);
214
- if (success) {
215
- return el;
216
- }
217
- if (failedDepth > tempFailedDepth) {
218
- tempFailedDepth = failedDepth;
219
- tempEl = el;
220
- }
221
- }
222
- return tempEl;
223
- }
224
- if (failedData.el) {
225
- const { failedDepth, maxDepth, el } = failedData;
226
- const rate = (failedDepth - 1) / maxDepth * 10;
227
- if (rate >= precision) {
228
- return el;
229
- }
230
- }
231
- return null;
232
- }
233
- function finderV2(target, root) {
234
- const {
235
- selectors,
236
- content = "",
237
- sequence = 0,
238
- precision = "strict",
239
- isDynamicContent = false,
240
- customSelector = "",
241
- type = "auto"
242
- } = target;
243
- if (type === "auto") {
244
- const mapping = {
245
- looser: 1,
246
- loose: 3,
247
- loosest: 5,
248
- strict: 7,
249
- stricter: 8,
250
- strictest: 10
251
- };
252
- const el = finderX(selectors, root, mapping[precision]);
253
- if (el) {
254
- if (isDynamicContent && content && el.innerText !== content) {
255
- return null;
256
- }
257
- return el;
258
- }
259
- } else {
260
- const sequenceMapping = {
261
- "1st": 0,
262
- "2st": 1,
263
- "3st": 2,
264
- "4st": 3,
265
- "5st": 4
266
- };
267
- if (customSelector) {
268
- const selector = customSelector.replace(/\\\\/g, "\\");
269
- const els = root.querySelectorAll(selector);
270
- if (els.length > 0) {
271
- const el = els[sequenceMapping[sequence]] || els[0];
272
- if (content && el.innerText.trim() !== content) {
273
- return null;
274
- }
275
- return el;
276
- }
277
- }
278
- }
279
- return null;
280
- }
281
- function finderX(node, root, precision = 10) {
282
- if (!node || node.selectors.length === 0) {
283
- return null;
284
- }
285
- const rootDocument = root || document;
286
- const elements = [];
287
- const nodeList = queryNodeListBySelectors(node.selectors, rootDocument, false);
288
- if (!nodeList || nodeList.length === 0) {
289
- return null;
290
- }
291
- if ([...new Set(nodeList)].length !== nodeList.length) {
292
- const el = findMostRecurringNode(nodeList);
293
- elements.push(el);
294
- } else {
295
- elements.push(...nodeList);
296
- }
297
- return finderMostPrecisionElement(elements, node, rootDocument, precision);
298
- }
299
-
300
- // src/condition.ts
301
- var import_fast_deep_equal = __toESM(require("fast-deep-equal"), 1);
302
- var parseUrl = (url) => {
303
- const urlPatterns = url.match(/^(([a-z\d]+):\/\/)?([^/?#]+)?(\/[^?#]*)?(\?([^#]*))?(#.*)?$/i);
304
- if (!urlPatterns) {
305
- return null;
306
- }
307
- const [, , scheme = "", domain = "", path = "", , query = "", fragment = ""] = urlPatterns;
308
- return { scheme, domain, path, query, fragment };
309
- };
310
- var replaceWildcard = (input, s1, s2) => {
311
- const withSpecialWords = replaceSpecialWords(input);
312
- const withWildcard = withSpecialWords.replace(/\\\*/g, `${s1}*`);
313
- if (!s2) {
314
- return withWildcard;
315
- }
316
- return withWildcard.replace(/:[a-z0-9_]+/g, `[^${s2}]+`);
317
- };
318
- var replaceSpecialWords = (str) => {
319
- return str.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
320
- };
321
- var parsePattern = (pattern) => {
322
- if (!pattern || !pattern.trim()) {
323
- return null;
324
- }
325
- const _pattern = parseUrl(pattern);
326
- if (!_pattern) {
327
- console.error("Invalid URL pattern:", pattern);
328
- return null;
329
- }
330
- const { scheme, domain, path, query, fragment } = _pattern;
331
- const _scheme = scheme ? replaceSpecialWords(scheme) : "[a-z\\d]+";
332
- const _domain = domain ? replaceWildcard(domain, "[^/]", ".") : "[^/]*";
333
- const _fragment = fragment ? replaceWildcard(fragment, ".", "/") : "(#.*)?";
334
- const _path = path ? replaceWildcard(path, "[^?#]", "/") : "/[^?#]*";
335
- let _query = "(\\?[^#]*)?";
336
- if (query) {
337
- new URLSearchParams(query).forEach((value, key) => {
338
- const _str = value === "" ? "=?" : value === "*" ? "(=[^&#]*)?" : `=${replaceWildcard(value, "[^#]")}`;
339
- _query += `(?=.*[?&]${replaceSpecialWords(key)}${_str}([&#]|$))`;
340
- });
341
- _query += "\\?[^#]*";
342
- }
343
- return new RegExp(`^${_scheme}://${_domain}(:\\d+)?${_path}${_query}${_fragment}$`);
344
- };
345
- var isMatchUrlPattern = (_url, includes, excludes) => {
346
- const isMatchIncludesConditions = includes.length > 0 ? includes.some((_include) => {
347
- const reg = parsePattern(_include);
348
- if (reg) {
349
- return reg.test(_url);
350
- }
351
- return false;
352
- }) : true;
353
- const isMatchExcludesConditions = excludes.length > 0 ? excludes.some((_exclude) => {
354
- const reg = parsePattern(_exclude);
355
- if (reg) {
356
- return reg.test(_url);
357
- }
358
- return false;
359
- }) : false;
360
- return isMatchIncludesConditions && !isMatchExcludesConditions;
361
- };
362
- var compareConditionsItem = (item1, item2) => {
363
- const { data = {}, ...others1 } = item1;
364
- const { data: data2 = {}, ...others2 } = item2;
365
- if (!(0, import_fast_deep_equal.default)(others2, others1)) {
366
- return false;
367
- }
368
- for (const key in data) {
369
- if (!(0, import_fast_deep_equal.default)(data[key], data2[key])) {
370
- return false;
371
- }
372
- }
373
- return true;
374
- };
375
- var conditionsIsSame = (rr1, rr2) => {
376
- const r1 = [...rr1];
377
- const r2 = [...rr2];
378
- if (r1.length === 0 && r2.length === 0) {
379
- return true;
380
- }
381
- if (r1.length !== r2.length) {
382
- return false;
383
- }
384
- const group1 = r1.filter((item) => item.type === "group");
385
- const group2 = r2.filter((item) => item.type === "group");
386
- if (group1.length !== group2.length) {
387
- return false;
388
- }
389
- for (let index = 0; index < r1.length; index++) {
390
- const item1 = r1[index];
391
- const item2 = r2[index];
392
- if (!item1 || !item2) {
393
- return false;
394
- }
395
- if (item1.type === "group") {
396
- if (!item2.conditions) {
397
- return false;
398
- }
399
- const c1 = item1.conditions;
400
- const c2 = item2.conditions;
401
- if (item1.operators !== item2.operators) {
402
- return false;
403
- }
404
- if (!conditionsIsSame(c1, c2)) {
405
- return false;
406
- }
407
- } else {
408
- if (!compareConditionsItem(item1, item2)) {
409
- return false;
410
- }
411
- }
412
- }
413
- return true;
414
- };
415
-
416
- // src/conditions.ts
417
- var import_types = require("@usertour/types");
418
- var import_date_fns = require("date-fns");
419
-
420
- // src/globals.ts
421
- var win = typeof window !== "undefined" ? window : void 0;
422
- var global = typeof globalThis !== "undefined" ? globalThis : win;
423
- var ArrayProto = Array.prototype;
424
- var nativeForEach = ArrayProto.forEach;
425
- var nativeIndexOf = ArrayProto.indexOf;
426
- var navigator = global == null ? void 0 : global.navigator;
427
- var document2 = global == null ? void 0 : global.document;
428
- var location = global == null ? void 0 : global.location;
429
- var fetch = global == null ? void 0 : global.fetch;
430
- var XMLHttpRequest = (global == null ? void 0 : global.XMLHttpRequest) && "withCredentials" in new global.XMLHttpRequest() ? global.XMLHttpRequest : void 0;
431
- var AbortController = global == null ? void 0 : global.AbortController;
432
- var userAgent = navigator == null ? void 0 : navigator.userAgent;
433
- var assignableWindow = win != null ? win : {};
434
-
435
- // src/listener.ts
436
- function on(obj, ...args) {
437
- if (obj == null ? void 0 : obj.addEventListener) {
438
- obj.addEventListener(...args);
439
- }
440
- }
441
- function off(obj, ...args) {
442
- if (obj == null ? void 0 : obj.removeEventListener) {
443
- obj.removeEventListener(...args);
444
- }
445
- }
446
-
447
- // src/conditions.ts
448
- var rulesTypes = Object.values(import_types.RulesType);
449
- var PRIORITIES = [
450
- import_types.ContentPriority.HIGHEST,
451
- import_types.ContentPriority.HIGH,
452
- import_types.ContentPriority.MEDIUM,
453
- import_types.ContentPriority.LOW,
454
- import_types.ContentPriority.LOWEST
455
- ];
456
- var isActiveRulesByCurrentPage = (rules) => {
457
- const { excludes, includes } = rules.data;
458
- if (location) {
459
- const href = location.href;
460
- return isMatchUrlPattern(href, includes, excludes);
461
- }
462
- return false;
463
- };
464
- var isActiveRulesByCurrentTime = (rules) => {
465
- const { endDate, endDateHour, endDateMinute, startDate, startDateHour, startDateMinute } = rules.data;
466
- const startTime = /* @__PURE__ */ new Date(`${startDate} ${startDateHour}:${startDateMinute}:00`);
467
- const endTime = /* @__PURE__ */ new Date(`${endDate} ${endDateHour}:${endDateMinute}:00`);
468
- const now = /* @__PURE__ */ new Date();
469
- if (!endDate) {
470
- return (0, import_date_fns.isAfter)(now, startTime);
471
- }
472
- return (0, import_date_fns.isAfter)(now, startTime) && (0, import_date_fns.isBefore)(now, endTime);
473
- };
474
- var isActivedContentRulesCondition = (rules, contentSession) => {
475
- const { contentId, logic } = rules.data;
476
- const { latestSession, seenSessions, completedSessions } = contentSession;
477
- if (!contentId || !logic || contentId !== contentSession.contentId) {
478
- return false;
479
- }
480
- if (logic === import_types.ContentConditionLogic.ACTIVED || logic === import_types.ContentConditionLogic.UNACTIVED) {
481
- if (!latestSession) {
482
- return logic === import_types.ContentConditionLogic.UNACTIVED;
483
- }
484
- const isActived = !(flowIsDismissed(latestSession) || checklistIsDimissed(latestSession));
485
- return logic === import_types.ContentConditionLogic.ACTIVED ? isActived : !isActived;
486
- }
487
- const isSeen = seenSessions > 0;
488
- const isCompleted = completedSessions > 0;
489
- if (logic === import_types.ContentConditionLogic.SEEN || logic === import_types.ContentConditionLogic.UNSEEN) {
490
- return logic === import_types.ContentConditionLogic.SEEN ? isSeen : !isSeen;
491
- }
492
- if (logic === import_types.ContentConditionLogic.COMPLETED || logic === import_types.ContentConditionLogic.UNCOMPLETED) {
493
- return logic === import_types.ContentConditionLogic.COMPLETED ? isCompleted : !isCompleted;
494
- }
495
- return false;
496
- };
497
- var isVisible = async (el) => {
498
- var _a, _b;
499
- if (!((_a = document2) == null ? void 0 : _a.body)) {
500
- return false;
501
- }
502
- const { middlewareData } = await (0, import_dom.computePosition)(el, document2.body, {
503
- strategy: "fixed",
504
- middleware: [(0, import_dom.hide)()]
505
- });
506
- if ((_b = middlewareData == null ? void 0 : middlewareData.hide) == null ? void 0 : _b.referenceHidden) {
507
- return false;
508
- }
509
- return true;
510
- };
511
- var cache = /* @__PURE__ */ new Map();
512
- var isClicked = (el) => {
513
- if (cache.has(el)) {
514
- return cache.get(el);
515
- }
516
- const onClick = () => {
517
- cache.set(el, true);
518
- off(el, "click", onClick);
519
- };
520
- on(el, "click", onClick);
521
- cache.set(el, false);
522
- return false;
523
- };
524
- var isActiveRulesByElement = async (rules) => {
525
- const { data } = rules;
526
- if (!document2) {
527
- return false;
528
- }
529
- const el = finderV2(data.elementData, document2);
530
- const isPresent = el ? await isVisible(el) : false;
531
- const isDisabled = el ? el.disabled : false;
532
- switch (data.logic) {
533
- case import_types.ElementConditionLogic.PRESENT:
534
- return isPresent;
535
- case import_types.ElementConditionLogic.UNPRESENT:
536
- return !isPresent;
537
- case import_types.ElementConditionLogic.DISABLED:
538
- return el && isDisabled;
539
- case import_types.ElementConditionLogic.UNDISABLED:
540
- return el && !isDisabled;
541
- case import_types.ElementConditionLogic.CLICKED:
542
- return el && isClicked(el);
543
- case import_types.ElementConditionLogic.UNCLICKED:
544
- return el && !isClicked(el);
545
- default:
546
- return false;
547
- }
548
- };
549
- var isActiveRulesByTextInput = async (rules) => {
550
- const {
551
- data: { elementData, logic, value }
552
- } = rules;
553
- if (!document2) {
554
- return false;
555
- }
556
- const el = finderV2(elementData, document2);
557
- if (!el) {
558
- return false;
559
- }
560
- const elValue = el.value;
561
- switch (logic) {
562
- case import_types.StringConditionLogic.IS:
563
- return elValue === value;
564
- case import_types.StringConditionLogic.NOT:
565
- return elValue !== value;
566
- case import_types.StringConditionLogic.CONTAINS:
567
- return elValue.includes(value);
568
- case import_types.StringConditionLogic.NOT_CONTAIN:
569
- return !elValue.includes(value);
570
- case import_types.StringConditionLogic.STARTS_WITH:
571
- return elValue.startsWith(value);
572
- case import_types.StringConditionLogic.ENDS_WITH:
573
- return elValue.endsWith(value);
574
- case import_types.StringConditionLogic.MATCH:
575
- return elValue.search(value) !== -1;
576
- case import_types.StringConditionLogic.UNMATCH:
577
- return elValue.search(value) === -1;
578
- case import_types.StringConditionLogic.ANY:
579
- return true;
580
- case import_types.StringConditionLogic.EMPTY:
581
- return !elValue;
582
- default:
583
- return false;
584
- }
585
- };
586
- var fillCache = /* @__PURE__ */ new Map();
587
- var isActiveRulesByTextFill = async (rules) => {
588
- const {
589
- data: { elementData }
590
- } = rules;
591
- if (!document2) {
592
- return false;
593
- }
594
- const el = finderV2(elementData, document2);
595
- if (!el) {
596
- return false;
597
- }
598
- const now = (/* @__PURE__ */ new Date()).getTime();
599
- const onKeyup = () => {
600
- const cacheData = fillCache.get(el);
601
- const data = { ...cacheData, timestamp: (/* @__PURE__ */ new Date()).getTime() };
602
- fillCache.set(el, data);
603
- };
604
- if (fillCache.has(el)) {
605
- const { timestamp, value, isActive: isActive2 } = fillCache.get(el);
606
- if (isActive2) {
607
- return true;
608
- }
609
- if (timestamp !== -1 && now - timestamp > 1e3 && value !== el.value) {
610
- off(document2, "click", onKeyup);
611
- fillCache.set(el, { timestamp, value, isActive: true });
612
- return true;
613
- }
614
- return false;
615
- }
616
- on(document2, "keyup", onKeyup);
617
- fillCache.set(el, { timestamp: -1, value: el.value, isActive: false });
618
- return false;
619
- };
620
- var isValidRulesType = (type) => {
621
- return rulesTypes.includes(type);
622
- };
623
- var isActiveRules = async (rules) => {
624
- if (!isValidRulesType(rules.type)) {
625
- return true;
626
- }
627
- switch (rules.type) {
628
- case import_types.RulesType.CURRENT_PAGE:
629
- return isActiveRulesByCurrentPage(rules);
630
- case import_types.RulesType.TIME:
631
- return isActiveRulesByCurrentTime(rules);
632
- case import_types.RulesType.ELEMENT:
633
- return await isActiveRulesByElement(rules);
634
- case import_types.RulesType.TEXT_INPUT:
635
- return await isActiveRulesByTextInput(rules);
636
- case import_types.RulesType.TEXT_FILL:
637
- return await isActiveRulesByTextFill(rules);
638
- default:
639
- return rules.actived;
640
- }
641
- };
642
- var activedRulesConditions = async (conditions, rewrite) => {
643
- const rulesCondition = [...conditions];
644
- for (let j = 0; j < rulesCondition.length; j++) {
645
- const rules = rulesCondition[j];
646
- if (rules.type !== "group") {
647
- if (rewrite == null ? void 0 : rewrite[rules.type]) {
648
- rulesCondition[j].actived = true;
649
- } else {
650
- rulesCondition[j].actived = await isActiveRules(rules);
651
- }
652
- } else if (rules.conditions) {
653
- rulesCondition[j].conditions = await activedRulesConditions(rules.conditions);
654
- }
655
- }
656
- return rulesCondition;
657
- };
658
- var activedContentRulesConditions = async (conditions, contents) => {
659
- const rulesCondition = [...conditions];
660
- for (let j = 0; j < rulesCondition.length; j++) {
661
- const rules = rulesCondition[j];
662
- if (rules.type !== "group") {
663
- if (rules.type === import_types.RulesType.CONTENT) {
664
- const content = contents.find((c) => c.contentId === rules.data.contentId);
665
- if (content) {
666
- const contentSession = {
667
- contentId: content.contentId,
668
- latestSession: content.latestSession,
669
- totalSessions: content.totalSessions,
670
- dismissedSessions: content.dismissedSessions,
671
- completedSessions: content.completedSessions,
672
- seenSessions: content.seenSessions
673
- };
674
- rulesCondition[j].actived = isActivedContentRulesCondition(rules, contentSession);
675
- }
676
- }
677
- } else if (rules.conditions) {
678
- rulesCondition[j].conditions = await activedContentRulesConditions(
679
- rules.conditions,
680
- contents
681
- );
682
- }
683
- }
684
- return rulesCondition;
685
- };
686
- var activedContentCondition = async (contents) => {
687
- const _contents = JSON.parse(JSON.stringify(contents));
688
- for (let index = 0; index < _contents.length; index++) {
689
- const content = _contents[index];
690
- const { enabledAutoStartRules, autoStartRules, hideRules, enabledHideRules } = content.config;
691
- if (enabledAutoStartRules && autoStartRules && autoStartRules.length > 0) {
692
- content.config.autoStartRules = await activedRulesConditions(autoStartRules);
693
- }
694
- if (enabledHideRules && hideRules && hideRules.length > 0) {
695
- content.config.hideRules = await activedRulesConditions(hideRules);
696
- }
697
- }
698
- return _contents;
699
- };
700
- var isActive = (autoStartRules) => {
701
- if (!autoStartRules || autoStartRules.length === 0) {
702
- return false;
703
- }
704
- const operator = autoStartRules[0].operators;
705
- const actives = autoStartRules.filter((rule) => {
706
- if (!rule.conditions) {
707
- return rule.actived;
708
- }
709
- return isActive(rule.conditions);
710
- });
711
- return operator === "and" ? actives.length === autoStartRules.length : actives.length > 0;
712
- };
713
- var isActiveContent = (content) => {
714
- const { enabledAutoStartRules, autoStartRules } = content.config;
715
- if (!enabledAutoStartRules || !isActive(autoStartRules)) {
716
- return false;
717
- }
718
- return true;
719
- };
720
- var priorityCompare = (a, b) => {
721
- var _a, _b, _c, _d;
722
- const a1 = (_b = (_a = a == null ? void 0 : a.config) == null ? void 0 : _a.autoStartRulesSetting) == null ? void 0 : _b.priority;
723
- const a2 = (_d = (_c = b == null ? void 0 : b.config) == null ? void 0 : _c.autoStartRulesSetting) == null ? void 0 : _d.priority;
724
- if (!a1 || !a2) {
725
- return 0;
726
- }
727
- const index1 = PRIORITIES.indexOf(a1);
728
- const index2 = PRIORITIES.indexOf(a2);
729
- if (index1 > index2) {
730
- return 1;
731
- }
732
- if (index1 < index2) {
733
- return -1;
734
- }
735
- return 0;
736
- };
737
- var filterAutoStartContent = (contents, type) => {
738
- return contents.filter((content) => {
739
- const isActive2 = isActiveContent(content);
740
- const isValid = isValidContent(content, contents);
741
- return content.type === type && isActive2 && isValid;
742
- }).sort(priorityCompare);
743
- };
744
- var isHasActivedContents = (source, dest) => {
745
- for (let index = 0; index < source.length; index++) {
746
- const content1 = source[index];
747
- const content2 = dest.find((c) => c.id === content1.id);
748
- if (!content2) {
749
- return true;
750
- }
751
- if (isActiveContent(content1) !== isActiveContent(content2)) {
752
- return true;
753
- }
754
- }
755
- return false;
756
- };
757
- var isSameContents = (source, dest) => {
758
- if (!source || !dest || source.length !== dest.length) {
759
- return false;
760
- }
761
- for (let index = 0; index < source.length; index++) {
762
- const content1 = source[index];
763
- const content2 = dest.find((c) => c.id === content1.id);
764
- if (!content2) {
765
- return false;
766
- }
767
- if (!conditionsIsSame(content1.config.autoStartRules, content2.config.autoStartRules)) {
768
- return false;
769
- }
770
- }
771
- return true;
772
- };
773
- var getLatestEvent = (currentContent, contents, eventCodeName) => {
774
- var _a;
775
- const bizEvents = [];
776
- const contentId = currentContent.id;
777
- const contentType = currentContent.type;
778
- for (let index = 0; index < contents.length; index++) {
779
- const content = contents[index];
780
- if (content.id === contentId || content.type !== contentType) {
781
- continue;
782
- }
783
- const sessionBizEvents = (_a = content.latestSession) == null ? void 0 : _a.bizEvent;
784
- if (sessionBizEvents && sessionBizEvents.length > 0) {
785
- bizEvents.push(...sessionBizEvents.filter((e) => {
786
- var _a2;
787
- return ((_a2 = e == null ? void 0 : e.event) == null ? void 0 : _a2.codeName) === eventCodeName;
788
- }));
789
- }
790
- }
791
- return findLatestEvent(bizEvents);
792
- };
793
- var findLatestEvent = (bizEvents) => {
794
- const initialValue = bizEvents[0];
795
- const lastEvent = bizEvents.reduce(
796
- (accumulator, currentValue) => {
797
- if ((0, import_date_fns.isAfter)(new Date(currentValue.createdAt), new Date(accumulator.createdAt))) {
798
- return currentValue;
799
- }
800
- return accumulator;
801
- },
802
- initialValue
803
- );
804
- return lastEvent;
805
- };
806
- var showEventMapping = {
807
- [import_types.ContentDataType.FLOW]: import_types.BizEvents.FLOW_STEP_SEEN,
808
- [import_types.ContentDataType.LAUNCHER]: import_types.BizEvents.LAUNCHER_SEEN,
809
- [import_types.ContentDataType.CHECKLIST]: import_types.BizEvents.CHECKLIST_SEEN
810
- };
811
- var isGreaterThenDuration = (dateLeft, dateRight, unit, duration) => {
812
- switch (unit) {
813
- case import_types.FrequencyUnits.SECONDS: {
814
- if ((0, import_date_fns.differenceInSeconds)(dateLeft, dateRight) >= duration) {
815
- return true;
816
- }
817
- return false;
818
- }
819
- case import_types.FrequencyUnits.MINUTES:
820
- if ((0, import_date_fns.differenceInMinutes)(dateLeft, dateRight) >= duration) {
821
- return true;
822
- }
823
- return false;
824
- case import_types.FrequencyUnits.HOURS:
825
- if ((0, import_date_fns.differenceInHours)(dateLeft, dateRight) >= duration) {
826
- return true;
827
- }
828
- return false;
829
- case import_types.FrequencyUnits.DAYES:
830
- if ((0, import_date_fns.differenceInDays)(dateLeft, dateRight) >= duration) {
831
- return true;
832
- }
833
- return false;
834
- default:
835
- return false;
836
- }
837
- };
838
- var checklistIsDimissed = (latestSession) => {
839
- var _a;
840
- return (_a = latestSession == null ? void 0 : latestSession.bizEvent) == null ? void 0 : _a.find(
841
- (event) => {
842
- var _a2;
843
- return ((_a2 = event == null ? void 0 : event.event) == null ? void 0 : _a2.codeName) === import_types.BizEvents.CHECKLIST_DISMISSED;
844
- }
845
- );
846
- };
847
- var flowIsDismissed = (latestSession) => {
848
- var _a;
849
- return (_a = latestSession == null ? void 0 : latestSession.bizEvent) == null ? void 0 : _a.find((event) => {
850
- var _a2;
851
- return ((_a2 = event == null ? void 0 : event.event) == null ? void 0 : _a2.codeName) === import_types.BizEvents.FLOW_ENDED;
852
- });
853
- };
854
- var flowIsSeen = (latestSession) => {
855
- var _a;
856
- return (_a = latestSession == null ? void 0 : latestSession.bizEvent) == null ? void 0 : _a.find(
857
- (event) => {
858
- var _a2;
859
- return ((_a2 = event == null ? void 0 : event.event) == null ? void 0 : _a2.codeName) === import_types.BizEvents.FLOW_STEP_SEEN;
860
- }
861
- );
862
- };
863
- var checklistIsSeen = (latestSession) => {
864
- var _a;
865
- return (_a = latestSession == null ? void 0 : latestSession.bizEvent) == null ? void 0 : _a.find(
866
- (event) => {
867
- var _a2;
868
- return ((_a2 = event == null ? void 0 : event.event) == null ? void 0 : _a2.codeName) === import_types.BizEvents.CHECKLIST_SEEN;
869
- }
870
- );
871
- };
872
- var isValidContent = (content, contents) => {
873
- var _a;
874
- const now = /* @__PURE__ */ new Date();
875
- if (content.type === import_types.ContentDataType.FLOW) {
876
- if (!content.steps || content.steps.length === 0) {
877
- return false;
878
- }
879
- } else {
880
- if (!content.data) {
881
- return false;
882
- }
883
- }
884
- if (!content.config.autoStartRulesSetting) {
885
- return true;
886
- }
887
- const { frequency, startIfNotComplete } = content.config.autoStartRulesSetting;
888
- const completedSessions = content.completedSessions;
889
- const dismissedSessions = content.dismissedSessions;
890
- if (startIfNotComplete && completedSessions > 0) {
891
- return false;
892
- }
893
- if (!frequency) {
894
- return true;
895
- }
896
- const contentType = content.type;
897
- const lastEventName = showEventMapping[contentType];
898
- const lastEvent = getLatestEvent(content, contents, lastEventName);
899
- const contentEvents = (_a = content.latestSession) == null ? void 0 : _a.bizEvent;
900
- if (lastEvent && frequency && frequency.atLeast && !isGreaterThenDuration(
901
- now,
902
- new Date(lastEvent.createdAt),
903
- frequency.atLeast.unit,
904
- frequency.atLeast.duration
905
- )) {
906
- return false;
907
- }
908
- if (frequency.frequency === import_types.Frequency.ONCE) {
909
- if (dismissedSessions > 0) {
910
- return false;
911
- }
912
- return true;
913
- }
914
- const showEventName = showEventMapping[contentType];
915
- const showEvents = contentEvents == null ? void 0 : contentEvents.filter(
916
- (e) => {
917
- var _a2, _b;
918
- return ((_a2 = e == null ? void 0 : e.event) == null ? void 0 : _a2.codeName) === showEventName && (contentType === import_types.ContentDataType.FLOW ? ((_b = e == null ? void 0 : e.data) == null ? void 0 : _b.flow_step_number) === 0 : true);
919
- }
920
- );
921
- if (!showEvents || showEvents.length === 0) {
922
- return true;
923
- }
924
- const lastShowEvent = findLatestEvent(showEvents);
925
- const lastShowEventDate = new Date(lastShowEvent.createdAt);
926
- if (frequency.frequency === import_types.Frequency.MULTIPLE) {
927
- if (frequency.every.times && dismissedSessions >= frequency.every.times) {
928
- return false;
929
- }
930
- }
931
- if (frequency.frequency === import_types.Frequency.MULTIPLE || frequency.frequency === import_types.Frequency.UNLIMITED) {
932
- if (!isGreaterThenDuration(now, lastShowEventDate, frequency.every.unit, frequency.every.duration)) {
933
- return false;
934
- }
935
- }
936
- return true;
937
- };
938
- var parseUrlParams = (url, paramName) => {
939
- if (!url || !paramName) {
940
- return null;
941
- }
942
- try {
943
- const urlObj = new URL(url);
944
- const searchParams = new URLSearchParams(urlObj.search);
945
- if (searchParams.has(paramName)) {
946
- return searchParams.get(paramName);
947
- }
948
- if (urlObj.hash) {
949
- const hashSearch = urlObj.hash.split("?")[1];
950
- if (hashSearch) {
951
- const hashParams = new URLSearchParams(hashSearch);
952
- if (hashParams.has(paramName)) {
953
- return hashParams.get(paramName);
954
- }
955
- }
956
- }
957
- return null;
958
- } catch (error) {
959
- console.error("Error parsing URL:", error);
960
- return null;
961
- }
962
- };
963
- var wait = (seconds) => {
964
- if (typeof seconds !== "number" || Number.isNaN(seconds)) {
965
- return Promise.reject(new Error("Invalid wait time: must be a number"));
966
- }
967
- if (seconds < 0) {
968
- return Promise.reject(new Error("Invalid wait time: cannot be negative"));
969
- }
970
- if (seconds === 0) {
971
- return Promise.resolve();
972
- }
973
- return new Promise((resolve, reject) => {
974
- try {
975
- setTimeout(resolve, seconds * 1e3);
976
- } catch (error) {
977
- reject(error);
978
- }
979
- });
980
- };
981
- // Annotate the CommonJS export names for ESM import in node:
982
- 0 && (module.exports = {
983
- PRIORITIES,
984
- activedContentCondition,
985
- activedContentRulesConditions,
986
- activedRulesConditions,
987
- checklistIsDimissed,
988
- checklistIsSeen,
989
- filterAutoStartContent,
990
- findLatestEvent,
991
- flowIsDismissed,
992
- flowIsSeen,
993
- isActive,
994
- isActiveContent,
995
- isHasActivedContents,
996
- isSameContents,
997
- isValidContent,
998
- isVisible,
999
- parseUrlParams,
1000
- wait
1001
- });