@accelerated-agency/visual-editor 0.1.2 → 0.1.3

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.
Files changed (2) hide show
  1. package/dist/vite.js +244 -226
  2. package/package.json +1 -1
package/dist/vite.js CHANGED
@@ -1766,246 +1766,264 @@ var getDefaultAnthropicApiKey = () => {
1766
1766
  return "";
1767
1767
  }
1768
1768
  };
1769
- function visualEditorProxyPlugin(options) {
1769
+ function createVisualEditorMiddleware(options) {
1770
1770
  const anthropicApiKey = options?.anthropicApiKey || getDefaultAnthropicApiKey();
1771
1771
  const enableGenerateTestApi = options?.enableGenerateTestApi ?? true;
1772
- return {
1773
- name: "visual-editor-proxy",
1774
- configureServer(server) {
1775
- server.middlewares.use("/bridge.js", (_req, res) => {
1776
- res.setHeader("Content-Type", "application/javascript; charset=utf-8");
1777
- res.setHeader("Cache-Control", "no-store");
1778
- res.end(BRIDGE_SCRIPT);
1779
- });
1780
- server.middlewares.use("/vvveb-editor", (_req, res) => {
1781
- res.setHeader("Content-Type", "text/html; charset=utf-8");
1782
- res.setHeader("Cache-Control", "no-store");
1783
- res.setHeader("X-Frame-Options", "SAMEORIGIN");
1784
- res.end(buildVvvebEditorHtml());
1785
- });
1786
- if (enableGenerateTestApi) {
1787
- server.middlewares.use("/api/generate-test", async (req, res) => {
1788
- if (req.method === "OPTIONS") {
1789
- res.setHeader("Access-Control-Allow-Origin", "*");
1790
- res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
1791
- res.setHeader("Access-Control-Allow-Headers", "Content-Type");
1792
- res.statusCode = 204;
1793
- res.end();
1794
- return;
1795
- }
1796
- if (req.method !== "POST") {
1797
- res.statusCode = 405;
1798
- res.end(JSON.stringify({ error: "Method not allowed" }));
1799
- return;
1800
- }
1801
- if (!anthropicApiKey) {
1802
- res.statusCode = 500;
1803
- res.setHeader("Content-Type", "application/json");
1804
- res.end(
1805
- JSON.stringify({ error: "ANTHROPIC_API_KEY is not configured" })
1806
- );
1807
- return;
1808
- }
1809
- try {
1810
- const chunks = [];
1811
- for await (const chunk of req) chunks.push(chunk);
1812
- const body = JSON.parse(Buffer.concat(chunks).toString());
1813
- if (!body.prompt || !body.pageSnapshot) {
1814
- res.statusCode = 400;
1815
- res.setHeader("Content-Type", "application/json");
1816
- res.end(JSON.stringify({ error: "Missing prompt or pageSnapshot" }));
1817
- return;
1818
- }
1819
- const parts = [
1820
- "## Optimization Goal",
1821
- body.prompt,
1822
- "",
1823
- "## Page Snapshot",
1824
- JSON.stringify(body.pageSnapshot, null, 2)
1825
- ];
1826
- const anthropicRes = await fetch("https://api.anthropic.com/v1/messages", {
1827
- method: "POST",
1828
- headers: {
1829
- "Content-Type": "application/json",
1830
- "x-api-key": anthropicApiKey,
1831
- "anthropic-version": "2023-06-01"
1832
- },
1833
- body: JSON.stringify({
1834
- model: "claude-sonnet-4-20250514",
1835
- max_tokens: 4096,
1836
- system: AI_SYSTEM_PROMPT,
1837
- messages: [{ role: "user", content: parts.join("\n") }]
1838
- })
1839
- });
1840
- if (!anthropicRes.ok) {
1841
- const errText = await anthropicRes.text();
1842
- res.statusCode = 502;
1843
- res.setHeader("Content-Type", "application/json");
1844
- res.end(
1845
- JSON.stringify({
1846
- error: `Anthropic API returned ${anthropicRes.status}`,
1847
- detail: errText
1848
- })
1849
- );
1850
- return;
1851
- }
1852
- const anthropicData = await anthropicRes.json();
1853
- const textBlock = anthropicData.content?.find((b) => b.type === "text");
1854
- if (!textBlock?.text) {
1855
- res.statusCode = 502;
1856
- res.setHeader("Content-Type", "application/json");
1857
- res.end(JSON.stringify({ error: "No text in Anthropic response" }));
1858
- return;
1859
- }
1860
- let cleaned = textBlock.text.trim();
1861
- if (cleaned.startsWith("```")) {
1862
- cleaned = cleaned.replace(/^```[a-zA-Z]*\n?/, "").replace(/\n?```\s*$/, "").trim();
1863
- }
1864
- let parsed;
1865
- try {
1866
- parsed = JSON.parse(cleaned);
1867
- } catch {
1868
- res.statusCode = 502;
1869
- res.setHeader("Content-Type", "application/json");
1870
- res.end(JSON.stringify({ error: "Invalid JSON from Claude", raw: cleaned }));
1871
- return;
1872
- }
1873
- const now = Date.now();
1874
- if (parsed.mutations) {
1875
- parsed.mutations = parsed.mutations.map((m, i) => ({
1876
- ...m,
1877
- id: m.id || `ai_mut_${String(i + 1).padStart(3, "0")}`,
1878
- timestamp: now + i
1879
- }));
1880
- }
1881
- res.setHeader("Content-Type", "application/json");
1882
- res.setHeader("Access-Control-Allow-Origin", "*");
1883
- res.end(JSON.stringify(parsed));
1884
- } catch (err) {
1885
- res.statusCode = 500;
1886
- res.setHeader("Content-Type", "application/json");
1887
- res.end(JSON.stringify({ error: err.message }));
1888
- }
1889
- });
1772
+ return async (req, res, next) => {
1773
+ const pathname = (req.url || "").split("?")[0];
1774
+ if (pathname === "/bridge.js") {
1775
+ res.setHeader("Content-Type", "application/javascript; charset=utf-8");
1776
+ res.setHeader("Cache-Control", "no-store");
1777
+ res.end(BRIDGE_SCRIPT);
1778
+ return;
1779
+ }
1780
+ if (pathname === "/vvveb-editor") {
1781
+ res.setHeader("Content-Type", "text/html; charset=utf-8");
1782
+ res.setHeader("Cache-Control", "no-store");
1783
+ res.setHeader("X-Frame-Options", "SAMEORIGIN");
1784
+ res.end(buildVvvebEditorHtml());
1785
+ return;
1786
+ }
1787
+ if (pathname === "/api/generate-test" && enableGenerateTestApi) {
1788
+ if (req.method === "OPTIONS") {
1789
+ res.setHeader("Access-Control-Allow-Origin", "*");
1790
+ res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
1791
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type");
1792
+ res.statusCode = 204;
1793
+ res.end();
1794
+ return;
1795
+ }
1796
+ if (req.method !== "POST") {
1797
+ res.statusCode = 405;
1798
+ res.end(JSON.stringify({ error: "Method not allowed" }));
1799
+ return;
1800
+ }
1801
+ if (!anthropicApiKey) {
1802
+ res.statusCode = 500;
1803
+ res.setHeader("Content-Type", "application/json");
1804
+ res.end(
1805
+ JSON.stringify({ error: "ANTHROPIC_API_KEY is not configured" })
1806
+ );
1807
+ return;
1890
1808
  }
1891
- server.middlewares.use("/api/proxy", async (req, res) => {
1809
+ try {
1810
+ const chunks = [];
1811
+ for await (const chunk of req) chunks.push(chunk);
1812
+ const body = JSON.parse(Buffer.concat(chunks).toString());
1813
+ if (!body.prompt || !body.pageSnapshot) {
1814
+ res.statusCode = 400;
1815
+ res.setHeader("Content-Type", "application/json");
1816
+ res.end(JSON.stringify({ error: "Missing prompt or pageSnapshot" }));
1817
+ return;
1818
+ }
1819
+ const parts = [
1820
+ "## Optimization Goal",
1821
+ body.prompt,
1822
+ "",
1823
+ "## Page Snapshot",
1824
+ JSON.stringify(body.pageSnapshot, null, 2)
1825
+ ];
1826
+ const anthropicRes = await fetch("https://api.anthropic.com/v1/messages", {
1827
+ method: "POST",
1828
+ headers: {
1829
+ "Content-Type": "application/json",
1830
+ "x-api-key": anthropicApiKey,
1831
+ "anthropic-version": "2023-06-01"
1832
+ },
1833
+ body: JSON.stringify({
1834
+ model: "claude-sonnet-4-20250514",
1835
+ max_tokens: 4096,
1836
+ system: AI_SYSTEM_PROMPT,
1837
+ messages: [{ role: "user", content: parts.join("\n") }]
1838
+ })
1839
+ });
1840
+ if (!anthropicRes.ok) {
1841
+ const errText = await anthropicRes.text();
1842
+ res.statusCode = 502;
1843
+ res.setHeader("Content-Type", "application/json");
1844
+ res.end(
1845
+ JSON.stringify({
1846
+ error: `Anthropic API returned ${anthropicRes.status}`,
1847
+ detail: errText
1848
+ })
1849
+ );
1850
+ return;
1851
+ }
1852
+ const anthropicData = await anthropicRes.json();
1853
+ const textBlock = anthropicData.content?.find((b) => b.type === "text");
1854
+ if (!textBlock?.text) {
1855
+ res.statusCode = 502;
1856
+ res.setHeader("Content-Type", "application/json");
1857
+ res.end(JSON.stringify({ error: "No text in Anthropic response" }));
1858
+ return;
1859
+ }
1860
+ let cleaned = textBlock.text.trim();
1861
+ if (cleaned.startsWith("```")) {
1862
+ cleaned = cleaned.replace(/^```[a-zA-Z]*\n?/, "").replace(/\n?```\s*$/, "").trim();
1863
+ }
1864
+ let parsed;
1892
1865
  try {
1893
- const url = new URL(req.url || "", "http://localhost");
1894
- const targetUrl = url.searchParams.get("url");
1895
- const password = url.searchParams.get("password") || "";
1896
- if (!targetUrl) {
1897
- res.statusCode = 400;
1898
- res.end(JSON.stringify({ error: "Missing url parameter" }));
1899
- return;
1900
- }
1901
- const parsed = new URL(targetUrl);
1902
- const origin = parsed.origin;
1903
- const method = (req.method || "GET").toUpperCase();
1904
- const headers = {
1905
- "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
1906
- Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
1907
- };
1908
- let cookieHeader = "";
1909
- if (password) {
1910
- const passResp = await fetch(`${origin}/password`, {
1911
- method: "POST",
1912
- headers: {
1913
- "Content-Type": "application/x-www-form-urlencoded",
1914
- ...headers
1915
- },
1916
- body: `form_type=storefront_password&utf8=%E2%9C%93&password=${encodeURIComponent(
1917
- password
1918
- )}`,
1919
- redirect: "manual"
1920
- });
1921
- const setCookies = passResp.headers.getSetCookie?.() || [];
1922
- cookieHeader = setCookies.map((c) => c.split(";")[0]).join("; ");
1923
- }
1924
- const fetchHeaders = { ...headers };
1925
- Object.entries(req.headers || {}).forEach(([key, value]) => {
1926
- const lowerKey = key.toLowerCase();
1927
- if (!value || [
1928
- "host",
1929
- "connection",
1930
- "content-length",
1931
- "accept-encoding",
1932
- "origin",
1933
- "referer"
1934
- ].includes(lowerKey)) {
1935
- return;
1936
- }
1937
- fetchHeaders[key] = Array.isArray(value) ? value.join(",") : String(value);
1938
- });
1939
- fetchHeaders.Origin = origin;
1940
- fetchHeaders.Referer = targetUrl;
1941
- if (cookieHeader) {
1942
- fetchHeaders.Cookie = fetchHeaders.Cookie ? `${fetchHeaders.Cookie}; ${cookieHeader}` : cookieHeader;
1943
- }
1944
- let requestBody;
1945
- if (!["GET", "HEAD"].includes(method)) {
1946
- const chunks = [];
1947
- for await (const chunk of req) {
1948
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
1949
- }
1950
- if (chunks.length > 0) requestBody = Buffer.concat(chunks);
1951
- }
1952
- const upstream = await fetch(targetUrl, {
1953
- method,
1954
- headers: fetchHeaders,
1955
- body: requestBody ? Buffer.from(requestBody) : null,
1956
- redirect: "follow"
1866
+ parsed = JSON.parse(cleaned);
1867
+ } catch {
1868
+ res.statusCode = 502;
1869
+ res.setHeader("Content-Type", "application/json");
1870
+ res.end(JSON.stringify({ error: "Invalid JSON from Claude", raw: cleaned }));
1871
+ return;
1872
+ }
1873
+ const now = Date.now();
1874
+ if (parsed.mutations) {
1875
+ parsed.mutations = parsed.mutations.map((m, i) => ({
1876
+ ...m,
1877
+ id: m.id || `ai_mut_${String(i + 1).padStart(3, "0")}`,
1878
+ timestamp: now + i
1879
+ }));
1880
+ }
1881
+ res.setHeader("Content-Type", "application/json");
1882
+ res.setHeader("Access-Control-Allow-Origin", "*");
1883
+ res.end(JSON.stringify(parsed));
1884
+ } catch (err) {
1885
+ res.statusCode = 500;
1886
+ res.setHeader("Content-Type", "application/json");
1887
+ res.end(JSON.stringify({ error: err.message }));
1888
+ }
1889
+ return;
1890
+ }
1891
+ if (pathname.startsWith("/api/proxy")) {
1892
+ try {
1893
+ const url = new URL(req.url || "", "http://localhost");
1894
+ const targetUrl = url.searchParams.get("url");
1895
+ const password = url.searchParams.get("password") || "";
1896
+ if (!targetUrl) {
1897
+ res.statusCode = 400;
1898
+ res.end(JSON.stringify({ error: "Missing url parameter" }));
1899
+ return;
1900
+ }
1901
+ const parsed = new URL(targetUrl);
1902
+ const origin = parsed.origin;
1903
+ const method = (req.method || "GET").toUpperCase();
1904
+ const headers = {
1905
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
1906
+ Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
1907
+ };
1908
+ let cookieHeader = "";
1909
+ if (password) {
1910
+ const passResp = await fetch(`${origin}/password`, {
1911
+ method: "POST",
1912
+ headers: {
1913
+ "Content-Type": "application/x-www-form-urlencoded",
1914
+ ...headers
1915
+ },
1916
+ body: `form_type=storefront_password&utf8=%E2%9C%93&password=${encodeURIComponent(
1917
+ password
1918
+ )}`,
1919
+ redirect: "manual"
1957
1920
  });
1958
- const responseContentType = upstream.headers.get("content-type") || "";
1959
- const isHtmlResponse = responseContentType.includes("text/html");
1960
- if (!isHtmlResponse) {
1961
- const binary = Buffer.from(await upstream.arrayBuffer());
1962
- res.statusCode = upstream.status;
1963
- if (responseContentType) {
1964
- res.setHeader("Content-Type", responseContentType);
1965
- }
1966
- res.setHeader("Access-Control-Allow-Origin", "*");
1967
- res.end(binary);
1968
- return;
1969
- }
1970
- let html = await upstream.text();
1971
- if (html.includes("form_type") && html.includes("storefront_password")) {
1972
- res.statusCode = 401;
1973
- res.end(JSON.stringify({ error: "Password authentication failed." }));
1921
+ const setCookies = passResp.headers.getSetCookie?.() || [];
1922
+ cookieHeader = setCookies.map((c) => c.split(";")[0]).join("; ");
1923
+ }
1924
+ const fetchHeaders = { ...headers };
1925
+ Object.entries(req.headers || {}).forEach(([key, value]) => {
1926
+ const lowerKey = key.toLowerCase();
1927
+ if (!value || [
1928
+ "host",
1929
+ "connection",
1930
+ "content-length",
1931
+ "accept-encoding",
1932
+ "origin",
1933
+ "referer"
1934
+ ].includes(lowerKey)) {
1974
1935
  return;
1975
1936
  }
1976
- html = html.replace(/(href|src|action)="\/(?!\/)/g, `$1="${origin}/`);
1977
- const escapedOrigin = origin.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1978
- const proxyBase = `/api/proxy?password=${encodeURIComponent(password)}&url=`;
1979
- html = html.replace(
1980
- new RegExp(`(href|src|action)="${escapedOrigin}(/[^"]*)"`, "g"),
1981
- (_, attr, urlPath) => `${attr}="${proxyBase}${encodeURIComponent(origin + urlPath)}"`
1982
- );
1983
- if (html.includes("</head>")) {
1984
- html = html.replace("</head>", `${popupHideCss}
1985
- </head>`);
1937
+ fetchHeaders[key] = Array.isArray(value) ? value.join(",") : String(value);
1938
+ });
1939
+ fetchHeaders.Origin = origin;
1940
+ fetchHeaders.Referer = targetUrl;
1941
+ if (cookieHeader) {
1942
+ fetchHeaders.Cookie = fetchHeaders.Cookie ? `${fetchHeaders.Cookie}; ${cookieHeader}` : cookieHeader;
1943
+ }
1944
+ let requestBody;
1945
+ if (!["GET", "HEAD"].includes(method)) {
1946
+ const chunks = [];
1947
+ for await (const chunk of req) {
1948
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
1986
1949
  }
1987
- const runtimeProxyScript = `<script>(function(){try{var TARGET_ORIGIN=${JSON.stringify(origin)};var TARGET_PAGE_URL=${JSON.stringify(targetUrl)};var PROXY_BASE=${JSON.stringify(`/api/proxy?password=${encodeURIComponent(password)}&url=`)};function isSkippable(raw){if(!raw||typeof raw!=="string")return true;return raw.startsWith("data:")||raw.startsWith("blob:")||raw.startsWith("javascript:")||raw.startsWith("#");}function toProxiedUrl(raw){if(isSkippable(raw))return raw;try{if(raw.startsWith("/api/proxy?"))return raw;var base=raw.startsWith("/")?TARGET_ORIGIN:TARGET_PAGE_URL;var abs=new URL(raw,base);if(abs.origin!==TARGET_ORIGIN)return raw;return PROXY_BASE+encodeURIComponent(abs.toString());}catch(_){return raw;}}if(window.fetch){var _fetch=window.fetch.bind(window);window.fetch=function(input,init){try{if(typeof input==="string"){input=toProxiedUrl(input);}else if(input&&input.url){var next=toProxiedUrl(input.url);if(next!==input.url){input=new Request(next,input);}}}catch(_){}return _fetch(input,init);};}if(window.XMLHttpRequest&&window.XMLHttpRequest.prototype&&window.XMLHttpRequest.prototype.open){var _open=window.XMLHttpRequest.prototype.open;window.XMLHttpRequest.prototype.open=function(method,url){try{arguments[1]=toProxiedUrl(url);}catch(_){}return _open.apply(this,arguments);};}if(window.navigator&&typeof window.navigator.sendBeacon==="function"){var _beacon=window.navigator.sendBeacon.bind(window.navigator);window.navigator.sendBeacon=function(url,data){try{return _beacon(toProxiedUrl(url),data);}catch(_){return _beacon(url,data);}};}if(window.navigator&&window.navigator.serviceWorker&&typeof window.navigator.serviceWorker.register==="function"){window.navigator.serviceWorker.register=function(){return Promise.resolve({scope:"disabled-in-editor-proxy"});};}}catch(_){}})();</script>`;
1988
- if (html.includes("</head>")) {
1989
- html = html.replace("</head>", `${runtimeProxyScript}
1990
- </head>`);
1991
- } else {
1992
- html = runtimeProxyScript + html;
1950
+ if (chunks.length > 0) requestBody = Buffer.concat(chunks);
1951
+ }
1952
+ const upstream = await fetch(targetUrl, {
1953
+ method,
1954
+ headers: fetchHeaders,
1955
+ body: requestBody ? Buffer.from(requestBody) : null,
1956
+ redirect: "follow"
1957
+ });
1958
+ const responseContentType = upstream.headers.get("content-type") || "";
1959
+ const isHtmlResponse = responseContentType.includes("text/html");
1960
+ if (!isHtmlResponse) {
1961
+ const binary = Buffer.from(await upstream.arrayBuffer());
1962
+ res.statusCode = upstream.status;
1963
+ if (responseContentType) {
1964
+ res.setHeader("Content-Type", responseContentType);
1993
1965
  }
1994
- const bridgeScript = `<script src="/bridge.js"></script>`;
1995
- html = html.includes("</body>") ? html.replace("</body>", `${bridgeScript}
1996
- </body>`) : html + bridgeScript;
1997
- res.setHeader("Content-Type", "text/html; charset=utf-8");
1998
1966
  res.setHeader("Access-Control-Allow-Origin", "*");
1999
- res.setHeader("X-Frame-Options", "SAMEORIGIN");
2000
- res.end(html);
2001
- } catch (err) {
2002
- res.statusCode = 500;
2003
- res.end(JSON.stringify({ error: err.message }));
1967
+ res.end(binary);
1968
+ return;
2004
1969
  }
2005
- });
1970
+ let html = await upstream.text();
1971
+ if (html.includes("form_type") && html.includes("storefront_password")) {
1972
+ res.statusCode = 401;
1973
+ res.end(JSON.stringify({ error: "Password authentication failed." }));
1974
+ return;
1975
+ }
1976
+ html = html.replace(/(href|src|action)="\/(?!\/)/g, `$1="${origin}/`);
1977
+ const escapedOrigin = origin.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1978
+ const proxyBase = `/api/proxy?password=${encodeURIComponent(password)}&url=`;
1979
+ html = html.replace(
1980
+ new RegExp(`(href|src|action)="${escapedOrigin}(/[^"]*)"`, "g"),
1981
+ (_, attr, urlPath) => `${attr}="${proxyBase}${encodeURIComponent(origin + urlPath)}"`
1982
+ );
1983
+ if (html.includes("</head>")) {
1984
+ html = html.replace("</head>", `${popupHideCss}
1985
+ </head>`);
1986
+ }
1987
+ const runtimeProxyScript = `<script>(function(){try{var TARGET_ORIGIN=${JSON.stringify(origin)};var TARGET_PAGE_URL=${JSON.stringify(targetUrl)};var PROXY_BASE=${JSON.stringify(`/api/proxy?password=${encodeURIComponent(password)}&url=`)};function isSkippable(raw){if(!raw||typeof raw!=="string")return true;return raw.startsWith("data:")||raw.startsWith("blob:")||raw.startsWith("javascript:")||raw.startsWith("#");}function toProxiedUrl(raw){if(isSkippable(raw))return raw;try{if(raw.startsWith("/api/proxy?"))return raw;var base=raw.startsWith("/")?TARGET_ORIGIN:TARGET_PAGE_URL;var abs=new URL(raw,base);if(abs.origin!==TARGET_ORIGIN)return raw;return PROXY_BASE+encodeURIComponent(abs.toString());}catch(_){return raw;}}if(window.fetch){var _fetch=window.fetch.bind(window);window.fetch=function(input,init){try{if(typeof input==="string"){input=toProxiedUrl(input);}else if(input&&input.url){var next=toProxiedUrl(input.url);if(next!==input.url){input=new Request(next,input);}}}catch(_){}return _fetch(input,init);};}if(window.XMLHttpRequest&&window.XMLHttpRequest.prototype&&window.XMLHttpRequest.prototype.open){var _open=window.XMLHttpRequest.prototype.open;window.XMLHttpRequest.prototype.open=function(method,url){try{arguments[1]=toProxiedUrl(url);}catch(_){}return _open.apply(this,arguments);};}if(window.navigator&&typeof window.navigator.sendBeacon==="function"){var _beacon=window.navigator.sendBeacon.bind(window.navigator);window.navigator.sendBeacon=function(url,data){try{return _beacon(toProxiedUrl(url),data);}catch(_){return _beacon(url,data);}};}if(window.navigator&&window.navigator.serviceWorker&&typeof window.navigator.serviceWorker.register==="function"){window.navigator.serviceWorker.register=function(){return Promise.resolve({scope:"disabled-in-editor-proxy"});};}}catch(_){}})();</script>`;
1988
+ if (html.includes("</head>")) {
1989
+ html = html.replace("</head>", `${runtimeProxyScript}
1990
+ </head>`);
1991
+ } else {
1992
+ html = runtimeProxyScript + html;
1993
+ }
1994
+ const bridgeScript = `<script src="/bridge.js"></script>`;
1995
+ html = html.includes("</body>") ? html.replace("</body>", `${bridgeScript}
1996
+ </body>`) : html + bridgeScript;
1997
+ res.setHeader("Content-Type", "text/html; charset=utf-8");
1998
+ res.setHeader("Access-Control-Allow-Origin", "*");
1999
+ res.setHeader("X-Frame-Options", "SAMEORIGIN");
2000
+ res.end(html);
2001
+ } catch (err) {
2002
+ res.statusCode = 500;
2003
+ res.end(JSON.stringify({ error: err.message }));
2004
+ }
2005
+ return;
2006
+ }
2007
+ next();
2008
+ };
2009
+ }
2010
+ function visualEditorProxyPlugin(options) {
2011
+ const mw = createVisualEditorMiddleware(options);
2012
+ return {
2013
+ name: "visual-editor-proxy",
2014
+ generateBundle() {
2015
+ this.emitFile({ type: "asset", fileName: "bridge.js", source: BRIDGE_SCRIPT });
2016
+ this.emitFile({ type: "asset", fileName: "vvveb-editor/index.html", source: buildVvvebEditorHtml() });
2017
+ },
2018
+ configureServer(server) {
2019
+ server.middlewares.use(mw);
2020
+ },
2021
+ configurePreviewServer(server) {
2022
+ server.middlewares.use(mw);
2006
2023
  }
2007
2024
  };
2008
2025
  }
2009
2026
  export {
2027
+ createVisualEditorMiddleware,
2010
2028
  visualEditorProxyPlugin
2011
2029
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@accelerated-agency/visual-editor",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "private": false,
5
5
  "description": "Conversion visual editor as a reusable React package",
6
6
  "type": "module",