@insitue/sdk 0.1.9 → 0.1.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,7 +1,7 @@
1
1
  import {
2
2
  mountCaptureOnly
3
- } from "./chunk-BNREKX5C.js";
4
- import "./chunk-CPPXBTE5.js";
3
+ } from "./chunk-PAKDACTF.js";
4
+ import "./chunk-SMR4AYKA.js";
5
5
  export {
6
6
  mountCaptureOnly
7
7
  };
@@ -15,7 +15,7 @@ import {
15
15
  setCaptureSettings,
16
16
  stopDisplayMedia,
17
17
  y
18
- } from "./chunk-CPPXBTE5.js";
18
+ } from "./chunk-SMR4AYKA.js";
19
19
 
20
20
  // src/client.ts
21
21
  var CompanionClient = class {
@@ -11,7 +11,7 @@ import {
11
11
  setCaptureSettings,
12
12
  stopDisplayMedia,
13
13
  y
14
- } from "./chunk-CPPXBTE5.js";
14
+ } from "./chunk-SMR4AYKA.js";
15
15
 
16
16
  // src/capture-only.ts
17
17
  var DEFAULT_INGEST = "https://www.insitue.com/api/v1/capture";
@@ -351,11 +351,19 @@ function CaptureOnlyApp(props) {
351
351
  style: `display:flex;justify-content:space-between;padding:9px 16px;border-top:1px solid ${C.line};color:${C.faint};font-size:11px`
352
352
  },
353
353
  [
354
- k("span", {}, "\u{1F512} Secrets scrubbed automatically"),
354
+ // No "Secrets scrubbed" badge — the redaction is narrow
355
+ // (regex on attr-names + console.log args; see
356
+ // packages/sdk/src/runtime.ts safeArg, capture-core/dom.ts
357
+ // serializeNode). Visible password VALUES, URL query
358
+ // params, and any text rendered in the screenshot pixels
359
+ // are NOT scrubbed — claiming otherwise misleads reporters
360
+ // about what's safe to capture. If we ever build real
361
+ // form-value redaction the badge can come back.
362
+ k("span", {}, ""),
355
363
  k(
356
364
  "span",
357
- { title: `@insitue/sdk@${"0.1.9"}` },
358
- `InSitue \xB7 v${"0.1.9"}`
365
+ { title: `@insitue/sdk@${"0.1.11"}` },
366
+ `InSitue \xB7 v${"0.1.11"}`
359
367
  )
360
368
  ]
361
369
  )
@@ -1641,16 +1641,6 @@ async function toCanvas(node, options = {}) {
1641
1641
  }
1642
1642
 
1643
1643
  // src/capture.ts
1644
- function crossOrigin(url) {
1645
- if (!url || url.startsWith("data:") || url.startsWith("blob:")) {
1646
- return false;
1647
- }
1648
- try {
1649
- return new URL(url, location.href).origin !== location.origin;
1650
- } catch {
1651
- return false;
1652
- }
1653
- }
1654
1644
  var IMAGE_PLACEHOLDER = "data:image/svg+xml;base64," + (typeof btoa !== "undefined" ? btoa(
1655
1645
  '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><rect width="32" height="32" fill="#e8e8e8"/><path d="M0 0 L32 32 M32 0 L0 32" stroke="#b0b0b0" stroke-width="1.5"/></svg>'
1656
1646
  ) : "");
@@ -1681,7 +1671,7 @@ async function renderViewportCrop(cropRect, pixelRatio) {
1681
1671
  out.height = Math.max(1, Math.round(cropRect.height * pixelRatio));
1682
1672
  const ctx = out.getContext("2d");
1683
1673
  if (!ctx) return { dataUrl: null, failedImages };
1684
- const drawnImgs = drawAbsoluteImagesOnto(
1674
+ const drawnImgs = await drawAbsoluteImagesOnto(
1685
1675
  ctx,
1686
1676
  cropRect,
1687
1677
  pixelRatio,
@@ -1721,67 +1711,102 @@ async function renderViewportCrop(cropRect, pixelRatio) {
1721
1711
  detectUnrenderedImages(ctx, cropRect, out, pixelRatio, failedImages);
1722
1712
  return { dataUrl: out.toDataURL("image/png"), failedImages };
1723
1713
  }
1724
- function drawAbsoluteImagesOnto(ctx, cropRect, pixelRatio, failedImages) {
1714
+ async function drawAbsoluteImagesOnto(ctx, cropRect, pixelRatio, failedImages) {
1725
1715
  const drawn = /* @__PURE__ */ new Set();
1726
1716
  const imgs = Array.from(
1727
1717
  document.querySelectorAll("img")
1728
1718
  ).filter(
1729
1719
  (img) => !img.closest?.("#insitu-root, [data-insitu-layer]")
1730
1720
  );
1731
- for (const img of imgs) {
1732
- const r3 = img.getBoundingClientRect();
1733
- if (r3.width <= 0 || r3.height <= 0) continue;
1734
- const cs = getComputedStyle(img);
1735
- if (cs.position !== "absolute" && cs.position !== "fixed") continue;
1736
- if (r3.right < cropRect.x || r3.left > cropRect.x + cropRect.width || r3.bottom < cropRect.y || r3.top > cropRect.y + cropRect.height) {
1737
- continue;
1738
- }
1739
- const src = img.currentSrc || img.src;
1740
- if (!src) continue;
1741
- if (crossOrigin(src) && img.crossOrigin !== "anonymous" && img.crossOrigin !== "use-credentials") {
1742
- failedImages.add(img);
1743
- continue;
1744
- }
1745
- if (!img.complete || img.naturalWidth === 0 || img.naturalHeight === 0) {
1746
- failedImages.add(img);
1747
- continue;
1748
- }
1749
- const dest = {
1750
- x: (r3.left - cropRect.x) * pixelRatio,
1751
- y: (r3.top - cropRect.y) * pixelRatio,
1752
- w: r3.width * pixelRatio,
1753
- h: r3.height * pixelRatio
1754
- };
1755
- const source = computeObjectFitSource(img, cs);
1756
- try {
1757
- ctx.drawImage(
1758
- img,
1759
- source.sx,
1760
- source.sy,
1761
- source.sw,
1762
- source.sh,
1763
- dest.x,
1764
- dest.y,
1765
- dest.w,
1766
- dest.h
1721
+ const PER_IMAGE_TIMEOUT_MS = 3e3;
1722
+ await Promise.allSettled(
1723
+ imgs.map(async (img) => {
1724
+ const r3 = img.getBoundingClientRect();
1725
+ if (r3.width <= 0 || r3.height <= 0) return;
1726
+ const cs = getComputedStyle(img);
1727
+ if (cs.position !== "absolute" && cs.position !== "fixed") return;
1728
+ if (r3.right < cropRect.x || r3.left > cropRect.x + cropRect.width || r3.bottom < cropRect.y || r3.top > cropRect.y + cropRect.height) {
1729
+ return;
1730
+ }
1731
+ const src = img.currentSrc || img.src;
1732
+ if (!src) return;
1733
+ const usesFreshLoad = !src.startsWith("data:") && !src.startsWith("blob:");
1734
+ let source;
1735
+ if (usesFreshLoad) {
1736
+ try {
1737
+ source = await loadFresh(src, PER_IMAGE_TIMEOUT_MS);
1738
+ } catch {
1739
+ failedImages.add(img);
1740
+ return;
1741
+ }
1742
+ } else {
1743
+ if (!img.complete || img.naturalWidth === 0) {
1744
+ failedImages.add(img);
1745
+ return;
1746
+ }
1747
+ source = img;
1748
+ }
1749
+ const objFit = computeObjectFitSource(
1750
+ { naturalWidth: source.naturalWidth, naturalHeight: source.naturalHeight },
1751
+ r3.width,
1752
+ r3.height,
1753
+ cs.objectFit || "fill"
1767
1754
  );
1768
- drawn.add(img);
1769
- } catch {
1770
- failedImages.add(img);
1771
- }
1772
- }
1755
+ const dest = {
1756
+ x: (r3.left - cropRect.x) * pixelRatio,
1757
+ y: (r3.top - cropRect.y) * pixelRatio,
1758
+ w: r3.width * pixelRatio,
1759
+ h: r3.height * pixelRatio
1760
+ };
1761
+ try {
1762
+ ctx.drawImage(
1763
+ source,
1764
+ objFit.sx,
1765
+ objFit.sy,
1766
+ objFit.sw,
1767
+ objFit.sh,
1768
+ dest.x,
1769
+ dest.y,
1770
+ dest.w,
1771
+ dest.h
1772
+ );
1773
+ drawn.add(img);
1774
+ } catch {
1775
+ failedImages.add(img);
1776
+ }
1777
+ })
1778
+ );
1773
1779
  return drawn;
1774
1780
  }
1775
- function computeObjectFitSource(img, cs) {
1776
- const nw = img.naturalWidth;
1777
- const nh = img.naturalHeight;
1778
- const r3 = img.getBoundingClientRect();
1779
- const dw = r3.width;
1780
- const dh = r3.height;
1781
+ function loadFresh(url, timeoutMs) {
1782
+ return new Promise((resolve, reject) => {
1783
+ const img = new Image();
1784
+ img.crossOrigin = "anonymous";
1785
+ const timer = setTimeout(() => {
1786
+ img.src = "";
1787
+ reject(new Error("timeout"));
1788
+ }, timeoutMs);
1789
+ img.onload = async () => {
1790
+ clearTimeout(timer);
1791
+ try {
1792
+ await img.decode();
1793
+ } catch {
1794
+ }
1795
+ resolve(img);
1796
+ };
1797
+ img.onerror = () => {
1798
+ clearTimeout(timer);
1799
+ reject(new Error("load failed"));
1800
+ };
1801
+ img.src = url;
1802
+ });
1803
+ }
1804
+ function computeObjectFitSource(natural, dw, dh, fit) {
1805
+ const nw = natural.naturalWidth;
1806
+ const nh = natural.naturalHeight;
1781
1807
  if (!nw || !nh || !dw || !dh) {
1782
1808
  return { sx: 0, sy: 0, sw: nw || 1, sh: nh || 1 };
1783
1809
  }
1784
- const fit = cs.objectFit || "fill";
1785
1810
  if (fit === "fill") {
1786
1811
  return { sx: 0, sy: 0, sw: nw, sh: nh };
1787
1812
  }
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  mountCaptureOnly
3
- } from "./chunk-BNREKX5C.js";
3
+ } from "./chunk-PAKDACTF.js";
4
4
  import {
5
5
  mountInSitue
6
- } from "./chunk-DSHJX2LF.js";
7
- import "./chunk-CPPXBTE5.js";
6
+ } from "./chunk-DJN4LPOV.js";
7
+ import "./chunk-SMR4AYKA.js";
8
8
 
9
9
  // src/InSitue.tsx
10
10
  import { useEffect } from "react";
@@ -52,7 +52,7 @@ function InSitueCapture({
52
52
  }
53
53
 
54
54
  // src/index.ts
55
- var SDK_VERSION = "0.1.9";
55
+ var SDK_VERSION = "0.1.11";
56
56
  export {
57
57
  InSitue,
58
58
  InSitueCapture,
package/dist/overlay.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  mountInSitue
3
- } from "./chunk-DSHJX2LF.js";
4
- import "./chunk-CPPXBTE5.js";
3
+ } from "./chunk-DJN4LPOV.js";
4
+ import "./chunk-SMR4AYKA.js";
5
5
  export {
6
6
  mountInSitue
7
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@insitue/sdk",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "InSitue capture SDK — drop one snippet into your deployed app; your users point at a bug, InSitue opens a verified pull request.",
5
5
  "license": "MIT",
6
6
  "type": "module",