@guidelytech/shared 0.15.0 → 0.17.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.
@@ -14,18 +14,18 @@ function slugify(input) {
14
14
  return input.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "untitled";
15
15
  }
16
16
  var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
17
- function randomId(size = 16) {
17
+ function randomId(size2 = 16) {
18
18
  const g = typeof globalThis !== "undefined" ? globalThis : {};
19
19
  let bytes;
20
20
  if (g.crypto && typeof g.crypto.getRandomValues === "function") {
21
- bytes = new Uint8Array(size);
21
+ bytes = new Uint8Array(size2);
22
22
  g.crypto.getRandomValues(bytes);
23
23
  } else {
24
- bytes = new Uint8Array(size);
25
- for (let i = 0; i < size; i++) bytes[i] = Math.floor(Math.random() * 256);
24
+ bytes = new Uint8Array(size2);
25
+ for (let i = 0; i < size2; i++) bytes[i] = Math.floor(Math.random() * 256);
26
26
  }
27
27
  let out = "";
28
- for (let i = 0; i < size; i++) out += ALPHABET[bytes[i] % ALPHABET.length];
28
+ for (let i = 0; i < size2; i++) out += ALPHABET[bytes[i] % ALPHABET.length];
29
29
  return out;
30
30
  }
31
31
  function isPlainObject(v) {
@@ -428,19 +428,91 @@ function contrastIssues(colors) {
428
428
  return issues;
429
429
  }
430
430
 
431
+ // src/error-detail.ts
432
+ var MAX_EXCEPTION_DETAIL_BYTES = 64 * 1024;
433
+ var MAX_EXCEPTION_DETAIL_RAW_BYTES = 1024 * 1024;
434
+ var MAX_BREADCRUMBS = 100;
435
+ var MAX_EXCEPTION_CHAIN = 20;
436
+ var MAX_DETAIL_FRAMES = 250;
437
+ var MAX_DETAIL_THREADS = 100;
438
+ var MAX_DEBUG_IMAGES = 500;
439
+ var MAX_ERROR_TAGS = 50;
440
+ var size = (v) => {
441
+ try {
442
+ return JSON.stringify(v)?.length ?? 0;
443
+ } catch {
444
+ return Infinity;
445
+ }
446
+ };
447
+ function normalizeTags(tags) {
448
+ const out = {};
449
+ for (const [k, v] of Object.entries(tags ?? {})) {
450
+ if (Object.keys(out).length >= MAX_ERROR_TAGS) break;
451
+ if (!k || v === void 0 || v === null) continue;
452
+ out[k.slice(0, 32)] = String(v).slice(0, 200);
453
+ }
454
+ return out;
455
+ }
456
+ function trimExceptionDetail(detail, max = MAX_EXCEPTION_DETAIL_BYTES) {
457
+ const d = detail;
458
+ if (d.breadcrumbs?.values && d.breadcrumbs.values.length > MAX_BREADCRUMBS) d.breadcrumbs.values = d.breadcrumbs.values.slice(-MAX_BREADCRUMBS);
459
+ if (d.exception?.values && d.exception.values.length > MAX_EXCEPTION_CHAIN) d.exception.values = d.exception.values.slice(-MAX_EXCEPTION_CHAIN);
460
+ if (d.threads?.values && d.threads.values.length > MAX_DETAIL_THREADS) d.threads.values = d.threads.values.slice(0, MAX_DETAIL_THREADS);
461
+ if (d.debug_meta?.images && d.debug_meta.images.length > MAX_DEBUG_IMAGES) d.debug_meta.images = d.debug_meta.images.slice(0, MAX_DEBUG_IMAGES);
462
+ const stacks = () => [...d.exception?.values ?? [], ...d.threads?.values ?? []].map((x) => x.stacktrace).filter((s) => !!s);
463
+ for (const s of stacks()) if (s.frames && s.frames.length > MAX_DETAIL_FRAMES) s.frames = s.frames.slice(-MAX_DETAIL_FRAMES);
464
+ if (size(d) <= max) return d;
465
+ while (d.breadcrumbs?.values.length && size(d) > max) d.breadcrumbs.values = d.breadcrumbs.values.slice(Math.ceil(d.breadcrumbs.values.length / 2));
466
+ if (size(d) <= max) return d;
467
+ for (const s of stacks())
468
+ for (const f of s.frames ?? []) {
469
+ delete f.vars;
470
+ delete f.pre_context;
471
+ delete f.post_context;
472
+ }
473
+ if (size(d) <= max) return d;
474
+ if (d.threads?.values) d.threads.values = d.threads.values.filter((t) => t.crashed || t.current);
475
+ if (size(d) <= max) return d;
476
+ if (d.extra) d.extra = { _trimmed: true };
477
+ if (d.request) delete d.request.data;
478
+ for (const s of stacks()) while (s.frames && s.frames.length > 20 && size(d) > max) s.frames.splice(Math.floor(s.frames.length / 2) - 5, 10);
479
+ if (d.debug_meta?.images && size(d) > max) d.debug_meta.images = d.debug_meta.images.slice(0, 50);
480
+ return d;
481
+ }
482
+ var matches = (patterns, value) => patterns.some((p) => typeof p === "string" ? p !== "" && value.includes(p) : safeTest(p, value));
483
+ function safeTest(re, value) {
484
+ re.lastIndex = 0;
485
+ return re.test(value);
486
+ }
487
+ function errorFilterDrops(e, opts) {
488
+ const message = e.message ?? "";
489
+ if (opts.ignoreErrors?.length && (matches(opts.ignoreErrors, `${e.type || "Error"}: ${message}`) || matches(opts.ignoreErrors, message))) return true;
490
+ if (!e.file) return false;
491
+ if (opts.denyUrls?.length && matches(opts.denyUrls, e.file)) return true;
492
+ if (opts.allowUrls?.length && !matches(opts.allowUrls, e.file)) return true;
493
+ return false;
494
+ }
495
+
431
496
  // src/events-util.ts
432
497
  var SENSITIVE_PROPERTY_PATTERN = /(password|passwd|secret|token|credit|card|cvv|ssn|iban)/i;
433
498
  var MAX_PROPERTY_BYTES = 8 * 1024;
499
+ var MAX_APP_VERSION_LENGTH = 64;
500
+ function normalizeAppVersion(input) {
501
+ if (typeof input !== "string" && typeof input !== "number") return null;
502
+ const printable = Array.from(String(input)).filter((c) => c.charCodeAt(0) > 31 && c.charCodeAt(0) !== 127).join("");
503
+ const v = printable.trim().slice(0, MAX_APP_VERSION_LENGTH).trim();
504
+ return v || null;
505
+ }
434
506
  function sanitizeProperties(props) {
435
507
  if (!props) return {};
436
508
  const out = {};
437
- let size = 0;
509
+ let size2 = 0;
438
510
  for (const [k, v] of Object.entries(props)) {
439
511
  if (SENSITIVE_PROPERTY_PATTERN.test(k)) continue;
440
512
  if (typeof v === "function" || typeof v === "symbol") continue;
441
513
  const str2 = typeof v === "string" ? v : JSON.stringify(v ?? null);
442
- size += k.length + (str2?.length ?? 0);
443
- if (size > MAX_PROPERTY_BYTES) break;
514
+ size2 += k.length + (str2?.length ?? 0);
515
+ if (size2 > MAX_PROPERTY_BYTES) break;
444
516
  out[k.slice(0, 100)] = typeof v === "string" ? v.slice(0, 1e3) : v;
445
517
  }
446
518
  return out;
@@ -450,16 +522,23 @@ function sanitizeProperties(props) {
450
522
  var MAX_STACK_FRAMES = 30;
451
523
  var V8 = /^\s*at (?:(.+?) \()?((?:[a-z][\w+.-]*:)?[^\s()]+?):(\d+):(\d+)\)?\s*$/i;
452
524
  var GECKO = /^\s*(.*?)@(.+?):(\d+):(\d+)\s*$/;
525
+ var HERMES = /^\s*at (?:(.+?) \()?address at ([^\s()]+?):(\d+):(\d+)\)?\s*$/;
526
+ function reactNativeBundleUrl(file) {
527
+ const base = file.replace(/[?#].*$/, "").split("/").pop() || file;
528
+ return `app:///${base}`;
529
+ }
453
530
  function parseStack(stack, max = MAX_STACK_FRAMES) {
454
531
  if (!stack || typeof stack !== "string") return [];
455
532
  const frames = [];
456
533
  for (const raw of stack.split("\n")) {
457
534
  if (frames.length >= max) break;
458
535
  const line = raw.slice(0, 1e3);
459
- const m = V8.exec(line) ?? GECKO.exec(line);
536
+ const hermes = HERMES.exec(line);
537
+ const m = hermes ?? V8.exec(line) ?? GECKO.exec(line);
460
538
  if (!m) continue;
461
539
  const fn = (m[1] || "").trim();
462
- frames.push({ fn: fn ? fn.slice(0, 200) : void 0, file: m[2]?.slice(0, 500), line: Number(m[3]), col: Number(m[4]) });
540
+ const file = hermes ? reactNativeBundleUrl(m[2]) : m[2];
541
+ frames.push({ fn: fn ? fn.slice(0, 200) : void 0, file: file?.slice(0, 500), line: Number(m[3]), col: Number(m[4]) });
463
542
  }
464
543
  return frames;
465
544
  }
@@ -479,13 +558,23 @@ function normalizeFrameFile(file) {
479
558
  var SOURCEMAP_MAX_FILE_BYTES = 100 * 1024 * 1024;
480
559
  var SOURCEMAP_MAX_FILES_PER_UPLOAD = 200;
481
560
  function fingerprintError(input) {
482
- const top = (input.frames ?? []).find((f) => f.file);
483
- const frameKey = input.original ? `src:${input.original.source}:${input.original.name || "?"}` : top ? `${normalizeFrameFile(top.file)}:${top.fn || "?"}` : "";
561
+ const withFile = (input.frames ?? []).filter((f) => f.file || f.module);
562
+ const top = withFile.find((f) => f.inApp === true) ?? withFile.find((f) => f.inApp !== false) ?? withFile[0];
563
+ const frameKey = input.original ? `src:${input.original.source}:${input.original.name || "?"}` : top ? `${top.file ? normalizeFrameFile(top.file) : `mod:${top.module}`}:${top.fn || "?"}` : "";
484
564
  const key = [input.type || "Error", normalizeErrorMessage(input.message || ""), frameKey].join("|");
485
565
  const a = fnv1a(key).toString(16).padStart(8, "0");
486
566
  const b = fnv1a(`guidely:${key}`).toString(16).padStart(8, "0");
487
567
  return a + b;
488
568
  }
569
+ function customFingerprint(parts, computed) {
570
+ if (!Array.isArray(parts) || parts.length === 0) return computed;
571
+ const items = parts.filter((p) => typeof p === "string" || typeof p === "number").map((p) => String(p).slice(0, 200)).slice(0, 20);
572
+ if (items.length === 0) return computed;
573
+ const isDefault = (p) => /^\{\{\s*default\s*\}\}$/i.test(p);
574
+ if (items.every(isDefault)) return computed;
575
+ const key = items.map((p) => isDefault(p) ? computed : p).join("|");
576
+ return fnv1a(key).toString(16).padStart(8, "0") + fnv1a(`guidely:fp:${key}`).toString(16).padStart(8, "0");
577
+ }
489
578
 
490
579
  // src/complaints-limits.ts
491
580
  var COMPLAINT_STATUSES = ["open", "in_review", "resolved"];
@@ -498,6 +587,10 @@ var MAX_COMPLAINT_ANSWER_LENGTH = 500;
498
587
  var MAX_COMPLAINT_ATTACHMENT_BYTES = 2 * 1024 * 1024;
499
588
  var complaintReference = (number) => `CMP-${number}`;
500
589
 
590
+ // src/bug-reports-limits.ts
591
+ var MAX_BUG_REPORT_LENGTH = 4e3;
592
+ var MAX_BUG_REPORT_SCREENSHOT_BYTES = 4 * 1024 * 1024;
593
+
501
594
  // src/agents-limits.ts
502
595
  var AGENT_TURN_ROLES = ["user", "assistant", "tool", "system"];
503
596
  var AGENT_OUTCOMES = ["success", "failure", "escalated", "abandoned"];
@@ -643,6 +736,19 @@ function isSafeMediaUrl(url) {
643
736
  return false;
644
737
  }
645
738
  }
739
+ function videoThumbnailUrl(url) {
740
+ const embed = url ? toEmbedUrl(url) : null;
741
+ if (embed?.provider !== "youtube") return null;
742
+ const id = embed.src.split("/embed/")[1]?.split("?")[0];
743
+ return id ? `https://i.ytimg.com/vi/${id}/hqdefault.jpg` : null;
744
+ }
745
+ function isVideoFileUrl(url) {
746
+ return isSafeMediaUrl(url) && /\.(mp4|webm|m4v|mov|ogv)$/i.test(new URL(url).pathname);
747
+ }
748
+ function stepVideo(step) {
749
+ if (!step.videoUrl || !isSafeMediaUrl(step.videoUrl)) return null;
750
+ return { url: step.videoUrl, poster: (step.imageUrl && isSafeMediaUrl(step.imageUrl) ? step.imageUrl : null) ?? videoThumbnailUrl(step.videoUrl) };
751
+ }
646
752
 
647
753
  // src/resource-center.ts
648
754
  var MAX_COLLECTION_DEPTH = 3;
@@ -765,6 +871,16 @@ function unreadAnnouncements(items, lastSeenAt) {
765
871
  if (Number.isNaN(seen)) return items.length;
766
872
  return items.filter((a) => Date.parse(a.publishedAt) > seen).length;
767
873
  }
874
+ var ARTICLE_HREF_PREFIX = "#guidely-article:";
875
+ var ARTICLE_ID = /^[A-Za-z0-9_-]{1,64}$/;
876
+ function articleHref(articleId) {
877
+ return `${ARTICLE_HREF_PREFIX}${articleId}`;
878
+ }
879
+ function articleIdFromHref(href) {
880
+ if (!href || !href.startsWith(ARTICLE_HREF_PREFIX)) return null;
881
+ const id = href.slice(ARTICLE_HREF_PREFIX.length);
882
+ return ARTICLE_ID.test(id) ? id : null;
883
+ }
768
884
 
769
885
  // src/howto-limits.ts
770
886
  var CAPTURE_PARAM = "guidely_capture";
@@ -1797,16 +1913,31 @@ export {
1797
1913
  contrastRatio,
1798
1914
  readableTextOn,
1799
1915
  contrastIssues,
1916
+ MAX_EXCEPTION_DETAIL_BYTES,
1917
+ MAX_EXCEPTION_DETAIL_RAW_BYTES,
1918
+ MAX_BREADCRUMBS,
1919
+ MAX_EXCEPTION_CHAIN,
1920
+ MAX_DETAIL_FRAMES,
1921
+ MAX_DETAIL_THREADS,
1922
+ MAX_DEBUG_IMAGES,
1923
+ MAX_ERROR_TAGS,
1924
+ normalizeTags,
1925
+ trimExceptionDetail,
1926
+ errorFilterDrops,
1800
1927
  SENSITIVE_PROPERTY_PATTERN,
1801
1928
  MAX_PROPERTY_BYTES,
1929
+ MAX_APP_VERSION_LENGTH,
1930
+ normalizeAppVersion,
1802
1931
  sanitizeProperties,
1803
1932
  MAX_STACK_FRAMES,
1933
+ reactNativeBundleUrl,
1804
1934
  parseStack,
1805
1935
  normalizeErrorMessage,
1806
1936
  normalizeFrameFile,
1807
1937
  SOURCEMAP_MAX_FILE_BYTES,
1808
1938
  SOURCEMAP_MAX_FILES_PER_UPLOAD,
1809
1939
  fingerprintError,
1940
+ customFingerprint,
1810
1941
  COMPLAINT_STATUSES,
1811
1942
  COMPLAINT_EVENTS,
1812
1943
  COMPLAINT_FIELD_TYPES,
@@ -1816,6 +1947,8 @@ export {
1816
1947
  MAX_COMPLAINT_ANSWER_LENGTH,
1817
1948
  MAX_COMPLAINT_ATTACHMENT_BYTES,
1818
1949
  complaintReference,
1950
+ MAX_BUG_REPORT_LENGTH,
1951
+ MAX_BUG_REPORT_SCREENSHOT_BYTES,
1819
1952
  AGENT_TURN_ROLES,
1820
1953
  AGENT_OUTCOMES,
1821
1954
  AGENT_TOOL_STATUSES,
@@ -1851,6 +1984,9 @@ export {
1851
1984
  EMBED_IFRAME_ATTRS,
1852
1985
  VIDEO_ATTRS,
1853
1986
  isSafeMediaUrl,
1987
+ videoThumbnailUrl,
1988
+ isVideoFileUrl,
1989
+ stepVideo,
1854
1990
  MAX_COLLECTION_DEPTH,
1855
1991
  matchesAudiences,
1856
1992
  resourceCenterSections,
@@ -1872,6 +2008,9 @@ export {
1872
2008
  orderedModules,
1873
2009
  visibleAnnouncements,
1874
2010
  unreadAnnouncements,
2011
+ ARTICLE_HREF_PREFIX,
2012
+ articleHref,
2013
+ articleIdFromHref,
1875
2014
  CAPTURE_PARAM,
1876
2015
  CAPTURE_SCREENSHOT_MAX_BYTES,
1877
2016
  PATH_ID_PATTERN,
@@ -1938,4 +2077,4 @@ export {
1938
2077
  sanitizeCustomCss,
1939
2078
  scopeCustomCss
1940
2079
  };
1941
- //# sourceMappingURL=chunk-XJXXVV3C.js.map
2080
+ //# sourceMappingURL=chunk-YL65O3FS.js.map