@oino-ts/types 0.0.14 → 0.0.16

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/README.md CHANGED
@@ -10,15 +10,15 @@
10
10
  # GETTING STARTED
11
11
 
12
12
  ### Setup
13
- Install the `@oino-ts/core` npm package and necessary database packages and import them in your code.
13
+ Install the `@oino-ts/db` npm package and necessary database packages and import them in your code.
14
14
  ```
15
- bun install @oino-ts/core
16
- bun install @oino-ts/bunsqlite
15
+ bun install @oino-ts/db
16
+ bun install @oino-ts/db-bunsqlite
17
17
  ```
18
18
 
19
19
  ```
20
- import { OINODb, OINOApi, OINOFactory } from "@oino-ts/core";
21
- import { OINODbBunSqlite } from "@oino-ts/bunsqlite"
20
+ import { OINODb, OINOApi, OINOFactory } from "@oino-ts/db";
21
+ import { OINODbBunSqlite } from "@oino-ts/db-bunsqlite"
22
22
  ```
23
23
 
24
24
  ### Register database and logger
@@ -51,7 +51,7 @@
51
51
  ### Write results back to HTTP Response
52
52
  The results for a GET request will contain [`OINOModelSet`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODbModelSet.html) data that can be written out as JSON or CSV as needed. For other requests result is just success or error with messages.
53
53
  ```
54
- return new Response(result.modelset.writeString(OINOContentType.json))
54
+ return new Response(result.data.writeString(OINOContentType.json))
55
55
  ```
56
56
 
57
57
 
@@ -129,12 +129,13 @@
129
129
  - Bun Sqlite through Bun native implementation
130
130
  - Postgresql through [pg](https://www.npmjs.com/package/pg)-package
131
131
  - Mariadb / Mysql-support through [mariadb](https://www.npmjs.com/package/mariadb)-package
132
+ - Sql Server through [mssql](https://www.npmjs.com/package/mssql)-package
132
133
 
133
134
  ## Complex Keys
134
135
  To support tables with multipart primary keys OINO generates a composite key `_OINOID_` that is included in the result and can be used as the REST ID. For example in the example above table `OrderDetails` has two primary keys `OrderID` and `ProductID` making the `_OINOID_` of form `11077:99`.
135
136
 
136
137
  ## Power Of SQL
137
- Since OINO controls the SQL, WHERE-conditions can be defined with [`OINOSqlFilter`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODbSqlFilter.html) and order with [`OINOSqlOrder`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODbSqlOrder.html) that are passed as HTTP request parameters. No more API development where you make unique API endpoints for each filter that fetch all data with original API and filter in backend code. Every API can be filtered when and as needed without unnessecary data tranfer and utilizing SQL indexing when available.
138
+ Since OINO is just generating SQL, WHERE-conditions can be defined with [`OINOSqlFilter`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODbSqlFilter.html) and order with [`OINOSqlOrder`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODbSqlOrder.html) that are passed as HTTP request parameters. No more API development where you make unique API endpoints for each filter that fetch all data with original API and filter in backend code. Every API can be filtered when and as needed without unnessecary data tranfer and utilizing SQL indexing when available.
138
139
 
139
140
  ## Swagger Support
140
141
  Swagger is great as long as the definitions are updated and with OINO you can automatically get a Swagger definition including a data model schema.
@@ -158,7 +159,7 @@
158
159
  # STATUS
159
160
  OINO is currently a hobby project which should and should considered in alpha status. That also means compatibility breaking changes can be made without prior notice when architectual issues are discovered.
160
161
 
161
- ## Beta
162
+ ## Beta
162
163
  For a beta status following milestones are planned:
163
164
 
164
165
  ### Realistic app
@@ -205,14 +206,16 @@
205
206
  # LINKS
206
207
  - [Github repository](https://github.com/pragmatta/oino-ts)
207
208
  - [NPM repository](https://www.npmjs.com/org/oino-ts)
208
-
209
+
209
210
 
210
211
  # ACKNOWLEDGEMENTS
211
212
 
212
213
  ## Libraries
213
214
  OINO uses the following open source libraries and npm packages and I would like to thank everyone for their contributions:
214
- - Postgresql support by [node-postgres package](https://www.npmjs.com/package/pg)
215
- - Mariadb / Mysql-support by [mariadb package](https://www.npmjs.com/package/mariadb)
215
+ - Postgresql [node-postgres package](https://www.npmjs.com/package/pg)
216
+ - Mariadb / Mysql [mariadb package](https://www.npmjs.com/package/mariadb)
217
+ - Sql Server [mssql package](https://www.npmjs.com/package/mssql)
218
+ - Custom base encoding [base-x package](https://www.npmjs.com/package/base-x)
216
219
 
217
220
  ## Bun
218
221
  OINO has been developed using the Bun runtime, not because of the speed improvements but for the first class Typescript support and integrated developper experience. Kudos on the bun team for making Typescript work more exiting again.
@@ -6,6 +6,9 @@ const _1 = require(".");
6
6
  * Class for rendering HTML from data.
7
7
  */
8
8
  class OINOHtmlTemplate {
9
+ _tag;
10
+ _tagCleanRegex;
11
+ _variables = {};
9
12
  /** HTML template string */
10
13
  template;
11
14
  /** Cache modified value for template */
@@ -16,12 +19,15 @@ class OINOHtmlTemplate {
16
19
  * Creates HTML Response from a key-value-pair.
17
20
  *
18
21
  * @param template template string
22
+ * @param tag tag to identify variables in template
19
23
  *
20
24
  */
21
- constructor(template) {
25
+ constructor(template, tag = "###") {
22
26
  this.template = template;
23
27
  this.modified = 0;
24
28
  this.expires = 0;
29
+ this._tag = tag;
30
+ this._tagCleanRegex = new RegExp(tag + ".*" + tag, "g");
25
31
  }
26
32
  /**
27
33
  * @returns whether template is empty
@@ -29,16 +35,10 @@ class OINOHtmlTemplate {
29
35
  isEmpty() {
30
36
  return this.template == "";
31
37
  }
32
- /**
33
- * Creates HTML Response from a key-value-pair.
34
- *
35
- * @param key key
36
- * @param value value
37
- *
38
- */
39
- renderFromKeyValue(key, value) {
40
- _1.OINOBenchmark.start("OINOHtmlTemplate", "renderFromKeyValue");
41
- const html = this.template.replaceAll('###' + key + '###', _1.OINOStr.encode(value, _1.OINOContentType.html));
38
+ _createHttpResult(html, removeUnusedTags) {
39
+ if (removeUnusedTags) {
40
+ html = html.replace(this._tagCleanRegex, "");
41
+ }
42
42
  const result = new _1.OINOHttpResult(html);
43
43
  if (this.expires >= 1) {
44
44
  result.expires = Math.round(this.expires);
@@ -46,34 +46,91 @@ class OINOHtmlTemplate {
46
46
  if (this.modified >= 1) {
47
47
  result.lastModified = this.modified;
48
48
  }
49
- _1.OINOBenchmark.end("OINOHtmlTemplate", "renderFromKeyValue");
50
49
  return result;
51
50
  }
51
+ _renderHtml() {
52
+ let html = this.template;
53
+ for (let key in this._variables) {
54
+ const value = this._variables[key];
55
+ html = html.replaceAll(this._tag + key + this._tag, value);
56
+ }
57
+ return html;
58
+ }
52
59
  /**
53
- * Creates HTML Response from object properties.
60
+ * Clear template variables.
54
61
  *
55
- * @param object object
62
+ */
63
+ clearVariables() {
64
+ this._variables = {};
65
+ }
66
+ /**
67
+ * Sets template variable from a key-value-pair.
68
+ *
69
+ * @param variable key
70
+ * @param value value
71
+ * @param escapeValue whether to escape value
56
72
  *
57
73
  */
58
- renderFromObject(object) {
59
- _1.OINOBenchmark.start("OINOHtmlTemplate", "renderFromObject");
60
- let html = this.template;
74
+ setVariableFromValue(variable, value, escapeValue = true) {
75
+ if (escapeValue) {
76
+ value = _1.OINOStr.encode(value, _1.OINOContentType.html);
77
+ }
78
+ this._variables[variable] = value;
79
+ }
80
+ /**
81
+ * Sets template variables from object properties.
82
+ *
83
+ * @param object any object
84
+ * @param escapeValue whether to escape value
85
+ *
86
+ */
87
+ setVariableFromProperties(object, escapeValue = true) {
61
88
  if (object) {
62
89
  for (let key in object) {
63
- const value = object[key];
64
- if (value) {
65
- html = html.replaceAll('###' + key + '###', _1.OINOStr.encode(value.toString(), _1.OINOContentType.html));
90
+ if (escapeValue) {
91
+ this._variables[key] = _1.OINOStr.encode(object[key], _1.OINOContentType.html);
92
+ }
93
+ else {
94
+ this._variables[key] = object[key];
66
95
  }
67
96
  }
68
97
  }
69
- html = html.replace(/###[^#]*###/g, "");
70
- const result = new _1.OINOHttpResult(html);
71
- if (this.expires >= 1) {
72
- result.expires = Math.round(this.expires);
73
- }
74
- if (this.modified >= 1) {
75
- result.lastModified = this.modified;
76
- }
98
+ }
99
+ /**
100
+ * Creates HTML Response from set variables.
101
+ *
102
+ * @param removeUnusedTags whether to remove unused tags
103
+ *
104
+ */
105
+ render(removeUnusedTags = true) {
106
+ return this._createHttpResult(this._renderHtml(), removeUnusedTags);
107
+ }
108
+ /**
109
+ * Creates HTML Response from a key-value-pair.
110
+ *
111
+ * @param key key
112
+ * @param value value
113
+ * @param removeUnusedTags whether to remove unused tags
114
+ *
115
+ */
116
+ renderFromKeyValue(key, value, removeUnusedTags = true) {
117
+ _1.OINOBenchmark.start("OINOHtmlTemplate", "renderFromKeyValue");
118
+ this.setVariableFromValue(key, value);
119
+ const result = this.render(removeUnusedTags);
120
+ _1.OINOBenchmark.end("OINOHtmlTemplate", "renderFromKeyValue");
121
+ return result;
122
+ }
123
+ /**
124
+ * Creates HTML Response from object properties.
125
+ *
126
+ * @param object object
127
+ * @param removeUnusedTags whether to remove unused tags
128
+ *
129
+ */
130
+ renderFromObject(object, removeUnusedTags = true) {
131
+ _1.OINOBenchmark.start("OINOHtmlTemplate", "renderFromObject");
132
+ this.setVariableFromProperties(object);
133
+ const result = this.render(removeUnusedTags);
77
134
  _1.OINOBenchmark.end("OINOHtmlTemplate", "renderFromObject");
78
135
  return result;
79
136
  }
@@ -81,43 +138,37 @@ class OINOHtmlTemplate {
81
138
  * Creates HTML Response from API result.
82
139
  *
83
140
  * @param result OINOResult-object
141
+ * @param removeUnusedTags whether to remove unused tags
142
+ * @param messageSeparator HTML separator for messages
84
143
  * @param includeErrorMessages include debug messages in result
85
144
  * @param includeWarningMessages include debug messages in result
86
145
  * @param includeInfoMessages include debug messages in result
87
146
  * @param includeDebugMessages include debug messages in result
88
147
  *
89
148
  */
90
- renderFromResult(result, includeErrorMessages = false, includeWarningMessages = false, includeInfoMessages = false, includeDebugMessages = false) {
149
+ renderFromResult(result, removeUnusedTags = true, messageSeparator, includeErrorMessages = false, includeWarningMessages = false, includeInfoMessages = false, includeDebugMessages = false) {
91
150
  _1.OINOBenchmark.start("OINOHtmlTemplate", "renderFromResult");
92
- let html = this.template;
93
- html = html.replaceAll('###statusCode###', _1.OINOStr.encode(result.statusCode.toString(), _1.OINOContentType.html));
94
- html = html.replaceAll('###statusMessage###', _1.OINOStr.encode(result.statusMessage.toString(), _1.OINOContentType.html));
95
- let messages = "";
151
+ this.setVariableFromValue("statusCode", result.statusCode.toString());
152
+ this.setVariableFromValue("statusMessage", result.statusMessage.toString());
153
+ let messages = [];
96
154
  for (let i = 0; i < result.messages.length; i++) {
97
155
  if (includeErrorMessages && result.messages[i].startsWith(_1.OINO_ERROR_PREFIX)) {
98
- messages += "<li>" + _1.OINOStr.encode(result.messages[i], _1.OINOContentType.html) + "</li>";
156
+ messages.push(_1.OINOStr.encode(result.messages[i], _1.OINOContentType.html));
99
157
  }
100
158
  if (includeWarningMessages && result.messages[i].startsWith(_1.OINO_WARNING_PREFIX)) {
101
- messages += "<li>" + _1.OINOStr.encode(result.messages[i], _1.OINOContentType.html) + "</li>";
159
+ messages.push(_1.OINOStr.encode(result.messages[i], _1.OINOContentType.html));
102
160
  }
103
161
  if (includeInfoMessages && result.messages[i].startsWith(_1.OINO_INFO_PREFIX)) {
104
- messages += "<li>" + _1.OINOStr.encode(result.messages[i], _1.OINOContentType.html) + "</li>";
162
+ messages.push(_1.OINOStr.encode(result.messages[i], _1.OINOContentType.html));
105
163
  }
106
164
  if (includeDebugMessages && result.messages[i].startsWith(_1.OINO_DEBUG_PREFIX)) {
107
- messages += "<li>" + _1.OINOStr.encode(result.messages[i], _1.OINOContentType.html) + "</li>";
165
+ messages.push(_1.OINOStr.encode(result.messages[i], _1.OINOContentType.html));
108
166
  }
109
167
  }
110
- if (messages) {
111
- html = html.replaceAll('###messages###', "<ul>" + messages + "</ul>");
112
- }
113
- html = html.replace(/###[^#]*###/g, "");
114
- const http_result = new _1.OINOHttpResult(html);
115
- if (this.expires >= 1) {
116
- http_result.expires = Math.round(this.expires);
117
- }
118
- if (this.modified >= 1) {
119
- http_result.lastModified = this.modified;
168
+ if (messages.length > 0) {
169
+ this.setVariableFromValue("messages", messages.join(messageSeparator), false); // messages have been escaped already
120
170
  }
171
+ const http_result = this.render(removeUnusedTags);
121
172
  _1.OINOBenchmark.end("OINOHtmlTemplate", "renderFromResult");
122
173
  return http_result;
123
174
  }
@@ -3,6 +3,9 @@ import { OINOStr, OINOContentType, OINOHttpResult, OINO_ERROR_PREFIX, OINO_WARNI
3
3
  * Class for rendering HTML from data.
4
4
  */
5
5
  export class OINOHtmlTemplate {
6
+ _tag;
7
+ _tagCleanRegex;
8
+ _variables = {};
6
9
  /** HTML template string */
7
10
  template;
8
11
  /** Cache modified value for template */
@@ -13,12 +16,15 @@ export class OINOHtmlTemplate {
13
16
  * Creates HTML Response from a key-value-pair.
14
17
  *
15
18
  * @param template template string
19
+ * @param tag tag to identify variables in template
16
20
  *
17
21
  */
18
- constructor(template) {
22
+ constructor(template, tag = "###") {
19
23
  this.template = template;
20
24
  this.modified = 0;
21
25
  this.expires = 0;
26
+ this._tag = tag;
27
+ this._tagCleanRegex = new RegExp(tag + ".*" + tag, "g");
22
28
  }
23
29
  /**
24
30
  * @returns whether template is empty
@@ -26,16 +32,10 @@ export class OINOHtmlTemplate {
26
32
  isEmpty() {
27
33
  return this.template == "";
28
34
  }
29
- /**
30
- * Creates HTML Response from a key-value-pair.
31
- *
32
- * @param key key
33
- * @param value value
34
- *
35
- */
36
- renderFromKeyValue(key, value) {
37
- OINOBenchmark.start("OINOHtmlTemplate", "renderFromKeyValue");
38
- const html = this.template.replaceAll('###' + key + '###', OINOStr.encode(value, OINOContentType.html));
35
+ _createHttpResult(html, removeUnusedTags) {
36
+ if (removeUnusedTags) {
37
+ html = html.replace(this._tagCleanRegex, "");
38
+ }
39
39
  const result = new OINOHttpResult(html);
40
40
  if (this.expires >= 1) {
41
41
  result.expires = Math.round(this.expires);
@@ -43,34 +43,91 @@ export class OINOHtmlTemplate {
43
43
  if (this.modified >= 1) {
44
44
  result.lastModified = this.modified;
45
45
  }
46
- OINOBenchmark.end("OINOHtmlTemplate", "renderFromKeyValue");
47
46
  return result;
48
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
+ }
49
56
  /**
50
- * Creates HTML Response from object properties.
57
+ * Clear template variables.
51
58
  *
52
- * @param object object
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
53
69
  *
54
70
  */
55
- renderFromObject(object) {
56
- OINOBenchmark.start("OINOHtmlTemplate", "renderFromObject");
57
- let html = this.template;
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) {
58
85
  if (object) {
59
86
  for (let key in object) {
60
- const value = object[key];
61
- if (value) {
62
- html = html.replaceAll('###' + key + '###', OINOStr.encode(value.toString(), OINOContentType.html));
87
+ if (escapeValue) {
88
+ this._variables[key] = OINOStr.encode(object[key], OINOContentType.html);
89
+ }
90
+ else {
91
+ this._variables[key] = object[key];
63
92
  }
64
93
  }
65
94
  }
66
- html = html.replace(/###[^#]*###/g, "");
67
- const result = new OINOHttpResult(html);
68
- if (this.expires >= 1) {
69
- result.expires = Math.round(this.expires);
70
- }
71
- if (this.modified >= 1) {
72
- result.lastModified = this.modified;
73
- }
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);
74
131
  OINOBenchmark.end("OINOHtmlTemplate", "renderFromObject");
75
132
  return result;
76
133
  }
@@ -78,43 +135,37 @@ export class OINOHtmlTemplate {
78
135
  * Creates HTML Response from API result.
79
136
  *
80
137
  * @param result OINOResult-object
138
+ * @param removeUnusedTags whether to remove unused tags
139
+ * @param messageSeparator HTML separator for messages
81
140
  * @param includeErrorMessages include debug messages in result
82
141
  * @param includeWarningMessages include debug messages in result
83
142
  * @param includeInfoMessages include debug messages in result
84
143
  * @param includeDebugMessages include debug messages in result
85
144
  *
86
145
  */
87
- renderFromResult(result, includeErrorMessages = false, includeWarningMessages = false, includeInfoMessages = false, includeDebugMessages = false) {
146
+ renderFromResult(result, removeUnusedTags = true, messageSeparator, includeErrorMessages = false, includeWarningMessages = false, includeInfoMessages = false, includeDebugMessages = false) {
88
147
  OINOBenchmark.start("OINOHtmlTemplate", "renderFromResult");
89
- let html = this.template;
90
- html = html.replaceAll('###statusCode###', OINOStr.encode(result.statusCode.toString(), OINOContentType.html));
91
- html = html.replaceAll('###statusMessage###', OINOStr.encode(result.statusMessage.toString(), OINOContentType.html));
92
- let messages = "";
148
+ this.setVariableFromValue("statusCode", result.statusCode.toString());
149
+ this.setVariableFromValue("statusMessage", result.statusMessage.toString());
150
+ let messages = [];
93
151
  for (let i = 0; i < result.messages.length; i++) {
94
152
  if (includeErrorMessages && result.messages[i].startsWith(OINO_ERROR_PREFIX)) {
95
- messages += "<li>" + OINOStr.encode(result.messages[i], OINOContentType.html) + "</li>";
153
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html));
96
154
  }
97
155
  if (includeWarningMessages && result.messages[i].startsWith(OINO_WARNING_PREFIX)) {
98
- messages += "<li>" + OINOStr.encode(result.messages[i], OINOContentType.html) + "</li>";
156
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html));
99
157
  }
100
158
  if (includeInfoMessages && result.messages[i].startsWith(OINO_INFO_PREFIX)) {
101
- messages += "<li>" + OINOStr.encode(result.messages[i], OINOContentType.html) + "</li>";
159
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html));
102
160
  }
103
161
  if (includeDebugMessages && result.messages[i].startsWith(OINO_DEBUG_PREFIX)) {
104
- messages += "<li>" + OINOStr.encode(result.messages[i], OINOContentType.html) + "</li>";
162
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html));
105
163
  }
106
164
  }
107
- if (messages) {
108
- html = html.replaceAll('###messages###', "<ul>" + messages + "</ul>");
109
- }
110
- html = html.replace(/###[^#]*###/g, "");
111
- const http_result = new OINOHttpResult(html);
112
- if (this.expires >= 1) {
113
- http_result.expires = Math.round(this.expires);
114
- }
115
- if (this.modified >= 1) {
116
- http_result.lastModified = this.modified;
165
+ if (messages.length > 0) {
166
+ this.setVariableFromValue("messages", messages.join(messageSeparator), false); // messages have been escaped already
117
167
  }
168
+ const http_result = this.render(removeUnusedTags);
118
169
  OINOBenchmark.end("OINOHtmlTemplate", "renderFromResult");
119
170
  return http_result;
120
171
  }
@@ -3,6 +3,9 @@ import { OINOResult, OINOHttpResult } from ".";
3
3
  * Class for rendering HTML from data.
4
4
  */
5
5
  export declare class OINOHtmlTemplate {
6
+ private _tag;
7
+ private _tagCleanRegex;
8
+ private _variables;
6
9
  /** HTML template string */
7
10
  template: string;
8
11
  /** Cache modified value for template */
@@ -13,37 +16,73 @@ export declare class OINOHtmlTemplate {
13
16
  * Creates HTML Response from a key-value-pair.
14
17
  *
15
18
  * @param template template string
19
+ * @param tag tag to identify variables in template
16
20
  *
17
21
  */
18
- constructor(template: string);
22
+ constructor(template: string, tag?: string);
19
23
  /**
20
24
  * @returns whether template is empty
21
25
  */
22
26
  isEmpty(): boolean;
27
+ protected _createHttpResult(html: string, removeUnusedTags: boolean): OINOHttpResult;
28
+ protected _renderHtml(): string;
29
+ /**
30
+ * Clear template variables.
31
+ *
32
+ */
33
+ clearVariables(): void;
34
+ /**
35
+ * Sets template variable from a key-value-pair.
36
+ *
37
+ * @param variable key
38
+ * @param value value
39
+ * @param escapeValue whether to escape value
40
+ *
41
+ */
42
+ setVariableFromValue(variable: string, value: string, escapeValue?: boolean): void;
43
+ /**
44
+ * Sets template variables from object properties.
45
+ *
46
+ * @param object any object
47
+ * @param escapeValue whether to escape value
48
+ *
49
+ */
50
+ setVariableFromProperties(object: any, escapeValue?: boolean): void;
51
+ /**
52
+ * Creates HTML Response from set variables.
53
+ *
54
+ * @param removeUnusedTags whether to remove unused tags
55
+ *
56
+ */
57
+ render(removeUnusedTags?: boolean): OINOHttpResult;
23
58
  /**
24
59
  * Creates HTML Response from a key-value-pair.
25
60
  *
26
61
  * @param key key
27
62
  * @param value value
63
+ * @param removeUnusedTags whether to remove unused tags
28
64
  *
29
65
  */
30
- renderFromKeyValue(key: string, value: string): OINOHttpResult;
66
+ renderFromKeyValue(key: string, value: string, removeUnusedTags?: boolean): OINOHttpResult;
31
67
  /**
32
68
  * Creates HTML Response from object properties.
33
69
  *
34
70
  * @param object object
71
+ * @param removeUnusedTags whether to remove unused tags
35
72
  *
36
73
  */
37
- renderFromObject(object: any): OINOHttpResult;
74
+ renderFromObject(object: any, removeUnusedTags?: boolean): OINOHttpResult;
38
75
  /**
39
76
  * Creates HTML Response from API result.
40
77
  *
41
78
  * @param result OINOResult-object
79
+ * @param removeUnusedTags whether to remove unused tags
80
+ * @param messageSeparator HTML separator for messages
42
81
  * @param includeErrorMessages include debug messages in result
43
82
  * @param includeWarningMessages include debug messages in result
44
83
  * @param includeInfoMessages include debug messages in result
45
84
  * @param includeDebugMessages include debug messages in result
46
85
  *
47
86
  */
48
- renderFromResult(result: OINOResult, includeErrorMessages?: boolean, includeWarningMessages?: boolean, includeInfoMessages?: boolean, includeDebugMessages?: boolean): OINOHttpResult;
87
+ renderFromResult(result: OINOResult, removeUnusedTags: boolean | undefined, messageSeparator: string, includeErrorMessages?: boolean, includeWarningMessages?: boolean, includeInfoMessages?: boolean, includeDebugMessages?: boolean): OINOHttpResult;
49
88
  }
@@ -40,7 +40,7 @@ export declare class OINOStr {
40
40
  *
41
41
  * @param str string to decode
42
42
  */
43
- static decodeJSON(str: string): string | null | undefined;
43
+ static decodeJSON(str: string): string;
44
44
  /**
45
45
  * Encode OINO serialized strings as valid CSV.
46
46
  *
@@ -52,7 +52,7 @@ export declare class OINOStr {
52
52
  *
53
53
  * @param str string to decode
54
54
  */
55
- static decodeCSV(str: string): string | null | undefined;
55
+ static decodeCSV(str: string): string;
56
56
  /**
57
57
  * Encode OINO serialized strings as valid Formdata.
58
58
  *
@@ -64,7 +64,7 @@ export declare class OINOStr {
64
64
  *
65
65
  * @param str string to decode
66
66
  */
67
- static decodeFormdata(str: string): string | null | undefined;
67
+ static decodeFormdata(str: string): string;
68
68
  /**
69
69
  * Encode OINO serialized strings as valid Urlencode.
70
70
  *
@@ -76,7 +76,7 @@ export declare class OINOStr {
76
76
  *
77
77
  * @param str string to decode
78
78
  */
79
- static decodeUrlencode(str: string): string | null | undefined;
79
+ static decodeUrlencode(str: string): string;
80
80
  /**
81
81
  * Encode OINO serialized strings as valid HTML content.
82
82
  *
@@ -88,7 +88,7 @@ export declare class OINOStr {
88
88
  *
89
89
  * @param str string to encode
90
90
  */
91
- static decodeHtml(str: string): string | null | undefined;
91
+ static decodeHtml(str: string): string;
92
92
  /**
93
93
  * Decode content type formatted string as OINO serialization.
94
94
  *
@@ -96,7 +96,7 @@ export declare class OINOStr {
96
96
  * @param contentType content type for serialization
97
97
  *
98
98
  */
99
- static decode(str: string, contentType: OINOContentType): string | null | undefined;
99
+ static decode(str: string, contentType: OINOContentType): string;
100
100
  /**
101
101
  * Encode OINO serialized string to the content type formatting.
102
102
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oino-ts/types",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "OINO TS package for types.",
5
5
  "author": "Matias Kiviniemi (pragmatta)",
6
6
  "license": "MPL-2.0",
@@ -4,6 +4,9 @@ import { OINOStr, OINOContentType, OINOResult, OINOHttpResult, OINO_ERROR_PREFIX
4
4
  * Class for rendering HTML from data.
5
5
  */
6
6
  export class OINOHtmlTemplate {
7
+ private _tag:string
8
+ private _tagCleanRegex:RegExp
9
+ private _variables:Record<string, string> = {}
7
10
  /** HTML template string */
8
11
  template: string;
9
12
 
@@ -17,12 +20,15 @@ export class OINOHtmlTemplate {
17
20
  * Creates HTML Response from a key-value-pair.
18
21
  *
19
22
  * @param template template string
23
+ * @param tag tag to identify variables in template
20
24
  *
21
25
  */
22
- constructor (template:string) {
26
+ constructor (template:string, tag:string = "###") {
23
27
  this.template = template
24
28
  this.modified = 0
25
29
  this.expires = 0
30
+ this._tag = tag
31
+ this._tagCleanRegex = new RegExp(tag + ".*" + tag, "g")
26
32
  }
27
33
 
28
34
  /**
@@ -32,23 +38,93 @@ export class OINOHtmlTemplate {
32
38
  return this.template == ""
33
39
  }
34
40
 
41
+ protected _createHttpResult(html:string, removeUnusedTags:boolean):OINOHttpResult {
42
+ if (removeUnusedTags) {
43
+ html = html.replace(this._tagCleanRegex, "")
44
+ }
45
+ const result:OINOHttpResult = new OINOHttpResult(html)
46
+ if (this.expires >= 1) {
47
+ result.expires = Math.round(this.expires)
48
+ }
49
+ if (this.modified >= 1) {
50
+ result.lastModified = this.modified
51
+ }
52
+ return result
53
+ }
54
+
55
+ protected _renderHtml():string {
56
+ let html:string = this.template
57
+ for (let key in this._variables) {
58
+ const value = this._variables[key]
59
+ html = html.replaceAll(this._tag + key + this._tag, value)
60
+ }
61
+ return html
62
+ }
63
+
64
+ /**
65
+ * Clear template variables.
66
+ *
67
+ */
68
+ clearVariables() {
69
+ this._variables = {}
70
+ }
71
+
72
+ /**
73
+ * Sets template variable from a key-value-pair.
74
+ *
75
+ * @param variable key
76
+ * @param value value
77
+ * @param escapeValue whether to escape value
78
+ *
79
+ */
80
+ setVariableFromValue(variable:string, value:string, escapeValue:boolean = true) {
81
+ if (escapeValue) {
82
+ value = OINOStr.encode(value, OINOContentType.html)
83
+ }
84
+ this._variables[variable] = value
85
+ }
86
+
87
+ /**
88
+ * Sets template variables from object properties.
89
+ *
90
+ * @param object any object
91
+ * @param escapeValue whether to escape value
92
+ *
93
+ */
94
+ setVariableFromProperties(object:any, escapeValue:boolean = true) {
95
+ if (object) {
96
+ for (let key in object) {
97
+ if (escapeValue) {
98
+ this._variables[key] = OINOStr.encode(object[key], OINOContentType.html)
99
+ } else {
100
+ this._variables[key] = object[key]
101
+ }
102
+ }
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Creates HTML Response from set variables.
108
+ *
109
+ * @param removeUnusedTags whether to remove unused tags
110
+ *
111
+ */
112
+ render(removeUnusedTags:boolean = true):OINOHttpResult {
113
+ return this._createHttpResult(this._renderHtml(), removeUnusedTags)
114
+ }
115
+
35
116
  /**
36
117
  * Creates HTML Response from a key-value-pair.
37
118
  *
38
119
  * @param key key
39
120
  * @param value value
121
+ * @param removeUnusedTags whether to remove unused tags
40
122
  *
41
123
  */
42
- renderFromKeyValue(key:string, value:string):OINOHttpResult {
124
+ renderFromKeyValue(key:string, value:string, removeUnusedTags:boolean = true):OINOHttpResult {
43
125
  OINOBenchmark.start("OINOHtmlTemplate", "renderFromKeyValue")
44
- const html:string = this.template.replaceAll('###' + key + '###', OINOStr.encode(value, OINOContentType.html))
45
- const result:OINOHttpResult = new OINOHttpResult(html)
46
- if (this.expires >= 1) {
47
- result.expires = Math.round(this.expires)
48
- }
49
- if (this.modified >= 1) {
50
- result.lastModified = this.modified
51
- }
126
+ this.setVariableFromValue(key, value)
127
+ const result:OINOHttpResult = this.render(removeUnusedTags)
52
128
  OINOBenchmark.end("OINOHtmlTemplate", "renderFromKeyValue")
53
129
  return result
54
130
  }
@@ -57,27 +133,13 @@ export class OINOHtmlTemplate {
57
133
  * Creates HTML Response from object properties.
58
134
  *
59
135
  * @param object object
136
+ * @param removeUnusedTags whether to remove unused tags
60
137
  *
61
138
  */
62
- renderFromObject(object:any):OINOHttpResult {
139
+ renderFromObject(object:any, removeUnusedTags:boolean = true):OINOHttpResult {
63
140
  OINOBenchmark.start("OINOHtmlTemplate", "renderFromObject")
64
- let html:string = this.template
65
- if (object) {
66
- for (let key in object) {
67
- const value = object[key]
68
- if (value) {
69
- html = html.replaceAll('###' + key + '###', OINOStr.encode(value.toString(), OINOContentType.html))
70
- }
71
- }
72
- }
73
- html = html.replace(/###[^#]*###/g, "")
74
- const result:OINOHttpResult = new OINOHttpResult(html)
75
- if (this.expires >= 1) {
76
- result.expires = Math.round(this.expires)
77
- }
78
- if (this.modified >= 1) {
79
- result.lastModified = this.modified
80
- }
141
+ this.setVariableFromProperties(object)
142
+ const result:OINOHttpResult = this.render(removeUnusedTags)
81
143
  OINOBenchmark.end("OINOHtmlTemplate", "renderFromObject")
82
144
  return result
83
145
  }
@@ -86,44 +148,38 @@ export class OINOHtmlTemplate {
86
148
  * Creates HTML Response from API result.
87
149
  *
88
150
  * @param result OINOResult-object
151
+ * @param removeUnusedTags whether to remove unused tags
152
+ * @param messageSeparator HTML separator for messages
89
153
  * @param includeErrorMessages include debug messages in result
90
154
  * @param includeWarningMessages include debug messages in result
91
155
  * @param includeInfoMessages include debug messages in result
92
156
  * @param includeDebugMessages include debug messages in result
93
157
  *
94
158
  */
95
- renderFromResult(result:OINOResult, includeErrorMessages:boolean=false, includeWarningMessages:boolean=false, includeInfoMessages:boolean=false, includeDebugMessages:boolean=false):OINOHttpResult {
159
+ renderFromResult(result:OINOResult, removeUnusedTags:boolean=true, messageSeparator:string, includeErrorMessages:boolean=false, includeWarningMessages:boolean=false, includeInfoMessages:boolean=false, includeDebugMessages:boolean=false):OINOHttpResult {
96
160
  OINOBenchmark.start("OINOHtmlTemplate", "renderFromResult")
97
- let html:string = this.template
98
- html = html.replaceAll('###statusCode###', OINOStr.encode(result.statusCode.toString(), OINOContentType.html))
99
- html = html.replaceAll('###statusMessage###', OINOStr.encode(result.statusMessage.toString(), OINOContentType.html))
100
- let messages = ""
161
+ this.setVariableFromValue("statusCode", result.statusCode.toString())
162
+ this.setVariableFromValue("statusMessage", result.statusMessage.toString())
163
+ let messages:string[] = []
101
164
  for (let i:number = 0; i<result.messages.length; i++) {
102
165
  if (includeErrorMessages && result.messages[i].startsWith(OINO_ERROR_PREFIX)) {
103
- messages += "<li>" + OINOStr.encode(result.messages[i], OINOContentType.html) + "</li>"
166
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html))
104
167
  }
105
168
  if (includeWarningMessages && result.messages[i].startsWith(OINO_WARNING_PREFIX)) {
106
- messages += "<li>" + OINOStr.encode(result.messages[i], OINOContentType.html) + "</li>"
169
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html))
107
170
  }
108
171
  if (includeInfoMessages && result.messages[i].startsWith(OINO_INFO_PREFIX)) {
109
- messages += "<li>" + OINOStr.encode(result.messages[i], OINOContentType.html) + "</li>"
172
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html))
110
173
  }
111
174
  if (includeDebugMessages && result.messages[i].startsWith(OINO_DEBUG_PREFIX)) {
112
- messages += "<li>" + OINOStr.encode(result.messages[i], OINOContentType.html) + "</li>"
175
+ messages.push(OINOStr.encode(result.messages[i], OINOContentType.html))
113
176
  }
114
177
 
115
178
  }
116
- if (messages) {
117
- html = html.replaceAll('###messages###', "<ul>" + messages + "</ul>")
118
- }
119
- html = html.replace(/###[^#]*###/g, "")
120
- const http_result:OINOHttpResult = new OINOHttpResult(html)
121
- if (this.expires >= 1) {
122
- http_result.expires = Math.round(this.expires)
123
- }
124
- if (this.modified >= 1) {
125
- http_result.lastModified = this.modified
126
- }
179
+ if (messages.length > 0) {
180
+ this.setVariableFromValue("messages", messages.join(messageSeparator), false) // messages have been escaped already
181
+ }
182
+ const http_result:OINOHttpResult = this.render(removeUnusedTags)
127
183
  OINOBenchmark.end("OINOHtmlTemplate", "renderFromResult")
128
184
  return http_result
129
185
  }
package/src/OINOStr.ts CHANGED
@@ -109,7 +109,7 @@ export class OINOStr {
109
109
  *
110
110
  * @param str string to decode
111
111
  */
112
- static decodeJSON(str:string):string|null|undefined {
112
+ static decodeJSON(str:string):string {
113
113
  return str // JSON parsing using JS methods, no need to decode anything
114
114
  }
115
115
 
@@ -133,7 +133,7 @@ export class OINOStr {
133
133
  *
134
134
  * @param str string to decode
135
135
  */
136
- static decodeCSV(str:string):string|null|undefined {
136
+ static decodeCSV(str:string):string {
137
137
  return str.replaceAll("\"\"", "\"")
138
138
  }
139
139
 
@@ -157,7 +157,7 @@ export class OINOStr {
157
157
  *
158
158
  * @param str string to decode
159
159
  */
160
- static decodeFormdata(str:string):string|null|undefined {
160
+ static decodeFormdata(str:string):string {
161
161
  return str
162
162
  }
163
163
  /**
@@ -180,7 +180,7 @@ export class OINOStr {
180
180
  *
181
181
  * @param str string to decode
182
182
  */
183
- static decodeUrlencode(str:string):string|null|undefined {
183
+ static decodeUrlencode(str:string):string {
184
184
  return decodeURIComponent(str)
185
185
  }
186
186
 
@@ -204,7 +204,7 @@ export class OINOStr {
204
204
  *
205
205
  * @param str string to encode
206
206
  */
207
- static decodeHtml(str:string):string|null|undefined {
207
+ static decodeHtml(str:string):string {
208
208
  return str.replaceAll('&amp;', '&').replaceAll('&lt;', '<').replaceAll('&gt;', '>').replaceAll('&quot;', '"').replaceAll('&#039;', "'")
209
209
  }
210
210
  /**
@@ -214,7 +214,7 @@ export class OINOStr {
214
214
  * @param contentType content type for serialization
215
215
  *
216
216
  */
217
- static decode(str:string, contentType:OINOContentType):string|null|undefined {
217
+ static decode(str:string, contentType:OINOContentType):string {
218
218
  if (contentType == OINOContentType.csv) {
219
219
  return this.decodeCSV(str)
220
220
  } else if (contentType == OINOContentType.json) {