@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,512 @@
1
+ import { Column } from "./column.js";
2
+ import { Record } from "./record.js";
3
+ import { ResponseTranslator as RT } from "./responsetranslator.js";
4
+ import { ResponseParser as RP } from "./responseparser.js";
5
+ /**
6
+ * Response Class
7
+ */
8
+ export class Response {
9
+ /**
10
+ * plain API response
11
+ */
12
+ raw;
13
+ /**
14
+ * hash representation of plain API response
15
+ */
16
+ hash;
17
+ /**
18
+ * The API Command used within this request
19
+ */
20
+ command;
21
+ /**
22
+ * Column names available in this responsse
23
+ * NOTE: this includes also FIRST, LAST, LIMIT, COUNT, TOTAL
24
+ * and maybe further specific columns in case of a list query
25
+ */
26
+ columnkeys;
27
+ /**
28
+ * Container of Column Instances
29
+ */
30
+ columns;
31
+ /**
32
+ * Record Index we currently point to in record list
33
+ */
34
+ recordIndex;
35
+ /**
36
+ * Record List (List of rows)
37
+ */
38
+ records;
39
+ /**
40
+ * Constructor
41
+ * @param raw API plain response
42
+ * @param cmd API command used within this request
43
+ * @param ph placeholder array to get vars in response description dynamically replaced
44
+ */
45
+ constructor(raw, cmd = {}, ph = {}) {
46
+ this.command = cmd;
47
+ if (this.command &&
48
+ Object.prototype.hasOwnProperty.call(this.command, "PASSWORD")) {
49
+ // make password no longer accessible
50
+ this.command.PASSWORD = "***";
51
+ }
52
+ this.raw = RT.translate(raw, cmd, ph);
53
+ console.log(this.raw);
54
+ console.log("-----------------------------------------");
55
+ this.hash = RP.parse(this.raw);
56
+ this.columnkeys = [];
57
+ this.columns = [];
58
+ this.recordIndex = 0;
59
+ this.records = [];
60
+ if (Object.prototype.hasOwnProperty.call(this.hash, "PROPERTY")) {
61
+ const colKeys = Object.keys(this.hash.PROPERTY);
62
+ let count = 0;
63
+ colKeys.forEach((c) => {
64
+ const d = this.hash.PROPERTY[c];
65
+ this.addColumn(c, d);
66
+ if (d.length > count) {
67
+ count = d.length;
68
+ }
69
+ });
70
+ for (let i = 0; i < count; i++) {
71
+ const d = {};
72
+ colKeys.forEach((k) => {
73
+ const col = this.getColumn(k);
74
+ if (col) {
75
+ const v = col.getDataByIndex(i);
76
+ if (v !== null) {
77
+ d[k] = v;
78
+ }
79
+ }
80
+ });
81
+ this.addRecord(d);
82
+ }
83
+ }
84
+ }
85
+ /**
86
+ * Get API response code
87
+ * @returns API response code
88
+ */
89
+ getCode() {
90
+ return parseInt(this.hash.CODE, 10);
91
+ }
92
+ /**
93
+ * Get API response description
94
+ * @returns API response description
95
+ */
96
+ getDescription() {
97
+ return this.hash.DESCRIPTION;
98
+ }
99
+ /**
100
+ * Get Plain API response
101
+ * @returns Plain API response
102
+ */
103
+ getPlain() {
104
+ return this.raw;
105
+ }
106
+ /**
107
+ * Get Queuetime of API response
108
+ * @returns Queuetime of API response
109
+ */
110
+ getQueuetime() {
111
+ if (Object.prototype.hasOwnProperty.call(this.hash, "QUEUETIME")) {
112
+ return parseFloat(this.hash.QUEUETIME);
113
+ }
114
+ return 0.0;
115
+ }
116
+ /**
117
+ * Get API response as Hash
118
+ * @returns API response hash
119
+ */
120
+ getHash() {
121
+ return this.hash;
122
+ }
123
+ /**
124
+ * Get Runtime of API response
125
+ * @returns Runtime of API response
126
+ */
127
+ getRuntime() {
128
+ if (Object.prototype.hasOwnProperty.call(this.hash, "RUNTIME")) {
129
+ return parseFloat(this.hash.RUNTIME);
130
+ }
131
+ return 0.0;
132
+ }
133
+ /**
134
+ * Check if current API response represents an error case
135
+ * API response code is an 5xx code
136
+ * @returns boolean result
137
+ */
138
+ isError() {
139
+ return this.hash.CODE.charAt(0) === "5";
140
+ }
141
+ /**
142
+ * Check if current API response represents a success case
143
+ * API response code is an 2xx code
144
+ * @returns boolean result
145
+ */
146
+ isSuccess() {
147
+ return this.hash.CODE.charAt(0) === "2";
148
+ }
149
+ /**
150
+ * Check if current API response represents a temporary error case
151
+ * API response code is an 4xx code
152
+ * @returns boolean result
153
+ */
154
+ isTmpError() {
155
+ return this.hash.CODE.charAt(0) === "4";
156
+ }
157
+ /**
158
+ * Check if current operation is returned as pending
159
+ * @returns boolean result
160
+ */
161
+ isPending() {
162
+ const cmd = this.getCommand();
163
+ // Check if the COMMAND is AddDomain (case-insensitive)
164
+ if (!cmd.COMMAND || cmd.COMMAND.toLowerCase() !== "adddomain") {
165
+ return false;
166
+ }
167
+ // Retrieve the STATUS column and check if its data equals REQUESTED (case-insensitive)
168
+ const status = this.getColumn("STATUS");
169
+ if (status) {
170
+ const statusData = status.getDataByIndex(0);
171
+ if (statusData && statusData.toLowerCase() === "requested") {
172
+ return true;
173
+ }
174
+ }
175
+ return false;
176
+ }
177
+ /**
178
+ * Add a column to the column list
179
+ * @param key column name
180
+ * @param data array of column data
181
+ * @returns Current Response Instance for method chaining
182
+ */
183
+ addColumn(key, data) {
184
+ const col = new Column(key, data);
185
+ this.columns.push(col);
186
+ this.columnkeys.push(key);
187
+ return this;
188
+ }
189
+ /**
190
+ * Add a record to the record list
191
+ * @param h row hash data
192
+ * @returns Current Response Instance for method chaining
193
+ */
194
+ addRecord(h) {
195
+ this.records.push(new Record(h));
196
+ return this;
197
+ }
198
+ /**
199
+ * Get column by column name
200
+ * @param key column name
201
+ * @returns column instance or null if column does not exist
202
+ */
203
+ getColumn(key) {
204
+ return this.hasColumn(key)
205
+ ? this.columns[this.columnkeys.indexOf(key)]
206
+ : null;
207
+ }
208
+ /**
209
+ * Get Data by Column Name and Index
210
+ * @param colkey column name
211
+ * @param index column data index
212
+ * @returns column data at index or null if not found
213
+ */
214
+ getColumnIndex(colkey, index) {
215
+ const col = this.getColumn(colkey);
216
+ return col ? col.getDataByIndex(index) : null;
217
+ }
218
+ /**
219
+ * Get Column Names
220
+ * @returns Array of Column Names
221
+ */
222
+ getColumnKeys() {
223
+ return this.columnkeys;
224
+ }
225
+ /**
226
+ * Get List of Columns
227
+ * @returns Array of Columns
228
+ */
229
+ getColumns() {
230
+ return this.columns;
231
+ }
232
+ /**
233
+ * Get Command used in this request
234
+ * @returns command
235
+ */
236
+ getCommand() {
237
+ return this.command;
238
+ }
239
+ /**
240
+ * Get Command used in this request in plain text format
241
+ * @return command as plain text
242
+ */
243
+ getCommandPlain() {
244
+ let tmp = "";
245
+ Object.keys(this.command).forEach((key) => {
246
+ tmp += `${key} = ${this.command[key]}\n`;
247
+ });
248
+ return tmp;
249
+ }
250
+ /**
251
+ * Get Page Number of current List Query
252
+ * @returns page number or null in case of a non-list response
253
+ */
254
+ getCurrentPageNumber() {
255
+ const first = this.getFirstRecordIndex();
256
+ const limit = this.getRecordsLimitation();
257
+ if (first !== null && limit) {
258
+ return Math.floor(first / limit) + 1;
259
+ }
260
+ return null;
261
+ }
262
+ /**
263
+ * Get Record of current record index
264
+ * @returns Record or null in case of a non-list response
265
+ */
266
+ getCurrentRecord() {
267
+ return this.hasCurrentRecord() ? this.records[this.recordIndex] : null;
268
+ }
269
+ /**
270
+ * Get Index of first row in this response
271
+ * @returns first row index
272
+ */
273
+ getFirstRecordIndex() {
274
+ const col = this.getColumn("FIRST");
275
+ if (col) {
276
+ const f = col.getDataByIndex(0);
277
+ if (f !== null) {
278
+ return parseInt(f, 10);
279
+ }
280
+ }
281
+ if (this.records.length) {
282
+ return 0;
283
+ }
284
+ return null;
285
+ }
286
+ /**
287
+ * Get last record index of the current list query
288
+ * @returns record index or null for a non-list response
289
+ */
290
+ getLastRecordIndex() {
291
+ const col = this.getColumn("LAST");
292
+ if (col) {
293
+ const l = col.getDataByIndex(0);
294
+ if (l !== null) {
295
+ return parseInt(l, 10);
296
+ }
297
+ }
298
+ const len = this.getRecordsCount();
299
+ if (len) {
300
+ return len - 1;
301
+ }
302
+ return null;
303
+ }
304
+ /**
305
+ * Get Response as List Hash including useful meta data for tables
306
+ * @returns hash including list meta data and array of rows in hash notation
307
+ */
308
+ getListHash() {
309
+ const lh = [];
310
+ this.getRecords().forEach((rec) => {
311
+ lh.push(rec.getData());
312
+ });
313
+ return {
314
+ LIST: lh,
315
+ meta: {
316
+ columns: this.getColumnKeys(),
317
+ pg: this.getPagination(),
318
+ },
319
+ };
320
+ }
321
+ /**
322
+ * Get next record in record list
323
+ * @returns Record or null in case there's no further record
324
+ */
325
+ getNextRecord() {
326
+ if (this.hasNextRecord()) {
327
+ return this.records[++this.recordIndex];
328
+ }
329
+ return null;
330
+ }
331
+ /**
332
+ * Get Page Number of next list query
333
+ * @returns page number or null if there's no next page
334
+ */
335
+ getNextPageNumber() {
336
+ const cp = this.getCurrentPageNumber();
337
+ if (cp === null) {
338
+ return null;
339
+ }
340
+ const page = cp + 1;
341
+ const pages = this.getNumberOfPages();
342
+ return page <= pages ? page : pages;
343
+ }
344
+ /**
345
+ * Get the number of pages available for this list query
346
+ * @returns number of pages
347
+ */
348
+ getNumberOfPages() {
349
+ const t = this.getRecordsTotalCount();
350
+ const limit = this.getRecordsLimitation();
351
+ if (t && limit) {
352
+ return Math.ceil(t / this.getRecordsLimitation());
353
+ }
354
+ return 0;
355
+ }
356
+ /**
357
+ * Get object containing all paging data
358
+ * @returns paginator data
359
+ */
360
+ getPagination() {
361
+ return {
362
+ COUNT: this.getRecordsCount(),
363
+ CURRENTPAGE: this.getCurrentPageNumber(),
364
+ FIRST: this.getFirstRecordIndex(),
365
+ LAST: this.getLastRecordIndex(),
366
+ LIMIT: this.getRecordsLimitation(),
367
+ NEXTPAGE: this.getNextPageNumber(),
368
+ PAGES: this.getNumberOfPages(),
369
+ PREVIOUSPAGE: this.getPreviousPageNumber(),
370
+ TOTAL: this.getRecordsTotalCount(),
371
+ };
372
+ }
373
+ /**
374
+ * Get Page Number of previous list query
375
+ * @returns page number or null if there's no previous page
376
+ */
377
+ getPreviousPageNumber() {
378
+ const cp = this.getCurrentPageNumber();
379
+ if (cp === null) {
380
+ return null;
381
+ }
382
+ return cp - 1 || null;
383
+ }
384
+ /**
385
+ * Get previous record in record list
386
+ * @returns Record or null if there's no previous record
387
+ */
388
+ getPreviousRecord() {
389
+ if (this.hasPreviousRecord()) {
390
+ return this.records[--this.recordIndex];
391
+ }
392
+ return null;
393
+ }
394
+ /**
395
+ * Get Record at given index
396
+ * @param idx record index
397
+ * @returns Record or null if index does not exist
398
+ */
399
+ getRecord(idx) {
400
+ if (idx >= 0 && this.records.length > idx) {
401
+ return this.records[idx];
402
+ }
403
+ return null;
404
+ }
405
+ /**
406
+ * Get all Records
407
+ * @returns array of records
408
+ */
409
+ getRecords() {
410
+ return this.records;
411
+ }
412
+ /**
413
+ * Get count of rows in this response
414
+ * @returns count of rows
415
+ */
416
+ getRecordsCount() {
417
+ return this.records.length;
418
+ }
419
+ /**
420
+ * Get total count of records available for the list query
421
+ * @returns total count of records or count of records for a non-list response
422
+ */
423
+ getRecordsTotalCount() {
424
+ const col = this.getColumn("TOTAL");
425
+ if (col) {
426
+ const t = col.getDataByIndex(0);
427
+ if (t !== null) {
428
+ return parseInt(t, 10);
429
+ }
430
+ }
431
+ return this.getRecordsCount();
432
+ }
433
+ /**
434
+ * Get limit(ation) setting of the current list query
435
+ * This is the count of requested rows
436
+ * @returns limit setting or count requested rows
437
+ */
438
+ getRecordsLimitation() {
439
+ const col = this.getColumn("LIMIT");
440
+ if (col) {
441
+ const l = col.getDataByIndex(0);
442
+ if (l !== null) {
443
+ return parseInt(l, 10);
444
+ }
445
+ }
446
+ return this.getRecordsCount();
447
+ }
448
+ /**
449
+ * Check if this list query has a next page
450
+ * @returns boolean result
451
+ */
452
+ hasNextPage() {
453
+ const cp = this.getCurrentPageNumber();
454
+ if (cp === null) {
455
+ return false;
456
+ }
457
+ return cp + 1 <= this.getNumberOfPages();
458
+ }
459
+ /**
460
+ * Check if this list query has a previous page
461
+ * @returns boolean result
462
+ */
463
+ hasPreviousPage() {
464
+ const cp = this.getCurrentPageNumber();
465
+ if (cp === null) {
466
+ return false;
467
+ }
468
+ return cp - 1 > 0;
469
+ }
470
+ /**
471
+ * Reset index in record list back to zero
472
+ * @returns Current Response Instance for method chaining
473
+ */
474
+ rewindRecordList() {
475
+ this.recordIndex = 0;
476
+ return this;
477
+ }
478
+ /**
479
+ * Check if column exists in response
480
+ * @param key column name
481
+ * @returns boolean result
482
+ */
483
+ hasColumn(key) {
484
+ return this.columnkeys.indexOf(key) !== -1;
485
+ }
486
+ /**
487
+ * Check if the record list contains a record for the
488
+ * current record index in use
489
+ * @returns boolean result
490
+ */
491
+ hasCurrentRecord() {
492
+ const len = this.records.length;
493
+ return len > 0 && this.recordIndex >= 0 && this.recordIndex < len;
494
+ }
495
+ /**
496
+ * Check if the record list contains a next record for the
497
+ * current record index in use
498
+ * @returns boolean result
499
+ */
500
+ hasNextRecord() {
501
+ const next = this.recordIndex + 1;
502
+ return this.hasCurrentRecord() && next < this.records.length;
503
+ }
504
+ /**
505
+ * Check if the record list contains a previous record for the
506
+ * current record index in use
507
+ * @returns boolean result
508
+ */
509
+ hasPreviousRecord() {
510
+ return this.recordIndex > 0 && this.hasCurrentRecord();
511
+ }
512
+ }
@@ -0,0 +1 @@
1
+ export declare const ResponseParser: any;
@@ -0,0 +1,36 @@
1
+ export const ResponseParser = {
2
+ /**
3
+ * Method to parse plain API response into js object
4
+ * @param raw API plain response
5
+ * @returns API response as JS Object (hash)
6
+ */
7
+ parse: (raw) => {
8
+ const hash = {};
9
+ const regexp = /^([^=]*[^\t= ])[\t ]*=[\t ]*(.*)$/;
10
+ const r = raw.replace(/\r\n/g, "\n").split("\n");
11
+ while (r.length) {
12
+ const row = r.shift();
13
+ let m;
14
+ if (row) {
15
+ m = row.match(regexp);
16
+ if (m) {
17
+ const mm = m[1].match(/^property\[([^\]]*)\]/i);
18
+ if (mm) {
19
+ if (!Object.prototype.hasOwnProperty.call(hash, "PROPERTY")) {
20
+ hash.PROPERTY = {};
21
+ }
22
+ mm[1] = mm[1].toUpperCase().replace(/\s/g, "");
23
+ if (!Object.prototype.hasOwnProperty.call(hash.PROPERTY, mm[1])) {
24
+ hash.PROPERTY[mm[1]] = [];
25
+ }
26
+ hash.PROPERTY[mm[1]].push(m[2].replace(/[\t ]*$/, ""));
27
+ }
28
+ else {
29
+ hash[m[1].toUpperCase()] = m[2].replace(/[\t ]*$/, "");
30
+ }
31
+ }
32
+ }
33
+ }
34
+ return hash;
35
+ },
36
+ };
@@ -0,0 +1,65 @@
1
+ import { Response } from "./response.js";
2
+ /**
3
+ * ResponseTemplateManager Singleton Class
4
+ */
5
+ export declare class ResponseTemplateManager {
6
+ /**
7
+ * Get ResponseTemplateManager Instance
8
+ * @returns ResponseTemplateManager Instance
9
+ */
10
+ static getInstance(): ResponseTemplateManager;
11
+ /**
12
+ * ResponseTemplateManager Instance
13
+ */
14
+ private static instance;
15
+ /**
16
+ * template container
17
+ */
18
+ templates: any;
19
+ private constructor();
20
+ /**
21
+ * Generate API response template string for given code and description
22
+ * @param code API response code
23
+ * @param description API response description
24
+ * @returns generate response template string
25
+ */
26
+ generateTemplate(code: string, description: string): string;
27
+ /**
28
+ * Add response template to template container
29
+ * @param id template id
30
+ * @param plain API plain response
31
+ * @returns ResponseTemplateManager instance for method chaining
32
+ */
33
+ addTemplate(id: string, plain: string): ResponseTemplateManager;
34
+ /**
35
+ * Get response template instance from template container
36
+ * @param id template id
37
+ * @returns template instance
38
+ */
39
+ getTemplate(id: string): Response;
40
+ /**
41
+ * Return all available response templates
42
+ * @returns all available response template instances
43
+ */
44
+ getTemplates(): any;
45
+ /**
46
+ * Check if given template exists in template container
47
+ * @param id template id
48
+ * @returns boolean result
49
+ */
50
+ hasTemplate(id: string): boolean;
51
+ /**
52
+ * Check if given API response hash matches a given template by code and description
53
+ * @param tpl2 api response hash
54
+ * @param id template id
55
+ * @returns boolean result
56
+ */
57
+ isTemplateMatchHash(tpl2: any, id: string): boolean;
58
+ /**
59
+ * Check if given API plain response matches a given template by code and description
60
+ * @param plain API plain response
61
+ * @param id template id
62
+ * @returns boolean result
63
+ */
64
+ isTemplateMatchPlain(plain: string, id: string): boolean;
65
+ }