@howone/sdk 0.1.27 → 0.1.28
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.
- package/dist/index.d.mts +54 -1
- package/dist/index.d.ts +54 -1
- package/dist/index.js +1059 -827
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1055 -827
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1518,7 +1518,7 @@ var LoginForm = ({
|
|
|
1518
1518
|
|
|
1519
1519
|
// src/components/auth/HowoneProvider.tsx
|
|
1520
1520
|
init_auth();
|
|
1521
|
-
import { createContext as createContext2, useContext as useContext2, useState as
|
|
1521
|
+
import { createContext as createContext2, useContext as useContext2, useState as useState7, useEffect as useEffect6 } from "react";
|
|
1522
1522
|
|
|
1523
1523
|
// src/components/theme/ThemeProvider.tsx
|
|
1524
1524
|
import { createContext, useContext, useEffect as useEffect3, useState as useState3 } from "react";
|
|
@@ -1586,869 +1586,444 @@ function GlobalToastContainer() {
|
|
|
1586
1586
|
);
|
|
1587
1587
|
}
|
|
1588
1588
|
|
|
1589
|
-
// src/components/
|
|
1590
|
-
import {
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
authUrl = "https://howone.dev/auth",
|
|
1600
|
-
redirectOnUnauthenticated = true
|
|
1589
|
+
// src/components/ElementSelectorProvider.tsx
|
|
1590
|
+
import { useEffect as useEffect5, useState as useState6, useCallback as useCallback3 } from "react";
|
|
1591
|
+
|
|
1592
|
+
// src/components/ElementSelector.tsx
|
|
1593
|
+
import { useEffect as useEffect4, useState as useState4, useCallback, useRef } from "react";
|
|
1594
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1595
|
+
var ElementSelector = ({
|
|
1596
|
+
active,
|
|
1597
|
+
onSelect,
|
|
1598
|
+
onCancel
|
|
1601
1599
|
}) => {
|
|
1602
|
-
const [
|
|
1603
|
-
const [
|
|
1604
|
-
const
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
if (
|
|
1610
|
-
const hashParams = new URLSearchParams(window.location.hash.slice(1));
|
|
1611
|
-
urlToken = hashParams.get("access_token") || hashParams.get("token");
|
|
1612
|
-
}
|
|
1613
|
-
if (urlToken) {
|
|
1614
|
-
console.log("[HowOneProvider] Token captured from URL, storing to localStorage...");
|
|
1615
|
-
setToken(urlToken);
|
|
1616
|
-
setTokenState(urlToken);
|
|
1617
|
-
setUser(parseUserFromToken(urlToken));
|
|
1618
|
-
params.delete("access_token");
|
|
1619
|
-
params.delete("token");
|
|
1620
|
-
params.delete("project_id");
|
|
1621
|
-
const newSearch = params.toString();
|
|
1622
|
-
const newUrl = window.location.pathname + (newSearch ? "?" + newSearch : "");
|
|
1623
|
-
window.history.replaceState({}, "", newUrl);
|
|
1624
|
-
console.log("[HowOneProvider] Token stored successfully, URL cleaned");
|
|
1625
|
-
}
|
|
1626
|
-
} catch (e) {
|
|
1627
|
-
console.error("[HowOneProvider] Failed to capture token from URL:", e);
|
|
1628
|
-
} finally {
|
|
1629
|
-
setHasCheckedUrlToken(true);
|
|
1630
|
-
}
|
|
1631
|
-
}, []);
|
|
1632
|
-
useEffect4(() => {
|
|
1633
|
-
if (!hasCheckedUrlToken) {
|
|
1634
|
-
return;
|
|
1635
|
-
}
|
|
1636
|
-
if (redirectOnUnauthenticated && !token && !user) {
|
|
1637
|
-
const currentUrl = new URL(window.location.href);
|
|
1638
|
-
if (!currentUrl.pathname.includes("/auth")) {
|
|
1639
|
-
console.log("[HowOneProvider] No token found, redirecting to auth page...");
|
|
1600
|
+
const [hoveredElement, setHoveredElement] = useState4(null);
|
|
1601
|
+
const [highlightRect, setHighlightRect] = useState4(null);
|
|
1602
|
+
const overlayRef = useRef(null);
|
|
1603
|
+
const getSourceLocation = useCallback((element) => {
|
|
1604
|
+
let current = element;
|
|
1605
|
+
while (current && current !== document.body) {
|
|
1606
|
+
const sourceLocationAttr = current.getAttribute("data-source-location");
|
|
1607
|
+
if (sourceLocationAttr) {
|
|
1640
1608
|
try {
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
if (projectId) {
|
|
1645
|
-
authUrlObj.searchParams.set("project_id", projectId);
|
|
1646
|
-
}
|
|
1647
|
-
console.log("[HowOneProvider] Redirecting to:", authUrlObj.toString());
|
|
1648
|
-
window.location.href = authUrlObj.toString();
|
|
1649
|
-
} catch (error) {
|
|
1650
|
-
console.error("[HowOneProvider] Failed to build auth URL:", error);
|
|
1651
|
-
window.location.href = authUrl;
|
|
1609
|
+
return JSON.parse(sourceLocationAttr.replace(/"/g, '"'));
|
|
1610
|
+
} catch (e) {
|
|
1611
|
+
console.error("Failed to parse source location:", e);
|
|
1652
1612
|
}
|
|
1653
1613
|
}
|
|
1614
|
+
current = current.parentElement;
|
|
1654
1615
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
isAuthenticated: !!token,
|
|
1668
|
-
logout
|
|
1669
|
-
};
|
|
1670
|
-
return /* @__PURE__ */ jsxs3(
|
|
1671
|
-
ThemeProvider,
|
|
1672
|
-
{
|
|
1673
|
-
defaultTheme,
|
|
1674
|
-
storageKey: themeStorageKey,
|
|
1675
|
-
forceDefault: forceDefaultTheme,
|
|
1676
|
-
children: [
|
|
1677
|
-
/* @__PURE__ */ jsxs3(HowoneContext.Provider, { value, children: [
|
|
1678
|
-
children,
|
|
1679
|
-
showFloatingButton && /* @__PURE__ */ jsx5(FloatingButton, { onClick: () => window.open("https://howone.ai", "_blank") })
|
|
1680
|
-
] }),
|
|
1681
|
-
/* @__PURE__ */ jsx5(GlobalToastContainer, {})
|
|
1682
|
-
]
|
|
1616
|
+
return null;
|
|
1617
|
+
}, []);
|
|
1618
|
+
const handleMouseMove = useCallback((e) => {
|
|
1619
|
+
if (!active) return;
|
|
1620
|
+
const elements = document.elementsFromPoint(e.clientX, e.clientY);
|
|
1621
|
+
const targetElement = elements.find(
|
|
1622
|
+
(el) => el !== overlayRef.current && !overlayRef.current?.contains(el) && el !== document.body && el !== document.documentElement
|
|
1623
|
+
);
|
|
1624
|
+
if (targetElement && targetElement !== hoveredElement) {
|
|
1625
|
+
setHoveredElement(targetElement);
|
|
1626
|
+
const rect = targetElement.getBoundingClientRect();
|
|
1627
|
+
setHighlightRect(rect);
|
|
1683
1628
|
}
|
|
1684
|
-
);
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
const
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1629
|
+
}, [active, hoveredElement]);
|
|
1630
|
+
const handleClick = useCallback((e) => {
|
|
1631
|
+
if (!active || !hoveredElement) return;
|
|
1632
|
+
e.preventDefault();
|
|
1633
|
+
e.stopPropagation();
|
|
1634
|
+
const sourceLocation = getSourceLocation(hoveredElement);
|
|
1635
|
+
const rect = hoveredElement.getBoundingClientRect();
|
|
1636
|
+
const elementData = {
|
|
1637
|
+
sourceLocation,
|
|
1638
|
+
element: {
|
|
1639
|
+
tagName: hoveredElement.tagName,
|
|
1640
|
+
className: hoveredElement.className,
|
|
1641
|
+
id: hoveredElement.id,
|
|
1642
|
+
text: hoveredElement.textContent?.substring(0, 100) || ""
|
|
1643
|
+
},
|
|
1644
|
+
rect: {
|
|
1645
|
+
top: rect.top,
|
|
1646
|
+
left: rect.left,
|
|
1647
|
+
width: rect.width,
|
|
1648
|
+
height: rect.height
|
|
1699
1649
|
}
|
|
1700
1650
|
};
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
// src/components/index.ts
|
|
1706
|
-
init_auth();
|
|
1707
|
-
|
|
1708
|
-
// src/howone/client.ts
|
|
1709
|
-
init_auth();
|
|
1710
|
-
init_config();
|
|
1711
|
-
var HowoneAuthClient = class {
|
|
1712
|
-
constructor() {
|
|
1713
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
1714
|
-
this.loading = false;
|
|
1715
|
-
}
|
|
1716
|
-
emit() {
|
|
1717
|
-
const state = {
|
|
1718
|
-
user: parseUserFromToken(getToken()),
|
|
1719
|
-
isLoading: this.loading
|
|
1720
|
-
};
|
|
1721
|
-
for (const l of this.listeners) {
|
|
1722
|
-
try {
|
|
1723
|
-
l(state);
|
|
1724
|
-
} catch (e) {
|
|
1725
|
-
void e;
|
|
1651
|
+
if (onSelect) {
|
|
1652
|
+
onSelect(elementData);
|
|
1653
|
+
if (onCancel) {
|
|
1654
|
+
onCancel();
|
|
1726
1655
|
}
|
|
1727
1656
|
}
|
|
1728
|
-
}
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1657
|
+
}, [active, hoveredElement, getSourceLocation, onSelect, onCancel]);
|
|
1658
|
+
useEffect4(() => {
|
|
1659
|
+
if (active) {
|
|
1660
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
1661
|
+
document.addEventListener("click", handleClick, true);
|
|
1662
|
+
document.body.style.overflow = "hidden";
|
|
1663
|
+
return () => {
|
|
1664
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
1665
|
+
document.removeEventListener("click", handleClick, true);
|
|
1666
|
+
document.body.style.overflow = "";
|
|
1667
|
+
};
|
|
1668
|
+
} else {
|
|
1669
|
+
setHoveredElement(null);
|
|
1670
|
+
setHighlightRect(null);
|
|
1735
1671
|
}
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
try {
|
|
1754
|
-
if (window.top && window.top !== window) {
|
|
1755
|
-
window.top.location.replace(authUrl.toString());
|
|
1756
|
-
} else {
|
|
1757
|
-
window.location.replace(authUrl.toString());
|
|
1672
|
+
}, [active, handleMouseMove, handleClick]);
|
|
1673
|
+
if (!active) return null;
|
|
1674
|
+
return /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1675
|
+
/* @__PURE__ */ jsx5(
|
|
1676
|
+
"div",
|
|
1677
|
+
{
|
|
1678
|
+
ref: overlayRef,
|
|
1679
|
+
style: {
|
|
1680
|
+
position: "fixed",
|
|
1681
|
+
top: 0,
|
|
1682
|
+
left: 0,
|
|
1683
|
+
right: 0,
|
|
1684
|
+
bottom: 0,
|
|
1685
|
+
backgroundColor: "rgba(0, 0, 0, 0.3)",
|
|
1686
|
+
zIndex: 999998,
|
|
1687
|
+
cursor: "crosshair",
|
|
1688
|
+
pointerEvents: "none"
|
|
1758
1689
|
}
|
|
1759
|
-
}
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1690
|
+
}
|
|
1691
|
+
),
|
|
1692
|
+
highlightRect && /* @__PURE__ */ jsx5(
|
|
1693
|
+
"div",
|
|
1694
|
+
{
|
|
1695
|
+
style: {
|
|
1696
|
+
position: "fixed",
|
|
1697
|
+
top: highlightRect.top,
|
|
1698
|
+
left: highlightRect.left,
|
|
1699
|
+
width: highlightRect.width,
|
|
1700
|
+
height: highlightRect.height,
|
|
1701
|
+
border: "2px dashed #36D2A6",
|
|
1702
|
+
borderRadius: "5px",
|
|
1703
|
+
backgroundColor: "rgba(54, 210, 166, 0.1)",
|
|
1704
|
+
zIndex: 999999,
|
|
1705
|
+
pointerEvents: "none",
|
|
1706
|
+
transition: "all 0.1s ease"
|
|
1763
1707
|
}
|
|
1764
1708
|
}
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1709
|
+
),
|
|
1710
|
+
hoveredElement && highlightRect && /* @__PURE__ */ jsx5(
|
|
1711
|
+
"div",
|
|
1712
|
+
{
|
|
1713
|
+
style: {
|
|
1714
|
+
position: "fixed",
|
|
1715
|
+
top: highlightRect.top - 30,
|
|
1716
|
+
left: highlightRect.left,
|
|
1717
|
+
backgroundColor: "#36D2A6",
|
|
1718
|
+
color: "white",
|
|
1719
|
+
padding: "4px 8px",
|
|
1720
|
+
borderRadius: "4px",
|
|
1721
|
+
fontSize: "12px",
|
|
1722
|
+
zIndex: 1e6,
|
|
1723
|
+
pointerEvents: "none",
|
|
1724
|
+
whiteSpace: "nowrap"
|
|
1725
|
+
},
|
|
1726
|
+
children: (() => {
|
|
1727
|
+
const location = getSourceLocation(hoveredElement);
|
|
1728
|
+
return location ? `${location.component} (${location.file}:${location.line})` : hoveredElement.tagName.toLowerCase();
|
|
1729
|
+
})()
|
|
1769
1730
|
}
|
|
1770
|
-
|
|
1771
|
-
}
|
|
1772
|
-
logout() {
|
|
1773
|
-
setToken(null);
|
|
1774
|
-
this.emit();
|
|
1775
|
-
}
|
|
1776
|
-
getUser() {
|
|
1777
|
-
return parseUserFromToken(getToken());
|
|
1778
|
-
}
|
|
1779
|
-
// helper to programmatically set token (e.g., after callback handling)
|
|
1780
|
-
setToken(token) {
|
|
1781
|
-
setToken(token);
|
|
1782
|
-
this.emit();
|
|
1783
|
-
}
|
|
1784
|
-
};
|
|
1785
|
-
var howone = {
|
|
1786
|
-
auth: new HowoneAuthClient()
|
|
1731
|
+
)
|
|
1732
|
+
] });
|
|
1787
1733
|
};
|
|
1788
|
-
var client_default = howone;
|
|
1789
1734
|
|
|
1790
|
-
// src/
|
|
1791
|
-
import {
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
})
|
|
1798
|
-
const
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1735
|
+
// src/hooks/use-element-selector.ts
|
|
1736
|
+
import { useState as useState5, useCallback as useCallback2 } from "react";
|
|
1737
|
+
function useElementSelector() {
|
|
1738
|
+
const [isSelecting, setIsSelecting] = useState5(false);
|
|
1739
|
+
const [selectedElement, setSelectedElement] = useState5(null);
|
|
1740
|
+
const startSelecting = useCallback2(() => {
|
|
1741
|
+
setIsSelecting(true);
|
|
1742
|
+
}, []);
|
|
1743
|
+
const stopSelecting = useCallback2(() => {
|
|
1744
|
+
setIsSelecting(false);
|
|
1745
|
+
}, []);
|
|
1746
|
+
const clearSelection = useCallback2(() => {
|
|
1747
|
+
setSelectedElement(null);
|
|
1748
|
+
}, []);
|
|
1749
|
+
return {
|
|
1750
|
+
isSelecting,
|
|
1751
|
+
selectedElement,
|
|
1752
|
+
startSelecting,
|
|
1753
|
+
stopSelecting,
|
|
1754
|
+
clearSelection
|
|
1802
1755
|
};
|
|
1803
|
-
|
|
1804
|
-
|
|
1756
|
+
}
|
|
1757
|
+
function sendElementSelectionToParent(data) {
|
|
1758
|
+
if (window.parent && window.parent !== window) {
|
|
1759
|
+
window.parent.postMessage({
|
|
1760
|
+
type: "ELEMENT_SELECTED",
|
|
1761
|
+
payload: data
|
|
1762
|
+
}, "*");
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
// src/components/ElementSelectorProvider.tsx
|
|
1767
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1768
|
+
var ElementSelectorProvider = ({ children }) => {
|
|
1769
|
+
const [isSelecting, setIsSelecting] = useState6(false);
|
|
1770
|
+
const handleCancel = useCallback3(() => {
|
|
1771
|
+
setIsSelecting(false);
|
|
1772
|
+
if (window.parent && window.parent !== window) {
|
|
1773
|
+
window.parent.postMessage({
|
|
1774
|
+
type: "ELEMENT_SELECTION_CANCELLED"
|
|
1775
|
+
}, "*");
|
|
1776
|
+
}
|
|
1777
|
+
console.log("\u{1F6AB} \u5143\u7D20\u9009\u62E9\u5DF2\u53D6\u6D88 (ESC)");
|
|
1778
|
+
}, []);
|
|
1779
|
+
const handleSelect = useCallback3((data) => {
|
|
1780
|
+
sendElementSelectionToParent(data);
|
|
1781
|
+
console.log("\u{1F3AF} \u5143\u7D20\u5DF2\u9009\u4E2D:", data.element.tagName, data.sourceLocation?.file);
|
|
1782
|
+
}, []);
|
|
1783
|
+
useEffect5(() => {
|
|
1784
|
+
const handleStartSelection = () => {
|
|
1785
|
+
setIsSelecting(true);
|
|
1786
|
+
};
|
|
1787
|
+
const handleCancelSelection = () => {
|
|
1788
|
+
handleCancel();
|
|
1789
|
+
};
|
|
1790
|
+
window.addEventListener("howone:start-element-selection", handleStartSelection);
|
|
1791
|
+
window.addEventListener("howone:cancel-element-selection", handleCancelSelection);
|
|
1792
|
+
const handleMessage = (event) => {
|
|
1793
|
+
if (event.data.type === "START_ELEMENT_SELECTION") {
|
|
1794
|
+
setIsSelecting(true);
|
|
1795
|
+
} else if (event.data.type === "CANCEL_ELEMENT_SELECTION") {
|
|
1796
|
+
handleCancel();
|
|
1797
|
+
}
|
|
1798
|
+
};
|
|
1799
|
+
window.addEventListener("message", handleMessage);
|
|
1800
|
+
return () => {
|
|
1801
|
+
window.removeEventListener("howone:start-element-selection", handleStartSelection);
|
|
1802
|
+
window.removeEventListener("howone:cancel-element-selection", handleCancelSelection);
|
|
1803
|
+
window.removeEventListener("message", handleMessage);
|
|
1804
|
+
};
|
|
1805
|
+
}, [handleCancel]);
|
|
1806
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1807
|
+
children,
|
|
1805
1808
|
/* @__PURE__ */ jsx6(
|
|
1806
|
-
|
|
1809
|
+
ElementSelector,
|
|
1807
1810
|
{
|
|
1808
|
-
|
|
1811
|
+
active: isSelecting,
|
|
1812
|
+
onSelect: handleSelect,
|
|
1813
|
+
onCancel: handleCancel
|
|
1809
1814
|
}
|
|
1810
|
-
)
|
|
1811
|
-
|
|
1812
|
-
] }) });
|
|
1813
|
-
};
|
|
1814
|
-
var LoadingSpinner = ({
|
|
1815
|
-
size = "md",
|
|
1816
|
-
className = ""
|
|
1817
|
-
}) => {
|
|
1818
|
-
const sizeClasses = {
|
|
1819
|
-
sm: "h-4 w-4",
|
|
1820
|
-
md: "h-8 w-8",
|
|
1821
|
-
lg: "h-12 w-12"
|
|
1822
|
-
};
|
|
1823
|
-
return /* @__PURE__ */ jsx6(
|
|
1824
|
-
"div",
|
|
1825
|
-
{
|
|
1826
|
-
className: `animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 ${sizeClasses[size]} ${className}`
|
|
1827
|
-
}
|
|
1828
|
-
);
|
|
1815
|
+
)
|
|
1816
|
+
] });
|
|
1829
1817
|
};
|
|
1830
1818
|
|
|
1831
|
-
// src/
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1819
|
+
// src/utils/unified-error-handler/types.ts
|
|
1820
|
+
var ERROR_CONFIG = {
|
|
1821
|
+
MAX_ERRORS: 100,
|
|
1822
|
+
MAX_INTERACTIONS: 50,
|
|
1823
|
+
DEDUP_WINDOW: 1e3,
|
|
1824
|
+
DEBOUNCE_TIME: 100,
|
|
1825
|
+
CACHE_DURATION: 3e5,
|
|
1826
|
+
SEVERITY_KEYWORDS: {
|
|
1827
|
+
CRITICAL: ["fatal", "critical", "security", "crash", "corruption"],
|
|
1828
|
+
HIGH: ["error", "exception", "failed", "timeout", "network error"],
|
|
1829
|
+
MEDIUM: ["warning", "deprecated", "slow", "performance"],
|
|
1830
|
+
LOW: ["info", "debug", "trace", "notice"]
|
|
1831
|
+
},
|
|
1832
|
+
CATEGORY_KEYWORDS: {
|
|
1833
|
+
SYNTAX: ["syntaxerror", "unexpected token", "parse error", "invalid syntax"],
|
|
1834
|
+
NETWORK: ["fetch", "xhr", "network", "cors", "timeout", "connection"],
|
|
1835
|
+
RUNTIME: ["referenceerror", "typeerror", "rangeerror", "undefined"],
|
|
1836
|
+
SECURITY: ["csp", "xss", "csrf", "security", "unauthorized"],
|
|
1837
|
+
PERFORMANCE: ["slow", "memory", "leak", "performance", "timeout"],
|
|
1838
|
+
DEVELOPMENT: ["vite", "hmr", "hot reload", "dev server", "webpack"],
|
|
1839
|
+
REACT: ["react", "jsx", "component", "hook", "render"],
|
|
1840
|
+
VITE: ["vite", "[vite]", "vite:react", "transform failed"]
|
|
1851
1841
|
}
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1842
|
+
};
|
|
1843
|
+
var GLOBAL_CONFIG = {
|
|
1844
|
+
ALLOWED_ORIGINS: [
|
|
1845
|
+
"https://howone.ai",
|
|
1846
|
+
"https://howone.dev",
|
|
1847
|
+
"http://localhost:3000",
|
|
1848
|
+
"http://localhost:5173"
|
|
1849
|
+
],
|
|
1850
|
+
DEBOUNCE_DELAY: 10,
|
|
1851
|
+
OVERRIDE_STYLESHEET_ID: "howone-override-styles"
|
|
1852
|
+
};
|
|
1853
|
+
var DEFAULT_SELECTOR_CONFIG = {
|
|
1854
|
+
HIGHLIGHT_COLOR: "#ff6b6b",
|
|
1855
|
+
HIGHLIGHT_BORDER_WIDTH: "2px",
|
|
1856
|
+
HIGHLIGHT_BORDER_STYLE: "solid",
|
|
1857
|
+
SELECTED_COLOR: "#4ecdc4",
|
|
1858
|
+
SELECTED_BORDER_WIDTH: "3px",
|
|
1859
|
+
TOOLTIP_BACKGROUND: "#333",
|
|
1860
|
+
TOOLTIP_COLOR: "#fff",
|
|
1861
|
+
TOOLTIP_PADDING: "8px 12px",
|
|
1862
|
+
TOOLTIP_BORDER_RADIUS: "4px",
|
|
1863
|
+
TOOLTIP_FONT_SIZE: "12px",
|
|
1864
|
+
TOOLTIP_Z_INDEX: "10000",
|
|
1865
|
+
FULL_WIDTH_TOOLTIP_OFFSET: 10,
|
|
1866
|
+
highlightClass: "howone-highlight",
|
|
1867
|
+
selectedClass: "howone-selected",
|
|
1868
|
+
cursor: "crosshair"
|
|
1869
|
+
};
|
|
1870
|
+
|
|
1871
|
+
// src/utils/unified-error-handler/utils/DeepSerializer.ts
|
|
1872
|
+
var CircularReference = class {
|
|
1873
|
+
constructor(path) {
|
|
1874
|
+
this.message = `[Circular Reference to ${path}]`;
|
|
1874
1875
|
}
|
|
1875
1876
|
};
|
|
1876
|
-
var
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1877
|
+
var TypeWrapper = class {
|
|
1878
|
+
constructor(type, value) {
|
|
1879
|
+
this._type = type;
|
|
1880
|
+
this.value = value;
|
|
1881
|
+
}
|
|
1882
|
+
};
|
|
1883
|
+
var DeepSerializer = class {
|
|
1884
|
+
/**
|
|
1885
|
+
* 深度序列化对象
|
|
1886
|
+
*/
|
|
1887
|
+
static serialize(obj, options = {}, visitedObjects = /* @__PURE__ */ new WeakMap(), path = "root") {
|
|
1888
|
+
const opts = { ...this.DEFAULT_OPTIONS, ...options };
|
|
1889
|
+
if (path.split(".").length > opts.maxDepth) {
|
|
1890
|
+
return new TypeWrapper(
|
|
1891
|
+
"MaxDepthReached",
|
|
1892
|
+
`[Max depth of ${opts.maxDepth} reached]`
|
|
1893
|
+
);
|
|
1885
1894
|
}
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
// src/components/theme/ThemeToggle.tsx
|
|
1890
|
-
import * as React4 from "react";
|
|
1891
|
-
import { Icon as Icon3 } from "@iconify/react";
|
|
1892
|
-
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1893
|
-
function ThemeToggle({ className }) {
|
|
1894
|
-
const { setTheme, theme } = useTheme();
|
|
1895
|
-
const [mounted, setMounted] = React4.useState(false);
|
|
1896
|
-
React4.useEffect(() => {
|
|
1897
|
-
setMounted(true);
|
|
1898
|
-
}, []);
|
|
1899
|
-
const handleToggle = () => {
|
|
1900
|
-
if (theme === "dark") {
|
|
1901
|
-
setTheme("light");
|
|
1902
|
-
} else {
|
|
1903
|
-
setTheme("dark");
|
|
1895
|
+
if (obj === void 0) {
|
|
1896
|
+
return new TypeWrapper("undefined", "undefined");
|
|
1904
1897
|
}
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
return /* @__PURE__ */ jsxs6(
|
|
1908
|
-
"button",
|
|
1909
|
-
{
|
|
1910
|
-
className: `relative inline-flex h-10 w-12 items-center justify-center rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground ${className || ""}`,
|
|
1911
|
-
disabled: true,
|
|
1912
|
-
children: [
|
|
1913
|
-
/* @__PURE__ */ jsx8(Icon3, { icon: "solar:sun-bold", width: 20, height: 20 }),
|
|
1914
|
-
/* @__PURE__ */ jsx8("span", { className: "sr-only", children: "\u5207\u6362\u4E3B\u9898" })
|
|
1915
|
-
]
|
|
1916
|
-
}
|
|
1917
|
-
);
|
|
1918
|
-
}
|
|
1919
|
-
return /* @__PURE__ */ jsxs6(
|
|
1920
|
-
"button",
|
|
1921
|
-
{
|
|
1922
|
-
className: `inline-flex h-10 w-12 items-center justify-center rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground transition-colors ${className || ""}`,
|
|
1923
|
-
onClick: handleToggle,
|
|
1924
|
-
children: [
|
|
1925
|
-
theme === "light" ? /* @__PURE__ */ jsx8(Icon3, { icon: "solar:sun-bold", width: 20, height: 20 }) : /* @__PURE__ */ jsx8(Icon3, { icon: "solar:moon-linear", width: 20, height: 20 }),
|
|
1926
|
-
/* @__PURE__ */ jsx8("span", { className: "sr-only", children: "\u5207\u6362\u4E3B\u9898" })
|
|
1927
|
-
]
|
|
1898
|
+
if (obj === null) {
|
|
1899
|
+
return null;
|
|
1928
1900
|
}
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
import { Bounce, toast } from "react-toastify";
|
|
1935
|
-
import { Icon as Icon4 } from "@iconify/react";
|
|
1936
|
-
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1937
|
-
var TOAST_ICONS = {
|
|
1938
|
-
success: {
|
|
1939
|
-
icon: "mdi:success",
|
|
1940
|
-
color: "text-green-400",
|
|
1941
|
-
className: "text-green-400",
|
|
1942
|
-
// 深色主题配置
|
|
1943
|
-
dark: {
|
|
1944
|
-
bgGradient: "bg-[#14181d]",
|
|
1945
|
-
// 移除透明度 f2
|
|
1946
|
-
gradientColor: "#389726",
|
|
1947
|
-
borderGradient: "border-[#389726]",
|
|
1948
|
-
borderGradientColor: "#389726"
|
|
1949
|
-
},
|
|
1950
|
-
// 浅色主题配置
|
|
1951
|
-
light: {
|
|
1952
|
-
bgGradient: "bg-[#fafafa]",
|
|
1953
|
-
// 移除透明度 ff
|
|
1954
|
-
gradientColor: "#22c55e",
|
|
1955
|
-
borderGradient: "border-[#22c55e]",
|
|
1956
|
-
borderGradientColor: "#22c55e"
|
|
1901
|
+
if (typeof obj === "string") {
|
|
1902
|
+
return obj.length > opts.maxStringLength ? new TypeWrapper(
|
|
1903
|
+
"String",
|
|
1904
|
+
`${obj.slice(0, opts.maxStringLength)}... [${obj.length - opts.maxStringLength} more characters]`
|
|
1905
|
+
) : obj;
|
|
1957
1906
|
}
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
icon: "ic:outline-close",
|
|
1961
|
-
color: "text-red-400",
|
|
1962
|
-
className: "text-red-400",
|
|
1963
|
-
dark: {
|
|
1964
|
-
bgGradient: "bg-[#14181d]",
|
|
1965
|
-
// 移除透明度 f2
|
|
1966
|
-
gradientColor: "#ef4444",
|
|
1967
|
-
borderGradient: "border-[#ef4444]",
|
|
1968
|
-
borderGradientColor: "#ef4444"
|
|
1969
|
-
},
|
|
1970
|
-
light: {
|
|
1971
|
-
bgGradient: "bg-[#fafafa]",
|
|
1972
|
-
// 移除透明度 ff
|
|
1973
|
-
gradientColor: "#f87171",
|
|
1974
|
-
borderGradient: "border-[#f87171]",
|
|
1975
|
-
borderGradientColor: "#f87171"
|
|
1907
|
+
if (typeof obj === "number") {
|
|
1908
|
+
return Number.isNaN(obj) ? new TypeWrapper("Number", "NaN") : Number.isFinite(obj) ? obj : new TypeWrapper("Number", obj > 0 ? "Infinity" : "-Infinity");
|
|
1976
1909
|
}
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
icon: "mi:warning",
|
|
1980
|
-
color: "text-yellow-400",
|
|
1981
|
-
className: "text-yellow-400",
|
|
1982
|
-
dark: {
|
|
1983
|
-
bgGradient: "bg-[#14181d]",
|
|
1984
|
-
// 移除透明度 f2
|
|
1985
|
-
gradientColor: "#facc15",
|
|
1986
|
-
borderGradient: "border-[#facc15]",
|
|
1987
|
-
borderGradientColor: "#facc15"
|
|
1988
|
-
},
|
|
1989
|
-
light: {
|
|
1990
|
-
bgGradient: "bg-[#fafafa]",
|
|
1991
|
-
// 移除透明度 ff
|
|
1992
|
-
gradientColor: "#f59e0b",
|
|
1993
|
-
borderGradient: "border-[#f59e0b]",
|
|
1994
|
-
borderGradientColor: "#f59e0b"
|
|
1910
|
+
if (typeof obj === "boolean") {
|
|
1911
|
+
return obj;
|
|
1995
1912
|
}
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
icon: "ic:outline-info",
|
|
1999
|
-
color: "text-blue-400",
|
|
2000
|
-
className: "text-blue-400",
|
|
2001
|
-
dark: {
|
|
2002
|
-
bgGradient: "bg-[#14181d]",
|
|
2003
|
-
// 移除透明度 f2
|
|
2004
|
-
gradientColor: "#60a5fa",
|
|
2005
|
-
borderGradient: "border-[#60a5fa]",
|
|
2006
|
-
borderGradientColor: "#f0f0f0"
|
|
2007
|
-
},
|
|
2008
|
-
light: {
|
|
2009
|
-
bgGradient: "bg-[#fafafa]",
|
|
2010
|
-
// 移除透明度 ff
|
|
2011
|
-
gradientColor: "#3b82f6",
|
|
2012
|
-
borderGradient: "border-[#3b82f6]",
|
|
2013
|
-
borderGradientColor: "#3b82f6"
|
|
1913
|
+
if (typeof obj === "bigint") {
|
|
1914
|
+
return new TypeWrapper("BigInt", obj.toString());
|
|
2014
1915
|
}
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
icon: "ic:round-notifications",
|
|
2018
|
-
color: "text-gray-400",
|
|
2019
|
-
className: "text-gray-400",
|
|
2020
|
-
dark: {
|
|
2021
|
-
bgGradient: "bg-[#14181d]",
|
|
2022
|
-
// 移除透明度 f2
|
|
2023
|
-
gradientColor: "#9ca3af",
|
|
2024
|
-
borderGradient: "border-[#9ca3af]",
|
|
2025
|
-
borderGradientColor: "#9ca3af"
|
|
2026
|
-
},
|
|
2027
|
-
light: {
|
|
2028
|
-
bgGradient: "bg-[#fafafa]",
|
|
2029
|
-
// 移除透明度 ff
|
|
2030
|
-
gradientColor: "#6b7280",
|
|
2031
|
-
borderGradient: "border-[#6b7280]",
|
|
2032
|
-
borderGradientColor: "#6b7280"
|
|
1916
|
+
if (typeof obj === "symbol") {
|
|
1917
|
+
return new TypeWrapper("Symbol", obj.toString());
|
|
2033
1918
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
2045
|
-
return actualTheme === "dark" ? "#b4b4b4" : "#6b7280";
|
|
2046
|
-
};
|
|
2047
|
-
const getCloseButtonHoverColor = () => {
|
|
2048
|
-
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
2049
|
-
return actualTheme === "dark" ? "white" : "#374151";
|
|
2050
|
-
};
|
|
2051
|
-
return /* @__PURE__ */ jsx9(
|
|
2052
|
-
Icon4,
|
|
2053
|
-
{
|
|
2054
|
-
icon: "vaadin:close",
|
|
2055
|
-
className: "flex items-center justify-center rounded-full relative z-10 flex-shrink-0 cursor-pointer \n transition-colors duration-200 drop-shadow-sm",
|
|
2056
|
-
onClick: handleClick,
|
|
2057
|
-
width: 14,
|
|
2058
|
-
height: 14,
|
|
2059
|
-
style: {
|
|
2060
|
-
color: getCloseButtonColor()
|
|
2061
|
-
},
|
|
2062
|
-
onMouseEnter: (e) => {
|
|
2063
|
-
e.currentTarget.style.color = getCloseButtonHoverColor();
|
|
2064
|
-
},
|
|
2065
|
-
onMouseLeave: (e) => {
|
|
2066
|
-
e.currentTarget.style.color = getCloseButtonColor();
|
|
1919
|
+
if (typeof obj === "function") {
|
|
1920
|
+
return new TypeWrapper("Function", {
|
|
1921
|
+
name: obj.name || "anonymous",
|
|
1922
|
+
stringValue: obj.toString().slice(0, opts.maxStringLength),
|
|
1923
|
+
length: obj.length
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1926
|
+
if (obj && typeof obj === "object") {
|
|
1927
|
+
if (visitedObjects.has(obj)) {
|
|
1928
|
+
return new CircularReference(visitedObjects.get(obj));
|
|
2067
1929
|
}
|
|
1930
|
+
visitedObjects.set(obj, path);
|
|
2068
1931
|
}
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
1932
|
+
if (obj instanceof Error) {
|
|
1933
|
+
return this.serializeError(obj, opts, visitedObjects, path);
|
|
1934
|
+
}
|
|
1935
|
+
if (obj instanceof Date) {
|
|
1936
|
+
return new TypeWrapper("Date", {
|
|
1937
|
+
iso: obj.toISOString(),
|
|
1938
|
+
value: obj.valueOf(),
|
|
1939
|
+
local: obj.toString()
|
|
1940
|
+
});
|
|
1941
|
+
}
|
|
1942
|
+
if (obj instanceof RegExp) {
|
|
1943
|
+
return new TypeWrapper("RegExp", {
|
|
1944
|
+
source: obj.source,
|
|
1945
|
+
flags: obj.flags,
|
|
1946
|
+
string: obj.toString()
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
if (obj instanceof Promise) {
|
|
1950
|
+
return new TypeWrapper("Promise", "[Promise]");
|
|
1951
|
+
}
|
|
1952
|
+
if (obj instanceof WeakMap || obj instanceof WeakSet) {
|
|
1953
|
+
return new TypeWrapper(
|
|
1954
|
+
obj.constructor.name,
|
|
1955
|
+
"[" + obj.constructor.name + "]"
|
|
1956
|
+
);
|
|
1957
|
+
}
|
|
1958
|
+
if (obj instanceof Set) {
|
|
1959
|
+
return this.serializeSet(obj, opts, visitedObjects, path);
|
|
1960
|
+
}
|
|
1961
|
+
if (obj instanceof Map) {
|
|
1962
|
+
return this.serializeMap(obj, opts, visitedObjects, path);
|
|
1963
|
+
}
|
|
1964
|
+
if (ArrayBuffer.isView(obj)) {
|
|
1965
|
+
return this.serializeTypedArray(obj);
|
|
1966
|
+
}
|
|
1967
|
+
if (Array.isArray(obj)) {
|
|
1968
|
+
return this.serializeArray(obj, opts, visitedObjects, path);
|
|
1969
|
+
}
|
|
1970
|
+
return this.serializeObject(obj, opts, visitedObjects, path);
|
|
2092
1971
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
}
|
|
2112
|
-
|
|
2113
|
-
),
|
|
2114
|
-
/* @__PURE__ */ jsx9(
|
|
2115
|
-
"div",
|
|
2116
|
-
{
|
|
2117
|
-
className: "absolute left-0 top-0 w-full h-full pointer-events-none rounded-xl",
|
|
2118
|
-
style: {
|
|
2119
|
-
border: "2px solid transparent",
|
|
2120
|
-
backgroundImage: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? `linear-gradient(135deg, ${themeConfig.borderGradientColor}60 0%, ${themeConfig.borderGradientColor}40 5%, transparent 22%)` : `linear-gradient(135deg, ${themeConfig.borderGradientColor}40 0%, ${themeConfig.borderGradientColor}25 5%, transparent 22%)`,
|
|
2121
|
-
backgroundOrigin: "border-box",
|
|
2122
|
-
backgroundClip: "border-box",
|
|
2123
|
-
WebkitMask: "linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0)",
|
|
2124
|
-
WebkitMaskComposite: "xor",
|
|
2125
|
-
mask: "linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0)",
|
|
2126
|
-
maskComposite: "exclude"
|
|
2127
|
-
}
|
|
2128
|
-
}
|
|
2129
|
-
),
|
|
2130
|
-
/* @__PURE__ */ jsx9("div", { className: "flex-shrink-0 mt-0.5 relative z-10", children: /* @__PURE__ */ jsx9("div", { className: `w-7 h-7 backdrop-blur-sm rounded-full flex items-center justify-center ${theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "bg-white/10" : "bg-black/5"}`, children: /* @__PURE__ */ jsx9(
|
|
2131
|
-
Icon4,
|
|
2132
|
-
{
|
|
2133
|
-
icon: iconConfig.icon,
|
|
2134
|
-
width: 16,
|
|
2135
|
-
height: 16,
|
|
2136
|
-
className: iconConfig.color,
|
|
2137
|
-
style: {
|
|
2138
|
-
color: themeConfig.gradientColor
|
|
1972
|
+
/**
|
|
1973
|
+
* 序列化错误对象
|
|
1974
|
+
*/
|
|
1975
|
+
static serializeError(error, opts, visitedObjects, path) {
|
|
1976
|
+
const errorObj = {
|
|
1977
|
+
name: error.name,
|
|
1978
|
+
message: error.message,
|
|
1979
|
+
stack: error.stack
|
|
1980
|
+
};
|
|
1981
|
+
for (const key of Object.getOwnPropertyNames(error)) {
|
|
1982
|
+
if (!errorObj[key]) {
|
|
1983
|
+
try {
|
|
1984
|
+
errorObj[key] = this.serialize(
|
|
1985
|
+
error[key],
|
|
1986
|
+
opts,
|
|
1987
|
+
visitedObjects,
|
|
1988
|
+
`${path}.${key}`
|
|
1989
|
+
);
|
|
1990
|
+
} catch (e) {
|
|
1991
|
+
errorObj[key] = new TypeWrapper("Error", `[Unable to serialize: ${e}]`);
|
|
2139
1992
|
}
|
|
2140
1993
|
}
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
backgroundClip: "text"
|
|
2161
|
-
},
|
|
2162
|
-
children: message
|
|
2163
|
-
}
|
|
1994
|
+
}
|
|
1995
|
+
return new TypeWrapper("Error", errorObj);
|
|
1996
|
+
}
|
|
1997
|
+
/**
|
|
1998
|
+
* 序列化 Set
|
|
1999
|
+
*/
|
|
2000
|
+
static serializeSet(set, opts, visitedObjects, path) {
|
|
2001
|
+
const values = Array.from(set);
|
|
2002
|
+
if (values.length > opts.maxArrayLength) {
|
|
2003
|
+
return new TypeWrapper("Set", {
|
|
2004
|
+
values: values.slice(0, opts.maxArrayLength).map(
|
|
2005
|
+
(item, index) => this.serialize(item, opts, visitedObjects, `${path}.Set[${index}]`)
|
|
2006
|
+
),
|
|
2007
|
+
truncated: values.length - opts.maxArrayLength
|
|
2008
|
+
});
|
|
2009
|
+
}
|
|
2010
|
+
return new TypeWrapper("Set", {
|
|
2011
|
+
values: values.map(
|
|
2012
|
+
(item, index) => this.serialize(item, opts, visitedObjects, `${path}.Set[${index}]`)
|
|
2164
2013
|
)
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
transition: Bounce
|
|
2179
|
-
};
|
|
2180
|
-
var createToast = (type) => {
|
|
2181
|
-
return (params) => {
|
|
2182
|
-
const { title, message, component, options } = params;
|
|
2183
|
-
toast(
|
|
2184
|
-
({ closeToast }) => /* @__PURE__ */ jsx9(
|
|
2185
|
-
ToastContent,
|
|
2186
|
-
{
|
|
2187
|
-
type,
|
|
2188
|
-
title,
|
|
2189
|
-
message: message || "",
|
|
2190
|
-
component,
|
|
2191
|
-
closeToast
|
|
2192
|
-
}
|
|
2193
|
-
),
|
|
2194
|
-
{
|
|
2195
|
-
...defaultToastOptions,
|
|
2196
|
-
...options,
|
|
2197
|
-
// 确保圆角样式不被覆盖,添加 rounded-xl 类
|
|
2198
|
-
className: "!p-0 !shadow-none !rounded-xl",
|
|
2199
|
-
style: { padding: 0, borderRadius: "0.75rem" }
|
|
2200
|
-
}
|
|
2201
|
-
);
|
|
2202
|
-
};
|
|
2203
|
-
};
|
|
2204
|
-
var ClayxToast = {
|
|
2205
|
-
success: createToast("success"),
|
|
2206
|
-
error: createToast("error"),
|
|
2207
|
-
warning: createToast("warning"),
|
|
2208
|
-
info: createToast("info"),
|
|
2209
|
-
default: createToast("default")
|
|
2210
|
-
};
|
|
2211
|
-
|
|
2212
|
-
// src/hooks/use-mobile.ts
|
|
2213
|
-
import * as React6 from "react";
|
|
2214
|
-
var MOBILE_BREAKPOINT = 768;
|
|
2215
|
-
function useIsMobile() {
|
|
2216
|
-
const [isMobile, setIsMobile] = React6.useState(void 0);
|
|
2217
|
-
React6.useEffect(() => {
|
|
2218
|
-
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
2219
|
-
const onChange = () => {
|
|
2220
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
2221
|
-
};
|
|
2222
|
-
mql.addEventListener("change", onChange);
|
|
2223
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
2224
|
-
return () => mql.removeEventListener("change", onChange);
|
|
2225
|
-
}, []);
|
|
2226
|
-
return !!isMobile;
|
|
2227
|
-
}
|
|
2228
|
-
|
|
2229
|
-
// src/hooks/use-debounce.ts
|
|
2230
|
-
import { useState as useState7, useEffect as useEffect7 } from "react";
|
|
2231
|
-
function useDebounce(value, delay) {
|
|
2232
|
-
const [debouncedValue, setDebouncedValue] = useState7(value);
|
|
2233
|
-
useEffect7(() => {
|
|
2234
|
-
const handler = setTimeout(() => {
|
|
2235
|
-
setDebouncedValue(value);
|
|
2236
|
-
}, delay);
|
|
2237
|
-
return () => {
|
|
2238
|
-
clearTimeout(handler);
|
|
2239
|
-
};
|
|
2240
|
-
}, [value, delay]);
|
|
2241
|
-
return debouncedValue;
|
|
2242
|
-
}
|
|
2243
|
-
|
|
2244
|
-
// src/utils/unified-error-handler/types.ts
|
|
2245
|
-
var ERROR_CONFIG = {
|
|
2246
|
-
MAX_ERRORS: 100,
|
|
2247
|
-
MAX_INTERACTIONS: 50,
|
|
2248
|
-
DEDUP_WINDOW: 1e3,
|
|
2249
|
-
DEBOUNCE_TIME: 100,
|
|
2250
|
-
CACHE_DURATION: 3e5,
|
|
2251
|
-
SEVERITY_KEYWORDS: {
|
|
2252
|
-
CRITICAL: ["fatal", "critical", "security", "crash", "corruption"],
|
|
2253
|
-
HIGH: ["error", "exception", "failed", "timeout", "network error"],
|
|
2254
|
-
MEDIUM: ["warning", "deprecated", "slow", "performance"],
|
|
2255
|
-
LOW: ["info", "debug", "trace", "notice"]
|
|
2256
|
-
},
|
|
2257
|
-
CATEGORY_KEYWORDS: {
|
|
2258
|
-
SYNTAX: ["syntaxerror", "unexpected token", "parse error", "invalid syntax"],
|
|
2259
|
-
NETWORK: ["fetch", "xhr", "network", "cors", "timeout", "connection"],
|
|
2260
|
-
RUNTIME: ["referenceerror", "typeerror", "rangeerror", "undefined"],
|
|
2261
|
-
SECURITY: ["csp", "xss", "csrf", "security", "unauthorized"],
|
|
2262
|
-
PERFORMANCE: ["slow", "memory", "leak", "performance", "timeout"],
|
|
2263
|
-
DEVELOPMENT: ["vite", "hmr", "hot reload", "dev server", "webpack"],
|
|
2264
|
-
REACT: ["react", "jsx", "component", "hook", "render"],
|
|
2265
|
-
VITE: ["vite", "[vite]", "vite:react", "transform failed"]
|
|
2266
|
-
}
|
|
2267
|
-
};
|
|
2268
|
-
var GLOBAL_CONFIG = {
|
|
2269
|
-
ALLOWED_ORIGINS: [
|
|
2270
|
-
"https://howone.ai",
|
|
2271
|
-
"https://howone.dev",
|
|
2272
|
-
"http://localhost:3000",
|
|
2273
|
-
"http://localhost:5173"
|
|
2274
|
-
],
|
|
2275
|
-
DEBOUNCE_DELAY: 10,
|
|
2276
|
-
OVERRIDE_STYLESHEET_ID: "howone-override-styles"
|
|
2277
|
-
};
|
|
2278
|
-
var DEFAULT_SELECTOR_CONFIG = {
|
|
2279
|
-
HIGHLIGHT_COLOR: "#ff6b6b",
|
|
2280
|
-
HIGHLIGHT_BORDER_WIDTH: "2px",
|
|
2281
|
-
HIGHLIGHT_BORDER_STYLE: "solid",
|
|
2282
|
-
SELECTED_COLOR: "#4ecdc4",
|
|
2283
|
-
SELECTED_BORDER_WIDTH: "3px",
|
|
2284
|
-
TOOLTIP_BACKGROUND: "#333",
|
|
2285
|
-
TOOLTIP_COLOR: "#fff",
|
|
2286
|
-
TOOLTIP_PADDING: "8px 12px",
|
|
2287
|
-
TOOLTIP_BORDER_RADIUS: "4px",
|
|
2288
|
-
TOOLTIP_FONT_SIZE: "12px",
|
|
2289
|
-
TOOLTIP_Z_INDEX: "10000",
|
|
2290
|
-
FULL_WIDTH_TOOLTIP_OFFSET: 10,
|
|
2291
|
-
highlightClass: "howone-highlight",
|
|
2292
|
-
selectedClass: "howone-selected",
|
|
2293
|
-
cursor: "crosshair"
|
|
2294
|
-
};
|
|
2295
|
-
|
|
2296
|
-
// src/utils/unified-error-handler/utils/DeepSerializer.ts
|
|
2297
|
-
var CircularReference = class {
|
|
2298
|
-
constructor(path) {
|
|
2299
|
-
this.message = `[Circular Reference to ${path}]`;
|
|
2300
|
-
}
|
|
2301
|
-
};
|
|
2302
|
-
var TypeWrapper = class {
|
|
2303
|
-
constructor(type, value) {
|
|
2304
|
-
this._type = type;
|
|
2305
|
-
this.value = value;
|
|
2306
|
-
}
|
|
2307
|
-
};
|
|
2308
|
-
var DeepSerializer = class {
|
|
2309
|
-
/**
|
|
2310
|
-
* 深度序列化对象
|
|
2311
|
-
*/
|
|
2312
|
-
static serialize(obj, options = {}, visitedObjects = /* @__PURE__ */ new WeakMap(), path = "root") {
|
|
2313
|
-
const opts = { ...this.DEFAULT_OPTIONS, ...options };
|
|
2314
|
-
if (path.split(".").length > opts.maxDepth) {
|
|
2315
|
-
return new TypeWrapper(
|
|
2316
|
-
"MaxDepthReached",
|
|
2317
|
-
`[Max depth of ${opts.maxDepth} reached]`
|
|
2318
|
-
);
|
|
2319
|
-
}
|
|
2320
|
-
if (obj === void 0) {
|
|
2321
|
-
return new TypeWrapper("undefined", "undefined");
|
|
2322
|
-
}
|
|
2323
|
-
if (obj === null) {
|
|
2324
|
-
return null;
|
|
2325
|
-
}
|
|
2326
|
-
if (typeof obj === "string") {
|
|
2327
|
-
return obj.length > opts.maxStringLength ? new TypeWrapper(
|
|
2328
|
-
"String",
|
|
2329
|
-
`${obj.slice(0, opts.maxStringLength)}... [${obj.length - opts.maxStringLength} more characters]`
|
|
2330
|
-
) : obj;
|
|
2331
|
-
}
|
|
2332
|
-
if (typeof obj === "number") {
|
|
2333
|
-
return Number.isNaN(obj) ? new TypeWrapper("Number", "NaN") : Number.isFinite(obj) ? obj : new TypeWrapper("Number", obj > 0 ? "Infinity" : "-Infinity");
|
|
2334
|
-
}
|
|
2335
|
-
if (typeof obj === "boolean") {
|
|
2336
|
-
return obj;
|
|
2337
|
-
}
|
|
2338
|
-
if (typeof obj === "bigint") {
|
|
2339
|
-
return new TypeWrapper("BigInt", obj.toString());
|
|
2340
|
-
}
|
|
2341
|
-
if (typeof obj === "symbol") {
|
|
2342
|
-
return new TypeWrapper("Symbol", obj.toString());
|
|
2343
|
-
}
|
|
2344
|
-
if (typeof obj === "function") {
|
|
2345
|
-
return new TypeWrapper("Function", {
|
|
2346
|
-
name: obj.name || "anonymous",
|
|
2347
|
-
stringValue: obj.toString().slice(0, opts.maxStringLength),
|
|
2348
|
-
length: obj.length
|
|
2349
|
-
});
|
|
2350
|
-
}
|
|
2351
|
-
if (obj && typeof obj === "object") {
|
|
2352
|
-
if (visitedObjects.has(obj)) {
|
|
2353
|
-
return new CircularReference(visitedObjects.get(obj));
|
|
2354
|
-
}
|
|
2355
|
-
visitedObjects.set(obj, path);
|
|
2356
|
-
}
|
|
2357
|
-
if (obj instanceof Error) {
|
|
2358
|
-
return this.serializeError(obj, opts, visitedObjects, path);
|
|
2359
|
-
}
|
|
2360
|
-
if (obj instanceof Date) {
|
|
2361
|
-
return new TypeWrapper("Date", {
|
|
2362
|
-
iso: obj.toISOString(),
|
|
2363
|
-
value: obj.valueOf(),
|
|
2364
|
-
local: obj.toString()
|
|
2365
|
-
});
|
|
2366
|
-
}
|
|
2367
|
-
if (obj instanceof RegExp) {
|
|
2368
|
-
return new TypeWrapper("RegExp", {
|
|
2369
|
-
source: obj.source,
|
|
2370
|
-
flags: obj.flags,
|
|
2371
|
-
string: obj.toString()
|
|
2372
|
-
});
|
|
2373
|
-
}
|
|
2374
|
-
if (obj instanceof Promise) {
|
|
2375
|
-
return new TypeWrapper("Promise", "[Promise]");
|
|
2376
|
-
}
|
|
2377
|
-
if (obj instanceof WeakMap || obj instanceof WeakSet) {
|
|
2378
|
-
return new TypeWrapper(
|
|
2379
|
-
obj.constructor.name,
|
|
2380
|
-
"[" + obj.constructor.name + "]"
|
|
2381
|
-
);
|
|
2382
|
-
}
|
|
2383
|
-
if (obj instanceof Set) {
|
|
2384
|
-
return this.serializeSet(obj, opts, visitedObjects, path);
|
|
2385
|
-
}
|
|
2386
|
-
if (obj instanceof Map) {
|
|
2387
|
-
return this.serializeMap(obj, opts, visitedObjects, path);
|
|
2388
|
-
}
|
|
2389
|
-
if (ArrayBuffer.isView(obj)) {
|
|
2390
|
-
return this.serializeTypedArray(obj);
|
|
2391
|
-
}
|
|
2392
|
-
if (Array.isArray(obj)) {
|
|
2393
|
-
return this.serializeArray(obj, opts, visitedObjects, path);
|
|
2394
|
-
}
|
|
2395
|
-
return this.serializeObject(obj, opts, visitedObjects, path);
|
|
2396
|
-
}
|
|
2397
|
-
/**
|
|
2398
|
-
* 序列化错误对象
|
|
2399
|
-
*/
|
|
2400
|
-
static serializeError(error, opts, visitedObjects, path) {
|
|
2401
|
-
const errorObj = {
|
|
2402
|
-
name: error.name,
|
|
2403
|
-
message: error.message,
|
|
2404
|
-
stack: error.stack
|
|
2405
|
-
};
|
|
2406
|
-
for (const key of Object.getOwnPropertyNames(error)) {
|
|
2407
|
-
if (!errorObj[key]) {
|
|
2408
|
-
try {
|
|
2409
|
-
errorObj[key] = this.serialize(
|
|
2410
|
-
error[key],
|
|
2411
|
-
opts,
|
|
2412
|
-
visitedObjects,
|
|
2413
|
-
`${path}.${key}`
|
|
2414
|
-
);
|
|
2415
|
-
} catch (e) {
|
|
2416
|
-
errorObj[key] = new TypeWrapper("Error", `[Unable to serialize: ${e}]`);
|
|
2417
|
-
}
|
|
2418
|
-
}
|
|
2419
|
-
}
|
|
2420
|
-
return new TypeWrapper("Error", errorObj);
|
|
2421
|
-
}
|
|
2422
|
-
/**
|
|
2423
|
-
* 序列化 Set
|
|
2424
|
-
*/
|
|
2425
|
-
static serializeSet(set, opts, visitedObjects, path) {
|
|
2426
|
-
const values = Array.from(set);
|
|
2427
|
-
if (values.length > opts.maxArrayLength) {
|
|
2428
|
-
return new TypeWrapper("Set", {
|
|
2429
|
-
values: values.slice(0, opts.maxArrayLength).map(
|
|
2430
|
-
(item, index) => this.serialize(item, opts, visitedObjects, `${path}.Set[${index}]`)
|
|
2431
|
-
),
|
|
2432
|
-
truncated: values.length - opts.maxArrayLength
|
|
2433
|
-
});
|
|
2434
|
-
}
|
|
2435
|
-
return new TypeWrapper("Set", {
|
|
2436
|
-
values: values.map(
|
|
2437
|
-
(item, index) => this.serialize(item, opts, visitedObjects, `${path}.Set[${index}]`)
|
|
2438
|
-
)
|
|
2439
|
-
});
|
|
2440
|
-
}
|
|
2441
|
-
/**
|
|
2442
|
-
* 序列化 Map
|
|
2443
|
-
*/
|
|
2444
|
-
static serializeMap(map, opts, visitedObjects, path) {
|
|
2445
|
-
const entries = {};
|
|
2446
|
-
let truncatedCount = 0;
|
|
2447
|
-
let addedCount = 0;
|
|
2448
|
-
for (const [key, value] of map.entries()) {
|
|
2449
|
-
if (addedCount >= opts.maxObjectKeys) {
|
|
2450
|
-
truncatedCount++;
|
|
2451
|
-
continue;
|
|
2014
|
+
});
|
|
2015
|
+
}
|
|
2016
|
+
/**
|
|
2017
|
+
* 序列化 Map
|
|
2018
|
+
*/
|
|
2019
|
+
static serializeMap(map, opts, visitedObjects, path) {
|
|
2020
|
+
const entries = {};
|
|
2021
|
+
let truncatedCount = 0;
|
|
2022
|
+
let addedCount = 0;
|
|
2023
|
+
for (const [key, value] of map.entries()) {
|
|
2024
|
+
if (addedCount >= opts.maxObjectKeys) {
|
|
2025
|
+
truncatedCount++;
|
|
2026
|
+
continue;
|
|
2452
2027
|
}
|
|
2453
2028
|
const keyString = typeof key === "object" ? JSON.stringify(
|
|
2454
2029
|
this.serialize(key, opts, visitedObjects, `${path}.MapKey`)
|
|
@@ -5005,7 +4580,7 @@ var InteractionTracking = class {
|
|
|
5005
4580
|
};
|
|
5006
4581
|
|
|
5007
4582
|
// src/utils/unified-error-handler/features/ElementSelector.ts
|
|
5008
|
-
var
|
|
4583
|
+
var ElementSelector2 = class {
|
|
5009
4584
|
constructor(sendMessage) {
|
|
5010
4585
|
this.config = { ...DEFAULT_SELECTOR_CONFIG };
|
|
5011
4586
|
this.isActive = false;
|
|
@@ -5999,7 +5574,6 @@ var MessageBridge = class {
|
|
|
5999
5574
|
this.handleSetStylesheet(payload);
|
|
6000
5575
|
break;
|
|
6001
5576
|
default:
|
|
6002
|
-
console.warn("[MessageBridge] \u672A\u77E5\u6D88\u606F\u7C7B\u578B:", type);
|
|
6003
5577
|
break;
|
|
6004
5578
|
}
|
|
6005
5579
|
} catch (error) {
|
|
@@ -6531,7 +6105,7 @@ var ErrorHandler = class {
|
|
|
6531
6105
|
const sendMessage = this.messageSender.createSendFunction();
|
|
6532
6106
|
this.errorTracking = new ErrorTracking(sendMessage);
|
|
6533
6107
|
this.interactionTracking = new InteractionTracking(sendMessage);
|
|
6534
|
-
this.elementSelector = new
|
|
6108
|
+
this.elementSelector = new ElementSelector2(sendMessage);
|
|
6535
6109
|
this.messageBridge = new MessageBridge();
|
|
6536
6110
|
this.viewDetector = new ViewDetector();
|
|
6537
6111
|
this.hardRefreshManager = new HardRefreshManager(GLOBAL_CONFIG.ALLOWED_ORIGINS);
|
|
@@ -6808,6 +6382,656 @@ var ErrorHandler = class {
|
|
|
6808
6382
|
}
|
|
6809
6383
|
};
|
|
6810
6384
|
|
|
6385
|
+
// src/components/auth/HowoneProvider.tsx
|
|
6386
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
6387
|
+
var HowoneContext = createContext2(null);
|
|
6388
|
+
var HowOneProvider = ({
|
|
6389
|
+
children,
|
|
6390
|
+
showFloatingButton = true,
|
|
6391
|
+
projectId,
|
|
6392
|
+
defaultTheme = "system",
|
|
6393
|
+
themeStorageKey = "howone-theme",
|
|
6394
|
+
forceDefaultTheme = false,
|
|
6395
|
+
authUrl = "https://howone.dev/auth",
|
|
6396
|
+
redirectOnUnauthenticated = true
|
|
6397
|
+
}) => {
|
|
6398
|
+
const [user, setUser] = useState7(() => parseUserFromToken(getToken()));
|
|
6399
|
+
const [token, setTokenState] = useState7(() => getToken());
|
|
6400
|
+
const [hasCheckedUrlToken, setHasCheckedUrlToken] = useState7(false);
|
|
6401
|
+
useEffect6(() => {
|
|
6402
|
+
const errorHandler = new ErrorHandler({
|
|
6403
|
+
enableViteHMR: true,
|
|
6404
|
+
enableElementSelector: true,
|
|
6405
|
+
enableInteractionTracking: true
|
|
6406
|
+
// enableConsoleCapture: true,
|
|
6407
|
+
// enableNetworkCapture: true,
|
|
6408
|
+
// maxErrors: 100,
|
|
6409
|
+
// maxInteractions: 50,
|
|
6410
|
+
// debounceTime: 100,
|
|
6411
|
+
// reportToParent: true,
|
|
6412
|
+
// reportToConsole: true
|
|
6413
|
+
});
|
|
6414
|
+
errorHandler.init();
|
|
6415
|
+
window.__ERROR_HANDLER__ = errorHandler;
|
|
6416
|
+
try {
|
|
6417
|
+
const params = new URLSearchParams(window.location.search);
|
|
6418
|
+
let urlToken = params.get("access_token") || params.get("token");
|
|
6419
|
+
if (!urlToken && window.location.hash) {
|
|
6420
|
+
const hashParams = new URLSearchParams(window.location.hash.slice(1));
|
|
6421
|
+
urlToken = hashParams.get("access_token") || hashParams.get("token");
|
|
6422
|
+
}
|
|
6423
|
+
if (urlToken) {
|
|
6424
|
+
console.log("[HowOneProvider] Token captured from URL, storing to localStorage...");
|
|
6425
|
+
setToken(urlToken);
|
|
6426
|
+
setTokenState(urlToken);
|
|
6427
|
+
setUser(parseUserFromToken(urlToken));
|
|
6428
|
+
params.delete("access_token");
|
|
6429
|
+
params.delete("token");
|
|
6430
|
+
params.delete("project_id");
|
|
6431
|
+
const newSearch = params.toString();
|
|
6432
|
+
const newUrl = window.location.pathname + (newSearch ? "?" + newSearch : "");
|
|
6433
|
+
window.history.replaceState({}, "", newUrl);
|
|
6434
|
+
console.log("[HowOneProvider] Token stored successfully, URL cleaned");
|
|
6435
|
+
}
|
|
6436
|
+
} catch (e) {
|
|
6437
|
+
console.error("[HowOneProvider] Failed to capture token from URL:", e);
|
|
6438
|
+
} finally {
|
|
6439
|
+
setHasCheckedUrlToken(true);
|
|
6440
|
+
}
|
|
6441
|
+
}, []);
|
|
6442
|
+
useEffect6(() => {
|
|
6443
|
+
if (!hasCheckedUrlToken) {
|
|
6444
|
+
return;
|
|
6445
|
+
}
|
|
6446
|
+
}, [token, user, redirectOnUnauthenticated, authUrl, projectId, hasCheckedUrlToken]);
|
|
6447
|
+
const logout = () => {
|
|
6448
|
+
try {
|
|
6449
|
+
setToken(null);
|
|
6450
|
+
} catch {
|
|
6451
|
+
}
|
|
6452
|
+
setTokenState(null);
|
|
6453
|
+
setUser(null);
|
|
6454
|
+
};
|
|
6455
|
+
const value = {
|
|
6456
|
+
user,
|
|
6457
|
+
token,
|
|
6458
|
+
isAuthenticated: !!token,
|
|
6459
|
+
logout
|
|
6460
|
+
};
|
|
6461
|
+
return /* @__PURE__ */ jsxs5(
|
|
6462
|
+
ThemeProvider,
|
|
6463
|
+
{
|
|
6464
|
+
defaultTheme,
|
|
6465
|
+
storageKey: themeStorageKey,
|
|
6466
|
+
forceDefault: forceDefaultTheme,
|
|
6467
|
+
children: [
|
|
6468
|
+
/* @__PURE__ */ jsx7(ElementSelectorProvider, { children: /* @__PURE__ */ jsxs5(HowoneContext.Provider, { value, children: [
|
|
6469
|
+
children,
|
|
6470
|
+
showFloatingButton && /* @__PURE__ */ jsx7(FloatingButton, { onClick: () => window.open("https://howone.ai", "_blank") })
|
|
6471
|
+
] }) }),
|
|
6472
|
+
/* @__PURE__ */ jsx7(GlobalToastContainer, {})
|
|
6473
|
+
]
|
|
6474
|
+
}
|
|
6475
|
+
);
|
|
6476
|
+
};
|
|
6477
|
+
function useHowoneContext() {
|
|
6478
|
+
const ctx = useContext2(HowoneContext);
|
|
6479
|
+
if (!ctx) {
|
|
6480
|
+
const t = getToken();
|
|
6481
|
+
return {
|
|
6482
|
+
user: parseUserFromToken(t),
|
|
6483
|
+
token: t,
|
|
6484
|
+
isAuthenticated: !!t,
|
|
6485
|
+
logout: () => {
|
|
6486
|
+
try {
|
|
6487
|
+
setToken(null);
|
|
6488
|
+
} catch {
|
|
6489
|
+
}
|
|
6490
|
+
}
|
|
6491
|
+
};
|
|
6492
|
+
}
|
|
6493
|
+
return ctx;
|
|
6494
|
+
}
|
|
6495
|
+
|
|
6496
|
+
// src/components/index.ts
|
|
6497
|
+
init_auth();
|
|
6498
|
+
|
|
6499
|
+
// src/howone/client.ts
|
|
6500
|
+
init_auth();
|
|
6501
|
+
init_config();
|
|
6502
|
+
var HowoneAuthClient = class {
|
|
6503
|
+
constructor() {
|
|
6504
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
6505
|
+
this.loading = false;
|
|
6506
|
+
}
|
|
6507
|
+
emit() {
|
|
6508
|
+
const state = {
|
|
6509
|
+
user: parseUserFromToken(getToken()),
|
|
6510
|
+
isLoading: this.loading
|
|
6511
|
+
};
|
|
6512
|
+
for (const l of this.listeners) {
|
|
6513
|
+
try {
|
|
6514
|
+
l(state);
|
|
6515
|
+
} catch (e) {
|
|
6516
|
+
void e;
|
|
6517
|
+
}
|
|
6518
|
+
}
|
|
6519
|
+
}
|
|
6520
|
+
onAuthStateChanged(listener) {
|
|
6521
|
+
this.listeners.add(listener);
|
|
6522
|
+
try {
|
|
6523
|
+
listener({ user: parseUserFromToken(getToken()), isLoading: this.loading });
|
|
6524
|
+
} catch (e) {
|
|
6525
|
+
void e;
|
|
6526
|
+
}
|
|
6527
|
+
return () => {
|
|
6528
|
+
this.listeners.delete(listener);
|
|
6529
|
+
};
|
|
6530
|
+
}
|
|
6531
|
+
// Simple redirect-based login trigger (consumer can override)
|
|
6532
|
+
login() {
|
|
6533
|
+
const root = getAuthRoot() || "https://create-x-backend-dev.fly.dev";
|
|
6534
|
+
try {
|
|
6535
|
+
const loc = window.location.href;
|
|
6536
|
+
const authUrl = new URL("/auth", String(root));
|
|
6537
|
+
authUrl.searchParams.set("redirect_uri", String(loc));
|
|
6538
|
+
try {
|
|
6539
|
+
const cfg = (init_config(), __toCommonJS(config_exports));
|
|
6540
|
+
const pid = cfg.getDefaultProjectId && cfg.getDefaultProjectId();
|
|
6541
|
+
if (pid) authUrl.searchParams.set("project_id", String(pid));
|
|
6542
|
+
} catch {
|
|
6543
|
+
}
|
|
6544
|
+
try {
|
|
6545
|
+
if (window.top && window.top !== window) {
|
|
6546
|
+
window.top.location.replace(authUrl.toString());
|
|
6547
|
+
} else {
|
|
6548
|
+
window.location.replace(authUrl.toString());
|
|
6549
|
+
}
|
|
6550
|
+
} catch {
|
|
6551
|
+
try {
|
|
6552
|
+
window.location.replace(String(root));
|
|
6553
|
+
} catch {
|
|
6554
|
+
}
|
|
6555
|
+
}
|
|
6556
|
+
} catch {
|
|
6557
|
+
try {
|
|
6558
|
+
window.location.replace(String(root));
|
|
6559
|
+
} catch {
|
|
6560
|
+
}
|
|
6561
|
+
}
|
|
6562
|
+
}
|
|
6563
|
+
logout() {
|
|
6564
|
+
setToken(null);
|
|
6565
|
+
this.emit();
|
|
6566
|
+
}
|
|
6567
|
+
getUser() {
|
|
6568
|
+
return parseUserFromToken(getToken());
|
|
6569
|
+
}
|
|
6570
|
+
// helper to programmatically set token (e.g., after callback handling)
|
|
6571
|
+
setToken(token) {
|
|
6572
|
+
setToken(token);
|
|
6573
|
+
this.emit();
|
|
6574
|
+
}
|
|
6575
|
+
};
|
|
6576
|
+
var howone = {
|
|
6577
|
+
auth: new HowoneAuthClient()
|
|
6578
|
+
};
|
|
6579
|
+
var client_default = howone;
|
|
6580
|
+
|
|
6581
|
+
// src/components/ui/Loading.tsx
|
|
6582
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
6583
|
+
var Loading = ({
|
|
6584
|
+
size = "md",
|
|
6585
|
+
text = "Loading...",
|
|
6586
|
+
className = "",
|
|
6587
|
+
fullScreen = false
|
|
6588
|
+
}) => {
|
|
6589
|
+
const sizeClasses = {
|
|
6590
|
+
sm: "h-4 w-4",
|
|
6591
|
+
md: "h-8 w-8",
|
|
6592
|
+
lg: "h-12 w-12"
|
|
6593
|
+
};
|
|
6594
|
+
const containerClasses = fullScreen ? "fixed inset-0 flex items-center justify-center bg-white/80 backdrop-blur-sm z-50" : "flex items-center justify-center p-4";
|
|
6595
|
+
return /* @__PURE__ */ jsx8("div", { className: `${containerClasses} ${className}`, children: /* @__PURE__ */ jsxs6("div", { className: "text-center", children: [
|
|
6596
|
+
/* @__PURE__ */ jsx8(
|
|
6597
|
+
"div",
|
|
6598
|
+
{
|
|
6599
|
+
className: `animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 mx-auto ${sizeClasses[size]}`
|
|
6600
|
+
}
|
|
6601
|
+
),
|
|
6602
|
+
text && /* @__PURE__ */ jsx8("p", { className: "mt-2 text-sm text-gray-600", children: text })
|
|
6603
|
+
] }) });
|
|
6604
|
+
};
|
|
6605
|
+
var LoadingSpinner = ({
|
|
6606
|
+
size = "md",
|
|
6607
|
+
className = ""
|
|
6608
|
+
}) => {
|
|
6609
|
+
const sizeClasses = {
|
|
6610
|
+
sm: "h-4 w-4",
|
|
6611
|
+
md: "h-8 w-8",
|
|
6612
|
+
lg: "h-12 w-12"
|
|
6613
|
+
};
|
|
6614
|
+
return /* @__PURE__ */ jsx8(
|
|
6615
|
+
"div",
|
|
6616
|
+
{
|
|
6617
|
+
className: `animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 ${sizeClasses[size]} ${className}`
|
|
6618
|
+
}
|
|
6619
|
+
);
|
|
6620
|
+
};
|
|
6621
|
+
|
|
6622
|
+
// src/components/ui/ErrorBoundary.tsx
|
|
6623
|
+
import { Component } from "react";
|
|
6624
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
6625
|
+
var ErrorBoundary = class extends Component {
|
|
6626
|
+
constructor(props) {
|
|
6627
|
+
super(props);
|
|
6628
|
+
this.handleRetry = () => {
|
|
6629
|
+
this.setState({ hasError: false, error: void 0, errorInfo: void 0 });
|
|
6630
|
+
};
|
|
6631
|
+
this.state = { hasError: false };
|
|
6632
|
+
}
|
|
6633
|
+
static getDerivedStateFromError(error) {
|
|
6634
|
+
return { hasError: true, error };
|
|
6635
|
+
}
|
|
6636
|
+
componentDidCatch(error, errorInfo) {
|
|
6637
|
+
this.setState({
|
|
6638
|
+
error,
|
|
6639
|
+
errorInfo
|
|
6640
|
+
});
|
|
6641
|
+
this.props.onError?.(error, errorInfo);
|
|
6642
|
+
}
|
|
6643
|
+
render() {
|
|
6644
|
+
if (this.state.hasError) {
|
|
6645
|
+
if (this.props.fallback) {
|
|
6646
|
+
const FallbackComponent = this.props.fallback;
|
|
6647
|
+
return /* @__PURE__ */ jsx9(FallbackComponent, { error: this.state.error, retry: this.handleRetry });
|
|
6648
|
+
}
|
|
6649
|
+
return /* @__PURE__ */ jsx9("div", { className: "min-h-[400px] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs7("div", { className: "text-center max-w-md", children: [
|
|
6650
|
+
/* @__PURE__ */ jsx9("div", { className: "text-red-500 text-6xl mb-4", children: "\u26A0\uFE0F" }),
|
|
6651
|
+
/* @__PURE__ */ jsx9("h2", { className: "text-xl font-semibold text-gray-900 mb-2", children: "Something went wrong" }),
|
|
6652
|
+
/* @__PURE__ */ jsx9("p", { className: "text-gray-600 mb-4", children: "An unexpected error occurred. Please try refreshing the page." }),
|
|
6653
|
+
/* @__PURE__ */ jsx9(
|
|
6654
|
+
"button",
|
|
6655
|
+
{
|
|
6656
|
+
onClick: this.handleRetry,
|
|
6657
|
+
className: "px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors",
|
|
6658
|
+
children: "Try Again"
|
|
6659
|
+
}
|
|
6660
|
+
),
|
|
6661
|
+
false
|
|
6662
|
+
] }) });
|
|
6663
|
+
}
|
|
6664
|
+
return this.props.children;
|
|
6665
|
+
}
|
|
6666
|
+
};
|
|
6667
|
+
var DefaultErrorFallback = ({ retry }) => /* @__PURE__ */ jsx9("div", { className: "min-h-[200px] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs7("div", { className: "text-center", children: [
|
|
6668
|
+
/* @__PURE__ */ jsx9("div", { className: "text-red-500 text-4xl mb-2", children: "\u26A0\uFE0F" }),
|
|
6669
|
+
/* @__PURE__ */ jsx9("p", { className: "text-gray-600 mb-2", children: "Something went wrong" }),
|
|
6670
|
+
retry && /* @__PURE__ */ jsx9(
|
|
6671
|
+
"button",
|
|
6672
|
+
{
|
|
6673
|
+
onClick: retry,
|
|
6674
|
+
className: "px-3 py-1 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 transition-colors",
|
|
6675
|
+
children: "Retry"
|
|
6676
|
+
}
|
|
6677
|
+
)
|
|
6678
|
+
] }) });
|
|
6679
|
+
|
|
6680
|
+
// src/components/theme/ThemeToggle.tsx
|
|
6681
|
+
import * as React6 from "react";
|
|
6682
|
+
import { Icon as Icon3 } from "@iconify/react";
|
|
6683
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
6684
|
+
function ThemeToggle({ className }) {
|
|
6685
|
+
const { setTheme, theme } = useTheme();
|
|
6686
|
+
const [mounted, setMounted] = React6.useState(false);
|
|
6687
|
+
React6.useEffect(() => {
|
|
6688
|
+
setMounted(true);
|
|
6689
|
+
}, []);
|
|
6690
|
+
const handleToggle = () => {
|
|
6691
|
+
if (theme === "dark") {
|
|
6692
|
+
setTheme("light");
|
|
6693
|
+
} else {
|
|
6694
|
+
setTheme("dark");
|
|
6695
|
+
}
|
|
6696
|
+
};
|
|
6697
|
+
if (!mounted) {
|
|
6698
|
+
return /* @__PURE__ */ jsxs8(
|
|
6699
|
+
"button",
|
|
6700
|
+
{
|
|
6701
|
+
className: `relative inline-flex h-10 w-12 items-center justify-center rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground ${className || ""}`,
|
|
6702
|
+
disabled: true,
|
|
6703
|
+
children: [
|
|
6704
|
+
/* @__PURE__ */ jsx10(Icon3, { icon: "solar:sun-bold", width: 20, height: 20 }),
|
|
6705
|
+
/* @__PURE__ */ jsx10("span", { className: "sr-only", children: "\u5207\u6362\u4E3B\u9898" })
|
|
6706
|
+
]
|
|
6707
|
+
}
|
|
6708
|
+
);
|
|
6709
|
+
}
|
|
6710
|
+
return /* @__PURE__ */ jsxs8(
|
|
6711
|
+
"button",
|
|
6712
|
+
{
|
|
6713
|
+
className: `inline-flex h-10 w-12 items-center justify-center rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground transition-colors ${className || ""}`,
|
|
6714
|
+
onClick: handleToggle,
|
|
6715
|
+
children: [
|
|
6716
|
+
theme === "light" ? /* @__PURE__ */ jsx10(Icon3, { icon: "solar:sun-bold", width: 20, height: 20 }) : /* @__PURE__ */ jsx10(Icon3, { icon: "solar:moon-linear", width: 20, height: 20 }),
|
|
6717
|
+
/* @__PURE__ */ jsx10("span", { className: "sr-only", children: "\u5207\u6362\u4E3B\u9898" })
|
|
6718
|
+
]
|
|
6719
|
+
}
|
|
6720
|
+
);
|
|
6721
|
+
}
|
|
6722
|
+
|
|
6723
|
+
// src/components/ui/Toast/ClayxToast.tsx
|
|
6724
|
+
import React7, { useCallback as useCallback4 } from "react";
|
|
6725
|
+
import { Bounce, toast } from "react-toastify";
|
|
6726
|
+
import { Icon as Icon4 } from "@iconify/react";
|
|
6727
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
6728
|
+
var TOAST_ICONS = {
|
|
6729
|
+
success: {
|
|
6730
|
+
icon: "mdi:success",
|
|
6731
|
+
color: "text-green-400",
|
|
6732
|
+
className: "text-green-400",
|
|
6733
|
+
// 深色主题配置
|
|
6734
|
+
dark: {
|
|
6735
|
+
bgGradient: "bg-[#14181d]",
|
|
6736
|
+
// 移除透明度 f2
|
|
6737
|
+
gradientColor: "#389726",
|
|
6738
|
+
borderGradient: "border-[#389726]",
|
|
6739
|
+
borderGradientColor: "#389726"
|
|
6740
|
+
},
|
|
6741
|
+
// 浅色主题配置
|
|
6742
|
+
light: {
|
|
6743
|
+
bgGradient: "bg-[#fafafa]",
|
|
6744
|
+
// 移除透明度 ff
|
|
6745
|
+
gradientColor: "#22c55e",
|
|
6746
|
+
borderGradient: "border-[#22c55e]",
|
|
6747
|
+
borderGradientColor: "#22c55e"
|
|
6748
|
+
}
|
|
6749
|
+
},
|
|
6750
|
+
error: {
|
|
6751
|
+
icon: "ic:outline-close",
|
|
6752
|
+
color: "text-red-400",
|
|
6753
|
+
className: "text-red-400",
|
|
6754
|
+
dark: {
|
|
6755
|
+
bgGradient: "bg-[#14181d]",
|
|
6756
|
+
// 移除透明度 f2
|
|
6757
|
+
gradientColor: "#ef4444",
|
|
6758
|
+
borderGradient: "border-[#ef4444]",
|
|
6759
|
+
borderGradientColor: "#ef4444"
|
|
6760
|
+
},
|
|
6761
|
+
light: {
|
|
6762
|
+
bgGradient: "bg-[#fafafa]",
|
|
6763
|
+
// 移除透明度 ff
|
|
6764
|
+
gradientColor: "#f87171",
|
|
6765
|
+
borderGradient: "border-[#f87171]",
|
|
6766
|
+
borderGradientColor: "#f87171"
|
|
6767
|
+
}
|
|
6768
|
+
},
|
|
6769
|
+
warning: {
|
|
6770
|
+
icon: "mi:warning",
|
|
6771
|
+
color: "text-yellow-400",
|
|
6772
|
+
className: "text-yellow-400",
|
|
6773
|
+
dark: {
|
|
6774
|
+
bgGradient: "bg-[#14181d]",
|
|
6775
|
+
// 移除透明度 f2
|
|
6776
|
+
gradientColor: "#facc15",
|
|
6777
|
+
borderGradient: "border-[#facc15]",
|
|
6778
|
+
borderGradientColor: "#facc15"
|
|
6779
|
+
},
|
|
6780
|
+
light: {
|
|
6781
|
+
bgGradient: "bg-[#fafafa]",
|
|
6782
|
+
// 移除透明度 ff
|
|
6783
|
+
gradientColor: "#f59e0b",
|
|
6784
|
+
borderGradient: "border-[#f59e0b]",
|
|
6785
|
+
borderGradientColor: "#f59e0b"
|
|
6786
|
+
}
|
|
6787
|
+
},
|
|
6788
|
+
info: {
|
|
6789
|
+
icon: "ic:outline-info",
|
|
6790
|
+
color: "text-blue-400",
|
|
6791
|
+
className: "text-blue-400",
|
|
6792
|
+
dark: {
|
|
6793
|
+
bgGradient: "bg-[#14181d]",
|
|
6794
|
+
// 移除透明度 f2
|
|
6795
|
+
gradientColor: "#60a5fa",
|
|
6796
|
+
borderGradient: "border-[#60a5fa]",
|
|
6797
|
+
borderGradientColor: "#f0f0f0"
|
|
6798
|
+
},
|
|
6799
|
+
light: {
|
|
6800
|
+
bgGradient: "bg-[#fafafa]",
|
|
6801
|
+
// 移除透明度 ff
|
|
6802
|
+
gradientColor: "#3b82f6",
|
|
6803
|
+
borderGradient: "border-[#3b82f6]",
|
|
6804
|
+
borderGradientColor: "#3b82f6"
|
|
6805
|
+
}
|
|
6806
|
+
},
|
|
6807
|
+
default: {
|
|
6808
|
+
icon: "ic:round-notifications",
|
|
6809
|
+
color: "text-gray-400",
|
|
6810
|
+
className: "text-gray-400",
|
|
6811
|
+
dark: {
|
|
6812
|
+
bgGradient: "bg-[#14181d]",
|
|
6813
|
+
// 移除透明度 f2
|
|
6814
|
+
gradientColor: "#9ca3af",
|
|
6815
|
+
borderGradient: "border-[#9ca3af]",
|
|
6816
|
+
borderGradientColor: "#9ca3af"
|
|
6817
|
+
},
|
|
6818
|
+
light: {
|
|
6819
|
+
bgGradient: "bg-[#fafafa]",
|
|
6820
|
+
// 移除透明度 ff
|
|
6821
|
+
gradientColor: "#6b7280",
|
|
6822
|
+
borderGradient: "border-[#6b7280]",
|
|
6823
|
+
borderGradientColor: "#6b7280"
|
|
6824
|
+
}
|
|
6825
|
+
}
|
|
6826
|
+
};
|
|
6827
|
+
var CloseButton = React7.memo(({ closeToast }) => {
|
|
6828
|
+
const { theme } = useTheme();
|
|
6829
|
+
const handleClick = useCallback4((e) => {
|
|
6830
|
+
e.preventDefault();
|
|
6831
|
+
e.stopPropagation();
|
|
6832
|
+
closeToast?.();
|
|
6833
|
+
}, [closeToast]);
|
|
6834
|
+
const getCloseButtonColor = () => {
|
|
6835
|
+
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
6836
|
+
return actualTheme === "dark" ? "#b4b4b4" : "#6b7280";
|
|
6837
|
+
};
|
|
6838
|
+
const getCloseButtonHoverColor = () => {
|
|
6839
|
+
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
6840
|
+
return actualTheme === "dark" ? "white" : "#374151";
|
|
6841
|
+
};
|
|
6842
|
+
return /* @__PURE__ */ jsx11(
|
|
6843
|
+
Icon4,
|
|
6844
|
+
{
|
|
6845
|
+
icon: "vaadin:close",
|
|
6846
|
+
className: "flex items-center justify-center rounded-full relative z-10 flex-shrink-0 cursor-pointer \n transition-colors duration-200 drop-shadow-sm",
|
|
6847
|
+
onClick: handleClick,
|
|
6848
|
+
width: 14,
|
|
6849
|
+
height: 14,
|
|
6850
|
+
style: {
|
|
6851
|
+
color: getCloseButtonColor()
|
|
6852
|
+
},
|
|
6853
|
+
onMouseEnter: (e) => {
|
|
6854
|
+
e.currentTarget.style.color = getCloseButtonHoverColor();
|
|
6855
|
+
},
|
|
6856
|
+
onMouseLeave: (e) => {
|
|
6857
|
+
e.currentTarget.style.color = getCloseButtonColor();
|
|
6858
|
+
}
|
|
6859
|
+
}
|
|
6860
|
+
);
|
|
6861
|
+
});
|
|
6862
|
+
CloseButton.displayName = "CloseButton";
|
|
6863
|
+
var ToastContent = ({ type, title, message, component, closeToast }) => {
|
|
6864
|
+
const iconConfig = TOAST_ICONS[type];
|
|
6865
|
+
const { theme } = useTheme();
|
|
6866
|
+
const handleClose = useCallback4(() => {
|
|
6867
|
+
closeToast?.();
|
|
6868
|
+
}, [closeToast]);
|
|
6869
|
+
const getTextColor = () => {
|
|
6870
|
+
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
6871
|
+
return actualTheme === "dark" ? "white" : "#1f2937";
|
|
6872
|
+
};
|
|
6873
|
+
const getThemeConfig = () => {
|
|
6874
|
+
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
6875
|
+
return actualTheme === "dark" ? iconConfig.dark : iconConfig.light;
|
|
6876
|
+
};
|
|
6877
|
+
const themeConfig = getThemeConfig();
|
|
6878
|
+
if (component) {
|
|
6879
|
+
return /* @__PURE__ */ jsxs9("div", { className: `flex items-start gap-3 !min-h-[90px] w-full backdrop-blur-md p-4 shadow-2xl relative overflow-hidden ${themeConfig.bgGradient}`, children: [
|
|
6880
|
+
/* @__PURE__ */ jsx11("div", { className: "flex-1 relative z-10", children: component }),
|
|
6881
|
+
/* @__PURE__ */ jsx11("div", { className: "relative z-10", children: /* @__PURE__ */ jsx11(CloseButton, { closeToast: handleClose }) })
|
|
6882
|
+
] });
|
|
6883
|
+
}
|
|
6884
|
+
return /* @__PURE__ */ jsxs9("div", { className: `flex items-start gap-3 !min-h-[90px] w-full backdrop-blur-md p-4 shadow-2xl relative overflow-hidden ${themeConfig.bgGradient}`, children: [
|
|
6885
|
+
/* @__PURE__ */ jsx11(
|
|
6886
|
+
"div",
|
|
6887
|
+
{
|
|
6888
|
+
className: "absolute left-0 top-0 w-full h-full rounded-xl",
|
|
6889
|
+
style: {
|
|
6890
|
+
background: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "#0f1419" : "#ffffff",
|
|
6891
|
+
zIndex: -2
|
|
6892
|
+
}
|
|
6893
|
+
}
|
|
6894
|
+
),
|
|
6895
|
+
/* @__PURE__ */ jsx11(
|
|
6896
|
+
"div",
|
|
6897
|
+
{
|
|
6898
|
+
className: "absolute left-0 top-0 w-full h-full pointer-events-none rounded-xl",
|
|
6899
|
+
style: {
|
|
6900
|
+
background: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? `linear-gradient(135deg, ${themeConfig.gradientColor}30 0%, ${themeConfig.gradientColor}20 15%, #14181df2 30%)` : `linear-gradient(135deg, ${themeConfig.gradientColor}15 0%, ${themeConfig.gradientColor}08 15%, #fafafaff 30%)`,
|
|
6901
|
+
zIndex: -1
|
|
6902
|
+
}
|
|
6903
|
+
}
|
|
6904
|
+
),
|
|
6905
|
+
/* @__PURE__ */ jsx11(
|
|
6906
|
+
"div",
|
|
6907
|
+
{
|
|
6908
|
+
className: "absolute left-0 top-0 w-full h-full pointer-events-none rounded-xl",
|
|
6909
|
+
style: {
|
|
6910
|
+
border: "2px solid transparent",
|
|
6911
|
+
backgroundImage: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? `linear-gradient(135deg, ${themeConfig.borderGradientColor}60 0%, ${themeConfig.borderGradientColor}40 5%, transparent 22%)` : `linear-gradient(135deg, ${themeConfig.borderGradientColor}40 0%, ${themeConfig.borderGradientColor}25 5%, transparent 22%)`,
|
|
6912
|
+
backgroundOrigin: "border-box",
|
|
6913
|
+
backgroundClip: "border-box",
|
|
6914
|
+
WebkitMask: "linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0)",
|
|
6915
|
+
WebkitMaskComposite: "xor",
|
|
6916
|
+
mask: "linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0)",
|
|
6917
|
+
maskComposite: "exclude"
|
|
6918
|
+
}
|
|
6919
|
+
}
|
|
6920
|
+
),
|
|
6921
|
+
/* @__PURE__ */ jsx11("div", { className: "flex-shrink-0 mt-0.5 relative z-10", children: /* @__PURE__ */ jsx11("div", { className: `w-7 h-7 backdrop-blur-sm rounded-full flex items-center justify-center ${theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "bg-white/10" : "bg-black/5"}`, children: /* @__PURE__ */ jsx11(
|
|
6922
|
+
Icon4,
|
|
6923
|
+
{
|
|
6924
|
+
icon: iconConfig.icon,
|
|
6925
|
+
width: 16,
|
|
6926
|
+
height: 16,
|
|
6927
|
+
className: iconConfig.color,
|
|
6928
|
+
style: {
|
|
6929
|
+
color: themeConfig.gradientColor
|
|
6930
|
+
}
|
|
6931
|
+
}
|
|
6932
|
+
) }) }),
|
|
6933
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-1 flex-1 relative z-10", children: [
|
|
6934
|
+
title && /* @__PURE__ */ jsx11(
|
|
6935
|
+
"div",
|
|
6936
|
+
{
|
|
6937
|
+
className: "text-[16px] font-semibold leading-tight drop-shadow-sm",
|
|
6938
|
+
style: {
|
|
6939
|
+
color: getTextColor(),
|
|
6940
|
+
backgroundClip: "text"
|
|
6941
|
+
},
|
|
6942
|
+
children: title
|
|
6943
|
+
}
|
|
6944
|
+
),
|
|
6945
|
+
message && /* @__PURE__ */ jsx11(
|
|
6946
|
+
"div",
|
|
6947
|
+
{
|
|
6948
|
+
className: "text-[13px] font-normal leading-relaxed drop-shadow-sm",
|
|
6949
|
+
style: {
|
|
6950
|
+
color: getTextColor(),
|
|
6951
|
+
backgroundClip: "text"
|
|
6952
|
+
},
|
|
6953
|
+
children: message
|
|
6954
|
+
}
|
|
6955
|
+
)
|
|
6956
|
+
] }),
|
|
6957
|
+
/* @__PURE__ */ jsx11("div", { className: "relative z-10", children: /* @__PURE__ */ jsx11(CloseButton, { closeToast: handleClose }) })
|
|
6958
|
+
] });
|
|
6959
|
+
};
|
|
6960
|
+
var defaultToastOptions = {
|
|
6961
|
+
position: "bottom-right",
|
|
6962
|
+
autoClose: 3e3,
|
|
6963
|
+
hideProgressBar: true,
|
|
6964
|
+
closeOnClick: false,
|
|
6965
|
+
pauseOnHover: true,
|
|
6966
|
+
draggable: true,
|
|
6967
|
+
pauseOnFocusLoss: false,
|
|
6968
|
+
theme: "dark",
|
|
6969
|
+
transition: Bounce
|
|
6970
|
+
};
|
|
6971
|
+
var createToast = (type) => {
|
|
6972
|
+
return (params) => {
|
|
6973
|
+
const { title, message, component, options } = params;
|
|
6974
|
+
toast(
|
|
6975
|
+
({ closeToast }) => /* @__PURE__ */ jsx11(
|
|
6976
|
+
ToastContent,
|
|
6977
|
+
{
|
|
6978
|
+
type,
|
|
6979
|
+
title,
|
|
6980
|
+
message: message || "",
|
|
6981
|
+
component,
|
|
6982
|
+
closeToast
|
|
6983
|
+
}
|
|
6984
|
+
),
|
|
6985
|
+
{
|
|
6986
|
+
...defaultToastOptions,
|
|
6987
|
+
...options,
|
|
6988
|
+
// 确保圆角样式不被覆盖,添加 rounded-xl 类
|
|
6989
|
+
className: "!p-0 !shadow-none !rounded-xl",
|
|
6990
|
+
style: { padding: 0, borderRadius: "0.75rem" }
|
|
6991
|
+
}
|
|
6992
|
+
);
|
|
6993
|
+
};
|
|
6994
|
+
};
|
|
6995
|
+
var ClayxToast = {
|
|
6996
|
+
success: createToast("success"),
|
|
6997
|
+
error: createToast("error"),
|
|
6998
|
+
warning: createToast("warning"),
|
|
6999
|
+
info: createToast("info"),
|
|
7000
|
+
default: createToast("default")
|
|
7001
|
+
};
|
|
7002
|
+
|
|
7003
|
+
// src/hooks/use-mobile.ts
|
|
7004
|
+
import * as React8 from "react";
|
|
7005
|
+
var MOBILE_BREAKPOINT = 768;
|
|
7006
|
+
function useIsMobile() {
|
|
7007
|
+
const [isMobile, setIsMobile] = React8.useState(void 0);
|
|
7008
|
+
React8.useEffect(() => {
|
|
7009
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
7010
|
+
const onChange = () => {
|
|
7011
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
7012
|
+
};
|
|
7013
|
+
mql.addEventListener("change", onChange);
|
|
7014
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
7015
|
+
return () => mql.removeEventListener("change", onChange);
|
|
7016
|
+
}, []);
|
|
7017
|
+
return !!isMobile;
|
|
7018
|
+
}
|
|
7019
|
+
|
|
7020
|
+
// src/hooks/use-debounce.ts
|
|
7021
|
+
import { useState as useState10, useEffect as useEffect9 } from "react";
|
|
7022
|
+
function useDebounce(value, delay) {
|
|
7023
|
+
const [debouncedValue, setDebouncedValue] = useState10(value);
|
|
7024
|
+
useEffect9(() => {
|
|
7025
|
+
const handler = setTimeout(() => {
|
|
7026
|
+
setDebouncedValue(value);
|
|
7027
|
+
}, delay);
|
|
7028
|
+
return () => {
|
|
7029
|
+
clearTimeout(handler);
|
|
7030
|
+
};
|
|
7031
|
+
}, [value, delay]);
|
|
7032
|
+
return debouncedValue;
|
|
7033
|
+
}
|
|
7034
|
+
|
|
6811
7035
|
// src/utils/unified-error-handler/simple.ts
|
|
6812
7036
|
var SimpleErrorHandler = class {
|
|
6813
7037
|
constructor() {
|
|
@@ -6902,6 +7126,8 @@ export {
|
|
|
6902
7126
|
DEFAULT_SELECTOR_CONFIG,
|
|
6903
7127
|
DefaultErrorFallback,
|
|
6904
7128
|
ERROR_CONFIG,
|
|
7129
|
+
ElementSelector,
|
|
7130
|
+
ElementSelectorProvider,
|
|
6905
7131
|
ErrorBoundary,
|
|
6906
7132
|
ErrorHandler,
|
|
6907
7133
|
FloatingButton,
|
|
@@ -6931,6 +7157,7 @@ export {
|
|
|
6931
7157
|
onAuthStateChanged,
|
|
6932
7158
|
parseUserFromToken,
|
|
6933
7159
|
request,
|
|
7160
|
+
sendElementSelectionToParent,
|
|
6934
7161
|
sendEmailVerificationCode,
|
|
6935
7162
|
setAuthRoot,
|
|
6936
7163
|
setDefaultProjectId,
|
|
@@ -6939,6 +7166,7 @@ export {
|
|
|
6939
7166
|
unifiedOAuth,
|
|
6940
7167
|
useAuth,
|
|
6941
7168
|
useDebounce,
|
|
7169
|
+
useElementSelector,
|
|
6942
7170
|
useHowoneContext,
|
|
6943
7171
|
useIsMobile,
|
|
6944
7172
|
useTheme,
|