attlaz-client 1.48.2 → 1.49.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/dist/Client.d.ts +5 -0
- package/dist/Client.js +10 -0
- package/dist/Http/ClientError.d.ts +1 -2
- package/dist/Http/ClientError.js +6 -29
- package/dist/Http/HttpClient.d.ts +0 -2
- package/dist/Http/HttpClient.js +34 -15
- package/dist/Http/Transport/OAuthClient.d.ts +8 -3
- package/dist/Http/Transport/OAuthClient.js +51 -26
- package/dist/Service/Endpoint.js +7 -1
- package/dist/Service/HealthAlertEndpoint.d.ts +3 -3
- package/dist/Service/HealthAlertEndpoint.js +4 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -13
package/dist/Client.d.ts
CHANGED
|
@@ -51,6 +51,11 @@ export declare class Client {
|
|
|
51
51
|
apiEndpoint: string | undefined;
|
|
52
52
|
}): Client;
|
|
53
53
|
setClientCredentials(clientId: string, clientSecret?: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Configure this client as a public OAuth client (no client_secret).
|
|
56
|
+
* Used for SPAs and other public clients that cannot keep a secret.
|
|
57
|
+
*/
|
|
58
|
+
setPublicClient(clientId: string): void;
|
|
54
59
|
setVersion(version: string | null): void;
|
|
55
60
|
getHttpClient(): OAuthClient;
|
|
56
61
|
authenticate(): Promise<boolean>;
|
package/dist/Client.js
CHANGED
|
@@ -104,6 +104,16 @@ export class Client {
|
|
|
104
104
|
this.httpClient = new OAuthClient(options);
|
|
105
105
|
this.transport = this.httpClient;
|
|
106
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Configure this client as a public OAuth client (no client_secret).
|
|
109
|
+
* Used for SPAs and other public clients that cannot keep a secret.
|
|
110
|
+
*/
|
|
111
|
+
setPublicClient(clientId) {
|
|
112
|
+
const options = new OAuthClientOptions(this.apiEndpoint, clientId, null);
|
|
113
|
+
options.scopes = ['all'];
|
|
114
|
+
this.httpClient = new OAuthClient(options);
|
|
115
|
+
this.transport = this.httpClient;
|
|
116
|
+
}
|
|
107
117
|
setVersion(version) {
|
|
108
118
|
this.httpClient.setVersion(version);
|
|
109
119
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { AxiosError } from 'axios';
|
|
2
1
|
export declare class ClientError extends Error {
|
|
3
2
|
httpStatus: number | null;
|
|
4
3
|
message: string;
|
|
5
4
|
response: unknown;
|
|
6
5
|
constructor(message: string, httpErrorCode?: number | null);
|
|
7
|
-
static fromError(error: Error
|
|
6
|
+
static fromError(error: Error): ClientError;
|
|
8
7
|
static byStatus(statusCode: number, statusText: string): ClientError | null;
|
|
9
8
|
}
|
package/dist/Http/ClientError.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AxiosError } from 'axios';
|
|
2
1
|
import { HttpStatus } from './HttpStatus.js';
|
|
3
2
|
export class ClientError extends Error {
|
|
4
3
|
httpStatus = null;
|
|
@@ -11,34 +10,6 @@ export class ClientError extends Error {
|
|
|
11
10
|
}
|
|
12
11
|
static fromError(error) {
|
|
13
12
|
let clientError = new ClientError('Unknown error', HttpStatus.HTTP_INTERNAL_SERVER_ERROR);
|
|
14
|
-
if (error instanceof AxiosError) {
|
|
15
|
-
if (error.code === 'ECONNREFUSED' || error.code === 'ERR_NETWORK') {
|
|
16
|
-
clientError.httpStatus = HttpStatus.HTTP_UNAVAILABLE;
|
|
17
|
-
clientError.message = 'Service not available';
|
|
18
|
-
return clientError;
|
|
19
|
-
}
|
|
20
|
-
if (error.status !== undefined && error.status !== null) {
|
|
21
|
-
clientError.httpStatus = error.status;
|
|
22
|
-
}
|
|
23
|
-
// console.log('Status', clientError.httpStatus);
|
|
24
|
-
// if(clientError.httpStatus === HttpStatusCode.Ref)
|
|
25
|
-
// clientError.message = error.message;
|
|
26
|
-
if (error.response === undefined) {
|
|
27
|
-
console.error('Unknown AxiosError error', {
|
|
28
|
-
error, status: error.status, code: error.code,
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
const response = {
|
|
33
|
-
status: error.response.status,
|
|
34
|
-
statusText: error.response.statusText,
|
|
35
|
-
data: error.response.data,
|
|
36
|
-
};
|
|
37
|
-
clientError.message = response.statusText;
|
|
38
|
-
clientError.response = response;
|
|
39
|
-
}
|
|
40
|
-
return clientError;
|
|
41
|
-
}
|
|
42
13
|
const xError = error;
|
|
43
14
|
if (xError.status !== null && xError.status !== undefined) {
|
|
44
15
|
const statusCode = xError.status;
|
|
@@ -72,6 +43,12 @@ export class ClientError extends Error {
|
|
|
72
43
|
clientError.httpStatus = HttpStatus.HTTP_INTERNAL_SERVER_ERROR;
|
|
73
44
|
}
|
|
74
45
|
}
|
|
46
|
+
else if (error instanceof TypeError) {
|
|
47
|
+
// fetch throws TypeError on network failures (ECONNREFUSED, DNS, etc.)
|
|
48
|
+
clientError.httpStatus = HttpStatus.HTTP_UNAVAILABLE;
|
|
49
|
+
clientError.message = 'Service not available';
|
|
50
|
+
return clientError;
|
|
51
|
+
}
|
|
75
52
|
clientError.name = error.name;
|
|
76
53
|
// TODO: only in debug mode
|
|
77
54
|
clientError.stack = error.stack;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { HttpClientRequest } from './HttpClientRequest.js';
|
|
2
2
|
import { HttpClientResponse } from './HttpClientResponse.js';
|
|
3
3
|
export declare class HttpClient {
|
|
4
|
-
private static readonly axiosInstance;
|
|
5
4
|
static request(request: HttpClientRequest): Promise<HttpClientResponse>;
|
|
6
|
-
private static axiosRequest;
|
|
7
5
|
}
|
package/dist/Http/HttpClient.js
CHANGED
|
@@ -1,32 +1,51 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
1
|
import { HttpClientResponse } from './HttpClientResponse.js';
|
|
3
2
|
import { ClientError } from './ClientError.js';
|
|
4
3
|
export class HttpClient {
|
|
5
|
-
static axiosInstance = axios.create();
|
|
6
4
|
static async request(request) {
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
static async axiosRequest(request) {
|
|
10
|
-
const requestConfig = {
|
|
11
|
-
url: request.getFullUrl(),
|
|
5
|
+
const init = {
|
|
12
6
|
method: request.method,
|
|
13
7
|
headers: request.headers,
|
|
14
8
|
};
|
|
15
9
|
if (request.body !== null && request.body !== undefined) {
|
|
16
|
-
|
|
10
|
+
init.body = request.body;
|
|
17
11
|
}
|
|
18
12
|
try {
|
|
19
|
-
const rawResponse = await
|
|
13
|
+
const rawResponse = await fetch(request.getFullUrl(), init);
|
|
14
|
+
if (!rawResponse.ok) {
|
|
15
|
+
const statusText = rawResponse.statusText || 'Unknown error';
|
|
16
|
+
const clientError = ClientError.byStatus(rawResponse.status, statusText)
|
|
17
|
+
?? new ClientError(statusText, rawResponse.status);
|
|
18
|
+
// Try to attach the response body for downstream error handling
|
|
19
|
+
try {
|
|
20
|
+
clientError.response = {
|
|
21
|
+
status: rawResponse.status,
|
|
22
|
+
statusText,
|
|
23
|
+
data: await rawResponse.json(),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Response body is not JSON — leave response as-is
|
|
28
|
+
}
|
|
29
|
+
throw clientError;
|
|
30
|
+
}
|
|
20
31
|
const httpResponse = new HttpClientResponse(rawResponse.status, rawResponse.statusText);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
httpResponse.headers[header] = headerValue === null ? '' : headerValue;
|
|
32
|
+
rawResponse.headers.forEach((value, header) => {
|
|
33
|
+
httpResponse.headers[header] = value;
|
|
24
34
|
});
|
|
25
|
-
|
|
35
|
+
const contentType = rawResponse.headers.get('content-type');
|
|
36
|
+
if (contentType !== null && contentType.includes('application/json')) {
|
|
37
|
+
httpResponse.body = await rawResponse.json();
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
httpResponse.body = await rawResponse.text();
|
|
41
|
+
}
|
|
26
42
|
return httpResponse;
|
|
27
43
|
}
|
|
28
|
-
catch (
|
|
29
|
-
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (error instanceof ClientError) {
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
throw ClientError.fromError(error);
|
|
30
49
|
}
|
|
31
50
|
}
|
|
32
51
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { Headers } from '../Data/Headers.js';
|
|
2
2
|
import { Parameters } from '../Data/Parameters.js';
|
|
3
|
-
import { ITransport } from './ITransport.js';
|
|
4
3
|
import { OAuthClientOptions } from '../OAuthClientOptions.js';
|
|
5
4
|
import { OAuthClientToken } from '../OAuthClientToken.js';
|
|
5
|
+
import { ITransport } from './ITransport.js';
|
|
6
6
|
export declare class OAuthClient implements ITransport {
|
|
7
7
|
private readonly options;
|
|
8
8
|
private debug;
|
|
9
|
-
private axiosInstance;
|
|
10
9
|
private oauthClientToken;
|
|
11
10
|
private refreshTokenPromise;
|
|
12
11
|
private version;
|
|
@@ -14,7 +13,13 @@ export declare class OAuthClient implements ITransport {
|
|
|
14
13
|
authenticate(username: string, password: string): Promise<boolean>;
|
|
15
14
|
authenticate(): Promise<boolean>;
|
|
16
15
|
refreshToken(): Promise<void>;
|
|
17
|
-
private
|
|
16
|
+
private isPublicClient;
|
|
17
|
+
/**
|
|
18
|
+
* Direct token request for public clients that must not send client_secret.
|
|
19
|
+
* The axios-oauth-client library always includes client_secret in the body,
|
|
20
|
+
* so public clients use this method instead.
|
|
21
|
+
*/
|
|
22
|
+
private requestToken;
|
|
18
23
|
isTokenExpires(): boolean;
|
|
19
24
|
request<T>(action: string, parameters?: Parameters, method?: string, signWithOauthToken?: boolean): Promise<T>;
|
|
20
25
|
isAuthenticated(): boolean;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import { clientCredentials, ownerCredentials, refreshToken } from 'axios-oauth-client';
|
|
3
1
|
import { JsonSerializable } from '../../Model/JsonSerializable.js';
|
|
4
2
|
import { VERSION } from '../../version.js';
|
|
5
3
|
import { ClientError } from '../ClientError.js';
|
|
@@ -9,7 +7,6 @@ import { OAuthClientToken } from '../OAuthClientToken.js';
|
|
|
9
7
|
export class OAuthClient {
|
|
10
8
|
options;
|
|
11
9
|
debug = false;
|
|
12
|
-
axiosInstance = null;
|
|
13
10
|
oauthClientToken = null;
|
|
14
11
|
refreshTokenPromise = null;
|
|
15
12
|
version = null;
|
|
@@ -22,15 +19,28 @@ export class OAuthClient {
|
|
|
22
19
|
try {
|
|
23
20
|
if (username !== null && username !== undefined && password !== null && password !== undefined) {
|
|
24
21
|
// Password flow / Owner Credentials grant
|
|
25
|
-
const
|
|
26
|
-
|
|
22
|
+
const params = {
|
|
23
|
+
grant_type: 'password',
|
|
24
|
+
client_id: this.options.clientId,
|
|
25
|
+
username,
|
|
26
|
+
password,
|
|
27
|
+
scope: this.options.scopes.join(' '),
|
|
28
|
+
};
|
|
29
|
+
if (!this.isPublicClient()) {
|
|
30
|
+
params.client_secret = this.options.clientSecret;
|
|
31
|
+
}
|
|
32
|
+
const rawAuthToken = await this.requestToken(params);
|
|
27
33
|
this.oauthClientToken = this.tokenToOauthClientToken(rawAuthToken);
|
|
28
34
|
return true;
|
|
29
35
|
}
|
|
30
36
|
if (this.options.clientId !== null && this.options.clientSecret !== null) {
|
|
31
|
-
// Client credentials flow
|
|
32
|
-
const
|
|
33
|
-
|
|
37
|
+
// Client credentials flow (only for confidential clients)
|
|
38
|
+
const rawAuthToken = await this.requestToken({
|
|
39
|
+
grant_type: 'client_credentials',
|
|
40
|
+
client_id: this.options.clientId,
|
|
41
|
+
client_secret: this.options.clientSecret,
|
|
42
|
+
scope: this.options.scopes.join(' '),
|
|
43
|
+
});
|
|
34
44
|
this.oauthClientToken = this.tokenToOauthClientToken(rawAuthToken);
|
|
35
45
|
}
|
|
36
46
|
return true;
|
|
@@ -53,24 +63,40 @@ export class OAuthClient {
|
|
|
53
63
|
throw new Error('unable to refresh token, refresh token not set');
|
|
54
64
|
}
|
|
55
65
|
try {
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
const params = {
|
|
67
|
+
grant_type: 'refresh_token',
|
|
68
|
+
client_id: this.options.clientId,
|
|
69
|
+
refresh_token: this.oauthClientToken.refresh_token,
|
|
70
|
+
scope: this.options.scopes.join(' '),
|
|
71
|
+
};
|
|
72
|
+
if (!this.isPublicClient()) {
|
|
73
|
+
params.client_secret = this.options.clientSecret;
|
|
74
|
+
}
|
|
75
|
+
const rawAuthToken = await this.requestToken(params);
|
|
76
|
+
this.oauthClientToken = this.tokenToOauthClientToken(rawAuthToken);
|
|
59
77
|
}
|
|
60
78
|
catch (e) {
|
|
61
79
|
throw ClientError.fromError(e);
|
|
62
80
|
}
|
|
63
81
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
82
|
+
isPublicClient() {
|
|
83
|
+
return this.options.clientSecret === null || this.options.clientSecret === '';
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Direct token request for public clients that must not send client_secret.
|
|
87
|
+
* The axios-oauth-client library always includes client_secret in the body,
|
|
88
|
+
* so public clients use this method instead.
|
|
89
|
+
*/
|
|
90
|
+
async requestToken(params) {
|
|
91
|
+
const response = await fetch(this.getApiEndpointUrl(this.options.accessTokenUri), {
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
94
|
+
body: new URLSearchParams(params).toString(),
|
|
95
|
+
});
|
|
96
|
+
if (!response.ok) {
|
|
97
|
+
throw new ClientError(response.statusText || 'Token request failed', response.status);
|
|
72
98
|
}
|
|
73
|
-
return
|
|
99
|
+
return response.json();
|
|
74
100
|
}
|
|
75
101
|
isTokenExpires() {
|
|
76
102
|
if (this.oauthClientToken === null) {
|
|
@@ -167,7 +193,7 @@ export class OAuthClient {
|
|
|
167
193
|
this.version = version;
|
|
168
194
|
}
|
|
169
195
|
isNodeEnvironment() {
|
|
170
|
-
return typeof process !== 'undefined' && process.versions
|
|
196
|
+
return typeof process !== 'undefined' && process.versions !== null && process.versions.node !== null;
|
|
171
197
|
}
|
|
172
198
|
tokenToOauthClientToken(oauthToken) {
|
|
173
199
|
let scopes = '';
|
|
@@ -185,7 +211,7 @@ export class OAuthClient {
|
|
|
185
211
|
return token;
|
|
186
212
|
}
|
|
187
213
|
getApiEndpointUrl(uri) {
|
|
188
|
-
if (uri.
|
|
214
|
+
if (uri.startsWith('http://') || uri.startsWith('https://')) {
|
|
189
215
|
return uri;
|
|
190
216
|
}
|
|
191
217
|
return this.options.apiEndpoint.replace(/\/+$/, '') + '/' + uri.replace(/^\/+/g, '');
|
|
@@ -210,10 +236,9 @@ export class OAuthClient {
|
|
|
210
236
|
requestData.setJsonHeader();
|
|
211
237
|
}
|
|
212
238
|
if (method === 'GET' && parameters !== null && parameters !== undefined) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
requestData.addQueryParam(key, value);
|
|
239
|
+
const params = parameters;
|
|
240
|
+
Object.keys(params).forEach((key) => {
|
|
241
|
+
requestData.addQueryParam(key, params[key]);
|
|
217
242
|
});
|
|
218
243
|
}
|
|
219
244
|
if (signWithOauthToken) {
|
package/dist/Service/Endpoint.js
CHANGED
|
@@ -114,6 +114,11 @@ export class Endpoint {
|
|
|
114
114
|
}
|
|
115
115
|
throw this.toApiError(error);
|
|
116
116
|
}
|
|
117
|
+
// TODO: add errors
|
|
118
|
+
/**
|
|
119
|
+
* Parse errors
|
|
120
|
+
*/
|
|
121
|
+
// TODO: temporary check until we know the API is fully upgraded
|
|
117
122
|
if (requestResponse === null || requestResponse === undefined) {
|
|
118
123
|
throw new ApiError('Unable to parse object: response is empty for action `[' + method + '] ' + action + '`', HttpStatus.HTTP_INTERNAL_SERVER_ERROR);
|
|
119
124
|
}
|
|
@@ -129,7 +134,7 @@ export class Endpoint {
|
|
|
129
134
|
const apiError = new ApiError(error.message, error.httpStatus);
|
|
130
135
|
if (error.response !== null && error.response !== undefined) {
|
|
131
136
|
const response = error.response;
|
|
132
|
-
if (response.data.error !== undefined) {
|
|
137
|
+
if (response.data !== null && response.data !== undefined && response.data.error !== undefined) {
|
|
133
138
|
if (response.data.error.type !== undefined) {
|
|
134
139
|
apiError.type = response.data.error.type;
|
|
135
140
|
}
|
|
@@ -165,6 +170,7 @@ export class Endpoint {
|
|
|
165
170
|
return data;
|
|
166
171
|
}
|
|
167
172
|
parseObject(rawObject, parser) {
|
|
173
|
+
// TODO: is it interesting to keep this wrapper, or only in develop mode?
|
|
168
174
|
const wrappedData = ObjectWrapper.wrap(rawObject);
|
|
169
175
|
try {
|
|
170
176
|
return parser(wrappedData);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EntityType } from '../Model/EntityType.js';
|
|
2
2
|
import { HealthAlert } from '../Model/HealthAlert/HealthAlert.js';
|
|
3
3
|
import { CollectionResult } from '../Model/Result/CollectionResult.js';
|
|
4
|
-
import {
|
|
4
|
+
import { Endpoint } from './Endpoint.js';
|
|
5
5
|
export declare class HealthAlertEndpoint extends Endpoint {
|
|
6
|
-
|
|
6
|
+
getCurrentAlertsByScope(scopeType: EntityType, scopeId: string, parentScopeId: string | null): Promise<CollectionResult<HealthAlert>>;
|
|
7
7
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Endpoint } from './Endpoint.js';
|
|
2
|
-
import { HealthAlert } from '../Model/HealthAlert/HealthAlert.js';
|
|
3
1
|
import { QueryString } from '../Http/Data/QueryString.js';
|
|
2
|
+
import { HealthAlert } from '../Model/HealthAlert/HealthAlert.js';
|
|
3
|
+
import { Endpoint } from './Endpoint.js';
|
|
4
4
|
export class HealthAlertEndpoint extends Endpoint {
|
|
5
|
-
async
|
|
5
|
+
async getCurrentAlertsByScope(scopeType, scopeId, parentScopeId) {
|
|
6
6
|
try {
|
|
7
|
-
const q = new QueryString('/health/' + scopeType + '/' + scopeId
|
|
7
|
+
const q = new QueryString('/health/' + scopeType + '/' + scopeId);
|
|
8
8
|
if (parentScopeId !== null) {
|
|
9
9
|
q.set('parentScopeId', parentScopeId);
|
|
10
10
|
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "1.
|
|
1
|
+
export declare const VERSION = "1.49.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "1.
|
|
1
|
+
export const VERSION = "1.49.0";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "attlaz-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.49.0",
|
|
4
4
|
"description": "Javascript Client to access Attlaz API",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -48,28 +48,20 @@
|
|
|
48
48
|
"cache": "~/.npm",
|
|
49
49
|
"registry": "https://registry.npmjs.org"
|
|
50
50
|
},
|
|
51
|
-
"dependencies": {
|
|
52
|
-
"axios": "^1.13.6",
|
|
53
|
-
"axios-oauth-client": "^2.2.0"
|
|
54
|
-
},
|
|
55
51
|
"devDependencies": {
|
|
56
52
|
"@types/jest": "^30.0.0",
|
|
57
|
-
"@types/node": "^24.
|
|
53
|
+
"@types/node": "^24.12.0",
|
|
58
54
|
"@typescript-eslint/eslint-plugin": "^8.1.0",
|
|
59
55
|
"@typescript-eslint/parser": "^8.1.0",
|
|
60
|
-
"
|
|
61
|
-
"eslint": "^
|
|
62
|
-
"eslint-config-attlaz-base": "^1.5.2",
|
|
56
|
+
"eslint": "^9.39.4",
|
|
57
|
+
"eslint-config-attlaz-base": "^1.6.0",
|
|
63
58
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
64
59
|
"eslint-plugin-import": "^2.32.0",
|
|
65
60
|
"eslint-plugin-jsdoc": "^51.4.1",
|
|
66
61
|
"eslint-plugin-prefer-arrow": "^1.2.3",
|
|
67
62
|
"eslint-plugin-promise": "^7.2.1",
|
|
68
|
-
"jest": "^30.
|
|
63
|
+
"jest": "^30.3.0",
|
|
69
64
|
"rimraf": "^6.1.3",
|
|
70
|
-
"rollup-plugin-commonjs": "^10.1.0",
|
|
71
|
-
"rollup-plugin-node-resolve": "^5.2.0",
|
|
72
|
-
"rollup-plugin-typescript": "^1.0.1",
|
|
73
65
|
"ts-jest": "^29.4.6",
|
|
74
66
|
"typescript": "^5.9.3"
|
|
75
67
|
},
|