@merkur/plugin-http-client 0.38.0 → 0.39.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/lib/index.cjs +49 -106
- package/lib/index.js +49 -106
- package/lib/index.mjs +49 -106
- package/package.json +4 -5
package/lib/index.cjs
CHANGED
|
@@ -5,44 +5,35 @@ var core = require('@merkur/core');
|
|
|
5
5
|
function setDefaultConfig(widget, newDefaultConfig) {
|
|
6
6
|
widget.$in.httpClient.defaultConfig = {
|
|
7
7
|
...widget.$in.httpClient.defaultConfig,
|
|
8
|
-
...newDefaultConfig
|
|
8
|
+
...newDefaultConfig
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
|
-
|
|
12
11
|
function getDefaultTransformers(widget) {
|
|
13
|
-
return [
|
|
14
|
-
transformBody(),
|
|
15
|
-
transformQuery(),
|
|
16
|
-
transformTimeout(),
|
|
17
|
-
];
|
|
12
|
+
return [transformBody(), transformQuery(), transformTimeout()];
|
|
18
13
|
}
|
|
19
14
|
function httpClientPlugin() {
|
|
20
15
|
return {
|
|
21
16
|
async setup(widget) {
|
|
22
17
|
core.assignMissingKeys(widget, httpClientAPI());
|
|
23
|
-
|
|
24
18
|
widget.$in.httpClient = {
|
|
25
19
|
defaultConfig: {
|
|
26
20
|
method: 'GET',
|
|
27
21
|
transformers: getDefaultTransformers(),
|
|
28
22
|
headers: {},
|
|
29
23
|
query: {},
|
|
30
|
-
timeout: 15000
|
|
31
|
-
}
|
|
24
|
+
timeout: 15000
|
|
25
|
+
}
|
|
32
26
|
};
|
|
33
|
-
|
|
34
27
|
widget.$dependencies.fetch = getFetchAPI();
|
|
35
28
|
widget.$dependencies.AbortController = AbortController;
|
|
36
|
-
|
|
37
29
|
return widget;
|
|
38
30
|
},
|
|
39
31
|
async create(widget) {
|
|
40
32
|
core.bindWidgetToFunctions(widget, widget.http);
|
|
41
33
|
return widget;
|
|
42
|
-
}
|
|
34
|
+
}
|
|
43
35
|
};
|
|
44
36
|
}
|
|
45
|
-
|
|
46
37
|
function httpClientAPI() {
|
|
47
38
|
return {
|
|
48
39
|
http: {
|
|
@@ -50,168 +41,129 @@ function httpClientAPI() {
|
|
|
50
41
|
let response = null;
|
|
51
42
|
let request = {
|
|
52
43
|
...widget.$in.httpClient.defaultConfig,
|
|
53
|
-
...requestConfig
|
|
44
|
+
...requestConfig
|
|
54
45
|
};
|
|
55
46
|
const transformers = request.transformers;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
transformers,
|
|
60
|
-
'transformRequest',
|
|
61
|
-
request,
|
|
62
|
-
response,
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
response = !response
|
|
66
|
-
? await widget.$dependencies.fetch(request.url, request)
|
|
67
|
-
: response;
|
|
68
|
-
|
|
69
|
-
[request, response] = await runTransformers(
|
|
70
|
-
widget,
|
|
71
|
-
transformers,
|
|
72
|
-
'transformResponse',
|
|
73
|
-
request,
|
|
74
|
-
response,
|
|
75
|
-
);
|
|
76
|
-
|
|
47
|
+
[request, response] = await runTransformers(widget, transformers, 'transformRequest', request, response);
|
|
48
|
+
response = !response ? await widget.$dependencies.fetch(request.url, request) : response;
|
|
49
|
+
[request, response] = await runTransformers(widget, transformers, 'transformResponse', request, response);
|
|
77
50
|
if (!response.ok) {
|
|
78
|
-
const error = new Error(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
);
|
|
51
|
+
const error = new Error(`Received ${response.status} status code when requesting ${request.url}`, {
|
|
52
|
+
cause: {
|
|
53
|
+
request,
|
|
54
|
+
response
|
|
55
|
+
}
|
|
56
|
+
});
|
|
84
57
|
// keep compatablity
|
|
85
58
|
error.request = request;
|
|
86
59
|
error.response = response;
|
|
87
|
-
|
|
88
60
|
return Promise.reject(error);
|
|
89
61
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
62
|
+
return {
|
|
63
|
+
request,
|
|
64
|
+
response
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
94
68
|
};
|
|
95
69
|
}
|
|
96
|
-
|
|
97
70
|
async function runTransformers(widget, transformers, method, ...rest) {
|
|
98
71
|
for (const transformer of transformers) {
|
|
99
72
|
if (typeof transformer[method] === 'function') {
|
|
100
73
|
rest = await transformer[method](widget, ...rest);
|
|
101
74
|
}
|
|
102
75
|
}
|
|
103
|
-
|
|
104
76
|
return rest;
|
|
105
77
|
}
|
|
106
|
-
|
|
107
78
|
function getFetchAPI() {
|
|
108
79
|
if (typeof window === 'undefined') {
|
|
109
80
|
return global?.fetch;
|
|
110
81
|
}
|
|
111
|
-
|
|
112
82
|
return window?.fetch?.bind?.(window);
|
|
113
83
|
}
|
|
114
|
-
|
|
115
84
|
function transformQuery() {
|
|
116
85
|
return {
|
|
117
86
|
async transformRequest(widget, request, response) {
|
|
118
|
-
let newRequest = {
|
|
119
|
-
|
|
120
|
-
|
|
87
|
+
let newRequest = {
|
|
88
|
+
...request
|
|
89
|
+
};
|
|
90
|
+
let {
|
|
91
|
+
baseUrl = '',
|
|
92
|
+
path = '/'
|
|
93
|
+
} = request;
|
|
121
94
|
if (!request.url) {
|
|
122
|
-
newRequest.url = `${
|
|
123
|
-
baseUrl.endsWith('/')
|
|
124
|
-
? baseUrl.substring(0, baseUrl.length - 1)
|
|
125
|
-
: baseUrl
|
|
126
|
-
}/${path.startsWith('/') ? path.substring(1) : path}`;
|
|
95
|
+
newRequest.url = `${baseUrl.endsWith('/') ? baseUrl.substring(0, baseUrl.length - 1) : baseUrl}/${path.startsWith('/') ? path.substring(1) : path}`;
|
|
127
96
|
} else {
|
|
128
97
|
newRequest.url = request.url;
|
|
129
98
|
}
|
|
130
|
-
|
|
131
|
-
const queryString = Object.keys(request.query)
|
|
132
|
-
.map((key) =>
|
|
133
|
-
[key, request.query[key]].map(encodeURIComponent).join('='),
|
|
134
|
-
)
|
|
135
|
-
.join('&');
|
|
99
|
+
const queryString = Object.keys(request.query).map(key => [key, request.query[key]].map(encodeURIComponent).join('=')).join('&');
|
|
136
100
|
const hasQuestionMark = newRequest.url.indexOf('?') !== -1;
|
|
137
|
-
|
|
138
101
|
if (hasQuestionMark) {
|
|
139
102
|
newRequest.url += queryString ? `&${queryString}` : '';
|
|
140
103
|
} else {
|
|
141
104
|
newRequest.url += queryString ? `?${queryString}` : '';
|
|
142
105
|
}
|
|
143
|
-
|
|
144
106
|
return [newRequest, response];
|
|
145
|
-
}
|
|
107
|
+
}
|
|
146
108
|
};
|
|
147
109
|
}
|
|
148
|
-
|
|
149
110
|
function transformBody() {
|
|
150
111
|
return {
|
|
151
112
|
async transformResponse(widget, request, response) {
|
|
152
113
|
if (response.status !== 204 && typeof response.json === 'function') {
|
|
153
114
|
const contentType = response.headers.get('content-type');
|
|
154
115
|
let body = null;
|
|
155
|
-
|
|
156
116
|
if (contentType && contentType.includes('application/json')) {
|
|
157
117
|
body = await response.json();
|
|
158
118
|
} else {
|
|
159
119
|
body = await response.text();
|
|
160
120
|
}
|
|
161
|
-
|
|
162
121
|
let newResponse = copyResponse(response);
|
|
163
122
|
newResponse.body = body;
|
|
164
|
-
|
|
165
123
|
return [request, newResponse];
|
|
166
124
|
}
|
|
167
|
-
|
|
168
125
|
return [request, response];
|
|
169
126
|
},
|
|
170
127
|
async transformRequest(widget, request, response) {
|
|
171
|
-
const {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
128
|
+
const {
|
|
129
|
+
body,
|
|
130
|
+
headers,
|
|
131
|
+
method
|
|
132
|
+
} = request;
|
|
133
|
+
if (body && (headers['Content-Type'] || headers['content-type']) === 'application/json' && !['GET', 'HEAD'].includes(method)) {
|
|
134
|
+
let newRequest = {
|
|
135
|
+
...request,
|
|
136
|
+
body: JSON.stringify(body)
|
|
137
|
+
};
|
|
181
138
|
return [newRequest, response];
|
|
182
139
|
}
|
|
183
|
-
|
|
184
140
|
return [request, response];
|
|
185
|
-
}
|
|
141
|
+
}
|
|
186
142
|
};
|
|
187
143
|
}
|
|
188
|
-
|
|
189
144
|
function transformTimeout() {
|
|
190
145
|
return {
|
|
191
146
|
async transformRequest(widget, request, response) {
|
|
192
|
-
let newRequest = {
|
|
193
|
-
|
|
147
|
+
let newRequest = {
|
|
148
|
+
...request
|
|
149
|
+
};
|
|
194
150
|
if ('timeout' in request) {
|
|
195
151
|
const controller = new widget.$dependencies.AbortController();
|
|
196
152
|
newRequest.signal = controller.signal;
|
|
197
|
-
|
|
198
153
|
newRequest.timeoutTimer = setTimeout(() => {
|
|
199
154
|
controller.abort();
|
|
200
155
|
}, request.timeout);
|
|
201
156
|
}
|
|
202
|
-
|
|
203
157
|
return [newRequest, response];
|
|
204
158
|
},
|
|
205
159
|
async transformResponse(widget, request, response) {
|
|
206
160
|
if ('timeoutTimer' in request) {
|
|
207
161
|
clearTimeout(request.timeoutTimer);
|
|
208
162
|
}
|
|
209
|
-
|
|
210
163
|
return [request, response];
|
|
211
|
-
}
|
|
164
|
+
}
|
|
212
165
|
};
|
|
213
166
|
}
|
|
214
|
-
|
|
215
167
|
function copyResponse(response) {
|
|
216
168
|
const {
|
|
217
169
|
body,
|
|
@@ -223,9 +175,8 @@ function copyResponse(response) {
|
|
|
223
175
|
trailers,
|
|
224
176
|
type,
|
|
225
177
|
url,
|
|
226
|
-
useFinalURL
|
|
178
|
+
useFinalURL
|
|
227
179
|
} = response;
|
|
228
|
-
|
|
229
180
|
return {
|
|
230
181
|
body: assign({}, body),
|
|
231
182
|
headers,
|
|
@@ -236,31 +187,23 @@ function copyResponse(response) {
|
|
|
236
187
|
trailers,
|
|
237
188
|
type,
|
|
238
189
|
url,
|
|
239
|
-
useFinalURL
|
|
190
|
+
useFinalURL
|
|
240
191
|
};
|
|
241
192
|
}
|
|
242
|
-
|
|
243
193
|
const PROTECTED_FIELDS = ['__proto__', 'prototype', 'constructor'];
|
|
244
194
|
function assign(target, source = {}, parentField = null) {
|
|
245
195
|
for (const field of Object.keys(source)) {
|
|
246
196
|
if (PROTECTED_FIELDS.includes(field)) {
|
|
247
197
|
return;
|
|
248
198
|
}
|
|
249
|
-
|
|
250
199
|
const value = source[field];
|
|
251
200
|
const fieldPath = parentField ? parentField + '.' + field : field;
|
|
252
|
-
|
|
253
201
|
if (value instanceof Array) {
|
|
254
202
|
target[field] = value.slice();
|
|
255
|
-
} else if (
|
|
256
|
-
value instanceof Object &&
|
|
257
|
-
!(value instanceof Function) &&
|
|
258
|
-
!(value instanceof RegExp)
|
|
259
|
-
) {
|
|
203
|
+
} else if (value instanceof Object && !(value instanceof Function) && !(value instanceof RegExp)) {
|
|
260
204
|
if (!(target[field] instanceof Object)) {
|
|
261
205
|
target[field] = {};
|
|
262
206
|
}
|
|
263
|
-
|
|
264
207
|
assign(target[field], value, fieldPath);
|
|
265
208
|
} else {
|
|
266
209
|
target[field] = value;
|
package/lib/index.js
CHANGED
|
@@ -5,44 +5,35 @@ var core = require('@merkur/core');
|
|
|
5
5
|
function setDefaultConfig(widget, newDefaultConfig) {
|
|
6
6
|
widget.$in.httpClient.defaultConfig = {
|
|
7
7
|
...widget.$in.httpClient.defaultConfig,
|
|
8
|
-
...newDefaultConfig
|
|
8
|
+
...newDefaultConfig
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
|
-
|
|
12
11
|
function getDefaultTransformers(widget) {
|
|
13
|
-
return [
|
|
14
|
-
transformBody(),
|
|
15
|
-
transformQuery(),
|
|
16
|
-
transformTimeout(),
|
|
17
|
-
];
|
|
12
|
+
return [transformBody(), transformQuery(), transformTimeout()];
|
|
18
13
|
}
|
|
19
14
|
function httpClientPlugin() {
|
|
20
15
|
return {
|
|
21
16
|
async setup(widget) {
|
|
22
17
|
core.assignMissingKeys(widget, httpClientAPI());
|
|
23
|
-
|
|
24
18
|
widget.$in.httpClient = {
|
|
25
19
|
defaultConfig: {
|
|
26
20
|
method: 'GET',
|
|
27
21
|
transformers: getDefaultTransformers(),
|
|
28
22
|
headers: {},
|
|
29
23
|
query: {},
|
|
30
|
-
timeout: 15000
|
|
31
|
-
}
|
|
24
|
+
timeout: 15000
|
|
25
|
+
}
|
|
32
26
|
};
|
|
33
|
-
|
|
34
27
|
widget.$dependencies.fetch = getFetchAPI();
|
|
35
28
|
widget.$dependencies.AbortController = AbortController;
|
|
36
|
-
|
|
37
29
|
return widget;
|
|
38
30
|
},
|
|
39
31
|
async create(widget) {
|
|
40
32
|
core.bindWidgetToFunctions(widget, widget.http);
|
|
41
33
|
return widget;
|
|
42
|
-
}
|
|
34
|
+
}
|
|
43
35
|
};
|
|
44
36
|
}
|
|
45
|
-
|
|
46
37
|
function httpClientAPI() {
|
|
47
38
|
return {
|
|
48
39
|
http: {
|
|
@@ -50,168 +41,129 @@ function httpClientAPI() {
|
|
|
50
41
|
let response = null;
|
|
51
42
|
let request = {
|
|
52
43
|
...widget.$in.httpClient.defaultConfig,
|
|
53
|
-
...requestConfig
|
|
44
|
+
...requestConfig
|
|
54
45
|
};
|
|
55
46
|
const transformers = request.transformers;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
transformers,
|
|
60
|
-
'transformRequest',
|
|
61
|
-
request,
|
|
62
|
-
response,
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
response = !response
|
|
66
|
-
? await widget.$dependencies.fetch(request.url, request)
|
|
67
|
-
: response;
|
|
68
|
-
|
|
69
|
-
[request, response] = await runTransformers(
|
|
70
|
-
widget,
|
|
71
|
-
transformers,
|
|
72
|
-
'transformResponse',
|
|
73
|
-
request,
|
|
74
|
-
response,
|
|
75
|
-
);
|
|
76
|
-
|
|
47
|
+
[request, response] = await runTransformers(widget, transformers, 'transformRequest', request, response);
|
|
48
|
+
response = !response ? await widget.$dependencies.fetch(request.url, request) : response;
|
|
49
|
+
[request, response] = await runTransformers(widget, transformers, 'transformResponse', request, response);
|
|
77
50
|
if (!response.ok) {
|
|
78
|
-
const error = new Error(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
);
|
|
51
|
+
const error = new Error(`Received ${response.status} status code when requesting ${request.url}`, {
|
|
52
|
+
cause: {
|
|
53
|
+
request,
|
|
54
|
+
response
|
|
55
|
+
}
|
|
56
|
+
});
|
|
84
57
|
// keep compatablity
|
|
85
58
|
error.request = request;
|
|
86
59
|
error.response = response;
|
|
87
|
-
|
|
88
60
|
return Promise.reject(error);
|
|
89
61
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
62
|
+
return {
|
|
63
|
+
request,
|
|
64
|
+
response
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
94
68
|
};
|
|
95
69
|
}
|
|
96
|
-
|
|
97
70
|
async function runTransformers(widget, transformers, method, ...rest) {
|
|
98
71
|
for (const transformer of transformers) {
|
|
99
72
|
if (typeof transformer[method] === 'function') {
|
|
100
73
|
rest = await transformer[method](widget, ...rest);
|
|
101
74
|
}
|
|
102
75
|
}
|
|
103
|
-
|
|
104
76
|
return rest;
|
|
105
77
|
}
|
|
106
|
-
|
|
107
78
|
function getFetchAPI() {
|
|
108
79
|
if (typeof window === 'undefined') {
|
|
109
80
|
return global?.fetch;
|
|
110
81
|
}
|
|
111
|
-
|
|
112
82
|
return window?.fetch?.bind?.(window);
|
|
113
83
|
}
|
|
114
|
-
|
|
115
84
|
function transformQuery() {
|
|
116
85
|
return {
|
|
117
86
|
async transformRequest(widget, request, response) {
|
|
118
|
-
let newRequest = {
|
|
119
|
-
|
|
120
|
-
|
|
87
|
+
let newRequest = {
|
|
88
|
+
...request
|
|
89
|
+
};
|
|
90
|
+
let {
|
|
91
|
+
baseUrl = '',
|
|
92
|
+
path = '/'
|
|
93
|
+
} = request;
|
|
121
94
|
if (!request.url) {
|
|
122
|
-
newRequest.url = `${
|
|
123
|
-
baseUrl.endsWith('/')
|
|
124
|
-
? baseUrl.substring(0, baseUrl.length - 1)
|
|
125
|
-
: baseUrl
|
|
126
|
-
}/${path.startsWith('/') ? path.substring(1) : path}`;
|
|
95
|
+
newRequest.url = `${baseUrl.endsWith('/') ? baseUrl.substring(0, baseUrl.length - 1) : baseUrl}/${path.startsWith('/') ? path.substring(1) : path}`;
|
|
127
96
|
} else {
|
|
128
97
|
newRequest.url = request.url;
|
|
129
98
|
}
|
|
130
|
-
|
|
131
|
-
const queryString = Object.keys(request.query)
|
|
132
|
-
.map((key) =>
|
|
133
|
-
[key, request.query[key]].map(encodeURIComponent).join('='),
|
|
134
|
-
)
|
|
135
|
-
.join('&');
|
|
99
|
+
const queryString = Object.keys(request.query).map(key => [key, request.query[key]].map(encodeURIComponent).join('=')).join('&');
|
|
136
100
|
const hasQuestionMark = newRequest.url.indexOf('?') !== -1;
|
|
137
|
-
|
|
138
101
|
if (hasQuestionMark) {
|
|
139
102
|
newRequest.url += queryString ? `&${queryString}` : '';
|
|
140
103
|
} else {
|
|
141
104
|
newRequest.url += queryString ? `?${queryString}` : '';
|
|
142
105
|
}
|
|
143
|
-
|
|
144
106
|
return [newRequest, response];
|
|
145
|
-
}
|
|
107
|
+
}
|
|
146
108
|
};
|
|
147
109
|
}
|
|
148
|
-
|
|
149
110
|
function transformBody() {
|
|
150
111
|
return {
|
|
151
112
|
async transformResponse(widget, request, response) {
|
|
152
113
|
if (response.status !== 204 && typeof response.json === 'function') {
|
|
153
114
|
const contentType = response.headers.get('content-type');
|
|
154
115
|
let body = null;
|
|
155
|
-
|
|
156
116
|
if (contentType && contentType.includes('application/json')) {
|
|
157
117
|
body = await response.json();
|
|
158
118
|
} else {
|
|
159
119
|
body = await response.text();
|
|
160
120
|
}
|
|
161
|
-
|
|
162
121
|
let newResponse = copyResponse(response);
|
|
163
122
|
newResponse.body = body;
|
|
164
|
-
|
|
165
123
|
return [request, newResponse];
|
|
166
124
|
}
|
|
167
|
-
|
|
168
125
|
return [request, response];
|
|
169
126
|
},
|
|
170
127
|
async transformRequest(widget, request, response) {
|
|
171
|
-
const {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
128
|
+
const {
|
|
129
|
+
body,
|
|
130
|
+
headers,
|
|
131
|
+
method
|
|
132
|
+
} = request;
|
|
133
|
+
if (body && (headers['Content-Type'] || headers['content-type']) === 'application/json' && !['GET', 'HEAD'].includes(method)) {
|
|
134
|
+
let newRequest = {
|
|
135
|
+
...request,
|
|
136
|
+
body: JSON.stringify(body)
|
|
137
|
+
};
|
|
181
138
|
return [newRequest, response];
|
|
182
139
|
}
|
|
183
|
-
|
|
184
140
|
return [request, response];
|
|
185
|
-
}
|
|
141
|
+
}
|
|
186
142
|
};
|
|
187
143
|
}
|
|
188
|
-
|
|
189
144
|
function transformTimeout() {
|
|
190
145
|
return {
|
|
191
146
|
async transformRequest(widget, request, response) {
|
|
192
|
-
let newRequest = {
|
|
193
|
-
|
|
147
|
+
let newRequest = {
|
|
148
|
+
...request
|
|
149
|
+
};
|
|
194
150
|
if ('timeout' in request) {
|
|
195
151
|
const controller = new widget.$dependencies.AbortController();
|
|
196
152
|
newRequest.signal = controller.signal;
|
|
197
|
-
|
|
198
153
|
newRequest.timeoutTimer = setTimeout(() => {
|
|
199
154
|
controller.abort();
|
|
200
155
|
}, request.timeout);
|
|
201
156
|
}
|
|
202
|
-
|
|
203
157
|
return [newRequest, response];
|
|
204
158
|
},
|
|
205
159
|
async transformResponse(widget, request, response) {
|
|
206
160
|
if ('timeoutTimer' in request) {
|
|
207
161
|
clearTimeout(request.timeoutTimer);
|
|
208
162
|
}
|
|
209
|
-
|
|
210
163
|
return [request, response];
|
|
211
|
-
}
|
|
164
|
+
}
|
|
212
165
|
};
|
|
213
166
|
}
|
|
214
|
-
|
|
215
167
|
function copyResponse(response) {
|
|
216
168
|
const {
|
|
217
169
|
body,
|
|
@@ -223,9 +175,8 @@ function copyResponse(response) {
|
|
|
223
175
|
trailers,
|
|
224
176
|
type,
|
|
225
177
|
url,
|
|
226
|
-
useFinalURL
|
|
178
|
+
useFinalURL
|
|
227
179
|
} = response;
|
|
228
|
-
|
|
229
180
|
return {
|
|
230
181
|
body: assign({}, body),
|
|
231
182
|
headers,
|
|
@@ -236,31 +187,23 @@ function copyResponse(response) {
|
|
|
236
187
|
trailers,
|
|
237
188
|
type,
|
|
238
189
|
url,
|
|
239
|
-
useFinalURL
|
|
190
|
+
useFinalURL
|
|
240
191
|
};
|
|
241
192
|
}
|
|
242
|
-
|
|
243
193
|
const PROTECTED_FIELDS = ['__proto__', 'prototype', 'constructor'];
|
|
244
194
|
function assign(target, source = {}, parentField = null) {
|
|
245
195
|
for (const field of Object.keys(source)) {
|
|
246
196
|
if (PROTECTED_FIELDS.includes(field)) {
|
|
247
197
|
return;
|
|
248
198
|
}
|
|
249
|
-
|
|
250
199
|
const value = source[field];
|
|
251
200
|
const fieldPath = parentField ? parentField + '.' + field : field;
|
|
252
|
-
|
|
253
201
|
if (value instanceof Array) {
|
|
254
202
|
target[field] = value.slice();
|
|
255
|
-
} else if (
|
|
256
|
-
value instanceof Object &&
|
|
257
|
-
!(value instanceof Function) &&
|
|
258
|
-
!(value instanceof RegExp)
|
|
259
|
-
) {
|
|
203
|
+
} else if (value instanceof Object && !(value instanceof Function) && !(value instanceof RegExp)) {
|
|
260
204
|
if (!(target[field] instanceof Object)) {
|
|
261
205
|
target[field] = {};
|
|
262
206
|
}
|
|
263
|
-
|
|
264
207
|
assign(target[field], value, fieldPath);
|
|
265
208
|
} else {
|
|
266
209
|
target[field] = value;
|
package/lib/index.mjs
CHANGED
|
@@ -3,44 +3,35 @@ import { bindWidgetToFunctions, assignMissingKeys } from '@merkur/core';
|
|
|
3
3
|
function setDefaultConfig(widget, newDefaultConfig) {
|
|
4
4
|
widget.$in.httpClient.defaultConfig = {
|
|
5
5
|
...widget.$in.httpClient.defaultConfig,
|
|
6
|
-
...newDefaultConfig
|
|
6
|
+
...newDefaultConfig
|
|
7
7
|
};
|
|
8
8
|
}
|
|
9
|
-
|
|
10
9
|
function getDefaultTransformers(widget) {
|
|
11
|
-
return [
|
|
12
|
-
transformBody(),
|
|
13
|
-
transformQuery(),
|
|
14
|
-
transformTimeout(),
|
|
15
|
-
];
|
|
10
|
+
return [transformBody(), transformQuery(), transformTimeout()];
|
|
16
11
|
}
|
|
17
12
|
function httpClientPlugin() {
|
|
18
13
|
return {
|
|
19
14
|
async setup(widget) {
|
|
20
15
|
assignMissingKeys(widget, httpClientAPI());
|
|
21
|
-
|
|
22
16
|
widget.$in.httpClient = {
|
|
23
17
|
defaultConfig: {
|
|
24
18
|
method: 'GET',
|
|
25
19
|
transformers: getDefaultTransformers(),
|
|
26
20
|
headers: {},
|
|
27
21
|
query: {},
|
|
28
|
-
timeout: 15000
|
|
29
|
-
}
|
|
22
|
+
timeout: 15000
|
|
23
|
+
}
|
|
30
24
|
};
|
|
31
|
-
|
|
32
25
|
widget.$dependencies.fetch = getFetchAPI();
|
|
33
26
|
widget.$dependencies.AbortController = AbortController;
|
|
34
|
-
|
|
35
27
|
return widget;
|
|
36
28
|
},
|
|
37
29
|
async create(widget) {
|
|
38
30
|
bindWidgetToFunctions(widget, widget.http);
|
|
39
31
|
return widget;
|
|
40
|
-
}
|
|
32
|
+
}
|
|
41
33
|
};
|
|
42
34
|
}
|
|
43
|
-
|
|
44
35
|
function httpClientAPI() {
|
|
45
36
|
return {
|
|
46
37
|
http: {
|
|
@@ -48,168 +39,129 @@ function httpClientAPI() {
|
|
|
48
39
|
let response = null;
|
|
49
40
|
let request = {
|
|
50
41
|
...widget.$in.httpClient.defaultConfig,
|
|
51
|
-
...requestConfig
|
|
42
|
+
...requestConfig
|
|
52
43
|
};
|
|
53
44
|
const transformers = request.transformers;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
transformers,
|
|
58
|
-
'transformRequest',
|
|
59
|
-
request,
|
|
60
|
-
response,
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
response = !response
|
|
64
|
-
? await widget.$dependencies.fetch(request.url, request)
|
|
65
|
-
: response;
|
|
66
|
-
|
|
67
|
-
[request, response] = await runTransformers(
|
|
68
|
-
widget,
|
|
69
|
-
transformers,
|
|
70
|
-
'transformResponse',
|
|
71
|
-
request,
|
|
72
|
-
response,
|
|
73
|
-
);
|
|
74
|
-
|
|
45
|
+
[request, response] = await runTransformers(widget, transformers, 'transformRequest', request, response);
|
|
46
|
+
response = !response ? await widget.$dependencies.fetch(request.url, request) : response;
|
|
47
|
+
[request, response] = await runTransformers(widget, transformers, 'transformResponse', request, response);
|
|
75
48
|
if (!response.ok) {
|
|
76
|
-
const error = new Error(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
);
|
|
49
|
+
const error = new Error(`Received ${response.status} status code when requesting ${request.url}`, {
|
|
50
|
+
cause: {
|
|
51
|
+
request,
|
|
52
|
+
response
|
|
53
|
+
}
|
|
54
|
+
});
|
|
82
55
|
// keep compatablity
|
|
83
56
|
error.request = request;
|
|
84
57
|
error.response = response;
|
|
85
|
-
|
|
86
58
|
return Promise.reject(error);
|
|
87
59
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
60
|
+
return {
|
|
61
|
+
request,
|
|
62
|
+
response
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
92
66
|
};
|
|
93
67
|
}
|
|
94
|
-
|
|
95
68
|
async function runTransformers(widget, transformers, method, ...rest) {
|
|
96
69
|
for (const transformer of transformers) {
|
|
97
70
|
if (typeof transformer[method] === 'function') {
|
|
98
71
|
rest = await transformer[method](widget, ...rest);
|
|
99
72
|
}
|
|
100
73
|
}
|
|
101
|
-
|
|
102
74
|
return rest;
|
|
103
75
|
}
|
|
104
|
-
|
|
105
76
|
function getFetchAPI() {
|
|
106
77
|
if (typeof window === 'undefined') {
|
|
107
78
|
return global?.fetch;
|
|
108
79
|
}
|
|
109
|
-
|
|
110
80
|
return window?.fetch?.bind?.(window);
|
|
111
81
|
}
|
|
112
|
-
|
|
113
82
|
function transformQuery() {
|
|
114
83
|
return {
|
|
115
84
|
async transformRequest(widget, request, response) {
|
|
116
|
-
let newRequest = {
|
|
117
|
-
|
|
118
|
-
|
|
85
|
+
let newRequest = {
|
|
86
|
+
...request
|
|
87
|
+
};
|
|
88
|
+
let {
|
|
89
|
+
baseUrl = '',
|
|
90
|
+
path = '/'
|
|
91
|
+
} = request;
|
|
119
92
|
if (!request.url) {
|
|
120
|
-
newRequest.url = `${
|
|
121
|
-
baseUrl.endsWith('/')
|
|
122
|
-
? baseUrl.substring(0, baseUrl.length - 1)
|
|
123
|
-
: baseUrl
|
|
124
|
-
}/${path.startsWith('/') ? path.substring(1) : path}`;
|
|
93
|
+
newRequest.url = `${baseUrl.endsWith('/') ? baseUrl.substring(0, baseUrl.length - 1) : baseUrl}/${path.startsWith('/') ? path.substring(1) : path}`;
|
|
125
94
|
} else {
|
|
126
95
|
newRequest.url = request.url;
|
|
127
96
|
}
|
|
128
|
-
|
|
129
|
-
const queryString = Object.keys(request.query)
|
|
130
|
-
.map((key) =>
|
|
131
|
-
[key, request.query[key]].map(encodeURIComponent).join('='),
|
|
132
|
-
)
|
|
133
|
-
.join('&');
|
|
97
|
+
const queryString = Object.keys(request.query).map(key => [key, request.query[key]].map(encodeURIComponent).join('=')).join('&');
|
|
134
98
|
const hasQuestionMark = newRequest.url.indexOf('?') !== -1;
|
|
135
|
-
|
|
136
99
|
if (hasQuestionMark) {
|
|
137
100
|
newRequest.url += queryString ? `&${queryString}` : '';
|
|
138
101
|
} else {
|
|
139
102
|
newRequest.url += queryString ? `?${queryString}` : '';
|
|
140
103
|
}
|
|
141
|
-
|
|
142
104
|
return [newRequest, response];
|
|
143
|
-
}
|
|
105
|
+
}
|
|
144
106
|
};
|
|
145
107
|
}
|
|
146
|
-
|
|
147
108
|
function transformBody() {
|
|
148
109
|
return {
|
|
149
110
|
async transformResponse(widget, request, response) {
|
|
150
111
|
if (response.status !== 204 && typeof response.json === 'function') {
|
|
151
112
|
const contentType = response.headers.get('content-type');
|
|
152
113
|
let body = null;
|
|
153
|
-
|
|
154
114
|
if (contentType && contentType.includes('application/json')) {
|
|
155
115
|
body = await response.json();
|
|
156
116
|
} else {
|
|
157
117
|
body = await response.text();
|
|
158
118
|
}
|
|
159
|
-
|
|
160
119
|
let newResponse = copyResponse(response);
|
|
161
120
|
newResponse.body = body;
|
|
162
|
-
|
|
163
121
|
return [request, newResponse];
|
|
164
122
|
}
|
|
165
|
-
|
|
166
123
|
return [request, response];
|
|
167
124
|
},
|
|
168
125
|
async transformRequest(widget, request, response) {
|
|
169
|
-
const {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
126
|
+
const {
|
|
127
|
+
body,
|
|
128
|
+
headers,
|
|
129
|
+
method
|
|
130
|
+
} = request;
|
|
131
|
+
if (body && (headers['Content-Type'] || headers['content-type']) === 'application/json' && !['GET', 'HEAD'].includes(method)) {
|
|
132
|
+
let newRequest = {
|
|
133
|
+
...request,
|
|
134
|
+
body: JSON.stringify(body)
|
|
135
|
+
};
|
|
179
136
|
return [newRequest, response];
|
|
180
137
|
}
|
|
181
|
-
|
|
182
138
|
return [request, response];
|
|
183
|
-
}
|
|
139
|
+
}
|
|
184
140
|
};
|
|
185
141
|
}
|
|
186
|
-
|
|
187
142
|
function transformTimeout() {
|
|
188
143
|
return {
|
|
189
144
|
async transformRequest(widget, request, response) {
|
|
190
|
-
let newRequest = {
|
|
191
|
-
|
|
145
|
+
let newRequest = {
|
|
146
|
+
...request
|
|
147
|
+
};
|
|
192
148
|
if ('timeout' in request) {
|
|
193
149
|
const controller = new widget.$dependencies.AbortController();
|
|
194
150
|
newRequest.signal = controller.signal;
|
|
195
|
-
|
|
196
151
|
newRequest.timeoutTimer = setTimeout(() => {
|
|
197
152
|
controller.abort();
|
|
198
153
|
}, request.timeout);
|
|
199
154
|
}
|
|
200
|
-
|
|
201
155
|
return [newRequest, response];
|
|
202
156
|
},
|
|
203
157
|
async transformResponse(widget, request, response) {
|
|
204
158
|
if ('timeoutTimer' in request) {
|
|
205
159
|
clearTimeout(request.timeoutTimer);
|
|
206
160
|
}
|
|
207
|
-
|
|
208
161
|
return [request, response];
|
|
209
|
-
}
|
|
162
|
+
}
|
|
210
163
|
};
|
|
211
164
|
}
|
|
212
|
-
|
|
213
165
|
function copyResponse(response) {
|
|
214
166
|
const {
|
|
215
167
|
body,
|
|
@@ -221,9 +173,8 @@ function copyResponse(response) {
|
|
|
221
173
|
trailers,
|
|
222
174
|
type,
|
|
223
175
|
url,
|
|
224
|
-
useFinalURL
|
|
176
|
+
useFinalURL
|
|
225
177
|
} = response;
|
|
226
|
-
|
|
227
178
|
return {
|
|
228
179
|
body: assign({}, body),
|
|
229
180
|
headers,
|
|
@@ -234,31 +185,23 @@ function copyResponse(response) {
|
|
|
234
185
|
trailers,
|
|
235
186
|
type,
|
|
236
187
|
url,
|
|
237
|
-
useFinalURL
|
|
188
|
+
useFinalURL
|
|
238
189
|
};
|
|
239
190
|
}
|
|
240
|
-
|
|
241
191
|
const PROTECTED_FIELDS = ['__proto__', 'prototype', 'constructor'];
|
|
242
192
|
function assign(target, source = {}, parentField = null) {
|
|
243
193
|
for (const field of Object.keys(source)) {
|
|
244
194
|
if (PROTECTED_FIELDS.includes(field)) {
|
|
245
195
|
return;
|
|
246
196
|
}
|
|
247
|
-
|
|
248
197
|
const value = source[field];
|
|
249
198
|
const fieldPath = parentField ? parentField + '.' + field : field;
|
|
250
|
-
|
|
251
199
|
if (value instanceof Array) {
|
|
252
200
|
target[field] = value.slice();
|
|
253
|
-
} else if (
|
|
254
|
-
value instanceof Object &&
|
|
255
|
-
!(value instanceof Function) &&
|
|
256
|
-
!(value instanceof RegExp)
|
|
257
|
-
) {
|
|
201
|
+
} else if (value instanceof Object && !(value instanceof Function) && !(value instanceof RegExp)) {
|
|
258
202
|
if (!(target[field] instanceof Object)) {
|
|
259
203
|
target[field] = {};
|
|
260
204
|
}
|
|
261
|
-
|
|
262
205
|
assign(target[field], value, fieldPath);
|
|
263
206
|
} else {
|
|
264
207
|
target[field] = value;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@merkur/plugin-http-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.39.0",
|
|
4
4
|
"description": "Merkur event emitter plugin.",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"module": "lib/index",
|
|
@@ -24,8 +24,7 @@
|
|
|
24
24
|
"preversion": "npm test",
|
|
25
25
|
"test": "jest --no-watchman -c ./jest.config.js",
|
|
26
26
|
"test:es:version": "es-check es11 ./lib/index.mjs --module && es-check es9 ./lib/index.es9.mjs --module && es-check es9 ./lib/index.es9.cjs --module",
|
|
27
|
-
"build": "rollup -c rollup.config.mjs"
|
|
28
|
-
"prepare": "npm run build"
|
|
27
|
+
"build": "rollup -c rollup.config.mjs"
|
|
29
28
|
},
|
|
30
29
|
"repository": {
|
|
31
30
|
"type": "git",
|
|
@@ -48,10 +47,10 @@
|
|
|
48
47
|
},
|
|
49
48
|
"homepage": "https://merkur.js.org/",
|
|
50
49
|
"devDependencies": {
|
|
51
|
-
"@merkur/core": "^0.
|
|
50
|
+
"@merkur/core": "^0.39.0"
|
|
52
51
|
},
|
|
53
52
|
"peerDependencies": {
|
|
54
53
|
"@merkur/core": "*"
|
|
55
54
|
},
|
|
56
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "8ad2c8b26246850ce6289502a8b05e882f80ce31"
|
|
57
56
|
}
|