@mui/x-license 7.16.0 → 7.18.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,186 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 7.18.0
7
+
8
+ _Sep 20, 2024_
9
+
10
+ We'd like to offer a big thanks to the 14 contributors who made this release possible. Here are some highlights ✨:
11
+
12
+ - 💫 Support [Row spanning](https://mui.com/x/react-data-grid/row-spanning/) on the Data Grid that automatically merges the consecutive cells in a column based on the cell value
13
+
14
+ <img width="600" src="https://github.com/user-attachments/assets/d32ec936-d238-4c92-9e1a-af6788d74cdf" alt="data grid row spanning" />
15
+
16
+ - ⏰ Support `date-fns` v4 (#14673) @LukasTy
17
+ - 🎉 Add option for Pickers to change the order of displayed years (#11780) @thomasmoon
18
+ - 🐞 Bugfixes
19
+ - 📚 Documentation improvements
20
+
21
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
22
+
23
+ ### Data Grid
24
+
25
+ #### `@mui/x-data-grid@7.18.0`
26
+
27
+ - [DataGrid] Add default reset value in row edit mode (#14050) @michelengelen
28
+ - [DataGrid] Add `columnGroupHeaderHeight` prop for sizing column group headers (#14637) @KenanYusuf
29
+ - [DataGrid] Fix `document` reference when the grid is rendered in a popup window (#14649) @arminmeh
30
+ - [DataGrid] Remove `minFirstColumn` from `GetHeadersParams` interface (#14450) @k-rajat19
31
+ - [DataGrid] Row spanning (#14124) @MBilalShafi
32
+
33
+ #### `@mui/x-data-grid-pro@7.18.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
34
+
35
+ Same changes as in `@mui/x-data-grid@7.18.0`, plus:
36
+
37
+ - [DataGridPro] Fix `onRowsScrollEnd` being triggered instantly when bottom pinned row is present (#14602) @arminmeh
38
+ - [DataGridPro] Fix header filters rendering issue for `isEmpty` and `isNotEmpty` filter operators (#14493) @k-rajat19
39
+ - [DataGridPro] Fix pinned columns in RTL mode (#14586) @KenanYusuf
40
+
41
+ #### `@mui/x-data-grid-premium@7.18.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
42
+
43
+ Same changes as in `@mui/x-data-grid-pro@7.18.0`.
44
+
45
+ ### Date and Time Pickers
46
+
47
+ #### `@mui/x-date-pickers@7.18.0`
48
+
49
+ - [pickers] Add option to change the order of displayed years (#11780) @thomasmoon
50
+ - [pickers] Support `date-fns` v4 (#14673) @LukasTy
51
+
52
+ #### `@mui/x-date-pickers-pro@7.18.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
53
+
54
+ Same changes as in `@mui/x-date-pickers@7.18.0`.
55
+
56
+ ### Charts
57
+
58
+ #### `@mui/x-charts@7.18.0`
59
+
60
+ - [charts] Add a `PolarProvider` to manage polar axes (#14642) @alexfauquette
61
+ - [charts] Fix `LineChart` animation being stuck with initial drawing area value (#14553) @JCQuintas
62
+ - [charts] Fix legend slot typing (#14657) @alexfauquette
63
+ - [charts] Pass the axis index to extremum getter (#14641) @alexfauquette
64
+ - [charts] Provide hooks to create custom tooltip (#14377) @alexfauquette
65
+
66
+ #### `@mui/x-charts-pro@7.0.0-beta.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
67
+
68
+ Same changes as in `@mui/x-charts@7.18.0`.
69
+
70
+ ### Tree View
71
+
72
+ #### `@mui/x-tree-view@7.18.0`
73
+
74
+ - [TreeView] Add `"use client"` directive to every public component and hook (#14579) @flaviendelangle
75
+
76
+ ### Docs
77
+
78
+ - [docs] Add `groupingValueGetter` callout in column definition docs (#14599) @michelengelen
79
+ - [docs] Clean v6 => v7 migration guide (#14652) @flaviendelangle
80
+ - [docs] Copy `vale-action.yml` from main repo @oliviertassinari
81
+ - [docs] Edit the Pickers Getting started doc (#14555) @samuelsycamore
82
+ - [docs] Fix TypeScript capitalization @oliviertassinari
83
+ - [docs] Fix Vale error @oliviertassinari
84
+ - [docs] Make the migration guide diff a bit easier to read @oliviertassinari
85
+ - [docs] Report Vale at warning level (#14660) @oliviertassinari
86
+ - [docs] Warn about the `valueGetter` and `valueFormatter` signature change (#14613) @cherniavskii
87
+ - [docs] Polish code formatting (#14603) @oliviertassinari
88
+ - [test] Spy on `observe` method to avoid flaky wait for a callback (#14640) @arminmeh
89
+
90
+ ### Core
91
+
92
+ - [core] Fix 301 link to Next.js and git diff @oliviertassinari
93
+ - [core] Fix failing CI on `master` (#14644) @cherniavskii
94
+ - [core] Fix `package.json` repository rule @oliviertassinari
95
+ - [core] MUI X repository moved to a new location @oliviertassinari
96
+ - [docs-infra] Strengthen CSP (#14581) @oliviertassinari
97
+ - [license] Finish renaming of LicensingModel (#14615) @oliviertassinari
98
+
99
+ ## 7.17.0
100
+
101
+ _Sep 13, 2024_
102
+
103
+ We'd like to offer a big thanks to the 12 contributors who made this release possible. Here are some highlights ✨:
104
+
105
+ - 📊 Charts performance improvement
106
+ - 🧑‍💻 New Data Grid [custom columns demo](https://mui.com/x/react-data-grid/custom-columns/#full-example)
107
+ - 🐞 Bugfixes
108
+ - 📚 Documentation improvements
109
+ - 🌍 Improve Hungarian (hu-HU) locale on the Data Grid
110
+
111
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
112
+
113
+ ### Data Grid
114
+
115
+ #### `@mui/x-data-grid@7.17.0`
116
+
117
+ - [DataGrid] Add "does not equal" and "does not contain" filter operators (#14489) @KenanYusuf
118
+ - [DataGrid] Add demo to the "Custom columns" page that does not use generator (#13695) @arminmeh
119
+ - [DataGrid] Fix Voice Over reading the column name twice (#14482) @arminmeh
120
+ - [DataGrid] Fix bug in CRUD example (#14513) @michelengelen
121
+ - [DataGrid] Fix failing jsdom tests caused by `:has()` selectors (#14559) @KenanYusuf
122
+ - [DataGrid] Refactor string operator filter functions (#14564) @KenanYusuf
123
+ - [l10n] Improve Hungarian (hu-HU) locale (#14506) @ntamas
124
+
125
+ #### `@mui/x-data-grid-pro@7.17.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
126
+
127
+ Same changes as in `@mui/x-data-grid@7.17.0`.
128
+
129
+ #### `@mui/x-data-grid-premium@7.17.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
130
+
131
+ Same changes as in `@mui/x-data-grid-pro@7.17.0`.
132
+
133
+ ### Date and Time Pickers
134
+
135
+ #### `@mui/x-date-pickers@7.17.0`
136
+
137
+ - [fields] Improve `useSplitFieldProps` and make it public (#14514) @flaviendelangle
138
+ - [pickers] Improve clear action label (#14243) @oliviertassinari
139
+ - [pickers] Add `"use client"` directive to every public component and hook (#14562) @flaviendelangle
140
+ - [pickers] Allow custom fields to validate the value (#14486) @flaviendelangle
141
+ - [pickers] Stop using utils in locales (#14505) @flaviendelangle
142
+
143
+ #### `@mui/x-date-pickers-pro@7.17.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
144
+
145
+ Same changes as in `@mui/x-date-pickers@7.17.0`, plus:
146
+
147
+ - [DateRangePicker] Fix `currentMonthCalendarPosition` not scrolling to future sibling (#14442) @GMchris
148
+
149
+ ### Charts
150
+
151
+ #### `@mui/x-charts@7.17.0`
152
+
153
+ - [charts] Add `"use client"` directive to every public component and hook (#14578) @flaviendelangle
154
+ - [charts] Allow `onItemClick` on the `Legend` component (#14231) @JCQuintas
155
+ - [charts] Fix `onAxisClick` with `layout='horizontal'` (#14547) @alexfauquette
156
+ - [charts] Replace `path` with `circle` for performance improvement (#14518) @alexfauquette
157
+
158
+ #### `@mui/x-charts-pro@7.0.0-beta.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
159
+
160
+ Same changes as in `@mui/x-charts@7.17.0`.
161
+
162
+ ### Tree View
163
+
164
+ #### `@mui/x-tree-view@7.17.0`
165
+
166
+ - [TreeView] Make `useTreeItem2` stable (#14498) @flaviendelangle
167
+
168
+ ### Docs
169
+
170
+ - [docs] Add missing callout on "Imperative API" tree view sections (#14503) @flaviendelangle
171
+ - [docs] Fix broken redirection to MUI X v5 @oliviertassinari
172
+ - [docs] Fix multiple `console.error` messages on `charts` docs (#14554) @JCQuintas
173
+ - [docs] Fixed typo in Row Grouping recipes (#14549) @Miodini
174
+ - [docs] Match title with blog posts @oliviertassinari
175
+
176
+ ### Core
177
+
178
+ - [core] Move warning methods to `@mui/x-internals` (#14528) @k-rajat19
179
+ - [core] Sync with core release flow @oliviertassinari
180
+ - [code-infra] Fix charts benchmark workflow (#14573) @JCQuintas
181
+ - [docs-infra] Type interface API pages (#14138) @alexfauquette
182
+ - [infra] Create `ESLint plugins` renovate group (#14574) @LukasTy
183
+ - [license] Clean-up terminology to match codebase (#14531) @oliviertassinari
184
+ - [test] Remove dead `act()` logic (#14529) @oliviertassinari
185
+
6
186
  ## 7.16.0
7
187
 
8
188
  _Sep 5, 2024_
@@ -108,7 +288,7 @@ We'd like to offer a big thanks to the 8 contributors who made this release poss
108
288
 
109
289
  - 💫 Support Material UI v6 (`@mui/material@6`) peer dependency (#14142) @cherniavskii
110
290
 
111
- You can now use MUI X components with either v5 or v6 of `@mui/material` package 🎉
291
+ You can now use MUI X components with either v5 or v6 of `@mui/material` package 🎉
112
292
 
113
293
  - 🐞 Bugfixes
114
294
 
@@ -153,7 +333,7 @@ Same changes as in `@mui/x-charts@7.15.0`, plus:
153
333
 
154
334
  - [docs] Fix sentence case `h2` @oliviertassinari
155
335
  - [docs] Clarify contribution guide references @oliviertassinari
156
- - [docs] Fix Stack Overflow issue canned response @oliviertassinari
336
+ - [docs] Fix Stack Overflow issue canned response @oliviertassinari
157
337
  - [docs] Fix outdated link to support page @oliviertassinari
158
338
  - [docs] Fix use of Material UI @oliviertassinari
159
339
  - [docs] Update deprecated props in docs (#14295) @JCQuintas
@@ -411,7 +591,7 @@ The [Pro plan](https://mui.com/x/introduction/licensing/#pro-plan) is receiving
411
591
 
412
592
  As always, every feature released as part of the MIT plan will remain free and MIT licensed forever.
413
593
 
414
- This expansion of the Pro plan comes with some adjustments to our pricing strategy. Learn more about those in the [Upcoming changes to MUI X pricing in 2024](https://mui.com/blog/mui-x-sep-2024-price-update/) blog post.
594
+ This expansion of the Pro plan comes with some adjustments to our pricing strategy. Learn more about those in the [Upcoming changes to MUI X pricing in 2024](https://mui.com/blog/mui-x-sep-2024-price-update/) blog post.
415
595
 
416
596
  ### Highlights
417
597
 
@@ -476,7 +656,7 @@ Same changes as in `@mui/x-date-pickers@7.12.0`.
476
656
  #### `@mui/x-charts@7.12.0`
477
657
 
478
658
  - [charts] Fix incorrect `axisId` prop being allowed in xAxis/yAxis config. Use `id` instead. (#13986) @JCQuintas
479
- - [charts] Use vendor to have Common JS bundle working out of the box (#13608) @alexfauquette
659
+ - [charts] Use vendor to have CommonJS bundle working out of the box (#13608) @alexfauquette
480
660
  - [charts] Divide the `SeriesProvider` to use in filtering (#14026) @JCQuintas
481
661
 
482
662
  ### Tree View
@@ -1,12 +1,10 @@
1
- import { LicenseScope, PlanVersion } from '../utils/licenseScope';
2
- import { LicensingModel } from '../utils/licensingModel';
1
+ import { PlanScope, PlanVersion } from '../utils/plan';
2
+ import { LicenseModel } from '../utils/licenseModel';
3
3
  export interface LicenseDetails {
4
- orderNumber: string;
5
4
  expiryDate: Date;
6
- scope?: LicenseScope;
7
- planScope?: LicenseScope;
8
- licenseModel?: LicensingModel;
9
- licensingModel?: LicensingModel;
5
+ licenseModel?: LicenseModel;
6
+ orderNumber: string;
7
+ planScope?: PlanScope;
10
8
  planVersion: PlanVersion;
11
9
  }
12
10
  export declare function generateLicense(details: LicenseDetails): string;
@@ -1,21 +1,13 @@
1
1
  import { md5 } from "../encoding/md5.js";
2
2
  import { base64Encode } from "../encoding/base64.js";
3
- import { LICENSE_SCOPES } from "../utils/licenseScope.js";
4
- import { LICENSING_MODELS } from "../utils/licensingModel.js";
3
+ import { PLAN_SCOPES } from "../utils/plan.js";
4
+ import { LICENSE_MODELS } from "../utils/licenseModel.js";
5
5
  const licenseVersion = '2';
6
6
  function getClearLicenseString(details) {
7
- // TODO remove
8
- if (details.licensingModel) {
9
- details.licenseModel = details.licensingModel;
10
- }
11
- // TODO remove
12
- if (details.scope) {
13
- details.planScope = details.scope;
14
- }
15
- if (details.planScope && !LICENSE_SCOPES.includes(details.planScope)) {
7
+ if (details.planScope && !PLAN_SCOPES.includes(details.planScope)) {
16
8
  throw new Error('MUI X: Invalid scope');
17
9
  }
18
- if (details.licenseModel && !LICENSING_MODELS.includes(details.licenseModel)) {
10
+ if (details.licenseModel && !LICENSE_MODELS.includes(details.licenseModel)) {
19
11
  throw new Error('MUI X: Invalid licensing model');
20
12
  }
21
13
  const keyParts = [`O=${details.orderNumber}`, `E=${details.expiryDate.getTime()}`, `S=${details.planScope}`, `LM=${details.licenseModel}`, `PV=${details.planVersion}`, `KV=${licenseVersion}`];
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-license v7.16.0
2
+ * @mui/x-license v7.18.0
3
3
  *
4
4
  * @license MUI X Commercial
5
5
  * This source code is licensed under the commercial license found in the
@@ -1,21 +1,13 @@
1
1
  import { md5 } from "../encoding/md5.js";
2
2
  import { base64Encode } from "../encoding/base64.js";
3
- import { LICENSE_SCOPES } from "../utils/licenseScope.js";
4
- import { LICENSING_MODELS } from "../utils/licensingModel.js";
3
+ import { PLAN_SCOPES } from "../utils/plan.js";
4
+ import { LICENSE_MODELS } from "../utils/licenseModel.js";
5
5
  const licenseVersion = '2';
6
6
  function getClearLicenseString(details) {
7
- // TODO remove
8
- if (details.licensingModel) {
9
- details.licenseModel = details.licensingModel;
10
- }
11
- // TODO remove
12
- if (details.scope) {
13
- details.planScope = details.scope;
14
- }
15
- if (details.planScope && !LICENSE_SCOPES.includes(details.planScope)) {
7
+ if (details.planScope && !PLAN_SCOPES.includes(details.planScope)) {
16
8
  throw new Error('MUI X: Invalid scope');
17
9
  }
18
- if (details.licenseModel && !LICENSING_MODELS.includes(details.licenseModel)) {
10
+ if (details.licenseModel && !LICENSE_MODELS.includes(details.licenseModel)) {
19
11
  throw new Error('MUI X: Invalid licensing model');
20
12
  }
21
13
  const keyParts = [`O=${details.orderNumber}`, `E=${details.expiryDate.getTime()}`, `S=${details.planScope}`, `LM=${details.licenseModel}`, `PV=${details.planVersion}`, `KV=${licenseVersion}`];
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-license v7.16.0
2
+ * @mui/x-license v7.18.0
3
3
  *
4
4
  * @license MUI X Commercial
5
5
  * This source code is licensed under the commercial license found in the
@@ -1,4 +1,4 @@
1
- export const LICENSING_MODELS = [
1
+ export const LICENSE_MODELS = [
2
2
  /**
3
3
  * A license is outdated if the current version of the software was released after the expiry date of the license.
4
4
  * But the license can be used indefinitely with an older version of the software.
@@ -10,6 +10,8 @@ export const LICENSING_MODELS = [
10
10
  */
11
11
  'annual',
12
12
  /**
13
- * TODO 2025 remove, legacy name of annual.
13
+ * Legacy. The previous name for 'annual'.
14
+ * Can be removed once old license keys generated with 'subscription' are no longer supported.
15
+ * To support for a while. We need more years of backward support and we sell multi year licenses.
14
16
  */
15
17
  'subscription'];
@@ -0,0 +1,2 @@
1
+ export const PLAN_SCOPES = ['pro', 'premium'];
2
+ export const PLAN_VERSIONS = ['initial', 'Q3-2024'];
@@ -1,8 +1,8 @@
1
1
  import { base64Decode, base64Encode } from "../encoding/base64.js";
2
2
  import { md5 } from "../encoding/md5.js";
3
3
  import { LICENSE_STATUS } from "../utils/licenseStatus.js";
4
- import { LICENSE_SCOPES } from "../utils/licenseScope.js";
5
- import { LICENSING_MODELS } from "../utils/licensingModel.js";
4
+ import { PLAN_SCOPES } from "../utils/plan.js";
5
+ import { LICENSE_MODELS } from "../utils/licenseModel.js";
6
6
  const getDefaultReleaseDate = () => {
7
7
  const today = new Date();
8
8
  today.setHours(0, 0, 0, 0);
@@ -11,7 +11,7 @@ const getDefaultReleaseDate = () => {
11
11
  export function generateReleaseInfo(releaseDate = getDefaultReleaseDate()) {
12
12
  return base64Encode(releaseDate.getTime().toString());
13
13
  }
14
- function isLicenseScopeSufficient(packageName, licenseScope) {
14
+ function isPlanScopeSufficient(packageName, planScope) {
15
15
  let acceptedScopes;
16
16
  if (packageName.includes('-pro')) {
17
17
  acceptedScopes = ['pro', 'premium'];
@@ -20,7 +20,7 @@ function isLicenseScopeSufficient(packageName, licenseScope) {
20
20
  } else {
21
21
  acceptedScopes = [];
22
22
  }
23
- return acceptedScopes.includes(licenseScope);
23
+ return acceptedScopes.includes(planScope);
24
24
  }
25
25
  const expiryReg = /^.*EXPIRY=([0-9]+),.*$/;
26
26
  const PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN = ['x-data-grid-pro', 'x-date-pickers-pro'];
@@ -39,29 +39,29 @@ const decodeLicenseVersion1 = license => {
39
39
  expiryTimestamp = null;
40
40
  }
41
41
  return {
42
- scope: 'pro',
43
- licensingModel: 'perpetual',
42
+ planScope: 'pro',
43
+ licenseModel: 'perpetual',
44
44
  expiryTimestamp,
45
45
  planVersion: 'initial'
46
46
  };
47
47
  };
48
48
 
49
49
  /**
50
- * Format: O=${orderNumber},E=${expiryTimestamp},S=${scope},LM=${licensingModel},PV=${planVersion},KV=2`;
50
+ * Format: O=${orderNumber},E=${expiryTimestamp},S=${planScope},LM=${licenseModel},PV=${planVersion},KV=2`;
51
51
  */
52
52
  const decodeLicenseVersion2 = license => {
53
53
  const licenseInfo = {
54
- scope: null,
55
- licensingModel: null,
54
+ planScope: null,
55
+ licenseModel: null,
56
56
  expiryTimestamp: null,
57
57
  planVersion: 'initial'
58
58
  };
59
59
  license.split(',').map(token => token.split('=')).filter(el => el.length === 2).forEach(([key, value]) => {
60
60
  if (key === 'S') {
61
- licenseInfo.scope = value;
61
+ licenseInfo.planScope = value;
62
62
  }
63
63
  if (key === 'LM') {
64
- licenseInfo.licensingModel = value;
64
+ licenseInfo.licenseModel = value;
65
65
  }
66
66
  if (key === 'E') {
67
67
  const expiryTimestamp = parseInt(value, 10);
@@ -116,7 +116,7 @@ export function verifyLicense({
116
116
  status: LICENSE_STATUS.Invalid
117
117
  };
118
118
  }
119
- if (license.licensingModel == null || !LICENSING_MODELS.includes(license.licensingModel)) {
119
+ if (license.licenseModel == null || !LICENSE_MODELS.includes(license.licenseModel)) {
120
120
  console.error('MUI X: Error checking license. Licensing model not found or invalid!');
121
121
  return {
122
122
  status: LICENSE_STATUS.Invalid
@@ -128,7 +128,7 @@ export function verifyLicense({
128
128
  status: LICENSE_STATUS.Invalid
129
129
  };
130
130
  }
131
- if (license.licensingModel === 'perpetual' || process.env.NODE_ENV === 'production') {
131
+ if (license.licenseModel === 'perpetual' || process.env.NODE_ENV === 'production') {
132
132
  const pkgTimestamp = parseInt(base64Decode(releaseInfo), 10);
133
133
  if (Number.isNaN(pkgTimestamp)) {
134
134
  throw new Error('MUI X: The release information is invalid. Not able to validate license.');
@@ -138,7 +138,7 @@ export function verifyLicense({
138
138
  status: LICENSE_STATUS.ExpiredVersion
139
139
  };
140
140
  }
141
- } else if (license.licensingModel === 'subscription' || license.licensingModel === 'annual') {
141
+ } else if (license.licenseModel === 'subscription' || license.licenseModel === 'annual') {
142
142
  if (new Date().getTime() > license.expiryTimestamp) {
143
143
  if (
144
144
  // 30 days grace
@@ -160,20 +160,20 @@ export function verifyLicense({
160
160
  };
161
161
  }
162
162
  }
163
- if (license.scope == null || !LICENSE_SCOPES.includes(license.scope)) {
164
- console.error('MUI X: Error checking license. scope not found or invalid!');
163
+ if (license.planScope == null || !PLAN_SCOPES.includes(license.planScope)) {
164
+ console.error('MUI X: Error checking license. planScope not found or invalid!');
165
165
  return {
166
166
  status: LICENSE_STATUS.Invalid
167
167
  };
168
168
  }
169
- if (!isLicenseScopeSufficient(packageName, license.scope)) {
169
+ if (!isPlanScopeSufficient(packageName, license.planScope)) {
170
170
  return {
171
171
  status: LICENSE_STATUS.OutOfScope
172
172
  };
173
173
  }
174
174
 
175
175
  // 'charts-pro' or 'tree-view-pro' can only be used with a newer Pro license
176
- if (license.planVersion === 'initial' && license.scope === 'pro' && !PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN.includes(packageName)) {
176
+ if (license.planVersion === 'initial' && license.planScope === 'pro' && !PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN.includes(packageName)) {
177
177
  return {
178
178
  status: LICENSE_STATUS.NotAvailableInInitialProPlan
179
179
  };
@@ -6,22 +6,14 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.generateLicense = generateLicense;
7
7
  var _md = require("../encoding/md5");
8
8
  var _base = require("../encoding/base64");
9
- var _licenseScope = require("../utils/licenseScope");
10
- var _licensingModel = require("../utils/licensingModel");
9
+ var _plan = require("../utils/plan");
10
+ var _licenseModel = require("../utils/licenseModel");
11
11
  const licenseVersion = '2';
12
12
  function getClearLicenseString(details) {
13
- // TODO remove
14
- if (details.licensingModel) {
15
- details.licenseModel = details.licensingModel;
16
- }
17
- // TODO remove
18
- if (details.scope) {
19
- details.planScope = details.scope;
20
- }
21
- if (details.planScope && !_licenseScope.LICENSE_SCOPES.includes(details.planScope)) {
13
+ if (details.planScope && !_plan.PLAN_SCOPES.includes(details.planScope)) {
22
14
  throw new Error('MUI X: Invalid scope');
23
15
  }
24
- if (details.licenseModel && !_licensingModel.LICENSING_MODELS.includes(details.licenseModel)) {
16
+ if (details.licenseModel && !_licenseModel.LICENSE_MODELS.includes(details.licenseModel)) {
25
17
  throw new Error('MUI X: Invalid licensing model');
26
18
  }
27
19
  const keyParts = [`O=${details.orderNumber}`, `E=${details.expiryDate.getTime()}`, `S=${details.planScope}`, `LM=${details.licenseModel}`, `PV=${details.planVersion}`, `KV=${licenseVersion}`];
package/node/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-license v7.16.0
2
+ * @mui/x-license v7.18.0
3
3
  *
4
4
  * @license MUI X Commercial
5
5
  * This source code is licensed under the commercial license found in the
@@ -3,8 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.LICENSING_MODELS = void 0;
7
- const LICENSING_MODELS = exports.LICENSING_MODELS = [
6
+ exports.LICENSE_MODELS = void 0;
7
+ const LICENSE_MODELS = exports.LICENSE_MODELS = [
8
8
  /**
9
9
  * A license is outdated if the current version of the software was released after the expiry date of the license.
10
10
  * But the license can be used indefinitely with an older version of the software.
@@ -16,6 +16,8 @@ const LICENSING_MODELS = exports.LICENSING_MODELS = [
16
16
  */
17
17
  'annual',
18
18
  /**
19
- * TODO 2025 remove, legacy name of annual.
19
+ * Legacy. The previous name for 'annual'.
20
+ * Can be removed once old license keys generated with 'subscription' are no longer supported.
21
+ * To support for a while. We need more years of backward support and we sell multi year licenses.
20
22
  */
21
23
  'subscription'];
@@ -3,6 +3,6 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.PLAN_VERSIONS = exports.LICENSE_SCOPES = void 0;
7
- const LICENSE_SCOPES = exports.LICENSE_SCOPES = ['pro', 'premium'];
6
+ exports.PLAN_VERSIONS = exports.PLAN_SCOPES = void 0;
7
+ const PLAN_SCOPES = exports.PLAN_SCOPES = ['pro', 'premium'];
8
8
  const PLAN_VERSIONS = exports.PLAN_VERSIONS = ['initial', 'Q3-2024'];
@@ -8,8 +8,8 @@ exports.verifyLicense = verifyLicense;
8
8
  var _base = require("../encoding/base64");
9
9
  var _md = require("../encoding/md5");
10
10
  var _licenseStatus = require("../utils/licenseStatus");
11
- var _licenseScope = require("../utils/licenseScope");
12
- var _licensingModel = require("../utils/licensingModel");
11
+ var _plan = require("../utils/plan");
12
+ var _licenseModel = require("../utils/licenseModel");
13
13
  const getDefaultReleaseDate = () => {
14
14
  const today = new Date();
15
15
  today.setHours(0, 0, 0, 0);
@@ -18,7 +18,7 @@ const getDefaultReleaseDate = () => {
18
18
  function generateReleaseInfo(releaseDate = getDefaultReleaseDate()) {
19
19
  return (0, _base.base64Encode)(releaseDate.getTime().toString());
20
20
  }
21
- function isLicenseScopeSufficient(packageName, licenseScope) {
21
+ function isPlanScopeSufficient(packageName, planScope) {
22
22
  let acceptedScopes;
23
23
  if (packageName.includes('-pro')) {
24
24
  acceptedScopes = ['pro', 'premium'];
@@ -27,7 +27,7 @@ function isLicenseScopeSufficient(packageName, licenseScope) {
27
27
  } else {
28
28
  acceptedScopes = [];
29
29
  }
30
- return acceptedScopes.includes(licenseScope);
30
+ return acceptedScopes.includes(planScope);
31
31
  }
32
32
  const expiryReg = /^.*EXPIRY=([0-9]+),.*$/;
33
33
  const PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN = ['x-data-grid-pro', 'x-date-pickers-pro'];
@@ -46,29 +46,29 @@ const decodeLicenseVersion1 = license => {
46
46
  expiryTimestamp = null;
47
47
  }
48
48
  return {
49
- scope: 'pro',
50
- licensingModel: 'perpetual',
49
+ planScope: 'pro',
50
+ licenseModel: 'perpetual',
51
51
  expiryTimestamp,
52
52
  planVersion: 'initial'
53
53
  };
54
54
  };
55
55
 
56
56
  /**
57
- * Format: O=${orderNumber},E=${expiryTimestamp},S=${scope},LM=${licensingModel},PV=${planVersion},KV=2`;
57
+ * Format: O=${orderNumber},E=${expiryTimestamp},S=${planScope},LM=${licenseModel},PV=${planVersion},KV=2`;
58
58
  */
59
59
  const decodeLicenseVersion2 = license => {
60
60
  const licenseInfo = {
61
- scope: null,
62
- licensingModel: null,
61
+ planScope: null,
62
+ licenseModel: null,
63
63
  expiryTimestamp: null,
64
64
  planVersion: 'initial'
65
65
  };
66
66
  license.split(',').map(token => token.split('=')).filter(el => el.length === 2).forEach(([key, value]) => {
67
67
  if (key === 'S') {
68
- licenseInfo.scope = value;
68
+ licenseInfo.planScope = value;
69
69
  }
70
70
  if (key === 'LM') {
71
- licenseInfo.licensingModel = value;
71
+ licenseInfo.licenseModel = value;
72
72
  }
73
73
  if (key === 'E') {
74
74
  const expiryTimestamp = parseInt(value, 10);
@@ -123,7 +123,7 @@ function verifyLicense({
123
123
  status: _licenseStatus.LICENSE_STATUS.Invalid
124
124
  };
125
125
  }
126
- if (license.licensingModel == null || !_licensingModel.LICENSING_MODELS.includes(license.licensingModel)) {
126
+ if (license.licenseModel == null || !_licenseModel.LICENSE_MODELS.includes(license.licenseModel)) {
127
127
  console.error('MUI X: Error checking license. Licensing model not found or invalid!');
128
128
  return {
129
129
  status: _licenseStatus.LICENSE_STATUS.Invalid
@@ -135,7 +135,7 @@ function verifyLicense({
135
135
  status: _licenseStatus.LICENSE_STATUS.Invalid
136
136
  };
137
137
  }
138
- if (license.licensingModel === 'perpetual' || process.env.NODE_ENV === 'production') {
138
+ if (license.licenseModel === 'perpetual' || process.env.NODE_ENV === 'production') {
139
139
  const pkgTimestamp = parseInt((0, _base.base64Decode)(releaseInfo), 10);
140
140
  if (Number.isNaN(pkgTimestamp)) {
141
141
  throw new Error('MUI X: The release information is invalid. Not able to validate license.');
@@ -145,7 +145,7 @@ function verifyLicense({
145
145
  status: _licenseStatus.LICENSE_STATUS.ExpiredVersion
146
146
  };
147
147
  }
148
- } else if (license.licensingModel === 'subscription' || license.licensingModel === 'annual') {
148
+ } else if (license.licenseModel === 'subscription' || license.licenseModel === 'annual') {
149
149
  if (new Date().getTime() > license.expiryTimestamp) {
150
150
  if (
151
151
  // 30 days grace
@@ -167,20 +167,20 @@ function verifyLicense({
167
167
  };
168
168
  }
169
169
  }
170
- if (license.scope == null || !_licenseScope.LICENSE_SCOPES.includes(license.scope)) {
171
- console.error('MUI X: Error checking license. scope not found or invalid!');
170
+ if (license.planScope == null || !_plan.PLAN_SCOPES.includes(license.planScope)) {
171
+ console.error('MUI X: Error checking license. planScope not found or invalid!');
172
172
  return {
173
173
  status: _licenseStatus.LICENSE_STATUS.Invalid
174
174
  };
175
175
  }
176
- if (!isLicenseScopeSufficient(packageName, license.scope)) {
176
+ if (!isPlanScopeSufficient(packageName, license.planScope)) {
177
177
  return {
178
178
  status: _licenseStatus.LICENSE_STATUS.OutOfScope
179
179
  };
180
180
  }
181
181
 
182
182
  // 'charts-pro' or 'tree-view-pro' can only be used with a newer Pro license
183
- if (license.planVersion === 'initial' && license.scope === 'pro' && !PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN.includes(packageName)) {
183
+ if (license.planVersion === 'initial' && license.planScope === 'pro' && !PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN.includes(packageName)) {
184
184
  return {
185
185
  status: _licenseStatus.LICENSE_STATUS.NotAvailableInInitialProPlan
186
186
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-license",
3
- "version": "7.16.0",
3
+ "version": "7.18.0",
4
4
  "description": "MUI X License verification",
5
5
  "author": "MUI Team",
6
6
  "main": "./node/index.js",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "https://github.com/mui/mui-x.git",
23
+ "url": "git+https://github.com/mui/mui-x.git",
24
24
  "directory": "packages/x-license"
25
25
  },
26
26
  "dependencies": {
package/utils/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export * from './licenseErrorMessageUtils';
2
2
  export * from './licenseInfo';
3
3
  export * from './licenseStatus';
4
- export type { LicenseScope } from './licenseScope';
5
- export type { LicensingModel } from './licensingModel';
4
+ export type { PlanScope } from './plan';
5
+ export type { LicenseModel } from './licenseModel';
6
6
  export type { MuiCommercialPackageName } from './commercialPackages';
@@ -0,0 +1,2 @@
1
+ export declare const LICENSE_MODELS: readonly ["perpetual", "annual", "subscription"];
2
+ export type LicenseModel = (typeof LICENSE_MODELS)[number];
@@ -1,4 +1,4 @@
1
- export const LICENSING_MODELS = [
1
+ export const LICENSE_MODELS = [
2
2
  /**
3
3
  * A license is outdated if the current version of the software was released after the expiry date of the license.
4
4
  * But the license can be used indefinitely with an older version of the software.
@@ -10,6 +10,8 @@ export const LICENSING_MODELS = [
10
10
  */
11
11
  'annual',
12
12
  /**
13
- * TODO 2025 remove, legacy name of annual.
13
+ * Legacy. The previous name for 'annual'.
14
+ * Can be removed once old license keys generated with 'subscription' are no longer supported.
15
+ * To support for a while. We need more years of backward support and we sell multi year licenses.
14
16
  */
15
17
  'subscription'];
@@ -1,4 +1,4 @@
1
- export declare const LICENSE_SCOPES: readonly ["pro", "premium"];
1
+ export declare const PLAN_SCOPES: readonly ["pro", "premium"];
2
2
  export declare const PLAN_VERSIONS: readonly ["initial", "Q3-2024"];
3
- export type LicenseScope = (typeof LICENSE_SCOPES)[number];
3
+ export type PlanScope = (typeof PLAN_SCOPES)[number];
4
4
  export type PlanVersion = (typeof PLAN_VERSIONS)[number];
package/utils/plan.js ADDED
@@ -0,0 +1,2 @@
1
+ export const PLAN_SCOPES = ['pro', 'premium'];
2
+ export const PLAN_VERSIONS = ['initial', 'Q3-2024'];
@@ -1,8 +1,8 @@
1
1
  import { base64Decode, base64Encode } from "../encoding/base64.js";
2
2
  import { md5 } from "../encoding/md5.js";
3
3
  import { LICENSE_STATUS } from "../utils/licenseStatus.js";
4
- import { LICENSE_SCOPES } from "../utils/licenseScope.js";
5
- import { LICENSING_MODELS } from "../utils/licensingModel.js";
4
+ import { PLAN_SCOPES } from "../utils/plan.js";
5
+ import { LICENSE_MODELS } from "../utils/licenseModel.js";
6
6
  const getDefaultReleaseDate = () => {
7
7
  const today = new Date();
8
8
  today.setHours(0, 0, 0, 0);
@@ -11,7 +11,7 @@ const getDefaultReleaseDate = () => {
11
11
  export function generateReleaseInfo(releaseDate = getDefaultReleaseDate()) {
12
12
  return base64Encode(releaseDate.getTime().toString());
13
13
  }
14
- function isLicenseScopeSufficient(packageName, licenseScope) {
14
+ function isPlanScopeSufficient(packageName, planScope) {
15
15
  let acceptedScopes;
16
16
  if (packageName.includes('-pro')) {
17
17
  acceptedScopes = ['pro', 'premium'];
@@ -20,7 +20,7 @@ function isLicenseScopeSufficient(packageName, licenseScope) {
20
20
  } else {
21
21
  acceptedScopes = [];
22
22
  }
23
- return acceptedScopes.includes(licenseScope);
23
+ return acceptedScopes.includes(planScope);
24
24
  }
25
25
  const expiryReg = /^.*EXPIRY=([0-9]+),.*$/;
26
26
  const PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN = ['x-data-grid-pro', 'x-date-pickers-pro'];
@@ -39,29 +39,29 @@ const decodeLicenseVersion1 = license => {
39
39
  expiryTimestamp = null;
40
40
  }
41
41
  return {
42
- scope: 'pro',
43
- licensingModel: 'perpetual',
42
+ planScope: 'pro',
43
+ licenseModel: 'perpetual',
44
44
  expiryTimestamp,
45
45
  planVersion: 'initial'
46
46
  };
47
47
  };
48
48
 
49
49
  /**
50
- * Format: O=${orderNumber},E=${expiryTimestamp},S=${scope},LM=${licensingModel},PV=${planVersion},KV=2`;
50
+ * Format: O=${orderNumber},E=${expiryTimestamp},S=${planScope},LM=${licenseModel},PV=${planVersion},KV=2`;
51
51
  */
52
52
  const decodeLicenseVersion2 = license => {
53
53
  const licenseInfo = {
54
- scope: null,
55
- licensingModel: null,
54
+ planScope: null,
55
+ licenseModel: null,
56
56
  expiryTimestamp: null,
57
57
  planVersion: 'initial'
58
58
  };
59
59
  license.split(',').map(token => token.split('=')).filter(el => el.length === 2).forEach(([key, value]) => {
60
60
  if (key === 'S') {
61
- licenseInfo.scope = value;
61
+ licenseInfo.planScope = value;
62
62
  }
63
63
  if (key === 'LM') {
64
- licenseInfo.licensingModel = value;
64
+ licenseInfo.licenseModel = value;
65
65
  }
66
66
  if (key === 'E') {
67
67
  const expiryTimestamp = parseInt(value, 10);
@@ -116,7 +116,7 @@ export function verifyLicense({
116
116
  status: LICENSE_STATUS.Invalid
117
117
  };
118
118
  }
119
- if (license.licensingModel == null || !LICENSING_MODELS.includes(license.licensingModel)) {
119
+ if (license.licenseModel == null || !LICENSE_MODELS.includes(license.licenseModel)) {
120
120
  console.error('MUI X: Error checking license. Licensing model not found or invalid!');
121
121
  return {
122
122
  status: LICENSE_STATUS.Invalid
@@ -128,7 +128,7 @@ export function verifyLicense({
128
128
  status: LICENSE_STATUS.Invalid
129
129
  };
130
130
  }
131
- if (license.licensingModel === 'perpetual' || process.env.NODE_ENV === 'production') {
131
+ if (license.licenseModel === 'perpetual' || process.env.NODE_ENV === 'production') {
132
132
  const pkgTimestamp = parseInt(base64Decode(releaseInfo), 10);
133
133
  if (Number.isNaN(pkgTimestamp)) {
134
134
  throw new Error('MUI X: The release information is invalid. Not able to validate license.');
@@ -138,7 +138,7 @@ export function verifyLicense({
138
138
  status: LICENSE_STATUS.ExpiredVersion
139
139
  };
140
140
  }
141
- } else if (license.licensingModel === 'subscription' || license.licensingModel === 'annual') {
141
+ } else if (license.licenseModel === 'subscription' || license.licenseModel === 'annual') {
142
142
  if (new Date().getTime() > license.expiryTimestamp) {
143
143
  if (
144
144
  // 30 days grace
@@ -160,20 +160,20 @@ export function verifyLicense({
160
160
  };
161
161
  }
162
162
  }
163
- if (license.scope == null || !LICENSE_SCOPES.includes(license.scope)) {
164
- console.error('MUI X: Error checking license. scope not found or invalid!');
163
+ if (license.planScope == null || !PLAN_SCOPES.includes(license.planScope)) {
164
+ console.error('MUI X: Error checking license. planScope not found or invalid!');
165
165
  return {
166
166
  status: LICENSE_STATUS.Invalid
167
167
  };
168
168
  }
169
- if (!isLicenseScopeSufficient(packageName, license.scope)) {
169
+ if (!isPlanScopeSufficient(packageName, license.planScope)) {
170
170
  return {
171
171
  status: LICENSE_STATUS.OutOfScope
172
172
  };
173
173
  }
174
174
 
175
175
  // 'charts-pro' or 'tree-view-pro' can only be used with a newer Pro license
176
- if (license.planVersion === 'initial' && license.scope === 'pro' && !PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN.includes(packageName)) {
176
+ if (license.planVersion === 'initial' && license.planScope === 'pro' && !PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN.includes(packageName)) {
177
177
  return {
178
178
  status: LICENSE_STATUS.NotAvailableInInitialProPlan
179
179
  };
@@ -1,2 +0,0 @@
1
- export const LICENSE_SCOPES = ['pro', 'premium'];
2
- export const PLAN_VERSIONS = ['initial', 'Q3-2024'];
@@ -1,2 +0,0 @@
1
- export const LICENSE_SCOPES = ['pro', 'premium'];
2
- export const PLAN_VERSIONS = ['initial', 'Q3-2024'];
@@ -1,2 +0,0 @@
1
- export declare const LICENSING_MODELS: readonly ["perpetual", "annual", "subscription"];
2
- export type LicensingModel = (typeof LICENSING_MODELS)[number];