@villedemontreal/http-request 7.4.4
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/LICENSE +21 -0
- package/README.md +216 -0
- package/dist/src/config/configs.d.ts +38 -0
- package/dist/src/config/configs.js +63 -0
- package/dist/src/config/configs.js.map +1 -0
- package/dist/src/config/constants.d.ts +40 -0
- package/dist/src/config/constants.js +40 -0
- package/dist/src/config/constants.js.map +1 -0
- package/dist/src/config/init.d.ts +22 -0
- package/dist/src/config/init.js +50 -0
- package/dist/src/config/init.js.map +1 -0
- package/dist/src/httpUtils.d.ts +131 -0
- package/dist/src/httpUtils.js +363 -0
- package/dist/src/httpUtils.js.map +1 -0
- package/dist/src/httpUtils.test.d.ts +1 -0
- package/dist/src/httpUtils.test.js +628 -0
- package/dist/src/httpUtils.test.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +24 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/utils/logger.d.ts +11 -0
- package/dist/src/utils/logger.js +54 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/testingConfigurations.d.ts +9 -0
- package/dist/src/utils/testingConfigurations.js +18 -0
- package/dist/src/utils/testingConfigurations.js.map +1 -0
- package/package.json +67 -0
- package/src/config/configs.ts +74 -0
- package/src/config/constants.ts +54 -0
- package/src/config/init.ts +55 -0
- package/src/httpUtils.test.ts +764 -0
- package/src/httpUtils.ts +405 -0
- package/src/index.ts +8 -0
- package/src/utils/logger.ts +53 -0
- package/src/utils/testingConfigurations.ts +14 -0
package/src/httpUtils.ts
ADDED
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import { IOrderBy, OrderByDirection, Timer, utils } from '@villedemontreal/general-utils';
|
|
2
|
+
import { Request } from 'express';
|
|
3
|
+
import httpHeaderFieldsTyped from 'http-header-fields-typed';
|
|
4
|
+
import * as _ from 'lodash';
|
|
5
|
+
import * as superagent from 'superagent';
|
|
6
|
+
import { configs } from './config/configs';
|
|
7
|
+
import { constants } from './config/constants';
|
|
8
|
+
import { createLogger } from './utils/logger';
|
|
9
|
+
|
|
10
|
+
const logger = createLogger('HttpUtils');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* HTTP utilities
|
|
14
|
+
*/
|
|
15
|
+
export class HttpUtils {
|
|
16
|
+
private readonly REQ_PARAMS_LOWERCASED = '__queryParamsLowercased';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Remove first and last slash of the string unless the string is the part after protocol (http://)
|
|
20
|
+
*/
|
|
21
|
+
public removeSlashes(text: string) {
|
|
22
|
+
if (text) {
|
|
23
|
+
let start;
|
|
24
|
+
let end: number;
|
|
25
|
+
start = 0;
|
|
26
|
+
while (start < text.length && text[start] === '/') {
|
|
27
|
+
start++;
|
|
28
|
+
}
|
|
29
|
+
end = text.length - 1;
|
|
30
|
+
while (end > start && text[end] === '/') {
|
|
31
|
+
end--;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let result = text.substring(start, end + 1);
|
|
35
|
+
// handle exception of the protocol that's followed with 2 slashes after the semi-colon.
|
|
36
|
+
if (result && result[result.length - 1] === ':') {
|
|
37
|
+
result += '/';
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
return text;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Join few parts of an url to a final string
|
|
46
|
+
*/
|
|
47
|
+
public urlJoin(...args: string[]) {
|
|
48
|
+
return _.map(args, this.removeSlashes)
|
|
49
|
+
.filter(x => !!x)
|
|
50
|
+
.join('/');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Sends a HTTP request built with Superagent.
|
|
55
|
+
*
|
|
56
|
+
* Will add the proper Correlation Id and will write
|
|
57
|
+
* useful logs.
|
|
58
|
+
*
|
|
59
|
+
* IMPORTANT : this method does NOT throw an Error on a
|
|
60
|
+
* 4XX-5XX status response! It will return it the same way
|
|
61
|
+
* it returns a 200 response and it is up to the calling code
|
|
62
|
+
* to validate the actual response's status. For example
|
|
63
|
+
* by using :
|
|
64
|
+
*
|
|
65
|
+
* if(response.ok) {...}
|
|
66
|
+
*
|
|
67
|
+
* and/or by checking the status :
|
|
68
|
+
*
|
|
69
|
+
* if(response.status === 404) {...}
|
|
70
|
+
*
|
|
71
|
+
* An error will be thrown only when a network problem occures or
|
|
72
|
+
* if the target server can't be reached.
|
|
73
|
+
*
|
|
74
|
+
* This is different from SuperAgent's default behavior that DOES
|
|
75
|
+
* throw an error on 4XX-5XX status responses.
|
|
76
|
+
*
|
|
77
|
+
*/
|
|
78
|
+
public async send(request: superagent.SuperAgentRequest): Promise<superagent.Response> {
|
|
79
|
+
if (_.isNil(request)) {
|
|
80
|
+
throw new Error(`The request object can't be empty`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if ('status' in request) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
`The request object must be of type SuperAgentRequest. Make sure this object has NOT already been awaited ` +
|
|
86
|
+
`prior to being passed here!`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (!request.url || request.url.indexOf('://') < 0) {
|
|
91
|
+
throw new Error(`The URL in your request MUST have a protocol and a hostname. Received: ${request.url}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (utils.isBlank(request.get(httpHeaderFieldsTyped.X_CORRELATION_ID))) {
|
|
95
|
+
const cid = configs.correlationId;
|
|
96
|
+
if (!utils.isBlank(cid)) {
|
|
97
|
+
request.set(httpHeaderFieldsTyped.X_CORRELATION_ID, cid);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ==========================================
|
|
102
|
+
// Adds timeouts, if they are not already set.
|
|
103
|
+
// ==========================================
|
|
104
|
+
const responseTimeoutRequestVarName = '_responseTimeout';
|
|
105
|
+
const timeoutRequestVarName = '_timeout';
|
|
106
|
+
request.timeout({
|
|
107
|
+
response:
|
|
108
|
+
request[responseTimeoutRequestVarName] !== undefined
|
|
109
|
+
? request[responseTimeoutRequestVarName]
|
|
110
|
+
: constants.request.timeoutsDefault.response,
|
|
111
|
+
deadline:
|
|
112
|
+
request[timeoutRequestVarName] !== undefined
|
|
113
|
+
? request[timeoutRequestVarName]
|
|
114
|
+
: constants.request.timeoutsDefault.deadline
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
logger.debug({
|
|
118
|
+
sendingCorrelationIdHeader: request.get(httpHeaderFieldsTyped.X_CORRELATION_ID) || null,
|
|
119
|
+
url: request.url,
|
|
120
|
+
method: request.method,
|
|
121
|
+
msg: `Http Client - Start request to ${request.method} ${request.url}`
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
let result;
|
|
125
|
+
const timer = new Timer();
|
|
126
|
+
try {
|
|
127
|
+
result = await request;
|
|
128
|
+
} catch (err) {
|
|
129
|
+
// ==========================================
|
|
130
|
+
// SuperAgent throws a error on 4XX/5XX status responses...
|
|
131
|
+
// But we prefere to return those responses as regular
|
|
132
|
+
// ones and leave it to the caling code to validate
|
|
133
|
+
// the status! That way, we can differenciate between
|
|
134
|
+
// a 4XX/5XX result and a *real* error, for example if
|
|
135
|
+
// the request can't be sent because of a network
|
|
136
|
+
// error....
|
|
137
|
+
// ==========================================
|
|
138
|
+
if (err.status && err.response) {
|
|
139
|
+
result = err.response;
|
|
140
|
+
} else {
|
|
141
|
+
// ==========================================
|
|
142
|
+
// Real error!
|
|
143
|
+
// ==========================================
|
|
144
|
+
logger.debug({
|
|
145
|
+
error: err,
|
|
146
|
+
url: request.url,
|
|
147
|
+
method: request.method,
|
|
148
|
+
timeTaken: timer.toString(),
|
|
149
|
+
msg: `Http Client - End request ERROR request to ${request.method} ${request.url}`
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
throw {
|
|
153
|
+
msg: `An error occured while making the HTTP request to ${request.method} ${request.url}`,
|
|
154
|
+
originalError: err
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
logger.debug({
|
|
160
|
+
url: request.url,
|
|
161
|
+
method: request.method,
|
|
162
|
+
statusCode: result.status,
|
|
163
|
+
timeTaken: timer.toString(),
|
|
164
|
+
msg: `Http Client - End request to ${request.method} ${request.url}`
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Gets all the values of a querystring parameter.
|
|
172
|
+
* Manages the fact that we may use insensitive routing.
|
|
173
|
+
*
|
|
174
|
+
* A querystring parameter may indeed contains multiple values. For
|
|
175
|
+
* example : "path?name=aaa&name=bbb" will result in an
|
|
176
|
+
* *array* when getting the "name" parameter : ['aaa', 'bbb'].
|
|
177
|
+
*
|
|
178
|
+
* @returns all the values of the parameters as an array (even if
|
|
179
|
+
* only one value is found) or an empty array if none are found.
|
|
180
|
+
*/
|
|
181
|
+
public getQueryParamAll(req: Request, key: string): string[] {
|
|
182
|
+
if (!req || !req.query || !key) {
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ==========================================
|
|
187
|
+
// URL parsing is case sensitive. We can
|
|
188
|
+
// directly return the params as an array here.
|
|
189
|
+
// ==========================================
|
|
190
|
+
if (configs.isUrlCaseSensitive) {
|
|
191
|
+
return this.getOriginalQueryParamAsArray(req, key);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ==========================================
|
|
195
|
+
// The URL parsing is case *insensitive* here.
|
|
196
|
+
// We need more work to make sure we merge
|
|
197
|
+
// params in a case insensitive manner.
|
|
198
|
+
// ==========================================
|
|
199
|
+
if (!req[this.REQ_PARAMS_LOWERCASED]) {
|
|
200
|
+
req[this.REQ_PARAMS_LOWERCASED] = [];
|
|
201
|
+
Object.keys(req.query).forEach((keyExisting: string) => {
|
|
202
|
+
const keyLower = keyExisting.toLowerCase();
|
|
203
|
+
|
|
204
|
+
if (keyLower in req[this.REQ_PARAMS_LOWERCASED]) {
|
|
205
|
+
req[this.REQ_PARAMS_LOWERCASED][keyLower].push(req.query[keyExisting]);
|
|
206
|
+
} else {
|
|
207
|
+
let val = req.query[keyExisting];
|
|
208
|
+
if (!_.isArray(val)) {
|
|
209
|
+
val = [val] as string[];
|
|
210
|
+
}
|
|
211
|
+
req[this.REQ_PARAMS_LOWERCASED][keyLower] = val;
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const values = req[this.REQ_PARAMS_LOWERCASED][key.toLowerCase()];
|
|
217
|
+
return values || [];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Get the last value of a querystring parameter.
|
|
222
|
+
* Manages the fact that we may use insensitive routing.
|
|
223
|
+
*
|
|
224
|
+
* A querystring parameter may indeed contains multiple values. For
|
|
225
|
+
* example : "path?name=aaa&name=bbb" will result in an
|
|
226
|
+
* *array* when getting the "name" parameter : ['aaa', 'bbb'].
|
|
227
|
+
*
|
|
228
|
+
* In many situation, we only want to deal withy a single value.
|
|
229
|
+
* This function return the last value of a query param.
|
|
230
|
+
*
|
|
231
|
+
* @returns the last parameter with that key or `undefined` if
|
|
232
|
+
* not found.
|
|
233
|
+
*/
|
|
234
|
+
public getQueryParamOne(req: Request, key: string): string {
|
|
235
|
+
const values = this.getQueryParamAll(req, key);
|
|
236
|
+
if (!values || values.length === 0) {
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return values[values.length - 1];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Get the last value of a querystring parameter *as a Date*.
|
|
245
|
+
* The parameter must be parsable using `new Date(xxx)`.
|
|
246
|
+
* It is recommended to always use ISO-8601 to represent dates
|
|
247
|
+
* (ex: "2020-04-21T17:13:33.107Z").
|
|
248
|
+
*
|
|
249
|
+
* If the parameter is found but can't be parsed to a Date,
|
|
250
|
+
* by default an `Error` is thrown. But if `errorHandler`
|
|
251
|
+
* is specified, it is called instead. This allows you
|
|
252
|
+
* to catch the error and throw a custom error, for
|
|
253
|
+
* example by using `throw createInvalidParameterError(xxx)`
|
|
254
|
+
* in an API.
|
|
255
|
+
*
|
|
256
|
+
* Manages the fact that we may use insensitive routing.
|
|
257
|
+
*
|
|
258
|
+
* @returns the last parameter with that key as a Date
|
|
259
|
+
* or `undefined` if not found.
|
|
260
|
+
* @throws An Error if the parameter is found but can't be parsed
|
|
261
|
+
* to a Date and no `errorHandler` is specified.
|
|
262
|
+
*/
|
|
263
|
+
public getQueryParamOneAsDate = (
|
|
264
|
+
req: Request,
|
|
265
|
+
key: string,
|
|
266
|
+
errorHandler?: (errMsg: string, value?: string) => any
|
|
267
|
+
): Date => {
|
|
268
|
+
const dateStr = this.getQueryParamOne(req, key);
|
|
269
|
+
let date: Date;
|
|
270
|
+
if (!utils.isBlank(dateStr)) {
|
|
271
|
+
date = new Date(dateStr);
|
|
272
|
+
if (isNaN(date.getTime())) {
|
|
273
|
+
const errorMsg = `Not a valid parsable date: "${dateStr}"`;
|
|
274
|
+
if (errorHandler) {
|
|
275
|
+
return errorHandler(errorMsg, dateStr);
|
|
276
|
+
}
|
|
277
|
+
throw new Error(errorMsg);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return date;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Get the last value of a querystring parameter *as a Number*.
|
|
285
|
+
* The parameter must be parsable using `Number(xxx)`.
|
|
286
|
+
*
|
|
287
|
+
* If the parameter is found but can't be parsed to a Number,
|
|
288
|
+
* by default an `Error` is thrown. But if `errorHandler`
|
|
289
|
+
* is specified, it is called instead. This allows you
|
|
290
|
+
* to catch the error and throw a custom error, for
|
|
291
|
+
* example by using `throw createInvalidParameterError(xxx)`
|
|
292
|
+
* in an API.
|
|
293
|
+
*
|
|
294
|
+
* Manages the fact that we may use insensitive routing.
|
|
295
|
+
*
|
|
296
|
+
* @returns the last parameter with that key as a Number
|
|
297
|
+
* or `undefined` if not found.
|
|
298
|
+
* @throws An Error if the parameter is found but can't be parsed
|
|
299
|
+
* to a Number and no `errorHandler` is specified.
|
|
300
|
+
*/
|
|
301
|
+
public getQueryParamOneAsNumber = (
|
|
302
|
+
req: Request,
|
|
303
|
+
key: string,
|
|
304
|
+
errorHandler?: (errMsg: string, value?: string) => any
|
|
305
|
+
): number => {
|
|
306
|
+
const numberStr = this.getQueryParamOne(req, key);
|
|
307
|
+
let val: number;
|
|
308
|
+
if (!utils.isBlank(numberStr)) {
|
|
309
|
+
val = Number(numberStr);
|
|
310
|
+
if (isNaN(val)) {
|
|
311
|
+
const errorMsg = `Not a valid number: "${numberStr}"`;
|
|
312
|
+
if (errorHandler) {
|
|
313
|
+
return errorHandler(errorMsg, numberStr);
|
|
314
|
+
}
|
|
315
|
+
throw new Error(errorMsg);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return val;
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Get the last value of a querystring parameter *as a boolean*.
|
|
323
|
+
* The value must be "true" or "false" (case insensitive) to
|
|
324
|
+
* be considered as a valid boolean. For example, the value '1'
|
|
325
|
+
* is invalid.
|
|
326
|
+
*
|
|
327
|
+
* @returns the last parameter with that key as a boolean
|
|
328
|
+
* or `undefined` if not found.
|
|
329
|
+
* @throws An Error if the parameter is found but can't be parsed
|
|
330
|
+
* to a valid boolean and no `errorHandler` is specified.
|
|
331
|
+
*/
|
|
332
|
+
public getQueryParamOneAsBoolean = (
|
|
333
|
+
req: Request,
|
|
334
|
+
key: string,
|
|
335
|
+
errorHandler?: (errMsg: string, value?: string) => any
|
|
336
|
+
): boolean => {
|
|
337
|
+
const boolStr = this.getQueryParamOne(req, key);
|
|
338
|
+
if (utils.isBlank(boolStr)) {
|
|
339
|
+
return undefined;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (boolStr.toLowerCase() === 'true') {
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (boolStr.toLowerCase() === 'false') {
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const errorMsg = `Not a valid boolean value: "${boolStr}"`;
|
|
351
|
+
if (errorHandler) {
|
|
352
|
+
return errorHandler(errorMsg, boolStr);
|
|
353
|
+
}
|
|
354
|
+
throw new Error(errorMsg);
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
private getOriginalQueryParamAsArray(req: Request, key: string) {
|
|
358
|
+
let val = req.query[key];
|
|
359
|
+
if (_.isUndefined(val)) {
|
|
360
|
+
return [];
|
|
361
|
+
}
|
|
362
|
+
if (!_.isArray(val)) {
|
|
363
|
+
val = [val] as string[];
|
|
364
|
+
}
|
|
365
|
+
return val as string[];
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Gets the "IOrderBy[]" from the querystring parameters
|
|
370
|
+
* of a search request.
|
|
371
|
+
*
|
|
372
|
+
* @see https://confluence.montreal.ca/pages/viewpage.action?spaceKey=AES&title=REST+API#RESTAPI-Tridelarequ%C3%AAte
|
|
373
|
+
*/
|
|
374
|
+
public getOrderBys = (req: Request): IOrderBy[] => {
|
|
375
|
+
const orderBys: IOrderBy[] = [];
|
|
376
|
+
|
|
377
|
+
const orderByStr = this.getQueryParamOne(req, 'orderBy');
|
|
378
|
+
if (utils.isBlank(orderByStr)) {
|
|
379
|
+
return orderBys;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const tokens: string[] = orderByStr.split(',');
|
|
383
|
+
for (let token of tokens) {
|
|
384
|
+
token = token.trim();
|
|
385
|
+
|
|
386
|
+
let key = token;
|
|
387
|
+
let direction: OrderByDirection = OrderByDirection.ASC;
|
|
388
|
+
if (token.startsWith('+')) {
|
|
389
|
+
key = token.substring(1);
|
|
390
|
+
} else if (token.startsWith('-')) {
|
|
391
|
+
key = token.substring(1);
|
|
392
|
+
direction = OrderByDirection.DESC;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const orderBy: IOrderBy = {
|
|
396
|
+
key,
|
|
397
|
+
direction
|
|
398
|
+
};
|
|
399
|
+
orderBys.push(orderBy);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return orderBys;
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
export let httpUtils: HttpUtils = new HttpUtils();
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './httpUtils';
|
|
2
|
+
|
|
3
|
+
// ==========================================
|
|
4
|
+
// We do not export the configs instance itself,
|
|
5
|
+
// only the "init()" method, so we can define
|
|
6
|
+
// required parameters.
|
|
7
|
+
// ==========================================
|
|
8
|
+
export * from './config/init';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ILogger, initLogger, LazyLogger, Logger, LoggerConfigs, LogLevel } from '@villedemontreal/logger';
|
|
2
|
+
import { configs } from '../config/configs';
|
|
3
|
+
|
|
4
|
+
let testingLoggerLibInitialised = false;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a Logger.
|
|
8
|
+
*/
|
|
9
|
+
export function createLogger(name: string): ILogger {
|
|
10
|
+
// ==========================================
|
|
11
|
+
// We use a LazyLogger so the real Logger
|
|
12
|
+
// is only created when the first
|
|
13
|
+
// log is actually performed... At that point,
|
|
14
|
+
// our "configs.loggerCreator" configuration
|
|
15
|
+
// must have been set by the code using our library!
|
|
16
|
+
//
|
|
17
|
+
// This pattern allows calling code to import
|
|
18
|
+
// modules from us in which a logger is
|
|
19
|
+
// created in the global scope :
|
|
20
|
+
//
|
|
21
|
+
// let logger = createLogger('someName');
|
|
22
|
+
//
|
|
23
|
+
// Without a Lazy Logger, the library configurations
|
|
24
|
+
// would at that moment *not* have been set yet
|
|
25
|
+
// (by the calling code) and an Error would be thrown
|
|
26
|
+
// because the "configs.loggerCreator" is required.
|
|
27
|
+
// ==========================================
|
|
28
|
+
return new LazyLogger(name, (nameArg: string) => {
|
|
29
|
+
return configs.loggerCreator(nameArg);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function initTestingLoggerConfigs() {
|
|
34
|
+
const loggerConfig: LoggerConfigs = new LoggerConfigs(() => 'test-cid');
|
|
35
|
+
loggerConfig.setLogLevel(LogLevel.DEBUG);
|
|
36
|
+
initLogger(loggerConfig);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A Logger that uses a dummy cid provider.
|
|
41
|
+
*
|
|
42
|
+
* Only use this when running the tests!
|
|
43
|
+
*/
|
|
44
|
+
export function getTestingLoggerCreator(): (name: string) => ILogger {
|
|
45
|
+
return (name: string): ILogger => {
|
|
46
|
+
if (!testingLoggerLibInitialised) {
|
|
47
|
+
initTestingLoggerConfigs();
|
|
48
|
+
testingLoggerLibInitialised = true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return new Logger(name);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { init } from '../config/init';
|
|
2
|
+
import { getTestingLoggerCreator } from '../utils/logger';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Call this when your need to set
|
|
6
|
+
* *Testing* configurations to the current
|
|
7
|
+
* library, without the need for a calling code
|
|
8
|
+
* to do so.
|
|
9
|
+
*
|
|
10
|
+
* A test Correlation Id will be used!
|
|
11
|
+
*/
|
|
12
|
+
export function setTestingConfigurations(caseSensitive = false): void {
|
|
13
|
+
init(getTestingLoggerCreator(), () => 'test-cid', caseSensitive);
|
|
14
|
+
}
|