@team-internet/apiconnector 10.0.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.
Files changed (58) hide show
  1. package/.devcontainer/Dockerfile +66 -0
  2. package/.devcontainer/devcontainer.json +30 -0
  3. package/.devcontainer/docker-compose.yml +11 -0
  4. package/.devcontainer/supporting_files/configuration/.czrc +1 -0
  5. package/.devcontainer/supporting_files/configuration/.p10k.zsh +1735 -0
  6. package/.devcontainer/supporting_files/configuration/.zshrc +23 -0
  7. package/.devcontainer/supporting_files/configuration/p10k-instant-prompt-vscode.zsh +323 -0
  8. package/.devcontainer/supporting_files/scripts/post-create.sh +11 -0
  9. package/.nycrc +6 -0
  10. package/CHANGELOG.md +582 -0
  11. package/CONTRIBUTING.md +132 -0
  12. package/LICENSE +21 -0
  13. package/README.md +56 -0
  14. package/dist/apiclient.d.ts +233 -0
  15. package/dist/apiclient.js +517 -0
  16. package/dist/column.d.ts +40 -0
  17. package/dist/column.js +52 -0
  18. package/dist/customlogger.d.ts +15 -0
  19. package/dist/customlogger.js +23 -0
  20. package/dist/index.d.ts +16 -0
  21. package/dist/index.js +16 -0
  22. package/dist/logger.d.ts +14 -0
  23. package/dist/logger.js +21 -0
  24. package/dist/record.d.ts +31 -0
  25. package/dist/record.js +42 -0
  26. package/dist/response.d.ts +264 -0
  27. package/dist/response.js +512 -0
  28. package/dist/responseparser.d.ts +1 -0
  29. package/dist/responseparser.js +36 -0
  30. package/dist/responsetemplatemanager.d.ts +65 -0
  31. package/dist/responsetemplatemanager.js +111 -0
  32. package/dist/responsetranslator.d.ts +32 -0
  33. package/dist/responsetranslator.js +144 -0
  34. package/dist/socketconfig.d.ts +62 -0
  35. package/dist/socketconfig.js +107 -0
  36. package/package.json +86 -0
  37. package/src/apiclient.ts +579 -0
  38. package/src/column.ts +57 -0
  39. package/src/customlogger.ts +29 -0
  40. package/src/index.ts +18 -0
  41. package/src/logger.ts +23 -0
  42. package/src/record.ts +46 -0
  43. package/src/response.ts +562 -0
  44. package/src/responseparser.ts +35 -0
  45. package/src/responsetemplatemanager.ts +136 -0
  46. package/src/responsetranslator.ts +191 -0
  47. package/src/socketconfig.ts +116 -0
  48. package/tests/apiclient.spec.ts +610 -0
  49. package/tests/app.js +47 -0
  50. package/tests/column.spec.ts +23 -0
  51. package/tests/index.spec.ts +22 -0
  52. package/tests/record.spec.ts +31 -0
  53. package/tests/response.spec.ts +341 -0
  54. package/tests/responseparser.spec.ts +13 -0
  55. package/tests/responsetemplatemanager.spec.ts +52 -0
  56. package/tests/socketconfig.spec.ts +14 -0
  57. package/tsconfig.json +7 -0
  58. package/typedoc.json +7 -0
@@ -0,0 +1,579 @@
1
+ import fetch from "cross-fetch";
2
+ import { Logger } from "./logger.js";
3
+ import { Response } from "./response.js";
4
+ import { ResponseTemplateManager } from "./responsetemplatemanager.js";
5
+ import { fixedURLEnc, SocketConfig } from "./socketconfig.js";
6
+ import { toAscii } from "idna-uts46-hx";
7
+
8
+ export const CNR_CONNECTION_URL_PROXY = "http://10.0.0.1/api/call.cgi";
9
+ export const CNR_CONNECTION_URL_LIVE = "https://api.rrpproxy.net/api/call.cgi";
10
+ export const CNR_CONNECTION_URL_OTE =
11
+ "https://api-ote.rrpproxy.net/api/call.cgi";
12
+
13
+ const rtm = ResponseTemplateManager.getInstance();
14
+
15
+ /**
16
+ * APIClient class
17
+ */
18
+ export class APIClient {
19
+ /**
20
+ * API connection timeout setting
21
+ */
22
+ public static readonly socketTimeout: number = 300000;
23
+ /**
24
+ * User Agent string
25
+ */
26
+ private ua: string;
27
+ /**
28
+ * API connection url
29
+ */
30
+ private socketURL: string;
31
+ /**
32
+ * Object covering API connection data
33
+ */
34
+ private socketConfig: SocketConfig;
35
+ /**
36
+ * activity flag for debug mode
37
+ */
38
+ private debugMode: boolean;
39
+ /**
40
+ * additional connection settings
41
+ */
42
+ private curlopts: any;
43
+ /**
44
+ * logger function for debug mode
45
+ */
46
+ private logger: Logger | null;
47
+ /**
48
+ * set sub user account
49
+ */
50
+ private subUser: string;
51
+ /**
52
+ * set sub user account role seperater
53
+ */
54
+ private readonly roleSeparator: string = ":";
55
+
56
+ public constructor() {
57
+ this.ua = "";
58
+ this.socketURL = "";
59
+ this.debugMode = false;
60
+ this.setURL(CNR_CONNECTION_URL_LIVE);
61
+ this.socketConfig = new SocketConfig();
62
+ this.useLIVESystem();
63
+ this.curlopts = {};
64
+ this.logger = null;
65
+ this.subUser = "";
66
+ this.roleSeparator = ":";
67
+ this.setDefaultLogger();
68
+ }
69
+
70
+ /**
71
+ * set custom logger to use instead of default one
72
+ * @param customLogger
73
+ * @returns Current APIClient instance for method chaining
74
+ */
75
+ public setCustomLogger(customLogger: Logger): APIClient {
76
+ this.logger = customLogger;
77
+ return this;
78
+ }
79
+ /**
80
+ * set default logger to use
81
+ * @returns Current APIClient instance for method chaining
82
+ */
83
+ public setDefaultLogger(): APIClient {
84
+ this.logger = new Logger();
85
+ return this;
86
+ }
87
+ /**
88
+ * Enable Debug Output to STDOUT
89
+ * @returns Current APIClient instance for method chaining
90
+ */
91
+ public enableDebugMode(): APIClient {
92
+ this.debugMode = true;
93
+ return this;
94
+ }
95
+
96
+ /**
97
+ * Disable Debug Output
98
+ * @returns Current APIClient instance for method chaining
99
+ */
100
+ public disableDebugMode(): APIClient {
101
+ this.debugMode = false;
102
+ return this;
103
+ }
104
+
105
+ /**
106
+ * Get the API connection url that is currently set
107
+ * @returns API connection url currently in use
108
+ */
109
+ public getURL(): string {
110
+ return this.socketURL;
111
+ }
112
+
113
+ /**
114
+ * Possibility to customize default user agent to fit your needs
115
+ * @param str user agent label
116
+ * @param rv revision of user agent
117
+ * @param modules further modules to add to user agent string, format: ["<mod1>/<rev>", "<mod2>/<rev>", ... ]
118
+ * @returns Current APIClient instance for method chaining
119
+ */
120
+ public setUserAgent(str: string, rv: string, modules: any = []): APIClient {
121
+ const mods = modules.length ? " " + modules.join(" ") : "";
122
+ this.ua =
123
+ `${str} ` +
124
+ `(${process.platform}; ${process.arch}; rv:${rv})` +
125
+ mods +
126
+ ` node-sdk/${this.getVersion()} ` +
127
+ `node/${process.version}`;
128
+ return this;
129
+ }
130
+
131
+ /**
132
+ * Get the User Agent
133
+ * @returns User Agent string
134
+ */
135
+ public getUserAgent(): string {
136
+ if (!this.ua.length) {
137
+ this.ua =
138
+ `NODE-SDK (${process.platform}; ${
139
+ process.arch
140
+ }; rv:${this.getVersion()}) ` + `node/${process.version}`;
141
+ }
142
+ return this.ua;
143
+ }
144
+
145
+ /**
146
+ * Set the proxy server to use for API communication
147
+ * @param proxy proxy server to use for communicatio
148
+ * @returns Current APIClient instance for method chaining
149
+ */
150
+ public setProxy(proxy: string): APIClient {
151
+ this.curlopts.proxy = proxy;
152
+ return this;
153
+ }
154
+
155
+ /**
156
+ * Get the proxy server configuration
157
+ * @returns proxy server configuration value or null if not set
158
+ */
159
+ public getProxy(): string | null {
160
+ if (Object.prototype.hasOwnProperty.call(this.curlopts, "proxy")) {
161
+ return this.curlopts.proxy;
162
+ }
163
+ return null;
164
+ }
165
+
166
+ /**
167
+ * Set the referer to use for API communication
168
+ * @param referer Referer
169
+ * @returns Current APIClient instance for method chaining
170
+ */
171
+ public setReferer(referer: string): APIClient {
172
+ this.curlopts.referer = referer;
173
+ return this;
174
+ }
175
+
176
+ /**
177
+ * Get the referer configuration
178
+ * @returns referer configuration value or null if not set
179
+ */
180
+ public getReferer(): string | null {
181
+ if (Object.prototype.hasOwnProperty.call(this.curlopts, "referer")) {
182
+ return this.curlopts.referer;
183
+ }
184
+ return null;
185
+ }
186
+
187
+ /**
188
+ * Get the current module version
189
+ * @returns module version
190
+ */
191
+ public getVersion(): string {
192
+ return "10.0.0";
193
+ }
194
+
195
+ /**
196
+ * Apply session data (session id and system entity) to given client request session
197
+ * @param session ClientRequest session instance
198
+ * @returns Current APIClient instance for method chaining
199
+ */
200
+ public saveSession(session: any): APIClient {
201
+ session.socketcfg = {
202
+ login: this.socketConfig.getLogin(),
203
+ session: this.socketConfig.getSession(),
204
+ };
205
+ return this;
206
+ }
207
+
208
+ /**
209
+ * Use existing configuration out of ClientRequest session
210
+ * to rebuild and reuse connection settings
211
+ * @param session ClientRequest session instance
212
+ * @returns Current APIClient instance for method chaining
213
+ */
214
+ public reuseSession(session: any): APIClient {
215
+ if (
216
+ !session ||
217
+ !session.socketcfg ||
218
+ !session.socketcfg.login ||
219
+ !session.socketcfg.session
220
+ ) {
221
+ return this;
222
+ }
223
+ this.setCredentials(session.socketcfg.login);
224
+ this.socketConfig.setSession(session.socketcfg.session);
225
+ return this;
226
+ }
227
+
228
+ /**
229
+ * Set another connection url to be used for API communication
230
+ * @param value API connection url to set
231
+ * @returns Current APIClient instance for method chaining
232
+ */
233
+ public setURL(value: string): APIClient {
234
+ this.socketURL = value;
235
+ return this;
236
+ }
237
+
238
+ /**
239
+ * Set Persistent to request session id for API communication
240
+ * @param value API session id
241
+ * @returns Current APIClient instance for method chaining
242
+ */
243
+ public setPersistent(): APIClient {
244
+ this.socketConfig.setPersistent();
245
+ return this;
246
+ }
247
+
248
+ /**
249
+ * Set Credentials to be used for API communication
250
+ * @param uid account name
251
+ * @param pw account password
252
+ * @returns Current APIClient instance for method chaining
253
+ */
254
+ public setCredentials(uid: string, pw: string = ""): APIClient {
255
+ this.socketConfig.setLogin(uid);
256
+ this.socketConfig.setPassword(pw);
257
+ return this;
258
+ }
259
+
260
+ /**
261
+ * Set Credentials to be used for API communication
262
+ * @param uid account name
263
+ * @param role role user id
264
+ * @param pw role user password
265
+ * @returns Current APIClient instance for method chaining
266
+ */
267
+ public setRoleCredentials(
268
+ uid: string,
269
+ role: string,
270
+ pw: string = "",
271
+ ): APIClient {
272
+ return this.setCredentials(
273
+ role ? `${uid}${this.roleSeparator}${role}` : uid,
274
+ pw,
275
+ );
276
+ }
277
+
278
+ /**
279
+ * Perform API login to start session-based communication
280
+ * @param otp optional one time password
281
+ * @returns Promise resolving with API Response
282
+ */
283
+ public async login(): Promise<Response> {
284
+ this.setPersistent();
285
+ const rr = await this.request({}, false);
286
+ this.socketConfig.setSession("");
287
+ if (rr.isSuccess()) {
288
+ const col = rr.getColumn("SESSIONID");
289
+ this.socketConfig.setSession(col ? col.getData()[0] : "");
290
+ }
291
+ return rr;
292
+ }
293
+
294
+ /**
295
+ * Perform API logout to close API session in use
296
+ * @returns Promise resolving with API Response
297
+ */
298
+ public async logout(): Promise<Response> {
299
+ const rr = await this.request(
300
+ {
301
+ COMMAND: "StopSession",
302
+ },
303
+ false,
304
+ );
305
+ if (rr.isSuccess()) {
306
+ this.socketConfig.setSession("");
307
+ }
308
+ return rr;
309
+ }
310
+
311
+ /**
312
+ * Perform API request using the given command
313
+ * @param cmd API command to request
314
+ * @returns Promise resolving with API Response
315
+ */
316
+ public async request(cmd: any, setUserView = true): Promise<Response> {
317
+ // set sub user id if available
318
+ if (setUserView && this.subUser !== "") {
319
+ cmd.SUBUSER = this.subUser;
320
+ }
321
+
322
+ // flatten nested api command bulk parameters
323
+ let mycmd = this.flattenCommand(cmd);
324
+
325
+ // auto convert umlaut names to punycode
326
+ mycmd = await this.autoIDNConvert(mycmd);
327
+
328
+ // request command to API
329
+ const cfg: any = {
330
+ CONNECTION_URL: this.socketURL,
331
+ };
332
+ // TODO: 300s (to be sure to get an API response)
333
+ const reqCfg: any = {
334
+ // encoding: "utf8", //default for type string
335
+ // gzip: true,
336
+ body: this.getPOSTData(mycmd),
337
+ headers: {
338
+ "User-Agent": this.getUserAgent(),
339
+ },
340
+ method: "POST",
341
+ timeout: APIClient.socketTimeout,
342
+ url: cfg.CONNECTION_URL,
343
+ };
344
+ const proxy = this.getProxy();
345
+ if (proxy) {
346
+ reqCfg.proxy = proxy;
347
+ }
348
+ const referer = this.getReferer();
349
+ if (referer) {
350
+ reqCfg.headers.Referer = referer;
351
+ }
352
+ return fetch(cfg.CONNECTION_URL, reqCfg)
353
+ .then(async (res: any) => {
354
+ let error = null;
355
+ let body;
356
+ if (res.ok) {
357
+ // res.status >= 200 && res.status < 300
358
+ body = await res.text();
359
+ } else {
360
+ error = res.status + (res.statusText ? " " + res.statusText : "");
361
+ body = rtm.getTemplate("httperror").getPlain();
362
+ }
363
+ const rr = new Response(body, mycmd, cfg);
364
+ if (this.debugMode && this.logger) {
365
+ this.logger.log(this.getPOSTData(mycmd, true), rr, error);
366
+ }
367
+ return rr;
368
+ })
369
+ .catch((err) => {
370
+ const body = rtm.getTemplate("httperror").getPlain();
371
+ const rr = new Response(body, mycmd, cfg);
372
+ if (this.debugMode && this.logger) {
373
+ this.logger.log(this.getPOSTData(mycmd, true), rr, err.message);
374
+ }
375
+ return rr;
376
+ });
377
+ }
378
+
379
+ /**
380
+ * Request the next page of list entries for the current list query
381
+ * Useful for tables
382
+ * @param rr API Response of current page
383
+ * @returns Promise resolving with API Response or null in case there are no further list entries
384
+ */
385
+ public async requestNextResponsePage(rr: Response): Promise<Response | null> {
386
+ const mycmd = rr.getCommand();
387
+ if (Object.prototype.hasOwnProperty.call(mycmd, "LAST")) {
388
+ throw new Error(
389
+ "Parameter LAST in use. Please remove it to avoid issues in requestNextPage.",
390
+ );
391
+ }
392
+ let first = 0;
393
+ if (Object.prototype.hasOwnProperty.call(mycmd, "FIRST")) {
394
+ first = mycmd.FIRST;
395
+ }
396
+ const total = rr.getRecordsTotalCount();
397
+ const limit = rr.getRecordsLimitation();
398
+ first += limit;
399
+ if (first < total) {
400
+ mycmd.FIRST = first;
401
+ mycmd.LIMIT = limit;
402
+ return this.request(mycmd);
403
+ }
404
+
405
+ return null;
406
+ }
407
+
408
+ /**
409
+ * Request all pages/entries for the given query command
410
+ * @param cmd API list command to use
411
+ * @returns Promise resolving with array of API Responses
412
+ */
413
+ public async requestAllResponsePages(cmd: any): Promise<Response[]> {
414
+ const responses: Response[] = [];
415
+ let rr: Response | null = await this.request({ ...cmd, FIRST: 0 });
416
+
417
+ while (rr !== null) {
418
+ responses.push(rr);
419
+ rr = await this.requestNextResponsePage(rr);
420
+ }
421
+
422
+ return responses;
423
+ }
424
+
425
+ /**
426
+ * Set a data view to a given subuser
427
+ * @param uid subuser account name
428
+ * @returns Current APIClient instance for method chaining
429
+ */
430
+ public setUserView(uid: string): APIClient {
431
+ this.subUser = uid;
432
+ return this;
433
+ }
434
+
435
+ /**
436
+ * Reset data view back from subuser to user
437
+ * @returns Current APIClient instance for method chaining
438
+ */
439
+ public resetUserView(): APIClient {
440
+ this.subUser = "";
441
+ return this;
442
+ }
443
+
444
+ /**
445
+ * Activate High Performance Connection Setup
446
+ * @see https://github.com/centralnicgroup-opensource/rtldev-middleware-node-sdk/blob/master/README.md
447
+ * @returns Current APIClient instance for method chaining
448
+ */
449
+ public useHighPerformanceConnectionSetup(): APIClient {
450
+ this.setURL(CNR_CONNECTION_URL_PROXY);
451
+ return this;
452
+ }
453
+
454
+ /**
455
+ * Activate Default Connection Setup (the default)
456
+ * @returns Current APIClient instance for method chaining
457
+ */
458
+ public useDefaultConnectionSetup(): APIClient {
459
+ this.setURL(CNR_CONNECTION_URL_LIVE);
460
+ return this;
461
+ }
462
+
463
+ /**
464
+ * Set OT&E System for API communication
465
+ * @returns Current APIClient instance for method chaining
466
+ */
467
+ public useOTESystem(): APIClient {
468
+ this.setURL(CNR_CONNECTION_URL_OTE);
469
+ return this;
470
+ }
471
+
472
+ /**
473
+ * Set LIVE System for API communication (this is the default setting)
474
+ * @returns Current APIClient instance for method chaining
475
+ */
476
+ public useLIVESystem(): APIClient {
477
+ this.setURL(CNR_CONNECTION_URL_LIVE);
478
+ return this;
479
+ }
480
+
481
+ /**
482
+ * Serialize given command for POST request including connection configuration data
483
+ * @param cmd API command to encode
484
+ * @returns encoded POST data string
485
+ */
486
+ public getPOSTData(cmd: any, secured = false): string {
487
+ let data = this.socketConfig.getPOSTData();
488
+ if (secured) {
489
+ data = data.replace(/s_pw=[^&]+/, "s_pw=***");
490
+ }
491
+
492
+ let tmp = "";
493
+ if (!(typeof cmd === "string" || cmd instanceof String)) {
494
+ Object.keys(cmd).forEach((key: string) => {
495
+ if (cmd[key] !== null && cmd[key] !== undefined) {
496
+ tmp += `${key}=${cmd[key].toString().replace(/\r|\n/g, "")}\n`;
497
+ }
498
+ });
499
+ } else {
500
+ tmp = "" + cmd;
501
+ }
502
+ if (secured) {
503
+ tmp = tmp.replace(/PASSWORD=[^\n]+/, "PASSWORD=***");
504
+ }
505
+ tmp = tmp.replace(/\n$/, "");
506
+ if (Object.keys(cmd).length > 0) {
507
+ data += `${fixedURLEnc("s_command")}=${fixedURLEnc(tmp)}`;
508
+ }
509
+
510
+ return data.endsWith("&") ? data.slice(0, -1) : data;
511
+ }
512
+
513
+ /**
514
+ * Flatten nested arrays in command
515
+ * @param cmd api command
516
+ * @returns api command with flattended parameters
517
+ */
518
+ private flattenCommand(cmd: any): any {
519
+ const newcmd: any = {};
520
+ Object.keys(cmd).forEach((key: string) => {
521
+ const val = cmd[key];
522
+ const newKey = key.toUpperCase();
523
+ if (val !== null && val !== undefined) {
524
+ if (Array.isArray(val)) {
525
+ let index = 0;
526
+ for (const row of val) {
527
+ newcmd[`${newKey}${index}`] = (row + "").replace(/\r|\n/g, "");
528
+ index++;
529
+ }
530
+ } else {
531
+ if (typeof val === "string" || val instanceof String) {
532
+ newcmd[newKey] = val.replace(/\r|\n/g, "");
533
+ } else {
534
+ newcmd[newKey] = val;
535
+ }
536
+ }
537
+ }
538
+ });
539
+ return newcmd;
540
+ }
541
+
542
+ /**
543
+ * Auto convert API command parameters to punycode, if necessary.
544
+ * @param cmd api command
545
+ * @returns Promise resolving with api command with IDN values replaced to punycode
546
+ */
547
+ private async autoIDNConvert(cmd: any): Promise<any> {
548
+ const keyPattern = /^(NAMESERVER|NS|DNSZONE)([0-9]*)$/i;
549
+ const objClassPattern =
550
+ /^(DOMAIN(APPLICATION|BLOCKING)?|NAMESERVER|NS|DNSZONE)$/i;
551
+ const asciiPattern = /^[A-Za-z0-9.\-]+$/;
552
+
553
+ const toConvert: string[] = [];
554
+ const idxs: string[] = [];
555
+
556
+ Object.keys(cmd).forEach((key) => {
557
+ const val = cmd[key];
558
+ if (
559
+ (keyPattern.test(key) ||
560
+ (key.toUpperCase() === "OBJECTID" &&
561
+ cmd.OBJECTCLASS &&
562
+ objClassPattern.test(cmd.OBJECTCLASS))) &&
563
+ !asciiPattern.test(val)
564
+ ) {
565
+ toConvert.push(val);
566
+ idxs.push(key);
567
+ }
568
+ });
569
+
570
+ if (toConvert.length > 0) {
571
+ const convertedValues = toConvert.map((value) => toAscii(value));
572
+ convertedValues.forEach((convertedValue, idx) => {
573
+ cmd[idxs[idx]] = convertedValue;
574
+ });
575
+ }
576
+
577
+ return cmd;
578
+ }
579
+ }
package/src/column.ts ADDED
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Column class
3
+ */
4
+ export class Column {
5
+ /**
6
+ * count of column data entries
7
+ */
8
+ public length: number;
9
+ /**
10
+ * column key name
11
+ */
12
+ private key: string;
13
+ /**
14
+ * column data container
15
+ */
16
+ private data: string[];
17
+
18
+ public constructor(key: string, data: string[]) {
19
+ this.key = key;
20
+ this.data = data;
21
+ this.length = data.length;
22
+ }
23
+
24
+ /**
25
+ * Get column name
26
+ * @returns column name
27
+ */
28
+ public getKey(): string {
29
+ return this.key;
30
+ }
31
+
32
+ /**
33
+ * Get column data
34
+ * @returns column data
35
+ */
36
+ public getData(): string[] {
37
+ return this.data;
38
+ }
39
+
40
+ /**
41
+ * Get column data at given index
42
+ * @param idx data index
43
+ * @returns data at given index
44
+ */
45
+ public getDataByIndex(idx: number): string | null {
46
+ return this.hasDataIndex(idx) ? this.data[idx] : null;
47
+ }
48
+
49
+ /**
50
+ * Check if column has a given data index
51
+ * @param idx data index
52
+ * @returns boolean result
53
+ */
54
+ private hasDataIndex(idx: number): boolean {
55
+ return idx >= 0 && idx < this.length;
56
+ }
57
+ }
@@ -0,0 +1,29 @@
1
+ import { Logger } from "./logger.js";
2
+ import { Response } from "./response.js";
3
+
4
+ /**
5
+ * Logger class
6
+ */
7
+ export class CustomLogger extends Logger {
8
+ /**
9
+ * output/log given data
10
+ * @param post request string used
11
+ * @param r Response object
12
+ * @param error error message or null
13
+ * @return current Logger instance for method chaining
14
+ */
15
+ public log(
16
+ post: string,
17
+ r: Response,
18
+ error: string | null = null,
19
+ ): CustomLogger {
20
+ // apply here whatever you need e.g.
21
+ console.log(post);
22
+ console.dir(r.getCommand());
23
+ if (error) {
24
+ console.error(error);
25
+ }
26
+ console.log(r.getPlain());
27
+ return this;
28
+ }
29
+ }
package/src/index.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { APIClient } from "./apiclient.js";
2
+ import { Response } from "./response.js";
3
+ import { ResponseTemplateManager } from "./responsetemplatemanager.js";
4
+
5
+ export {
6
+ /**
7
+ * APIClient class
8
+ */
9
+ APIClient,
10
+ /**
11
+ * Response class
12
+ */
13
+ Response, // need this to replace 'applyCustomChanges'
14
+ /**
15
+ * ResponseTemplateManager class
16
+ */
17
+ ResponseTemplateManager,
18
+ };
package/src/logger.ts ADDED
@@ -0,0 +1,23 @@
1
+ import { Response } from "./response.js";
2
+
3
+ /**
4
+ * Logger class
5
+ */
6
+ export class Logger {
7
+ /**
8
+ * output/log given data
9
+ * @param post request string used
10
+ * @param r Response object
11
+ * @param error error message or null
12
+ * @return current Logger instance for method chaining
13
+ */
14
+ public log(post: string, r: Response, error: string | null = null): Logger {
15
+ console.dir(r.getCommand());
16
+ console.log(post);
17
+ if (error) {
18
+ console.error(`HTTP communication failed: ${error}`);
19
+ }
20
+ console.log(r.getPlain());
21
+ return this;
22
+ }
23
+ }