@svgrid/enterprise 3.1.2 → 3.1.4

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.
@@ -16045,7 +16045,7 @@ function hasFieldConditions(schema) {
16045
16045
  *
16046
16046
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
16047
16047
  */
16048
- var SVGRID_VERSION = "3.1.2";
16048
+ var SVGRID_VERSION = "3.1.4";
16049
16049
  /**
16050
16050
  * The version of `@svgrid/grid`, which releases on its own line: enterprise is
16051
16051
  * on 3.1.x while the grid is on 3.0.x.
@@ -41821,75 +41821,149 @@ function missingEnvKeys(envExample, envLocal) {
41821
41821
  return declared.filter((k) => !present.has(k));
41822
41822
  }
41823
41823
  //#endregion
41824
- //#region src/revoked.ts
41825
- var REVOKED_KEYS = /* @__PURE__ */ new Set([]);
41826
- /**
41827
- * Pull the expiry out of a key.
41828
- *
41829
- * Keys are `SVENTERPRISE[-KIND]-<SLUG>-<SEATS>-<DATE>-<RANDOM>`, so the date is
41830
- * always the second-to-last segment regardless of whether a KIND is present.
41831
- * Two widths are accepted:
41832
- *
41833
- * YYYYMM - subscription granularity; expires at the end of that month.
41834
- * YYYYMMDD - trial granularity; expires at the end of that day.
41835
- *
41836
- * The 6-digit form came first, so every key issued before day-precision trials
41837
- * existed still parses. Anything else (including the older keys whose slug sits
41838
- * in that position) yields null, which reads as "no expiry encoded".
41839
- *
41840
- * Boundaries are UTC so a key does not lapse at a different instant per
41841
- * timezone. Kept in sync with the (maintainer-side) key issuer.
41842
- */
41843
- function parseLicenseExpiry(key) {
41844
- if (!key) return null;
41845
- const segments = key.split("-");
41846
- if (segments.length < 3) return null;
41847
- const stamp = segments[segments.length - 2];
41848
- if (stamp == null) return null;
41849
- if (/^\d{6}$/.test(stamp)) {
41850
- const year = Number(stamp.slice(0, 4));
41851
- const month = Number(stamp.slice(4, 6));
41852
- if (month < 1 || month > 12) return null;
41853
- return /* @__PURE__ */ new Date(Date.UTC(year, month, 1) - 1);
41854
- }
41855
- if (/^\d{8}$/.test(stamp)) {
41856
- const year = Number(stamp.slice(0, 4));
41857
- const month = Number(stamp.slice(4, 6));
41858
- const day = Number(stamp.slice(6, 8));
41859
- if (month < 1 || month > 12 || day < 1 || day > 31) return null;
41860
- const end = new Date(Date.UTC(year, month - 1, day, 23, 59, 59, 999));
41861
- if (end.getUTCMonth() !== month - 1) return null;
41862
- return end;
41863
- }
41864
- return null;
41824
+ //#region src/sha256.ts
41825
+ var K = new Uint32Array([
41826
+ 1116352408,
41827
+ 1899447441,
41828
+ 3049323471,
41829
+ 3921009573,
41830
+ 961987163,
41831
+ 1508970993,
41832
+ 2453635748,
41833
+ 2870763221,
41834
+ 3624381080,
41835
+ 310598401,
41836
+ 607225278,
41837
+ 1426881987,
41838
+ 1925078388,
41839
+ 2162078206,
41840
+ 2614888103,
41841
+ 3248222580,
41842
+ 3835390401,
41843
+ 4022224774,
41844
+ 264347078,
41845
+ 604807628,
41846
+ 770255983,
41847
+ 1249150122,
41848
+ 1555081692,
41849
+ 1996064986,
41850
+ 2554220882,
41851
+ 2821834349,
41852
+ 2952996808,
41853
+ 3210313671,
41854
+ 3336571891,
41855
+ 3584528711,
41856
+ 113926993,
41857
+ 338241895,
41858
+ 666307205,
41859
+ 773529912,
41860
+ 1294757372,
41861
+ 1396182291,
41862
+ 1695183700,
41863
+ 1986661051,
41864
+ 2177026350,
41865
+ 2456956037,
41866
+ 2730485921,
41867
+ 2820302411,
41868
+ 3259730800,
41869
+ 3345764771,
41870
+ 3516065817,
41871
+ 3600352804,
41872
+ 4094571909,
41873
+ 275423344,
41874
+ 430227734,
41875
+ 506948616,
41876
+ 659060556,
41877
+ 883997877,
41878
+ 958139571,
41879
+ 1322822218,
41880
+ 1537002063,
41881
+ 1747873779,
41882
+ 1955562222,
41883
+ 2024104815,
41884
+ 2227730452,
41885
+ 2361852424,
41886
+ 2428436474,
41887
+ 2756734187,
41888
+ 3204031479,
41889
+ 3329325298
41890
+ ]);
41891
+ var rotr = (x, n) => x >>> n | x << 32 - n;
41892
+ function sha256Hex(input) {
41893
+ const data = new TextEncoder().encode(input);
41894
+ const bitLen = data.length * 8;
41895
+ const total = Math.ceil((data.length + 9) / 64) * 64;
41896
+ const buf = new Uint8Array(total);
41897
+ buf.set(data);
41898
+ buf[data.length] = 128;
41899
+ const view = new DataView(buf.buffer);
41900
+ view.setUint32(total - 8, Math.floor(bitLen / 4294967296));
41901
+ view.setUint32(total - 4, bitLen >>> 0);
41902
+ const h = new Uint32Array([
41903
+ 1779033703,
41904
+ 3144134277,
41905
+ 1013904242,
41906
+ 2773480762,
41907
+ 1359893119,
41908
+ 2600822924,
41909
+ 528734635,
41910
+ 1541459225
41911
+ ]);
41912
+ const w = /* @__PURE__ */ new Uint32Array(64);
41913
+ for (let off = 0; off < total; off += 64) {
41914
+ for (let i = 0; i < 16; i++) w[i] = view.getUint32(off + i * 4);
41915
+ for (let i = 16; i < 64; i++) {
41916
+ const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ w[i - 15] >>> 3;
41917
+ const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ w[i - 2] >>> 10;
41918
+ w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
41919
+ }
41920
+ let a = h[0], b = h[1], c = h[2], d = h[3], e = h[4], f = h[5], g = h[6], hh = h[7];
41921
+ for (let i = 0; i < 64; i++) {
41922
+ const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
41923
+ const ch = e & f ^ ~e & g;
41924
+ const t1 = hh + S1 + ch + K[i] + w[i] >>> 0;
41925
+ const t2 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + (a & b ^ a & c ^ b & c) >>> 0;
41926
+ hh = g;
41927
+ g = f;
41928
+ f = e;
41929
+ e = d + t1 >>> 0;
41930
+ d = c;
41931
+ c = b;
41932
+ b = a;
41933
+ a = t1 + t2 >>> 0;
41934
+ }
41935
+ h[0] = h[0] + a >>> 0;
41936
+ h[1] = h[1] + b >>> 0;
41937
+ h[2] = h[2] + c >>> 0;
41938
+ h[3] = h[3] + d >>> 0;
41939
+ h[4] = h[4] + e >>> 0;
41940
+ h[5] = h[5] + f >>> 0;
41941
+ h[6] = h[6] + g >>> 0;
41942
+ h[7] = h[7] + hh >>> 0;
41943
+ }
41944
+ let out = "";
41945
+ for (const word of h) out += word.toString(16).padStart(8, "0");
41946
+ return out;
41865
41947
  }
41948
+ //#endregion
41949
+ //#region src/license-core.ts
41866
41950
  /** Classify a license key string. Pure and side-effect-free.
41867
41951
  * `now` is injectable so expiry behaviour is testable without faking clocks. */
41868
41952
  function checkLicenseKey(key, now = /* @__PURE__ */ new Date()) {
41869
- if (key == null || key === "") return {
41953
+ if (key == null || key.trim() === "") return {
41870
41954
  status: "unset",
41871
41955
  valid: false,
41872
41956
  edition: "suite"
41873
41957
  };
41874
- if (!key.startsWith("SVENTERPRISE-")) return {
41958
+ if (sha256Hex(key.trim().toLowerCase()) !== "dabe98638cdc5760637bb2a741e65680a6ff0fb590d8b1018c9597650486cb10") return {
41875
41959
  status: "invalid",
41876
41960
  valid: false,
41877
41961
  edition: "suite"
41878
41962
  };
41879
- if (REVOKED_KEYS.has(key)) return {
41880
- status: "revoked",
41881
- valid: false,
41882
- edition: "suite"
41883
- };
41884
- const expiresAt = parseLicenseExpiry(key) ?? void 0;
41885
- const expired = expiresAt ? now.getTime() > expiresAt.getTime() : void 0;
41886
- const status = key.startsWith("SVENTERPRISE-DEV") ? "dev" : key.startsWith("SVENTERPRISE-EVAL") ? "eval" : "licensed";
41887
41963
  return {
41888
- status,
41964
+ status: "licensed",
41889
41965
  valid: true,
41890
- edition: status === "licensed" && key.startsWith(`SVENTERPRISE-GRID-`) ? "grid" : "suite",
41891
- expiresAt,
41892
- expired
41966
+ edition: "suite"
41893
41967
  };
41894
41968
  }
41895
41969
  //#endregion
@@ -17,7 +17,7 @@
17
17
  * ```
18
18
  */
19
19
  import { registerPivotEngine } from '@svgrid/grid';
20
- import { isLicenseKeySet } from './license.js';
20
+ import { hasValidLicense } from './license.js';
21
21
  import { emitUnlicensedNudge } from './watermark.js';
22
22
  import { createPivotModel } from './pivot.js';
23
23
  let enabled = false;
@@ -34,6 +34,6 @@ export function enablePivot() {
34
34
  return;
35
35
  enabled = true;
36
36
  registerPivotEngine(pivotEngine);
37
- if (!isLicenseKeySet())
37
+ if (!hasValidLicense())
38
38
  emitUnlicensedNudge();
39
39
  }
package/dist/scheduler.js CHANGED
@@ -16,7 +16,7 @@
16
16
  * ```
17
17
  */
18
18
  import { registerSchedulerView } from '@svgrid/grid';
19
- import { isLicenseKeySet } from './license.js';
19
+ import { hasValidLicense } from './license.js';
20
20
  import { emitUnlicensedNudge } from './watermark.js';
21
21
  import SvGridScheduler from './SvGridScheduler.svelte';
22
22
  let enabled = false;
@@ -30,7 +30,7 @@ export function enableSchedulerView() {
30
30
  return;
31
31
  enabled = true;
32
32
  registerSchedulerView(SvGridScheduler);
33
- if (!isLicenseKeySet())
33
+ if (!hasValidLicense())
34
34
  emitUnlicensedNudge();
35
35
  }
36
36
  export { default as SvGridScheduler } from './SvGridScheduler.svelte';
@@ -22,7 +22,7 @@
22
22
  * ```
23
23
  */
24
24
  import { registerSelectionBarView } from '@svgrid/grid';
25
- import { isLicenseKeySet } from './license.js';
25
+ import { hasValidLicense } from './license.js';
26
26
  import { emitUnlicensedNudge } from './watermark.js';
27
27
  import SvGridSelectionBar from './SvGridSelectionBar.svelte';
28
28
  let enabled = false;
@@ -36,7 +36,7 @@ export function enableSelectionBar() {
36
36
  return;
37
37
  enabled = true;
38
38
  registerSelectionBarView(SvGridSelectionBar);
39
- if (!isLicenseKeySet())
39
+ if (!hasValidLicense())
40
40
  emitUnlicensedNudge();
41
41
  }
42
42
  export { default as SvGridSelectionBar } from './SvGridSelectionBar.svelte';
@@ -19,7 +19,7 @@
19
19
  * const ctl = createServerRowModel(source, { groupBy: ['region'], onChange })
20
20
  * ```
21
21
  */
22
- import { isLicenseKeySet } from '../license.js';
22
+ import { hasValidLicense } from '../license.js';
23
23
  import { emitUnlicensedNudge } from '../watermark.js';
24
24
  let enabled = false;
25
25
  /**
@@ -34,7 +34,7 @@ export function enableServerRowModel() {
34
34
  if (enabled)
35
35
  return;
36
36
  enabled = true;
37
- if (!isLicenseKeySet())
37
+ if (!hasValidLicense())
38
38
  emitUnlicensedNudge();
39
39
  }
40
40
  /**
@@ -0,0 +1 @@
1
+ export declare function sha256Hex(input: string): string;
package/dist/sha256.js ADDED
@@ -0,0 +1,69 @@
1
+ // Synchronous SHA-256 for the license check. WebCrypto's digest() is async,
2
+ // and setLicenseKey / checkLicenseKey are synchronous on purpose (they run at
3
+ // module start-up and in the Node / MCP generator), so the key is hashed here.
4
+ // FIPS 180-4, over the UTF-8 bytes of the input; returns lowercase hex.
5
+ const K = new Uint32Array([
6
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
7
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
8
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
9
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
10
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
11
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
12
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
13
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
14
+ ]);
15
+ const rotr = (x, n) => (x >>> n) | (x << (32 - n));
16
+ export function sha256Hex(input) {
17
+ const data = new TextEncoder().encode(input);
18
+ const bitLen = data.length * 8;
19
+ // Message + 0x80 + zero padding + 64-bit length, to a multiple of 64 bytes.
20
+ const total = Math.ceil((data.length + 9) / 64) * 64;
21
+ const buf = new Uint8Array(total);
22
+ buf.set(data);
23
+ buf[data.length] = 0x80;
24
+ const view = new DataView(buf.buffer);
25
+ view.setUint32(total - 8, Math.floor(bitLen / 0x100000000));
26
+ view.setUint32(total - 4, bitLen >>> 0);
27
+ const h = new Uint32Array([
28
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
29
+ ]);
30
+ const w = new Uint32Array(64);
31
+ for (let off = 0; off < total; off += 64) {
32
+ for (let i = 0; i < 16; i++)
33
+ w[i] = view.getUint32(off + i * 4);
34
+ for (let i = 16; i < 64; i++) {
35
+ const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);
36
+ const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);
37
+ w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0;
38
+ }
39
+ let a = h[0], b = h[1], c = h[2], d = h[3], e = h[4], f = h[5], g = h[6], hh = h[7];
40
+ for (let i = 0; i < 64; i++) {
41
+ const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
42
+ const ch = (e & f) ^ (~e & g);
43
+ const t1 = (hh + S1 + ch + K[i] + w[i]) >>> 0;
44
+ const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
45
+ const maj = (a & b) ^ (a & c) ^ (b & c);
46
+ const t2 = (S0 + maj) >>> 0;
47
+ hh = g;
48
+ g = f;
49
+ f = e;
50
+ e = (d + t1) >>> 0;
51
+ d = c;
52
+ c = b;
53
+ b = a;
54
+ a = (t1 + t2) >>> 0;
55
+ }
56
+ h[0] = (h[0] + a) >>> 0;
57
+ h[1] = (h[1] + b) >>> 0;
58
+ h[2] = (h[2] + c) >>> 0;
59
+ h[3] = (h[3] + d) >>> 0;
60
+ h[4] = (h[4] + e) >>> 0;
61
+ h[5] = (h[5] + f) >>> 0;
62
+ h[6] = (h[6] + g) >>> 0;
63
+ h[7] = (h[7] + hh) >>> 0;
64
+ }
65
+ let out = '';
66
+ for (const word of h)
67
+ out += word.toString(16).padStart(8, '0');
68
+ return out;
69
+ }
@@ -16,6 +16,7 @@
16
16
  // - SSR-safe: every DOM access is guarded. On the server it's a no-op.
17
17
  // - Zero dependencies, inline styles - no CSS file to import, nothing to
18
18
  // bundle, works in any host app regardless of its styling.
19
+ import { isFirstPartySite } from './first-party.js';
19
20
  const CARD_ATTR = 'data-svgrid-enterprise-upgrade';
20
21
  const PRICING_URL = 'https://svgrid.com/pricing';
21
22
  // ?ref=in-app lets us measure how many trials start from this exact prompt
@@ -32,6 +33,8 @@ export function showUpgradePrompt(feature, opts) {
32
33
  return;
33
34
  if (typeof document === 'undefined' || typeof window === 'undefined')
34
35
  return;
36
+ if (isFirstPartySite())
37
+ return;
35
38
  if (document.querySelector(`[${CARD_ATTR}]`))
36
39
  return;
37
40
  shownThisSession = true;
package/dist/version.d.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
12
12
  */
13
- export declare const SVGRID_VERSION = "3.1.2";
13
+ export declare const SVGRID_VERSION = "3.1.4";
14
14
  /**
15
15
  * The version of `@svgrid/grid`, which releases on its own line: enterprise is
16
16
  * on 3.1.x while the grid is on 3.0.x.
package/dist/version.js CHANGED
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
12
12
  */
13
- export const SVGRID_VERSION = '3.1.2';
13
+ export const SVGRID_VERSION = '3.1.4';
14
14
  /**
15
15
  * The version of `@svgrid/grid`, which releases on its own line: enterprise is
16
16
  * on 3.1.x while the grid is on 3.0.x.
package/dist/watermark.js CHANGED
@@ -1,15 +1,19 @@
1
1
  // Evaluation UX for unlicensed @svgrid/enterprise use. Shows a small clickable
2
2
  // "www.svgrid.com" watermark in the bottom-right corner of every SvGrid on
3
3
  // the page, which fades out after 5 seconds, and emits a one-time console
4
- // nudge. Hard errors (revoked / bad-prefix keys) still throw via license.ts -
5
- // this file is only for the "no key set" case where the feature continues to
6
- // work but the user gets nudged.
4
+ // nudge. Shown for "no key" and for a key that is not the license key alike;
5
+ // neither throws, the feature keeps working and the user gets nudged. Never
6
+ // shown on svgrid.com itself (first-party.ts).
7
+ import { isFirstPartySite } from './first-party.js';
7
8
  const WATERMARK_ATTR = 'data-svgrid-enterprise-watermark';
8
9
  // Marks a grid that has already shown (and faded) its watermark, so the
9
10
  // MutationObserver doesn't re-add it once it fades out and is removed.
10
11
  const NUDGED_ATTR = 'data-svgrid-enterprise-nudged';
11
- const HOMEPAGE_URL = 'https://svgrid.com';
12
- const LICENSE_URL = 'https://svgrid.com/pricing/';
12
+ // Both point at pricing with UTM tags, the convention upgrade-prompt.ts set.
13
+ // The watermark link carries rel="noreferrer", so without utm_medium the site
14
+ // analytics cannot tell a visit from an unlicensed install from direct traffic.
15
+ const WATERMARK_URL = 'https://svgrid.com/pricing/?utm_source=svgrid-enterprise&utm_medium=watermark';
16
+ const LICENSE_URL = 'https://svgrid.com/pricing/?utm_source=svgrid-enterprise&utm_medium=console';
13
17
  const WATERMARK_LABEL = 'www.svgrid.com';
14
18
  // How long the watermark stays fully visible before it starts fading, and how
15
19
  // long the fade itself takes.
@@ -18,6 +22,8 @@ const FADE_MS = 700;
18
22
  let consoleNudgeShown = false;
19
23
  let observer = null;
20
24
  export function emitUnlicensedNudge() {
25
+ if (isFirstPartySite())
26
+ return;
21
27
  showConsoleOnce();
22
28
  if (typeof document === 'undefined' || typeof window === 'undefined')
23
29
  return;
@@ -128,7 +134,7 @@ function ensureFixedFallback() {
128
134
  function buildWatermark(kind) {
129
135
  const a = document.createElement('a');
130
136
  a.setAttribute(WATERMARK_ATTR, kind);
131
- a.href = HOMEPAGE_URL;
137
+ a.href = WATERMARK_URL;
132
138
  a.target = '_blank';
133
139
  a.rel = 'noopener noreferrer';
134
140
  a.textContent = WATERMARK_LABEL;