@oino-ts/db 0.0.11 → 0.0.12
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 +6 -6
- package/dist/cjs/OINODbApi.js +86 -10
- package/dist/cjs/OINODbDataModel.js +1 -1
- package/dist/cjs/OINODbFactory.js +55 -85
- package/dist/cjs/OINODbRequestParams.js +55 -15
- package/dist/cjs/index.js +4 -1
- package/dist/esm/OINODbApi.js +84 -9
- package/dist/esm/OINODbDataModel.js +2 -2
- package/dist/esm/OINODbFactory.js +55 -85
- package/dist/esm/OINODbRequestParams.js +55 -15
- package/dist/esm/index.js +2 -2
- package/dist/types/OINODbApi.d.ts +28 -4
- package/dist/types/OINODbFactory.d.ts +16 -31
- package/dist/types/OINODbRequestParams.d.ts +20 -5
- package/dist/types/index.d.ts +4 -4
- package/package.json +2 -2
- package/src/OINODbApi.test.ts +9 -9
- package/src/OINODbApi.ts +91 -10
- package/src/OINODbDataModel.ts +1 -1
- package/src/OINODbFactory.ts +63 -92
- package/src/OINODbRequestParams.ts +54 -16
- package/src/index.ts +4 -4
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
### Register database and logger
|
|
25
|
-
Register your database implementation and logger (see [`OINOConsoleLog`](https://pragmatta.github.io/oino-ts/classes/
|
|
25
|
+
Register your database implementation and logger (see [`OINOConsoleLog`](https://pragmatta.github.io/oino-ts/classes/types_src.OINOConsoleLog.html) how to implement your own)
|
|
26
26
|
|
|
27
27
|
```
|
|
28
28
|
OINOLog.setLogger(new OINOConsoleLog())
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
### Create a database
|
|
33
|
-
Creating a database connection [`OINODb`](https://pragmatta.github.io/oino-ts/classes/
|
|
33
|
+
Creating a database connection [`OINODb`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODb.html) is done by passing [`OINODbParams`](https://pragmatta.github.io/oino-ts/types/db_src.OINODbParams.html) to the factory method. For [`OINODbBunSqlite`](https://pragmatta.github.io/oino-ts/classes/db_bunsqlite_src.OINODbBunSqlite.html) that means a file url for the database file, for others network host, port, credentials etc.
|
|
34
34
|
```
|
|
35
35
|
const db:OINODb = await OINOFactory.createDb( { type: "OINODbBunSqlite", url: "file://../localDb/northwind.sqlite" } )
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
### Create an API
|
|
39
|
-
From a database you can create an [`OINOApi`](https://pragmatta.github.io/oino-ts/classes/
|
|
39
|
+
From a database you can create an [`OINOApi`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODbApi.html) by passing [`OINOApiParams`](https://pragmatta.github.io/oino-ts/types/db_src.OINODbApiParams.html) with table name and preferences to the factory method.
|
|
40
40
|
```
|
|
41
41
|
const api_employees:OINOApi = await OINOFactory.createApi(db, { tableName: "Employees", excludeFields:["BirthDate"] })
|
|
42
42
|
```
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
### Write results back to HTTP Response
|
|
52
|
-
The results for a GET request will contain [`OINOModelSet`](https://pragmatta.github.io/oino-ts/classes/
|
|
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
54
|
return new Response(result.modelset.writeString(OINOContentType.json))
|
|
55
55
|
```
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
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
135
|
|
|
136
136
|
## Power Of SQL
|
|
137
|
-
Since OINO controls the SQL, WHERE-conditions can be defined with [`OINOSqlFilter`](https://pragmatta.github.io/oino-ts/classes/
|
|
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
138
|
|
|
139
139
|
## Swagger Support
|
|
140
140
|
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.
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
OINO is developped Typescript first but compiles to standard CommonJS and the NPM packages should work on either ESM / CommonJS. Checkout sample apps `readmeApp` (ESM) and `nodeApp` (CommonJS).
|
|
150
150
|
|
|
151
151
|
## HTMX support
|
|
152
|
-
OINO is [htmx.org](https://htmx.org) friendly, allowing easy translation of [`OINODataRow`](https://pragmatta.github.io/oino-ts/types/
|
|
152
|
+
OINO is [htmx.org](https://htmx.org) friendly, allowing easy translation of [`OINODataRow`](https://pragmatta.github.io/oino-ts/types/db_src.OINODataRow.html) to HTML output using templates (cf. the [htmx sample app](https://github.com/pragmatta/oino-ts/tree/main/samples/htmxApp)).
|
|
153
153
|
|
|
154
154
|
### Hashids
|
|
155
155
|
Autoinc numeric id's are very pragmatic and fit well with OINO (e.g. using a form without primary key fields to insert new rows with database assigned ids). However it's not always sensible to share information about the sequence. Hashids solve this by masking the original values by encrypting the ids using AES-128 and some randomness. Length of the hashid can be chosen from 12-32 characters where longer ids provide more security. However this should not be considereded a cryptographic solution for keeping ids secret but rather making it infeasible to iterate all ids.
|
package/dist/cjs/OINODbApi.js
CHANGED
|
@@ -5,29 +5,94 @@
|
|
|
5
5
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.OINODbApi = exports.OINODbApiResult = void 0;
|
|
8
|
+
exports.OINODbApi = exports.OINODbHtmlTemplate = exports.OINODbApiResult = void 0;
|
|
9
9
|
const index_js_1 = require("./index.js");
|
|
10
|
+
const types_1 = require("@oino-ts/types");
|
|
10
11
|
const hashid_1 = require("@oino-ts/hashid");
|
|
12
|
+
const API_EMPTY_PARAMS = { sqlParams: {} };
|
|
11
13
|
/**
|
|
12
14
|
* OINO API request result object with returned data and/or http status code/message and
|
|
13
15
|
* error / warning messages.
|
|
14
16
|
*
|
|
15
17
|
*/
|
|
16
|
-
class OINODbApiResult extends
|
|
18
|
+
class OINODbApiResult extends types_1.OINOResult {
|
|
19
|
+
/** DbApi request params */
|
|
20
|
+
params;
|
|
17
21
|
/** Returned data if any */
|
|
18
22
|
data;
|
|
19
23
|
/**
|
|
20
24
|
* Constructor of OINODbApiResult.
|
|
21
25
|
*
|
|
26
|
+
* @param params DbApi request parameters
|
|
22
27
|
* @param data result data
|
|
23
28
|
*
|
|
24
29
|
*/
|
|
25
|
-
constructor(data) {
|
|
30
|
+
constructor(params, data) {
|
|
26
31
|
super();
|
|
32
|
+
this.params = params;
|
|
27
33
|
this.data = data;
|
|
28
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Creates a HTTP Response from API results.
|
|
37
|
+
*
|
|
38
|
+
* @param headers Headers to include in the response
|
|
39
|
+
*
|
|
40
|
+
*/
|
|
41
|
+
getResponse(headers = {}) {
|
|
42
|
+
let response = null;
|
|
43
|
+
if (this.success && this.data) {
|
|
44
|
+
response = new Response(this.data.writeString(this.params.responseType), { status: this.statusCode, statusText: this.statusMessage, headers: headers });
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
response = new Response(JSON.stringify(this), { status: this.statusCode, statusText: this.statusMessage, headers: headers });
|
|
48
|
+
}
|
|
49
|
+
for (let i = 0; i < this.messages.length; i++) {
|
|
50
|
+
response.headers.set('X-OINO-MESSAGE-' + i, this.messages[i]);
|
|
51
|
+
}
|
|
52
|
+
return response;
|
|
53
|
+
}
|
|
29
54
|
}
|
|
30
55
|
exports.OINODbApiResult = OINODbApiResult;
|
|
56
|
+
/**
|
|
57
|
+
* Specialized HTML template that can render ´OINODbApiResult´.
|
|
58
|
+
*
|
|
59
|
+
*/
|
|
60
|
+
class OINODbHtmlTemplate extends index_js_1.OINOHtmlTemplate {
|
|
61
|
+
/**
|
|
62
|
+
* Creates HTML Response from API modelset.
|
|
63
|
+
*
|
|
64
|
+
* @param modelset OINO API dataset
|
|
65
|
+
*
|
|
66
|
+
*/
|
|
67
|
+
renderFromDbData(modelset) {
|
|
68
|
+
let html = "";
|
|
69
|
+
const dataset = modelset.dataset;
|
|
70
|
+
const datamodel = modelset.datamodel;
|
|
71
|
+
while (!dataset.isEof()) {
|
|
72
|
+
const row = dataset.getRow();
|
|
73
|
+
let row_id_seed = datamodel.getRowPrimarykeyValues(row).join(' ');
|
|
74
|
+
let primary_key_values = [];
|
|
75
|
+
let html_row = this.template.replaceAll('###' + index_js_1.OINODbConfig.OINODB_ID_FIELD + '###', '###createHtmlFromData_temporary_oinoid###');
|
|
76
|
+
for (let i = 0; i < datamodel.fields.length; i++) {
|
|
77
|
+
const f = datamodel.fields[i];
|
|
78
|
+
let value = f.serializeCell(row[i]);
|
|
79
|
+
if (f.fieldParams.isPrimaryKey) {
|
|
80
|
+
if (value && (f instanceof index_js_1.OINONumberDataField) && (datamodel.api.hashid)) {
|
|
81
|
+
value = datamodel.api.hashid.encode(value, f.name + " " + row_id_seed);
|
|
82
|
+
}
|
|
83
|
+
primary_key_values.push(value || "");
|
|
84
|
+
}
|
|
85
|
+
html_row = html_row.replaceAll('###' + f.name + '###', index_js_1.OINOStr.encode(value, index_js_1.OINOContentType.html));
|
|
86
|
+
}
|
|
87
|
+
html_row = html_row.replaceAll('###createHtmlFromData_temporary_oinoid###', index_js_1.OINOStr.encode(index_js_1.OINODbConfig.printOINOId(primary_key_values), index_js_1.OINOContentType.html));
|
|
88
|
+
html += html_row + "\r\n";
|
|
89
|
+
dataset.next();
|
|
90
|
+
}
|
|
91
|
+
const result = new index_js_1.OINOHttpResult(html);
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.OINODbHtmlTemplate = OINODbHtmlTemplate;
|
|
31
96
|
/**
|
|
32
97
|
* API class with method to process HTTP REST requests.
|
|
33
98
|
*
|
|
@@ -99,7 +164,7 @@ class OINODbApi {
|
|
|
99
164
|
}
|
|
100
165
|
async _doGet(result, id, params) {
|
|
101
166
|
index_js_1.OINOBenchmark.start("doGet");
|
|
102
|
-
const sql = this.datamodel.printSqlSelect(id, params.sqlParams);
|
|
167
|
+
const sql = this.datamodel.printSqlSelect(id, params.sqlParams || {});
|
|
103
168
|
// OINOLog.debug("OINODbApi.doGet sql", {sql:sql})
|
|
104
169
|
try {
|
|
105
170
|
const sql_res = await this.db.sqlSelect(sql);
|
|
@@ -201,19 +266,31 @@ class OINODbApi {
|
|
|
201
266
|
*
|
|
202
267
|
* @param method HTTP verb (uppercase)
|
|
203
268
|
* @param id URL id of the REST request
|
|
204
|
-
* @param body HTTP body data as string
|
|
269
|
+
* @param body HTTP body data as either serialized string or unserialized JS object / OINODataRow-array
|
|
205
270
|
* @param params HTTP URL parameters as key-value-pairs
|
|
206
271
|
*
|
|
207
272
|
*/
|
|
208
|
-
async doRequest(method, id, body, params) {
|
|
273
|
+
async doRequest(method, id, body, params = API_EMPTY_PARAMS) {
|
|
209
274
|
index_js_1.OINOBenchmark.start("doRequest");
|
|
210
|
-
|
|
211
|
-
|
|
275
|
+
// OINOLog.debug("OINODbApi.doRequest enter", {method:method, id:id, body:body, params:params})
|
|
276
|
+
let result = new OINODbApiResult(params);
|
|
277
|
+
let rows = [];
|
|
278
|
+
if ((method == "POST") || (method == "PUT")) {
|
|
279
|
+
if (Array.isArray(body)) {
|
|
280
|
+
rows = body;
|
|
281
|
+
}
|
|
282
|
+
else if (typeof (body) == "object") {
|
|
283
|
+
rows = [index_js_1.OINODbFactory.createRowFromObject(this.datamodel, body)];
|
|
284
|
+
}
|
|
285
|
+
else if (typeof (body) == "string") {
|
|
286
|
+
rows = index_js_1.OINODbFactory.createRows(this.datamodel, body, params);
|
|
287
|
+
}
|
|
288
|
+
// OINOLog.debug("OINODbApi.doRequest - OINODataRow rows", {rows:rows})
|
|
289
|
+
}
|
|
212
290
|
if (method == "GET") {
|
|
213
291
|
await this._doGet(result, id, params);
|
|
214
292
|
}
|
|
215
293
|
else if (method == "PUT") {
|
|
216
|
-
const rows = index_js_1.OINODbFactory.createRows(this.datamodel, body, params);
|
|
217
294
|
if (!id) {
|
|
218
295
|
result.setError(400, "HTTP PUT method requires an URL ID for the row that is updated!", "DoRequest");
|
|
219
296
|
}
|
|
@@ -230,7 +307,6 @@ class OINODbApi {
|
|
|
230
307
|
}
|
|
231
308
|
}
|
|
232
309
|
else if (method == "POST") {
|
|
233
|
-
const rows = index_js_1.OINODbFactory.createRows(this.datamodel, body, params);
|
|
234
310
|
if (id) {
|
|
235
311
|
result.setError(400, "HTTP POST method must not have an URL ID as it does not target an existing row but creates a new one!", "DoRequest");
|
|
236
312
|
}
|
|
@@ -241,7 +241,7 @@ class OINODbDataModel {
|
|
|
241
241
|
result += "\nLIMIT " + limit_sql;
|
|
242
242
|
}
|
|
243
243
|
result += ";";
|
|
244
|
-
|
|
244
|
+
// OINOLog.debug("OINODbDataModel.printSqlSelect", {result:result})
|
|
245
245
|
return result;
|
|
246
246
|
}
|
|
247
247
|
/**
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.OINODbFactory = void 0;
|
|
9
|
+
const OINOResult_js_1 = require("../../types/src/OINOResult.js");
|
|
9
10
|
const index_js_1 = require("./index.js");
|
|
10
11
|
/**
|
|
11
12
|
* Static factory class for easily creating things based on data
|
|
@@ -58,8 +59,21 @@ class OINODbFactory {
|
|
|
58
59
|
* @param request HTTP Request
|
|
59
60
|
*/
|
|
60
61
|
static createParamsFromRequest(request) {
|
|
61
|
-
let result = { sqlParams: {} };
|
|
62
62
|
const url = new URL(request.url);
|
|
63
|
+
let sql_params = {};
|
|
64
|
+
const filter = url.searchParams.get(index_js_1.OINODbConfig.OINODB_SQL_FILTER_PARAM);
|
|
65
|
+
if (filter) {
|
|
66
|
+
sql_params.filter = index_js_1.OINODbSqlFilter.parse(filter);
|
|
67
|
+
}
|
|
68
|
+
const order = url.searchParams.get(index_js_1.OINODbConfig.OINODB_SQL_ORDER_PARAM);
|
|
69
|
+
if (order) {
|
|
70
|
+
sql_params.order = index_js_1.OINODbSqlOrder.parse(order);
|
|
71
|
+
}
|
|
72
|
+
const limit = url.searchParams.get(index_js_1.OINODbConfig.OINODB_SQL_LIMIT_PARAM);
|
|
73
|
+
if (limit) {
|
|
74
|
+
sql_params.limit = index_js_1.OINODbSqlLimit.parse(limit);
|
|
75
|
+
}
|
|
76
|
+
let result = { sqlParams: sql_params };
|
|
63
77
|
const content_type = request.headers.get("content-type");
|
|
64
78
|
if (content_type == index_js_1.OINOContentType.csv) {
|
|
65
79
|
result.requestType = index_js_1.OINOContentType.csv;
|
|
@@ -87,42 +101,9 @@ class OINODbFactory {
|
|
|
87
101
|
if (result.responseType === undefined) {
|
|
88
102
|
result.responseType = index_js_1.OINOContentType.json;
|
|
89
103
|
}
|
|
90
|
-
const filter = url.searchParams.get(index_js_1.OINODbConfig.OINODB_SQL_FILTER_PARAM);
|
|
91
|
-
if (filter) {
|
|
92
|
-
result.sqlParams.filter = index_js_1.OINODbSqlFilter.parse(filter);
|
|
93
|
-
}
|
|
94
|
-
const order = url.searchParams.get(index_js_1.OINODbConfig.OINODB_SQL_ORDER_PARAM);
|
|
95
|
-
if (order) {
|
|
96
|
-
result.sqlParams.order = new index_js_1.OINODbSqlOrder(order);
|
|
97
|
-
}
|
|
98
|
-
const limit = url.searchParams.get(index_js_1.OINODbConfig.OINODB_SQL_LIMIT_PARAM);
|
|
99
|
-
if (limit) {
|
|
100
|
-
result.sqlParams.limit = new index_js_1.OINODbSqlLimit(limit);
|
|
101
|
-
}
|
|
102
104
|
// OINOLog.debug("createParamsFromRequest", {params:result})
|
|
103
105
|
return result;
|
|
104
106
|
}
|
|
105
|
-
/**
|
|
106
|
-
* Creates a HTTP Response from API results.
|
|
107
|
-
*
|
|
108
|
-
* @param apiResult API results
|
|
109
|
-
* @param requestParams API request parameters
|
|
110
|
-
* @param responseHeaders Headers to include in the response
|
|
111
|
-
*
|
|
112
|
-
*/
|
|
113
|
-
static createResponseFromApiResult(apiResult, requestParams, responseHeaders = {}) {
|
|
114
|
-
let response = null;
|
|
115
|
-
if (apiResult.success && apiResult.data) {
|
|
116
|
-
response = new Response(apiResult.data.writeString(requestParams.responseType), { status: apiResult.statusCode, statusText: apiResult.statusMessage, headers: responseHeaders });
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
response = new Response(JSON.stringify(apiResult), { status: apiResult.statusCode, statusText: apiResult.statusMessage, headers: responseHeaders });
|
|
120
|
-
}
|
|
121
|
-
for (let i = 0; i < apiResult.messages.length; i++) {
|
|
122
|
-
response.headers.set('X-OINO-MESSAGE-' + i, apiResult.messages[i]);
|
|
123
|
-
}
|
|
124
|
-
return response;
|
|
125
|
-
}
|
|
126
107
|
/**
|
|
127
108
|
* Creates HTML Response from API modelset.
|
|
128
109
|
*
|
|
@@ -131,7 +112,7 @@ class OINODbFactory {
|
|
|
131
112
|
*
|
|
132
113
|
*/
|
|
133
114
|
static createHtmlFromData(modelset, template) {
|
|
134
|
-
let
|
|
115
|
+
let html = "";
|
|
135
116
|
const dataset = modelset.dataset;
|
|
136
117
|
const datamodel = modelset.datamodel;
|
|
137
118
|
while (!dataset.isEof()) {
|
|
@@ -151,44 +132,16 @@ class OINODbFactory {
|
|
|
151
132
|
html_row = html_row.replaceAll('###' + f.name + '###', index_js_1.OINOStr.encode(value, index_js_1.OINOContentType.html));
|
|
152
133
|
}
|
|
153
134
|
html_row = html_row.replaceAll('###createHtmlFromData_temporary_oinoid###', index_js_1.OINOStr.encode(index_js_1.OINODbConfig.printOINOId(primary_key_values), index_js_1.OINOContentType.html));
|
|
154
|
-
|
|
135
|
+
html += html_row + "\r\n";
|
|
155
136
|
dataset.next();
|
|
156
137
|
}
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Creates HTML Response from a row id.
|
|
161
|
-
*
|
|
162
|
-
* @param oinoId OINO id
|
|
163
|
-
* @param template HTML template
|
|
164
|
-
*
|
|
165
|
-
*/
|
|
166
|
-
static createHtmlFromOinoId(oinoId, template) {
|
|
167
|
-
let result = template.replaceAll('###' + index_js_1.OINODbConfig.OINODB_ID_FIELD + '###', index_js_1.OINOStr.encode(oinoId, index_js_1.OINOContentType.html));
|
|
168
|
-
return result;
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Creates HTML Response from object properties.
|
|
172
|
-
*
|
|
173
|
-
* @param object object
|
|
174
|
-
* @param template HTML template
|
|
175
|
-
*
|
|
176
|
-
*/
|
|
177
|
-
static createHtmlFromObject(object, template) {
|
|
178
|
-
let result = template;
|
|
179
|
-
for (let key in object) {
|
|
180
|
-
const value = object[key];
|
|
181
|
-
if (value) {
|
|
182
|
-
result = result.replaceAll('###' + key + '###', index_js_1.OINOStr.encode(value.toString(), index_js_1.OINOContentType.html));
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
result = result.replace(/###[^#]*###/g, "");
|
|
138
|
+
const result = new OINOResult_js_1.OINOHttpResult(html);
|
|
186
139
|
return result;
|
|
187
140
|
}
|
|
188
141
|
/**
|
|
189
142
|
* Creates HTML Response from API result.
|
|
190
143
|
*
|
|
191
|
-
* @param
|
|
144
|
+
* @param result OINOResult-object
|
|
192
145
|
* @param template HTML template
|
|
193
146
|
* @param includeErrorMessages include debug messages in result
|
|
194
147
|
* @param includeWarningMessages include debug messages in result
|
|
@@ -196,30 +149,31 @@ class OINODbFactory {
|
|
|
196
149
|
* @param includeDebugMessages include debug messages in result
|
|
197
150
|
*
|
|
198
151
|
*/
|
|
199
|
-
static
|
|
200
|
-
let
|
|
201
|
-
|
|
202
|
-
|
|
152
|
+
static createHtmlNotificationFromResult(result, template, includeErrorMessages = false, includeWarningMessages = false, includeInfoMessages = false, includeDebugMessages = false) {
|
|
153
|
+
let html = template;
|
|
154
|
+
html = html.replaceAll('###statusCode###', index_js_1.OINOStr.encode(result.statusCode.toString(), index_js_1.OINOContentType.html));
|
|
155
|
+
html = html.replaceAll('###statusMessage###', index_js_1.OINOStr.encode(result.statusMessage.toString(), index_js_1.OINOContentType.html));
|
|
203
156
|
let messages = "";
|
|
204
|
-
for (let i = 0; i <
|
|
205
|
-
if (includeErrorMessages &&
|
|
206
|
-
messages += "<li>" + index_js_1.OINOStr.encode(
|
|
157
|
+
for (let i = 0; i < result.messages.length; i++) {
|
|
158
|
+
if (includeErrorMessages && result.messages[i].startsWith(index_js_1.OINO_ERROR_PREFIX)) {
|
|
159
|
+
messages += "<li>" + index_js_1.OINOStr.encode(result.messages[i], index_js_1.OINOContentType.html) + "</li>";
|
|
207
160
|
}
|
|
208
|
-
if (includeWarningMessages &&
|
|
209
|
-
messages += "<li>" + index_js_1.OINOStr.encode(
|
|
161
|
+
if (includeWarningMessages && result.messages[i].startsWith(index_js_1.OINO_WARNING_PREFIX)) {
|
|
162
|
+
messages += "<li>" + index_js_1.OINOStr.encode(result.messages[i], index_js_1.OINOContentType.html) + "</li>";
|
|
210
163
|
}
|
|
211
|
-
if (includeInfoMessages &&
|
|
212
|
-
messages += "<li>" + index_js_1.OINOStr.encode(
|
|
164
|
+
if (includeInfoMessages && result.messages[i].startsWith(index_js_1.OINO_INFO_PREFIX)) {
|
|
165
|
+
messages += "<li>" + index_js_1.OINOStr.encode(result.messages[i], index_js_1.OINOContentType.html) + "</li>";
|
|
213
166
|
}
|
|
214
|
-
if (includeDebugMessages &&
|
|
215
|
-
messages += "<li>" + index_js_1.OINOStr.encode(
|
|
167
|
+
if (includeDebugMessages && result.messages[i].startsWith(index_js_1.OINO_DEBUG_PREFIX)) {
|
|
168
|
+
messages += "<li>" + index_js_1.OINOStr.encode(result.messages[i], index_js_1.OINOContentType.html) + "</li>";
|
|
216
169
|
}
|
|
217
170
|
}
|
|
218
171
|
if (messages) {
|
|
219
|
-
|
|
172
|
+
html = html.replaceAll('###messages###', "<ul>" + messages + "</ul>");
|
|
220
173
|
}
|
|
221
|
-
|
|
222
|
-
|
|
174
|
+
html = html.replace(/###[^#]*###/g, "");
|
|
175
|
+
const http_result = new OINOResult_js_1.OINOHttpResult(html);
|
|
176
|
+
return http_result;
|
|
223
177
|
}
|
|
224
178
|
static _findCsvLineEnd(csvData, start) {
|
|
225
179
|
const n = csvData.length;
|
|
@@ -496,7 +450,7 @@ class OINODbFactory {
|
|
|
496
450
|
start = end;
|
|
497
451
|
end = this._findMultipartBoundary(data, multipartBoundary, start);
|
|
498
452
|
}
|
|
499
|
-
|
|
453
|
+
// OINOLog.debug("createRowFromFormdata: next row", {row:row})
|
|
500
454
|
result.push(row);
|
|
501
455
|
return result;
|
|
502
456
|
}
|
|
@@ -507,7 +461,7 @@ class OINODbFactory {
|
|
|
507
461
|
const data_parts = data.trim().split('&');
|
|
508
462
|
for (let i = 0; i < data_parts.length; i++) {
|
|
509
463
|
const param_parts = data_parts[i].split('=');
|
|
510
|
-
|
|
464
|
+
// OINOLog.debug("createRowFromUrlencoded: next param", {param_parts:param_parts})
|
|
511
465
|
if (param_parts.length == 2) {
|
|
512
466
|
const key = index_js_1.OINOStr.decodeUrlencode(param_parts[0]) || "";
|
|
513
467
|
const field_index = datamodel.findFieldIndexByName(key);
|
|
@@ -525,7 +479,7 @@ class OINODbFactory {
|
|
|
525
479
|
}
|
|
526
480
|
// const value = requestParams[]
|
|
527
481
|
}
|
|
528
|
-
console.log("createRowFromUrlencoded: next row=" + row)
|
|
482
|
+
// console.log("createRowFromUrlencoded: next row=" + row)
|
|
529
483
|
result.push(row);
|
|
530
484
|
return result;
|
|
531
485
|
}
|
|
@@ -559,5 +513,21 @@ class OINODbFactory {
|
|
|
559
513
|
return [];
|
|
560
514
|
}
|
|
561
515
|
}
|
|
516
|
+
/**
|
|
517
|
+
* Create one data row from javascript object based on the datamodel.
|
|
518
|
+
* NOTE! Data assumed to be unserialized i.e. of the native type (string, number, boolean, Buffer)
|
|
519
|
+
*
|
|
520
|
+
* @param datamodel datamodel of the api
|
|
521
|
+
* @param data data as javascript object
|
|
522
|
+
*
|
|
523
|
+
*/
|
|
524
|
+
static createRowFromObject(datamodel, data) {
|
|
525
|
+
const fields = datamodel.fields;
|
|
526
|
+
let result = new Array(fields.length);
|
|
527
|
+
for (let i = 0; i < fields.length; i++) {
|
|
528
|
+
result[i] = data[fields[i].name];
|
|
529
|
+
}
|
|
530
|
+
return result;
|
|
531
|
+
}
|
|
562
532
|
}
|
|
563
533
|
exports.OINODbFactory = OINODbFactory;
|
|
@@ -173,7 +173,7 @@ class OINODbSqlFilter {
|
|
|
173
173
|
result += this._rightSide;
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
|
-
|
|
176
|
+
// OINOLog.debug("OINOFilter.toSql", {result:result})
|
|
177
177
|
return "(" + result + ")";
|
|
178
178
|
}
|
|
179
179
|
}
|
|
@@ -185,26 +185,47 @@ exports.OINODbSqlFilter = OINODbSqlFilter;
|
|
|
185
185
|
class OINODbSqlOrder {
|
|
186
186
|
static _orderColumnRegex = /^\s*(\w+)\s?(ASC|DESC)?\s*?$/i;
|
|
187
187
|
_columns;
|
|
188
|
-
|
|
188
|
+
_descending;
|
|
189
189
|
/**
|
|
190
190
|
* Constructor for `OINODbSqlOrder`.
|
|
191
191
|
*
|
|
192
|
-
* @param
|
|
192
|
+
* @param column_or_array single or array of columns to order on
|
|
193
|
+
* @param descending_or_array single or array of booleans if ordes is descending
|
|
193
194
|
*
|
|
194
195
|
*/
|
|
195
|
-
constructor(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
196
|
+
constructor(column_or_array, descending_or_array) {
|
|
197
|
+
index_js_1.OINOLog.debug("OINODbSqlOrder.constructor", { columns: column_or_array, directions: descending_or_array });
|
|
198
|
+
if (Array.isArray(column_or_array)) {
|
|
199
|
+
this._columns = column_or_array;
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
this._columns = [column_or_array];
|
|
203
|
+
}
|
|
204
|
+
if (Array.isArray(descending_or_array)) {
|
|
205
|
+
this._descending = descending_or_array;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
this._descending = [descending_or_array];
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Constructor for `OINODbSqlOrder` as parser of http parameter.
|
|
213
|
+
*
|
|
214
|
+
* @param orderString string representation of ordering from HTTP-request
|
|
215
|
+
*
|
|
216
|
+
*/
|
|
217
|
+
static parse(orderString) {
|
|
218
|
+
let columns = [];
|
|
219
|
+
let directions = [];
|
|
199
220
|
const column_strings = orderString.split(',');
|
|
200
221
|
for (let i = 0; i < column_strings.length; i++) {
|
|
201
222
|
let match = OINODbSqlOrder._orderColumnRegex.exec(column_strings[i]);
|
|
202
223
|
if (match != null) {
|
|
203
|
-
|
|
204
|
-
|
|
224
|
+
columns.push(match[1]);
|
|
225
|
+
directions.push((match[2] || "DESC").toUpperCase() == "DESC");
|
|
205
226
|
}
|
|
206
227
|
}
|
|
207
|
-
|
|
228
|
+
return new OINODbSqlOrder(columns, directions);
|
|
208
229
|
}
|
|
209
230
|
/**
|
|
210
231
|
* Does filter contain any valid conditions.
|
|
@@ -231,7 +252,13 @@ class OINODbSqlOrder {
|
|
|
231
252
|
if (result) {
|
|
232
253
|
result += ",";
|
|
233
254
|
}
|
|
234
|
-
result += dataModel.api.db.printSqlColumnname(field.name) + " "
|
|
255
|
+
result += dataModel.api.db.printSqlColumnname(field.name) + " ";
|
|
256
|
+
if (this._descending[i]) {
|
|
257
|
+
result += "DESC";
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
result += "ASC";
|
|
261
|
+
}
|
|
235
262
|
}
|
|
236
263
|
}
|
|
237
264
|
// OINOLog.debug("OINODbSqlOrder.toSql", {result:result})
|
|
@@ -249,12 +276,25 @@ class OINODbSqlLimit {
|
|
|
249
276
|
/**
|
|
250
277
|
* Constructor for `OINODbSqlLimit`.
|
|
251
278
|
*
|
|
252
|
-
* @param
|
|
279
|
+
* @param limit maximum number of items to return
|
|
280
|
+
*
|
|
281
|
+
*/
|
|
282
|
+
constructor(limit) {
|
|
283
|
+
this._limit = limit;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Constructor for `OINODbSqlLimit` as parser of http parameter.
|
|
287
|
+
*
|
|
288
|
+
* @param limitString string representation of limit from HTTP-request
|
|
253
289
|
*
|
|
254
290
|
*/
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
291
|
+
static parse(limitString) {
|
|
292
|
+
try {
|
|
293
|
+
return new OINODbSqlLimit(Number.parseInt(limitString));
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
return new OINODbSqlLimit(-1);
|
|
297
|
+
}
|
|
258
298
|
}
|
|
259
299
|
/**
|
|
260
300
|
* Does filter contain any valid conditions.
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OINODB_EMPTY_ROWS = exports.OINODB_EMPTY_ROW = exports.OINODbSwagger = exports.OINODbFactory = exports.OINODbConfig = exports.OINODbSqlBooleanOperation = exports.OINODbSqlLimit = exports.OINODbSqlComparison = exports.OINODbSqlOrder = exports.OINODbSqlFilter = exports.OINODbMemoryDataSet = exports.OINODbDataSet = exports.OINODb = exports.OINODatetimeDataField = exports.OINOBlobDataField = exports.OINOStringDataField = exports.OINONumberDataField = exports.OINOBooleanDataField = exports.OINODbDataField = exports.OINODbModelSet = exports.OINODbDataModel = exports.OINODbApi = exports.OINODbApiResult = exports.OINOResult = exports.OINOConsoleLog = exports.OINOLogLevel = exports.OINOLog = exports.OINOBenchmark = exports.OINOStr = exports.OINO_DEBUG_PREFIX = exports.OINO_INFO_PREFIX = exports.OINO_WARNING_PREFIX = exports.OINO_ERROR_PREFIX = exports.OINOContentType = void 0;
|
|
3
|
+
exports.OINODB_EMPTY_ROWS = exports.OINODB_EMPTY_ROW = exports.OINODbSwagger = exports.OINODbFactory = exports.OINODbConfig = exports.OINODbSqlBooleanOperation = exports.OINODbSqlLimit = exports.OINODbSqlComparison = exports.OINODbSqlOrder = exports.OINODbSqlFilter = exports.OINODbMemoryDataSet = exports.OINODbDataSet = exports.OINODb = exports.OINODatetimeDataField = exports.OINOBlobDataField = exports.OINOStringDataField = exports.OINONumberDataField = exports.OINOBooleanDataField = exports.OINODbDataField = exports.OINODbModelSet = exports.OINODbDataModel = exports.OINODbApi = exports.OINODbHtmlTemplate = exports.OINODbApiResult = exports.OINOHtmlTemplate = exports.OINOHttpResult = exports.OINOResult = exports.OINOConsoleLog = exports.OINOLogLevel = exports.OINOLog = exports.OINOBenchmark = exports.OINOStr = exports.OINO_DEBUG_PREFIX = exports.OINO_INFO_PREFIX = exports.OINO_WARNING_PREFIX = exports.OINO_ERROR_PREFIX = exports.OINOContentType = void 0;
|
|
4
4
|
const types_1 = require("@oino-ts/types");
|
|
5
5
|
Object.defineProperty(exports, "OINOContentType", { enumerable: true, get: function () { return types_1.OINOContentType; } });
|
|
6
6
|
var types_2 = require("@oino-ts/types");
|
|
@@ -14,8 +14,11 @@ Object.defineProperty(exports, "OINOLog", { enumerable: true, get: function () {
|
|
|
14
14
|
Object.defineProperty(exports, "OINOLogLevel", { enumerable: true, get: function () { return types_2.OINOLogLevel; } });
|
|
15
15
|
Object.defineProperty(exports, "OINOConsoleLog", { enumerable: true, get: function () { return types_2.OINOConsoleLog; } });
|
|
16
16
|
Object.defineProperty(exports, "OINOResult", { enumerable: true, get: function () { return types_2.OINOResult; } });
|
|
17
|
+
Object.defineProperty(exports, "OINOHttpResult", { enumerable: true, get: function () { return types_2.OINOHttpResult; } });
|
|
18
|
+
Object.defineProperty(exports, "OINOHtmlTemplate", { enumerable: true, get: function () { return types_2.OINOHtmlTemplate; } });
|
|
17
19
|
var OINODbApi_js_1 = require("./OINODbApi.js");
|
|
18
20
|
Object.defineProperty(exports, "OINODbApiResult", { enumerable: true, get: function () { return OINODbApi_js_1.OINODbApiResult; } });
|
|
21
|
+
Object.defineProperty(exports, "OINODbHtmlTemplate", { enumerable: true, get: function () { return OINODbApi_js_1.OINODbHtmlTemplate; } });
|
|
19
22
|
Object.defineProperty(exports, "OINODbApi", { enumerable: true, get: function () { return OINODbApi_js_1.OINODbApi; } });
|
|
20
23
|
var OINODbDataModel_js_1 = require("./OINODbDataModel.js");
|
|
21
24
|
Object.defineProperty(exports, "OINODbDataModel", { enumerable: true, get: function () { return OINODbDataModel_js_1.OINODbDataModel; } });
|