@forgecharts/sdk 1.3.7 → 1.3.9

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/internal.js CHANGED
@@ -10792,12 +10792,14 @@ function validateLicensePolicy(payload) {
10792
10792
  }
10793
10793
 
10794
10794
  // src/licensing/LicenseManager.ts
10795
+ var GLOBAL_INSTANCE_KEY = /* @__PURE__ */ Symbol.for("@forgecharts/sdk:LicenseManager");
10795
10796
  var DEFAULT_MODE = "unmanaged";
10796
10797
  var DEFAULT_PRODUCT_TIER = "core";
10797
10798
  var DEFAULT_FEATURES = {};
10798
10799
  var LicenseManager = class _LicenseManager {
10799
10800
  static instance = null;
10800
10801
  payload = null;
10802
+ status = "idle";
10801
10803
  subscribers = /* @__PURE__ */ new Set();
10802
10804
  constructor() {
10803
10805
  }
@@ -10825,10 +10827,12 @@ var LicenseManager = class _LicenseManager {
10825
10827
  });
10826
10828
  }
10827
10829
  static getInstance() {
10828
- if (!_LicenseManager.instance) {
10829
- _LicenseManager.instance = new _LicenseManager();
10830
+ const registry = globalThis;
10831
+ if (!registry[GLOBAL_INSTANCE_KEY]) {
10832
+ registry[GLOBAL_INSTANCE_KEY] = _LicenseManager.instance ?? new _LicenseManager();
10830
10833
  }
10831
- return _LicenseManager.instance;
10834
+ _LicenseManager.instance = registry[GLOBAL_INSTANCE_KEY];
10835
+ return registry[GLOBAL_INSTANCE_KEY];
10832
10836
  }
10833
10837
  /**
10834
10838
  * Validate a license key against the licensing endpoint.
@@ -10844,17 +10848,27 @@ var LicenseManager = class _LicenseManager {
10844
10848
  if (!verifyUrl) {
10845
10849
  throw new Error("LicenseManager: verifyUrl is required");
10846
10850
  }
10847
- const res = await fetch(verifyUrl, {
10848
- method: "POST",
10849
- headers: { "Content-Type": "application/json" },
10850
- body: JSON.stringify({ licenseKey: key.trim().toUpperCase() })
10851
- });
10852
- if (!res.ok) {
10853
- throw new Error(`License server error: ${res.status} ${res.statusText}`);
10854
- }
10855
- const data = await res.json();
10856
- if (!data.valid) {
10857
- throw new Error(data.reason ?? "License invalid");
10851
+ this.status = "pending";
10852
+ this.notify();
10853
+ let data;
10854
+ try {
10855
+ const res = await fetch(verifyUrl, {
10856
+ method: "POST",
10857
+ headers: { "Content-Type": "application/json" },
10858
+ body: JSON.stringify({ licenseKey: key.trim().toUpperCase() })
10859
+ });
10860
+ if (!res.ok) {
10861
+ throw new Error(`License server error: ${res.status} ${res.statusText}`);
10862
+ }
10863
+ data = await res.json();
10864
+ if (!data.valid) {
10865
+ throw new Error(data.reason ?? "License invalid");
10866
+ }
10867
+ } catch (err) {
10868
+ this.payload = null;
10869
+ this.status = "failed";
10870
+ this.notify();
10871
+ throw err;
10858
10872
  }
10859
10873
  const raw = {
10860
10874
  licenseKey: data.licenseKey ?? key.trim().toUpperCase(),
@@ -10869,14 +10883,29 @@ var LicenseManager = class _LicenseManager {
10869
10883
  };
10870
10884
  const payload = this.#applyPolicyPipeline(raw);
10871
10885
  this.payload = payload;
10886
+ this.status = "valid";
10872
10887
  this.notify();
10873
10888
  return payload;
10874
10889
  }
10875
10890
  /** Load a pre-validated payload (e.g. from cache / localStorage). Runs through the same migration + guardrail pipeline as `validateLicense`. */
10876
10891
  loadLicense(payload) {
10877
10892
  this.payload = this.#applyPolicyPipeline(payload);
10893
+ this.status = "valid";
10878
10894
  this.notify();
10879
10895
  }
10896
+ /** Where the license is in its validation lifecycle. */
10897
+ getValidationStatus() {
10898
+ return this.status;
10899
+ }
10900
+ /**
10901
+ * True when a validation attempt is pending or has failed — every
10902
+ * license-gated feature must be denied. 'idle' (validation never
10903
+ * attempted) is NOT locked down: dev/test usage keeps the permissive
10904
+ * "omitted = allowed" defaults.
10905
+ */
10906
+ isLockedDown() {
10907
+ return this.status === "pending" || this.status === "failed";
10908
+ }
10880
10909
  /**
10881
10910
  * Runs a raw/legacy/partial payload through `migrateLegacyPayload` (fills
10882
10911
  * missing productTier/capabilities/schemaVersion, deterministically, with
@@ -10931,9 +10960,10 @@ var LicenseManager = class _LicenseManager {
10931
10960
  hasCapability(name) {
10932
10961
  return this.getCapabilities()[name] === true;
10933
10962
  }
10934
- /** Clear the current license state (returns to safe unmanaged defaults). */
10963
+ /** Clear the current license state (returns to safe unmanaged defaults and 'idle' status). */
10935
10964
  clear() {
10936
10965
  this.payload = null;
10966
+ this.status = "idle";
10937
10967
  this.notify();
10938
10968
  }
10939
10969
  };
@@ -11300,8 +11330,14 @@ var ChartRuntimeResolver = class _ChartRuntimeResolver {
11300
11330
  * If the active license has an explicit feature flag, use it.
11301
11331
  * Otherwise fall back to `defaultValue` (allows capability even without an
11302
11332
  * explicit flag, matching the "omitted = allowed" convention).
11333
+ *
11334
+ * Lockdown override: while a validation attempt is pending or has failed,
11335
+ * every gated feature is denied — a failed verify must never yield more
11336
+ * than a valid one. 'idle' (validation never attempted) keeps the
11337
+ * permissive defaults for dev/test usage.
11303
11338
  */
11304
11339
  #featureOrDefault(name, defaultValue) {
11340
+ if (this.lm.isLockedDown()) return false;
11305
11341
  const features = this.lm.getFeatures();
11306
11342
  const flag = features[name];
11307
11343
  return flag === void 0 ? defaultValue : flag === true;