@coframe/sdk 1.1.56 → 1.1.59

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.
@@ -480,6 +480,10 @@ const getSelectorWithoutCache = (element, options) => {
480
480
  }
481
481
  return null;
482
482
  }
483
+ const ownId = (el) => {
484
+ const id = el.getAttribute('id');
485
+ return id && !isGeneratedIdentifier(id) ? id : undefined;
486
+ };
483
487
  const getParentNode = (element) => {
484
488
  return element.parentElement || getShadowHost(element);
485
489
  };
@@ -487,7 +491,7 @@ const getSelectorWithoutCache = (element, options) => {
487
491
  var _a;
488
492
  const selector = {
489
493
  t: el.tagName.toLowerCase(),
490
- id: el.getAttribute('id') || undefined,
494
+ id: ownId(el),
491
495
  text: getInnerText(el) || undefined,
492
496
  href: el.getAttribute('href') || undefined,
493
497
  dataTestId: el.getAttribute('data-test-id') || undefined,
@@ -572,12 +576,33 @@ const getElement = (selector, options) => {
572
576
  return null;
573
577
  };
574
578
  const resolvedPathCache = new Map();
579
+ const isGeneratedIdentifier = (value) => {
580
+ const token = value.trim();
581
+ if (!token)
582
+ return false;
583
+ const frameworkId = /^(?::r[0-9a-z]+:|«r[0-9a-z]+»|radix-:?r?[0-9a-z]+:?.*|headlessui-[a-z-]+-:?r?[0-9a-z]+:?|react-aria\d+.*|mui-\d+|ember\d+)$/;
584
+ const cssInJsClass = /^(?:css-[0-9a-z]{5,}(?:-[A-Za-z0-9]+)?|sc-[A-Za-z]{5,}|jsx-\d{6,}|[A-Za-z][A-Za-z0-9]*_[A-Za-z0-9]+__[A-Za-z0-9_-]{5})$/;
585
+ if (frameworkId.test(token) || cssInJsClass.test(token))
586
+ return true;
587
+ return token.split(/[-_:.]+/).some((segment) => {
588
+ var _a, _b;
589
+ if (/^\d{8,}$/.test(segment))
590
+ return true;
591
+ if (/^[0-9a-f]{6,}$/.test(segment) &&
592
+ /\d/.test(segment) &&
593
+ /[a-f]/.test(segment))
594
+ return true;
595
+ return (/^[0-9a-zA-Z]{8,}$/.test(segment) &&
596
+ ((_b = (_a = segment.match(/\d+|[a-zA-Z]+/g)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) >= 5);
597
+ });
598
+ };
599
+ const stableId = (id) => id && !isGeneratedIdentifier(id) ? id : undefined;
575
600
  const selectorKey = (selector) => selector.fingerprint || JSON.stringify(selector);
576
601
  const keepsIdentity = (document, element, selector) => {
577
602
  if (element.tagName.toLowerCase() !== selector.t.toLowerCase())
578
603
  return false;
579
604
  const attrs = [
580
- ['id', selector.id],
605
+ ['id', stableId(selector.id)],
581
606
  ['data-test-id', selector.dataTestId],
582
607
  ['aria-label', selector.ariaLabel],
583
608
  ];
@@ -843,7 +868,7 @@ const generateRelativePaths = (sel, max) => {
843
868
  const uniqueQueries = [];
844
869
  const nonUniqQueries = [];
845
870
  const newWipPaths = [];
846
- if (currentSel.id) {
871
+ if (currentSel.id && !isGeneratedIdentifier(currentSel.id)) {
847
872
  uniqueQueries.push({
848
873
  xpath: `[@id="${currentSel.id}"]`,
849
874
  css: `#${currentSel.id}`,
@@ -2506,6 +2531,7 @@ function isElementVisible(el) {
2506
2531
  }
2507
2532
  const VALUE_UNKNOWN_YET = 'n/a';
2508
2533
  function checkActivationCondition(condition, personalizationHeaders, currentUrl, languages, browserPlatform, userToken, userVisitCount, runJsFunction, logger, options) {
2534
+ var _a;
2509
2535
  if (condition.and) {
2510
2536
  const results = condition.and.map((c) => checkActivationCondition(c, personalizationHeaders, currentUrl, languages, browserPlatform, userToken, userVisitCount, runJsFunction, logger));
2511
2537
  const hasUnknown = results.some((r) => r === VALUE_UNKNOWN_YET);
@@ -2612,12 +2638,13 @@ function checkActivationCondition(condition, personalizationHeaders, currentUrl,
2612
2638
  }
2613
2639
  }
2614
2640
  }
2615
- if (condition.device) {
2616
- const isMobileDevice = personalizationHeaders['x-is-mobile-viewer'] === 'true';
2617
- if (condition.device.includes('mobile') && !isMobileDevice) {
2618
- return false;
2641
+ if ((_a = condition.device) === null || _a === void 0 ? void 0 : _a.length) {
2642
+ let device = personalizationHeaders['x-device-type'];
2643
+ if (!['desktop', 'mobile', 'tablet'].includes(device)) {
2644
+ device =
2645
+ personalizationHeaders['x-is-mobile-viewer'] === 'true' ? 'mobile' : '';
2619
2646
  }
2620
- if (condition.device.includes('desktop') && isMobileDevice) {
2647
+ if (!condition.device.includes(device)) {
2621
2648
  return false;
2622
2649
  }
2623
2650
  }
@@ -478,6 +478,10 @@ const getSelectorWithoutCache = (element, options) => {
478
478
  }
479
479
  return null;
480
480
  }
481
+ const ownId = (el) => {
482
+ const id = el.getAttribute('id');
483
+ return id && !isGeneratedIdentifier(id) ? id : undefined;
484
+ };
481
485
  const getParentNode = (element) => {
482
486
  return element.parentElement || getShadowHost(element);
483
487
  };
@@ -485,7 +489,7 @@ const getSelectorWithoutCache = (element, options) => {
485
489
  var _a;
486
490
  const selector = {
487
491
  t: el.tagName.toLowerCase(),
488
- id: el.getAttribute('id') || undefined,
492
+ id: ownId(el),
489
493
  text: getInnerText(el) || undefined,
490
494
  href: el.getAttribute('href') || undefined,
491
495
  dataTestId: el.getAttribute('data-test-id') || undefined,
@@ -570,12 +574,33 @@ const getElement = (selector, options) => {
570
574
  return null;
571
575
  };
572
576
  const resolvedPathCache = new Map();
577
+ const isGeneratedIdentifier = (value) => {
578
+ const token = value.trim();
579
+ if (!token)
580
+ return false;
581
+ const frameworkId = /^(?::r[0-9a-z]+:|«r[0-9a-z]+»|radix-:?r?[0-9a-z]+:?.*|headlessui-[a-z-]+-:?r?[0-9a-z]+:?|react-aria\d+.*|mui-\d+|ember\d+)$/;
582
+ const cssInJsClass = /^(?:css-[0-9a-z]{5,}(?:-[A-Za-z0-9]+)?|sc-[A-Za-z]{5,}|jsx-\d{6,}|[A-Za-z][A-Za-z0-9]*_[A-Za-z0-9]+__[A-Za-z0-9_-]{5})$/;
583
+ if (frameworkId.test(token) || cssInJsClass.test(token))
584
+ return true;
585
+ return token.split(/[-_:.]+/).some((segment) => {
586
+ var _a, _b;
587
+ if (/^\d{8,}$/.test(segment))
588
+ return true;
589
+ if (/^[0-9a-f]{6,}$/.test(segment) &&
590
+ /\d/.test(segment) &&
591
+ /[a-f]/.test(segment))
592
+ return true;
593
+ return (/^[0-9a-zA-Z]{8,}$/.test(segment) &&
594
+ ((_b = (_a = segment.match(/\d+|[a-zA-Z]+/g)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) >= 5);
595
+ });
596
+ };
597
+ const stableId = (id) => id && !isGeneratedIdentifier(id) ? id : undefined;
573
598
  const selectorKey = (selector) => selector.fingerprint || JSON.stringify(selector);
574
599
  const keepsIdentity = (document, element, selector) => {
575
600
  if (element.tagName.toLowerCase() !== selector.t.toLowerCase())
576
601
  return false;
577
602
  const attrs = [
578
- ['id', selector.id],
603
+ ['id', stableId(selector.id)],
579
604
  ['data-test-id', selector.dataTestId],
580
605
  ['aria-label', selector.ariaLabel],
581
606
  ];
@@ -841,7 +866,7 @@ const generateRelativePaths = (sel, max) => {
841
866
  const uniqueQueries = [];
842
867
  const nonUniqQueries = [];
843
868
  const newWipPaths = [];
844
- if (currentSel.id) {
869
+ if (currentSel.id && !isGeneratedIdentifier(currentSel.id)) {
845
870
  uniqueQueries.push({
846
871
  xpath: `[@id="${currentSel.id}"]`,
847
872
  css: `#${currentSel.id}`,
@@ -2504,6 +2529,7 @@ function isElementVisible(el) {
2504
2529
  }
2505
2530
  const VALUE_UNKNOWN_YET = 'n/a';
2506
2531
  function checkActivationCondition(condition, personalizationHeaders, currentUrl, languages, browserPlatform, userToken, userVisitCount, runJsFunction, logger, options) {
2532
+ var _a;
2507
2533
  if (condition.and) {
2508
2534
  const results = condition.and.map((c) => checkActivationCondition(c, personalizationHeaders, currentUrl, languages, browserPlatform, userToken, userVisitCount, runJsFunction, logger));
2509
2535
  const hasUnknown = results.some((r) => r === VALUE_UNKNOWN_YET);
@@ -2610,12 +2636,13 @@ function checkActivationCondition(condition, personalizationHeaders, currentUrl,
2610
2636
  }
2611
2637
  }
2612
2638
  }
2613
- if (condition.device) {
2614
- const isMobileDevice = personalizationHeaders['x-is-mobile-viewer'] === 'true';
2615
- if (condition.device.includes('mobile') && !isMobileDevice) {
2616
- return false;
2639
+ if ((_a = condition.device) === null || _a === void 0 ? void 0 : _a.length) {
2640
+ let device = personalizationHeaders['x-device-type'];
2641
+ if (!['desktop', 'mobile', 'tablet'].includes(device)) {
2642
+ device =
2643
+ personalizationHeaders['x-is-mobile-viewer'] === 'true' ? 'mobile' : '';
2617
2644
  }
2618
- if (condition.device.includes('desktop') && isMobileDevice) {
2645
+ if (!condition.device.includes(device)) {
2619
2646
  return false;
2620
2647
  }
2621
2648
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coframe/sdk",
3
- "version": "1.1.56",
3
+ "version": "1.1.59",
4
4
  "description": "Coframe optimizes your website using generative AI to deliver maximum impact to your audience and allow your site to improve itself as you sleep. Learn more at coframe.com.",
5
5
  "main": "dist/pkg/cf.cjs.js",
6
6
  "module": "dist/pkg/cf.esm.mjs",