@jetbrains/ring-ui 7.0.94 → 7.0.96
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/components/auth/auth-core.d.ts +19 -2
- package/components/auth/auth-core.js +86 -48
- package/components/auth/request-builder.d.ts +12 -0
- package/components/auth/request-builder.js +27 -0
- package/components/list/list.d.ts +1 -1
- package/components/list/list.js +14 -1
- package/components/tabs/dumb-tabs.js +1 -1
- package/package.json +11 -11
|
@@ -8,6 +8,7 @@ import TokenValidator, { type TokenValidationError, type TokenValidatorConfig }
|
|
|
8
8
|
import type AuthDialogService from '../auth-dialog-service/auth-dialog-service';
|
|
9
9
|
export declare const DEFAULT_EXPIRES_TIMEOUT: number;
|
|
10
10
|
export declare const DEFAULT_BACKGROUND_TIMEOUT: number;
|
|
11
|
+
export declare const TOKEN_REFRESH_RETRY_DELAYS: number[];
|
|
11
12
|
export declare const USER_CHANGED_EVENT = "userChange";
|
|
12
13
|
export declare const DOMAIN_USER_CHANGED_EVENT = "domainUser";
|
|
13
14
|
export declare const LOGOUT_EVENT = "logout";
|
|
@@ -80,6 +81,8 @@ export interface AuthConfig extends TokenValidatorConfig {
|
|
|
80
81
|
translations?: AuthTranslations | null | undefined;
|
|
81
82
|
userParams?: RequestParams | undefined;
|
|
82
83
|
waitForRedirectTimeout: number;
|
|
84
|
+
tokenRefreshRetryDelays: readonly number[];
|
|
85
|
+
rpInitiatedLogout: boolean;
|
|
83
86
|
}
|
|
84
87
|
type AuthPayloadMap = {
|
|
85
88
|
userChange: [AuthUser | undefined | void, void];
|
|
@@ -120,6 +123,7 @@ declare class Auth implements HTTPAuth {
|
|
|
120
123
|
static DEFAULT_CONFIG: Omit<AuthConfig, "serverUri">;
|
|
121
124
|
static API_PATH: string;
|
|
122
125
|
static API_AUTH_PATH: string;
|
|
126
|
+
static API_LOGOUT_PATH: string;
|
|
123
127
|
static API_PROFILE_PATH: string;
|
|
124
128
|
static CLOSE_BACKEND_DOWN_MESSAGE: string;
|
|
125
129
|
static CLOSE_WINDOW_MESSAGE: string;
|
|
@@ -137,6 +141,7 @@ declare class Auth implements HTTPAuth {
|
|
|
137
141
|
_tokenValidator: TokenValidator | null;
|
|
138
142
|
private _postponed;
|
|
139
143
|
private _backendCheckPromise;
|
|
144
|
+
private _forceTokenUpdatePromise;
|
|
140
145
|
private _authDialogService;
|
|
141
146
|
_domainStorage: AuthStorage<UserChange>;
|
|
142
147
|
user: AuthUser | null;
|
|
@@ -166,9 +171,18 @@ declare class Auth implements HTTPAuth {
|
|
|
166
171
|
requestToken(): Promise<string | null>;
|
|
167
172
|
/**
|
|
168
173
|
* Get new token in the background or redirect to the login page.
|
|
169
|
-
*
|
|
174
|
+
*
|
|
175
|
+
* Retries background token refresh with delays from {@link AuthConfig.tokenRefreshRetryDelays}
|
|
176
|
+
* with increasing delays before showing the auth dialog.
|
|
177
|
+
* This handles transient failures that commonly occur after network
|
|
178
|
+
* recovery (e.g. waking from sleep, switching networks) where the first
|
|
179
|
+
* iframe-based auth attempt fails but a subsequent one succeeds once
|
|
180
|
+
* the Hub session is re-established.
|
|
181
|
+
*
|
|
182
|
+
* @return {Promise.<string | null>}
|
|
170
183
|
*/
|
|
171
184
|
forceTokenUpdate(): Promise<string | null>;
|
|
185
|
+
private _doForceTokenUpdate;
|
|
172
186
|
loadCurrentService(): Promise<void>;
|
|
173
187
|
getAPIPath(): string;
|
|
174
188
|
/**
|
|
@@ -187,7 +201,10 @@ declare class Auth implements HTTPAuth {
|
|
|
187
201
|
private _extractErrorMessage;
|
|
188
202
|
private _showBackendDownDialog;
|
|
189
203
|
/**
|
|
190
|
-
* Wipe accessToken and redirect to
|
|
204
|
+
* Wipe accessToken and redirect to logout endpoint.
|
|
205
|
+
* Uses RP-initiated logout flow (oauth2/logout) when rpInitiatedLogout config is enabled,
|
|
206
|
+
* falls back to oauth2/auth redirect otherwise.
|
|
207
|
+
* See: https://youtrack.jetbrains.com/projects/HUB/articles/HUB-A-43#rp-initiated-logout
|
|
191
208
|
*/
|
|
192
209
|
logout(extraParams?: Record<string, unknown>): Promise<void>;
|
|
193
210
|
private _runEmbeddedLogin;
|
|
@@ -15,6 +15,7 @@ export const DEFAULT_BACKGROUND_TIMEOUT = 10 * 1000;
|
|
|
15
15
|
const DEFAULT_BACKEND_CHECK_TIMEOUT = 10 * 1000;
|
|
16
16
|
const BACKGROUND_REDIRECT_TIMEOUT = 20 * 1000;
|
|
17
17
|
const DEFAULT_WAIT_FOR_REDIRECT_TIMEOUT = 5 * 1000;
|
|
18
|
+
export const TOKEN_REFRESH_RETRY_DELAYS = [0, 2000, 5000];
|
|
18
19
|
export const USER_CHANGED_EVENT = 'userChange';
|
|
19
20
|
export const DOMAIN_USER_CHANGED_EVENT = 'domainUser';
|
|
20
21
|
export const LOGOUT_EVENT = 'logout';
|
|
@@ -43,12 +44,15 @@ const DEFAULT_CONFIG = {
|
|
|
43
44
|
onBackendDown: () => () => { },
|
|
44
45
|
defaultExpiresIn: DEFAULT_EXPIRES_TIMEOUT,
|
|
45
46
|
waitForRedirectTimeout: DEFAULT_WAIT_FOR_REDIRECT_TIMEOUT,
|
|
47
|
+
tokenRefreshRetryDelays: TOKEN_REFRESH_RETRY_DELAYS,
|
|
48
|
+
rpInitiatedLogout: true,
|
|
46
49
|
translations: null,
|
|
47
50
|
};
|
|
48
51
|
class Auth {
|
|
49
52
|
static DEFAULT_CONFIG = DEFAULT_CONFIG;
|
|
50
53
|
static API_PATH = 'api/rest/';
|
|
51
54
|
static API_AUTH_PATH = 'oauth2/auth';
|
|
55
|
+
static API_LOGOUT_PATH = 'oauth2/logout';
|
|
52
56
|
static API_PROFILE_PATH = 'users/me';
|
|
53
57
|
static CLOSE_BACKEND_DOWN_MESSAGE = 'backend-check-succeeded';
|
|
54
58
|
static CLOSE_WINDOW_MESSAGE = 'close-login-window';
|
|
@@ -66,6 +70,7 @@ class Auth {
|
|
|
66
70
|
_tokenValidator = null;
|
|
67
71
|
_postponed = false;
|
|
68
72
|
_backendCheckPromise = null;
|
|
73
|
+
_forceTokenUpdatePromise = null;
|
|
69
74
|
_authDialogService = undefined;
|
|
70
75
|
_domainStorage;
|
|
71
76
|
user = null;
|
|
@@ -106,6 +111,7 @@ class Auth {
|
|
|
106
111
|
this._domainStorage = new AuthStorage({ messagePrefix: 'domain-message-' });
|
|
107
112
|
this._requestBuilder = new AuthRequestBuilder({
|
|
108
113
|
authorization: this.config.serverUri + Auth.API_PATH + Auth.API_AUTH_PATH,
|
|
114
|
+
logout: this.config.serverUri + Auth.API_PATH + Auth.API_LOGOUT_PATH,
|
|
109
115
|
clientId,
|
|
110
116
|
redirect,
|
|
111
117
|
redirectUri,
|
|
@@ -205,6 +211,8 @@ class Auth {
|
|
|
205
211
|
throw error;
|
|
206
212
|
}
|
|
207
213
|
if (this._canShowDialogs()) {
|
|
214
|
+
// eslint-disable-next-line no-console
|
|
215
|
+
console.error('RingUI Auth: Init failure', error);
|
|
208
216
|
this._showAuthDialog({ nonInteractive: true, error });
|
|
209
217
|
}
|
|
210
218
|
}
|
|
@@ -218,7 +226,7 @@ class Auth {
|
|
|
218
226
|
if (this.user && userID === this.user.id) {
|
|
219
227
|
return;
|
|
220
228
|
}
|
|
221
|
-
this.forceTokenUpdate();
|
|
229
|
+
this.forceTokenUpdate().catch(noop);
|
|
222
230
|
});
|
|
223
231
|
let state;
|
|
224
232
|
try {
|
|
@@ -240,7 +248,7 @@ class Auth {
|
|
|
240
248
|
if (message) {
|
|
241
249
|
const { userID, serviceID } = message;
|
|
242
250
|
if (serviceID !== this.config.clientId && (!userID || this.user?.id !== userID)) {
|
|
243
|
-
this.forceTokenUpdate();
|
|
251
|
+
this.forceTokenUpdate().catch(noop);
|
|
244
252
|
}
|
|
245
253
|
}
|
|
246
254
|
// Access token appears to be valid.
|
|
@@ -338,9 +346,26 @@ class Auth {
|
|
|
338
346
|
}
|
|
339
347
|
/**
|
|
340
348
|
* Get new token in the background or redirect to the login page.
|
|
341
|
-
*
|
|
349
|
+
*
|
|
350
|
+
* Retries background token refresh with delays from {@link AuthConfig.tokenRefreshRetryDelays}
|
|
351
|
+
* with increasing delays before showing the auth dialog.
|
|
352
|
+
* This handles transient failures that commonly occur after network
|
|
353
|
+
* recovery (e.g. waking from sleep, switching networks) where the first
|
|
354
|
+
* iframe-based auth attempt fails but a subsequent one succeeds once
|
|
355
|
+
* the Hub session is re-established.
|
|
356
|
+
*
|
|
357
|
+
* @return {Promise.<string | null>}
|
|
342
358
|
*/
|
|
343
|
-
|
|
359
|
+
forceTokenUpdate() {
|
|
360
|
+
if (this._forceTokenUpdatePromise) {
|
|
361
|
+
return this._forceTokenUpdatePromise;
|
|
362
|
+
}
|
|
363
|
+
this._forceTokenUpdatePromise = this._doForceTokenUpdate().finally(() => {
|
|
364
|
+
this._forceTokenUpdatePromise = null;
|
|
365
|
+
});
|
|
366
|
+
return this._forceTokenUpdatePromise;
|
|
367
|
+
}
|
|
368
|
+
async _doForceTokenUpdate() {
|
|
344
369
|
try {
|
|
345
370
|
if (!this._backendCheckPromise) {
|
|
346
371
|
this._backendCheckPromise = this._checkBackendsStatusesIfEnabled();
|
|
@@ -353,44 +378,48 @@ class Auth {
|
|
|
353
378
|
finally {
|
|
354
379
|
this._backendCheckPromise = null;
|
|
355
380
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if (!(error instanceof Error)) {
|
|
361
|
-
return null;
|
|
381
|
+
let lastError = null;
|
|
382
|
+
for (const delay of this.config.tokenRefreshRetryDelays) {
|
|
383
|
+
if (delay > 0) {
|
|
384
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
362
385
|
}
|
|
363
|
-
|
|
364
|
-
return
|
|
365
|
-
const onTryAgain = async () => {
|
|
366
|
-
try {
|
|
367
|
-
const result = await this._backgroundFlow?.authorize();
|
|
368
|
-
resolve(result ?? null);
|
|
369
|
-
}
|
|
370
|
-
catch (retryError) {
|
|
371
|
-
if (retryError instanceof Error) {
|
|
372
|
-
this._showAuthDialog({
|
|
373
|
-
nonInteractive: true,
|
|
374
|
-
error: retryError,
|
|
375
|
-
onTryAgain,
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
throw retryError;
|
|
379
|
-
}
|
|
380
|
-
};
|
|
381
|
-
this._showAuthDialog({
|
|
382
|
-
nonInteractive: true,
|
|
383
|
-
error: error,
|
|
384
|
-
onTryAgain,
|
|
385
|
-
});
|
|
386
|
-
});
|
|
386
|
+
try {
|
|
387
|
+
return (await this._backgroundFlow?.authorize()) ?? null;
|
|
387
388
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
this._redirectCurrentPage(authRequest.url);
|
|
389
|
+
catch (error) {
|
|
390
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
391
391
|
}
|
|
392
|
-
throw new TokenValidator.TokenValidationError(error.message);
|
|
393
392
|
}
|
|
393
|
+
if (this._canShowDialogs()) {
|
|
394
|
+
return new Promise(resolve => {
|
|
395
|
+
const onTryAgain = async () => {
|
|
396
|
+
try {
|
|
397
|
+
const result = await this._backgroundFlow?.authorize();
|
|
398
|
+
resolve(result ?? null);
|
|
399
|
+
}
|
|
400
|
+
catch (retryError) {
|
|
401
|
+
if (retryError instanceof Error) {
|
|
402
|
+
this._showAuthDialog({
|
|
403
|
+
nonInteractive: true,
|
|
404
|
+
error: retryError,
|
|
405
|
+
onTryAgain,
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
throw retryError;
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
this._showAuthDialog({
|
|
412
|
+
nonInteractive: true,
|
|
413
|
+
error: lastError,
|
|
414
|
+
onTryAgain,
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
const authRequest = await this._requestBuilder?.prepareAuthRequest();
|
|
419
|
+
if (authRequest) {
|
|
420
|
+
this._redirectCurrentPage(authRequest.url);
|
|
421
|
+
}
|
|
422
|
+
throw new TokenValidator.TokenValidationError(lastError?.message ?? 'Failed to refresh token');
|
|
394
423
|
}
|
|
395
424
|
async loadCurrentService() {
|
|
396
425
|
if (this._service.serviceName) {
|
|
@@ -468,7 +497,10 @@ class Auth {
|
|
|
468
497
|
}
|
|
469
498
|
_beforeLogout(params) {
|
|
470
499
|
if (this._canShowDialogs()) {
|
|
471
|
-
|
|
500
|
+
const onTryAgain = async () => {
|
|
501
|
+
await this.forceTokenUpdate();
|
|
502
|
+
};
|
|
503
|
+
this._showAuthDialog({ onTryAgain, ...params });
|
|
472
504
|
return;
|
|
473
505
|
}
|
|
474
506
|
this.logout();
|
|
@@ -504,7 +536,7 @@ class Auth {
|
|
|
504
536
|
return;
|
|
505
537
|
}
|
|
506
538
|
if (this.user?.guest && nonInteractive) {
|
|
507
|
-
this.forceTokenUpdate();
|
|
539
|
+
this.forceTokenUpdate().catch(noop);
|
|
508
540
|
}
|
|
509
541
|
else {
|
|
510
542
|
this._initDeferred?.resolve?.();
|
|
@@ -633,20 +665,24 @@ class Auth {
|
|
|
633
665
|
});
|
|
634
666
|
}
|
|
635
667
|
/**
|
|
636
|
-
* Wipe accessToken and redirect to
|
|
668
|
+
* Wipe accessToken and redirect to logout endpoint.
|
|
669
|
+
* Uses RP-initiated logout flow (oauth2/logout) when rpInitiatedLogout config is enabled,
|
|
670
|
+
* falls back to oauth2/auth redirect otherwise.
|
|
671
|
+
* See: https://youtrack.jetbrains.com/projects/HUB/articles/HUB-A-43#rp-initiated-logout
|
|
637
672
|
*/
|
|
638
673
|
async logout(extraParams) {
|
|
639
|
-
const requestParams = {
|
|
640
|
-
request_credentials: 'required',
|
|
641
|
-
...extraParams,
|
|
642
|
-
};
|
|
643
674
|
await this._checkBackendsStatusesIfEnabled();
|
|
644
675
|
await this.listeners.trigger('logout');
|
|
645
676
|
this._updateDomainUser(null);
|
|
646
677
|
await this._storage?.wipeToken();
|
|
647
|
-
const
|
|
648
|
-
|
|
649
|
-
this.
|
|
678
|
+
const request = this.config.rpInitiatedLogout
|
|
679
|
+
? await this._requestBuilder?.prepareLogoutRequest(extraParams)
|
|
680
|
+
: await this._requestBuilder?.prepareAuthRequest({
|
|
681
|
+
request_credentials: 'required',
|
|
682
|
+
...extraParams,
|
|
683
|
+
});
|
|
684
|
+
if (request) {
|
|
685
|
+
this._redirectCurrentPage(request.url);
|
|
650
686
|
}
|
|
651
687
|
}
|
|
652
688
|
async _runEmbeddedLogin() {
|
|
@@ -681,6 +717,8 @@ class Auth {
|
|
|
681
717
|
}
|
|
682
718
|
}
|
|
683
719
|
catch (e) {
|
|
720
|
+
// eslint-disable-next-line no-console
|
|
721
|
+
console.error('RingUI Auth: login failure', e);
|
|
684
722
|
this._beforeLogout();
|
|
685
723
|
}
|
|
686
724
|
}
|
|
@@ -3,6 +3,7 @@ import type { AuthState } from './storage';
|
|
|
3
3
|
import type AuthStorage from './storage';
|
|
4
4
|
export interface AuthRequestBuilderConfig {
|
|
5
5
|
authorization: string;
|
|
6
|
+
logout?: string | null | undefined;
|
|
6
7
|
redirectUri?: string | null | undefined;
|
|
7
8
|
requestCredentials?: string | null | undefined;
|
|
8
9
|
clientId?: string | null | undefined;
|
|
@@ -38,6 +39,17 @@ export default class AuthRequestBuilder {
|
|
|
38
39
|
url: string;
|
|
39
40
|
stateId: string;
|
|
40
41
|
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Build a logout URL for RP-initiated logout flow.
|
|
44
|
+
* See: https://youtrack.jetbrains.com/projects/HUB/articles/HUB-A-43#rp-initiated-logout
|
|
45
|
+
*
|
|
46
|
+
* @param {object=} extraParams additional query parameters for logout request
|
|
47
|
+
* @return {Promise.<{url: string, stateId: string}>} logout URL with required parameters
|
|
48
|
+
*/
|
|
49
|
+
prepareLogoutRequest(extraParams?: Record<string, unknown> | null | undefined): Promise<{
|
|
50
|
+
url: string;
|
|
51
|
+
stateId: string;
|
|
52
|
+
}>;
|
|
41
53
|
/**
|
|
42
54
|
* @param {string} id
|
|
43
55
|
* @param {StoredState} storedState
|
|
@@ -51,6 +51,33 @@ export default class AuthRequestBuilder {
|
|
|
51
51
|
stateId,
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Build a logout URL for RP-initiated logout flow.
|
|
56
|
+
* See: https://youtrack.jetbrains.com/projects/HUB/articles/HUB-A-43#rp-initiated-logout
|
|
57
|
+
*
|
|
58
|
+
* @param {object=} extraParams additional query parameters for logout request
|
|
59
|
+
* @return {Promise.<{url: string, stateId: string}>} logout URL with required parameters
|
|
60
|
+
*/
|
|
61
|
+
async prepareLogoutRequest(extraParams) {
|
|
62
|
+
if (!this.config.logout) {
|
|
63
|
+
throw new Error('Logout URL is not configured');
|
|
64
|
+
}
|
|
65
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
66
|
+
const stateId = AuthRequestBuilder._uuid();
|
|
67
|
+
const logoutParams = {
|
|
68
|
+
client_id: this.config.clientId,
|
|
69
|
+
state: stateId,
|
|
70
|
+
...extraParams,
|
|
71
|
+
};
|
|
72
|
+
await this._saveState(stateId, {
|
|
73
|
+
restoreLocation: window.location.href,
|
|
74
|
+
scopes: [...this.config.scopes],
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
url: encodeURL(this.config.logout, logoutParams),
|
|
78
|
+
stateId,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
54
81
|
/**
|
|
55
82
|
* @param {string} id
|
|
56
83
|
* @param {StoredState} storedState
|
|
@@ -109,7 +109,7 @@ export default class List<T = unknown> extends Component<ListProps<T>, ListState
|
|
|
109
109
|
};
|
|
110
110
|
componentDidMount(): void;
|
|
111
111
|
shouldComponentUpdate(nextProps: ListProps<T>, nextState: ListState<T>): boolean;
|
|
112
|
-
componentDidUpdate(prevProps: ListProps<T>): void;
|
|
112
|
+
componentDidUpdate(prevProps: ListProps<T>, prevState: ListState<T>): void;
|
|
113
113
|
componentWillUnmount(): void;
|
|
114
114
|
scheduleScrollListener: (cb: () => void) => void;
|
|
115
115
|
static isItemType: typeof isItemType;
|
package/components/list/list.js
CHANGED
|
@@ -126,11 +126,24 @@ export default class List extends Component {
|
|
|
126
126
|
return (Object.keys(nextProps).some(key => !Object.is(nextProps[key], this.props[key])) ||
|
|
127
127
|
Object.keys(nextState).some(key => nextState[key] !== this.state[key]));
|
|
128
128
|
}
|
|
129
|
-
componentDidUpdate(prevProps) {
|
|
129
|
+
componentDidUpdate(prevProps, prevState) {
|
|
130
130
|
if (this.virtualizedList && prevProps.data !== this.props.data) {
|
|
131
131
|
this.virtualizedList.recomputeRowHeights();
|
|
132
132
|
}
|
|
133
133
|
const { activeIndex } = this.state;
|
|
134
|
+
if (!this.virtualizedList &&
|
|
135
|
+
!this.props.disableScrollToActive &&
|
|
136
|
+
this.state.needScrollToActive &&
|
|
137
|
+
activeIndex != null &&
|
|
138
|
+
activeIndex !== prevState.activeIndex) {
|
|
139
|
+
const itemId = this.getId(this.props.data[activeIndex]);
|
|
140
|
+
if (itemId) {
|
|
141
|
+
document.getElementById(itemId)?.scrollIntoView?.({
|
|
142
|
+
block: 'center',
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
this.setState({ needScrollToActive: false });
|
|
146
|
+
}
|
|
134
147
|
const isActiveItemRetainedPosition = activeIndex
|
|
135
148
|
? prevProps.data[activeIndex]?.key === this.props.data[activeIndex]?.key
|
|
136
149
|
: false;
|
|
@@ -15,7 +15,7 @@ class Tabs extends PureComponent {
|
|
|
15
15
|
const { selected, children } = this.props;
|
|
16
16
|
const childrenArray = React.Children.toArray(children).filter(Boolean);
|
|
17
17
|
const selectedIndex = childrenArray.findIndex((tab, i) => getTabId(tab, i) === selected);
|
|
18
|
-
const actualSelectedIndex = selectedIndex === -1 ?
|
|
18
|
+
const actualSelectedIndex = selectedIndex === -1 ? childrenArray.findIndex(tab => tab.type !== CustomItem) : selectedIndex;
|
|
19
19
|
const selectedItem = childrenArray[actualSelectedIndex];
|
|
20
20
|
return { selectedItem, selectedKey: getTabId(selectedItem, actualSelectedIndex) };
|
|
21
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jetbrains/ring-ui",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.96",
|
|
4
4
|
"description": "JetBrains UI library",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "JetBrains"
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"@csstools/stylelint-no-at-nest-rule": "^5.0.0",
|
|
101
101
|
"@eslint/compat": "^2.0.2",
|
|
102
102
|
"@eslint/eslintrc": "^3.3.3",
|
|
103
|
-
"@eslint/js": "^
|
|
103
|
+
"@eslint/js": "^10.0.1",
|
|
104
104
|
"@figma/code-connect": "^1.3.13",
|
|
105
105
|
"@jetbrains/eslint-config": "^6.0.5",
|
|
106
106
|
"@jetbrains/logos": "3.0.0-canary.734b213.0",
|
|
@@ -128,17 +128,17 @@
|
|
|
128
128
|
"@types/react-dom": "^19.2.3",
|
|
129
129
|
"@types/webpack-env": "^1.18.8",
|
|
130
130
|
"@vitejs/plugin-react": "^5.1.4",
|
|
131
|
-
"@vitest/eslint-plugin": "^1.6.
|
|
131
|
+
"@vitest/eslint-plugin": "^1.6.9",
|
|
132
132
|
"acorn": "^8.15.0",
|
|
133
133
|
"babel-plugin-require-context-hook": "^1.0.0",
|
|
134
|
-
"caniuse-lite": "^1.0.
|
|
134
|
+
"caniuse-lite": "^1.0.30001770",
|
|
135
135
|
"chai-as-promised": "^8.0.2",
|
|
136
136
|
"chai-dom": "^1.12.1",
|
|
137
137
|
"cheerio": "^1.2.0",
|
|
138
138
|
"core-js": "^3.48.0",
|
|
139
139
|
"cpy-cli": "^7.0.0",
|
|
140
140
|
"dotenv-cli": "^11.0.0",
|
|
141
|
-
"eslint": "^
|
|
141
|
+
"eslint": "^10.0.1",
|
|
142
142
|
"eslint-config-prettier": "^10.1.8",
|
|
143
143
|
"eslint-import-resolver-exports": "^1.0.0-beta.5",
|
|
144
144
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
"eslint-plugin-react": "^7.37.5",
|
|
150
150
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
151
151
|
"eslint-plugin-storybook": "^10.2.8",
|
|
152
|
-
"eslint-plugin-unicorn": "^
|
|
152
|
+
"eslint-plugin-unicorn": "^63.0.0",
|
|
153
153
|
"events": "^3.3.0",
|
|
154
154
|
"glob": "^13.0.3",
|
|
155
155
|
"globals": "^17.3.0",
|
|
@@ -169,13 +169,13 @@
|
|
|
169
169
|
"react": "^19.2.4",
|
|
170
170
|
"react-dom": "^19.2.4",
|
|
171
171
|
"regenerator-runtime": "^0.14.1",
|
|
172
|
-
"rimraf": "^6.1.
|
|
172
|
+
"rimraf": "^6.1.3",
|
|
173
173
|
"rollup": "^4.57.1",
|
|
174
174
|
"rollup-plugin-clear": "^2.0.7",
|
|
175
175
|
"storage-mock": "^2.1.0",
|
|
176
|
-
"storybook": "10.2.
|
|
176
|
+
"storybook": "10.2.13",
|
|
177
177
|
"stylelint": "^17.3.0",
|
|
178
|
-
"stylelint-config-sass-guidelines": "^
|
|
178
|
+
"stylelint-config-sass-guidelines": "^13.0.0",
|
|
179
179
|
"svg-inline-loader": "^0.8.2",
|
|
180
180
|
"teamcity-service-messages": "^0.1.14",
|
|
181
181
|
"terser-webpack-plugin": "^5.3.16",
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
"change-case": "^4.1.1",
|
|
224
224
|
"classnames": "^2.5.1",
|
|
225
225
|
"combokeys": "^3.0.1",
|
|
226
|
-
"css-loader": "^7.1.
|
|
226
|
+
"css-loader": "^7.1.4",
|
|
227
227
|
"csstype": "^3.2.1",
|
|
228
228
|
"date-fns": "^4.1.0",
|
|
229
229
|
"dequal": "^2.0.3",
|
|
@@ -238,7 +238,7 @@
|
|
|
238
238
|
"postcss-calc": "^10.1.1",
|
|
239
239
|
"postcss-flexbugs-fixes": "^5.0.2",
|
|
240
240
|
"postcss-font-family-system-ui": "^5.0.0",
|
|
241
|
-
"postcss-loader": "^8.2.
|
|
241
|
+
"postcss-loader": "^8.2.1",
|
|
242
242
|
"postcss-modules-values-replace": "^4.2.2",
|
|
243
243
|
"postcss-preset-env": "^11.1.3",
|
|
244
244
|
"react-compiler-runtime": "^1.0.0",
|