@oino-ts/common 0.1.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.
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OINOStr = void 0;
4
+ const _1 = require(".");
5
+ /**
6
+ * Static class string utilities.
7
+ *
8
+ */
9
+ class OINOStr {
10
+ /**
11
+ * Split string by the top level of the given type of brackets.
12
+ * E.g. splitByBrackets("a(bc(d))ef(gh)kl", true, true, '(', ')') would return ["a", "bc(d)", "ef", "gh", "kl"]
13
+ *
14
+ * @param str string to split
15
+ * @param includePartsBetweenBlocks whether to include strings between top level brackets
16
+ * @param includeTrailingUnescapedBlock whether to include final block that is missing necessary end brackets
17
+ * @param startBracket starting bracket, e.g. '('
18
+ * @param endBracket ending bracket, e.g. ')'
19
+ *
20
+ */
21
+ static splitByBrackets(str, includePartsBetweenBlocks, includeTrailingUnescapedBlock, startBracket, endBracket) {
22
+ let result = [];
23
+ let parenthesis_count = 0;
24
+ let start = 0;
25
+ let end = 0;
26
+ while (end < str.length) {
27
+ if (str[end] == startBracket) {
28
+ if (parenthesis_count == 0) {
29
+ if ((end > start) && includePartsBetweenBlocks) { // there is some first level string to add to result
30
+ result.push(str.substring(start, end));
31
+ }
32
+ start = end + 1;
33
+ }
34
+ parenthesis_count++;
35
+ }
36
+ else if (str[end] == endBracket) {
37
+ parenthesis_count--;
38
+ if (parenthesis_count == 0) {
39
+ if (end >= start) {
40
+ result.push(str.substring(start, end));
41
+ }
42
+ start = end + 1;
43
+ }
44
+ }
45
+ end++;
46
+ }
47
+ if ((end > start) && ((includePartsBetweenBlocks && (parenthesis_count == 0)) || (includeTrailingUnescapedBlock && (parenthesis_count > 0)))) { // if there is stuff after last block or unfinished block (and those are supported)
48
+ result.push(str.substring(start, end)); // i == str.length
49
+ }
50
+ return result;
51
+ }
52
+ /**
53
+ * Split string by delimeter excluding delimeters inside given brackets.
54
+ * E.g. splitExcludingBrackets("a,(bc,d),ef,(g,h),k", ',', '(', ')') would return ["a", "bc,d", "ef", "g,h", "k"]
55
+ *
56
+ * @param str string to split
57
+ * @param delimeter string to use as delimeter
58
+ * @param startBracket starting bracket, e.g. '('
59
+ * @param endBracket ending bracket, e.g. ')'
60
+ */
61
+ static splitExcludingBrackets(str, delimeter, startBracket, endBracket) {
62
+ let result = [];
63
+ let bracket_level = 0;
64
+ let start = 0;
65
+ let end = 0;
66
+ while (end < str.length) {
67
+ if (str[end] == startBracket) {
68
+ bracket_level++;
69
+ }
70
+ else if (str[end] == endBracket) {
71
+ bracket_level--;
72
+ }
73
+ else if ((str[end] == delimeter) && (bracket_level == 0)) { // only delimeters at top level will break
74
+ result.push(str.substring(start, end));
75
+ start = end + 1;
76
+ }
77
+ end++;
78
+ }
79
+ if (end > start) {
80
+ result.push(str.substring(start, end)); // i == str.length
81
+ }
82
+ return result;
83
+ }
84
+ /**
85
+ * Encode OINO serialized strings as valid JSON.
86
+ *
87
+ * @param str string to encode
88
+ * @param valueType wether it is a value type
89
+ */
90
+ static encodeJSON(str, valueType = false) {
91
+ if (str === undefined) { // no undefined literal in JSON
92
+ return "null";
93
+ }
94
+ else if (str === null) {
95
+ return "null";
96
+ }
97
+ else {
98
+ if (valueType) {
99
+ return str;
100
+ }
101
+ else {
102
+ return JSON.stringify(str);
103
+ }
104
+ }
105
+ }
106
+ /**
107
+ * Decode JSON string as OINO serialization.
108
+ *
109
+ * @param str string to decode
110
+ */
111
+ static decodeJSON(str) {
112
+ return str; // JSON parsing using JS methods, no need to decode anything
113
+ }
114
+ /**
115
+ * Encode OINO serialized strings as valid CSV.
116
+ *
117
+ * @param str string to encode
118
+ */
119
+ static encodeCSV(str) {
120
+ if (str === undefined) {
121
+ return "";
122
+ }
123
+ else if (str === null) {
124
+ return "null";
125
+ }
126
+ else {
127
+ return "\"" + str.replaceAll("\"", "\"\"") + "\"";
128
+ }
129
+ }
130
+ /**
131
+ * Decode CSV string as OINO serialization.
132
+ *
133
+ * @param str string to decode
134
+ */
135
+ static decodeCSV(str) {
136
+ return str.replaceAll("\"\"", "\"");
137
+ }
138
+ /**
139
+ * Encode OINO serialized strings as valid Formdata.
140
+ *
141
+ * @param str string to encode
142
+ */
143
+ static encodeFormdata(str) {
144
+ if (str === undefined) {
145
+ return "";
146
+ }
147
+ else if (str === null) {
148
+ return "";
149
+ }
150
+ else {
151
+ return str;
152
+ }
153
+ }
154
+ /**
155
+ * Decode Formdata string as OINO serialization.
156
+ *
157
+ * @param str string to decode
158
+ */
159
+ static decodeFormdata(str) {
160
+ return str;
161
+ }
162
+ /**
163
+ * Encode OINO serialized strings as valid Urlencode.
164
+ *
165
+ * @param str string to encode
166
+ */
167
+ static encodeUrlencode(str) {
168
+ if (str === undefined) {
169
+ return "";
170
+ }
171
+ else if (str === null) {
172
+ return "null";
173
+ }
174
+ else {
175
+ return encodeURIComponent(str);
176
+ }
177
+ }
178
+ /**
179
+ * Decode Urlencode string as OINO serialization.
180
+ *
181
+ * @param str string to decode
182
+ */
183
+ static decodeUrlencode(str) {
184
+ return decodeURIComponent(str);
185
+ }
186
+ /**
187
+ * Encode OINO serialized strings as valid HTML content.
188
+ *
189
+ * @param str string to encode
190
+ */
191
+ static encodeHtml(str) {
192
+ if (str === undefined) {
193
+ return "";
194
+ }
195
+ else if (str === null) {
196
+ return "";
197
+ }
198
+ else {
199
+ return str.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&#039;');
200
+ }
201
+ }
202
+ /**
203
+ * Decode HTML string as OINO serialization.
204
+ *
205
+ * @param str string to encode
206
+ */
207
+ static decodeHtml(str) {
208
+ return str.replaceAll('&amp;', '&').replaceAll('&lt;', '<').replaceAll('&gt;', '>').replaceAll('&quot;', '"').replaceAll('&#039;', "'");
209
+ }
210
+ /**
211
+ * Decode content type formatted string as OINO serialization.
212
+ *
213
+ * @param str string to decode
214
+ * @param contentType content type for serialization
215
+ *
216
+ */
217
+ static decode(str, contentType) {
218
+ if (contentType == _1.OINOContentType.csv) {
219
+ return this.decodeCSV(str);
220
+ }
221
+ else if (contentType == _1.OINOContentType.json) {
222
+ return this.decodeJSON(str);
223
+ }
224
+ else if (contentType == _1.OINOContentType.formdata) {
225
+ return this.decodeFormdata(str);
226
+ }
227
+ else if (contentType == _1.OINOContentType.urlencode) {
228
+ return this.decodeUrlencode(str);
229
+ }
230
+ else if (contentType == _1.OINOContentType.html) {
231
+ return str;
232
+ }
233
+ else {
234
+ return str;
235
+ }
236
+ }
237
+ /**
238
+ * Encode OINO serialized string to the content type formatting.
239
+ *
240
+ * @param str string to encode
241
+ * @param contentType content type for serialization
242
+ *
243
+ */
244
+ static encode(str, contentType) {
245
+ if (contentType == _1.OINOContentType.csv) {
246
+ return this.encodeCSV(str);
247
+ }
248
+ else if (contentType == _1.OINOContentType.json) {
249
+ return this.encodeJSON(str);
250
+ }
251
+ else if (contentType == _1.OINOContentType.formdata) {
252
+ return this.encodeFormdata(str);
253
+ }
254
+ else if (contentType == _1.OINOContentType.urlencode) {
255
+ return this.encodeUrlencode(str);
256
+ }
257
+ else if (contentType == _1.OINOContentType.html) {
258
+ return this.encodeHtml(str);
259
+ }
260
+ else {
261
+ return str || "";
262
+ }
263
+ }
264
+ }
265
+ exports.OINOStr = OINOStr;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OINOContentType = exports.OINO_DEBUG_PREFIX = exports.OINO_INFO_PREFIX = exports.OINO_WARNING_PREFIX = exports.OINO_ERROR_PREFIX = exports.OINOHtmlTemplate = exports.OINOStr = exports.OINOHttpResult = exports.OINOResult = exports.OINOConsoleLog = exports.OINOLogLevel = exports.OINOLog = exports.OINOBenchmark = void 0;
4
+ var OINOBenchmark_js_1 = require("./OINOBenchmark.js");
5
+ Object.defineProperty(exports, "OINOBenchmark", { enumerable: true, get: function () { return OINOBenchmark_js_1.OINOBenchmark; } });
6
+ var OINOLog_js_1 = require("./OINOLog.js");
7
+ Object.defineProperty(exports, "OINOLog", { enumerable: true, get: function () { return OINOLog_js_1.OINOLog; } });
8
+ Object.defineProperty(exports, "OINOLogLevel", { enumerable: true, get: function () { return OINOLog_js_1.OINOLogLevel; } });
9
+ Object.defineProperty(exports, "OINOConsoleLog", { enumerable: true, get: function () { return OINOLog_js_1.OINOConsoleLog; } });
10
+ var OINOResult_js_1 = require("./OINOResult.js");
11
+ Object.defineProperty(exports, "OINOResult", { enumerable: true, get: function () { return OINOResult_js_1.OINOResult; } });
12
+ Object.defineProperty(exports, "OINOHttpResult", { enumerable: true, get: function () { return OINOResult_js_1.OINOHttpResult; } });
13
+ var OINOStr_js_1 = require("./OINOStr.js");
14
+ Object.defineProperty(exports, "OINOStr", { enumerable: true, get: function () { return OINOStr_js_1.OINOStr; } });
15
+ var OINOHtmlTemplate_js_1 = require("./OINOHtmlTemplate.js");
16
+ Object.defineProperty(exports, "OINOHtmlTemplate", { enumerable: true, get: function () { return OINOHtmlTemplate_js_1.OINOHtmlTemplate; } });
17
+ /** OINO error message prefix */
18
+ exports.OINO_ERROR_PREFIX = "OINO ERROR";
19
+ /** OINO warning message prefix */
20
+ exports.OINO_WARNING_PREFIX = "OINO WARNING";
21
+ /** OINO info message prefix */
22
+ exports.OINO_INFO_PREFIX = "OINO INFO";
23
+ /** OINO debug message prefix */
24
+ exports.OINO_DEBUG_PREFIX = "OINO DEBUG";
25
+ /**
26
+ * Supported content format mime-types
27
+ */
28
+ var OINOContentType;
29
+ (function (OINOContentType) {
30
+ /** JSON encoded data */
31
+ OINOContentType["json"] = "application/json";
32
+ /** CSV encoded data */
33
+ OINOContentType["csv"] = "text/csv";
34
+ /** Multipart encoded form data */
35
+ OINOContentType["formdata"] = "multipart/form-data";
36
+ /** URL encoded form data */
37
+ OINOContentType["urlencode"] = "application/x-www-form-urlencoded";
38
+ /** HTML encoded data (output only) */
39
+ OINOContentType["html"] = "text/html";
40
+ })(OINOContentType || (exports.OINOContentType = OINOContentType = {}));
@@ -0,0 +1,104 @@
1
+ /*
2
+ * This Source Code Form is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
+ */
6
+ /**
7
+ * Static class for benchmarking functions.
8
+ *
9
+ */
10
+ export class OINOBenchmark {
11
+ static _benchmarkCount = {};
12
+ static _benchmarkData = {};
13
+ static _benchmarkEnabled = {};
14
+ static _benchmarkStart = {};
15
+ /**
16
+ * Reset benchmark data (but not what is enabled).
17
+ *
18
+ */
19
+ static reset() {
20
+ this._benchmarkData = {};
21
+ this._benchmarkCount = {};
22
+ }
23
+ /**
24
+ * Set benchmark names that are enabled.
25
+ *
26
+ * @param module array of those benchmarks that are enabled
27
+ */
28
+ static setEnabled(module) {
29
+ this._benchmarkEnabled = {};
30
+ module.forEach(module_name => {
31
+ this._benchmarkEnabled[module_name] = true;
32
+ });
33
+ }
34
+ /**
35
+ * Start benchmark timing.
36
+ *
37
+ * @param module of the benchmark
38
+ * @param method of the benchmark
39
+ */
40
+ static start(module, method) {
41
+ const name = module + "." + method;
42
+ if (this._benchmarkEnabled[module]) {
43
+ if (this._benchmarkCount[name] == undefined) {
44
+ this._benchmarkCount[name] = 0;
45
+ this._benchmarkData[name] = 0;
46
+ }
47
+ this._benchmarkStart[name] = performance.now();
48
+ }
49
+ }
50
+ /**
51
+ * Complete benchmark timing
52
+ *
53
+ * @param module of the benchmark
54
+ * @param method of the benchmark
55
+ * @param category optional subcategory of the benchmark
56
+ */
57
+ static end(module, method, category) {
58
+ const name = module + "." + method;
59
+ let result = 0;
60
+ if (this._benchmarkEnabled[module]) {
61
+ const duration = performance.now() - this._benchmarkStart[name];
62
+ this._benchmarkCount[name] += 1;
63
+ this._benchmarkData[name] += duration;
64
+ if (category) {
65
+ const category_name = name + "." + category;
66
+ if (this._benchmarkCount[category_name] == undefined) {
67
+ this._benchmarkCount[category_name] = 0;
68
+ this._benchmarkData[category_name] = 0;
69
+ }
70
+ this._benchmarkCount[category_name] += 1;
71
+ this._benchmarkData[category_name] += duration;
72
+ }
73
+ result = this._benchmarkData[name] / this._benchmarkCount[name];
74
+ }
75
+ return result;
76
+ }
77
+ /**
78
+ * Get given benchmark data.
79
+ *
80
+ * @param module of the benchmark
81
+ * @param method of the benchmark
82
+ *
83
+ */
84
+ static get(module, method) {
85
+ const name = module + "." + method;
86
+ if (this._benchmarkEnabled[module]) {
87
+ return this._benchmarkData[module] / this._benchmarkCount[module];
88
+ }
89
+ return -1;
90
+ }
91
+ /**
92
+ * Get all benchmark data.
93
+ *
94
+ */
95
+ static getAll() {
96
+ let result = {};
97
+ for (const name in this._benchmarkData) {
98
+ if (this._benchmarkCount[name] > 0) {
99
+ result[name] = this._benchmarkData[name] / this._benchmarkCount[name];
100
+ }
101
+ }
102
+ return result;
103
+ }
104
+ }
@@ -0,0 +1,173 @@
1
+ import { OINOStr, OINOContentType, OINOHttpResult, OINO_ERROR_PREFIX, OINO_WARNING_PREFIX, OINO_INFO_PREFIX, OINO_DEBUG_PREFIX, OINOBenchmark } from ".";
2
+ /**
3
+ * Class for rendering HTML from data.
4
+ */
5
+ export class OINOHtmlTemplate {
6
+ _tag;
7
+ _tagCleanRegex;
8
+ _variables = {};
9
+ /** HTML template string */
10
+ template;
11
+ /** Cache modified value for template */
12
+ modified;
13
+ /** Cache expiration value for template */
14
+ expires;
15
+ /**
16
+ * Creates HTML Response from a key-value-pair.
17
+ *
18
+ * @param template template string
19
+ * @param tag tag to identify variables in template
20
+ *
21
+ */
22
+ constructor(template, tag = "###") {
23
+ this.template = template;
24
+ this.modified = 0;
25
+ this.expires = 0;
26
+ this._tag = tag;
27
+ this._tagCleanRegex = new RegExp(tag + ".*" + tag, "g");
28
+ }
29
+ /**
30
+ * @returns whether template is empty
31
+ */
32
+ isEmpty() {
33
+ return this.template == "";
34
+ }
35
+ _createHttpResult(html, removeUnusedTags) {
36
+ if (removeUnusedTags) {
37
+ html = html.replace(this._tagCleanRegex, "");
38
+ }
39
+ const result = new OINOHttpResult(html);
40
+ if (this.expires >= 1) {
41
+ result.expires = Math.round(this.expires);
42
+ }
43
+ if (this.modified >= 1) {
44
+ result.lastModified = this.modified;
45
+ }
46
+ return result;
47
+ }
48
+ _renderHtml() {
49
+ let html = this.template;
50
+ for (let key in this._variables) {
51
+ const value = this._variables[key];
52
+ html = html.replaceAll(this._tag + key + this._tag, value);
53
+ }
54
+ return html;
55
+ }
56
+ /**
57
+ * Clear template variables.
58
+ *
59
+ */
60
+ clearVariables() {
61
+ this._variables = {};
62
+ }
63
+ /**
64
+ * Sets template variable from a key-value-pair.
65
+ *
66
+ * @param variable key
67
+ * @param value value
68
+ * @param escapeValue whether to escape value
69
+ *
70
+ */
71
+ setVariableFromValue(variable, value, escapeValue = true) {
72
+ if (escapeValue) {
73
+ value = OINOStr.encode(value, OINOContentType.html);
74
+ }
75
+ this._variables[variable] = value;
76
+ }
77
+ /**
78
+ * Sets template variables from object properties.
79
+ *
80
+ * @param object any object
81
+ * @param escapeValue whether to escape value
82
+ *
83
+ */
84
+ setVariableFromProperties(object, escapeValue = true) {
85
+ if (object) {
86
+ for (let key in object) {
87
+ if (escapeValue) {
88
+ this._variables[key] = OINOStr.encode(object[key], OINOContentType.html);
89
+ }
90
+ else {
91
+ this._variables[key] = object[key];
92
+ }
93
+ }
94
+ }
95
+ }
96
+ /**
97
+ * Creates HTML Response from set variables.
98
+ *
99
+ * @param removeUnusedTags whether to remove unused tags
100
+ *
101
+ */
102
+ render(removeUnusedTags = true) {
103
+ return this._createHttpResult(this._renderHtml(), removeUnusedTags);
104
+ }
105
+ /**
106
+ * Creates HTML Response from a key-value-pair.
107
+ *
108
+ * @param key key
109
+ * @param value value
110
+ * @param removeUnusedTags whether to remove unused tags
111
+ *
112
+ */
113
+ renderFromKeyValue(key, value, removeUnusedTags = true) {
114
+ OINOBenchmark.start("OINOHtmlTemplate", "renderFromKeyValue");
115
+ this.setVariableFromValue(key, value);
116
+ const result = this.render(removeUnusedTags);
117
+ OINOBenchmark.end("OINOHtmlTemplate", "renderFromKeyValue");
118
+ return result;
119
+ }
120
+ /**
121
+ * Creates HTML Response from object properties.
122
+ *
123
+ * @param object object
124
+ * @param removeUnusedTags whether to remove unused tags
125
+ *
126
+ */
127
+ renderFromObject(object, removeUnusedTags = true) {
128
+ OINOBenchmark.start("OINOHtmlTemplate", "renderFromObject");
129
+ this.setVariableFromProperties(object);
130
+ const result = this.render(removeUnusedTags);
131
+ OINOBenchmark.end("OINOHtmlTemplate", "renderFromObject");
132
+ return result;
133
+ }
134
+ /**
135
+ * Creates HTML Response from API result.
136
+ *
137
+ * @param result OINOResult-object
138
+ * @param removeUnusedTags whether to remove unused tags
139
+ * @param messageSeparator HTML separator for messages
140
+ * @param includeErrorMessages include debug messages in result
141
+ * @param includeWarningMessages include debug messages in result
142
+ * @param includeInfoMessages include debug messages in result
143
+ * @param includeDebugMessages include debug messages in result
144
+ *
145
+ */
146
+ renderFromResult(result, removeUnusedTags = true, messageSeparator, includeErrorMessages = false, includeWarningMessages = false, includeInfoMessages = false, includeDebugMessages = false) {
147
+ OINOBenchmark.start("OINOHtmlTemplate", "renderFromResult");
148
+ this.setVariableFromValue("statusCode", result.statusCode.toString());
149
+ this.setVariableFromValue("statusMessage", result.statusMessage.toString());
150
+ let messages = [];
151
+ for (let i = 0; i < result.messages.length; i++) {
152
+ if (includeErrorMessages && result.messages[i].startsWith(OINO_ERROR_PREFIX)) {
153
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html));
154
+ }
155
+ if (includeWarningMessages && result.messages[i].startsWith(OINO_WARNING_PREFIX)) {
156
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html));
157
+ }
158
+ if (includeInfoMessages && result.messages[i].startsWith(OINO_INFO_PREFIX)) {
159
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html));
160
+ }
161
+ if (includeDebugMessages && result.messages[i].startsWith(OINO_DEBUG_PREFIX)) {
162
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html));
163
+ }
164
+ }
165
+ if (messages.length > 0) {
166
+ this.setVariableFromValue("messages", messages.join(messageSeparator), false); // messages have been escaped already
167
+ }
168
+ const http_result = this.render(removeUnusedTags);
169
+ OINOBenchmark.end("OINOHtmlTemplate", "renderFromResult");
170
+ return http_result;
171
+ }
172
+ }
173
+ ;