@oino-ts/common 0.21.1 → 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/OINOBenchmark.js +3 -4
- 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/OINOBenchmark.js +3 -4
- 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/OINOBenchmark.d.ts +1 -1
- 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 -324
- 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,448 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.OINOParser = void 0;
|
|
9
|
+
const node_buffer_1 = require("node:buffer");
|
|
10
|
+
const OINOConstants_js_1 = require("./OINOConstants.js");
|
|
11
|
+
const OINOStr_js_1 = require("./OINOStr.js");
|
|
12
|
+
const OINOLog_js_1 = require("./OINOLog.js");
|
|
13
|
+
const OINODataField_js_1 = require("./OINODataField.js");
|
|
14
|
+
/**
|
|
15
|
+
* Static factory class for easily creating things based on data
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
class OINOParser {
|
|
19
|
+
/**
|
|
20
|
+
* Create data rows from request body based on the datamodel.
|
|
21
|
+
*
|
|
22
|
+
* @param datamodel datamodel of the api
|
|
23
|
+
* @param data data as either serialized string or unserialized JS object or OINODataRow-array or Buffer/Uint8Array binary data
|
|
24
|
+
* @param contentType content type of the data
|
|
25
|
+
* @param multipartBoundary multipart boundary for formdata parsing, if applicable
|
|
26
|
+
*
|
|
27
|
+
*/
|
|
28
|
+
static createRows(datamodel, data, contentType, multipartBoundary) {
|
|
29
|
+
let result = [];
|
|
30
|
+
if (typeof data == "string") {
|
|
31
|
+
result = this._createRowsFromText(datamodel, data, contentType, multipartBoundary);
|
|
32
|
+
}
|
|
33
|
+
else if ((data instanceof node_buffer_1.Buffer) || (data instanceof Uint8Array)) {
|
|
34
|
+
result = this._createRowsFromBlob(datamodel, data, contentType, multipartBoundary);
|
|
35
|
+
}
|
|
36
|
+
else if (typeof data == "object") {
|
|
37
|
+
result = [this._createRowFromObject(datamodel, data)];
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
static _createRowsFromText(datamodel, data, contentType, multipartBoundary) {
|
|
42
|
+
if ((contentType == OINOConstants_js_1.OINOContentType.json) || (contentType == undefined)) {
|
|
43
|
+
return this._createRowFromJson(datamodel, data);
|
|
44
|
+
}
|
|
45
|
+
else if (contentType == OINOConstants_js_1.OINOContentType.csv) {
|
|
46
|
+
return this._createRowFromCsv(datamodel, data);
|
|
47
|
+
}
|
|
48
|
+
else if (contentType == OINOConstants_js_1.OINOContentType.formdata) {
|
|
49
|
+
return this._createRowFromFormdata(datamodel, node_buffer_1.Buffer.from(data, "utf8"), multipartBoundary || "");
|
|
50
|
+
}
|
|
51
|
+
else if (contentType == OINOConstants_js_1.OINOContentType.urlencode) {
|
|
52
|
+
return this._createRowFromUrlencoded(datamodel, data);
|
|
53
|
+
}
|
|
54
|
+
else if (contentType == OINOConstants_js_1.OINOContentType.html) {
|
|
55
|
+
OINOLog_js_1.OINOLog.error("@oino-ts/db", "OINOParser", "createRowsFromText", "HTML can't be used as an input content type!", { contentType: OINOConstants_js_1.OINOContentType.html });
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
OINOLog_js_1.OINOLog.error("@oino-ts/db", "OINOParser", "createRowsFromText", "Unrecognized input content type!", { contentType: contentType });
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
static _createRowsFromBlob(datamodel, data, contentType, multipartBoundary) {
|
|
64
|
+
if (data instanceof Uint8Array && !(data instanceof node_buffer_1.Buffer)) {
|
|
65
|
+
data = node_buffer_1.Buffer.from(data);
|
|
66
|
+
}
|
|
67
|
+
if ((contentType == OINOConstants_js_1.OINOContentType.json) || (contentType == undefined)) {
|
|
68
|
+
return this._createRowFromJson(datamodel, data.toString()); // JSON is always a string
|
|
69
|
+
}
|
|
70
|
+
else if (contentType == OINOConstants_js_1.OINOContentType.csv) {
|
|
71
|
+
return this._createRowFromCsv(datamodel, data.toString()); // binary data has to be base64 encoded so it's a string
|
|
72
|
+
}
|
|
73
|
+
else if (contentType == OINOConstants_js_1.OINOContentType.formdata) {
|
|
74
|
+
return this._createRowFromFormdata(datamodel, data, multipartBoundary || "");
|
|
75
|
+
}
|
|
76
|
+
else if (contentType == OINOConstants_js_1.OINOContentType.urlencode) {
|
|
77
|
+
return this._createRowFromUrlencoded(datamodel, data.toString()); // data is urlencoded so it's a string
|
|
78
|
+
}
|
|
79
|
+
else if (contentType == OINOConstants_js_1.OINOContentType.html) {
|
|
80
|
+
OINOLog_js_1.OINOLog.error("@oino-ts/db", "OINOParser", "createRowsFromBlob", "HTML can't be used as an input content type!", { contentType: OINOConstants_js_1.OINOContentType.html });
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
OINOLog_js_1.OINOLog.error("@oino-ts/db", "OINOParser", "createRowsFromBlob", "Unrecognized input content type!", { contentType: contentType });
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Create one data row from javascript object based on the datamodel.
|
|
90
|
+
* NOTE! Data assumed to be unserialized i.e. of the native type (string, number, boolean, Buffer)
|
|
91
|
+
*
|
|
92
|
+
* @param datamodel datamodel of the api
|
|
93
|
+
* @param data data as javascript object
|
|
94
|
+
*
|
|
95
|
+
*/
|
|
96
|
+
static _createRowFromObject(datamodel, data) {
|
|
97
|
+
const fields = datamodel.fields;
|
|
98
|
+
let result = new Array(fields.length);
|
|
99
|
+
for (let i = 0; i < fields.length; i++) {
|
|
100
|
+
result[i] = data[fields[i].name];
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
static _findCsvLineEnd(csvData, start) {
|
|
105
|
+
const n = csvData.length;
|
|
106
|
+
if (start >= n) {
|
|
107
|
+
return start;
|
|
108
|
+
}
|
|
109
|
+
let end = start;
|
|
110
|
+
let quote_open = false;
|
|
111
|
+
while (end < n) {
|
|
112
|
+
if (csvData[end] == "\"") {
|
|
113
|
+
if (!quote_open) {
|
|
114
|
+
quote_open = true;
|
|
115
|
+
}
|
|
116
|
+
else if ((end < n - 1) && (csvData[end + 1] == "\"")) {
|
|
117
|
+
end++;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
quote_open = false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else if ((!quote_open) && (csvData[end] == "\r")) {
|
|
124
|
+
return end;
|
|
125
|
+
}
|
|
126
|
+
end++;
|
|
127
|
+
}
|
|
128
|
+
return n;
|
|
129
|
+
}
|
|
130
|
+
static _parseCsvLine(csvLine) {
|
|
131
|
+
let result = [];
|
|
132
|
+
const n = csvLine.length;
|
|
133
|
+
let start = 0;
|
|
134
|
+
let end = 0;
|
|
135
|
+
let quote_open = false;
|
|
136
|
+
let has_quotes = false;
|
|
137
|
+
let has_escaped_quotes = false;
|
|
138
|
+
let found_field = false;
|
|
139
|
+
while (end < n) {
|
|
140
|
+
if (csvLine[end] == "\"") {
|
|
141
|
+
if (!quote_open) {
|
|
142
|
+
quote_open = true;
|
|
143
|
+
}
|
|
144
|
+
else if ((end < n - 1) && (csvLine[end + 1] == "\"")) {
|
|
145
|
+
end++;
|
|
146
|
+
has_escaped_quotes = true;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
has_quotes = true;
|
|
150
|
+
quote_open = false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if ((!quote_open) && ((end == n - 1) || (csvLine[end] == ","))) {
|
|
154
|
+
found_field = true;
|
|
155
|
+
if (end == n - 1) {
|
|
156
|
+
end++;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (found_field) {
|
|
160
|
+
// console.log("OINODB_csvParseLine: next field=" + csvLine.substring(start,end) + ", start="+start+", end="+end)
|
|
161
|
+
let field_str;
|
|
162
|
+
if (has_quotes) {
|
|
163
|
+
field_str = csvLine.substring(start + 1, end - 1);
|
|
164
|
+
}
|
|
165
|
+
else if (start == end) {
|
|
166
|
+
field_str = undefined;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
field_str = csvLine.substring(start, end);
|
|
170
|
+
if (field_str == "null") {
|
|
171
|
+
field_str = null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
result.push(field_str);
|
|
175
|
+
has_quotes = false;
|
|
176
|
+
has_escaped_quotes = true;
|
|
177
|
+
found_field = false;
|
|
178
|
+
start = end + 1;
|
|
179
|
+
}
|
|
180
|
+
end++;
|
|
181
|
+
}
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
static _createRowFromCsv(datamodel, data) {
|
|
185
|
+
let result = [];
|
|
186
|
+
const n = data.length;
|
|
187
|
+
let start = 0;
|
|
188
|
+
let end = this._findCsvLineEnd(data, start);
|
|
189
|
+
const header_str = data.substring(start, end);
|
|
190
|
+
const headers = this._parseCsvLine(header_str);
|
|
191
|
+
let field_to_header_mapping = new Array(datamodel.fields.length);
|
|
192
|
+
let headers_found = false;
|
|
193
|
+
for (let i = 0; i < field_to_header_mapping.length; i++) {
|
|
194
|
+
field_to_header_mapping[i] = headers.indexOf(datamodel.fields[i].name);
|
|
195
|
+
headers_found = headers_found || (field_to_header_mapping[i] >= 0);
|
|
196
|
+
}
|
|
197
|
+
if (!headers_found) {
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
start = end + 1;
|
|
201
|
+
end = start;
|
|
202
|
+
while (end < n) {
|
|
203
|
+
while ((start < n) && ((data[start] == "\r") || (data[start] == "\n"))) {
|
|
204
|
+
start++;
|
|
205
|
+
}
|
|
206
|
+
if (start >= n) {
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
end = this._findCsvLineEnd(data, start);
|
|
210
|
+
const row_data = this._parseCsvLine(data.substring(start, end));
|
|
211
|
+
const row = new Array(field_to_header_mapping.length);
|
|
212
|
+
let has_data = false;
|
|
213
|
+
for (let i = 0; i < datamodel.fields.length; i++) {
|
|
214
|
+
const field = datamodel.fields[i];
|
|
215
|
+
let j = field_to_header_mapping[i];
|
|
216
|
+
let value = row_data[j];
|
|
217
|
+
if ((value === undefined) || (value === null)) { // null/undefined-decoding built into the parser
|
|
218
|
+
row[i] = value;
|
|
219
|
+
}
|
|
220
|
+
else if ((j >= 0) && (j < row_data.length)) {
|
|
221
|
+
value = OINOStr_js_1.OINOStr.decode(value, OINOConstants_js_1.OINOContentType.csv);
|
|
222
|
+
if (value && (field.fieldParams.isPrimaryKey || field.fieldParams.isForeignKey) && (field instanceof OINODataField_js_1.OINONumberDataField) && (datamodel.api.hashid)) {
|
|
223
|
+
value = datamodel.api.hashid.decode(value);
|
|
224
|
+
}
|
|
225
|
+
row[i] = field.deserializeCell(value);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
row[i] = undefined;
|
|
229
|
+
}
|
|
230
|
+
has_data = has_data || (row[i] !== undefined);
|
|
231
|
+
}
|
|
232
|
+
// console.log("createRowFromCsv: next row=" + row)
|
|
233
|
+
if (has_data) {
|
|
234
|
+
result.push(row);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
OINOLog_js_1.OINOLog.warning("@oino-ts/db", "OINOParser", "_createRowFromCsv", "Empty row skipped", {});
|
|
238
|
+
}
|
|
239
|
+
start = end;
|
|
240
|
+
end = start;
|
|
241
|
+
}
|
|
242
|
+
return result;
|
|
243
|
+
}
|
|
244
|
+
static _createRowFromJsonObj(obj, datamodel) {
|
|
245
|
+
// console.log("createRowFromJsonObj: obj=" + JSON.stringify(obj))
|
|
246
|
+
const fields = datamodel.fields;
|
|
247
|
+
let result = new Array(fields.length);
|
|
248
|
+
let has_data = false;
|
|
249
|
+
// console.log("createRowFromJsonObj: " + result)
|
|
250
|
+
for (let i = 0; i < fields.length; i++) {
|
|
251
|
+
const field = fields[i];
|
|
252
|
+
let value = obj[field.name];
|
|
253
|
+
// console.log("createRowFromJsonObj: key=" + field.name + ", val=" + val)
|
|
254
|
+
if ((value === null) || (value === undefined)) { // must be checed first as null is an object
|
|
255
|
+
result[i] = value;
|
|
256
|
+
}
|
|
257
|
+
else if (Array.isArray(value) || typeof value === "object") {
|
|
258
|
+
result[i] = JSON.stringify(value); // store as proper JSON string so JSON.parse can recover it
|
|
259
|
+
}
|
|
260
|
+
else if (typeof value === "string") {
|
|
261
|
+
value = OINOStr_js_1.OINOStr.decode(value, OINOConstants_js_1.OINOContentType.json);
|
|
262
|
+
if (value && (field.fieldParams.isPrimaryKey || field.fieldParams.isForeignKey) && (field instanceof OINODataField_js_1.OINONumberDataField) && (datamodel.api.hashid)) {
|
|
263
|
+
value = datamodel.api.hashid.decode(value);
|
|
264
|
+
}
|
|
265
|
+
result[i] = field.deserializeCell(value);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
result[i] = value; // value types are passed as-is
|
|
269
|
+
}
|
|
270
|
+
has_data = has_data || (result[i] !== undefined);
|
|
271
|
+
// console.log("createRowFromJsonObj: result["+i+"]=" + result[i])
|
|
272
|
+
}
|
|
273
|
+
// console.log("createRowFromJsonObj: " + result)
|
|
274
|
+
if (has_data) {
|
|
275
|
+
return result;
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
OINOLog_js_1.OINOLog.warning("@oino-ts/db", "OINOParser", "_createRowFromJsonObj", "Empty row skipped", {});
|
|
279
|
+
return undefined;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
static _createRowFromJson(datamodel, data) {
|
|
283
|
+
let result = [];
|
|
284
|
+
// console.log("OINORowFactoryJson: data=" + data)
|
|
285
|
+
const obj = JSON.parse(data);
|
|
286
|
+
if (Array.isArray(obj)) {
|
|
287
|
+
obj.forEach(row => {
|
|
288
|
+
const data_row = this._createRowFromJsonObj(row, datamodel);
|
|
289
|
+
if (data_row !== undefined) {
|
|
290
|
+
result.push(data_row);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
const data_row = this._createRowFromJsonObj(obj, datamodel);
|
|
296
|
+
if (data_row !== undefined) {
|
|
297
|
+
result.push(data_row);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return result;
|
|
301
|
+
}
|
|
302
|
+
static _findMultipartBoundary(formData, multipartBoundary, start) {
|
|
303
|
+
let n = formData.indexOf(multipartBoundary, start);
|
|
304
|
+
if (n >= 0) {
|
|
305
|
+
n += multipartBoundary.length + 2;
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
n = formData.length;
|
|
309
|
+
}
|
|
310
|
+
return n;
|
|
311
|
+
}
|
|
312
|
+
static _parseMultipartLine(data, start) {
|
|
313
|
+
let line_end = data.indexOf('\r\n', start);
|
|
314
|
+
if (line_end >= start) {
|
|
315
|
+
return data.subarray(start, line_end).toString();
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
return '';
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
static _multipartHeaderRegex = /Content-Disposition\: (form-data|file); name=\"([^\"]+)\"(; filename=.*)?/i;
|
|
322
|
+
static _createRowFromFormdata(datamodel, data, multipartBoundary) {
|
|
323
|
+
if (!multipartBoundary || (multipartBoundary.length == 0)) {
|
|
324
|
+
OINOLog_js_1.OINOLog.error("@oino-ts/db", "OINOParser", "_createRowFromFormdata", "Multipart boundary missing for formdata parsing!", {});
|
|
325
|
+
throw new Error(OINOConstants_js_1.OINO_ERROR_PREFIX + "Multipart boundary missing for formdata parsing!");
|
|
326
|
+
}
|
|
327
|
+
let result = [];
|
|
328
|
+
try {
|
|
329
|
+
const n = data.length;
|
|
330
|
+
let start = this._findMultipartBoundary(data, multipartBoundary, 0);
|
|
331
|
+
let end = this._findMultipartBoundary(data, multipartBoundary, start);
|
|
332
|
+
const row = new Array(datamodel.fields.length);
|
|
333
|
+
let has_data = false;
|
|
334
|
+
while (end < n) {
|
|
335
|
+
let block_ok = true;
|
|
336
|
+
let l = this._parseMultipartLine(data, start);
|
|
337
|
+
start += l.length + 2;
|
|
338
|
+
const header_matches = OINOParser._multipartHeaderRegex.exec(l);
|
|
339
|
+
if (!header_matches) {
|
|
340
|
+
OINOLog_js_1.OINOLog.warning("@oino-ts/db", "OINOParser", "_createRowFromFormdata", "Unsupported block skipped", { header_line: l });
|
|
341
|
+
block_ok = false;
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
const field_name = header_matches[2];
|
|
345
|
+
const is_file = header_matches[3] != null;
|
|
346
|
+
let is_base64 = false;
|
|
347
|
+
const field_index = datamodel.findFieldIndexByName(field_name);
|
|
348
|
+
if (field_index < 0) {
|
|
349
|
+
OINOLog_js_1.OINOLog.warning("@oino-ts/db", "OINOParser", "_createRowFromFormdata", "Form field not found and skipped!", { field_name: field_name });
|
|
350
|
+
block_ok = false;
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
const field = datamodel.fields[field_index];
|
|
354
|
+
l = this._parseMultipartLine(data, start);
|
|
355
|
+
while (block_ok && (l != '')) {
|
|
356
|
+
if (l.startsWith('Content-Type:') && (l.indexOf('multipart/mixed') >= 0)) {
|
|
357
|
+
OINOLog_js_1.OINOLog.warning("@oino-ts/db", "OINOParser", "_createRowFromFormdata", "Mixed multipart files not supported and skipped!", { header_line: l });
|
|
358
|
+
block_ok = false;
|
|
359
|
+
}
|
|
360
|
+
else if (l.startsWith('Content-Transfer-Encoding:') && (l.indexOf('BASE64') >= 0)) {
|
|
361
|
+
is_base64 = true;
|
|
362
|
+
}
|
|
363
|
+
start += l.length + 2;
|
|
364
|
+
l = this._parseMultipartLine(data, start);
|
|
365
|
+
}
|
|
366
|
+
start += 2;
|
|
367
|
+
if (!block_ok) {
|
|
368
|
+
OINOLog_js_1.OINOLog.warning("@oino-ts/db", "OINOParser", "_createRowFromFormdata", "Invalid block skipped", { field_name: field_name });
|
|
369
|
+
}
|
|
370
|
+
else if (start + multipartBoundary.length + 2 >= end) {
|
|
371
|
+
row[field_index] = null;
|
|
372
|
+
}
|
|
373
|
+
else if (is_file) {
|
|
374
|
+
if (is_base64) {
|
|
375
|
+
const value = this._parseMultipartLine(data, start).trim();
|
|
376
|
+
row[field_index] = field.deserializeCell(OINOStr_js_1.OINOStr.decode(value, OINOConstants_js_1.OINOContentType.formdata));
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
const e = this._findMultipartBoundary(data, multipartBoundary, start);
|
|
380
|
+
const value = data.subarray(start, e - 2);
|
|
381
|
+
row[field_index] = value;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
let value = OINOStr_js_1.OINOStr.decode(this._parseMultipartLine(data, start).trim(), OINOConstants_js_1.OINOContentType.formdata);
|
|
386
|
+
if (value && (field.fieldParams.isPrimaryKey || field.fieldParams.isForeignKey) && (field instanceof OINODataField_js_1.OINONumberDataField) && (datamodel.api.hashid)) {
|
|
387
|
+
value = datamodel.api.hashid.decode(value);
|
|
388
|
+
}
|
|
389
|
+
row[field_index] = field.deserializeCell(value);
|
|
390
|
+
}
|
|
391
|
+
has_data = has_data || (row[field_index] !== undefined);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
start = end;
|
|
395
|
+
end = this._findMultipartBoundary(data, multipartBoundary, start);
|
|
396
|
+
}
|
|
397
|
+
if (has_data) {
|
|
398
|
+
result.push(row);
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
OINOLog_js_1.OINOLog.warning("@oino-ts/db", "OINOParser", "_createRowFromFormdata", "Empty row skipped", {});
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
catch (e) {
|
|
405
|
+
OINOLog_js_1.OINOLog.exception("@oino-ts/db", "OINOParser", "_createRowFromFormdata", "Exception parsing formdata", { message: e.message, stack: e.stack });
|
|
406
|
+
}
|
|
407
|
+
return result;
|
|
408
|
+
}
|
|
409
|
+
static _createRowFromUrlencoded(datamodel, data) {
|
|
410
|
+
let result = [];
|
|
411
|
+
const row = new Array(datamodel.fields.length);
|
|
412
|
+
let has_data = false;
|
|
413
|
+
const data_parts = data.trim().split('&');
|
|
414
|
+
try {
|
|
415
|
+
for (let i = 0; i < data_parts.length; i++) {
|
|
416
|
+
const param_parts = data_parts[i].split('=');
|
|
417
|
+
if (param_parts.length == 2) {
|
|
418
|
+
const key = OINOStr_js_1.OINOStr.decodeUrlencode(param_parts[0]) || "";
|
|
419
|
+
const field_index = datamodel.findFieldIndexByName(key);
|
|
420
|
+
if (field_index < 0) {
|
|
421
|
+
OINOLog_js_1.OINOLog.info("@oino-ts/db", "OINOParser", "_createRowFromUrlencoded", "Param field not found", { field: key });
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
const field = datamodel.fields[field_index];
|
|
425
|
+
let value = OINOStr_js_1.OINOStr.decode(param_parts[1], OINOConstants_js_1.OINOContentType.urlencode);
|
|
426
|
+
if (value && (field.fieldParams.isPrimaryKey || field.fieldParams.isForeignKey) && (field instanceof OINODataField_js_1.OINONumberDataField) && (datamodel.api.hashid)) {
|
|
427
|
+
value = datamodel.api.hashid.decode(value);
|
|
428
|
+
}
|
|
429
|
+
row[field_index] = field.deserializeCell(value);
|
|
430
|
+
has_data = has_data || (row[field_index] !== undefined);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
// const value = requestParams[]
|
|
434
|
+
}
|
|
435
|
+
if (has_data) {
|
|
436
|
+
result.push(row);
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
OINOLog_js_1.OINOLog.warning("@oino-ts/db", "OINOParser", "_createRowFromUrlencoded", "Empty row skipped", {});
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
catch (e) {
|
|
443
|
+
OINOLog_js_1.OINOLog.exception("@oino-ts/db", "OINOParser", "_createRowFromUrlencoded", "Exception parsing urlencoded data", { message: e.message, stack: e.stack });
|
|
444
|
+
}
|
|
445
|
+
return result;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
exports.OINOParser = OINOParser;
|