@autometa/http 1.2.0 → 1.3.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 +27 -0
- package/dist/esm/index.js +921 -427
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.cts +1053 -86
- package/dist/index.d.ts +1053 -86
- package/dist/index.js +936 -429
- package/dist/index.js.map +1 -1
- package/package.json +7 -3
- package/src/axios-client.ts +35 -0
- package/src/default-client-factory.axios.spec.ts +9 -0
- package/src/default-client-factory.other.spec.ts +13 -0
- package/src/default-client-factory.ts +7 -0
- package/src/default-schema.spec.ts +74 -0
- package/src/default-schema.ts +128 -0
- package/src/http-client.ts +20 -0
- package/src/http-request.spec.ts +141 -0
- package/src/http-request.ts +164 -0
- package/src/http-response.ts +107 -0
- package/src/http.spec.ts +169 -0
- package/src/http.ts +867 -0
- package/src/index.ts +13 -0
- package/src/request-meta.config.spec.ts +81 -0
- package/src/request-meta.config.ts +117 -0
- package/src/request.config.ts +19 -0
- package/src/schema.map.spec.ts +50 -0
- package/src/schema.map.ts +68 -0
- package/src/transform-response.ts +43 -0
- package/src/types.ts +37 -0
package/dist/index.js
CHANGED
|
@@ -53,133 +53,425 @@ var __privateSet = (obj, member, value, setter) => {
|
|
|
53
53
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
54
54
|
return value;
|
|
55
55
|
};
|
|
56
|
+
var __privateMethod = (obj, member, method) => {
|
|
57
|
+
__accessCheck(obj, member, "access private method");
|
|
58
|
+
return method;
|
|
59
|
+
};
|
|
56
60
|
|
|
57
61
|
// src/index.ts
|
|
58
62
|
var src_exports = {};
|
|
59
63
|
__export(src_exports, {
|
|
60
|
-
|
|
64
|
+
AnySchema: () => AnySchema,
|
|
65
|
+
AxiosClient: () => AxiosClient,
|
|
66
|
+
BooleanSchema: () => BooleanSchema,
|
|
67
|
+
EmptySchema: () => EmptySchema,
|
|
61
68
|
HTTP: () => HTTP,
|
|
62
|
-
|
|
69
|
+
HTTPClient: () => HTTPClient,
|
|
70
|
+
HTTPRequest: () => HTTPRequest,
|
|
71
|
+
HTTPRequestBuilder: () => HTTPRequestBuilder,
|
|
72
|
+
HTTPResponse: () => HTTPResponse,
|
|
73
|
+
HTTPResponseBuilder: () => HTTPResponseBuilder,
|
|
74
|
+
JSONSchema: () => JSONSchema,
|
|
75
|
+
NullSchema: () => NullSchema,
|
|
76
|
+
NumberSchema: () => NumberSchema,
|
|
77
|
+
StringSchema: () => StringSchema,
|
|
78
|
+
UndefinedSchema: () => UndefinedSchema,
|
|
79
|
+
defaultClient: () => defaultClient
|
|
63
80
|
});
|
|
64
81
|
module.exports = __toCommonJS(src_exports);
|
|
65
82
|
|
|
66
|
-
// src/http
|
|
67
|
-
var HTTPResponse = class {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
response.data = data;
|
|
75
|
-
}
|
|
76
|
-
response.status = original.status;
|
|
77
|
-
response.statusText = original.statusText;
|
|
78
|
-
response.headers = original.headers;
|
|
79
|
-
response.request = original.request;
|
|
80
|
-
response.actual = original;
|
|
83
|
+
// src/http-response.ts
|
|
84
|
+
var HTTPResponse = class _HTTPResponse {
|
|
85
|
+
constructor() {
|
|
86
|
+
this.headers = {};
|
|
87
|
+
}
|
|
88
|
+
static fromRaw(response) {
|
|
89
|
+
const newResponse = new _HTTPResponse();
|
|
90
|
+
Object.assign(newResponse, response);
|
|
81
91
|
return response;
|
|
82
92
|
}
|
|
93
|
+
decompose(transformFn) {
|
|
94
|
+
const value = getDecompositionValue(this.data, transformFn);
|
|
95
|
+
return new HTTPResponseBuilder().status(this.status).statusText(this.statusText).headers(this.headers).request(this.request).data(value).build();
|
|
96
|
+
}
|
|
83
97
|
};
|
|
84
|
-
|
|
98
|
+
function getDecompositionValue(data, transformFn) {
|
|
99
|
+
return typeof transformFn === "function" ? transformFn(data) : transformFn;
|
|
100
|
+
}
|
|
101
|
+
var _response;
|
|
102
|
+
var _HTTPResponseBuilder = class _HTTPResponseBuilder {
|
|
103
|
+
constructor() {
|
|
104
|
+
__privateAdd(this, _response, new HTTPResponse());
|
|
105
|
+
}
|
|
106
|
+
static create() {
|
|
107
|
+
return new _HTTPResponseBuilder();
|
|
108
|
+
}
|
|
109
|
+
derive() {
|
|
110
|
+
return _HTTPResponseBuilder.create().data(__privateGet(this, _response).data).headers(__privateGet(this, _response).headers).request(__privateGet(this, _response).request).status(__privateGet(this, _response).status).statusText(__privateGet(this, _response).statusText);
|
|
111
|
+
}
|
|
112
|
+
status(code) {
|
|
113
|
+
__privateGet(this, _response).status = code;
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
statusText(text) {
|
|
117
|
+
__privateGet(this, _response).statusText = text;
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
data(data) {
|
|
121
|
+
__privateGet(this, _response).data = data;
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
headers(dict) {
|
|
125
|
+
__privateGet(this, _response).headers = dict;
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
header(name, value) {
|
|
129
|
+
__privateGet(this, _response).headers[name] = value;
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
request(request) {
|
|
133
|
+
__privateGet(this, _response).request = request;
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
build() {
|
|
137
|
+
return __privateGet(this, _response);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
_response = new WeakMap();
|
|
141
|
+
var HTTPResponseBuilder = _HTTPResponseBuilder;
|
|
142
|
+
|
|
143
|
+
// src/axios-client.ts
|
|
144
|
+
var import_axios = __toESM(require("axios"), 1);
|
|
145
|
+
|
|
146
|
+
// src/http-client.ts
|
|
147
|
+
var defaultClient;
|
|
148
|
+
var HTTPClient = class {
|
|
149
|
+
static Use(client) {
|
|
150
|
+
if (client) {
|
|
151
|
+
defaultClient = client;
|
|
152
|
+
}
|
|
153
|
+
return function(target) {
|
|
154
|
+
defaultClient = target;
|
|
155
|
+
};
|
|
156
|
+
}
|
|
85
157
|
};
|
|
86
158
|
|
|
159
|
+
// src/axios-client.ts
|
|
160
|
+
var AxiosClient = class extends HTTPClient {
|
|
161
|
+
async request(request, options) {
|
|
162
|
+
const { baseUrl, route, params, headers, method, data } = request;
|
|
163
|
+
const url = [baseUrl, ...route].join("/");
|
|
164
|
+
const axiosRequest = {
|
|
165
|
+
url,
|
|
166
|
+
params,
|
|
167
|
+
headers,
|
|
168
|
+
method,
|
|
169
|
+
data,
|
|
170
|
+
validateStatus: function(status) {
|
|
171
|
+
return status >= 0 && status < 600;
|
|
172
|
+
},
|
|
173
|
+
...options
|
|
174
|
+
};
|
|
175
|
+
const response = await (0, import_axios.default)(axiosRequest);
|
|
176
|
+
return HTTPResponseBuilder.create().status(response.status).statusText(response.statusText).data(response.data).headers(response.headers).request(request).build();
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
AxiosClient = __decorateClass([
|
|
180
|
+
HTTPClient.Use()
|
|
181
|
+
], AxiosClient);
|
|
182
|
+
|
|
87
183
|
// src/http.ts
|
|
88
|
-
var
|
|
184
|
+
var import_injection = require("@autometa/injection");
|
|
185
|
+
|
|
186
|
+
// src/default-client-factory.ts
|
|
187
|
+
function defaultClientFactory() {
|
|
188
|
+
const type = defaultClient;
|
|
189
|
+
return new type();
|
|
190
|
+
}
|
|
89
191
|
|
|
90
|
-
// src/http.
|
|
91
|
-
var import_errors4 = require("@autometa/errors");
|
|
192
|
+
// src/http-request.ts
|
|
92
193
|
var import_url_join_ts = require("url-join-ts");
|
|
194
|
+
var HTTPRequest = class _HTTPRequest {
|
|
195
|
+
constructor(config) {
|
|
196
|
+
this.headers = {};
|
|
197
|
+
this.params = {};
|
|
198
|
+
this.route = [];
|
|
199
|
+
Object.assign(this, config);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Returns the full URL of the request, including the base url,
|
|
203
|
+
* routes, and query parameters.
|
|
204
|
+
*
|
|
205
|
+
* ```ts
|
|
206
|
+
* console.log(request.fullUrl())// https://example.com/foo?bar=baz?array=1,2,3
|
|
207
|
+
* ```
|
|
208
|
+
*
|
|
209
|
+
* Note characters may be converted to escape codes. I.e (space => %20) and (comma => %2C)
|
|
210
|
+
*
|
|
211
|
+
* N.B this method estimates what the url will be. The actual value
|
|
212
|
+
* might be different depending on your underlying HTTPClient and
|
|
213
|
+
* configuration. For example, query parameters might
|
|
214
|
+
* use different array formats.
|
|
215
|
+
*/
|
|
216
|
+
fullUrl() {
|
|
217
|
+
return (0, import_url_join_ts.urlJoinP)(this.baseUrl, this.route, this.params);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Returns a new independent copy of the request.
|
|
221
|
+
*/
|
|
222
|
+
static derive(original) {
|
|
223
|
+
const request = new _HTTPRequest();
|
|
224
|
+
request.headers = { ...original.headers };
|
|
225
|
+
request.params = { ...original.params };
|
|
226
|
+
request.baseUrl = original.baseUrl;
|
|
227
|
+
request.route = [...original.route];
|
|
228
|
+
request.method = original.method;
|
|
229
|
+
request.data = original.data;
|
|
230
|
+
return request;
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
var _request, _dynamicHeaders;
|
|
234
|
+
var _HTTPRequestBuilder = class _HTTPRequestBuilder {
|
|
235
|
+
constructor(request = () => new HTTPRequest()) {
|
|
236
|
+
__privateAdd(this, _request, void 0);
|
|
237
|
+
__privateAdd(this, _dynamicHeaders, /* @__PURE__ */ new Map());
|
|
238
|
+
if (typeof request === "function") {
|
|
239
|
+
__privateSet(this, _request, request());
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
__privateSet(this, _request, request);
|
|
243
|
+
}
|
|
244
|
+
static create() {
|
|
245
|
+
return new _HTTPRequestBuilder();
|
|
246
|
+
}
|
|
247
|
+
get request() {
|
|
248
|
+
return __privateGet(this, _request);
|
|
249
|
+
}
|
|
250
|
+
resolveDynamicHeaders() {
|
|
251
|
+
for (const [name, value] of __privateGet(this, _dynamicHeaders)) {
|
|
252
|
+
try {
|
|
253
|
+
__privateGet(this, _request).headers[name] = String(value());
|
|
254
|
+
} catch (e) {
|
|
255
|
+
const cause = e;
|
|
256
|
+
const msg = `Failed to resolve dynamic header "${name}":
|
|
257
|
+
${cause}`;
|
|
258
|
+
throw new Error(msg);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return this;
|
|
262
|
+
}
|
|
263
|
+
url(url) {
|
|
264
|
+
__privateGet(this, _request).baseUrl = url;
|
|
265
|
+
return this;
|
|
266
|
+
}
|
|
267
|
+
route(...route) {
|
|
268
|
+
__privateGet(this, _request).route.push(...route);
|
|
269
|
+
return this;
|
|
270
|
+
}
|
|
271
|
+
param(name, value) {
|
|
272
|
+
if (Array.isArray(value)) {
|
|
273
|
+
const asStr = value.map(String);
|
|
274
|
+
__privateGet(this, _request).params[name] = asStr;
|
|
275
|
+
return this;
|
|
276
|
+
}
|
|
277
|
+
if (!Array.isArray(value) && typeof value === "object") {
|
|
278
|
+
__privateGet(this, _request).params[name] = value;
|
|
279
|
+
return this;
|
|
280
|
+
}
|
|
281
|
+
__privateGet(this, _request).params[name] = String(value);
|
|
282
|
+
return this;
|
|
283
|
+
}
|
|
284
|
+
params(dict) {
|
|
285
|
+
Object.assign(__privateGet(this, _request).params, dict);
|
|
286
|
+
return this;
|
|
287
|
+
}
|
|
288
|
+
data(data) {
|
|
289
|
+
__privateGet(this, _request).data = data;
|
|
290
|
+
return this;
|
|
291
|
+
}
|
|
292
|
+
header(name, value) {
|
|
293
|
+
if (typeof value === "function") {
|
|
294
|
+
value = value();
|
|
295
|
+
}
|
|
296
|
+
__privateGet(this, _request).headers[name] = String(value);
|
|
297
|
+
return this;
|
|
298
|
+
}
|
|
299
|
+
headers(dict) {
|
|
300
|
+
Object.assign(__privateGet(this, _request).headers, dict);
|
|
301
|
+
return this;
|
|
302
|
+
}
|
|
303
|
+
get() {
|
|
304
|
+
return __privateGet(this, _request);
|
|
305
|
+
}
|
|
306
|
+
method(method) {
|
|
307
|
+
__privateGet(this, _request).method = method;
|
|
308
|
+
return this;
|
|
309
|
+
}
|
|
310
|
+
derive() {
|
|
311
|
+
const request = HTTPRequest.derive(__privateGet(this, _request));
|
|
312
|
+
return new _HTTPRequestBuilder(request);
|
|
313
|
+
}
|
|
314
|
+
build() {
|
|
315
|
+
return __privateGet(this, _request);
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
_request = new WeakMap();
|
|
319
|
+
_dynamicHeaders = new WeakMap();
|
|
320
|
+
var HTTPRequestBuilder = _HTTPRequestBuilder;
|
|
93
321
|
|
|
94
322
|
// src/schema.map.ts
|
|
95
|
-
var
|
|
96
|
-
var
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
323
|
+
var _map;
|
|
324
|
+
var _SchemaMap = class _SchemaMap {
|
|
325
|
+
constructor(map) {
|
|
326
|
+
__privateAdd(this, _map, void 0);
|
|
327
|
+
if (map instanceof _SchemaMap) {
|
|
328
|
+
__privateSet(this, _map, new Map(__privateGet(map, _map)));
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
__privateSet(this, _map, new Map(map));
|
|
102
332
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (typeof arg === "number") {
|
|
106
|
-
this.registerSingle(parser, arg);
|
|
107
|
-
} else {
|
|
108
|
-
this.registerRange(parser, arg);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
return parser.parse;
|
|
333
|
+
derive() {
|
|
334
|
+
return new _SchemaMap(__privateGet(this, _map));
|
|
112
335
|
}
|
|
113
|
-
|
|
336
|
+
registerStatus(parser, ...codes) {
|
|
114
337
|
codes.forEach((code) => {
|
|
115
338
|
if (__privateGet(this, _map).has(code)) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
);
|
|
339
|
+
const msg = `Status code ${code} is already registered with a parser`;
|
|
340
|
+
throw new Error(msg);
|
|
119
341
|
}
|
|
120
|
-
assertIsStatusCode(code);
|
|
121
342
|
__privateGet(this, _map).set(code, parser);
|
|
122
343
|
});
|
|
123
344
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
registerRange(parser, ...range) {
|
|
129
|
-
range.forEach(({ from, to }) => {
|
|
130
|
-
assertIsStatusCode(from);
|
|
131
|
-
assertIsStatusCode(to);
|
|
132
|
-
for (let i = from; i <= to; i++) {
|
|
133
|
-
if (!IsStatusCode(i)) {
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
if (__privateGet(this, _map).has(i)) {
|
|
137
|
-
throw new import_errors.AutomationError(
|
|
138
|
-
`Status code ${i} is already registered with a parser`
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
__privateGet(this, _map).set(i, parser);
|
|
345
|
+
registerRange(parser, from, to) {
|
|
346
|
+
for (let i = from; i <= to; i++) {
|
|
347
|
+
if (__privateGet(this, _map).has(i)) {
|
|
348
|
+
throw new Error(`Status code ${i} is already registered with a parser`);
|
|
142
349
|
}
|
|
143
|
-
|
|
350
|
+
__privateGet(this, _map).set(i, parser);
|
|
351
|
+
}
|
|
144
352
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
return local;
|
|
353
|
+
validate(status, data, requireSchema) {
|
|
354
|
+
const parser = this.getParser(status, requireSchema);
|
|
355
|
+
if ("parse" in parser) {
|
|
356
|
+
return parser.parse(data);
|
|
150
357
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
throw new
|
|
161
|
-
|
|
162
|
-
|
|
358
|
+
if ("validate" in parser) {
|
|
359
|
+
return parser.validate(data);
|
|
360
|
+
}
|
|
361
|
+
try {
|
|
362
|
+
return parser(data);
|
|
363
|
+
} catch (e) {
|
|
364
|
+
const msg = `Failed to schema parse response data for status code ${status} with data:
|
|
365
|
+
|
|
366
|
+
${JSON.stringify(data, null, 2)}}`;
|
|
367
|
+
throw new Error(msg);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
getParser(status, requireSchema) {
|
|
371
|
+
const parser = __privateGet(this, _map).get(status);
|
|
372
|
+
if (!parser && requireSchema) {
|
|
373
|
+
const msg = `No parser registered for status code ${status} but 'requireSchema' is true`;
|
|
374
|
+
throw new Error(msg);
|
|
375
|
+
}
|
|
376
|
+
if (parser) {
|
|
377
|
+
return parser;
|
|
163
378
|
}
|
|
164
|
-
return
|
|
379
|
+
return (data) => data;
|
|
380
|
+
}
|
|
381
|
+
toObject() {
|
|
382
|
+
return Object.fromEntries(__privateGet(this, _map));
|
|
165
383
|
}
|
|
166
384
|
};
|
|
167
|
-
_children = new WeakMap();
|
|
168
385
|
_map = new WeakMap();
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
386
|
+
var SchemaMap = _SchemaMap;
|
|
387
|
+
|
|
388
|
+
// src/request-meta.config.ts
|
|
389
|
+
var MetaConfig = class {
|
|
390
|
+
constructor() {
|
|
391
|
+
this.onSend = [];
|
|
392
|
+
this.onReceive = [];
|
|
175
393
|
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
394
|
+
};
|
|
395
|
+
var _schemaMap, _requireSchema, _allowPlainText, _onBeforeSend, _onAfterSend, _throwOnServerError, _setOnSend, setOnSend_fn, _setOnReceive, setOnReceive_fn;
|
|
396
|
+
var _MetaConfigBuilder = class _MetaConfigBuilder {
|
|
397
|
+
constructor() {
|
|
398
|
+
__privateAdd(this, _setOnSend);
|
|
399
|
+
__privateAdd(this, _setOnReceive);
|
|
400
|
+
__privateAdd(this, _schemaMap, new SchemaMap());
|
|
401
|
+
__privateAdd(this, _requireSchema, false);
|
|
402
|
+
__privateAdd(this, _allowPlainText, false);
|
|
403
|
+
__privateAdd(this, _onBeforeSend, []);
|
|
404
|
+
__privateAdd(this, _onAfterSend, []);
|
|
405
|
+
__privateAdd(this, _throwOnServerError, false);
|
|
406
|
+
}
|
|
407
|
+
schemaMap(map) {
|
|
408
|
+
__privateSet(this, _schemaMap, map);
|
|
409
|
+
return this;
|
|
410
|
+
}
|
|
411
|
+
schema(parser, ...args) {
|
|
412
|
+
args.forEach((arg) => {
|
|
413
|
+
if (typeof arg === "number") {
|
|
414
|
+
__privateGet(this, _schemaMap).registerStatus(parser, arg);
|
|
415
|
+
} else {
|
|
416
|
+
__privateGet(this, _schemaMap).registerRange(parser, arg.from, arg.to);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
return this;
|
|
420
|
+
}
|
|
421
|
+
requireSchema(value) {
|
|
422
|
+
__privateSet(this, _requireSchema, value);
|
|
423
|
+
return this;
|
|
424
|
+
}
|
|
425
|
+
allowPlainText(value) {
|
|
426
|
+
__privateSet(this, _allowPlainText, value);
|
|
427
|
+
return this;
|
|
428
|
+
}
|
|
429
|
+
onBeforeSend(description, hook) {
|
|
430
|
+
__privateGet(this, _onBeforeSend).push([description, hook]);
|
|
431
|
+
return this;
|
|
432
|
+
}
|
|
433
|
+
throwOnServerError(value) {
|
|
434
|
+
__privateSet(this, _throwOnServerError, value);
|
|
435
|
+
return this;
|
|
436
|
+
}
|
|
437
|
+
onReceiveResponse(description, hook) {
|
|
438
|
+
__privateGet(this, _onAfterSend).push([description, hook]);
|
|
439
|
+
return this;
|
|
440
|
+
}
|
|
441
|
+
build() {
|
|
442
|
+
const config = new MetaConfig();
|
|
443
|
+
config.schemas = __privateGet(this, _schemaMap).derive();
|
|
444
|
+
config.requireSchema = __privateGet(this, _requireSchema);
|
|
445
|
+
config.allowPlainText = __privateGet(this, _allowPlainText);
|
|
446
|
+
config.onSend = __privateGet(this, _onBeforeSend);
|
|
447
|
+
config.onReceive = __privateGet(this, _onAfterSend);
|
|
448
|
+
return config;
|
|
449
|
+
}
|
|
450
|
+
derive() {
|
|
451
|
+
var _a, _b;
|
|
452
|
+
return __privateMethod(_b = __privateMethod(_a = new _MetaConfigBuilder().schemaMap(__privateGet(this, _schemaMap).derive()).requireSchema(__privateGet(this, _requireSchema)).allowPlainText(__privateGet(this, _allowPlainText)).throwOnServerError(__privateGet(this, _throwOnServerError)), _setOnSend, setOnSend_fn).call(_a, __privateGet(this, _onBeforeSend)), _setOnReceive, setOnReceive_fn).call(_b, __privateGet(this, _onAfterSend));
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
_schemaMap = new WeakMap();
|
|
456
|
+
_requireSchema = new WeakMap();
|
|
457
|
+
_allowPlainText = new WeakMap();
|
|
458
|
+
_onBeforeSend = new WeakMap();
|
|
459
|
+
_onAfterSend = new WeakMap();
|
|
460
|
+
_throwOnServerError = new WeakMap();
|
|
461
|
+
_setOnSend = new WeakSet();
|
|
462
|
+
setOnSend_fn = function(hooks) {
|
|
463
|
+
__privateSet(this, _onBeforeSend, hooks);
|
|
464
|
+
return this;
|
|
465
|
+
};
|
|
466
|
+
_setOnReceive = new WeakSet();
|
|
467
|
+
setOnReceive_fn = function(hooks) {
|
|
468
|
+
__privateSet(this, _onAfterSend, hooks);
|
|
469
|
+
return this;
|
|
470
|
+
};
|
|
471
|
+
var MetaConfigBuilder = _MetaConfigBuilder;
|
|
180
472
|
|
|
181
473
|
// src/transform-response.ts
|
|
182
|
-
var
|
|
474
|
+
var import_errors = require("@autometa/errors");
|
|
183
475
|
var import_assert_is_json = __toESM(require("@stdlib/assert-is-json"), 1);
|
|
184
476
|
var import_cli_highlight = require("cli-highlight");
|
|
185
477
|
function transformResponse(allowPlainText, data) {
|
|
@@ -195,12 +487,15 @@ function transformResponse(allowPlainText, data) {
|
|
|
195
487
|
if ((0, import_assert_is_json.default)(data)) {
|
|
196
488
|
return JSON.parse(data);
|
|
197
489
|
}
|
|
198
|
-
if (["true", "false"].includes(data)) {
|
|
490
|
+
if (typeof data === "string" && ["true", "false"].includes(data)) {
|
|
199
491
|
return JSON.parse(data);
|
|
200
492
|
}
|
|
201
|
-
if (/^\d*\.?\d+$/.test(data)) {
|
|
493
|
+
if (typeof data === "string" && /^\d*\.?\d+$/.test(data)) {
|
|
202
494
|
return JSON.parse(data);
|
|
203
495
|
}
|
|
496
|
+
if (typeof data === "object") {
|
|
497
|
+
return data;
|
|
498
|
+
}
|
|
204
499
|
if (allowPlainText) {
|
|
205
500
|
return data;
|
|
206
501
|
}
|
|
@@ -208,394 +503,606 @@ function transformResponse(allowPlainText, data) {
|
|
|
208
503
|
const message = [
|
|
209
504
|
`Could not parse a response as json, and this request was not configured to allow plain text responses.`,
|
|
210
505
|
`To allow plain text responses, use the 'allowPlainText' method on the HTTP client.`,
|
|
211
|
-
"
|
|
506
|
+
"",
|
|
212
507
|
response
|
|
213
508
|
];
|
|
214
|
-
throw new
|
|
509
|
+
throw new import_errors.AutomationError(message.join("\n"));
|
|
215
510
|
}
|
|
216
511
|
|
|
217
|
-
// src/
|
|
218
|
-
var
|
|
219
|
-
var
|
|
220
|
-
var
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
this
|
|
225
|
-
this
|
|
226
|
-
this
|
|
227
|
-
this
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
body:
|
|
255
|
-
${body}`;
|
|
256
|
-
__privateGet(this, _result).error = new import_errors3.AutomationError(message, { cause: e });
|
|
257
|
-
}
|
|
512
|
+
// src/http.ts
|
|
513
|
+
var import_errors2 = require("@autometa/errors");
|
|
514
|
+
var _request2, _metaConfig, _makeRequest, makeRequest_fn, _validateResponse, validateResponse_fn;
|
|
515
|
+
var HTTP = class {
|
|
516
|
+
constructor(client = defaultClientFactory(), builder = new HTTPRequestBuilder(), metaConfig = new MetaConfigBuilder()) {
|
|
517
|
+
this.client = client;
|
|
518
|
+
__privateAdd(this, _makeRequest);
|
|
519
|
+
__privateAdd(this, _validateResponse);
|
|
520
|
+
__privateAdd(this, _request2, void 0);
|
|
521
|
+
__privateAdd(this, _metaConfig, void 0);
|
|
522
|
+
__privateSet(this, _request2, builder.derive());
|
|
523
|
+
__privateSet(this, _metaConfig, metaConfig.derive());
|
|
524
|
+
}
|
|
525
|
+
static create(client = new AxiosClient(), builder = new HTTPRequestBuilder(), metaConfig = new MetaConfigBuilder()) {
|
|
526
|
+
return new HTTP(client, builder, metaConfig);
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Sets the base url of the request for this client, such as
|
|
530
|
+
* `https://api.example.com`, and could include always-used routes like
|
|
531
|
+
* the api version, such as `/v1` or `/api/v1` at the end.
|
|
532
|
+
*
|
|
533
|
+
* ```ts
|
|
534
|
+
*
|
|
535
|
+
* \@Fixture(INJECTION_SCOPE.TRANSIENT)
|
|
536
|
+
* export abstract class BaseClient {
|
|
537
|
+
* constructor(protected readonly http: HTTP) {
|
|
538
|
+
* this.http.url("https://api.example.com");
|
|
539
|
+
* }
|
|
540
|
+
* }
|
|
541
|
+
* ```
|
|
542
|
+
* @param url
|
|
543
|
+
* @returns
|
|
544
|
+
*/
|
|
545
|
+
url(url) {
|
|
546
|
+
__privateGet(this, _request2).url(url);
|
|
547
|
+
return this;
|
|
258
548
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
const message = `Failed to validate response from ${method}:${fullUrl}.
|
|
271
|
-
|
|
272
|
-
Provided body was:
|
|
273
|
-
${JSON.stringify(data, null, 2)}`;
|
|
274
|
-
__privateGet(this, _result).error = new import_errors3.AutomationError(message, { cause: error });
|
|
275
|
-
}
|
|
549
|
+
/**
|
|
550
|
+
* If set to true, all requests derived from this client will require a schema be defined
|
|
551
|
+
* matching any response status code. If set to false, a schema will still be used for validation
|
|
552
|
+
* if defined, or the unadulterated original body will be returned if no schema matches.
|
|
553
|
+
*
|
|
554
|
+
* @param required Whether or not a schema is required for all responses.
|
|
555
|
+
* @returns This instance of HTTP.
|
|
556
|
+
*/
|
|
557
|
+
requireSchema(required) {
|
|
558
|
+
__privateGet(this, _metaConfig).requireSchema(required);
|
|
559
|
+
return this;
|
|
276
560
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
561
|
+
/**
|
|
562
|
+
* If set to true, all requests derived from this client will allow plain text
|
|
563
|
+
* responses. If set to false, plain text responses will throw an serialization error.
|
|
564
|
+
*
|
|
565
|
+
* Useful when an endpoint returns a HTML or plain text response. If the plain text
|
|
566
|
+
* is the value of `true` or `false`, or a number, it will be parsed into the
|
|
567
|
+
* appropriate type.
|
|
568
|
+
*
|
|
569
|
+
* This method is a shared chain method, and will return the same instance of HTTP.
|
|
570
|
+
*
|
|
571
|
+
* @param allow Whether or not plain text responses are allowed.
|
|
572
|
+
* @returns This instance of HTTP.
|
|
573
|
+
*/
|
|
574
|
+
sharedAllowPlainText(allow) {
|
|
575
|
+
__privateGet(this, _metaConfig).allowPlainText(allow);
|
|
576
|
+
return this;
|
|
291
577
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
578
|
+
/**
|
|
579
|
+
* If set to true, all requests derived from this client will allow plain text
|
|
580
|
+
* responses. If set to false, plain text responses will throw an serialization error.
|
|
581
|
+
*
|
|
582
|
+
* Useful when an endpoint returns a HTML or plain text response. If the plain text
|
|
583
|
+
* is the value of `true` or `false`, or a number, it will be parsed into the
|
|
584
|
+
* appropriate type.
|
|
585
|
+
*
|
|
586
|
+
* This method is a request chain method, and will return a new instance of HTTP.
|
|
587
|
+
*
|
|
588
|
+
* @param allow Whether or not plain text responses are allowed.
|
|
589
|
+
* @returns A new child instance of HTTP derived from this one.
|
|
590
|
+
*/
|
|
591
|
+
allowPlainText(allow) {
|
|
592
|
+
return HTTP.create(
|
|
593
|
+
this.client,
|
|
594
|
+
__privateGet(this, _request2).derive(),
|
|
595
|
+
__privateGet(this, _metaConfig).derive().allowPlainText(allow)
|
|
308
596
|
);
|
|
309
597
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
598
|
+
/**
|
|
599
|
+
* Attaches a route to the request, such as `/product` or `/user`. Subsequent calls
|
|
600
|
+
* to this method will append the route to the existing route, such as `/product/1`.
|
|
601
|
+
*
|
|
602
|
+
* Numbers will be converted to strings automatically. Routes can be defined one
|
|
603
|
+
* at a time or as a spread argument.
|
|
604
|
+
*
|
|
605
|
+
* ```ts
|
|
606
|
+
* constructor(http: HTTP) {
|
|
607
|
+
* super(http);
|
|
608
|
+
* this.http.sharedRoute("user", id).get();
|
|
609
|
+
* }
|
|
610
|
+
*
|
|
611
|
+
* // or
|
|
612
|
+
*
|
|
613
|
+
* constructor(http: HTTP) {
|
|
614
|
+
* super(http);
|
|
615
|
+
* this.http
|
|
616
|
+
* .sharedRoute("user")
|
|
617
|
+
* .sharedRoute(id)
|
|
618
|
+
* .get();
|
|
619
|
+
* }
|
|
620
|
+
* ```
|
|
621
|
+
*
|
|
622
|
+
* This method is a shared chain method, and will return the same instance of HTTP. All
|
|
623
|
+
* child clients will inherit the routes defined by this method. Useful to configure
|
|
624
|
+
* in the constructor body.
|
|
625
|
+
*
|
|
626
|
+
* @param route A route or spread list of routes to append to the request.
|
|
627
|
+
* @returns This instance of HTTP.
|
|
628
|
+
*/
|
|
629
|
+
sharedRoute(...route) {
|
|
630
|
+
__privateGet(this, _request2).route(...route.map((r) => r.toString()));
|
|
334
631
|
return this;
|
|
335
632
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
633
|
+
/**
|
|
634
|
+
* Attaches a route to the request, such as `/product` or `/user`. Subsequent calls
|
|
635
|
+
* to this method will append the route to the existing route, such as `/product/1`.
|
|
636
|
+
*
|
|
637
|
+
* Numbers will be converted to strings automatically. Routes can be defined one
|
|
638
|
+
* at a time or as a spread argument.
|
|
639
|
+
*
|
|
640
|
+
* ```ts
|
|
641
|
+
* getUser(id: number) {
|
|
642
|
+
* return this.http.route("user", id).get();
|
|
643
|
+
* }
|
|
644
|
+
*
|
|
645
|
+
* // or
|
|
646
|
+
*
|
|
647
|
+
* getUser(id: number) {
|
|
648
|
+
* return this.http
|
|
649
|
+
* .route("user")
|
|
650
|
+
* .route(id)
|
|
651
|
+
* .get();
|
|
652
|
+
* }
|
|
653
|
+
* ```
|
|
654
|
+
*
|
|
655
|
+
* This method is a request chain method, and will return a new instance of HTTP, inheriting
|
|
656
|
+
* any routes previously defined and appending the new route. Useful to configure
|
|
657
|
+
* in class methods as part of finalizing a request.
|
|
658
|
+
*
|
|
659
|
+
* @param route A route or spread list of routes to append to the request.
|
|
660
|
+
* @returns A new child instance of HTTP derived from this one.
|
|
661
|
+
*/
|
|
662
|
+
route(...route) {
|
|
663
|
+
const mapped = route.map((r) => String(r));
|
|
664
|
+
return HTTP.create(this.client, __privateGet(this, _request2).derive().route(...mapped));
|
|
356
665
|
}
|
|
357
|
-
|
|
358
|
-
|
|
666
|
+
sharedSchema(parser, ...args) {
|
|
667
|
+
__privateGet(this, _metaConfig).schema(parser, ...args);
|
|
359
668
|
return this;
|
|
360
669
|
}
|
|
361
670
|
schema(parser, ...args) {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
return this;
|
|
671
|
+
return HTTP.create(
|
|
672
|
+
this.client,
|
|
673
|
+
__privateGet(this, _request2).derive(),
|
|
674
|
+
__privateGet(this, _metaConfig).derive().schema(parser, ...args)
|
|
675
|
+
);
|
|
368
676
|
}
|
|
369
|
-
|
|
370
|
-
__privateGet(this,
|
|
677
|
+
sharedParam(name, value) {
|
|
678
|
+
__privateGet(this, _request2).param(name, value);
|
|
371
679
|
return this;
|
|
372
680
|
}
|
|
373
|
-
|
|
374
|
-
|
|
681
|
+
/**
|
|
682
|
+
* `onSend` is a pre-request hook which will be executed in order of definition
|
|
683
|
+
* immediately before the request is sent. This hook can be used to analyze or
|
|
684
|
+
* log the request state.
|
|
685
|
+
*
|
|
686
|
+
* ```ts
|
|
687
|
+
*
|
|
688
|
+
* \@Fixture(INJECTION_SCOPE.TRANSIENT)
|
|
689
|
+
* export class UserController extends BaseController {
|
|
690
|
+
* constructor(private readonly http: HTTP) {
|
|
691
|
+
* super(http);
|
|
692
|
+
* this.http
|
|
693
|
+
* .sharedRoute("user")
|
|
694
|
+
* .sharedOnSend("log request",
|
|
695
|
+
* (request) => console.log(JSON.stringify(request, null, 2))
|
|
696
|
+
* );
|
|
697
|
+
* }
|
|
698
|
+
* }
|
|
699
|
+
* ```
|
|
700
|
+
*
|
|
701
|
+
* This method is a shared chain method, and will return the same instance of HTTP. All
|
|
702
|
+
* child clients will inherit the onSend hooks defined by this method. Useful to configure
|
|
703
|
+
* in the constructor body.
|
|
704
|
+
*
|
|
705
|
+
* @param description A description of the hook, used for debugging.
|
|
706
|
+
* @param hook The hook to execute.
|
|
707
|
+
* @returns This instance of HTTP.
|
|
708
|
+
*/
|
|
709
|
+
sharedOnSend(description, hook) {
|
|
710
|
+
__privateGet(this, _metaConfig).onBeforeSend(description, hook);
|
|
375
711
|
return this;
|
|
376
712
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
713
|
+
/**
|
|
714
|
+
* `onReceive` is a post-request hook which will be executed in order of definition
|
|
715
|
+
* immediately after the response is received. This hook can be used to analyze or
|
|
716
|
+
* log the response state.
|
|
717
|
+
*
|
|
718
|
+
* ```ts
|
|
719
|
+
*
|
|
720
|
+
* \@Fixture(INJECTION_SCOPE.TRANSIENT)
|
|
721
|
+
* export class UserController extends BaseController {
|
|
722
|
+
* constructor(private readonly http: HTTP) {
|
|
723
|
+
* super(http);
|
|
724
|
+
* this.http
|
|
725
|
+
* .sharedRoute("user")
|
|
726
|
+
* .sharedOnReceive("log response",
|
|
727
|
+
* (response) => console.log(JSON.stringify(response, null, 2))
|
|
728
|
+
* );
|
|
729
|
+
* }
|
|
730
|
+
* }
|
|
731
|
+
* ```
|
|
732
|
+
*
|
|
733
|
+
* This method is a shared chain method, and will return the same instance of HTTP. All
|
|
734
|
+
* child clients will inherit the onReceive hooks defined by this method. Useful to configure
|
|
735
|
+
* in the constructor body.
|
|
736
|
+
*
|
|
737
|
+
* @param description A description of the hook, used for debugging.
|
|
738
|
+
* @param hook The hook to execute.
|
|
739
|
+
* @returns This instance of HTTP.
|
|
740
|
+
*/
|
|
741
|
+
sharedOnReceive(description, hook) {
|
|
742
|
+
__privateGet(this, _metaConfig).onReceiveResponse(description, hook);
|
|
380
743
|
return this;
|
|
381
744
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
745
|
+
/**
|
|
746
|
+
* Attaches a query string parameter object to the request. Query string
|
|
747
|
+
* parameters are key-value pairs which are appended to the request url, such as
|
|
748
|
+
* `https://api.example.com?name=John&age=30`.
|
|
749
|
+
*
|
|
750
|
+
* This method is a shared chain method, and will return the same instance of HTTP. All
|
|
751
|
+
* child clients will inherit the query string parameters defined by this method. Useful to configure
|
|
752
|
+
* in the constructor body.
|
|
753
|
+
*
|
|
754
|
+
* ```ts
|
|
755
|
+
* constructor(http: HTTP) {
|
|
756
|
+
* super(http);
|
|
757
|
+
* this.http
|
|
758
|
+
* .sharedParams({ 'is-test': "true" })
|
|
759
|
+
* ```
|
|
760
|
+
* @param name The name of the query string parameter.
|
|
761
|
+
* @param value The value of the query string parameter.
|
|
762
|
+
* @returns This instance of HTTP.
|
|
763
|
+
*/
|
|
764
|
+
sharedParams(dict) {
|
|
765
|
+
__privateGet(this, _request2).params(dict);
|
|
386
766
|
return this;
|
|
387
767
|
}
|
|
768
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
388
769
|
param(name, value) {
|
|
389
|
-
__privateGet(this,
|
|
390
|
-
|
|
391
|
-
|
|
770
|
+
return HTTP.create(this.client, __privateGet(this, _request2).derive().param(name, value));
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* Attaches a query string parameter object to the request. Query string
|
|
774
|
+
* parameters are key-value pairs which are appended to the request url, such as
|
|
775
|
+
* `https://api.example.com?name=John&age=30`.
|
|
776
|
+
*
|
|
777
|
+
* This method is a shared chain method, and will return the same instance of HTTP. All
|
|
778
|
+
* child clients will inherit the query string parameters defined by this method. Useful to configure
|
|
779
|
+
* in the constructor body.
|
|
780
|
+
*
|
|
781
|
+
* ```ts
|
|
782
|
+
* getUser(id: number) {
|
|
783
|
+
* return this.http
|
|
784
|
+
* .route(id)
|
|
785
|
+
* .param({ name: "John", age: "30" })
|
|
786
|
+
*
|
|
787
|
+
* @param name The name of the query string parameter.
|
|
788
|
+
* @param value The value of the query string parameter.
|
|
789
|
+
* @returns This instance of HTTP.
|
|
790
|
+
*/
|
|
392
791
|
params(dict) {
|
|
393
|
-
|
|
792
|
+
__privateGet(this, _request2).params(dict);
|
|
793
|
+
return HTTP.create(this.client, __privateGet(this, _request2).derive().params(dict));
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Attaches a shared data payload to this client. The data payload is the body of the request,
|
|
797
|
+
* and can be any type. If the data payload is an object, it will be serialized to JSON.
|
|
798
|
+
*
|
|
799
|
+
* This method is a shared chain method, and will return the same instance of HTTP. All
|
|
800
|
+
* child clients will inherit the data payload defined by this method. Useful to configure
|
|
801
|
+
* in the constructor body.
|
|
802
|
+
*
|
|
803
|
+
* @param data The data payload to attach to the request.
|
|
804
|
+
* @returns This instance of HTTP.
|
|
805
|
+
*/
|
|
806
|
+
sharedData(data) {
|
|
807
|
+
__privateGet(this, _request2).data(data);
|
|
394
808
|
return this;
|
|
395
809
|
}
|
|
396
|
-
|
|
397
|
-
|
|
810
|
+
/**
|
|
811
|
+
* Attaches a shared header to this client. Headers are string:string key-value pairs which are
|
|
812
|
+
* sent with the request, such as `Content-Type: application/json`.
|
|
813
|
+
*
|
|
814
|
+
* Numbers, Booleans and Null will be converted to string values automatically.
|
|
815
|
+
*
|
|
816
|
+
* A Factory function can also be provided to generate the header value at the time of request.
|
|
817
|
+
*
|
|
818
|
+
* This method is a shared chain method, and will return the same instance of HTTP. All
|
|
819
|
+
* child clients will inherit the header defined by this method. Useful to configure
|
|
820
|
+
* in the constructor body.
|
|
821
|
+
*
|
|
822
|
+
* @param name The name of the header.
|
|
823
|
+
* @param value The value of the header.
|
|
824
|
+
*/
|
|
825
|
+
sharedHeader(name, value) {
|
|
826
|
+
__privateGet(this, _request2).header(name, value);
|
|
398
827
|
return this;
|
|
399
828
|
}
|
|
400
|
-
|
|
401
|
-
return this.
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
829
|
+
header(name, value) {
|
|
830
|
+
return HTTP.create(this.client, __privateGet(this, _request2).derive().header(name, value));
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Attaches a data payload to this request. The data payload is the body of the request,
|
|
834
|
+
* and can be any type. If the data payload is an object, it will be serialized to JSON.
|
|
835
|
+
*
|
|
836
|
+
* This method is a request chain method, and will return a new instance of HTTP, inheriting
|
|
837
|
+
* any data payload previously defined and appending the new payload. Useful to configure
|
|
838
|
+
* in class methods as part of finalizing a request.
|
|
839
|
+
*
|
|
840
|
+
* @param data The data payload to attach to the request.
|
|
841
|
+
* @returns A new child instance of HTTP derived from this one.
|
|
842
|
+
*/
|
|
843
|
+
data(data) {
|
|
844
|
+
__privateGet(this, _request2).data(data);
|
|
845
|
+
return HTTP.create(this.client, __privateGet(this, _request2).derive().data(data));
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* `onSend` is a pre-request hook which will be executed in order of definition
|
|
849
|
+
* immediately before the request is sent. This hook can be used to modify the request,
|
|
850
|
+
* or to log the state of a request before final send-off.
|
|
851
|
+
*
|
|
852
|
+
* ```ts
|
|
853
|
+
*
|
|
854
|
+
* \@Fixture(INJECTION_SCOPE.TRANSIENT)
|
|
855
|
+
* export class UserController extends BaseController {
|
|
856
|
+
* constructor(private readonly http: HTTP) {
|
|
857
|
+
* super(http);
|
|
858
|
+
* }
|
|
859
|
+
*
|
|
860
|
+
* getUser(id: number) {
|
|
861
|
+
* return this.http
|
|
862
|
+
* .route(id)
|
|
863
|
+
* .onSend("log request",
|
|
864
|
+
* (request) => console.log(JSON.stringify(request, null, 2)
|
|
865
|
+
* )
|
|
866
|
+
* .get();
|
|
867
|
+
* }
|
|
868
|
+
* ```
|
|
869
|
+
*
|
|
870
|
+
* This method is a request chain method, and will return a new instance of HTTP, inheriting
|
|
871
|
+
* any onSend hooks previously defined and appending the new hook. Useful to configure
|
|
872
|
+
* in class methods as part of finalizing a request.
|
|
873
|
+
*
|
|
874
|
+
* @param description A description of the hook, used for debugging.
|
|
875
|
+
* @param hook The hook to execute.
|
|
876
|
+
* @returns A new child instance of HTTP derived from this one.
|
|
877
|
+
*/
|
|
878
|
+
onSend(description, hook) {
|
|
879
|
+
return HTTP.create(
|
|
880
|
+
this.client,
|
|
881
|
+
__privateGet(this, _request2).derive(),
|
|
882
|
+
__privateGet(this, _metaConfig).derive().onBeforeSend(description, hook)
|
|
883
|
+
);
|
|
414
884
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
885
|
+
/**
|
|
886
|
+
* `onReceive` is a post-request hook which will be executed in order of definition
|
|
887
|
+
* immediately after the response is received. This hook can be used to modify the response,
|
|
888
|
+
* or to log the state of a response after it is received.
|
|
889
|
+
*
|
|
890
|
+
* ```ts
|
|
891
|
+
*
|
|
892
|
+
* \@Fixture(INJECTION_SCOPE.TRANSIENT)
|
|
893
|
+
* export class UserController extends BaseController {
|
|
894
|
+
* constructor(private readonly http: HTTP) {
|
|
895
|
+
* super(http);
|
|
896
|
+
* }
|
|
897
|
+
*
|
|
898
|
+
* getUser(id: number) {
|
|
899
|
+
* return this.http
|
|
900
|
+
* .route(id)
|
|
901
|
+
* .onReceive("log response",
|
|
902
|
+
* (response) => console.log(JSON.stringify(response, null, 2)
|
|
903
|
+
* )
|
|
904
|
+
* .get();
|
|
905
|
+
* }
|
|
906
|
+
* ```
|
|
907
|
+
*
|
|
908
|
+
* This method is a request chain method, and will return a new instance of HTTP, inheriting
|
|
909
|
+
* any onReceive hooks previously defined and appending the new hook. Useful to configure
|
|
910
|
+
* in class methods as part of finalizing a request.
|
|
911
|
+
*
|
|
912
|
+
* @param description A description of the hook, used for debugging.
|
|
913
|
+
* @param hook The hook to execute.
|
|
914
|
+
* @returns A new child instance of HTTP derived from this one.
|
|
915
|
+
*/
|
|
916
|
+
onReceive(description, hook) {
|
|
917
|
+
return HTTP.create(
|
|
918
|
+
this.client,
|
|
919
|
+
__privateGet(this, _request2).derive(),
|
|
920
|
+
__privateGet(this, _metaConfig).derive().onReceiveResponse(description, hook)
|
|
424
921
|
);
|
|
425
|
-
await executor.tryRequest();
|
|
426
|
-
if (executor.requestSucceeded && !executor.validationFailed) {
|
|
427
|
-
const response = executor.getValidatedResponse();
|
|
428
|
-
this.tryRunAfterHooks(response);
|
|
429
|
-
return response;
|
|
430
|
-
}
|
|
431
|
-
if (executor.requestSucceeded) {
|
|
432
|
-
const response = executor.getResponse();
|
|
433
|
-
this.tryRunAfterHooks(response);
|
|
434
|
-
}
|
|
435
|
-
throw executor.error;
|
|
436
|
-
}
|
|
437
|
-
constructOptions(method) {
|
|
438
|
-
const url = this.currentUrl;
|
|
439
|
-
const headers = __privateGet(this, _headers) && Object.fromEntries(__privateGet(this, _headers));
|
|
440
|
-
const responseType = __privateGet(this, _responseType);
|
|
441
|
-
const data = __privateGet(this, _data);
|
|
442
|
-
return {
|
|
443
|
-
method,
|
|
444
|
-
url,
|
|
445
|
-
headers,
|
|
446
|
-
data,
|
|
447
|
-
responseType,
|
|
448
|
-
validateStatus: function(status) {
|
|
449
|
-
return status >= 100 && status < 500;
|
|
450
|
-
},
|
|
451
|
-
transformResponse: transformResponse.bind(null, __privateGet(this, _allowPlainText))
|
|
452
|
-
};
|
|
453
922
|
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
923
|
+
/**
|
|
924
|
+
* Executes the current request state as a GET request.
|
|
925
|
+
*
|
|
926
|
+
* @param options Additional options to pass to the underlying http client, such
|
|
927
|
+
* as e.g Axios configuration values.
|
|
928
|
+
* @returns A promise which resolves to the response.
|
|
929
|
+
*/
|
|
930
|
+
get(options) {
|
|
931
|
+
return __privateMethod(this, _makeRequest, makeRequest_fn).call(this, __privateGet(this, _request2).derive().method("GET"), options);
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Executes the current request state as a POST request.
|
|
935
|
+
*
|
|
936
|
+
* @param data The data payload to attach to the request.
|
|
937
|
+
* @param options Additional options to pass to the underlying http client, such
|
|
938
|
+
* as e.g Axios configuration values.
|
|
939
|
+
* @returns A promise which resolves to the response.
|
|
940
|
+
*/
|
|
941
|
+
post(options) {
|
|
942
|
+
return __privateMethod(this, _makeRequest, makeRequest_fn).call(this, __privateGet(this, _request2).derive().method("POST"), options);
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* Executes the current request state as a DELETE request.
|
|
946
|
+
*
|
|
947
|
+
* @param options Additional options to pass to the underlying http client, such
|
|
948
|
+
* as e.g Axios configuration values.
|
|
949
|
+
* @returns A promise which resolves to the response.
|
|
950
|
+
* as e.g Axios configuration values.
|
|
951
|
+
*/
|
|
952
|
+
delete(options) {
|
|
953
|
+
return __privateMethod(this, _makeRequest, makeRequest_fn).call(this, __privateGet(this, _request2).derive().method("DELETE"), options);
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Executes the current request state as a PUT request.
|
|
957
|
+
*
|
|
958
|
+
* @param options Additional options to pass to the underlying http client, such
|
|
959
|
+
* as e.g Axios configuration values.
|
|
960
|
+
* @returns A promise which resolves to the response.
|
|
961
|
+
*/
|
|
962
|
+
put(options) {
|
|
963
|
+
return __privateMethod(this, _makeRequest, makeRequest_fn).call(this, __privateGet(this, _request2).derive().method("PUT"), options);
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Executes the current request state as a PATCH request.
|
|
967
|
+
*
|
|
968
|
+
* @param options Additional options to pass to the underlying http client, such
|
|
969
|
+
* as e.g Axios configuration values.
|
|
970
|
+
* @returns A promise which resolves to the response.
|
|
971
|
+
*/
|
|
972
|
+
patch(options) {
|
|
973
|
+
return __privateMethod(this, _makeRequest, makeRequest_fn).call(this, __privateGet(this, _request2).derive().method("PATCH"), options);
|
|
974
|
+
}
|
|
975
|
+
head(options) {
|
|
976
|
+
return __privateMethod(this, _makeRequest, makeRequest_fn).call(this, __privateGet(this, _request2).derive().method("HEAD"), options);
|
|
977
|
+
}
|
|
978
|
+
options(options) {
|
|
979
|
+
return __privateMethod(this, _makeRequest, makeRequest_fn).call(this, __privateGet(this, _request2).derive().method("OPTIONS"), options);
|
|
980
|
+
}
|
|
981
|
+
trace(options) {
|
|
982
|
+
return __privateMethod(this, _makeRequest, makeRequest_fn).call(this, __privateGet(this, _request2).derive().method("TRACE"), options);
|
|
983
|
+
}
|
|
984
|
+
connect(options) {
|
|
985
|
+
return __privateMethod(this, _makeRequest, makeRequest_fn).call(this, __privateGet(this, _request2).derive().method("CONNECT"), options);
|
|
986
|
+
}
|
|
987
|
+
async runOnSendHooks(meta, request) {
|
|
988
|
+
for (const [description, hook] of meta.onSend) {
|
|
989
|
+
try {
|
|
990
|
+
await hook(request);
|
|
991
|
+
} catch (e) {
|
|
992
|
+
const cause = e;
|
|
993
|
+
const msg = `An error occurred while sending a request in hook: '${description}'`;
|
|
994
|
+
throw new import_errors2.AutomationError(msg, { cause });
|
|
460
995
|
}
|
|
461
|
-
} catch (e) {
|
|
462
|
-
const error = e;
|
|
463
|
-
const message = `HTTP Client 'onBeforeRequest' experienced an error at listener count ${index}`;
|
|
464
|
-
throw new import_errors4.AutomationError(message, { cause: error });
|
|
465
996
|
}
|
|
466
997
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
998
|
+
async runOnReceiveHooks(meta, response) {
|
|
999
|
+
for (const [description, hook] of meta.onReceive) {
|
|
1000
|
+
try {
|
|
1001
|
+
await hook(response);
|
|
1002
|
+
} catch (e) {
|
|
1003
|
+
const cause = e;
|
|
1004
|
+
const msg = `An error occurred while receiving a response in hook: '${description}'`;
|
|
1005
|
+
throw new import_errors2.AutomationError(msg, { cause });
|
|
473
1006
|
}
|
|
474
|
-
} catch (e) {
|
|
475
|
-
const error = e;
|
|
476
|
-
const message = `HTTP Client 'onRequestReceived' experienced an error at listener count ${index}`;
|
|
477
|
-
throw new import_errors4.AutomationError(message, { cause: error });
|
|
478
1007
|
}
|
|
479
1008
|
}
|
|
480
1009
|
};
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
1010
|
+
_request2 = new WeakMap();
|
|
1011
|
+
_metaConfig = new WeakMap();
|
|
1012
|
+
_makeRequest = new WeakSet();
|
|
1013
|
+
makeRequest_fn = async function(builder, options) {
|
|
1014
|
+
const request = builder.resolveDynamicHeaders().build();
|
|
1015
|
+
const meta = __privateGet(this, _metaConfig).derive().build();
|
|
1016
|
+
await this.runOnSendHooks(meta, request);
|
|
1017
|
+
const result = await this.client.request(request, options);
|
|
1018
|
+
result.data = transformResponse(meta.allowPlainText, result.data);
|
|
1019
|
+
await this.runOnReceiveHooks(meta, result);
|
|
1020
|
+
const validated = __privateMethod(this, _validateResponse, validateResponse_fn).call(this, result, meta);
|
|
1021
|
+
return validated;
|
|
1022
|
+
};
|
|
1023
|
+
_validateResponse = new WeakSet();
|
|
1024
|
+
validateResponse_fn = function(response, meta) {
|
|
1025
|
+
const { status, data } = response;
|
|
1026
|
+
const validated = meta.schemas.validate(
|
|
1027
|
+
status,
|
|
1028
|
+
data,
|
|
1029
|
+
meta.requireSchema
|
|
1030
|
+
);
|
|
1031
|
+
response.data = validated;
|
|
1032
|
+
return response;
|
|
1033
|
+
};
|
|
1034
|
+
HTTP = __decorateClass([
|
|
494
1035
|
(0, import_injection.Fixture)(import_injection.INJECTION_SCOPE.TRANSIENT)
|
|
495
|
-
],
|
|
1036
|
+
], HTTP);
|
|
496
1037
|
|
|
497
|
-
// src/
|
|
498
|
-
var
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
__privateAdd(this, _schemaMap2, new SchemaMap());
|
|
506
|
-
__privateAdd(this, _onBeforeSend2, []);
|
|
507
|
-
__privateAdd(this, _onAfterSend2, []);
|
|
508
|
-
__privateAdd(this, _allowPlainText2, false);
|
|
509
|
-
}
|
|
510
|
-
allowPlainText(value) {
|
|
511
|
-
__privateSet(this, _allowPlainText2, value);
|
|
512
|
-
return this;
|
|
513
|
-
}
|
|
514
|
-
requireSchema(value) {
|
|
515
|
-
__privateSet(this, _requireSchema2, value);
|
|
516
|
-
return this;
|
|
517
|
-
}
|
|
518
|
-
url(url) {
|
|
519
|
-
__privateSet(this, _url2, url);
|
|
520
|
-
return this;
|
|
521
|
-
}
|
|
522
|
-
sharedOnBeforeSend(hook) {
|
|
523
|
-
__privateGet(this, _onBeforeSend2).push(hook);
|
|
524
|
-
return this;
|
|
525
|
-
}
|
|
526
|
-
sharedOnReceiveResponse(hook) {
|
|
527
|
-
__privateGet(this, _onAfterSend2).push(hook);
|
|
528
|
-
return this;
|
|
529
|
-
}
|
|
530
|
-
onBeforeSend(hook) {
|
|
531
|
-
return this.builder().onBeforeSend(hook);
|
|
532
|
-
}
|
|
533
|
-
onReceiveResponse(hook) {
|
|
534
|
-
return this.builder().onReceivedResponse(hook);
|
|
535
|
-
}
|
|
536
|
-
sharedSchema(parser, ...args) {
|
|
537
|
-
__privateGet(this, _schemaMap2).register(parser, ...args);
|
|
538
|
-
return this;
|
|
539
|
-
}
|
|
540
|
-
schema(parser, ...args) {
|
|
541
|
-
return this.builder().schema(parser, ...args);
|
|
542
|
-
}
|
|
543
|
-
sharedRoute(...route) {
|
|
544
|
-
__privateGet(this, _route2).push(...route);
|
|
545
|
-
return this;
|
|
546
|
-
}
|
|
547
|
-
param(name, value) {
|
|
548
|
-
return this.builder().param(name, value);
|
|
549
|
-
}
|
|
550
|
-
params(dict) {
|
|
551
|
-
return this.builder().params(dict);
|
|
552
|
-
}
|
|
553
|
-
data(data) {
|
|
554
|
-
return this.builder().data(data);
|
|
1038
|
+
// src/default-schema.ts
|
|
1039
|
+
var import_assert_is_json2 = __toESM(require("@stdlib/assert-is-json"), 1);
|
|
1040
|
+
function AnySchema(data) {
|
|
1041
|
+
return data;
|
|
1042
|
+
}
|
|
1043
|
+
function EmptySchema(data) {
|
|
1044
|
+
if (data !== null && data !== void 0 && data !== "null") {
|
|
1045
|
+
throw new Error(`Expected null but got <${typeof data}> for ${data}`);
|
|
555
1046
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
1047
|
+
return data === "null" ? null : data;
|
|
1048
|
+
}
|
|
1049
|
+
function NullSchema(data) {
|
|
1050
|
+
if (data !== null && data !== "null") {
|
|
1051
|
+
throw new Error(`Expected null but got <${typeof data}> for ${data}`);
|
|
559
1052
|
}
|
|
560
|
-
|
|
561
|
-
|
|
1053
|
+
return null;
|
|
1054
|
+
}
|
|
1055
|
+
function UndefinedSchema(data) {
|
|
1056
|
+
if (data !== void 0) {
|
|
1057
|
+
throw new Error(`Expected undefined but got <${typeof data}> for ${data}`);
|
|
562
1058
|
}
|
|
563
|
-
|
|
564
|
-
|
|
1059
|
+
return void 0;
|
|
1060
|
+
}
|
|
1061
|
+
function BooleanSchema(data) {
|
|
1062
|
+
if (!(typeof data === "boolean") && ["true", "false"].includes(String(data)) === false) {
|
|
1063
|
+
throw new Error(`Expected boolean but got <${typeof data}> for ${data}`);
|
|
565
1064
|
}
|
|
566
|
-
|
|
567
|
-
|
|
1065
|
+
return JSON.parse(data);
|
|
1066
|
+
}
|
|
1067
|
+
function NumberSchema(data) {
|
|
1068
|
+
if (!(typeof data === "number") && /^\d*\.?\d+$/.test(String(data)) === false) {
|
|
1069
|
+
throw new Error(`Expected number but got <${typeof data}> for ${data}`);
|
|
568
1070
|
}
|
|
569
|
-
|
|
570
|
-
|
|
1071
|
+
return JSON.parse(data);
|
|
1072
|
+
}
|
|
1073
|
+
function StringSchema(data) {
|
|
1074
|
+
if (typeof data !== "string") {
|
|
1075
|
+
throw new Error(`Expected string but got <${typeof data}> for ${data}`);
|
|
571
1076
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
1077
|
+
return data;
|
|
1078
|
+
}
|
|
1079
|
+
function JSONSchema(data) {
|
|
1080
|
+
if (typeof data === "object") {
|
|
1081
|
+
return data;
|
|
575
1082
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
for (const [key, value] of __privateGet(this, _headers2).entries()) {
|
|
579
|
-
dict[key] = typeof value === "string" ? value : value();
|
|
580
|
-
}
|
|
581
|
-
return dict;
|
|
1083
|
+
if (!(0, import_assert_is_json2.default)(data)) {
|
|
1084
|
+
throw new Error(`Expected JSON but got <${typeof data}> for ${data}`);
|
|
582
1085
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
_headers2 = new WeakMap();
|
|
587
|
-
_requireSchema2 = new WeakMap();
|
|
588
|
-
_schemaMap2 = new WeakMap();
|
|
589
|
-
_onBeforeSend2 = new WeakMap();
|
|
590
|
-
_onAfterSend2 = new WeakMap();
|
|
591
|
-
_allowPlainText2 = new WeakMap();
|
|
592
|
-
HTTP = __decorateClass([
|
|
593
|
-
(0, import_injection2.Fixture)(import_injection2.INJECTION_SCOPE.TRANSIENT)
|
|
594
|
-
], HTTP);
|
|
1086
|
+
const result = JSON.parse(data);
|
|
1087
|
+
return result;
|
|
1088
|
+
}
|
|
595
1089
|
// Annotate the CommonJS export names for ESM import in node:
|
|
596
1090
|
0 && (module.exports = {
|
|
597
|
-
|
|
1091
|
+
AnySchema,
|
|
1092
|
+
AxiosClient,
|
|
1093
|
+
BooleanSchema,
|
|
1094
|
+
EmptySchema,
|
|
598
1095
|
HTTP,
|
|
599
|
-
|
|
1096
|
+
HTTPClient,
|
|
1097
|
+
HTTPRequest,
|
|
1098
|
+
HTTPRequestBuilder,
|
|
1099
|
+
HTTPResponse,
|
|
1100
|
+
HTTPResponseBuilder,
|
|
1101
|
+
JSONSchema,
|
|
1102
|
+
NullSchema,
|
|
1103
|
+
NumberSchema,
|
|
1104
|
+
StringSchema,
|
|
1105
|
+
UndefinedSchema,
|
|
1106
|
+
defaultClient
|
|
600
1107
|
});
|
|
601
1108
|
//# sourceMappingURL=index.js.map
|