@forgecharts/sdk 1.5.10 → 1.5.12
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.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +176 -3
- package/dist/index.js.map +1 -1
- package/dist/internal.js +176 -3
- package/dist/internal.js.map +1 -1
- package/dist/licensing/LicenseManager.d.ts +54 -0
- package/dist/licensing/LicenseManager.d.ts.map +1 -1
- package/dist/licensing/__tests__/dataBlocking.test.d.ts +2 -0
- package/dist/licensing/__tests__/dataBlocking.test.d.ts.map +1 -0
- package/dist/react/canvas/ChartCanvas.d.ts.map +1 -1
- package/dist/react/canvas/LicenseRequiredOverlay.d.ts +20 -0
- package/dist/react/canvas/LicenseRequiredOverlay.d.ts.map +1 -0
- package/dist/react/hooks/useHostLicense.d.ts +17 -0
- package/dist/react/hooks/useHostLicense.d.ts.map +1 -0
- package/dist/react/hooks/useLicenseDataBlocked.d.ts +15 -0
- package/dist/react/hooks/useLicenseDataBlocked.d.ts.map +1 -0
- package/dist/react/index.d.ts +4 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +176 -3
- package/dist/react/index.js.map +1 -1
- package/dist/react/internal.js +176 -3
- package/dist/react/internal.js.map +1 -1
- package/package.json +1 -1
package/dist/react/internal.js
CHANGED
|
@@ -10734,6 +10734,8 @@ var LicenseManager = class _LicenseManager {
|
|
|
10734
10734
|
static instance = null;
|
|
10735
10735
|
payload = null;
|
|
10736
10736
|
status = "idle";
|
|
10737
|
+
failureKind = null;
|
|
10738
|
+
hostState = "unknown";
|
|
10737
10739
|
subscribers = /* @__PURE__ */ new Set();
|
|
10738
10740
|
constructor() {
|
|
10739
10741
|
}
|
|
@@ -10784,6 +10786,7 @@ var LicenseManager = class _LicenseManager {
|
|
|
10784
10786
|
}
|
|
10785
10787
|
this.status = "pending";
|
|
10786
10788
|
this.notify();
|
|
10789
|
+
let failureKind = "unreachable";
|
|
10787
10790
|
let data;
|
|
10788
10791
|
try {
|
|
10789
10792
|
const res = await fetch(verifyUrl, {
|
|
@@ -10792,15 +10795,18 @@ var LicenseManager = class _LicenseManager {
|
|
|
10792
10795
|
body: JSON.stringify({ licenseKey: key.trim().toUpperCase() })
|
|
10793
10796
|
});
|
|
10794
10797
|
if (!res.ok) {
|
|
10798
|
+
failureKind = res.status >= 400 && res.status < 500 ? "invalid" : "unreachable";
|
|
10795
10799
|
throw new Error(`License server error: ${res.status} ${res.statusText}`);
|
|
10796
10800
|
}
|
|
10797
10801
|
data = await res.json();
|
|
10798
10802
|
if (!data.valid) {
|
|
10803
|
+
failureKind = "invalid";
|
|
10799
10804
|
throw new Error(data.reason ?? "License invalid");
|
|
10800
10805
|
}
|
|
10801
10806
|
} catch (err) {
|
|
10802
10807
|
this.payload = null;
|
|
10803
10808
|
this.status = "failed";
|
|
10809
|
+
this.failureKind = failureKind;
|
|
10804
10810
|
this.notify();
|
|
10805
10811
|
throw err;
|
|
10806
10812
|
}
|
|
@@ -10818,6 +10824,7 @@ var LicenseManager = class _LicenseManager {
|
|
|
10818
10824
|
const payload = this.#applyPolicyPipeline(raw);
|
|
10819
10825
|
this.payload = payload;
|
|
10820
10826
|
this.status = "valid";
|
|
10827
|
+
this.failureKind = null;
|
|
10821
10828
|
this.notify();
|
|
10822
10829
|
return payload;
|
|
10823
10830
|
}
|
|
@@ -10825,6 +10832,7 @@ var LicenseManager = class _LicenseManager {
|
|
|
10825
10832
|
loadLicense(payload) {
|
|
10826
10833
|
this.payload = this.#applyPolicyPipeline(payload);
|
|
10827
10834
|
this.status = "valid";
|
|
10835
|
+
this.failureKind = null;
|
|
10828
10836
|
this.notify();
|
|
10829
10837
|
}
|
|
10830
10838
|
/** Where the license is in its validation lifecycle. */
|
|
@@ -10840,6 +10848,43 @@ var LicenseManager = class _LicenseManager {
|
|
|
10840
10848
|
isLockedDown() {
|
|
10841
10849
|
return this.status === "pending" || this.status === "failed";
|
|
10842
10850
|
}
|
|
10851
|
+
/** Why the last validation failed, or null if it did not fail. */
|
|
10852
|
+
getFailureKind() {
|
|
10853
|
+
return this.status === "failed" ? this.failureKind : null;
|
|
10854
|
+
}
|
|
10855
|
+
/**
|
|
10856
|
+
* True when MARKET DATA must be withheld — i.e. the licence server gave a
|
|
10857
|
+
* definitive negative.
|
|
10858
|
+
*
|
|
10859
|
+
* Deliberately narrower than `isLockedDown()`. Hiding a button on an
|
|
10860
|
+
* ambiguous failure is cheap; blanking a live trading chart is not. So this
|
|
10861
|
+
* stays false while a verify is in flight and false when the server was
|
|
10862
|
+
* unreachable — only an outright rejection blocks data.
|
|
10863
|
+
*
|
|
10864
|
+
* 'idle' is also false: a host that never calls validateLicense (tests, the
|
|
10865
|
+
* unmanaged SDK path) keeps working exactly as before.
|
|
10866
|
+
*/
|
|
10867
|
+
isDataBlocked() {
|
|
10868
|
+
if (this.hostState === "unlicensed") return true;
|
|
10869
|
+
if (this.hostState === "licensed") return false;
|
|
10870
|
+
return this.status === "failed" && this.failureKind === "invalid";
|
|
10871
|
+
}
|
|
10872
|
+
/** What the host deployment reports about its own licence. */
|
|
10873
|
+
getHostLicenseState() {
|
|
10874
|
+
return this.hostState;
|
|
10875
|
+
}
|
|
10876
|
+
/**
|
|
10877
|
+
* Record the host deployment's answer from GET /api/license.
|
|
10878
|
+
*
|
|
10879
|
+
* Pass 'unlicensed' ONLY when the host answered and said it has no licence.
|
|
10880
|
+
* A network failure, missing apiUrl, or non-OK response must pass 'unknown',
|
|
10881
|
+
* otherwise an outage would blank every chart the deployment serves.
|
|
10882
|
+
*/
|
|
10883
|
+
setHostLicenseState(state) {
|
|
10884
|
+
if (this.hostState === state) return;
|
|
10885
|
+
this.hostState = state;
|
|
10886
|
+
this.notify();
|
|
10887
|
+
}
|
|
10843
10888
|
/**
|
|
10844
10889
|
* Runs a raw/legacy/partial payload through `migrateLegacyPayload` (fills
|
|
10845
10890
|
* missing productTier/capabilities/schemaVersion, deterministically, with
|
|
@@ -10898,6 +10943,8 @@ var LicenseManager = class _LicenseManager {
|
|
|
10898
10943
|
clear() {
|
|
10899
10944
|
this.payload = null;
|
|
10900
10945
|
this.status = "idle";
|
|
10946
|
+
this.failureKind = null;
|
|
10947
|
+
this.hostState = "unknown";
|
|
10901
10948
|
this.notify();
|
|
10902
10949
|
}
|
|
10903
10950
|
};
|
|
@@ -18058,6 +18105,126 @@ function useChartCapabilities(config) {
|
|
|
18058
18105
|
}, []);
|
|
18059
18106
|
return useMemo(() => applyRuntimeConfig(licCaps, config), [licCaps, config]);
|
|
18060
18107
|
}
|
|
18108
|
+
function useLicenseDataBlocked() {
|
|
18109
|
+
const [blocked, setBlocked] = useState(
|
|
18110
|
+
() => LicenseManager.getInstance().isDataBlocked()
|
|
18111
|
+
);
|
|
18112
|
+
useEffect(() => {
|
|
18113
|
+
const lm = LicenseManager.getInstance();
|
|
18114
|
+
setBlocked(lm.isDataBlocked());
|
|
18115
|
+
return lm.subscribe(() => setBlocked(lm.isDataBlocked()));
|
|
18116
|
+
}, []);
|
|
18117
|
+
return blocked;
|
|
18118
|
+
}
|
|
18119
|
+
function useHostLicense(apiUrl, getAuthToken) {
|
|
18120
|
+
useEffect(() => {
|
|
18121
|
+
if (!apiUrl) return;
|
|
18122
|
+
let cancelled = false;
|
|
18123
|
+
const lm = LicenseManager.getInstance();
|
|
18124
|
+
void (async () => {
|
|
18125
|
+
try {
|
|
18126
|
+
const headers = {};
|
|
18127
|
+
if (getAuthToken) {
|
|
18128
|
+
try {
|
|
18129
|
+
const tok = await getAuthToken();
|
|
18130
|
+
if (tok) headers["Authorization"] = `Bearer ${tok}`;
|
|
18131
|
+
} catch {
|
|
18132
|
+
}
|
|
18133
|
+
}
|
|
18134
|
+
const res = await fetch(`${apiUrl.replace(/\/+$/, "")}/api/license`, { headers });
|
|
18135
|
+
if (cancelled) return;
|
|
18136
|
+
if (!res.ok) {
|
|
18137
|
+
lm.setHostLicenseState("unknown");
|
|
18138
|
+
return;
|
|
18139
|
+
}
|
|
18140
|
+
const data = await res.json();
|
|
18141
|
+
if (cancelled) return;
|
|
18142
|
+
if (data.licensePayload && typeof data.licensePayload === "object") {
|
|
18143
|
+
lm.loadLicense(data.licensePayload);
|
|
18144
|
+
lm.setHostLicenseState("licensed");
|
|
18145
|
+
} else {
|
|
18146
|
+
lm.setHostLicenseState("unlicensed");
|
|
18147
|
+
}
|
|
18148
|
+
} catch {
|
|
18149
|
+
if (!cancelled) lm.setHostLicenseState("unknown");
|
|
18150
|
+
}
|
|
18151
|
+
})();
|
|
18152
|
+
return () => {
|
|
18153
|
+
cancelled = true;
|
|
18154
|
+
};
|
|
18155
|
+
}, [apiUrl, getAuthToken]);
|
|
18156
|
+
}
|
|
18157
|
+
function LicenseRequiredOverlay({
|
|
18158
|
+
reason,
|
|
18159
|
+
onOpenLicenseSettings
|
|
18160
|
+
}) {
|
|
18161
|
+
return /* @__PURE__ */ jsxs(
|
|
18162
|
+
"div",
|
|
18163
|
+
{
|
|
18164
|
+
role: "alert",
|
|
18165
|
+
"data-testid": "fc-license-required",
|
|
18166
|
+
style: {
|
|
18167
|
+
position: "absolute",
|
|
18168
|
+
inset: 0,
|
|
18169
|
+
zIndex: 100,
|
|
18170
|
+
background: "rgba(0,0,0,0.6)",
|
|
18171
|
+
backdropFilter: "blur(4px)",
|
|
18172
|
+
display: "flex",
|
|
18173
|
+
flexDirection: "column",
|
|
18174
|
+
alignItems: "center",
|
|
18175
|
+
justifyContent: "center",
|
|
18176
|
+
gap: 12,
|
|
18177
|
+
// Swallow interaction: no crosshair or drawing on a blocked chart.
|
|
18178
|
+
pointerEvents: "auto"
|
|
18179
|
+
},
|
|
18180
|
+
children: [
|
|
18181
|
+
/* @__PURE__ */ jsxs(
|
|
18182
|
+
"svg",
|
|
18183
|
+
{
|
|
18184
|
+
viewBox: "0 0 24 24",
|
|
18185
|
+
width: "40",
|
|
18186
|
+
height: "40",
|
|
18187
|
+
fill: "none",
|
|
18188
|
+
stroke: "rgba(255,255,255,0.7)",
|
|
18189
|
+
strokeWidth: "1.8",
|
|
18190
|
+
strokeLinecap: "round",
|
|
18191
|
+
strokeLinejoin: "round",
|
|
18192
|
+
"aria-hidden": "true",
|
|
18193
|
+
children: [
|
|
18194
|
+
/* @__PURE__ */ jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2" }),
|
|
18195
|
+
/* @__PURE__ */ jsx("path", { d: "M7 11V7a5 5 0 0110 0v4" })
|
|
18196
|
+
]
|
|
18197
|
+
}
|
|
18198
|
+
),
|
|
18199
|
+
/* @__PURE__ */ jsx("div", { style: { color: "#fff", fontWeight: 700, fontSize: 18, letterSpacing: "0.01em" }, children: "Unlicensed" }),
|
|
18200
|
+
/* @__PURE__ */ jsxs("div", { style: { color: "rgba(255,255,255,0.65)", fontSize: 13, textAlign: "center", maxWidth: 340 }, children: [
|
|
18201
|
+
"Please activate your license in the admin studio.",
|
|
18202
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
18203
|
+
"Market data is unavailable until a valid license is installed."
|
|
18204
|
+
] }),
|
|
18205
|
+
reason && /* @__PURE__ */ jsx("div", { style: { color: "rgba(255,255,255,0.45)", fontSize: 12, fontStyle: "italic" }, children: reason }),
|
|
18206
|
+
onOpenLicenseSettings && /* @__PURE__ */ jsx(
|
|
18207
|
+
"button",
|
|
18208
|
+
{
|
|
18209
|
+
onClick: onOpenLicenseSettings,
|
|
18210
|
+
style: {
|
|
18211
|
+
marginTop: 4,
|
|
18212
|
+
padding: "8px 16px",
|
|
18213
|
+
borderRadius: 8,
|
|
18214
|
+
border: "1px solid rgba(255,255,255,0.25)",
|
|
18215
|
+
background: "rgba(255,255,255,0.12)",
|
|
18216
|
+
color: "#fff",
|
|
18217
|
+
fontSize: 13,
|
|
18218
|
+
fontWeight: 600,
|
|
18219
|
+
cursor: "pointer"
|
|
18220
|
+
},
|
|
18221
|
+
children: "Open license settings"
|
|
18222
|
+
}
|
|
18223
|
+
)
|
|
18224
|
+
]
|
|
18225
|
+
}
|
|
18226
|
+
);
|
|
18227
|
+
}
|
|
18061
18228
|
|
|
18062
18229
|
// src/react/assets/logo_dark.png
|
|
18063
18230
|
var logo_dark_default = "data:image/png;base64,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";
|
|
@@ -22701,6 +22868,8 @@ var ChartCanvas = forwardRef(
|
|
|
22701
22868
|
const [bars, setBars] = useState([]);
|
|
22702
22869
|
const [panes, setPanes] = useState([]);
|
|
22703
22870
|
const capabilities = useChartCapabilities();
|
|
22871
|
+
const dataBlocked = useLicenseDataBlocked();
|
|
22872
|
+
useHostLicense(apiUrl, getAuthToken);
|
|
22704
22873
|
const [indicators, setIndicators] = useState([]);
|
|
22705
22874
|
const [totalHeight, setTotalHeight] = useState(600);
|
|
22706
22875
|
const [activeTool, setActiveTool] = useState(initialActiveTool ?? "cursor");
|
|
@@ -22821,7 +22990,10 @@ var ChartCanvas = forwardRef(
|
|
|
22821
22990
|
symbol,
|
|
22822
22991
|
interval: timeframe,
|
|
22823
22992
|
theme,
|
|
22824
|
-
|
|
22993
|
+
// Withhold the datafeed entirely rather than covering the canvas: an
|
|
22994
|
+
// unlicensed deployment should make no market-data requests at all, and
|
|
22995
|
+
// there must be nothing behind the overlay to reveal.
|
|
22996
|
+
...datafeed !== void 0 && !dataBlocked ? { datafeed } : {},
|
|
22825
22997
|
...renderBackend !== void 0 ? { renderBackend } : {}
|
|
22826
22998
|
});
|
|
22827
22999
|
for (const config of initialIndicators) {
|
|
@@ -22965,7 +23137,7 @@ var ChartCanvas = forwardRef(
|
|
|
22965
23137
|
transformRef.current = null;
|
|
22966
23138
|
delete window.__chart;
|
|
22967
23139
|
};
|
|
22968
|
-
}, []);
|
|
23140
|
+
}, [dataBlocked]);
|
|
22969
23141
|
useEffect(() => {
|
|
22970
23142
|
chartRef.current?.setSymbol(symbol);
|
|
22971
23143
|
}, [symbol]);
|
|
@@ -23826,6 +23998,7 @@ var ChartCanvas = forwardRef(
|
|
|
23826
23998
|
overflow: "hidden"
|
|
23827
23999
|
},
|
|
23828
24000
|
children: [
|
|
24001
|
+
dataBlocked && /* @__PURE__ */ jsx(LicenseRequiredOverlay, {}),
|
|
23829
24002
|
/* @__PURE__ */ jsx(
|
|
23830
24003
|
LeftToolbar,
|
|
23831
24004
|
{
|
|
@@ -37346,6 +37519,6 @@ function IndicatorPane({
|
|
|
37346
37519
|
] });
|
|
37347
37520
|
}
|
|
37348
37521
|
|
|
37349
|
-
export { AgentFAB, AgentProvider, AssistantPanel, BottomToolbar, ChartCanvas, ChartContextMenu, ChartSettingsDialog, ChartWorkspace, CommandDispatcher, DEFAULT_FAVORITES, FloatingPanel, IndicatorLabel, IndicatorPane, IndicatorsDialog, LayoutMenu, LeftToolbar, ManagedAppShell, MultiPaneChart, OrderTicket, PointerOverlay, RightToolbar, SymbolSearchDialog, TabBar, TopToolbar, VoiceInput, createTradingBridgeLogger, useAgent, useChartCapabilities };
|
|
37522
|
+
export { AgentFAB, AgentProvider, AssistantPanel, BottomToolbar, ChartCanvas, ChartContextMenu, ChartSettingsDialog, ChartWorkspace, CommandDispatcher, DEFAULT_FAVORITES, FloatingPanel, IndicatorLabel, IndicatorPane, IndicatorsDialog, LayoutMenu, LeftToolbar, LicenseRequiredOverlay, ManagedAppShell, MultiPaneChart, OrderTicket, PointerOverlay, RightToolbar, SymbolSearchDialog, TabBar, TopToolbar, VoiceInput, createTradingBridgeLogger, useAgent, useChartCapabilities, useHostLicense, useLicenseDataBlocked };
|
|
37350
37523
|
//# sourceMappingURL=internal.js.map
|
|
37351
37524
|
//# sourceMappingURL=internal.js.map
|