xjs-node 1.0.3 → 1.0.5
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/README.md
CHANGED
|
@@ -58,7 +58,7 @@ import { HttpResolver, s_clientMode } from "xjs-node";
|
|
|
58
58
|
const context = http.newContext();
|
|
59
59
|
res = await context.get("https://begyyal.net/1");
|
|
60
60
|
// this request sends with cookies that is set by precedent requests.
|
|
61
|
-
// in POST, payload is treated as json if it is an object.
|
|
61
|
+
// in POST, payload is treated as json if it is an object. (but also Stream is acceptable.)
|
|
62
62
|
res = await context.post("https://begyyal.net/2", { a: "b" });
|
|
63
63
|
})();
|
|
64
64
|
```
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
|
|
3
|
-
import { OutgoingHttpHeaders, IncomingHttpHeaders } from "http";
|
|
4
|
-
import { ClientOption, IHttpClient } from "./i-http-client";
|
|
2
|
+
import { ClientOption, HttpResponse, IHttpClient, RequestOption } from "./i-http-client";
|
|
5
3
|
import { Loggable } from "xjs-common";
|
|
6
4
|
export declare const s_clientMode: {
|
|
7
5
|
nodejs: {
|
|
@@ -28,70 +26,24 @@ export declare class HttpResolverContext implements IHttpClient {
|
|
|
28
26
|
private _cookies?;
|
|
29
27
|
get clientMode(): string;
|
|
30
28
|
constructor(cmv: number, op?: ClientOption, _l?: Loggable);
|
|
31
|
-
get(url: string, op?: {
|
|
32
|
-
headers?: OutgoingHttpHeaders;
|
|
33
|
-
ignoreQuery?: boolean;
|
|
34
|
-
downloadPath?: string;
|
|
35
|
-
timeout?: number;
|
|
36
|
-
} & {
|
|
29
|
+
get(url: string, op?: RequestOption & {
|
|
37
30
|
outerRedirectCount?: number;
|
|
38
|
-
}): Promise<{
|
|
39
|
-
headers?: IncomingHttpHeaders;
|
|
40
|
-
payload: string;
|
|
41
|
-
}>;
|
|
42
|
-
get(url: string, op?: {
|
|
43
|
-
headers?: OutgoingHttpHeaders;
|
|
44
|
-
ignoreQuery?: boolean;
|
|
45
|
-
downloadPath?: string;
|
|
46
|
-
timeout?: number;
|
|
47
31
|
responseType: "string";
|
|
48
|
-
}
|
|
32
|
+
}): Promise<HttpResponse<string>>;
|
|
33
|
+
get(url: string, op?: RequestOption & {
|
|
49
34
|
outerRedirectCount?: number;
|
|
50
|
-
}): Promise<{
|
|
51
|
-
headers?: IncomingHttpHeaders;
|
|
52
|
-
payload: string;
|
|
53
|
-
}>;
|
|
54
|
-
get(url: string, op?: {
|
|
55
|
-
headers?: OutgoingHttpHeaders;
|
|
56
|
-
ignoreQuery?: boolean;
|
|
57
|
-
downloadPath?: string;
|
|
58
|
-
timeout?: number;
|
|
59
35
|
responseType: "buffer";
|
|
60
|
-
}
|
|
36
|
+
}): Promise<HttpResponse<Buffer>>;
|
|
37
|
+
get(url: string, op?: RequestOption & {
|
|
61
38
|
outerRedirectCount?: number;
|
|
62
|
-
}): Promise<
|
|
63
|
-
|
|
64
|
-
payload: Buffer;
|
|
65
|
-
}>;
|
|
66
|
-
post(url: string, payload: any, op?: {
|
|
67
|
-
headers?: OutgoingHttpHeaders;
|
|
68
|
-
ignoreQuery?: boolean;
|
|
69
|
-
downloadPath?: string;
|
|
70
|
-
timeout?: number;
|
|
71
|
-
}): Promise<{
|
|
72
|
-
headers?: IncomingHttpHeaders;
|
|
73
|
-
payload: string;
|
|
74
|
-
}>;
|
|
75
|
-
post(url: string, payload: any, op?: {
|
|
76
|
-
headers?: OutgoingHttpHeaders;
|
|
77
|
-
ignoreQuery?: boolean;
|
|
78
|
-
downloadPath?: string;
|
|
79
|
-
timeout?: number;
|
|
39
|
+
}): Promise<HttpResponse<string>>;
|
|
40
|
+
post(url: string, payload: any, op?: RequestOption & {
|
|
80
41
|
responseType: "string";
|
|
81
|
-
}): Promise<
|
|
82
|
-
|
|
83
|
-
payload: string;
|
|
84
|
-
}>;
|
|
85
|
-
post(url: string, payload: any, op?: {
|
|
86
|
-
headers?: OutgoingHttpHeaders;
|
|
87
|
-
ignoreQuery?: boolean;
|
|
88
|
-
downloadPath?: string;
|
|
89
|
-
timeout?: number;
|
|
42
|
+
}): Promise<HttpResponse<string>>;
|
|
43
|
+
post(url: string, payload: any, op?: RequestOption & {
|
|
90
44
|
responseType: "buffer";
|
|
91
|
-
}): Promise<
|
|
92
|
-
|
|
93
|
-
payload: Buffer;
|
|
94
|
-
}>;
|
|
45
|
+
}): Promise<HttpResponse<Buffer>>;
|
|
46
|
+
post(url: string, payload: any, op?: RequestOption): Promise<HttpResponse<string>>;
|
|
95
47
|
private createProxyAgent;
|
|
96
48
|
private getIn;
|
|
97
49
|
private postIn;
|
|
@@ -35,6 +35,7 @@ const async_hooks_1 = require("async_hooks");
|
|
|
35
35
|
const u_file_1 = require("../../func/u-file");
|
|
36
36
|
const u_1 = require("../../func/u");
|
|
37
37
|
const xjs_common_1 = require("xjs-common");
|
|
38
|
+
const stream_1 = require("stream");
|
|
38
39
|
exports.s_clientMode = {
|
|
39
40
|
nodejs: { id: 0, cipherOrder: null },
|
|
40
41
|
chrome: { id: 1, cipherOrder: [2, 0, 1] },
|
|
@@ -44,36 +45,36 @@ const s_errCode = 1200;
|
|
|
44
45
|
const s_redirectLimit = 5;
|
|
45
46
|
const s_mode2headers = new Map([
|
|
46
47
|
[exports.s_clientMode.firefox, (cmv) => ({
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
48
|
+
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
|
49
|
+
"accept-encoding": "gzip, deflate, br",
|
|
50
|
+
"accept-language": "en-US,en;q=0.5",
|
|
51
|
+
"sec-fetch-dest": "document",
|
|
52
|
+
"sec-fetch-mode": "navigate",
|
|
53
|
+
"sec-fetch-site": "none",
|
|
54
|
+
"sec-fetch-user": "?1",
|
|
55
|
+
"upgrade-insecure-requests": "1",
|
|
56
|
+
"user-agent": `Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:${cmv}.0) Gecko/20100101 Firefox/${cmv}.0`
|
|
56
57
|
})],
|
|
57
58
|
[exports.s_clientMode.chrome, (cmv) => {
|
|
58
59
|
const uad = cmv < 130
|
|
59
60
|
? `"Not/A)Brand";v="8", "Chromium";v="${cmv}", "Google Chrome";v="${cmv}"`
|
|
60
61
|
: `"Chromium";v="${cmv}", "Not:A-Brand";v="24", "Google Chrome";v="${cmv}"`;
|
|
61
62
|
const ch = {
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
63
|
+
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
|
64
|
+
"accept-encoding": "gzip, deflate, br, zstd",
|
|
65
|
+
"accept-language": "en-US,en;q=0.9",
|
|
66
|
+
"sec-ch-ua": uad,
|
|
67
|
+
"sec-ch-ua-mobile": "?0",
|
|
68
|
+
"sec-ch-ua-platform": '"Windows"',
|
|
69
|
+
"sec-fetch-dest": "document",
|
|
70
|
+
"sec-fetch-mode": "navigate",
|
|
71
|
+
"sec-fetch-site": "none",
|
|
72
|
+
"sec-fetch-user": "?1",
|
|
73
|
+
"upgrade-insecure-requests": "1",
|
|
74
|
+
"user-agent": `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${cmv}.0.0.0 Safari/537.36`
|
|
74
75
|
};
|
|
75
76
|
if (cmv >= 124)
|
|
76
|
-
ch["
|
|
77
|
+
ch["priority"] = "u=0, i";
|
|
77
78
|
return ch;
|
|
78
79
|
}]
|
|
79
80
|
]);
|
|
@@ -97,16 +98,6 @@ class HttpResolverContext {
|
|
|
97
98
|
this._chHeaders = s_mode2headers.get(this._mode)(this.cmv);
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
|
-
/**
|
|
101
|
-
* request GET to the url.
|
|
102
|
-
* @param url target url.
|
|
103
|
-
* @param op.headers http headers.
|
|
104
|
-
* @param op.ignoreQuery {@link RequestOption.ignoreQuery}
|
|
105
|
-
* @param op.downloadPath {@link RequestOption.downloadPath}
|
|
106
|
-
* @param op.timeout {@link RequestOption.timeout}
|
|
107
|
-
* @param op.responseType {@link RequestOption.responseType}
|
|
108
|
-
* @returns string encoded by utf-8 as response payload.
|
|
109
|
-
*/
|
|
110
101
|
async get(url, op) {
|
|
111
102
|
const u = new url_1.URL(url);
|
|
112
103
|
const proxyAgent = this._proxyConfig && await this.createProxyAgent(u);
|
|
@@ -114,17 +105,6 @@ class HttpResolverContext {
|
|
|
114
105
|
Object.assign(rc, op);
|
|
115
106
|
return await this._als.run(rc, this.getIn, u).finally(() => proxyAgent?.destroy());
|
|
116
107
|
}
|
|
117
|
-
/**
|
|
118
|
-
* request POST to the url.
|
|
119
|
-
* @param url target url.
|
|
120
|
-
* @param payload request payload. if this is an object, it is treated as json.
|
|
121
|
-
* @param op.headers http headers.
|
|
122
|
-
* @param op.ignoreQuery {@link RequestOption.ignoreQuery}
|
|
123
|
-
* @param op.downloadPath {@link RequestOption.downloadPath}
|
|
124
|
-
* @param op.timeout {@link RequestOption.timeout}
|
|
125
|
-
* @param op.responseType {@link RequestOption.responseType}
|
|
126
|
-
* @returns string encoded by utf-8 as response payload.
|
|
127
|
-
*/
|
|
128
108
|
async post(url, payload, op) {
|
|
129
109
|
const u = new url_1.URL(url);
|
|
130
110
|
const proxyAgent = this._proxyConfig && await this.createProxyAgent(u);
|
|
@@ -137,7 +117,7 @@ class HttpResolverContext {
|
|
|
137
117
|
return new Promise((resolve, reject) => {
|
|
138
118
|
const headers = {};
|
|
139
119
|
if (conf.auth)
|
|
140
|
-
headers['
|
|
120
|
+
headers['proxy-authorization'] = `Basic ${Buffer.from(conf.auth.name + ':' + conf.auth.pass).toString('base64')}`;
|
|
141
121
|
const req = (0, http_1.request)({
|
|
142
122
|
host: conf.server,
|
|
143
123
|
port: conf.port,
|
|
@@ -162,19 +142,22 @@ class HttpResolverContext {
|
|
|
162
142
|
const params = {};
|
|
163
143
|
const rc = this._als.getStore();
|
|
164
144
|
params.method = xjs_common_1.HttpMethod.Get;
|
|
165
|
-
params.headers = rc.headers
|
|
145
|
+
params.headers = xjs_common_1.UHttp.normalizeHeaders(rc.headers);
|
|
166
146
|
return await this.reqHttps(u, params);
|
|
167
147
|
};
|
|
168
148
|
postIn = async (u, payload) => {
|
|
169
149
|
const params = {};
|
|
170
150
|
const rc = this._als.getStore();
|
|
171
151
|
params.method = xjs_common_1.HttpMethod.Post;
|
|
172
|
-
params.headers = rc.headers
|
|
152
|
+
params.headers = xjs_common_1.UHttp.normalizeHeaders(rc.headers);
|
|
173
153
|
let p = payload;
|
|
174
|
-
if (
|
|
154
|
+
if (p instanceof stream_1.Stream) {
|
|
155
|
+
params.headers["content-type"] ??= "application/octet-stream";
|
|
156
|
+
}
|
|
157
|
+
else if (xjs_common_1.UType.isObject(payload)) {
|
|
175
158
|
p = JSON.stringify(payload);
|
|
176
|
-
params.headers["
|
|
177
|
-
params.headers["
|
|
159
|
+
params.headers["content-length"] = p.length;
|
|
160
|
+
params.headers["content-type"] = "application/json";
|
|
178
161
|
}
|
|
179
162
|
return await this.reqHttps(u, params, p);
|
|
180
163
|
};
|
|
@@ -199,7 +182,10 @@ class HttpResolverContext {
|
|
|
199
182
|
reject(new xjs_common_1.XjsErr(s_errCode, "The http request timeout, maybe server did not respond."));
|
|
200
183
|
});
|
|
201
184
|
if (payload)
|
|
202
|
-
|
|
185
|
+
if (payload instanceof stream_1.Stream)
|
|
186
|
+
payload.pipe(req);
|
|
187
|
+
else
|
|
188
|
+
req.write(payload);
|
|
203
189
|
req.end();
|
|
204
190
|
});
|
|
205
191
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
2
|
import { Loggable } from "xjs-common";
|
|
4
3
|
import { HttpResolverContext } from "./http-resolver-context";
|
|
5
|
-
import { ClientOption, IHttpClient } from "./i-http-client";
|
|
6
|
-
import { IncomingHttpHeaders, OutgoingHttpHeaders } from "http";
|
|
4
|
+
import { ClientOption, HttpResponse, IHttpClient, RequestOption } from "./i-http-client";
|
|
7
5
|
export interface ClientMode {
|
|
8
6
|
id: number;
|
|
9
7
|
cipherOrder: number[];
|
|
@@ -31,69 +29,23 @@ export declare class HttpResolver implements IHttpClient {
|
|
|
31
29
|
* @returns a http client as new context.
|
|
32
30
|
*/
|
|
33
31
|
newContext(op?: ClientOption): HttpResolverContext;
|
|
34
|
-
get(url: string, op?: {
|
|
35
|
-
headers?: OutgoingHttpHeaders;
|
|
36
|
-
ignoreQuery?: boolean;
|
|
37
|
-
downloadPath?: string;
|
|
38
|
-
timeout?: number;
|
|
39
|
-
} & ClientOption & {
|
|
32
|
+
get(url: string, op?: RequestOption & ClientOption & {
|
|
40
33
|
redirectAsNewRequest?: boolean;
|
|
41
|
-
}): Promise<{
|
|
42
|
-
headers?: IncomingHttpHeaders;
|
|
43
|
-
payload: string;
|
|
44
|
-
}>;
|
|
45
|
-
get(url: string, op?: {
|
|
46
|
-
headers?: OutgoingHttpHeaders;
|
|
47
|
-
ignoreQuery?: boolean;
|
|
48
|
-
downloadPath?: string;
|
|
49
|
-
timeout?: number;
|
|
50
34
|
responseType: "string";
|
|
51
|
-
}
|
|
35
|
+
}): Promise<HttpResponse<string>>;
|
|
36
|
+
get(url: string, op?: RequestOption & ClientOption & {
|
|
52
37
|
redirectAsNewRequest?: boolean;
|
|
53
|
-
}): Promise<{
|
|
54
|
-
headers?: IncomingHttpHeaders;
|
|
55
|
-
payload: string;
|
|
56
|
-
}>;
|
|
57
|
-
get(url: string, op?: {
|
|
58
|
-
headers?: OutgoingHttpHeaders;
|
|
59
|
-
ignoreQuery?: boolean;
|
|
60
|
-
downloadPath?: string;
|
|
61
|
-
timeout?: number;
|
|
62
38
|
responseType: "buffer";
|
|
63
|
-
}
|
|
39
|
+
}): Promise<HttpResponse<Buffer>>;
|
|
40
|
+
get(url: string, op?: RequestOption & ClientOption & {
|
|
64
41
|
redirectAsNewRequest?: boolean;
|
|
65
|
-
}): Promise<
|
|
66
|
-
|
|
67
|
-
payload: Buffer;
|
|
68
|
-
}>;
|
|
69
|
-
post(url: string, payload: any, op?: {
|
|
70
|
-
headers?: OutgoingHttpHeaders;
|
|
71
|
-
ignoreQuery?: boolean;
|
|
72
|
-
downloadPath?: string;
|
|
73
|
-
timeout?: number;
|
|
74
|
-
} & ClientOption): Promise<{
|
|
75
|
-
headers?: IncomingHttpHeaders;
|
|
76
|
-
payload: string;
|
|
77
|
-
}>;
|
|
78
|
-
post(url: string, payload: any, op?: {
|
|
79
|
-
headers?: OutgoingHttpHeaders;
|
|
80
|
-
ignoreQuery?: boolean;
|
|
81
|
-
downloadPath?: string;
|
|
82
|
-
timeout?: number;
|
|
42
|
+
}): Promise<HttpResponse<string>>;
|
|
43
|
+
post(url: string, payload: any, op?: RequestOption & ClientOption & {
|
|
83
44
|
responseType: "string";
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
payload: string;
|
|
87
|
-
}>;
|
|
88
|
-
post(url: string, payload: any, op?: {
|
|
89
|
-
headers?: OutgoingHttpHeaders;
|
|
90
|
-
ignoreQuery?: boolean;
|
|
91
|
-
downloadPath?: string;
|
|
92
|
-
timeout?: number;
|
|
45
|
+
}): Promise<HttpResponse<string>>;
|
|
46
|
+
post(url: string, payload: any, op?: RequestOption & ClientOption & {
|
|
93
47
|
responseType: "buffer";
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
payload: Buffer;
|
|
97
|
-
}>;
|
|
48
|
+
}): Promise<HttpResponse<Buffer>>;
|
|
49
|
+
post(url: string, payload: any, op?: RequestOption & ClientOption): Promise<HttpResponse<string>>;
|
|
98
50
|
private fixCmv;
|
|
99
51
|
}
|
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
import { IncomingHttpHeaders, OutgoingHttpHeaders } from "http";
|
|
4
4
|
import { ClientMode, ProxyConfig } from "./http-resolver";
|
|
5
5
|
export interface ClientOption {
|
|
6
|
+
/**
|
|
7
|
+
* {@link s_clientMode} that is imitated. default is random between chrome or firefox.
|
|
8
|
+
*/
|
|
6
9
|
mode?: ClientMode;
|
|
10
|
+
/**
|
|
11
|
+
* proxy configuration.
|
|
12
|
+
*/
|
|
7
13
|
proxy?: ProxyConfig;
|
|
8
14
|
}
|
|
9
15
|
export interface RequestOption {
|
|
@@ -26,7 +32,7 @@ export interface RequestOption {
|
|
|
26
32
|
*/
|
|
27
33
|
responseType?: "string" | "buffer";
|
|
28
34
|
}
|
|
29
|
-
export interface HttpResponse {
|
|
35
|
+
export interface HttpResponse<T = string | Buffer> {
|
|
30
36
|
/**
|
|
31
37
|
* http headers in the response.
|
|
32
38
|
*/
|
|
@@ -34,7 +40,7 @@ export interface HttpResponse {
|
|
|
34
40
|
/**
|
|
35
41
|
* response payload which has a type depends on {@link RequestOption.responseType}.
|
|
36
42
|
*/
|
|
37
|
-
payload?:
|
|
43
|
+
payload?: T;
|
|
38
44
|
}
|
|
39
45
|
export interface IHttpClient {
|
|
40
46
|
/**
|
|
@@ -49,14 +55,22 @@ export interface IHttpClient {
|
|
|
49
55
|
* @param op.responseType {@link RequestOption.responseType}
|
|
50
56
|
* @param op.redirectAsNewRequest handle redirect as new request. this may be efficient when using proxy which is implemented reverse proxy.
|
|
51
57
|
* @returns http response. {@link HttpResponse}
|
|
52
|
-
|
|
58
|
+
*/
|
|
59
|
+
get(url: string, op?: RequestOption & ClientOption & {
|
|
60
|
+
redirectAsNewRequest?: boolean;
|
|
61
|
+
responseType: "string";
|
|
62
|
+
}): Promise<HttpResponse<string>>;
|
|
63
|
+
get(url: string, op?: RequestOption & ClientOption & {
|
|
64
|
+
redirectAsNewRequest?: boolean;
|
|
65
|
+
responseType: "buffer";
|
|
66
|
+
}): Promise<HttpResponse<Buffer>>;
|
|
53
67
|
get(url: string, op?: RequestOption & ClientOption & {
|
|
54
68
|
redirectAsNewRequest?: boolean;
|
|
55
|
-
}): Promise<HttpResponse
|
|
69
|
+
}): Promise<HttpResponse<string>>;
|
|
56
70
|
/**
|
|
57
71
|
* request POST to the url with new context.
|
|
58
72
|
* @param url target url. (currently https only)
|
|
59
|
-
* @param payload request payload. if this is an object,
|
|
73
|
+
* @param payload request payload. if this is a Stream, pipe will be used, otherwise if an object, this is treated as json.
|
|
60
74
|
* @param op.headers http headers.
|
|
61
75
|
* @param op.mode {@link s_clientMode} that is imitated. default is random between chrome or firefox.
|
|
62
76
|
* @param op.proxy proxy configuration.
|
|
@@ -66,5 +80,11 @@ export interface IHttpClient {
|
|
|
66
80
|
* @param op.responseType {@link RequestOption.responseType}
|
|
67
81
|
* @returns http response. {@link HttpResponse}
|
|
68
82
|
*/
|
|
69
|
-
post(url: string, payload: any, op?: RequestOption & ClientOption
|
|
83
|
+
post(url: string, payload: any, op?: RequestOption & ClientOption & {
|
|
84
|
+
responseType: "string";
|
|
85
|
+
}): Promise<HttpResponse<string>>;
|
|
86
|
+
post(url: string, payload: any, op?: RequestOption & ClientOption & {
|
|
87
|
+
responseType: "buffer";
|
|
88
|
+
}): Promise<HttpResponse<Buffer>>;
|
|
89
|
+
post(url: string, payload: any, op?: RequestOption & ClientOption): Promise<HttpResponse<string>>;
|
|
70
90
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xjs-node",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "library modules for nodejs + typescript that bundled general-purpose implementations.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -29,6 +29,6 @@
|
|
|
29
29
|
"typescript": "^4.9.5"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"xjs-common": "^10.1.
|
|
32
|
+
"xjs-common": "^10.1.3"
|
|
33
33
|
}
|
|
34
34
|
}
|