@oino-ts/common 0.21.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +183 -0
- package/dist/cjs/OINOApi.js +322 -0
- package/dist/cjs/OINOConfig.js +104 -0
- package/dist/cjs/OINOConstants.js +42 -0
- package/dist/cjs/OINODataField.js +346 -0
- package/dist/cjs/OINODataModel.js +182 -0
- package/dist/cjs/OINODataSource.js +165 -0
- package/dist/cjs/OINOFormatter.js +6 -5
- package/dist/cjs/OINOHtmlTemplate.js +21 -18
- package/dist/cjs/OINOModelSet.js +333 -0
- package/dist/cjs/OINOParser.js +448 -0
- package/dist/cjs/OINOQueryParams.js +434 -0
- package/dist/cjs/OINORequest.js +21 -13
- package/dist/cjs/OINOResult.js +13 -12
- package/dist/cjs/OINOStr.js +11 -11
- package/dist/cjs/OINOSwagger.js +205 -0
- package/dist/cjs/index.js +57 -39
- package/dist/esm/OINOApi.js +315 -0
- package/dist/esm/OINOConfig.js +100 -0
- package/dist/esm/OINOConstants.js +39 -0
- package/dist/esm/OINODataField.js +337 -0
- package/dist/esm/OINODataModel.js +178 -0
- package/dist/esm/OINODataSource.js +159 -0
- package/dist/esm/OINOFormatter.js +2 -1
- package/dist/esm/OINOHtmlTemplate.js +4 -1
- package/dist/esm/OINOModelSet.js +329 -0
- package/dist/esm/OINOParser.js +444 -0
- package/dist/esm/OINOQueryParams.js +426 -0
- package/dist/esm/OINORequest.js +9 -1
- package/dist/esm/OINOResult.js +2 -1
- package/dist/esm/OINOStr.js +1 -1
- package/dist/esm/OINOSwagger.js +201 -0
- package/dist/esm/index.js +14 -32
- package/dist/types/OINOApi.d.ts +191 -0
- package/dist/types/OINOConfig.d.ts +63 -0
- package/dist/types/OINOConstants.d.ts +51 -0
- package/dist/types/OINODataField.d.ts +209 -0
- package/dist/types/OINODataModel.d.ts +78 -0
- package/dist/types/OINODataSource.d.ts +184 -0
- package/dist/types/OINOHtmlTemplate.d.ts +1 -1
- package/dist/types/OINOModelSet.d.ts +64 -0
- package/dist/types/OINOParser.d.ts +42 -0
- package/dist/types/OINOQueryParams.d.ts +270 -0
- package/dist/types/OINORequest.d.ts +4 -1
- package/dist/types/OINOResult.d.ts +1 -1
- package/dist/types/OINOStr.d.ts +1 -1
- package/dist/types/OINOSwagger.d.ts +25 -0
- package/dist/types/index.d.ts +14 -31
- package/package.json +32 -32
- package/src/OINOApi.ts +429 -0
- package/src/OINOBenchmark.ts +323 -323
- package/src/OINOConfig.ts +113 -0
- package/src/OINOConstants.ts +59 -0
- package/src/OINODataField.ts +371 -0
- package/src/OINODataModel.ts +187 -0
- package/src/OINODataSource.ts +280 -0
- package/src/OINOFormatter.ts +166 -165
- package/src/OINOHeaders.ts +51 -51
- package/src/OINOHtmlTemplate.test.ts +114 -114
- package/src/OINOHtmlTemplate.ts +225 -222
- package/src/OINOLog.ts +292 -292
- package/src/OINOModelSet.ts +359 -0
- package/src/OINOParser.ts +441 -0
- package/src/OINOQueryParams.ts +449 -0
- package/src/OINORequest.ts +204 -196
- package/src/OINOResult.ts +331 -330
- package/src/OINOStr.ts +254 -254
- package/src/OINOSwagger.ts +213 -0
- package/src/index.ts +18 -38
|
@@ -0,0 +1,426 @@
|
|
|
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
|
+
import { OINO_ERROR_PREFIX } from "./OINOConstants.js";
|
|
7
|
+
import { OINOStr } from "./OINOStr.js";
|
|
8
|
+
import { OINOLog } from "./OINOLog.js";
|
|
9
|
+
const OINO_FIELD_NAME_CHARS = "\\w\\s\\-\\_\\#\\¤";
|
|
10
|
+
/**
|
|
11
|
+
* Supported logical conjunctions in filter predicates.
|
|
12
|
+
* @enum
|
|
13
|
+
*/
|
|
14
|
+
export var OINOQueryBooleanOperation;
|
|
15
|
+
(function (OINOQueryBooleanOperation) {
|
|
16
|
+
OINOQueryBooleanOperation["and"] = "and";
|
|
17
|
+
OINOQueryBooleanOperation["or"] = "or";
|
|
18
|
+
OINOQueryBooleanOperation["not"] = "not";
|
|
19
|
+
})(OINOQueryBooleanOperation || (OINOQueryBooleanOperation = {}));
|
|
20
|
+
/**
|
|
21
|
+
* Supported logical conjunctions in filter predicates.
|
|
22
|
+
* @enum
|
|
23
|
+
*/
|
|
24
|
+
export var OINOQueryComparison;
|
|
25
|
+
(function (OINOQueryComparison) {
|
|
26
|
+
OINOQueryComparison["lt"] = "lt";
|
|
27
|
+
OINOQueryComparison["le"] = "le";
|
|
28
|
+
OINOQueryComparison["eq"] = "eq";
|
|
29
|
+
OINOQueryComparison["ne"] = "ne";
|
|
30
|
+
OINOQueryComparison["ge"] = "ge";
|
|
31
|
+
OINOQueryComparison["gt"] = "gt";
|
|
32
|
+
OINOQueryComparison["like"] = "like";
|
|
33
|
+
})(OINOQueryComparison || (OINOQueryComparison = {}));
|
|
34
|
+
/**
|
|
35
|
+
* Supported logical conjunctions in filter predicates.
|
|
36
|
+
* @enum
|
|
37
|
+
*/
|
|
38
|
+
export var OINOQueryNullCheck;
|
|
39
|
+
(function (OINOQueryNullCheck) {
|
|
40
|
+
OINOQueryNullCheck["isnull"] = "isnull";
|
|
41
|
+
OINOQueryNullCheck["isNotNull"] = "isNotNull";
|
|
42
|
+
})(OINOQueryNullCheck || (OINOQueryNullCheck = {}));
|
|
43
|
+
/**
|
|
44
|
+
* Supported aggregation functions in OINODbQueryAggregate.
|
|
45
|
+
* @enum
|
|
46
|
+
*/
|
|
47
|
+
export var OINOQueryAggregateFunctions;
|
|
48
|
+
(function (OINOQueryAggregateFunctions) {
|
|
49
|
+
OINOQueryAggregateFunctions["count"] = "count";
|
|
50
|
+
OINOQueryAggregateFunctions["sum"] = "sum";
|
|
51
|
+
OINOQueryAggregateFunctions["avg"] = "avg";
|
|
52
|
+
OINOQueryAggregateFunctions["min"] = "min";
|
|
53
|
+
OINOQueryAggregateFunctions["max"] = "max";
|
|
54
|
+
})(OINOQueryAggregateFunctions || (OINOQueryAggregateFunctions = {}));
|
|
55
|
+
/**
|
|
56
|
+
* Class for recursively parsing of filters and printing them as SQL conditions.
|
|
57
|
+
* Supports three types of statements
|
|
58
|
+
* - comparison: (field)-lt|le|eq|ge|gt|like(value)
|
|
59
|
+
* - negation: -not(filter)
|
|
60
|
+
* - conjunction/disjunction: (filter)-and|or(filter)
|
|
61
|
+
* Supported conditions are comparisons (<, <=, =, >=, >) and substring match (LIKE).
|
|
62
|
+
*
|
|
63
|
+
*/
|
|
64
|
+
export class OINOQueryFilter {
|
|
65
|
+
static _booleanOperationRegex = /^\s?\-(and|or)\s?$/i;
|
|
66
|
+
static _negationRegex = /^-(not)\((.+)\)$/i;
|
|
67
|
+
static _filterComparisonRegex = /^\(([^'"\(\)]+)\)\s?\-(lt|le|eq|ne|ge|gt|like)\s?\(([^'"\(\)]+)\)$/i;
|
|
68
|
+
static _filterNullCheckRegex = /^-(isnull|isNotNull)\((.+)\)$/i;
|
|
69
|
+
leftSide;
|
|
70
|
+
rightSide;
|
|
71
|
+
operator;
|
|
72
|
+
/**
|
|
73
|
+
* Constructor of `OINOQueryFilter`
|
|
74
|
+
* @param leftSide left side of the filter, either another filter or a column name
|
|
75
|
+
* @param operation operation of the filter, either `OINOQueryComparison` or `OINOQueryBooleanOperation`
|
|
76
|
+
* @param rightSide right side of the filter, either another filter or a value
|
|
77
|
+
*/
|
|
78
|
+
constructor(leftSide, operation, rightSide) {
|
|
79
|
+
if (!(((operation === null) && (leftSide == "") && (rightSide == "")) ||
|
|
80
|
+
((operation !== null) && (Object.values(OINOQueryComparison).includes(operation)) && (typeof (leftSide) == "string") && (leftSide != "") && (typeof (rightSide) == "string") && (rightSide != "")) ||
|
|
81
|
+
((operation == OINOQueryBooleanOperation.not) && (leftSide == "") && (rightSide instanceof OINOQueryFilter)) ||
|
|
82
|
+
(((operation == OINOQueryNullCheck.isnull) || (operation == OINOQueryNullCheck.isNotNull)) && (typeof (leftSide) == "string") && (rightSide == "")) ||
|
|
83
|
+
(((operation == OINOQueryBooleanOperation.and) || (operation == OINOQueryBooleanOperation.or)) && (leftSide instanceof OINOQueryFilter) && (rightSide instanceof OINOQueryFilter)))) {
|
|
84
|
+
OINOLog.error("@oino-ts/db", "OINOQueryFilter", "constructor", "Unsupported OINOQueryFilter format", { leftSide: leftSide, operation: operation, rightSide: rightSide });
|
|
85
|
+
throw new Error(OINO_ERROR_PREFIX + ": Unsupported OINOQueryFilter format!");
|
|
86
|
+
}
|
|
87
|
+
this.leftSide = leftSide;
|
|
88
|
+
this.operator = operation;
|
|
89
|
+
this.rightSide = rightSide;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Constructor for `OINOQueryFilter` as parser of http parameter.
|
|
93
|
+
*
|
|
94
|
+
* Supports three types of statements:
|
|
95
|
+
* - comparison: (field)-lt|le|eq|ge|gt|like(value)
|
|
96
|
+
* - negation: -not(filter)
|
|
97
|
+
* - conjunction/disjunction: (filter)-and|or(filter)
|
|
98
|
+
* - null check: -isnull(field) or -isNotNull(field)
|
|
99
|
+
*
|
|
100
|
+
* @param filterString string representation of filter from HTTP-request
|
|
101
|
+
*
|
|
102
|
+
*/
|
|
103
|
+
static parse(filterString) {
|
|
104
|
+
if (!filterString) {
|
|
105
|
+
return new OINOQueryFilter("", null, "");
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
let match = OINOQueryFilter._filterComparisonRegex.exec(filterString);
|
|
109
|
+
if ((match != null) && (match.length == 4)) {
|
|
110
|
+
return new OINOQueryFilter(match[1], match[2].toLowerCase(), match[3]);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
let match = OINOQueryFilter._negationRegex.exec(filterString);
|
|
114
|
+
if (match != null) {
|
|
115
|
+
return new OINOQueryFilter("", OINOQueryBooleanOperation.not, OINOQueryFilter.parse(match[3]));
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
let boolean_parts = OINOStr.splitByBrackets(filterString, true, false, '(', ')');
|
|
119
|
+
if (boolean_parts.length == 3 && (boolean_parts[1].match(OINOQueryFilter._booleanOperationRegex))) {
|
|
120
|
+
return new OINOQueryFilter(OINOQueryFilter.parse(boolean_parts[0]), boolean_parts[1].trim().toLowerCase().substring(1), OINOQueryFilter.parse(boolean_parts[2]));
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
let match = OINOQueryFilter._filterNullCheckRegex.exec(filterString);
|
|
124
|
+
if ((match != null)) {
|
|
125
|
+
return new OINOQueryFilter(match[2], match[1].toLowerCase(), "");
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
OINOLog.error("@oino-ts/db", "OINOQueryFilter", "constructor", "Invalid filter", { filterString: filterString });
|
|
129
|
+
throw new Error(OINO_ERROR_PREFIX + ": Invalid filter '" + filterString + "'"); // invalid filter could be a security risk, stop processing
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Construct a new `OINOQueryFilter` as combination of (boolean and/or) of two filters.
|
|
138
|
+
*
|
|
139
|
+
* @param leftSide left side to combine
|
|
140
|
+
* @param operation boolean operation to use in combination
|
|
141
|
+
* @param rightSide right side to combine
|
|
142
|
+
*
|
|
143
|
+
*/
|
|
144
|
+
static combine(leftSide, operation, rightSide) {
|
|
145
|
+
if ((leftSide) && (!leftSide.isEmpty()) && (rightSide) && (!rightSide.isEmpty())) {
|
|
146
|
+
return new OINOQueryFilter(leftSide, operation, rightSide);
|
|
147
|
+
}
|
|
148
|
+
else if ((leftSide) && (!leftSide.isEmpty())) {
|
|
149
|
+
return leftSide;
|
|
150
|
+
}
|
|
151
|
+
else if ((rightSide) && (!rightSide.isEmpty())) {
|
|
152
|
+
return rightSide;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Combine two filters with an AND operation.
|
|
160
|
+
*
|
|
161
|
+
* @param leftSide left side filter
|
|
162
|
+
* @param rightSide right side filter
|
|
163
|
+
*
|
|
164
|
+
*/
|
|
165
|
+
static and(leftSide, rightSide) {
|
|
166
|
+
if ((leftSide) && (!leftSide.isEmpty()) && (rightSide) && (!rightSide.isEmpty())) {
|
|
167
|
+
return new OINOQueryFilter(leftSide, OINOQueryBooleanOperation.and, rightSide);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Combine two filters with an OR operation.
|
|
175
|
+
*
|
|
176
|
+
* @param leftSide left side filter
|
|
177
|
+
* @param rightSide right side filter
|
|
178
|
+
*
|
|
179
|
+
*/
|
|
180
|
+
static or(leftSide, rightSide) {
|
|
181
|
+
if ((leftSide) && (!leftSide.isEmpty()) && (rightSide) && (!rightSide.isEmpty())) {
|
|
182
|
+
return new OINOQueryFilter(leftSide, OINOQueryBooleanOperation.or, rightSide);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Negate a filter with a NOT operation.
|
|
190
|
+
*
|
|
191
|
+
* @param leftSide left side filter
|
|
192
|
+
*
|
|
193
|
+
*/
|
|
194
|
+
static not(leftSide) {
|
|
195
|
+
if ((leftSide) && (!leftSide.isEmpty())) {
|
|
196
|
+
return new OINOQueryFilter(leftSide, OINOQueryBooleanOperation.not, "");
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Does filter contain any valid conditions.
|
|
204
|
+
*
|
|
205
|
+
*/
|
|
206
|
+
isEmpty() {
|
|
207
|
+
return (this.leftSide == "") && (this.operator == null) && (this.rightSide == "");
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Class for ordering select results on a number of columns.
|
|
212
|
+
*
|
|
213
|
+
*/
|
|
214
|
+
export class OINOQueryOrder {
|
|
215
|
+
static _orderColumnRegex = /^\s*(\w+)\s?(ASC|DESC|\+|\-)?\s*?$/i;
|
|
216
|
+
columns;
|
|
217
|
+
descending;
|
|
218
|
+
/**
|
|
219
|
+
* Constructor for `OINOQueryOrder`.
|
|
220
|
+
*
|
|
221
|
+
* @param column_or_array single or array of columns to order on
|
|
222
|
+
* @param descending_or_array single or array of booleans if ordes is descending
|
|
223
|
+
*
|
|
224
|
+
*/
|
|
225
|
+
constructor(column_or_array, descending_or_array) {
|
|
226
|
+
if (Array.isArray(column_or_array)) {
|
|
227
|
+
this.columns = column_or_array;
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
this.columns = [column_or_array];
|
|
231
|
+
}
|
|
232
|
+
if (Array.isArray(descending_or_array)) {
|
|
233
|
+
this.descending = descending_or_array;
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
this.descending = [descending_or_array];
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Constructor for `OINOQueryOrder` as parser of http parameter.
|
|
241
|
+
*
|
|
242
|
+
* Supports comma separated list of column orders formatted as :
|
|
243
|
+
* - `column` - order by column in ascending order
|
|
244
|
+
* - `column ASC|DESC` - order by single either ascending or descending order
|
|
245
|
+
* - `column+|-` - order by single either ascending or descending order
|
|
246
|
+
*
|
|
247
|
+
* @param orderString string representation of order from HTTP-request
|
|
248
|
+
*
|
|
249
|
+
*/
|
|
250
|
+
static parse(orderString) {
|
|
251
|
+
let columns = [];
|
|
252
|
+
let directions = [];
|
|
253
|
+
const column_strings = orderString.split(',');
|
|
254
|
+
for (let i = 0; i < column_strings.length; i++) {
|
|
255
|
+
let match = OINOQueryOrder._orderColumnRegex.exec(column_strings[i]);
|
|
256
|
+
if (match != null) {
|
|
257
|
+
columns.push(match[1]);
|
|
258
|
+
const dir = (match[2] || "ASC").toUpperCase();
|
|
259
|
+
directions.push((dir == "DESC") || (dir == "-"));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return new OINOQueryOrder(columns, directions);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Does filter contain any valid conditions.
|
|
266
|
+
*
|
|
267
|
+
*/
|
|
268
|
+
isEmpty() {
|
|
269
|
+
return (this.columns.length == 0);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Class for limiting the number of results.
|
|
274
|
+
*
|
|
275
|
+
*/
|
|
276
|
+
export class OINOQueryLimit {
|
|
277
|
+
static _limitRegex = /^(\d+)(\spage\s|\.)?(\d+)?$/i;
|
|
278
|
+
limit;
|
|
279
|
+
page;
|
|
280
|
+
/**
|
|
281
|
+
* Constructor for `OINOQueryLimit`.
|
|
282
|
+
*
|
|
283
|
+
* @param limit maximum number of items to return
|
|
284
|
+
* @param page page number to return starting from 1
|
|
285
|
+
*
|
|
286
|
+
*/
|
|
287
|
+
constructor(limit, page = -1) {
|
|
288
|
+
this.limit = limit;
|
|
289
|
+
this.page = page;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Constructor for `OINOQueryLimit` as parser of http parameter.
|
|
293
|
+
*
|
|
294
|
+
* Supports limit and page formatted as:
|
|
295
|
+
* - `limit` - limit number of items to return
|
|
296
|
+
* - `limit page n` - limit number of items to return and return page n (starting from 1)
|
|
297
|
+
* - `limit.n` - limit number of items to return and return page n (starting from 1)
|
|
298
|
+
*
|
|
299
|
+
* @param limitString string representation of limit from HTTP-request
|
|
300
|
+
*
|
|
301
|
+
*/
|
|
302
|
+
static parse(limitString) {
|
|
303
|
+
let match = OINOQueryLimit._limitRegex.exec(limitString);
|
|
304
|
+
if ((match != null) && (match.length == 4)) {
|
|
305
|
+
return new OINOQueryLimit(Number.parseInt(match[1]), Number.parseInt(match[3]));
|
|
306
|
+
}
|
|
307
|
+
else if (match != null) {
|
|
308
|
+
return new OINOQueryLimit(Number.parseInt(match[1]));
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
return new OINOQueryLimit(-1);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Does filter contain any valid conditions.
|
|
316
|
+
*
|
|
317
|
+
*/
|
|
318
|
+
isEmpty() {
|
|
319
|
+
return (this.limit <= 0);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Class for limiting the number of results.
|
|
324
|
+
*
|
|
325
|
+
*/
|
|
326
|
+
export class OINOQueryAggregate {
|
|
327
|
+
static _aggregateRegex = new RegExp("^(count|sum|avg|min|max)\\(([" + OINO_FIELD_NAME_CHARS + "]+)\\)$", "mi");
|
|
328
|
+
functions;
|
|
329
|
+
fields;
|
|
330
|
+
/**
|
|
331
|
+
* Constructor for `OINOQueryAggregate`.
|
|
332
|
+
*
|
|
333
|
+
* @param functions aggregate function to use
|
|
334
|
+
* @param fields fields to aggregate
|
|
335
|
+
*
|
|
336
|
+
*/
|
|
337
|
+
constructor(functions, fields) {
|
|
338
|
+
this.functions = functions;
|
|
339
|
+
this.fields = fields;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Constructor for `OINOQueryAggregate` as parser of http parameter.
|
|
343
|
+
*
|
|
344
|
+
* Supports comma separated list of aggregates formatted as:
|
|
345
|
+
* - `function(field)`
|
|
346
|
+
*
|
|
347
|
+
* Supported functions are count, sum, avg, min, max.
|
|
348
|
+
*
|
|
349
|
+
* @param aggregatorString string representation of limit from HTTP-request
|
|
350
|
+
*
|
|
351
|
+
*/
|
|
352
|
+
static parse(aggregatorString) {
|
|
353
|
+
let funtions = [];
|
|
354
|
+
let fields = [];
|
|
355
|
+
const aggregator_parts = aggregatorString.split(',');
|
|
356
|
+
for (let i = 0; i < aggregator_parts.length; i++) {
|
|
357
|
+
let match = OINOQueryAggregate._aggregateRegex.exec(aggregator_parts[i]);
|
|
358
|
+
if ((match != null) && (match.length == 3)) {
|
|
359
|
+
funtions.push(match[1]);
|
|
360
|
+
fields.push(match[2]);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return new OINOQueryAggregate(funtions, fields);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Does filter contain any valid conditions.
|
|
367
|
+
*
|
|
368
|
+
*/
|
|
369
|
+
isEmpty() {
|
|
370
|
+
return (this.functions.length <= 0);
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Does filter contain any valid conditions.
|
|
374
|
+
*
|
|
375
|
+
* @param field field to check if it is aggregated
|
|
376
|
+
*/
|
|
377
|
+
isAggregated(field) {
|
|
378
|
+
return (this.fields.includes(field));
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Class for ordering select results on a number of columns.
|
|
383
|
+
*
|
|
384
|
+
*/
|
|
385
|
+
export class OINOQuerySelect {
|
|
386
|
+
columns;
|
|
387
|
+
/**
|
|
388
|
+
* Constructor for `OINOQuerySelect`.
|
|
389
|
+
*
|
|
390
|
+
* @param columns array of columns to select
|
|
391
|
+
*
|
|
392
|
+
*/
|
|
393
|
+
constructor(columns) {
|
|
394
|
+
this.columns = columns;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Constructor for `OINOQuerySelect` as parser of http parameter.
|
|
398
|
+
*
|
|
399
|
+
* @param columns comma separated string selected columns from HTTP-request
|
|
400
|
+
*
|
|
401
|
+
*/
|
|
402
|
+
static parse(columns) {
|
|
403
|
+
if (columns == "") {
|
|
404
|
+
return new OINOQuerySelect([]);
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
return new OINOQuerySelect(columns.split(','));
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Does select contain any valid columns.
|
|
412
|
+
*
|
|
413
|
+
*/
|
|
414
|
+
isEmpty() {
|
|
415
|
+
return (this.columns.length == 0);
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Does select include given column.
|
|
419
|
+
*
|
|
420
|
+
* @param field field to check if it is selected
|
|
421
|
+
*
|
|
422
|
+
*/
|
|
423
|
+
isSelected(field) {
|
|
424
|
+
return ((this.columns.length == 0) || (this.columns.includes(field)));
|
|
425
|
+
}
|
|
426
|
+
}
|
package/dist/esm/OINORequest.js
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
6
|
import { Buffer } from "node:buffer";
|
|
7
|
-
import { OINOContentType, OINO_REQUEST_TYPE_PARAM, OINO_RESPONSE_TYPE_PARAM,
|
|
7
|
+
import { OINOContentType, OINO_REQUEST_TYPE_PARAM, OINO_RESPONSE_TYPE_PARAM, OINO_RESPONSE_DOWNLOAD_PARAM } from "./OINOConstants.js";
|
|
8
|
+
import { OINOHeaders } from "./OINOHeaders.js";
|
|
8
9
|
/**
|
|
9
10
|
* OINO API request result object with returned data and/or http status code/message and
|
|
10
11
|
* error / warning messages.
|
|
@@ -33,6 +34,7 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
33
34
|
body;
|
|
34
35
|
requestType;
|
|
35
36
|
responseType;
|
|
37
|
+
responseDownload;
|
|
36
38
|
multipartBoundary;
|
|
37
39
|
lastModified;
|
|
38
40
|
etags;
|
|
@@ -89,6 +91,12 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
89
91
|
}
|
|
90
92
|
this.responseType = response_type ?? OINOContentType.json;
|
|
91
93
|
}
|
|
94
|
+
if (init.responseDownload) {
|
|
95
|
+
this.responseDownload = init.responseDownload;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
this.responseDownload = this.url?.searchParams.get(OINO_RESPONSE_DOWNLOAD_PARAM) ?? "";
|
|
99
|
+
}
|
|
92
100
|
const last_modified = this.headers.get("if-modified-since");
|
|
93
101
|
if (last_modified) {
|
|
94
102
|
this.lastModified = new Date(last_modified).getTime();
|
package/dist/esm/OINOResult.js
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { createHash } from "node:crypto";
|
|
7
7
|
import { Buffer } from "node:buffer";
|
|
8
|
-
import { OINO_DEBUG_PREFIX, OINO_ERROR_PREFIX, OINO_INFO_PREFIX, OINO_WARNING_PREFIX
|
|
8
|
+
import { OINO_DEBUG_PREFIX, OINO_ERROR_PREFIX, OINO_INFO_PREFIX, OINO_WARNING_PREFIX } from "./OINOConstants.js";
|
|
9
|
+
import { OINOHeaders } from "./OINOHeaders.js";
|
|
9
10
|
/**
|
|
10
11
|
* OINO API request result object with returned data and/or http status code/message and
|
|
11
12
|
* error / warning messages.
|
package/dist/esm/OINOStr.js
CHANGED
|
@@ -0,0 +1,201 @@
|
|
|
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 Swagger utilities
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
export class OINOSwagger {
|
|
11
|
+
static _getSchemaApiMethodParamsQueryId() {
|
|
12
|
+
return {
|
|
13
|
+
"schema": {
|
|
14
|
+
"type": "string"
|
|
15
|
+
},
|
|
16
|
+
"in": "path",
|
|
17
|
+
"name": "id",
|
|
18
|
+
"required": true
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
static _getSchemaApiMethodParamsBody(tableName) {
|
|
22
|
+
return {
|
|
23
|
+
"required": true,
|
|
24
|
+
"content": {
|
|
25
|
+
"application/json": {
|
|
26
|
+
"schema": {
|
|
27
|
+
"$ref": "#/components/schemas/" + tableName
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
static _getSchemaApiMethodDescription(method, tableName, hasQueryIdParam) {
|
|
34
|
+
if (hasQueryIdParam) {
|
|
35
|
+
return method.toUpperCase() + " " + tableName + " object";
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
return method.toUpperCase() + " " + tableName + " object array";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
static _getSchemaApiMethodOperationId(method, tableName, hasQueryIdParam) {
|
|
42
|
+
if (hasQueryIdParam) {
|
|
43
|
+
return method + tableName;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
return method + tableName + "All";
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
static _getSchemaOinoResponse() {
|
|
50
|
+
return {
|
|
51
|
+
"type": "object",
|
|
52
|
+
"properties": {
|
|
53
|
+
"success": {
|
|
54
|
+
"type": "boolean"
|
|
55
|
+
},
|
|
56
|
+
"status": {
|
|
57
|
+
"type": "number"
|
|
58
|
+
},
|
|
59
|
+
"statusText": {
|
|
60
|
+
"type": "string"
|
|
61
|
+
},
|
|
62
|
+
"messages": {
|
|
63
|
+
"type": "array",
|
|
64
|
+
"items": {
|
|
65
|
+
"type": "string"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"required": [
|
|
70
|
+
"success",
|
|
71
|
+
"status",
|
|
72
|
+
"statusText",
|
|
73
|
+
"messages"
|
|
74
|
+
]
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
static _getSchemaFieldType(field) {
|
|
78
|
+
let type_string;
|
|
79
|
+
if (field.type == "boolean") {
|
|
80
|
+
type_string = "boolean";
|
|
81
|
+
}
|
|
82
|
+
else if (field.type == "integer" || field.type == "number") {
|
|
83
|
+
type_string = "number";
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
type_string = "string";
|
|
87
|
+
}
|
|
88
|
+
if (!field.fieldParams.isNotNull) {
|
|
89
|
+
return {
|
|
90
|
+
"anyOf": [
|
|
91
|
+
{
|
|
92
|
+
"type": type_string
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"type": "null"
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
return { type: type_string };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
static _getSwaggerApiType(api) {
|
|
105
|
+
let result = {
|
|
106
|
+
type: "object",
|
|
107
|
+
properties: {},
|
|
108
|
+
required: []
|
|
109
|
+
};
|
|
110
|
+
let field;
|
|
111
|
+
for (field of api.datamodel.fields) {
|
|
112
|
+
result.properties[field.name] = this._getSchemaFieldType(field);
|
|
113
|
+
if (field.fieldParams.isPrimaryKey) {
|
|
114
|
+
result.required.push(field.name);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
static _getSchemaType(tableName, hasQueryIdParam, hasResultData) {
|
|
120
|
+
if (hasResultData && hasQueryIdParam) {
|
|
121
|
+
return { "$ref": "#/components/schemas/" + tableName };
|
|
122
|
+
}
|
|
123
|
+
else if (hasResultData) {
|
|
124
|
+
return { type: "array", items: { "$ref": "#/components/schemas/" + tableName } };
|
|
125
|
+
}
|
|
126
|
+
else if (hasQueryIdParam) {
|
|
127
|
+
return { "$ref": "#/components/schemas/OINOResponse" };
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
return { "$ref": "#/components/schemas/OINOResponse" };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
static _getSchemaApiMethodParams(hasQueryIdParam) {
|
|
134
|
+
if (hasQueryIdParam) {
|
|
135
|
+
return [this._getSchemaApiMethodParamsQueryId()];
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
static _getSchemaApiMethod(method, tableName, hasQueryIdParam, hasBody, hasResultData) {
|
|
142
|
+
const result = {
|
|
143
|
+
responses: {
|
|
144
|
+
200: { description: this._getSchemaApiMethodDescription(method, tableName, hasQueryIdParam), content: { "application/json": { schema: this._getSchemaType(tableName, hasQueryIdParam, hasResultData) } } }
|
|
145
|
+
},
|
|
146
|
+
"operationId": this._getSchemaApiMethodOperationId(method, tableName, hasQueryIdParam),
|
|
147
|
+
"parameters": this._getSchemaApiMethodParams(hasQueryIdParam)
|
|
148
|
+
};
|
|
149
|
+
if (hasBody) {
|
|
150
|
+
result["requestBody"] = this._getSchemaApiMethodParamsBody(tableName);
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
static _getSwaggerApiPath(tableName, hasQueryIdParam) {
|
|
155
|
+
if (hasQueryIdParam) {
|
|
156
|
+
return {
|
|
157
|
+
get: this._getSchemaApiMethod("get", tableName, hasQueryIdParam, false, true),
|
|
158
|
+
put: this._getSchemaApiMethod("put", tableName, hasQueryIdParam, true, false),
|
|
159
|
+
delete: this._getSchemaApiMethod("delete", tableName, hasQueryIdParam, false, false)
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
return {
|
|
164
|
+
get: this._getSchemaApiMethod("get", tableName, hasQueryIdParam, false, true),
|
|
165
|
+
post: this._getSchemaApiMethod("post", tableName, hasQueryIdParam, true, false)
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Returns swagger.json as object of the given API's.
|
|
171
|
+
*
|
|
172
|
+
* @param apis array of API's use for Swagger definition
|
|
173
|
+
*
|
|
174
|
+
*/
|
|
175
|
+
static getApiDefinition(apis) {
|
|
176
|
+
let result = {
|
|
177
|
+
"openapi": "3.1.0",
|
|
178
|
+
"info": {
|
|
179
|
+
"title": "",
|
|
180
|
+
"description": "",
|
|
181
|
+
"version": ""
|
|
182
|
+
},
|
|
183
|
+
"paths": {},
|
|
184
|
+
"components": {
|
|
185
|
+
"schemas": {
|
|
186
|
+
OINOResponse: this._getSchemaOinoResponse()
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
for (let i = 0; i < apis.length; i++) {
|
|
191
|
+
if (!apis[i].initialized) {
|
|
192
|
+
throw new Error("API " + apis[i].params.tableName + " is not initialized, cannot create Swagger definition");
|
|
193
|
+
}
|
|
194
|
+
const table_name = apis[i].params.tableName;
|
|
195
|
+
result.paths["/" + table_name] = this._getSwaggerApiPath(table_name, false);
|
|
196
|
+
result.paths["/" + table_name + "/{id}"] = this._getSwaggerApiPath(table_name, true);
|
|
197
|
+
result.components.schemas[table_name] = this._getSwaggerApiType(apis[i]);
|
|
198
|
+
}
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
}
|