@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
package/package.json
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@oino-ts/common",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "OINO TS package for common classes.",
|
|
5
|
-
"author": "Matias Kiviniemi (pragmatta)",
|
|
6
|
-
"license": "MPL-2.0",
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "https://github.com/pragmatta/oino-ts.git"
|
|
10
|
-
},
|
|
11
|
-
"keywords": [
|
|
12
|
-
"types",
|
|
13
|
-
"typescript",
|
|
14
|
-
"library"
|
|
15
|
-
],
|
|
16
|
-
"main": "./dist/cjs/index.js",
|
|
17
|
-
"module": "./dist/esm/index.js",
|
|
18
|
-
"types": "./dist/types/index.d.ts",
|
|
19
|
-
"dependencies": {
|
|
20
|
-
},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"@oino-ts/types": "0.
|
|
23
|
-
"@types/node": "^22.0.0",
|
|
24
|
-
"typescript": "~5.9.0"
|
|
25
|
-
},
|
|
26
|
-
"files": [
|
|
27
|
-
"src/*.ts",
|
|
28
|
-
"dist/cjs/*.js",
|
|
29
|
-
"dist/esm/*.js",
|
|
30
|
-
"dist/types/*.d.ts"
|
|
31
|
-
]
|
|
32
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@oino-ts/common",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OINO TS package for common classes.",
|
|
5
|
+
"author": "Matias Kiviniemi (pragmatta)",
|
|
6
|
+
"license": "MPL-2.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/pragmatta/oino-ts.git"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"types",
|
|
13
|
+
"typescript",
|
|
14
|
+
"library"
|
|
15
|
+
],
|
|
16
|
+
"main": "./dist/cjs/index.js",
|
|
17
|
+
"module": "./dist/esm/index.js",
|
|
18
|
+
"types": "./dist/types/index.d.ts",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@oino-ts/types": "1.0.0",
|
|
23
|
+
"@types/node": "^22.0.0",
|
|
24
|
+
"typescript": "~5.9.0"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"src/*.ts",
|
|
28
|
+
"dist/cjs/*.js",
|
|
29
|
+
"dist/esm/*.js",
|
|
30
|
+
"dist/types/*.d.ts"
|
|
31
|
+
]
|
|
32
|
+
}
|
package/src/OINOApi.ts
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer"
|
|
2
|
+
import { OINOHashid } from "@oino-ts/hashid"
|
|
3
|
+
|
|
4
|
+
import { OINOContentType, OINODataRow } from "./OINOConstants.js"
|
|
5
|
+
import { OINODataSet, OINODataSource } from "./OINODataSource.js"
|
|
6
|
+
import { OINODataModel } from "./OINODataModel.js"
|
|
7
|
+
import { OINOModelSet } from "./OINOModelSet.js"
|
|
8
|
+
import { OINOQueryParams, OINOQueryFilter, OINOQueryOrder, OINOQueryAggregate, OINOQueryLimit, OINOQuerySelect, OINOQueryBooleanOperation } from "./OINOQueryParams.js"
|
|
9
|
+
import { OINOConfig } from "./OINOConfig.js"
|
|
10
|
+
import { OINOHttpRequest, OINOHttpRequestInit } from "./OINORequest.js"
|
|
11
|
+
import { OINOHttpResult, OINOResult } from "./OINOResult.js"
|
|
12
|
+
import { OINOHtmlTemplate } from "./OINOHtmlTemplate.js"
|
|
13
|
+
import { OINODataField, OINODatetimeDataField, OINONumberDataField } from "./OINODataField.js"
|
|
14
|
+
import { OINOBenchmark } from "./OINOBenchmark.js"
|
|
15
|
+
|
|
16
|
+
/** API parameters */
|
|
17
|
+
export type OINOApiParams = {
|
|
18
|
+
/** Name of the api */
|
|
19
|
+
apiName: string
|
|
20
|
+
/** Name of the database table */
|
|
21
|
+
tableName: string
|
|
22
|
+
/** Reject values that exceed field max length (behaviour on such is platform dependent) */
|
|
23
|
+
failOnOversizedValues?: boolean
|
|
24
|
+
/** Reject PUT-requests that contain values for autoinc-type fields */
|
|
25
|
+
failOnUpdateOnAutoinc?: boolean
|
|
26
|
+
/** Reject POST-requests without primary key value (can work if DB-side ) */
|
|
27
|
+
failOnInsertWithoutKey?: boolean
|
|
28
|
+
/** Reject POST-requests without primary key value (can work if DB-side ) */
|
|
29
|
+
failOnAnyInvalidRows?: boolean
|
|
30
|
+
/** Treat date type fields as just strings and use the native formatting instead of the ISO 8601 format */
|
|
31
|
+
useDatesAsString?: boolean
|
|
32
|
+
/** Include given fields from the API and exclude rest (if defined) */
|
|
33
|
+
includeFields?:string[],
|
|
34
|
+
/** Exclude all fields with this prefix from the API */
|
|
35
|
+
excludeFieldPrefix?:string
|
|
36
|
+
/** Exclude given fields from the API and include rest (if defined) */
|
|
37
|
+
excludeFields?:string[],
|
|
38
|
+
/** Enable hashids for numeric primarykeys by adding a 32 char key */
|
|
39
|
+
hashidKey?:string,
|
|
40
|
+
/** Set (minimum) length (12-32 chars) of the hashids */
|
|
41
|
+
hashidLength?:number,
|
|
42
|
+
/** Make hashids static per row/table */
|
|
43
|
+
hashidStaticIds?: boolean,
|
|
44
|
+
/** Name of field that has the modified field */
|
|
45
|
+
cacheModifiedField?:string,
|
|
46
|
+
/** Return inserted id values */
|
|
47
|
+
returnInsertedIds?: boolean
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type OINOApiData = string|OINODataRow[]|Buffer|Uint8Array|object|null
|
|
51
|
+
|
|
52
|
+
export interface OINOApiRequestInit extends OINOHttpRequestInit {
|
|
53
|
+
rowId?: string
|
|
54
|
+
rowData?: OINOApiData
|
|
55
|
+
queryParams?: OINOQueryParams
|
|
56
|
+
filter?: OINOQueryFilter|string
|
|
57
|
+
order?: OINOQueryOrder|string
|
|
58
|
+
limit?: OINOQueryLimit|string
|
|
59
|
+
aggregate?: OINOQueryAggregate|string
|
|
60
|
+
select?: OINOQuerySelect|string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export class OINOApiRequest extends OINOHttpRequest {
|
|
64
|
+
rowId:string
|
|
65
|
+
rowData:OINOApiData
|
|
66
|
+
queryParams:OINOQueryParams
|
|
67
|
+
|
|
68
|
+
constructor (init: OINOApiRequestInit) {
|
|
69
|
+
super(init)
|
|
70
|
+
this.rowId = init?.rowId || ""
|
|
71
|
+
this.rowData = init?.rowData || null // rowData is not compatible with OINOHttpRequest body so it's not automatically set, caller can set both if needed
|
|
72
|
+
this.queryParams = init?.queryParams || {}
|
|
73
|
+
|
|
74
|
+
if (init?.filter) {
|
|
75
|
+
if (init.filter instanceof OINOQueryFilter) {
|
|
76
|
+
this.queryParams.filter = init.filter
|
|
77
|
+
} else {
|
|
78
|
+
this.queryParams.filter = OINOQueryFilter.parse(init.filter)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (!this.queryParams.filter) {
|
|
82
|
+
const filter_params = this.url?.searchParams.getAll(OINOConfig.OINO_QUERY_FILTER_PARAM) || []
|
|
83
|
+
for (let i=0; i<filter_params.length; i++) {
|
|
84
|
+
const f = OINOQueryFilter.parse(filter_params[i])
|
|
85
|
+
if (i > 0) {
|
|
86
|
+
this.queryParams.filter = OINOQueryFilter.combine(this.queryParams.filter, OINOQueryBooleanOperation.and, f)
|
|
87
|
+
} else {
|
|
88
|
+
this.queryParams.filter = f
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (init?.order) {
|
|
93
|
+
if (init.order instanceof OINOQueryOrder) {
|
|
94
|
+
this.queryParams.order = init.order
|
|
95
|
+
} else {
|
|
96
|
+
this.queryParams.order = OINOQueryOrder.parse(init.order)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (!this.queryParams.order) {
|
|
100
|
+
const order_param = this.url?.searchParams.get(OINOConfig.OINO_QUERY_ORDER_PARAM)
|
|
101
|
+
if (order_param) {
|
|
102
|
+
this.queryParams.order = OINOQueryOrder.parse(order_param)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (init?.limit) {
|
|
106
|
+
if (init.limit instanceof OINOQueryLimit) {
|
|
107
|
+
this.queryParams.limit = init.limit
|
|
108
|
+
} else {
|
|
109
|
+
this.queryParams.limit = OINOQueryLimit.parse(init.limit)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (!this.queryParams.limit) {
|
|
113
|
+
const limit_param = this.url?.searchParams.get(OINOConfig.OINO_QUERY_LIMIT_PARAM)
|
|
114
|
+
if (limit_param) {
|
|
115
|
+
this.queryParams.limit = OINOQueryLimit.parse(limit_param)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (init?.aggregate) {
|
|
119
|
+
if (init.aggregate instanceof OINOQueryAggregate) {
|
|
120
|
+
this.queryParams.aggregate = init.aggregate
|
|
121
|
+
} else {
|
|
122
|
+
this.queryParams.aggregate = OINOQueryAggregate.parse(init.aggregate)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (!this.queryParams.aggregate) {
|
|
126
|
+
const aggregate_param = this.url?.searchParams.get(OINOConfig.OINO_QUERY_AGGREGATE_PARAM)
|
|
127
|
+
if (aggregate_param) {
|
|
128
|
+
this.queryParams.aggregate = OINOQueryAggregate.parse(aggregate_param)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (init?.select) {
|
|
132
|
+
if (init.select instanceof OINOQuerySelect) {
|
|
133
|
+
this.queryParams.select = init.select
|
|
134
|
+
} else {
|
|
135
|
+
this.queryParams.select = OINOQuerySelect.parse(init.select)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (!this.queryParams.select) {
|
|
139
|
+
const select_param = this.url?.searchParams.get(OINOConfig.OINO_QUERY_SELECT_PARAM)
|
|
140
|
+
if (select_param) {
|
|
141
|
+
this.queryParams.select = OINOQuerySelect.parse(select_param)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
static async fromFetchRequest(request: Request, rowId?: string, rowData?: OINOApiData, queryParams?: OINOQueryParams): Promise<OINOApiRequest> {
|
|
146
|
+
return new OINOApiRequest({
|
|
147
|
+
url: new URL(request.url),
|
|
148
|
+
method: request.method,
|
|
149
|
+
headers: Object.fromEntries(request.headers as any),
|
|
150
|
+
rowId: rowId,
|
|
151
|
+
rowData: rowData ?? Buffer.from(await request.arrayBuffer()),
|
|
152
|
+
queryParams: queryParams
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
static fromHttpRequest(request: OINOHttpRequest, rowId?: string, rowData?: OINOApiData, queryParams?: OINOQueryParams): OINOApiRequest {
|
|
157
|
+
return new OINOApiRequest({
|
|
158
|
+
url: typeof request.url === "string" ? new URL(request.url) : request.url,
|
|
159
|
+
method: request.method,
|
|
160
|
+
headers: Object.fromEntries(request.headers as any),
|
|
161
|
+
rowId: rowId,
|
|
162
|
+
rowData: rowData ?? request.bodyAsBuffer(),
|
|
163
|
+
requestType: request.requestType,
|
|
164
|
+
responseType: request.responseType,
|
|
165
|
+
multipartBoundary: request.multipartBoundary,
|
|
166
|
+
lastModified: request.lastModified,
|
|
167
|
+
queryParams: queryParams
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* OINO API request result object with returned data and/or http status code/message and
|
|
174
|
+
* error / warning messages.
|
|
175
|
+
*
|
|
176
|
+
*/
|
|
177
|
+
export class OINOApiResult extends OINOResult {
|
|
178
|
+
/** DbApi request params */
|
|
179
|
+
request: OINOApiRequest
|
|
180
|
+
|
|
181
|
+
/** Returned data if any */
|
|
182
|
+
data?: OINOModelSet;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Constructor of OINOApiResult.
|
|
186
|
+
*
|
|
187
|
+
* @param request DbApi request parameters
|
|
188
|
+
* @param data result data
|
|
189
|
+
*
|
|
190
|
+
*/
|
|
191
|
+
constructor (request:OINOApiRequest, data?:OINOModelSet) {
|
|
192
|
+
super()
|
|
193
|
+
this.request = request
|
|
194
|
+
this.data = data
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Creates a HTTP Response from API results.
|
|
199
|
+
*
|
|
200
|
+
* @param headers Headers to include in the response
|
|
201
|
+
*
|
|
202
|
+
*/
|
|
203
|
+
async writeApiResponse(headers:Record<string, string> = {}):Promise<Response> {
|
|
204
|
+
let response:Response|null = null
|
|
205
|
+
if (this.success && this.data) {
|
|
206
|
+
const body = await this.data.writeString(this.request.responseType)
|
|
207
|
+
response = new Response(body, {status:this.status, statusText: this.statusText, headers: headers })
|
|
208
|
+
} else {
|
|
209
|
+
response = new Response(JSON.stringify(this, null, 3), {status:this.status, statusText: this.statusText, headers: headers })
|
|
210
|
+
}
|
|
211
|
+
if (this.request.responseDownload) {
|
|
212
|
+
response.headers.set('Content-Disposition', 'attachment; filename="' + this.request.responseDownload + '"')
|
|
213
|
+
} else {
|
|
214
|
+
response.headers.set('Content-Disposition', 'inline')
|
|
215
|
+
}
|
|
216
|
+
for (let i=0; i<this.messages.length; i++) {
|
|
217
|
+
response.headers.set('X-OINO-MESSAGE-' + i, this.messages[i])
|
|
218
|
+
}
|
|
219
|
+
return Promise.resolve(response)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Specialized HTML template that can render ´OINOApiResult´.
|
|
225
|
+
*
|
|
226
|
+
*/
|
|
227
|
+
export class OINOApiHtmlTemplate extends OINOHtmlTemplate {
|
|
228
|
+
/** Locale validation regex */
|
|
229
|
+
static LOCALE_REGEX:RegExp = /^(\w\w)(\-\w\w)?$/
|
|
230
|
+
/** Locale formatter */
|
|
231
|
+
protected _locale:Intl.DateTimeFormat|null
|
|
232
|
+
protected _numberDecimals:number = -1
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Constructor of OINOApiHtmlTemplate.
|
|
236
|
+
*
|
|
237
|
+
* @param template HTML template string
|
|
238
|
+
* @param numberDecimals Number of decimals to use for numbers, -1 for no formatting
|
|
239
|
+
* @param dateLocaleStr Datetime format string, either "iso" for ISO8601 or "default" for system default or valid locale string
|
|
240
|
+
* @param dateLocaleStyle Datetime format style, either "short/medium/long/full" or Intl.DateTimeFormat options
|
|
241
|
+
*
|
|
242
|
+
*/
|
|
243
|
+
constructor (template:string, numberDecimals:number=-1, dateLocaleStr:string="", dateLocaleStyle:string|any="") {
|
|
244
|
+
super(template)
|
|
245
|
+
let locale_opts:any
|
|
246
|
+
if ((dateLocaleStyle == null) || (dateLocaleStyle == "")) {
|
|
247
|
+
locale_opts = { dateStyle: "medium", timeStyle: "medium" }
|
|
248
|
+
} else if (typeof dateLocaleStyle == "string") {
|
|
249
|
+
locale_opts = { dateStyle: dateLocaleStyle, timeStyle: dateLocaleStyle }
|
|
250
|
+
} else {
|
|
251
|
+
locale_opts = dateLocaleStyle
|
|
252
|
+
}
|
|
253
|
+
this._locale = null
|
|
254
|
+
this._numberDecimals = numberDecimals
|
|
255
|
+
|
|
256
|
+
if ((dateLocaleStr != null) && (dateLocaleStr != "") && OINOApiHtmlTemplate.LOCALE_REGEX.test(dateLocaleStr)) {
|
|
257
|
+
try {
|
|
258
|
+
this._locale = new Intl.DateTimeFormat(dateLocaleStr, locale_opts)
|
|
259
|
+
} catch (e:any) {}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Creates HTML Response from API modelset.
|
|
265
|
+
*
|
|
266
|
+
* @param modelset OINO API dataset
|
|
267
|
+
* @param overrideValues values to override in the data
|
|
268
|
+
*
|
|
269
|
+
*/
|
|
270
|
+
async renderFromDbData(modelset:OINOModelSet, overrideValues?:any):Promise<OINOHttpResult> {
|
|
271
|
+
OINOBenchmark.startMetric("OINOHtmlTemplate", "renderFromDbData")
|
|
272
|
+
let html:string = ""
|
|
273
|
+
const dataset:OINODataSet|undefined = modelset.dataset
|
|
274
|
+
const datamodel = modelset.datamodel
|
|
275
|
+
const api = modelset.datamodel.api
|
|
276
|
+
const modified_index = datamodel.findFieldIndexByName(api.params.cacheModifiedField || "")
|
|
277
|
+
let last_modified:number = this.modified
|
|
278
|
+
|
|
279
|
+
while (!dataset.isEof()) {
|
|
280
|
+
const row:OINODataRow = dataset.getRow()
|
|
281
|
+
if (modified_index >= 0) {
|
|
282
|
+
last_modified = Math.max(last_modified, new Date(row[modified_index] as Date).getTime())
|
|
283
|
+
}
|
|
284
|
+
let row_id_seed:string = datamodel.getRowPrimarykeyValues(row).join(' ')
|
|
285
|
+
let primary_key_values:string[] = []
|
|
286
|
+
this.clearVariables()
|
|
287
|
+
this.setVariableFromValue(OINOConfig.OINO_ID_FIELD, "")
|
|
288
|
+
for (let i=0; i<datamodel.fields.length; i++) {
|
|
289
|
+
const f:OINODataField = datamodel.fields[i]
|
|
290
|
+
let value:string|null|undefined
|
|
291
|
+
if ((f instanceof OINODatetimeDataField) && (this._locale != null)) {
|
|
292
|
+
value = f.serializeCellWithLocale(row[i], this._locale)
|
|
293
|
+
|
|
294
|
+
} else if ((f instanceof OINONumberDataField) && (this._numberDecimals >= 0) && (typeof row[i] === "number")) {
|
|
295
|
+
// console.debug("renderFromDbData number decimals", { field: f.name, value: row[i], type: typeof row[i] });
|
|
296
|
+
value = (row[i]! as number).toFixed(this._numberDecimals)
|
|
297
|
+
|
|
298
|
+
} else {
|
|
299
|
+
value = f.serializeCell(row[i])
|
|
300
|
+
}
|
|
301
|
+
if (f.fieldParams.isPrimaryKey || f.fieldParams.isForeignKey) {
|
|
302
|
+
if (value && (f instanceof OINONumberDataField) && (datamodel.api.hashid)) {
|
|
303
|
+
value = datamodel.api.hashid.encode(value, f.name + " " + row_id_seed)
|
|
304
|
+
}
|
|
305
|
+
if (f.fieldParams.isPrimaryKey) {
|
|
306
|
+
primary_key_values.push(value || "")
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
this.setVariableFromValue(f.name, value || "")
|
|
310
|
+
}
|
|
311
|
+
this.setVariableFromProperties(overrideValues)
|
|
312
|
+
this.setVariableFromValue(OINOConfig.OINO_ID_FIELD, OINOConfig.printOINOId(primary_key_values))
|
|
313
|
+
html += this._renderHtml() + "\r\n"
|
|
314
|
+
await dataset.next()
|
|
315
|
+
}
|
|
316
|
+
this.modified = last_modified
|
|
317
|
+
const result:OINOHttpResult = this._createHttpResult(html)
|
|
318
|
+
OINOBenchmark.endMetric("OINOHtmlTemplate", "renderFromDbData")
|
|
319
|
+
return result
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* API class with method to process HTTP REST requests.
|
|
327
|
+
*
|
|
328
|
+
*/
|
|
329
|
+
export abstract class OINOApi {
|
|
330
|
+
/** Enable debug output on errors */
|
|
331
|
+
protected _debugOnError:boolean = false
|
|
332
|
+
|
|
333
|
+
/** API database reference */
|
|
334
|
+
readonly datasource: OINODataSource
|
|
335
|
+
|
|
336
|
+
/** API parameters */
|
|
337
|
+
readonly params: OINOApiParams
|
|
338
|
+
|
|
339
|
+
/** API hashid */
|
|
340
|
+
readonly hashid:OINOHashid|null
|
|
341
|
+
|
|
342
|
+
/** Is API initialized */
|
|
343
|
+
initialized: boolean = false
|
|
344
|
+
|
|
345
|
+
/** API datamodel */
|
|
346
|
+
datamodel: OINODataModel|null = null
|
|
347
|
+
|
|
348
|
+
constructor(datasource: OINODataSource, params:OINOApiParams) {
|
|
349
|
+
this.datasource = datasource
|
|
350
|
+
this.params = params
|
|
351
|
+
|
|
352
|
+
if (this.params.hashidKey) {
|
|
353
|
+
this.hashid = new OINOHashid(this.params.hashidKey, this.params.apiName, this.params.hashidLength, this.params.hashidStaticIds)
|
|
354
|
+
} else {
|
|
355
|
+
this.hashid = null
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Method for handling a HTTP REST request with GET, POST, PUT, DELETE corresponding to
|
|
361
|
+
* SQL select, insert, update and delete.
|
|
362
|
+
*
|
|
363
|
+
* @param request OINO HTTP request object containing all parameters of the REST request
|
|
364
|
+
* @param rowId URL id of the REST request
|
|
365
|
+
* @param rowData HTTP body data as either serialized string or unserialized JS object or OINODataRow-array or Buffer/Uint8Array binary data
|
|
366
|
+
* @param queryParams SQL parameters for the REST request
|
|
367
|
+
*
|
|
368
|
+
*/
|
|
369
|
+
abstract doHttpRequest(request: OINOHttpRequest, rowId:string, rowData:OINOApiData, queryParams:OINOQueryParams):Promise<OINOApiResult>;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Method for handling a HTTP REST request with GET, POST, PUT, DELETE corresponding to
|
|
373
|
+
* SQL select, insert, update and delete.
|
|
374
|
+
*
|
|
375
|
+
* @param method HTTP method of the REST request
|
|
376
|
+
* @param rowId URL id of the REST request
|
|
377
|
+
* @param rowData HTTP body data as either serialized string or unserialized JS object or OINODataRow-array or Buffer/Uint8Array binary data
|
|
378
|
+
* @param queryParams SQL parameters for the REST request
|
|
379
|
+
* @param contentType content type of the HTTP body data, default is JSON
|
|
380
|
+
*
|
|
381
|
+
*/
|
|
382
|
+
abstract doRequest(method:string, rowId:string, rowData:OINOApiData, queryParams:OINOQueryParams, contentType:OINOContentType):Promise<OINOApiResult>;
|
|
383
|
+
|
|
384
|
+
abstract doApiRequest(request:OINOApiRequest):Promise<OINOApiResult>;
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Method for handling a HTTP REST request with batch update using PUT or DELETE methods.
|
|
388
|
+
*
|
|
389
|
+
* @param method HTTP method of the REST request
|
|
390
|
+
* @param rowId URL id of the REST request
|
|
391
|
+
* @param rowData HTTP body data as either serialized string or unserialized JS object or OINODataRow-array or Buffer/Uint8Array binary data
|
|
392
|
+
*
|
|
393
|
+
*/
|
|
394
|
+
abstract doBatchUpdate(method:string, rowId:string, rowData:OINOApiData, queryParams?: OINOQueryParams):Promise<OINOApiResult>;
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Method for handling a HTTP REST request with batch update using PUT or DELETE methods.
|
|
398
|
+
*
|
|
399
|
+
* @param request HTTP URL parameters as key-value-pairs
|
|
400
|
+
*
|
|
401
|
+
*/
|
|
402
|
+
abstract doBatchApiRequest(request:OINOApiRequest):Promise<OINOApiResult>;
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Enable or disable debug output on errors.
|
|
406
|
+
*
|
|
407
|
+
* @param debugOnError true to enable debug output on errors, false to disable
|
|
408
|
+
*/
|
|
409
|
+
setDebugOnError(debugOnError:boolean) {
|
|
410
|
+
this._debugOnError = debugOnError
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Method to check if a field is included in the API params.
|
|
415
|
+
*
|
|
416
|
+
* @param fieldName name of the field
|
|
417
|
+
*
|
|
418
|
+
*/
|
|
419
|
+
|
|
420
|
+
public isFieldIncluded(fieldName:string):boolean {
|
|
421
|
+
const params = this.params
|
|
422
|
+
return (
|
|
423
|
+
((params.excludeFieldPrefix == undefined) || (params.excludeFieldPrefix == "") || (fieldName.startsWith(params.excludeFieldPrefix) == false)) &&
|
|
424
|
+
((params.excludeFields == undefined) || (params.excludeFields.length == 0) || (params.excludeFields.indexOf(fieldName) < 0)) &&
|
|
425
|
+
((params.includeFields == undefined) || (params.includeFields.length == 0) || (params.includeFields.indexOf(fieldName) >= 0))
|
|
426
|
+
)
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
}
|