@svgrid/enterprise 2.5.1 → 2.5.3
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/cdn/svgrid-enterprise.svelte-external.js +2989 -2981
- package/dist/designer/assets/{index-OwdzSsmo.js → index-CBYU-KNn.js} +3 -3
- package/dist/designer/assets/{src-LRVqg7Sf.js → src-i309BeJb.js} +184 -184
- package/dist/designer/index.html +2 -2
- package/dist/node/studio.js +1 -1
- package/package.json +1 -1
- package/src/license-expiry.test.ts +53 -0
- package/src/license.ts +33 -8
- package/src/version.ts +1 -1
package/dist/designer/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>SvGrid Studio - Designer</title>
|
|
7
|
-
<script type="module" crossorigin src="./assets/index-
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-CBYU-KNn.js"></script>
|
|
8
8
|
<link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-Dd_uD5pT.js">
|
|
9
9
|
<link rel="modulepreload" crossorigin href="./assets/disclose-version-CIm4S9xS.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="./assets/export-format-DwjuTfrQ.js">
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/easing-zaypKrr0.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/chart-DHEgt4lN.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/SvGridChart-BEDNTdc5.js">
|
|
19
|
-
<link rel="modulepreload" crossorigin href="./assets/src-
|
|
19
|
+
<link rel="modulepreload" crossorigin href="./assets/src-i309BeJb.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="./assets/SvListBox-BVzVfCG3.js">
|
|
21
21
|
<link rel="stylesheet" crossorigin href="./assets/dismissable-BF-9TJSd.css">
|
|
22
22
|
<link rel="stylesheet" crossorigin href="./assets/SvDateTimePicker-Cygij-dr.css">
|
package/dist/node/studio.js
CHANGED
|
@@ -15130,7 +15130,7 @@ function hasFieldConditions(schema) {
|
|
|
15130
15130
|
*
|
|
15131
15131
|
* `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
|
|
15132
15132
|
*/
|
|
15133
|
-
var SVGRID_VERSION = "2.5.
|
|
15133
|
+
var SVGRID_VERSION = "2.5.3";
|
|
15134
15134
|
//#endregion
|
|
15135
15135
|
//#region src/studio/emit-project.ts
|
|
15136
15136
|
var has = (blocks, kind) => blocks.some((b) => b.config.kind === kind);
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"type": "commercial",
|
|
5
5
|
"url": "https://svgrid.com/pricing"
|
|
6
6
|
},
|
|
7
|
-
"version": "2.5.
|
|
7
|
+
"version": "2.5.3",
|
|
8
8
|
"description": "Enterprise feature pack for SvGrid: Excel (xlsx), PDF, CSV, TSV and HTML export, Excel/CSV/JSON import, pivot tables with a drag-and-drop designer, paginated print, Kanban board and scheduler views. Requires a paid license key.",
|
|
9
9
|
"license": "SEE LICENSE IN LICENSE",
|
|
10
10
|
"author": "jQWidgets <sales@jqwidgets.com>",
|
|
@@ -9,10 +9,25 @@ import {
|
|
|
9
9
|
setLicenseKey,
|
|
10
10
|
} from './license'
|
|
11
11
|
import { dismissUpgradePrompt } from './upgrade-prompt'
|
|
12
|
+
import { emitUnlicensedNudge } from './watermark'
|
|
13
|
+
|
|
14
|
+
// Keep everything else in the module real; only the watermark emitter is spied.
|
|
15
|
+
vi.mock('./watermark', async (importOriginal) => ({
|
|
16
|
+
...(await importOriginal()),
|
|
17
|
+
emitUnlicensedNudge: vi.fn(),
|
|
18
|
+
}))
|
|
12
19
|
|
|
13
20
|
const KEY = 'SVENTERPRISE-EVAL-GUNEI-5-20260904-RGY2TN'
|
|
14
21
|
const CARD = '[data-svgrid-enterprise-upgrade]'
|
|
15
22
|
|
|
23
|
+
/** Calls to emitUnlicensedNudge() since the last reset.
|
|
24
|
+
*
|
|
25
|
+
* Spied rather than counted in the DOM: the real function attaches its badge
|
|
26
|
+
* to grid elements on a microtask, so in a document with no grid it renders
|
|
27
|
+
* nothing and a node count would read 0 for every case - passing even if the
|
|
28
|
+
* watermark were wired up wrongly. The call is the contract under test. */
|
|
29
|
+
const watermarkCalls = () => vi.mocked(emitUnlicensedNudge).mock.calls.length
|
|
30
|
+
|
|
16
31
|
describe('trial key expiry parsing', () => {
|
|
17
32
|
it('unlocks Enterprise today', () => {
|
|
18
33
|
const info = checkLicenseKey(KEY, new Date('2026-08-21T12:00:00Z'))
|
|
@@ -51,6 +66,7 @@ describe('what happens after the trial ends', () => {
|
|
|
51
66
|
vi.useRealTimers()
|
|
52
67
|
clearLicenseKey()
|
|
53
68
|
dismissUpgradePrompt()
|
|
69
|
+
vi.mocked(emitUnlicensedNudge).mockClear()
|
|
54
70
|
document.body.innerHTML = ''
|
|
55
71
|
})
|
|
56
72
|
|
|
@@ -81,6 +97,43 @@ describe('what happens after the trial ends', () => {
|
|
|
81
97
|
expect(getLicenseExpiry()?.toISOString()).toBe('2026-09-04T23:59:59.999Z')
|
|
82
98
|
})
|
|
83
99
|
|
|
100
|
+
it('a lapsed trial gets the watermark, the console notice AND the card', () => {
|
|
101
|
+
vi.useFakeTimers({ now: new Date('2026-09-20T10:00:00Z') })
|
|
102
|
+
const info = vi.spyOn(console, 'info').mockImplementation(() => {})
|
|
103
|
+
setLicenseKey(KEY)
|
|
104
|
+
assertEnterpriseLicensed('Export')
|
|
105
|
+
|
|
106
|
+
// The evaluation is over, so the app stops looking licensed on every
|
|
107
|
+
// surface - it just keeps working.
|
|
108
|
+
expect(document.querySelector(CARD)).not.toBeNull()
|
|
109
|
+
expect(watermarkCalls()).toBeGreaterThan(0)
|
|
110
|
+
expect(info.mock.calls.flat().join(' ')).toMatch(/evaluation license expired on 2026-09-04/)
|
|
111
|
+
info.mockRestore()
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('the expiry console notice fires once, not on every Pro call', () => {
|
|
115
|
+
vi.useFakeTimers({ now: new Date('2026-09-20T10:00:00Z') })
|
|
116
|
+
const info = vi.spyOn(console, 'info').mockImplementation(() => {})
|
|
117
|
+
setLicenseKey(KEY)
|
|
118
|
+
assertEnterpriseLicensed('Export')
|
|
119
|
+
assertEnterpriseLicensed('Export')
|
|
120
|
+
assertEnterpriseLicensed('Print')
|
|
121
|
+
|
|
122
|
+
const expiryNotices = info.mock.calls
|
|
123
|
+
.flat()
|
|
124
|
+
.filter((m) => typeof m === 'string' && m.includes('evaluation license expired'))
|
|
125
|
+
expect(expiryNotices).toHaveLength(1)
|
|
126
|
+
info.mockRestore()
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('an app with no key at all still gets the watermark', () => {
|
|
130
|
+
clearLicenseKey()
|
|
131
|
+
assertEnterpriseLicensed('Export')
|
|
132
|
+
|
|
133
|
+
expect(document.querySelector(CARD)).not.toBeNull()
|
|
134
|
+
expect(watermarkCalls()).toBeGreaterThan(0)
|
|
135
|
+
})
|
|
136
|
+
|
|
84
137
|
it('a paid key never shows the card', () => {
|
|
85
138
|
vi.useFakeTimers({ now: new Date('2026-09-20T10:00:00Z') })
|
|
86
139
|
setLicenseKey('SVENTERPRISE-ACME-5-202705-ABC123')
|
package/src/license.ts
CHANGED
|
@@ -12,10 +12,11 @@
|
|
|
12
12
|
// in REVOKED_KEYS -> throws (revoked / leaked / expired)
|
|
13
13
|
// starts with "SVENTERPRISE-DEV" or
|
|
14
14
|
// "SVENTERPRISE-EVAL" -> works; one-time console.info notice
|
|
15
|
-
// an EXPIRED dev/eval key -> still works, but
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
15
|
+
// an EXPIRED dev/eval key -> still works, but stops looking
|
|
16
|
+
// licensed: watermark + a one-time
|
|
17
|
+
// console notice naming the expiry date
|
|
18
|
+
// + the upgrade card. Stays a soft gate
|
|
19
|
+
// so a trial ending cannot break a build.
|
|
19
20
|
// any other "SVENTERPRISE-..." -> works silently (paid production)
|
|
20
21
|
|
|
21
22
|
import { checkLicenseKey, VALID_PREFIX, type LicenseInfo } from './license-core'
|
|
@@ -26,6 +27,22 @@ export { checkLicenseKey, type LicenseInfo, type LicenseStatus } from './license
|
|
|
26
27
|
|
|
27
28
|
let currentKey: string | null = null
|
|
28
29
|
let noticedDev = false
|
|
30
|
+
let noticedExpired = false
|
|
31
|
+
|
|
32
|
+
/** One-time console notice for a trial that has run out. Separate from the
|
|
33
|
+
* dev/eval notice: that one says "not for production", this one says the
|
|
34
|
+
* evaluation is over and names the date, which is the actionable part. */
|
|
35
|
+
function noticeExpired(info: LicenseInfo): void {
|
|
36
|
+
if (noticedExpired) return
|
|
37
|
+
noticedExpired = true
|
|
38
|
+
const on = info.expiresAt ? ` on ${info.expiresAt.toISOString().slice(0, 10)}` : ''
|
|
39
|
+
// eslint-disable-next-line no-console
|
|
40
|
+
console.info(
|
|
41
|
+
`@svgrid/enterprise: your evaluation license expired${on}. Everything still ` +
|
|
42
|
+
'works, but the watermark and upgrade notice stay until a license key is set. ' +
|
|
43
|
+
'Contact sales@jqwidgets.com or see https://svgrid.com/pricing',
|
|
44
|
+
)
|
|
45
|
+
}
|
|
29
46
|
|
|
30
47
|
export function setLicenseKey(key: string): void {
|
|
31
48
|
if (typeof key !== 'string' || key.length === 0) {
|
|
@@ -33,11 +50,13 @@ export function setLicenseKey(key: string): void {
|
|
|
33
50
|
}
|
|
34
51
|
currentKey = key
|
|
35
52
|
noticedDev = false
|
|
53
|
+
noticedExpired = false
|
|
36
54
|
}
|
|
37
55
|
|
|
38
56
|
export function clearLicenseKey(): void {
|
|
39
57
|
currentKey = null
|
|
40
58
|
noticedDev = false
|
|
59
|
+
noticedExpired = false
|
|
41
60
|
}
|
|
42
61
|
|
|
43
62
|
export function getLicenseKey(): string | null {
|
|
@@ -84,8 +103,13 @@ export function nudgeEnterprise(feature?: EnterpriseFeatureLabel): void {
|
|
|
84
103
|
// `valid` stays true past a trial's expiry (the feature keeps running), so
|
|
85
104
|
// checking it alone would let a lapsed trial through silently forever.
|
|
86
105
|
if (info.valid && !info.expired) return
|
|
106
|
+
const lapsedTrial = info.valid && info.expired === true
|
|
107
|
+
// A lapsed trial gets the same treatment as an unlicensed app - watermark,
|
|
108
|
+
// console notice and card. The evaluation is over; the app keeps running,
|
|
109
|
+
// but it stops looking licensed.
|
|
87
110
|
emitUnlicensedNudge()
|
|
88
|
-
|
|
111
|
+
if (lapsedTrial) noticeExpired(info)
|
|
112
|
+
showUpgradePrompt(feature, { expired: lapsedTrial })
|
|
89
113
|
}
|
|
90
114
|
|
|
91
115
|
export function assertEnterpriseLicensed(feature?: EnterpriseFeatureLabel): void {
|
|
@@ -111,10 +135,11 @@ export function assertEnterpriseLicensed(feature?: EnterpriseFeatureLabel): void
|
|
|
111
135
|
case 'dev':
|
|
112
136
|
case 'eval':
|
|
113
137
|
if (info.expired) {
|
|
114
|
-
// The trial is over. Deliberately NOT a throw: the app keeps working
|
|
115
|
-
//
|
|
116
|
-
//
|
|
138
|
+
// The trial is over. Deliberately NOT a throw: the app keeps working,
|
|
139
|
+
// so the developer sees the nudges without their users hitting a broken
|
|
140
|
+
// build. Watermark + console notice + card, same as an unlicensed app.
|
|
117
141
|
emitUnlicensedNudge()
|
|
142
|
+
noticeExpired(info)
|
|
118
143
|
showUpgradePrompt(feature, { expired: true })
|
|
119
144
|
return
|
|
120
145
|
}
|
package/src/version.ts
CHANGED