heroshot 0.14.1 → 0.15.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.
@@ -1,74 +1,74 @@
1
1
  import { jsx as h, jsxs as y } from "react/jsx-runtime";
2
- import I, { createContext as $, useContext as j, useMemo as g, useState as C, useEffect as L } from "react";
3
- function z(e, t) {
4
- return e.screenshots[t];
2
+ import $, { createContext as I, useContext as j, useMemo as g, useState as C, useEffect as L } from "react";
3
+ function z(e, n) {
4
+ return e.screenshots[n];
5
5
  }
6
- function N(e, t = {}) {
7
- const { slug: a, format: s } = e, { viewport: r, colorScheme: c } = t, n = [a];
8
- r && n.push(r), c && n.push(c);
9
- const i = s === "jpeg" ? "jpg" : "png";
10
- return `${n.join("-")}.${i}`;
6
+ function N(e, n = {}) {
7
+ const { slug: c, format: s } = e, { viewport: t, colorScheme: i } = n, r = [c];
8
+ t && r.push(t), i && r.push(i);
9
+ const a = s === "jpeg" ? "jpg" : "png";
10
+ return `${r.join("-")}.${a}`;
11
11
  }
12
- function O(e, t, a = {}) {
13
- const s = N(t, a);
14
- return `${e.outputDirectory}/${s}`;
12
+ function O(e, n, c = {}) {
13
+ const s = N(n, c), t = e.outputDirectory;
14
+ return `${t.startsWith("/") ? "" : "/"}${t}/${s}`;
15
15
  }
16
- function H(e, t, a) {
17
- const { colorSchemes: s } = t, r = s.length > 0, c = (i) => O(e, t, { viewport: a, colorScheme: i }), n = {
18
- default: r ? c("light") : c()
16
+ function x(e, n, c) {
17
+ const { colorSchemes: s } = n, t = s.length > 0, i = (a) => O(e, n, { viewport: c, colorScheme: a }), r = {
18
+ default: t ? i("light") : i()
19
19
  };
20
- return s.includes("light") && (n.light = c("light")), s.includes("dark") && (n.dark = c("dark")), n;
20
+ return s.includes("light") && (r.light = i("light")), s.includes("dark") && (r.dark = i("dark")), r;
21
21
  }
22
- function R(e, t) {
23
- const a = H(e, t), s = {};
24
- for (const r of t.viewports)
25
- s[r] = H(e, t, r);
22
+ function R(e, n) {
23
+ const c = x(e, n), s = {};
24
+ for (const t of n.viewports)
25
+ s[t] = x(e, n, t);
26
26
  return {
27
- ...a,
27
+ ...c,
28
28
  viewports: s
29
29
  };
30
30
  }
31
- let x = null;
31
+ let S = null;
32
32
  function Q(e) {
33
- x = e;
33
+ S = e;
34
34
  }
35
35
  function V() {
36
- return x;
36
+ return S;
37
37
  }
38
- const D = $(null);
38
+ const D = I(null);
39
39
  function _({
40
40
  manifest: e,
41
- children: t
41
+ children: n
42
42
  }) {
43
- return /* @__PURE__ */ h(D.Provider, { value: e, children: t });
43
+ return /* @__PURE__ */ h(D.Provider, { value: e, children: n });
44
44
  }
45
- function S() {
45
+ function H() {
46
46
  if (globalThis.window === void 0) return { isDark: !1, hasThemeHandling: !1 };
47
47
  const { theme: e } = document.documentElement.dataset;
48
48
  return e ? { isDark: e === "dark", hasThemeHandling: !0 } : document.documentElement.classList.contains("dark") ? { isDark: !0, hasThemeHandling: !0 } : document.documentElement.classList.length > 0 ? { isDark: !1, hasThemeHandling: !0 } : globalThis.matchMedia?.("(prefers-color-scheme: dark)").matches ? { isDark: !0, hasThemeHandling: !1 } : { isDark: !1, hasThemeHandling: !1 };
49
49
  }
50
- function A() {
51
- const e = I.useRef(!1), [t, a] = C(() => S().isDark);
50
+ function W() {
51
+ const e = $.useRef(!1), [n, c] = C(() => H().isDark);
52
52
  return L(() => {
53
- const s = S();
53
+ const s = H();
54
54
  e.current = s.hasThemeHandling;
55
- const r = () => {
55
+ const t = () => {
56
56
  const { theme: u } = document.documentElement.dataset;
57
57
  return u ? (e.current = !0, u === "dark") : document.documentElement.classList.contains("dark") ? (e.current = !0, !0) : e.current ? !1 : globalThis.matchMedia?.("(prefers-color-scheme: dark)").matches ?? !1;
58
- }, c = new MutationObserver(() => {
59
- e.current = !0, a(r());
58
+ }, i = new MutationObserver(() => {
59
+ e.current = !0, c(t());
60
60
  });
61
- c.observe(document.documentElement, {
61
+ i.observe(document.documentElement, {
62
62
  attributes: !0,
63
63
  attributeFilter: ["data-theme", "class"]
64
64
  });
65
- const n = globalThis.matchMedia?.("(prefers-color-scheme: dark)"), i = () => {
66
- a(r());
65
+ const r = globalThis.matchMedia?.("(prefers-color-scheme: dark)"), a = () => {
66
+ c(t());
67
67
  };
68
- return n?.addEventListener("change", i), () => {
69
- c.disconnect(), n?.removeEventListener("change", i);
68
+ return r?.addEventListener("change", a), () => {
69
+ i.disconnect(), r?.removeEventListener("change", a);
70
70
  };
71
- }, []), t;
71
+ }, []), n;
72
72
  }
73
73
  const k = {
74
74
  mobile: 430,
@@ -78,16 +78,16 @@ const k = {
78
78
  };
79
79
  function q({
80
80
  name: e,
81
- alt: t = "",
82
- manifest: a,
81
+ alt: n = "",
82
+ manifest: c,
83
83
  className: s
84
84
  }) {
85
- const r = A(), c = j(D), n = a ?? c ?? V(), i = g(() => n ? z(n, e) : null, [n, e]), u = g(() => !i || !n ? null : R(n, i), [n, i]), v = g(() => {
85
+ const t = W(), i = j(D), r = c ?? i ?? V(), a = g(() => r ? z(r, e) : null, [r, e]), u = g(() => !a || !r ? null : R(r, a), [r, a]), v = g(() => {
86
86
  if (!u) return "";
87
87
  const { light: o, dark: f } = u;
88
- return r && f ? f : !r && o ? o : u.default;
89
- }, [u, r]), T = g(() => {
90
- if (!u || !i) return [];
88
+ return t && f ? f : !t && o ? o : u.default;
89
+ }, [u, t]), T = g(() => {
90
+ if (!u || !a) return [];
91
91
  const { viewports: o } = u, f = Object.keys(o);
92
92
  if (f.length === 0) return [];
93
93
  const b = [...f].sort((l, m) => {
@@ -100,17 +100,17 @@ function q({
100
100
  const p = d.light || d.default, E = d.dark || d.light || d.default, w = k[l] || Number.parseInt(l.split("x")[0] || "1280", 10), M = m === b.length - 1;
101
101
  return {
102
102
  viewport: l,
103
- srcset: r ? E : p,
103
+ srcset: t ? E : p,
104
104
  width: w,
105
105
  media: M ? void 0 : `(max-width: ${w}px)`
106
106
  };
107
107
  }).filter((l) => l !== null);
108
- }, [u, i, r]), P = T.length > 0;
109
- if (!n) {
108
+ }, [u, a, t]), P = T.length > 0;
109
+ if (!r) {
110
110
  const o = "Heroshot: No manifest found. Add heroshot() plugin to vite config, use HeroshotProvider, or pass manifest prop.";
111
111
  return typeof console < "u" && console.warn(o), /* @__PURE__ */ h("span", { style: { color: "red", fontSize: "12px" }, children: o });
112
112
  }
113
- if (!i) {
113
+ if (!a) {
114
114
  const o = `Heroshot: Screenshot "${e}" not found in config`;
115
115
  return typeof console < "u" && console.warn(o), /* @__PURE__ */ h("span", { style: { color: "red", fontSize: "12px" }, children: o });
116
116
  }
@@ -121,10 +121,10 @@ function q({
121
121
  srcSet: o.srcset,
122
122
  media: o.media
123
123
  },
124
- `${o.viewport}-${r}`
124
+ `${o.viewport}-${t}`
125
125
  )),
126
- /* @__PURE__ */ h("img", { src: v, alt: t, loading: "lazy" })
127
- ] }) : /* @__PURE__ */ h("img", { src: v, alt: t, className: s, loading: "lazy" });
126
+ /* @__PURE__ */ h("img", { src: v, alt: n, loading: "lazy" })
127
+ ] }) : /* @__PURE__ */ h("img", { src: v, alt: n, className: s, loading: "lazy" });
128
128
  }
129
129
  export {
130
130
  q as Heroshot,
@@ -2,27 +2,27 @@ function h(t, n) {
2
2
  return t.screenshots[n];
3
3
  }
4
4
  function l(t, n = {}) {
5
- const { slug: o, format: e } = t, { viewport: r, colorScheme: i } = n, s = [o];
6
- r && s.push(r), i && s.push(i);
5
+ const { slug: i, format: e } = t, { viewport: o, colorScheme: r } = n, s = [i];
6
+ o && s.push(o), r && s.push(r);
7
7
  const c = e === "jpeg" ? "jpg" : "png";
8
8
  return `${s.join("-")}.${c}`;
9
9
  }
10
- function f(t, n, o = {}) {
11
- const e = l(n, o);
12
- return `${t.outputDirectory}/${e}`;
10
+ function f(t, n, i = {}) {
11
+ const e = l(n, i), o = t.outputDirectory;
12
+ return `${o.startsWith("/") ? "" : "/"}${o}/${e}`;
13
13
  }
14
- function a(t, n, o) {
15
- const { colorSchemes: e } = n, r = e.length > 0, i = (c) => f(t, n, { viewport: o, colorScheme: c }), s = {
16
- default: r ? i("light") : i()
14
+ function a(t, n, i) {
15
+ const { colorSchemes: e } = n, o = e.length > 0, r = (c) => f(t, n, { viewport: i, colorScheme: c }), s = {
16
+ default: o ? r("light") : r()
17
17
  };
18
- return e.includes("light") && (s.light = i("light")), e.includes("dark") && (s.dark = i("dark")), s;
18
+ return e.includes("light") && (s.light = r("light")), e.includes("dark") && (s.dark = r("dark")), s;
19
19
  }
20
20
  function g(t, n) {
21
- const o = a(t, n), e = {};
22
- for (const r of n.viewports)
23
- e[r] = a(t, n, r);
21
+ const i = a(t, n), e = {};
22
+ for (const o of n.viewports)
23
+ e[o] = a(t, n, o);
24
24
  return {
25
- ...o,
25
+ ...i,
26
26
  viewports: e
27
27
  };
28
28
  }
@@ -1,40 +1,40 @@
1
- import { defineComponent as L, computed as m, ref as N, onMounted as T, onUnmounted as C, createElementBlock as h, openBlock as v, normalizeClass as _, createElementVNode as D, Fragment as I, renderList as j, toDisplayString as z } from "vue";
2
- let M = null;
1
+ import { defineComponent as L, computed as h, ref as N, onMounted as T, onUnmounted as C, createElementBlock as m, openBlock as v, normalizeClass as x, createElementVNode as D, Fragment as I, renderList as j, toDisplayString as z } from "vue";
2
+ let E = null;
3
3
  function G(n) {
4
- M = n;
4
+ E = n;
5
5
  }
6
6
  function B() {
7
- return M;
7
+ return E;
8
8
  }
9
9
  function V(n, e) {
10
10
  return n.screenshots[e];
11
11
  }
12
12
  function F(n, e = {}) {
13
- const { slug: r, format: t } = n, { viewport: a, colorScheme: o } = e, s = [r];
14
- a && s.push(a), o && s.push(o);
13
+ const { slug: o, format: t } = n, { viewport: s, colorScheme: a } = e, r = [o];
14
+ s && r.push(s), a && r.push(a);
15
15
  const l = t === "jpeg" ? "jpg" : "png";
16
- return `${s.join("-")}.${l}`;
16
+ return `${r.join("-")}.${l}`;
17
17
  }
18
- function O(n, e, r = {}) {
19
- const t = F(e, r);
20
- return `${n.outputDirectory}/${t}`;
18
+ function O(n, e, o = {}) {
19
+ const t = F(e, o), s = n.outputDirectory;
20
+ return `${s.startsWith("/") ? "" : "/"}${s}/${t}`;
21
21
  }
22
- function E(n, e, r) {
23
- const { colorSchemes: t } = e, a = t.length > 0, o = (l) => O(n, e, { viewport: r, colorScheme: l }), s = {
24
- default: a ? o("light") : o()
22
+ function _(n, e, o) {
23
+ const { colorSchemes: t } = e, s = t.length > 0, a = (l) => O(n, e, { viewport: o, colorScheme: l }), r = {
24
+ default: s ? a("light") : a()
25
25
  };
26
- return t.includes("light") && (s.light = o("light")), t.includes("dark") && (s.dark = o("dark")), s;
26
+ return t.includes("light") && (r.light = a("light")), t.includes("dark") && (r.dark = a("dark")), r;
27
27
  }
28
- function A(n, e) {
29
- const r = E(n, e), t = {};
30
- for (const a of e.viewports)
31
- t[a] = E(n, e, a);
28
+ function W(n, e) {
29
+ const o = _(n, e), t = {};
30
+ for (const s of e.viewports)
31
+ t[s] = _(n, e, s);
32
32
  return {
33
- ...r,
33
+ ...o,
34
34
  viewports: t
35
35
  };
36
36
  }
37
- const W = ["srcset", "media"], Q = ["src", "alt"], R = ["src", "alt"], U = {
37
+ const A = ["srcset", "media"], Q = ["src", "alt"], R = ["src", "alt"], U = {
38
38
  key: 2,
39
39
  style: { color: "red", "font-size": "12px" }
40
40
  }, J = /* @__PURE__ */ L({
@@ -46,78 +46,78 @@ const W = ["srcset", "media"], Q = ["src", "alt"], R = ["src", "alt"], U = {
46
46
  class: {}
47
47
  },
48
48
  setup(n) {
49
- const e = n, r = m(() => e.manifest ?? B()), t = N(!1);
50
- let a = !1;
51
- function o() {
52
- return globalThis.window === void 0 ? !1 : document.documentElement.classList.contains("dark") ? !0 : a ? !1 : !!globalThis.matchMedia?.("(prefers-color-scheme: dark)").matches;
49
+ const e = n, o = h(() => e.manifest ?? B()), t = N(!1);
50
+ let s = !1;
51
+ function a() {
52
+ return globalThis.window === void 0 ? !1 : document.documentElement.classList.contains("dark") ? !0 : s ? !1 : !!globalThis.matchMedia?.("(prefers-color-scheme: dark)").matches;
53
53
  }
54
54
  T(() => {
55
- a = document.documentElement.classList.length > 0 || document.documentElement.dataset.theme !== void 0, t.value = o();
56
- const u = new MutationObserver(() => {
57
- a = !0, t.value = document.documentElement.classList.contains("dark");
55
+ s = document.documentElement.classList.length > 0 || document.documentElement.dataset.theme !== void 0, t.value = a();
56
+ const i = new MutationObserver(() => {
57
+ s = !0, t.value = document.documentElement.classList.contains("dark");
58
58
  });
59
- u.observe(document.documentElement, {
59
+ i.observe(document.documentElement, {
60
60
  attributes: !0,
61
61
  attributeFilter: ["class"]
62
62
  });
63
- const c = globalThis.matchMedia?.("(prefers-color-scheme: dark)"), i = () => {
64
- t.value = o();
63
+ const c = globalThis.matchMedia?.("(prefers-color-scheme: dark)"), u = () => {
64
+ t.value = a();
65
65
  };
66
- c?.addEventListener("change", i), C(() => {
67
- u.disconnect(), c?.removeEventListener("change", i);
66
+ c?.addEventListener("change", u), C(() => {
67
+ i.disconnect(), c?.removeEventListener("change", u);
68
68
  });
69
69
  });
70
- const s = m(() => r.value ? V(r.value, e.name) : null), l = m(() => !s.value || !r.value ? null : A(r.value, s.value)), w = m(() => {
70
+ const r = h(() => o.value ? V(o.value, e.name) : null), l = h(() => !r.value || !o.value ? null : W(o.value, r.value)), w = h(() => {
71
71
  if (!l.value) return "";
72
- const { light: u, dark: c } = l.value;
73
- return t.value && c ? c : !t.value && u ? u : l.value.default;
72
+ const { light: i, dark: c } = l.value;
73
+ return t.value && c ? c : !t.value && i ? i : l.value.default;
74
74
  }), g = {
75
75
  mobile: 430,
76
76
  // iPhone 15/16 Pro Max viewport
77
77
  tablet: 768,
78
78
  desktop: 1280
79
- }, y = m(() => {
80
- if (!l.value || !s.value) return [];
81
- const { viewports: u } = l.value, c = Object.keys(u);
79
+ }, y = h(() => {
80
+ if (!l.value || !r.value) return [];
81
+ const { viewports: i } = l.value, c = Object.keys(i);
82
82
  if (c.length === 0) return [];
83
- const i = [...c].sort((f, p) => {
83
+ const u = [...c].sort((f, p) => {
84
84
  const d = g[f] || Number.parseInt(f.split("x")[0] || "1280", 10), b = g[p] || Number.parseInt(p.split("x")[0] || "1280", 10);
85
85
  return d - b;
86
86
  });
87
- return i.map((f, p) => {
88
- const d = u[f];
87
+ return u.map((f, p) => {
88
+ const d = i[f];
89
89
  if (!d) return null;
90
- const b = d.light || d.default, P = d.dark || d.light || d.default, S = g[f] || Number.parseInt(f.split("x")[0] || "1280", 10), $ = p === i.length - 1, H = t.value ? P : b;
90
+ const b = d.light || d.default, $ = d.dark || d.light || d.default, S = g[f] || Number.parseInt(f.split("x")[0] || "1280", 10), P = p === u.length - 1, H = t.value ? $ : b;
91
91
  return {
92
92
  viewport: f,
93
93
  srcset: H,
94
94
  width: S,
95
95
  // Media query: max-width for this viewport (except for largest which is fallback)
96
- media: $ ? void 0 : `(max-width: ${S}px)`
96
+ media: P ? void 0 : `(max-width: ${S}px)`
97
97
  };
98
98
  }).filter(Boolean);
99
- }), x = m(() => y.value.length > 0), k = m(() => r.value ? s.value ? null : `Heroshot: Screenshot "${e.name}" not found in config` : "Heroshot: No manifest found. Add heroshot() plugin to vite config or pass manifest prop.");
100
- return k.value && typeof console < "u" && console.warn(k.value), (u, c) => s.value && x.value ? (v(), h("picture", {
99
+ }), M = h(() => y.value.length > 0), k = h(() => o.value ? r.value ? null : `Heroshot: Screenshot "${e.name}" not found in config` : "Heroshot: No manifest found. Add heroshot() plugin to vite config or pass manifest prop.");
100
+ return k.value && typeof console < "u" && console.warn(k.value), (i, c) => r.value && M.value ? (v(), m("picture", {
101
101
  key: 0,
102
- class: _(e.class)
102
+ class: x(e.class)
103
103
  }, [
104
- (v(!0), h(I, null, j(y.value, (i) => (v(), h("source", {
105
- key: `${i.viewport}-${t.value}`,
106
- srcset: i.srcset,
107
- media: i.media
108
- }, null, 8, W))), 128)),
104
+ (v(!0), m(I, null, j(y.value, (u) => (v(), m("source", {
105
+ key: `${u.viewport}-${t.value}`,
106
+ srcset: u.srcset,
107
+ media: u.media
108
+ }, null, 8, A))), 128)),
109
109
  D("img", {
110
110
  src: w.value,
111
111
  alt: n.alt,
112
112
  loading: "lazy"
113
113
  }, null, 8, Q)
114
- ], 2)) : s.value ? (v(), h("img", {
114
+ ], 2)) : r.value ? (v(), m("img", {
115
115
  key: 1,
116
116
  src: w.value,
117
117
  alt: n.alt,
118
- class: _(e.class),
118
+ class: x(e.class),
119
119
  loading: "lazy"
120
- }, null, 10, R)) : (v(), h("span", U, z(k.value), 1));
120
+ }, null, 10, R)) : (v(), m("span", U, z(k.value), 1));
121
121
  }
122
122
  });
123
123
  export {
package/dist/mcp/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { _ as loadConfig, b as screenshotSchema, g as getConfigPath, i as filterScreenshots, r as sync, t as generateSnippets, v as saveConfig, x as generateUid } from "../snippet-B6Lg_Ant.js";
2
+ import { _ as loadConfig, b as screenshotSchema, g as getConfigPath, i as filterScreenshots, r as sync, t as generateSnippets, v as saveConfig, x as generateUid } from "../snippet-Fc-PkcTD.js";
3
3
  import { z } from "zod";
4
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
5
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -190,7 +190,7 @@ const resizeActionSchema = z.object({
190
190
  }).describe("Resize the browser viewport mid-flow.");
191
191
  const hideActionSchema = z.object({
192
192
  type: z.literal("hide"),
193
- selectors: z.array(z.string()).describe("Element selectors to hide (display: none)")
193
+ selectors: z.array(z.string()).describe("Element selectors to hide (visibility: hidden)")
194
194
  }).describe("Hide elements from screenshot. Use to remove cookie banners, chat widgets, ads.");
195
195
  /** Union of all supported action types. Actions execute sequentially before screenshot. */
196
196
  const actionSchema = z.discriminatedUnion("type", [
@@ -370,7 +370,8 @@ const configSchema = z.object({
370
370
  jpegQuality: z.number().int().min(1).max(100).default(80).describe("JPEG compression quality (1-100), only used when outputFormat is \"jpeg\""),
371
371
  browser: browserSchema.optional().describe("Default browser settings applied to all screenshots"),
372
372
  workers: z.number().int().min(1).optional().describe("Number of parallel capture workers (default: 1)"),
373
- screenshots: z.array(screenshotSchema).default([]).describe("Screenshot definitions")
373
+ screenshots: z.array(screenshotSchema).default([]).describe("Screenshot definitions"),
374
+ hiddenElements: z.record(z.string(), z.array(z.string())).optional().describe("Elements to hide per domain (hostname → CSS selectors)")
374
375
  });
375
376
 
376
377
  //#endregion
@@ -793,7 +794,8 @@ function buildCaptureOptions(config, viewportOnly) {
793
794
  return {
794
795
  format: config.outputFormat ?? "png",
795
796
  quality: config.jpegQuality,
796
- fullPage: !viewportOnly
797
+ fullPage: !viewportOnly,
798
+ hiddenElements: config.hiddenElements
797
799
  };
798
800
  }
799
801
  /**
@@ -957,11 +959,11 @@ function executeHandleDialog(page, action) {
957
959
 
958
960
  //#endregion
959
961
  //#region src/sync/actions/hide.ts
960
- /** Hide elements by setting display: none */
962
+ /** Hide elements by setting visibility: hidden (preserves layout) */
961
963
  async function executeHide(page, action) {
962
964
  if (action.type !== "hide") return;
963
965
  for (const selector of action.selectors) await page.locator(selector).evaluateAll((elements) => {
964
- for (const element of elements) element.style.display = "none";
966
+ for (const element of elements) element.style.setProperty("visibility", "hidden", "important");
965
967
  });
966
968
  }
967
969
 
@@ -1861,6 +1863,14 @@ async function captureScreenshot(page, screenshot, outputDirectory, captureOptio
1861
1863
  ...navResult,
1862
1864
  filename
1863
1865
  };
1866
+ if (captureOptions.hiddenElements) {
1867
+ const { hiddenElements: hiddenByDomain } = captureOptions;
1868
+ const { hostname } = new URL(url);
1869
+ if (hiddenByDomain[hostname]?.length) await executeHide(page, {
1870
+ type: "hide",
1871
+ selectors: hiddenByDomain[hostname]
1872
+ });
1873
+ }
1864
1874
  if (screenshot.actions && screenshot.actions.length > 0) try {
1865
1875
  await executeActions(page, screenshot.actions);
1866
1876
  await page.waitForTimeout(500);