@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,111 @@
1
+ import { ResponseParser } from "./responseparser.js";
2
+ import { Response } from "./response.js";
3
+ /**
4
+ * ResponseTemplateManager Singleton Class
5
+ */
6
+ export class ResponseTemplateManager {
7
+ /**
8
+ * Get ResponseTemplateManager Instance
9
+ * @returns ResponseTemplateManager Instance
10
+ */
11
+ static getInstance() {
12
+ if (!ResponseTemplateManager.instance) {
13
+ ResponseTemplateManager.instance = new ResponseTemplateManager();
14
+ }
15
+ return ResponseTemplateManager.instance;
16
+ }
17
+ /**
18
+ * ResponseTemplateManager Instance
19
+ */
20
+ static instance;
21
+ /**
22
+ * template container
23
+ */
24
+ templates;
25
+ constructor() {
26
+ this.templates = {
27
+ 404: this.generateTemplate("421", "Page not found"),
28
+ 500: this.generateTemplate("500", "Internal server error"),
29
+ empty: this.generateTemplate("423", "Empty API response. Probably unreachable API end point {CONNECTION_URL}"),
30
+ error: this.generateTemplate("421", "Command failed due to server error. Client should try again"),
31
+ expired: this.generateTemplate("530", "SESSIONID NOT FOUND"),
32
+ httperror: this.generateTemplate("421", "Command failed due to HTTP communication error"),
33
+ invalid: this.generateTemplate("423", "Invalid API response. Contact Support"),
34
+ nocurl: this.generateTemplate("423", "API access error: curl_init failed"),
35
+ notfound: this.generateTemplate("500", "Response Template not found"),
36
+ unauthorized: this.generateTemplate("500", "Unauthorized"),
37
+ };
38
+ }
39
+ /**
40
+ * Generate API response template string for given code and description
41
+ * @param code API response code
42
+ * @param description API response description
43
+ * @returns generate response template string
44
+ */
45
+ generateTemplate(code, description) {
46
+ return `[RESPONSE]\r\nCODE=${code}\r\nDESCRIPTION=${description}\r\nEOF\r\n`;
47
+ }
48
+ /**
49
+ * Add response template to template container
50
+ * @param id template id
51
+ * @param plain API plain response
52
+ * @returns ResponseTemplateManager instance for method chaining
53
+ */
54
+ addTemplate(id, plain) {
55
+ this.templates[id] = plain;
56
+ return ResponseTemplateManager.instance;
57
+ }
58
+ /**
59
+ * Get response template instance from template container
60
+ * @param id template id
61
+ * @returns template instance
62
+ */
63
+ getTemplate(id) {
64
+ if (this.hasTemplate(id)) {
65
+ return new Response(id);
66
+ }
67
+ console.log("template id " + id);
68
+ return new Response("notfound");
69
+ }
70
+ /**
71
+ * Return all available response templates
72
+ * @returns all available response template instances
73
+ */
74
+ getTemplates() {
75
+ const tpls = {};
76
+ Object.keys(this.templates).forEach((key) => {
77
+ tpls[key] = new Response(key);
78
+ });
79
+ return tpls;
80
+ }
81
+ /**
82
+ * Check if given template exists in template container
83
+ * @param id template id
84
+ * @returns boolean result
85
+ */
86
+ hasTemplate(id) {
87
+ return Object.prototype.hasOwnProperty.call(this.templates, id);
88
+ }
89
+ /**
90
+ * Check if given API response hash matches a given template by code and description
91
+ * @param tpl2 api response hash
92
+ * @param id template id
93
+ * @returns boolean result
94
+ */
95
+ isTemplateMatchHash(tpl2, id) {
96
+ const h = this.getTemplate(id).getHash();
97
+ return h.CODE === tpl2.CODE && h.DESCRIPTION === tpl2.DESCRIPTION;
98
+ }
99
+ /**
100
+ * Check if given API plain response matches a given template by code and description
101
+ * @param plain API plain response
102
+ * @param id template id
103
+ * @returns boolean result
104
+ */
105
+ isTemplateMatchPlain(plain, id) {
106
+ const h = this.getTemplate(id).getHash();
107
+ const tpl2 = ResponseParser.parse(plain);
108
+ return h.CODE === tpl2.CODE && h.DESCRIPTION === tpl2.DESCRIPTION;
109
+ }
110
+ }
111
+ ResponseTemplateManager.getInstance();
@@ -0,0 +1,32 @@
1
+ /**
2
+ * ResponseTranslator class
3
+ */
4
+ export declare class ResponseTranslator {
5
+ /**
6
+ * Regular Expression Mapping for API DESCRIPTION Property translation
7
+ */
8
+ private static descriptionRegexMap;
9
+ /**
10
+ * translate a raw api response
11
+ * @param raw API raw response
12
+ * @param cmd requested API command
13
+ * @param ph list of place holder vars
14
+ * @returns new translated raw response
15
+ */
16
+ static translate(raw: string, cmd: any, ph?: any): string;
17
+ /**
18
+ * Finds a match in the given text and performs replacements based on patterns and placeholders.
19
+ *
20
+ * This function searches for a specified regular expression pattern in the provided text and
21
+ * performs replacements based on the matched pattern, command data, and placeholder values.
22
+ *
23
+ * @param regex The regular expression pattern to search for.
24
+ * @param newraw The input text where the match will be searched for.
25
+ * @param val The value to be used in replacement if a match is found.
26
+ * @param cmd The command data containing replacements, if applicable.
27
+ * @param ph An array of placeholder values for further replacements.
28
+ *
29
+ * @return Returns non-empty string if replacements were performed, empty string otherwise.
30
+ */
31
+ protected static findMatch(regex: string, newraw: string, val: string, cmd?: any, ph?: any): string;
32
+ }
@@ -0,0 +1,144 @@
1
+ import { ResponseTemplateManager as RTM } from "./responsetemplatemanager.js";
2
+ function preg_quote(str, delimiter = "") {
3
+ // MIT, from: https://locutus.io/php/preg_quote/
4
+ return (str + "").replace(new RegExp("[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\" + delimiter + "-]", "g"), "\\$&");
5
+ }
6
+ /**
7
+ * ResponseTranslator class
8
+ */
9
+ export class ResponseTranslator {
10
+ /**
11
+ * Regular Expression Mapping for API DESCRIPTION Property translation
12
+ */
13
+ static descriptionRegexMap = {
14
+ // HX
15
+ "Authorization failed; Operation forbidden by ACL": "Authorization failed; Used Command `{COMMAND}` not white-listed by your Access Control List",
16
+ "Request is not available; DOMAIN TRANSFER IS PROHIBITED BY STATUS (clientTransferProhibited)/WRONG AUTH": "This Domain is locked and the given Authorization Code is wrong. Initiating a Transfer is therefore impossible.",
17
+ "Request is not available; DOMAIN TRANSFER IS PROHIBITED BY STATUS (clientTransferProhibited)": "This Domain is locked. Initiating a Transfer is therefore impossible.",
18
+ "Request is not available; DOMAIN TRANSFER IS PROHIBITED BY STATUS (requested)": "Registration of this Domain Name has not yet completed. Initiating a Transfer is therefore impossible.",
19
+ "Request is not available; DOMAIN TRANSFER IS PROHIBITED BY STATUS (requestedcreate)": "Registration of this Domain Name has not yet completed. Initiating a Transfer is therefore impossible.",
20
+ "Request is not available; DOMAIN TRANSFER IS PROHIBITED BY STATUS (requesteddelete)": "Deletion of this Domain Name has been requested. Initiating a Transfer is therefore impossible.",
21
+ "Request is not available; DOMAIN TRANSFER IS PROHIBITED BY STATUS (pendingdelete)": "Deletion of this Domain Name is pending. Initiating a Transfer is therefore impossible.",
22
+ "Request is not available; DOMAIN TRANSFER IS PROHIBITED BY WRONG AUTH": "The given Authorization Code is wrong. Initiating a Transfer is therefore impossible.",
23
+ "Request is not available; DOMAIN TRANSFER IS PROHIBITED BY AGE OF THE DOMAIN": "This Domain Name is within 60 days of initial registration. Initiating a Transfer is therefore impossible.",
24
+ "Attribute value is not unique; DOMAIN is already assigned to your account": "You cannot transfer a domain that is already on your account at the registrar's system.",
25
+ // CNR
26
+ "Missing required attribute; premium domain name. please provide required parameters": "Confirm the Premium pricing by providing the necessary premium domain price data.",
27
+ SkipPregQuote: {
28
+ // HX
29
+ "Invalid attribute value syntax; resource record [(.+)]": "Invalid Syntax for DNSZone Resource Record: $1",
30
+ "Missing required attribute; CLASS(?:=| [MUST BE )PREMIUM_([w+]+)[s]]": "Confirm the Premium pricing by providing the parameter CLASS with the value PREMIUM_$1.",
31
+ "Syntax error in Parameter DOMAIN ((.+))": "The Domain Name $1 is invalid.",
32
+ },
33
+ };
34
+ /**
35
+ * translate a raw api response
36
+ * @param raw API raw response
37
+ * @param cmd requested API command
38
+ * @param ph list of place holder vars
39
+ * @returns new translated raw response
40
+ */
41
+ static translate(raw, cmd, ph = {}) {
42
+ let httperror = "";
43
+ let newraw = raw || "empty";
44
+ // Hint: Empty API Response (replace {CONNECTION_URL} later)
45
+ // curl error handling
46
+ const isHTTPError = newraw.substring(0, 10) === "httperror|";
47
+ if (isHTTPError) {
48
+ [newraw, httperror] = newraw.split("|");
49
+ }
50
+ // Explicit call for a static template
51
+ if (RTM.getInstance().hasTemplate(newraw)) {
52
+ // don't use getTemplate as it leads to endless loop as of again
53
+ // creating a response instance
54
+ newraw = RTM.getInstance().templates[newraw];
55
+ if (isHTTPError && httperror.length) {
56
+ newraw = newraw.replace(/\{HTTPERROR\}/, " (" + httperror + ")");
57
+ }
58
+ }
59
+ // Missing CODE or DESCRIPTION in API Response
60
+ if ((!/description[\s]*=/i.test(newraw) || // missing description
61
+ /description[\s]*=\r\n/i.test(newraw) || // empty description
62
+ !/code[\s]*=/i.test(newraw)) && // missing code
63
+ RTM.getInstance().hasTemplate("invalid")) {
64
+ newraw = RTM.getInstance().templates.invalid;
65
+ }
66
+ // Iterate through the description-to-regex mapping
67
+ // generic API response description rewrite
68
+ let data = "";
69
+ for (const [regex, val] of Object.entries(ResponseTranslator.descriptionRegexMap)) {
70
+ // Check if regex should be treated as multiple patterns
71
+ if (regex === "SkipPregQuote") {
72
+ // Iterate through each temporary pattern in val
73
+ for (const [tmpregex, tmpval] of Object.entries(val)) {
74
+ // Attempt to find a match using the temporary pattern
75
+ data = ResponseTranslator.findMatch(tmpregex, newraw, "" + tmpval, cmd, ph);
76
+ // If a match is found, exit the inner loop
77
+ if (data) {
78
+ newraw = data;
79
+ break;
80
+ }
81
+ }
82
+ }
83
+ else {
84
+ // Escape the pattern and attempt to find a match for it
85
+ const escapedregex = preg_quote(regex);
86
+ console.log(newraw);
87
+ data = ResponseTranslator.findMatch(escapedregex, newraw, val, cmd, ph);
88
+ console.log(newraw);
89
+ }
90
+ // If a match is found, exit the outer loop
91
+ if (data) {
92
+ newraw = data;
93
+ break;
94
+ }
95
+ }
96
+ const cregex = /\{.+\}/;
97
+ if (cregex.test(newraw)) {
98
+ newraw = newraw.replace(cregex, "");
99
+ }
100
+ return newraw;
101
+ }
102
+ /**
103
+ * Finds a match in the given text and performs replacements based on patterns and placeholders.
104
+ *
105
+ * This function searches for a specified regular expression pattern in the provided text and
106
+ * performs replacements based on the matched pattern, command data, and placeholder values.
107
+ *
108
+ * @param regex The regular expression pattern to search for.
109
+ * @param newraw The input text where the match will be searched for.
110
+ * @param val The value to be used in replacement if a match is found.
111
+ * @param cmd The command data containing replacements, if applicable.
112
+ * @param ph An array of placeholder values for further replacements.
113
+ *
114
+ * @return Returns non-empty string if replacements were performed, empty string otherwise.
115
+ */
116
+ static findMatch(regex, newraw, val, cmd = {}, ph = {}) {
117
+ // match the response for given description
118
+ // NOTE: we match if the description starts with the given description
119
+ // it would also match if it is followed by additional text
120
+ const qregex = new RegExp("/descriptions*=s*" + regex + "([^\\r\\n]+)?/i");
121
+ let ret = "";
122
+ if (qregex.test(newraw)) {
123
+ // If "COMMAND" exists in cmd, replace "{COMMAND}" in val
124
+ if (Object.prototype.hasOwnProperty.call(cmd, "COMMAND")) {
125
+ val = val.replace("{COMMAND}", cmd.COMMAND);
126
+ }
127
+ // If $newraw matches $qregex, replace with "description=" . $val
128
+ let tmp = newraw.replace(qregex, "description=" + val);
129
+ if (newraw !== tmp) {
130
+ ret = tmp;
131
+ }
132
+ }
133
+ // Generic replacing of placeholder vars
134
+ const vregex = /\{[^}]+\}/;
135
+ if (vregex.test(newraw)) {
136
+ for (const [tkey, tval] of Object.entries(ph)) {
137
+ newraw = newraw.replace("{" + tkey + "}", "" + tval);
138
+ }
139
+ newraw = newraw.replace(vregex, "");
140
+ ret = newraw;
141
+ }
142
+ return ret;
143
+ }
144
+ }
@@ -0,0 +1,62 @@
1
+ export declare const fixedURLEnc: (str: string) => string;
2
+ /**
3
+ * SocketConfig Class
4
+ */
5
+ export declare class SocketConfig {
6
+ /**
7
+ * account name
8
+ */
9
+ private login;
10
+ /**
11
+ * persistent for session request
12
+ */
13
+ private persistent;
14
+ /**
15
+ * account password
16
+ */
17
+ private pw;
18
+ /**
19
+ * API session id
20
+ */
21
+ private sessionid;
22
+ constructor();
23
+ /**
24
+ * Create POST data string out of connection data
25
+ * @returns POST data string
26
+ */
27
+ getPOSTData(): string;
28
+ /**
29
+ * Get API Session ID in use
30
+ * @returns API Session ID
31
+ */
32
+ getSession(): string;
33
+ /**
34
+ * Set account login to use
35
+ * @param value account login
36
+ * @returns Current SocketConfig instance for method chaining
37
+ */
38
+ setLogin(value: string): SocketConfig;
39
+ /**
40
+ * Get account login to use
41
+ * @returns Current login
42
+ */
43
+ getLogin(): string;
44
+ /**
45
+ * Set persistent to request session id
46
+ * @param value one time password
47
+ * @returns Current SocketConfig instance for method chaining
48
+ */
49
+ setPersistent(): SocketConfig;
50
+ /**
51
+ * Set account password to use
52
+ * @param value account password
53
+ * @returns Current SocketConfig instance for method chaining
54
+ */
55
+ setPassword(value: string): SocketConfig;
56
+ /**
57
+ * Set API Session ID to use
58
+ * @param value API Session ID
59
+ * @returns Current SocketConfig instance for method chaining
60
+ */
61
+ setSession(value: string): SocketConfig;
62
+ }
@@ -0,0 +1,107 @@
1
+ export const fixedURLEnc = (str) => {
2
+ return encodeURIComponent(str).replace(/[!'()*]/g, (c) => {
3
+ return `%${c.charCodeAt(0).toString(16).toUpperCase()}`;
4
+ });
5
+ };
6
+ /**
7
+ * SocketConfig Class
8
+ */
9
+ export class SocketConfig {
10
+ /**
11
+ * account name
12
+ */
13
+ login;
14
+ /**
15
+ * persistent for session request
16
+ */
17
+ persistent;
18
+ /**
19
+ * account password
20
+ */
21
+ pw;
22
+ /**
23
+ * API session id
24
+ */
25
+ sessionid;
26
+ constructor() {
27
+ this.login = "";
28
+ this.persistent = "";
29
+ this.pw = "";
30
+ this.sessionid = "";
31
+ }
32
+ /**
33
+ * Create POST data string out of connection data
34
+ * @returns POST data string
35
+ */
36
+ getPOSTData() {
37
+ let data = "";
38
+ if (this.login !== "") {
39
+ data += `${fixedURLEnc("s_login")}=${fixedURLEnc(this.login)}&`;
40
+ }
41
+ if (this.persistent !== "") {
42
+ data += `${fixedURLEnc("persistent")}=${fixedURLEnc(this.persistent)}&`;
43
+ }
44
+ if (this.pw !== "") {
45
+ data += `${fixedURLEnc("s_pw")}=${fixedURLEnc(this.pw)}&`;
46
+ }
47
+ if (this.sessionid !== "") {
48
+ data += `${fixedURLEnc("s_sessionid")}=${fixedURLEnc(this.sessionid)}&`;
49
+ }
50
+ return data;
51
+ }
52
+ /**
53
+ * Get API Session ID in use
54
+ * @returns API Session ID
55
+ */
56
+ getSession() {
57
+ return this.sessionid;
58
+ }
59
+ /**
60
+ * Set account login to use
61
+ * @param value account login
62
+ * @returns Current SocketConfig instance for method chaining
63
+ */
64
+ setLogin(value) {
65
+ this.sessionid = "";
66
+ this.login = value;
67
+ return this;
68
+ }
69
+ /**
70
+ * Get account login to use
71
+ * @returns Current login
72
+ */
73
+ getLogin() {
74
+ return this.login;
75
+ }
76
+ /**
77
+ * Set persistent to request session id
78
+ * @param value one time password
79
+ * @returns Current SocketConfig instance for method chaining
80
+ */
81
+ setPersistent() {
82
+ this.sessionid = "";
83
+ this.persistent = "1";
84
+ return this;
85
+ }
86
+ /**
87
+ * Set account password to use
88
+ * @param value account password
89
+ * @returns Current SocketConfig instance for method chaining
90
+ */
91
+ setPassword(value) {
92
+ this.sessionid = "";
93
+ this.pw = value;
94
+ return this;
95
+ }
96
+ /**
97
+ * Set API Session ID to use
98
+ * @param value API Session ID
99
+ * @returns Current SocketConfig instance for method chaining
100
+ */
101
+ setSession(value) {
102
+ this.sessionid = value;
103
+ this.pw = "";
104
+ this.persistent = "";
105
+ return this;
106
+ }
107
+ }
package/package.json ADDED
@@ -0,0 +1,86 @@
1
+ {
2
+ "name": "@team-internet/apiconnector",
3
+ "description": "Node.js SDK for the insanely fast CentralNic Reseller (fka RRPProxy) API",
4
+ "version": "10.0.0",
5
+ "private": false,
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "author": {
10
+ "name": "Kai Schwarz",
11
+ "email": "kai.schwarz@centralnic.com"
12
+ },
13
+ "sideEffects": false,
14
+ "type": "module",
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "//": "...",
18
+ "license": "MIT",
19
+ "engines": {
20
+ "node": ">=20.6.1"
21
+ },
22
+ "homepage": "https://github.com/centralnicgroup-opensource/rtldev-middleware-node-sdk",
23
+ "repository": "github:centralnicgroup-opensource/rtldev-middleware-node-sdk",
24
+ "bugs": "https://github.com/centralnicgroup-opensource/rtldev-middleware-node-sdk/issues",
25
+ "maintainers": [
26
+ {
27
+ "name": "Kai Schwarz",
28
+ "email": "kai.schwarz@centralnic.com"
29
+ },
30
+ {
31
+ "name": "Asif Nawaz",
32
+ "email": "asif.nawaz@centralnic.com"
33
+ }
34
+ ],
35
+ "keywords": [
36
+ "centralnicreseller",
37
+ "centralnic",
38
+ "cnr",
39
+ "domain",
40
+ "api",
41
+ "connector",
42
+ "ssl",
43
+ "cert",
44
+ "dns",
45
+ "backorder",
46
+ "premium",
47
+ "preregistration",
48
+ "registration",
49
+ "application"
50
+ ],
51
+ "scripts": {
52
+ "compile": "rm -rf dist && tsc --version && tsc --declaration",
53
+ "lint": "prettier --write .",
54
+ "prepublish": "npm run compile",
55
+ "documentation": "typedoc",
56
+ "test": "cross-env NODE_ENV=development c8 mocha",
57
+ "test-demo": "npm run prepublish && node ./tests/app.js"
58
+ },
59
+ "devDependencies": {
60
+ "@semantic-release/changelog": "^6.0.3",
61
+ "@semantic-release/git": "^10.0.1",
62
+ "@tsconfig/node20": "^20.1.4",
63
+ "@types/chai": "^4.3.19",
64
+ "@types/chai-as-promised": "^8.0.1",
65
+ "@types/mocha": "^10.0.9",
66
+ "@types/nock": "^10.0.3",
67
+ "@types/node": "^22.9.0",
68
+ "c8": "^10.1.2",
69
+ "chai": "^5.1.1",
70
+ "chai-as-promised": "^8.0.0",
71
+ "cross-env": "^7.0.3",
72
+ "mocha": "^10.8.2",
73
+ "nock": "^13.5.6",
74
+ "prettier": "^3.0.0",
75
+ "semantic-release": "^24.2.0",
76
+ "semantic-release-replace-plugin": "github:centralnicgroup-opensource/rtldev-middleware-semantic-release-replace-plugin",
77
+ "semantic-release-teams-notify-plugin": "github:centralnicgroup-opensource/rtldev-middleware-semantic-release-notify-plugin",
78
+ "tsx": "^4.19.2",
79
+ "typedoc": "^0.26.11",
80
+ "typescript": "^5.6.3"
81
+ },
82
+ "dependencies": {
83
+ "cross-fetch": "^4.0.0",
84
+ "idna-uts46-hx": "^6.0.5"
85
+ }
86
+ }