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