@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.
@@ -21,11 +21,40 @@ import type { CapabilitySet, LegacyPayloadShape, ProductTier } from './capabilit
21
21
  * a failed verify must never yield more than a valid one.
22
22
  */
23
23
  export type LicenseValidationStatus = 'idle' | 'pending' | 'valid' | 'failed';
24
+ /**
25
+ * WHY a validation failed. Gating features is the same either way — a failed
26
+ * verify never grants more than a valid one — but withholding MARKET DATA is
27
+ * not: blanking a live trading chart because the licence server had a blip
28
+ * would be far worse than briefly showing data to an unlicensed user.
29
+ *
30
+ * 'invalid' — the server answered and rejected the key (bad, revoked,
31
+ * expired). A definitive negative; safe to block data.
32
+ * 'unreachable' — network error, timeout, or a 5xx from the licence server.
33
+ * We do NOT know the licence is bad, so data keeps flowing.
34
+ */
35
+ export type LicenseFailureKind = 'invalid' | 'unreachable';
36
+ /**
37
+ * What the HOST DEPLOYMENT says about its own licence, via GET /api/license.
38
+ *
39
+ * This is the authoritative answer for a self-hosted Kit: the operator installs
40
+ * a key in Admin Studio, and every chart served by that deployment inherits it.
41
+ * A client-side key is only a hint by comparison — the deployment's own answer
42
+ * is what decides whether it is licensed.
43
+ *
44
+ * 'licensed' — the host returned a licence payload.
45
+ * 'unlicensed' — the host answered and said it has NO licence. Definitive.
46
+ * 'unknown' — not asked yet, no host configured, or the host was
47
+ * unreachable. Never blocks: an embed with no host, or a
48
+ * momentary outage, must not blank a live chart.
49
+ */
50
+ export type HostLicenseState = 'licensed' | 'unlicensed' | 'unknown';
24
51
  export declare class LicenseManager {
25
52
  #private;
26
53
  private static instance;
27
54
  private payload;
28
55
  private status;
56
+ private failureKind;
57
+ private hostState;
29
58
  private readonly subscribers;
30
59
  private constructor();
31
60
  /**
@@ -61,6 +90,31 @@ export declare class LicenseManager {
61
90
  * "omitted = allowed" defaults.
62
91
  */
63
92
  isLockedDown(): boolean;
93
+ /** Why the last validation failed, or null if it did not fail. */
94
+ getFailureKind(): LicenseFailureKind | null;
95
+ /**
96
+ * True when MARKET DATA must be withheld — i.e. the licence server gave a
97
+ * definitive negative.
98
+ *
99
+ * Deliberately narrower than `isLockedDown()`. Hiding a button on an
100
+ * ambiguous failure is cheap; blanking a live trading chart is not. So this
101
+ * stays false while a verify is in flight and false when the server was
102
+ * unreachable — only an outright rejection blocks data.
103
+ *
104
+ * 'idle' is also false: a host that never calls validateLicense (tests, the
105
+ * unmanaged SDK path) keeps working exactly as before.
106
+ */
107
+ isDataBlocked(): boolean;
108
+ /** What the host deployment reports about its own licence. */
109
+ getHostLicenseState(): HostLicenseState;
110
+ /**
111
+ * Record the host deployment's answer from GET /api/license.
112
+ *
113
+ * Pass 'unlicensed' ONLY when the host answered and said it has no licence.
114
+ * A network failure, missing apiUrl, or non-OK response must pass 'unknown',
115
+ * otherwise an outage would blank every chart the deployment serves.
116
+ */
117
+ setHostLicenseState(state: HostLicenseState): void;
64
118
  /** Return the currently loaded payload, or null if none. */
65
119
  getLicense(): LicensePayload | null;
66
120
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"LicenseManager.d.ts","sourceRoot":"","sources":["../../src/licensing/LicenseManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAe,MAAM,gBAAgB,CAAC;AAEhG,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AASzF;;;;;;;;GAQG;AACH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE9E,qBAAa,cAAc;;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA+B;IAEtD,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;IAE1D,OAAO;IAEP;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAKrC,OAAO,CAAC,MAAM;IAMd,MAAM,CAAC,WAAW,IAAI,cAAc;IAepC;;;;;;OAMG;IACG,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAgE9E,gJAAgJ;IAChJ,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAM9C,wDAAwD;IACxD,mBAAmB,IAAI,uBAAuB;IAI9C;;;;;OAKG;IACH,YAAY,IAAI,OAAO;IAoBvB,4DAA4D;IAC5D,UAAU,IAAI,cAAc,GAAG,IAAI;IAInC;;;;OAIG;IACH,OAAO,IAAI,WAAW;IAItB,uDAAuD;IACvD,WAAW,IAAI,eAAe;IAI9B,yEAAyE;IACzE,UAAU,CAAC,IAAI,EAAE,MAAM,eAAe,GAAG,OAAO;IAIhD;;;;OAIG;IACH,cAAc,IAAI,WAAW;IAI7B;;;OAGG;IACH,eAAe,IAAI,aAAa;IAIhC,4EAA4E;IAC5E,aAAa,CAAC,IAAI,EAAE,MAAM,aAAa,GAAG,OAAO;IAIjD,8FAA8F;IAC9F,KAAK,IAAI,IAAI;CAKd"}
1
+ {"version":3,"file":"LicenseManager.d.ts","sourceRoot":"","sources":["../../src/licensing/LicenseManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAe,MAAM,gBAAgB,CAAC;AAEhG,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AASzF;;;;;;;;GAQG;AACH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,aAAa,CAAC;AAE3D;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC;AAErE,qBAAa,cAAc;;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA+B;IAEtD,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;IAE1D,OAAO;IAEP;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAKrC,OAAO,CAAC,MAAM;IAMd,MAAM,CAAC,WAAW,IAAI,cAAc;IAepC;;;;;;OAMG;IACG,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA6E9E,gJAAgJ;IAChJ,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAO9C,wDAAwD;IACxD,mBAAmB,IAAI,uBAAuB;IAI9C;;;;;OAKG;IACH,YAAY,IAAI,OAAO;IAIvB,kEAAkE;IAClE,cAAc,IAAI,kBAAkB,GAAG,IAAI;IAI3C;;;;;;;;;;;OAWG;IACH,aAAa,IAAI,OAAO;IAgBxB,8DAA8D;IAC9D,mBAAmB,IAAI,gBAAgB;IAIvC;;;;;;OAMG;IACH,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAsBlD,4DAA4D;IAC5D,UAAU,IAAI,cAAc,GAAG,IAAI;IAInC;;;;OAIG;IACH,OAAO,IAAI,WAAW;IAItB,uDAAuD;IACvD,WAAW,IAAI,eAAe;IAI9B,yEAAyE;IACzE,UAAU,CAAC,IAAI,EAAE,MAAM,eAAe,GAAG,OAAO;IAIhD;;;;OAIG;IACH,cAAc,IAAI,WAAW;IAI7B;;;OAGG;IACH,eAAe,IAAI,aAAa;IAIhC,4EAA4E;IAC5E,aAAa,CAAC,IAAI,EAAE,MAAM,aAAa,GAAG,OAAO;IAIjD,8FAA8F;IAC9F,KAAK,IAAI,IAAI;CAOd"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dataBlocking.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataBlocking.test.d.ts","sourceRoot":"","sources":["../../../src/licensing/__tests__/dataBlocking.test.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"ChartCanvas.d.ts","sourceRoot":"","sources":["../../../src/react/canvas/ChartCanvas.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChartCanvas.d.ts","sourceRoot":"","sources":["../../../src/react/canvas/ChartCanvas.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAKlD,OAAO,KAAK,EACM,eAAe,EAAa,eAAe,EACjC,eAAe,EAAE,WAAW,EAAE,SAAS,EACjE,UAAU,EACX,MAAM,QAAQ,CAAC;AAGhB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAavE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAyR3E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,6EAA6E;IAC7E,iBAAiB,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IAC5C,kEAAkE;IAClE,kBAAkB,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IAClD,8DAA8D;IAC9D,YAAY,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,MAAM,GAAG,IAAI,CAAC;IACzD,sDAAsD;IACtD,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,qDAAqD;IACrD,sBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,mEAAmE;IACnE,mBAAmB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE,uEAAuE;IACvE,iBAAiB,EAAE,MAAM,MAAM,CAAC;IAChC,mDAAmD;IACnD,aAAa,EAAE,MAAM,SAAS,OAAO,oBAAoB,EAAE,iBAAiB,EAAE,CAAC;IAC/E,yDAAyD;IACzD,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChD;;;;OAIG;IACH,eAAe,EAAE,MAAM,mBAAmB,GAAG,IAAI,CAAC;IAClD,4FAA4F;IAC5F,iBAAiB,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,2DAA2D;IAC3D,YAAY,EAAE,MAAM,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,eAAe,EAAE,CAAC;IACtC;;;;OAIG;IACH,eAAe,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC1C,oGAAoG;IACpG,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,+IAA+I;IAC/I,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,qBAAqB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACrE,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,0DAA0D;IAC1D,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,uGAAuG;IACvG,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,yHAAyH;IACzH,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,4FAA4F;IAC5F,wBAAwB,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAC7D;;;OAGG;IACH,iBAAiB,CAAC,EAAE,eAAe,CAAC;IACpC,6FAA6F;IAC7F,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IACtD;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,oBAAoB,EAAE,UAAU,CAAC;IAC5D,0FAA0F;IAC1F,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,oBAAoB,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7E;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC;;;OAGG;IACH,aAAa,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAClC,iGAAiG;IACjG,qBAAqB,CAAC,EAAE,cAAc,CAAC;IACvC,yFAAyF;IACzF,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;IAC5D,wFAAwF;IACxF,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,sCAAsC;IACtC,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,wCAAwC;IACxC,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACnD,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,0EAA0E;IAC1E,qBAAqB,CAAC,EAAE,cAAc,CAAC;IACvC,yEAAyE;IACzE,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,iFAAiF;IACjF,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,yFAAyF;IACzF,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChF,iGAAiG;IACjG,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACxC,CAAC;AAEF,uCAAuC;AACvC,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AACnD,wCAAwC;AACxC,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAErD,eAAO,MAAM,WAAW,gHAuvDtB,CAAC;AAEH,kCAAkC;AAClC,eAAO,MAAM,cAAc,gHAAc,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Unlicensed overlay — blocks the chart area when there is no valid licence.
3
+ *
4
+ * Restores the overlay that lived in apps/frontend/src/App.tsx until 6e718ac,
5
+ * moved into the SDK so every embedder gets it rather than only the legacy
6
+ * chart app. Same visual language as the original: blurred scrim, padlock,
7
+ * and a pointer to Admin Studio.
8
+ *
9
+ * ChartCanvas also withholds the datafeed while blocked, so there is no market
10
+ * data behind this — it states the situation rather than merely hiding it.
11
+ */
12
+ export interface LicenseRequiredOverlayProps {
13
+ /** Reason text from the licence server, when it gave one. */
14
+ reason?: string | undefined;
15
+ /** Optional action, e.g. open the host's licence settings. */
16
+ onOpenLicenseSettings?: (() => void) | undefined;
17
+ }
18
+ export declare function LicenseRequiredOverlay({ reason, onOpenLicenseSettings, }: LicenseRequiredOverlayProps): import("react").JSX.Element;
19
+ export default LicenseRequiredOverlay;
20
+ //# sourceMappingURL=LicenseRequiredOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LicenseRequiredOverlay.d.ts","sourceRoot":"","sources":["../../../src/react/canvas/LicenseRequiredOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,2BAA2B;IAC1C,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,8DAA8D;IAC9D,qBAAqB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CAClD;AAED,wBAAgB,sBAAsB,CAAC,EACrC,MAAM,EACN,qBAAqB,GACtB,EAAE,2BAA2B,+BAwD7B;AAED,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Resolve the HOST DEPLOYMENT's licence from `GET {apiUrl}/api/license`.
3
+ *
4
+ * For a self-hosted Kit this is the authoritative answer: the operator installs
5
+ * a key in Admin Studio and every chart the deployment serves inherits it. A
6
+ * client-side key is a hint by comparison.
7
+ *
8
+ * Three outcomes, and the distinction matters:
9
+ * payload returned -> 'licensed', and the payload is loaded so capabilities apply
10
+ * {licensePayload:null} -> 'unlicensed'. The host ANSWERED and said it holds no
11
+ * licence, so charts are blocked.
12
+ * anything else -> 'unknown'. No apiUrl, network failure, non-OK response
13
+ * or unparseable body. Never blocks — an outage must not
14
+ * blank every chart the deployment serves.
15
+ */
16
+ export declare function useHostLicense(apiUrl?: string, getAuthToken?: (() => string | Promise<string>) | undefined): void;
17
+ //# sourceMappingURL=useHostLicense.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHostLicense.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useHostLicense.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,GAC1D,IAAI,CA2CN"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * True when market data must be withheld because the licence server gave a
3
+ * definitive negative (explicit rejection or 4xx).
4
+ *
5
+ * Deliberately narrow — see LicenseManager.isDataBlocked(). It stays FALSE
6
+ * while a verify is in flight and false when the server was unreachable, so a
7
+ * licence-server blip never blanks a live trading chart; only an outright
8
+ * rejection does. It is also false for hosts that never validate at all, which
9
+ * keeps the unmanaged SDK path and tests working unchanged.
10
+ *
11
+ * Re-renders whenever licence state changes, so installing a valid key
12
+ * restores the chart without a reload.
13
+ */
14
+ export declare function useLicenseDataBlocked(): boolean;
15
+ //# sourceMappingURL=useLicenseDataBlocked.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLicenseDataBlocked.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useLicenseDataBlocked.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAc/C"}
@@ -20,6 +20,10 @@
20
20
  */
21
21
  export { ChartCanvas } from './canvas/ChartCanvas';
22
22
  export type { ChartCanvasHandle, ChartCanvasProps } from './canvas/ChartCanvas';
23
+ export { LicenseRequiredOverlay } from './canvas/LicenseRequiredOverlay';
24
+ export type { LicenseRequiredOverlayProps } from './canvas/LicenseRequiredOverlay';
25
+ export { useLicenseDataBlocked } from './hooks/useLicenseDataBlocked';
26
+ export { useHostLicense } from './hooks/useHostLicense';
23
27
  export { ChartWorkspace } from './workspace/ChartWorkspace';
24
28
  export type { ChartWorkspaceProps, TabItem, TradingSession } from './workspace/ChartWorkspace';
25
29
  export { useChartCapabilities } from './hooks/useChartCapabilities';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGhF,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,YAAY,EAAE,mBAAmB,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGpE,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAG9E,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC3G,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC9D,YAAY,EACV,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,QAAQ,GACT,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGhF,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,YAAY,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,YAAY,EAAE,mBAAmB,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGpE,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAG9E,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC3G,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC9D,YAAY,EACV,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,QAAQ,GACT,MAAM,oBAAoB,CAAC"}
@@ -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
  };
@@ -17835,6 +17882,126 @@ function useChartCapabilities(config) {
17835
17882
  }, []);
17836
17883
  return useMemo(() => applyRuntimeConfig(licCaps, config), [licCaps, config]);
17837
17884
  }
17885
+ function useLicenseDataBlocked() {
17886
+ const [blocked, setBlocked] = useState(
17887
+ () => LicenseManager.getInstance().isDataBlocked()
17888
+ );
17889
+ useEffect(() => {
17890
+ const lm = LicenseManager.getInstance();
17891
+ setBlocked(lm.isDataBlocked());
17892
+ return lm.subscribe(() => setBlocked(lm.isDataBlocked()));
17893
+ }, []);
17894
+ return blocked;
17895
+ }
17896
+ function useHostLicense(apiUrl, getAuthToken) {
17897
+ useEffect(() => {
17898
+ if (!apiUrl) return;
17899
+ let cancelled = false;
17900
+ const lm = LicenseManager.getInstance();
17901
+ void (async () => {
17902
+ try {
17903
+ const headers = {};
17904
+ if (getAuthToken) {
17905
+ try {
17906
+ const tok = await getAuthToken();
17907
+ if (tok) headers["Authorization"] = `Bearer ${tok}`;
17908
+ } catch {
17909
+ }
17910
+ }
17911
+ const res = await fetch(`${apiUrl.replace(/\/+$/, "")}/api/license`, { headers });
17912
+ if (cancelled) return;
17913
+ if (!res.ok) {
17914
+ lm.setHostLicenseState("unknown");
17915
+ return;
17916
+ }
17917
+ const data = await res.json();
17918
+ if (cancelled) return;
17919
+ if (data.licensePayload && typeof data.licensePayload === "object") {
17920
+ lm.loadLicense(data.licensePayload);
17921
+ lm.setHostLicenseState("licensed");
17922
+ } else {
17923
+ lm.setHostLicenseState("unlicensed");
17924
+ }
17925
+ } catch {
17926
+ if (!cancelled) lm.setHostLicenseState("unknown");
17927
+ }
17928
+ })();
17929
+ return () => {
17930
+ cancelled = true;
17931
+ };
17932
+ }, [apiUrl, getAuthToken]);
17933
+ }
17934
+ function LicenseRequiredOverlay({
17935
+ reason,
17936
+ onOpenLicenseSettings
17937
+ }) {
17938
+ return /* @__PURE__ */ jsxs(
17939
+ "div",
17940
+ {
17941
+ role: "alert",
17942
+ "data-testid": "fc-license-required",
17943
+ style: {
17944
+ position: "absolute",
17945
+ inset: 0,
17946
+ zIndex: 100,
17947
+ background: "rgba(0,0,0,0.6)",
17948
+ backdropFilter: "blur(4px)",
17949
+ display: "flex",
17950
+ flexDirection: "column",
17951
+ alignItems: "center",
17952
+ justifyContent: "center",
17953
+ gap: 12,
17954
+ // Swallow interaction: no crosshair or drawing on a blocked chart.
17955
+ pointerEvents: "auto"
17956
+ },
17957
+ children: [
17958
+ /* @__PURE__ */ jsxs(
17959
+ "svg",
17960
+ {
17961
+ viewBox: "0 0 24 24",
17962
+ width: "40",
17963
+ height: "40",
17964
+ fill: "none",
17965
+ stroke: "rgba(255,255,255,0.7)",
17966
+ strokeWidth: "1.8",
17967
+ strokeLinecap: "round",
17968
+ strokeLinejoin: "round",
17969
+ "aria-hidden": "true",
17970
+ children: [
17971
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2" }),
17972
+ /* @__PURE__ */ jsx("path", { d: "M7 11V7a5 5 0 0110 0v4" })
17973
+ ]
17974
+ }
17975
+ ),
17976
+ /* @__PURE__ */ jsx("div", { style: { color: "#fff", fontWeight: 700, fontSize: 18, letterSpacing: "0.01em" }, children: "Unlicensed" }),
17977
+ /* @__PURE__ */ jsxs("div", { style: { color: "rgba(255,255,255,0.65)", fontSize: 13, textAlign: "center", maxWidth: 340 }, children: [
17978
+ "Please activate your license in the admin studio.",
17979
+ /* @__PURE__ */ jsx("br", {}),
17980
+ "Market data is unavailable until a valid license is installed."
17981
+ ] }),
17982
+ reason && /* @__PURE__ */ jsx("div", { style: { color: "rgba(255,255,255,0.45)", fontSize: 12, fontStyle: "italic" }, children: reason }),
17983
+ onOpenLicenseSettings && /* @__PURE__ */ jsx(
17984
+ "button",
17985
+ {
17986
+ onClick: onOpenLicenseSettings,
17987
+ style: {
17988
+ marginTop: 4,
17989
+ padding: "8px 16px",
17990
+ borderRadius: 8,
17991
+ border: "1px solid rgba(255,255,255,0.25)",
17992
+ background: "rgba(255,255,255,0.12)",
17993
+ color: "#fff",
17994
+ fontSize: 13,
17995
+ fontWeight: 600,
17996
+ cursor: "pointer"
17997
+ },
17998
+ children: "Open license settings"
17999
+ }
18000
+ )
18001
+ ]
18002
+ }
18003
+ );
18004
+ }
17838
18005
 
17839
18006
  // src/react/assets/logo_dark.png
17840
18007
  var logo_dark_default = "data:image/png;base64,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";
@@ -22478,6 +22645,8 @@ var ChartCanvas = forwardRef(
22478
22645
  const [bars, setBars] = useState([]);
22479
22646
  const [panes, setPanes] = useState([]);
22480
22647
  const capabilities = useChartCapabilities();
22648
+ const dataBlocked = useLicenseDataBlocked();
22649
+ useHostLicense(apiUrl, getAuthToken);
22481
22650
  const [indicators, setIndicators] = useState([]);
22482
22651
  const [totalHeight, setTotalHeight] = useState(600);
22483
22652
  const [activeTool, setActiveTool] = useState(initialActiveTool ?? "cursor");
@@ -22598,7 +22767,10 @@ var ChartCanvas = forwardRef(
22598
22767
  symbol,
22599
22768
  interval: timeframe,
22600
22769
  theme,
22601
- ...datafeed !== void 0 ? { datafeed } : {},
22770
+ // Withhold the datafeed entirely rather than covering the canvas: an
22771
+ // unlicensed deployment should make no market-data requests at all, and
22772
+ // there must be nothing behind the overlay to reveal.
22773
+ ...datafeed !== void 0 && !dataBlocked ? { datafeed } : {},
22602
22774
  ...renderBackend !== void 0 ? { renderBackend } : {}
22603
22775
  });
22604
22776
  for (const config of initialIndicators) {
@@ -22742,7 +22914,7 @@ var ChartCanvas = forwardRef(
22742
22914
  transformRef.current = null;
22743
22915
  delete window.__chart;
22744
22916
  };
22745
- }, []);
22917
+ }, [dataBlocked]);
22746
22918
  useEffect(() => {
22747
22919
  chartRef.current?.setSymbol(symbol);
22748
22920
  }, [symbol]);
@@ -23603,6 +23775,7 @@ var ChartCanvas = forwardRef(
23603
23775
  overflow: "hidden"
23604
23776
  },
23605
23777
  children: [
23778
+ dataBlocked && /* @__PURE__ */ jsx(LicenseRequiredOverlay, {}),
23606
23779
  /* @__PURE__ */ jsx(
23607
23780
  LeftToolbar,
23608
23781
  {
@@ -33027,6 +33200,6 @@ var CommandDispatcher = class {
33027
33200
  }
33028
33201
  };
33029
33202
 
33030
- export { AgentFAB, AgentProvider, AssistantPanel, ChartCanvas, ChartWorkspace, CommandDispatcher, OrderTicket, VoiceInput, createTradingBridgeLogger, useAgent, useChartCapabilities };
33203
+ export { AgentFAB, AgentProvider, AssistantPanel, ChartCanvas, ChartWorkspace, CommandDispatcher, LicenseRequiredOverlay, OrderTicket, VoiceInput, createTradingBridgeLogger, useAgent, useChartCapabilities, useHostLicense, useLicenseDataBlocked };
33031
33204
  //# sourceMappingURL=index.js.map
33032
33205
  //# sourceMappingURL=index.js.map