@usertour/helpers 0.0.6 → 0.0.8

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
@@ -58,11 +58,14 @@ __export(src_exports, {
58
58
  deepClone: () => deepClone,
59
59
  defaultContentConfig: () => defaultContentConfig,
60
60
  defaultStep: () => defaultStep,
61
- document: () => document,
61
+ document: () => document2,
62
62
  evalCode: () => evalCode,
63
63
  fetch: () => fetch,
64
64
  filterAutoStartContent: () => filterAutoStartContent,
65
65
  findLatestEvent: () => findLatestEvent,
66
+ finder: () => finder,
67
+ finderV2: () => finderV2,
68
+ finderX: () => finderX,
66
69
  flowIsDismissed: () => flowIsDismissed,
67
70
  flowIsSeen: () => flowIsSeen,
68
71
  formatDate: () => formatDate,
@@ -122,6 +125,8 @@ __export(src_exports, {
122
125
  nativeIndexOf: () => nativeIndexOf,
123
126
  navigator: () => navigator,
124
127
  parseUrlParams: () => parseUrlParams,
128
+ parserV2: () => parserV2,
129
+ parserX: () => parserX,
125
130
  removeAuthToken: () => removeAuthToken,
126
131
  setAuthToken: () => setAuthToken,
127
132
  storage: () => storage,
@@ -831,7 +836,7 @@ var ArrayProto = Array.prototype;
831
836
  var nativeForEach = ArrayProto.forEach;
832
837
  var nativeIndexOf = ArrayProto.indexOf;
833
838
  var navigator = global == null ? void 0 : global.navigator;
834
- var document = global == null ? void 0 : global.document;
839
+ var document2 = global == null ? void 0 : global.document;
835
840
  var location = global == null ? void 0 : global.location;
836
841
  var fetch = global == null ? void 0 : global.fetch;
837
842
  var XMLHttpRequest = (global == null ? void 0 : global.XMLHttpRequest) && "withCredentials" in new global.XMLHttpRequest() ? global.XMLHttpRequest : void 0;
@@ -1394,7 +1399,319 @@ var JWTLicenseValidator = {
1394
1399
 
1395
1400
  // src/conditions.ts
1396
1401
  var import_dom = require("@floating-ui/dom");
1397
- var import_finder = require("@usertour-packages/finder");
1402
+
1403
+ // src/finderx.ts
1404
+ var import_finder = require("@medv/finder");
1405
+ var finderAttrs = [
1406
+ "data-for",
1407
+ "data-id",
1408
+ "data-testid",
1409
+ "data-test-id",
1410
+ "for",
1411
+ "id",
1412
+ "name",
1413
+ "placeholder",
1414
+ "role"
1415
+ ];
1416
+ var defaultConfig = {
1417
+ idName: () => false,
1418
+ className: () => false,
1419
+ tagName: () => false,
1420
+ attr: () => false,
1421
+ seedMinLength: 1,
1422
+ optimizedMinLength: 2,
1423
+ threshold: 1e3,
1424
+ maxNumberOfTries: 1e4
1425
+ };
1426
+ var finderConfigs = [
1427
+ {
1428
+ ...defaultConfig,
1429
+ tagName: () => true
1430
+ },
1431
+ {
1432
+ ...defaultConfig,
1433
+ idName: () => true
1434
+ },
1435
+ {
1436
+ ...defaultConfig,
1437
+ tagName: () => true,
1438
+ attr: (name) => finderAttrs.includes(name)
1439
+ },
1440
+ {
1441
+ ...defaultConfig,
1442
+ className: () => true,
1443
+ attr: (name) => finderAttrs.includes(name)
1444
+ },
1445
+ {
1446
+ ...defaultConfig,
1447
+ tagName: () => true,
1448
+ idName: () => true,
1449
+ className: () => true,
1450
+ attr: () => false
1451
+ },
1452
+ {
1453
+ ...defaultConfig,
1454
+ tagName: () => true,
1455
+ idName: () => true,
1456
+ className: () => true,
1457
+ attr: (name) => finderAttrs.includes(name)
1458
+ }
1459
+ ];
1460
+ function getMaxDepth(node) {
1461
+ if (node.parentNode) {
1462
+ return getMaxDepth(node.parentNode);
1463
+ }
1464
+ return node.depth;
1465
+ }
1466
+ function queryNodeListBySelectors(selectors, rootDocument, removeRepeat = true) {
1467
+ const nodes = [];
1468
+ if (!selectors) {
1469
+ return nodes;
1470
+ }
1471
+ for (const s of selectors) {
1472
+ const els = rootDocument.querySelectorAll(s.replace(/\\\\/g, "\\"));
1473
+ if (els && els.length > 0) {
1474
+ nodes.push(...Array.from(els));
1475
+ }
1476
+ }
1477
+ return removeRepeat ? [...new Set(nodes)] : nodes;
1478
+ }
1479
+ function findMostRecurringNode(nodes) {
1480
+ const m = /* @__PURE__ */ new Map();
1481
+ let finalNode = nodes[0];
1482
+ let count = 0;
1483
+ for (const node of nodes) {
1484
+ const i = m.get(node) ? m.get(node) + 1 : 1;
1485
+ m.set(node, i);
1486
+ }
1487
+ m.forEach((value, key) => {
1488
+ if (value > count) {
1489
+ count = value;
1490
+ finalNode = key;
1491
+ }
1492
+ });
1493
+ return finalNode;
1494
+ }
1495
+ function compareParentNode(node, el, rootDocument, isCompareSibings = false) {
1496
+ let nodeParentNode = node.parentNode;
1497
+ let elParentElement = el.parentElement;
1498
+ const maxDepth = getMaxDepth(node);
1499
+ const xresult = {
1500
+ maxDepth,
1501
+ failedDepth: 0,
1502
+ success: true
1503
+ };
1504
+ while (nodeParentNode && elParentElement) {
1505
+ if (elParentElement === rootDocument) {
1506
+ break;
1507
+ }
1508
+ if (elParentElement === document.body || elParentElement === document.documentElement || elParentElement.parentElement === document.body) {
1509
+ break;
1510
+ }
1511
+ const parentNodes = queryNodeListBySelectors(nodeParentNode.selectors, rootDocument);
1512
+ const isMatchSibings = isCompareSibings ? compareSibingsNode(nodeParentNode, elParentElement, rootDocument) : true;
1513
+ if (!parentNodes || parentNodes.length === 0 || !parentNodes.includes(elParentElement) || !isMatchSibings) {
1514
+ xresult.failedDepth = nodeParentNode.depth;
1515
+ xresult.success = false;
1516
+ }
1517
+ nodeParentNode = nodeParentNode.parentNode;
1518
+ elParentElement = elParentElement.parentElement;
1519
+ }
1520
+ return xresult;
1521
+ }
1522
+ function compareSibingsNode(node, el, rootDocument) {
1523
+ let isMatchNext = true;
1524
+ let isMatchPrevious = true;
1525
+ const { previousElementSelectors, nextElementSelectors } = node;
1526
+ if (nextElementSelectors && nextElementSelectors.length > 0) {
1527
+ const nextElementSiblings = queryNodeListBySelectors(nextElementSelectors, rootDocument);
1528
+ isMatchNext = el.nextElementSibling && nextElementSiblings.includes(el.nextElementSibling);
1529
+ }
1530
+ if (previousElementSelectors && previousElementSelectors.length > 0) {
1531
+ const previousElementSiblings = queryNodeListBySelectors(
1532
+ previousElementSelectors,
1533
+ rootDocument
1534
+ );
1535
+ isMatchPrevious = el.previousElementSibling && previousElementSiblings.includes(el.previousElementSibling);
1536
+ }
1537
+ return isMatchNext && isMatchPrevious;
1538
+ }
1539
+ function queryElementSelectors(input) {
1540
+ const classes = Array.from(input.classList);
1541
+ const selectors = [];
1542
+ const configs = [...finderConfigs];
1543
+ for (const className of classes) {
1544
+ configs.push({
1545
+ ...defaultConfig,
1546
+ className: (name) => {
1547
+ if (classes.filter((cn2) => cn2 !== className).includes(name)) {
1548
+ return false;
1549
+ }
1550
+ return true;
1551
+ }
1552
+ });
1553
+ }
1554
+ try {
1555
+ for (const cfg of configs) {
1556
+ selectors.push(finder(input, cfg));
1557
+ }
1558
+ } catch (_) {
1559
+ return selectors;
1560
+ }
1561
+ return [...new Set(selectors)];
1562
+ }
1563
+ function parseSelectorsTree(input, parentNode, depth = 0) {
1564
+ const selectors = queryElementSelectors(input);
1565
+ if (selectors.length === 0) {
1566
+ return parentNode;
1567
+ }
1568
+ const currentNode = {
1569
+ previousElementSelectors: [],
1570
+ nextElementSelectors: [],
1571
+ selectors,
1572
+ depth
1573
+ };
1574
+ if (input.previousElementSibling) {
1575
+ currentNode.previousElementSelectors = queryElementSelectors(input.previousElementSibling);
1576
+ }
1577
+ if (input.nextElementSibling) {
1578
+ currentNode.nextElementSelectors = queryElementSelectors(input.nextElementSibling);
1579
+ }
1580
+ if (parentNode === null) {
1581
+ if (input.parentElement) {
1582
+ parseSelectorsTree(input.parentElement, currentNode, depth + 1);
1583
+ }
1584
+ return currentNode;
1585
+ }
1586
+ parentNode.parentNode = currentNode;
1587
+ if (input.parentElement) {
1588
+ parseSelectorsTree(input.parentElement, currentNode, depth + 1);
1589
+ }
1590
+ return parentNode;
1591
+ }
1592
+ function finderMostPrecisionElement(elements, node, rootDocument, precision) {
1593
+ const successEls = [];
1594
+ let failedData = {
1595
+ el: null,
1596
+ failedDepth: 0,
1597
+ maxDepth: 0
1598
+ };
1599
+ for (const el of elements) {
1600
+ const { success, failedDepth, maxDepth } = compareParentNode(node, el, rootDocument);
1601
+ if (success) {
1602
+ successEls.push(el);
1603
+ } else if (!failedData.el || failedDepth > failedData.failedDepth) {
1604
+ failedData = { el, failedDepth, maxDepth };
1605
+ }
1606
+ }
1607
+ if (successEls.length === 1) {
1608
+ return successEls[0];
1609
+ }
1610
+ if (successEls.length > 1) {
1611
+ let tempEl = successEls[0];
1612
+ let tempFailedDepth = 0;
1613
+ for (const el of successEls) {
1614
+ const { success, failedDepth } = compareParentNode(node, el, rootDocument, true);
1615
+ if (success) {
1616
+ return el;
1617
+ }
1618
+ if (failedDepth > tempFailedDepth) {
1619
+ tempFailedDepth = failedDepth;
1620
+ tempEl = el;
1621
+ }
1622
+ }
1623
+ return tempEl;
1624
+ }
1625
+ if (failedData.el) {
1626
+ const { failedDepth, maxDepth, el } = failedData;
1627
+ const rate = (failedDepth - 1) / maxDepth * 10;
1628
+ if (rate >= precision) {
1629
+ return el;
1630
+ }
1631
+ }
1632
+ return null;
1633
+ }
1634
+ function finder(input, options) {
1635
+ return (0, import_finder.finder)(input, options);
1636
+ }
1637
+ function parserX(input) {
1638
+ return parseSelectorsTree(input, null);
1639
+ }
1640
+ function parserV2(element) {
1641
+ var _a;
1642
+ const content = (_a = element.innerText) != null ? _a : "";
1643
+ const selectors = parseSelectorsTree(element, null);
1644
+ const selectorsList = queryElementSelectors(element);
1645
+ return { content, selectors, selectorsList };
1646
+ }
1647
+ function finderV2(target, root) {
1648
+ const {
1649
+ selectors,
1650
+ content = "",
1651
+ sequence = 0,
1652
+ precision = "strict",
1653
+ isDynamicContent = false,
1654
+ customSelector = "",
1655
+ type = "auto"
1656
+ } = target;
1657
+ if (type === "auto") {
1658
+ const mapping = {
1659
+ looser: 1,
1660
+ loose: 3,
1661
+ loosest: 5,
1662
+ strict: 7,
1663
+ stricter: 8,
1664
+ strictest: 10
1665
+ };
1666
+ const el = finderX(selectors, root, mapping[precision]);
1667
+ if (el) {
1668
+ if (isDynamicContent && content && el.innerText !== content) {
1669
+ return null;
1670
+ }
1671
+ return el;
1672
+ }
1673
+ } else {
1674
+ const sequenceMapping = {
1675
+ "1st": 0,
1676
+ "2st": 1,
1677
+ "3st": 2,
1678
+ "4st": 3,
1679
+ "5st": 4
1680
+ };
1681
+ if (customSelector) {
1682
+ const selector = customSelector.replace(/\\\\/g, "\\");
1683
+ const els = root.querySelectorAll(selector);
1684
+ if (els.length > 0) {
1685
+ const el = els[sequenceMapping[sequence]] || els[0];
1686
+ if (content && el.innerText.trim() !== content) {
1687
+ return null;
1688
+ }
1689
+ return el;
1690
+ }
1691
+ }
1692
+ }
1693
+ return null;
1694
+ }
1695
+ function finderX(node, root, precision = 10) {
1696
+ if (!node || node.selectors.length === 0) {
1697
+ return null;
1698
+ }
1699
+ const rootDocument = root || document;
1700
+ const elements = [];
1701
+ const nodeList = queryNodeListBySelectors(node.selectors, rootDocument, false);
1702
+ if (!nodeList || nodeList.length === 0) {
1703
+ return null;
1704
+ }
1705
+ if ([...new Set(nodeList)].length !== nodeList.length) {
1706
+ const el = findMostRecurringNode(nodeList);
1707
+ elements.push(el);
1708
+ } else {
1709
+ elements.push(...nodeList);
1710
+ }
1711
+ return finderMostPrecisionElement(elements, node, rootDocument, precision);
1712
+ }
1713
+
1714
+ // src/conditions.ts
1398
1715
  var import_types4 = require("@usertour/types");
1399
1716
  var import_date_fns = require("date-fns");
1400
1717
 
@@ -1462,10 +1779,10 @@ var isActivedContentRulesCondition = (rules, contentSession) => {
1462
1779
  };
1463
1780
  var isVisible = async (el) => {
1464
1781
  var _a, _b;
1465
- if (!((_a = document) == null ? void 0 : _a.body)) {
1782
+ if (!((_a = document2) == null ? void 0 : _a.body)) {
1466
1783
  return false;
1467
1784
  }
1468
- const { middlewareData } = await (0, import_dom.computePosition)(el, document.body, {
1785
+ const { middlewareData } = await (0, import_dom.computePosition)(el, document2.body, {
1469
1786
  strategy: "fixed",
1470
1787
  middleware: [(0, import_dom.hide)()]
1471
1788
  });
@@ -1489,10 +1806,10 @@ var isClicked = (el) => {
1489
1806
  };
1490
1807
  var isActiveRulesByElement = async (rules) => {
1491
1808
  const { data } = rules;
1492
- if (!document) {
1809
+ if (!document2) {
1493
1810
  return false;
1494
1811
  }
1495
- const el = (0, import_finder.finderV2)(data.elementData, document);
1812
+ const el = finderV2(data.elementData, document2);
1496
1813
  const isPresent = el ? await isVisible(el) : false;
1497
1814
  const isDisabled = el ? el.disabled : false;
1498
1815
  switch (data.logic) {
@@ -1516,10 +1833,10 @@ var isActiveRulesByTextInput = async (rules) => {
1516
1833
  const {
1517
1834
  data: { elementData, logic, value }
1518
1835
  } = rules;
1519
- if (!document) {
1836
+ if (!document2) {
1520
1837
  return false;
1521
1838
  }
1522
- const el = (0, import_finder.finderV2)(elementData, document);
1839
+ const el = finderV2(elementData, document2);
1523
1840
  if (!el) {
1524
1841
  return false;
1525
1842
  }
@@ -1554,10 +1871,10 @@ var isActiveRulesByTextFill = async (rules) => {
1554
1871
  const {
1555
1872
  data: { elementData }
1556
1873
  } = rules;
1557
- if (!document) {
1874
+ if (!document2) {
1558
1875
  return false;
1559
1876
  }
1560
- const el = (0, import_finder.finderV2)(elementData, document);
1877
+ const el = finderV2(elementData, document2);
1561
1878
  if (!el) {
1562
1879
  return false;
1563
1880
  }
@@ -1573,13 +1890,13 @@ var isActiveRulesByTextFill = async (rules) => {
1573
1890
  return true;
1574
1891
  }
1575
1892
  if (timestamp !== -1 && now - timestamp > 1e3 && value !== el.value) {
1576
- off(document, "click", onKeyup);
1893
+ off(document2, "click", onKeyup);
1577
1894
  fillCache.set(el, { timestamp, value, isActive: true });
1578
1895
  return true;
1579
1896
  }
1580
1897
  return false;
1581
1898
  }
1582
- on(document, "keyup", onKeyup);
1899
+ on(document2, "keyup", onKeyup);
1583
1900
  fillCache.set(el, { timestamp: -1, value: el.value, isActive: false });
1584
1901
  return false;
1585
1902
  };
@@ -1974,6 +2291,9 @@ var wait = (seconds) => {
1974
2291
  fetch,
1975
2292
  filterAutoStartContent,
1976
2293
  findLatestEvent,
2294
+ finder,
2295
+ finderV2,
2296
+ finderX,
1977
2297
  flowIsDismissed,
1978
2298
  flowIsSeen,
1979
2299
  formatDate,
@@ -2033,6 +2353,8 @@ var wait = (seconds) => {
2033
2353
  nativeIndexOf,
2034
2354
  navigator,
2035
2355
  parseUrlParams,
2356
+ parserV2,
2357
+ parserX,
2036
2358
  removeAuthToken,
2037
2359
  setAuthToken,
2038
2360
  storage,
package/dist/index.d.cts CHANGED
@@ -14,6 +14,7 @@ export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb,
14
14
  export { GenerateLicenseOptions, JWTLicenseSigner, JWTLicenseSignerOptions } from './jwt-license-signer.cjs';
15
15
  export { JWTLicenseValidator } from './jwt-license-validator.cjs';
16
16
  export { PRIORITIES, activedContentCondition, activedContentRulesConditions, activedRulesConditions, checklistIsDimissed, checklistIsSeen, filterAutoStartContent, findLatestEvent, flowIsDismissed, flowIsSeen, isActive, isActiveContent, isHasActivedContents, isSameContents, isValidContent, isVisible, parseUrlParams, wait } from './conditions.cjs';
17
+ export { Options, Target, TargetResult, XData, XNode, XResult, finder, finderV2, finderX, parserV2, parserX } from './finderx.cjs';
17
18
  export { default as isEqual } from 'fast-deep-equal';
18
19
  import '@usertour/types';
19
20
  import './storage.cjs';
package/dist/index.d.ts CHANGED
@@ -14,6 +14,7 @@ export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb,
14
14
  export { GenerateLicenseOptions, JWTLicenseSigner, JWTLicenseSignerOptions } from './jwt-license-signer.js';
15
15
  export { JWTLicenseValidator } from './jwt-license-validator.js';
16
16
  export { PRIORITIES, activedContentCondition, activedContentRulesConditions, activedRulesConditions, checklistIsDimissed, checklistIsSeen, filterAutoStartContent, findLatestEvent, flowIsDismissed, flowIsSeen, isActive, isActiveContent, isHasActivedContents, isSameContents, isValidContent, isVisible, parseUrlParams, wait } from './conditions.js';
17
+ export { Options, Target, TargetResult, XData, XNode, XResult, finder, finderV2, finderX, parserV2, parserX } from './finderx.js';
17
18
  export { default as isEqual } from 'fast-deep-equal';
18
19
  import '@usertour/types';
19
20
  import './storage.js';
package/dist/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ import {
2
+ defaultStep
3
+ } from "./chunk-FW54TSA3.js";
1
4
  import {
2
5
  deepClone
3
6
  } from "./chunk-2AEGAICC.js";
@@ -21,9 +24,6 @@ import {
21
24
  import {
22
25
  JWTLicenseValidator
23
26
  } from "./chunk-Y5PCSFVZ.js";
24
- import {
25
- defaultStep
26
- } from "./chunk-FW54TSA3.js";
27
27
  import {
28
28
  getAuthToken,
29
29
  removeAuthToken,
@@ -50,7 +50,14 @@ import {
50
50
  isVisible,
51
51
  parseUrlParams,
52
52
  wait
53
- } from "./chunk-OASNBRBF.js";
53
+ } from "./chunk-7IK5Q5N2.js";
54
+ import {
55
+ finder,
56
+ finderV2,
57
+ finderX,
58
+ parserV2,
59
+ parserX
60
+ } from "./chunk-DEG6MTU7.js";
54
61
  import "./chunk-Y6FPPOKF.js";
55
62
  import {
56
63
  AbortController,
@@ -156,6 +163,9 @@ export {
156
163
  fetch,
157
164
  filterAutoStartContent,
158
165
  findLatestEvent,
166
+ finder,
167
+ finderV2,
168
+ finderX,
159
169
  flowIsDismissed,
160
170
  flowIsSeen,
161
171
  formatDate,
@@ -215,6 +225,8 @@ export {
215
225
  nativeIndexOf,
216
226
  navigator,
217
227
  parseUrlParams,
228
+ parserV2,
229
+ parserX,
218
230
  removeAuthToken,
219
231
  setAuthToken,
220
232
  storage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usertour/helpers",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "type": "module",
5
5
  "description": "Utility functions and helpers shared across the UserTour project",
6
6
  "homepage": "https://www.usertour.io",
@@ -26,26 +26,26 @@
26
26
  "prepublishOnly": "pnpm build"
27
27
  },
28
28
  "dependencies": {
29
+ "@floating-ui/dom": "^1.4.4",
30
+ "@medv/finder": "^3.1.0",
31
+ "@paralleldrive/cuid2": "^2.2.2",
32
+ "@types/jsonwebtoken": "^9.0.10",
29
33
  "@usertour/types": "^0.0.5",
30
- "fast-deep-equal": "^3.1.3",
31
34
  "chroma-js": "^3.1.2",
32
- "deepmerge-ts": "^7.1.3",
33
- "@paralleldrive/cuid2": "^2.2.2",
34
35
  "class-variance-authority": "^0.4.0",
35
36
  "clsx": "^1.2.1",
36
- "tailwind-merge": "^1.13.2",
37
- "jsonwebtoken": "^9.0.2",
38
- "@floating-ui/dom": "^1.4.4",
39
- "@types/jsonwebtoken": "^9.0.10",
40
- "@usertour-packages/finder": "workspace:^",
41
37
  "date-fns": "^2.30.0",
38
+ "deepmerge-ts": "^7.1.3",
39
+ "fast-deep-equal": "^3.1.3",
40
+ "jsonwebtoken": "^9.0.2",
41
+ "tailwind-merge": "^1.13.2",
42
42
  "uuid": "^9.0.1"
43
43
  },
44
44
  "devDependencies": {
45
- "@typescript-eslint/eslint-plugin": "^5.59.0",
46
- "@typescript-eslint/parser": "^5.59.0",
47
45
  "@types/chroma-js": "^3.1.1",
48
46
  "@types/uuid": "^9.0.6",
47
+ "@typescript-eslint/eslint-plugin": "^5.59.0",
48
+ "@typescript-eslint/parser": "^5.59.0",
49
49
  "eslint": "^8.38.0",
50
50
  "typescript": "^5.0.2"
51
51
  },