backend-plus 2.0.0-rc.3 → 2.0.0-rc.31
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/for-client/css/my-menu.styl +4 -0
- package/for-client/my-localdb.js +2 -2
- package/for-client/my-menu.js +15 -11
- package/for-client/my-tables.js +23 -19
- package/for-client/my-websqldb.d.ts +0 -1
- package/for-client/my-websqldb.js +2 -2
- package/install/get_app_user-fun.sql +6 -0
- package/lib/backend-plus.d.ts +162 -29
- package/lib/backend-plus.js +231 -90
- package/lib/procedures-table.js +51 -19
- package/package.json +37 -36
- package/unlogged/my-ajax.js +52 -33
package/README.md
CHANGED
|
@@ -6,11 +6,11 @@ Backend for the anti Pareto rule.
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|

|
|
9
|
-
[](https://npmjs.org/package/backend-plus)
|
|
10
|
+
[](https://npmjs.org/package/backend-plus)
|
|
11
|
+
[](https://travis-ci.org/codenautas/backend-plus)
|
|
12
|
+
[](https://coveralls.io/r/codenautas/backend-plus)
|
|
13
|
+
[](https://david-dm.org/codenautas/backend-plus)
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
language: 
|
|
@@ -205,7 +205,7 @@ entry | usage
|
|
|
205
205
|
-----------------------------|---------------
|
|
206
206
|
server |
|
|
207
207
|
.port | port where is listening
|
|
208
|
-
.base-
|
|
208
|
+
.base-url | base url added to domain name
|
|
209
209
|
.module-store |
|
|
210
210
|
install | (see Spanish)
|
|
211
211
|
.dump | (see Spanish)
|
package/for-client/my-localdb.js
CHANGED
|
@@ -8,8 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
12
|
-
return g =
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
12
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
13
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
14
|
function step(op) {
|
|
15
15
|
if (f) throw new TypeError("Generator is already executing.");
|
package/for-client/my-menu.js
CHANGED
|
@@ -152,7 +152,7 @@ myOwn.wScreens.procAux = {
|
|
|
152
152
|
button.disabled=false;
|
|
153
153
|
divProgressOutside.style.opacity=0.33;
|
|
154
154
|
toggleProgress.disabled=false;
|
|
155
|
-
labelProgress.textContent=resultOk?my.messages.completed:'error';
|
|
155
|
+
labelProgress.textContent=typeof resultOk == "string" ? resultOk : resultOk !== false ? my.messages.completed : 'error';
|
|
156
156
|
}).catch(function(err){
|
|
157
157
|
my.log(err);
|
|
158
158
|
divProgress.textContent=err.message;
|
|
@@ -291,9 +291,11 @@ myOwn.showPage = function showPage(pageDef){
|
|
|
291
291
|
rightMenu.style.zIndex=300;
|
|
292
292
|
totalLayout.appendChild(rightMenu);
|
|
293
293
|
}
|
|
294
|
-
rightMenu
|
|
295
|
-
|
|
296
|
-
my.
|
|
294
|
+
if (rightMenu != null) {
|
|
295
|
+
rightMenu.onclick=function(){
|
|
296
|
+
if(!my.offline.mode){
|
|
297
|
+
my.rightMenu();
|
|
298
|
+
}
|
|
297
299
|
}
|
|
298
300
|
}
|
|
299
301
|
};
|
|
@@ -539,9 +541,9 @@ myOwn.informDetectedStatus = function informDetectedStatus(statusCode, logged) {
|
|
|
539
541
|
}
|
|
540
542
|
if(statusCode==='notLogged'){
|
|
541
543
|
var notLogged = document.getElementById('not-logged');
|
|
542
|
-
notLogged.style.display='inherit';
|
|
544
|
+
if (notLogged) notLogged.style.display='inherit';
|
|
543
545
|
var activeUser = document.getElementById('active-user');
|
|
544
|
-
activeUser.style.display='none';
|
|
546
|
+
if (activeUser) activeUser.style.display='none';
|
|
545
547
|
}
|
|
546
548
|
}
|
|
547
549
|
|
|
@@ -558,11 +560,13 @@ myOwn.offlineModeRefresh = function offlineModeRefresh(){
|
|
|
558
560
|
/** @type {HTMLImageElement} */
|
|
559
561
|
// @ts-ignore
|
|
560
562
|
var imgLight = document.getElementById('light-airplane');
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
563
|
+
if (imgLight != null) {
|
|
564
|
+
var skin=((my.config||{}).config||{}).skin;
|
|
565
|
+
if(my.offline.mode){
|
|
566
|
+
imgLight.src=my.path.img+'airplane-on.png';
|
|
567
|
+
}else{
|
|
568
|
+
imgLight.src=my.path.img+'airplane-off.png';
|
|
569
|
+
}
|
|
566
570
|
}
|
|
567
571
|
}
|
|
568
572
|
|
package/for-client/my-tables.js
CHANGED
|
@@ -183,20 +183,15 @@ myOwn.i18n.messages.es=changing(myOwn.i18n.messages.es, {
|
|
|
183
183
|
/** @param {string} text */
|
|
184
184
|
function regex4search(text){
|
|
185
185
|
return new RegExp(
|
|
186
|
-
text.trim().replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
186
|
+
text.toString().trim().replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
187
187
|
// .replace(/"/g,"\\b")
|
|
188
188
|
.replace(/[ñÑ]/g,'(?:gn|nn?i?|[ñÑ])')
|
|
189
|
-
.replace(/[cCçÇ]/g,'[
|
|
190
|
-
.replace(/[
|
|
191
|
-
.replace(/[
|
|
192
|
-
.replace(/[
|
|
193
|
-
.replace(/[
|
|
194
|
-
.replace(/[
|
|
195
|
-
.replace(/a/gi,'[AáÁàÀäÄãÃ]')
|
|
196
|
-
.replace(/e/gi,'[EéÉèÈëË]')
|
|
197
|
-
.replace(/i/gi,'[IíÍìÌïÏ]')
|
|
198
|
-
.replace(/o/gi,'[OóÓòÒöÖõÕ]')
|
|
199
|
-
.replace(/u/gi,'[UúÚùÙüÜ]')
|
|
189
|
+
.replace(/[cCçÇ]/g,'[cCçÇ]')
|
|
190
|
+
.replace(/[AáÁàÀäÄãÃ]/gi,'[AáÁàÀäÄãÃ]')
|
|
191
|
+
.replace(/[EéÉèÈëË]/gi,'[EéÉèÈëË]')
|
|
192
|
+
.replace(/[IíÍìÌïÏ]/gi,'[IíÍìÌïÏ]')
|
|
193
|
+
.replace(/[OóÓòÒöÖõÕ]/gi,'[OóÓòÒöÖõÕ]')
|
|
194
|
+
.replace(/[UúÚùÙüÜ]/gi,'[UúÚùÙüÜ]')
|
|
200
195
|
// .replace(/\s+/g,'.*\\s+.*') mas estricto, exige el espacio
|
|
201
196
|
.replace(/\s+/g,'.*')
|
|
202
197
|
, 'i');
|
|
@@ -212,9 +207,9 @@ myOwn.comparatorParameterNull={
|
|
|
212
207
|
'!=\u2205':true,
|
|
213
208
|
}
|
|
214
209
|
myOwn.comparator={
|
|
215
|
-
'=':function(valueToCheck,condition){return valueToCheck
|
|
216
|
-
'~':function(valueToCheck,condition){return condition==null ||
|
|
217
|
-
'!~':function(valueToCheck,condition){return condition==null ||
|
|
210
|
+
'=':function(valueToCheck,condition){return sameValue(valueToCheck,condition);},
|
|
211
|
+
'~': function(valueToCheck,condition){return condition==null || condition instanceof Date ? Math.abs(condition-valueToCheck) <= 1000*60*60*24 : regex4search(condition).test(valueToCheck);},
|
|
212
|
+
'!~':function(valueToCheck,condition){return condition==null || condition instanceof Date ? Math.abs(condition-valueToCheck) > 1000*60*60*24 :!regex4search(condition).test(valueToCheck);},
|
|
218
213
|
'/R/i':function(valueToCheck,condition){return condition==null || RegExp(condition,'i').test(valueToCheck);},
|
|
219
214
|
'\u2205':function(valueToCheck,condition){return valueToCheck == null;},//\u2205 = conjunto vacío
|
|
220
215
|
'!=\u2205':function(valueToCheck,condition){return valueToCheck != null;},//\u2205 = conjunto vacío
|
|
@@ -690,11 +685,18 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
|
|
|
690
685
|
if (myOwn.config.config['grid-row-retain-moved-or-deleted'] && !force) {
|
|
691
686
|
var depotsToRetain = grid.depots.filter(depot => depot.tick == tick);
|
|
692
687
|
for (depot of depotsToRetain) {
|
|
688
|
+
depot['$refreshed'] = false
|
|
693
689
|
if (depot.tr && depot.tr.getAttribute('not-here')) depot.tr.removeAttribute('not-here')
|
|
694
690
|
}
|
|
695
691
|
}
|
|
696
692
|
while (depot = depotsToDelete.pop()) {
|
|
697
693
|
depot.manager.displayAsDeleted(depot, force ? 'change-ff' : 'unknown');
|
|
694
|
+
if (myOwn.config.config['grid-row-retain-moved-or-deleted']) {
|
|
695
|
+
if(!depot['$refreshed']){
|
|
696
|
+
grid.retrieveRowAndRefresh(depot,{retrieveIgnoringWhere:true})
|
|
697
|
+
depot['$refreshed'] = true
|
|
698
|
+
}
|
|
699
|
+
}
|
|
698
700
|
}
|
|
699
701
|
}
|
|
700
702
|
})
|
|
@@ -998,7 +1000,7 @@ myOwn.DataColumnGrid.prototype.thFilter = function thFilter(depot, iColumn){
|
|
|
998
1000
|
var grid = this.grid;
|
|
999
1001
|
var fieldDef = this.fieldDef;
|
|
1000
1002
|
var fieldName=fieldDef.name;
|
|
1001
|
-
depot.rowSymbols[fieldDef.name]=depot.rowSymbols[fieldDef.name]||'~';
|
|
1003
|
+
depot.rowSymbols[fieldDef.name]=depot.rowSymbols[fieldDef.name]||(fieldDef.typeName == 'text' ? '~' : '=');
|
|
1002
1004
|
var filterImage=my.path.img+my.comparator.traductor[depot.rowSymbols[fieldDef.name]]+'.png';
|
|
1003
1005
|
var th=html.td(this.cellAttributes({class:"autoFilter", "typed-controls-direct-input":true},{skipMandatory:true})).create();
|
|
1004
1006
|
var symbolFilter=th;
|
|
@@ -1615,7 +1617,7 @@ myOwn.dialogDownload = function dialogDownload(grid){
|
|
|
1615
1617
|
}else{
|
|
1616
1618
|
separator='|';
|
|
1617
1619
|
var trans={
|
|
1618
|
-
'|':'
|
|
1620
|
+
'|':'\\x7C',
|
|
1619
1621
|
'\\':'\\\\',
|
|
1620
1622
|
'\r':'\\r',
|
|
1621
1623
|
'\n':'\\n',
|
|
@@ -2246,7 +2248,8 @@ myOwn.TableGrid.prototype.createRowInsertElements = function createRowInsertElem
|
|
|
2246
2248
|
}
|
|
2247
2249
|
var depotForInsert = grid.createDepotFromRow({$allow:{delete:true, update:true}}, 'new');
|
|
2248
2250
|
grid.connector.fixedFields.forEach(function(pair){
|
|
2249
|
-
|
|
2251
|
+
var fieldDef = grid.def.field[pair.fieldName];
|
|
2252
|
+
if(!pair.range && (fieldDef.inTable !== false || fieldDef.isPk && pair.value !=null)){
|
|
2250
2253
|
depotForInsert.row[pair.fieldName] = pair.value;
|
|
2251
2254
|
depotForInsert.rowPendingForUpdate[pair.fieldName] = pair.value;
|
|
2252
2255
|
}
|
|
@@ -2385,7 +2388,8 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
|
|
|
2385
2388
|
fixedFields:grid.def.primaryKey.map(function(fieldName, i){
|
|
2386
2389
|
return {fieldName:fieldName, value:depot.primaryKeyValues[i]};
|
|
2387
2390
|
}),
|
|
2388
|
-
pick:grid.def.pick
|
|
2391
|
+
pick:grid.def.pick,
|
|
2392
|
+
retrieveIgnoringWhere: opts?opts.retrieveIgnoringWhere:false
|
|
2389
2393
|
}).then(function(result){
|
|
2390
2394
|
grid.depotRefresh(depot,{updatedRow:result[0], sendedForUpdate:{}}, opts);
|
|
2391
2395
|
})
|
|
@@ -8,8 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
12
|
-
return g =
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
12
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
13
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
14
|
function step(op) {
|
|
15
15
|
if (f) throw new TypeError("Generator is already executing.");
|
package/lib/backend-plus.d.ts
CHANGED
|
@@ -12,9 +12,7 @@ export type LangId = 'en'|'es'|'etc...';
|
|
|
12
12
|
|
|
13
13
|
export type Server=net.Server;
|
|
14
14
|
|
|
15
|
-
export
|
|
16
|
-
[key:string]: any
|
|
17
|
-
}
|
|
15
|
+
export type CoreFunctionParameters<T extends Record<string, any>> = T;
|
|
18
16
|
|
|
19
17
|
export type MarkdownDoc = 'markdown documentation with `` can content newlines. The identation of the first line is deleted in all others'|'etc...';
|
|
20
18
|
|
|
@@ -34,14 +32,14 @@ export type UploadedFileInfo={
|
|
|
34
32
|
path: string
|
|
35
33
|
|
|
36
34
|
}
|
|
37
|
-
export type CoreFunction = ((context: ProcedureContext, parameters: CoreFunctionParameters) => Promise<any>)
|
|
38
|
-
|
|
35
|
+
export type CoreFunction<T> = ((context: ProcedureContext, parameters: CoreFunctionParameters<T>) => Promise<any>)
|
|
36
|
+
| ((context: ProcedureContext, parameters: CoreFunctionParameters<T>, files?:UploadedFileInfo[]) => Promise<any>);
|
|
39
37
|
|
|
40
|
-
export interface ProcedureDef {
|
|
38
|
+
export interface ProcedureDef<T = any> {
|
|
41
39
|
action: string
|
|
42
40
|
parameters: ProcedureParameter[]
|
|
43
41
|
method?: 'get'|'post'
|
|
44
|
-
coreFunction: CoreFunction
|
|
42
|
+
coreFunction: CoreFunction<T>
|
|
45
43
|
encoding?:'JSON4all'|'JSON'|'download'
|
|
46
44
|
multipart?:true
|
|
47
45
|
progress?:true
|
|
@@ -78,7 +76,7 @@ export interface ContextForDump extends Context {
|
|
|
78
76
|
forDump?:boolean
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
export type InformProgressFunction=(opts:Error|{data:any}|{start:any}|{message:string}|{message?:string, lengthComputable:boolean, loaded:number, total:number, force?:boolean})=>void
|
|
79
|
+
export type InformProgressFunction=(opts:Error|{data:any}|{start:any}|{message:string}|{idGroup?:string, message?:string, lengthComputable:boolean, loaded:number, total:number, force?:boolean})=>void
|
|
82
80
|
|
|
83
81
|
export interface ProcedureContext extends Context{
|
|
84
82
|
client:Client
|
|
@@ -93,6 +91,11 @@ export interface Request extends express.Request {
|
|
|
93
91
|
user?:User
|
|
94
92
|
session:express.Request["session"]
|
|
95
93
|
}
|
|
94
|
+
export interface RequestDb {
|
|
95
|
+
user?:User
|
|
96
|
+
machineId?:string
|
|
97
|
+
userAgent?:{shortDescription?:string}
|
|
98
|
+
}
|
|
96
99
|
export {Response, Express} from "express";
|
|
97
100
|
export interface ResponsePlus extends express.Response{}
|
|
98
101
|
export interface ExpressPlus extends express.Express{}
|
|
@@ -136,7 +139,7 @@ export type MenuInfoPath={
|
|
|
136
139
|
path:string
|
|
137
140
|
} & MenuInfoMinimo;
|
|
138
141
|
export interface ClientModuleDefinition{
|
|
139
|
-
type:'js'|'css'|'ttf'
|
|
142
|
+
type:'js'|'css'|'ttf'|'mjs'
|
|
140
143
|
module?:string // module where to search in node_modules (node_modules/module/modPath/file) to serve
|
|
141
144
|
modPath?:string // path inside module where to find file to serve
|
|
142
145
|
src?:string // full path where browser search file (path/file)
|
|
@@ -171,6 +174,7 @@ export type SequenceDefinition = {
|
|
|
171
174
|
prefix?:string /* Prefix for the generated value */
|
|
172
175
|
}
|
|
173
176
|
export type ExportMetadataDefinition={ /* TODO: define */ }
|
|
177
|
+
export type PostInputOptions='upperSpanish' | 'upperWithoutDiacritics' | 'parseDecimal'
|
|
174
178
|
export type FieldDefinition = EditableDbDefinition & {
|
|
175
179
|
name:string
|
|
176
180
|
typeName:PgKnownTypes|'ARRAY:text'
|
|
@@ -186,7 +190,7 @@ export type FieldDefinition = EditableDbDefinition & {
|
|
|
186
190
|
serverSide?:boolean /* default:!clientSide if the value is retrived from the database */
|
|
187
191
|
inTable?:boolean /* default:!clientSide && !sql.fields[...].expr. Is a real fisical field in the table */
|
|
188
192
|
/* sizeByte?:number deprecated size in bytes for numbers */
|
|
189
|
-
|
|
193
|
+
allowEmptyText?:boolean /* if a text field accepts '' as a valid value */
|
|
190
194
|
mobileInputType?:string
|
|
191
195
|
extraRow?:number
|
|
192
196
|
inexactNumber?:number /* default:depends on typeName if = means abs(x-v)<espilon
|
|
@@ -212,6 +216,8 @@ export type FieldDefinition = EditableDbDefinition & {
|
|
|
212
216
|
inherited?:boolean
|
|
213
217
|
nameForUpsert?:string
|
|
214
218
|
alwaysShow?:boolean /* show when appears in fixed fields */
|
|
219
|
+
suggestingKeys?:string[]
|
|
220
|
+
postInput?:PostInputOptions
|
|
215
221
|
} & ({} | {
|
|
216
222
|
sequence:SequenceDefinition
|
|
217
223
|
nullable:true
|
|
@@ -252,22 +258,24 @@ export type Constraint = {constraintType:string, consName?:string} & (
|
|
|
252
258
|
{constraintType:'unique', fields:string[], where?:string} |
|
|
253
259
|
{constraintType:'check', expr?:string}
|
|
254
260
|
)
|
|
261
|
+
export type OtherTableDefs = Record<string,Partial<TableDefinition & {prefilledField:Record<string,any>}>>
|
|
255
262
|
export type TableDefinition = EditableDbDefinition & {
|
|
256
263
|
name:string
|
|
257
264
|
elementName?:string
|
|
258
265
|
tableName?:string
|
|
259
266
|
schema?:string
|
|
260
267
|
title?:string
|
|
261
|
-
fields:FieldDefinition[]
|
|
262
|
-
primaryKey:string[]
|
|
263
|
-
refrescable?: boolean
|
|
268
|
+
fields:FieldDefinition[]
|
|
269
|
+
primaryKey:string[]
|
|
270
|
+
refrescable?: boolean
|
|
264
271
|
sql?:{
|
|
272
|
+
primaryKey4Delete?:string[]
|
|
265
273
|
isTable?:boolean
|
|
266
274
|
from?:string
|
|
267
275
|
where?:string
|
|
268
276
|
postCreateSqls?:string
|
|
269
|
-
skipEnance?: boolean
|
|
270
|
-
isReferable?: boolean
|
|
277
|
+
skipEnance?: boolean
|
|
278
|
+
isReferable?: boolean
|
|
271
279
|
logicalDeletes?:{
|
|
272
280
|
fieldName:string
|
|
273
281
|
valueToDelete:string
|
|
@@ -276,24 +284,26 @@ export type TableDefinition = EditableDbDefinition & {
|
|
|
276
284
|
fieldName:string
|
|
277
285
|
}
|
|
278
286
|
tableName?:string
|
|
287
|
+
tableName4Delete?:string
|
|
279
288
|
fields?:{
|
|
280
289
|
[k:string]:{
|
|
281
290
|
expr:string
|
|
282
291
|
}
|
|
283
|
-
}
|
|
292
|
+
}
|
|
284
293
|
orderBy?:string[]
|
|
285
294
|
viewBody?:string
|
|
286
295
|
insertIfNotUpdate?:boolean
|
|
287
296
|
policies?:{
|
|
288
|
-
all ?:{using?:string, check?:string}
|
|
289
|
-
select?:{using?:string}
|
|
290
|
-
insert?:{
|
|
291
|
-
update?:{using?:string, check?:string}
|
|
292
|
-
delete?:{using?:string}
|
|
297
|
+
all ?:{name?:string, using?:string, check?:string}
|
|
298
|
+
select?:{name?:string, using?:string}
|
|
299
|
+
insert?:{name?:string, check?:string}
|
|
300
|
+
update?:{name?:string, using?:string, check?:string}
|
|
301
|
+
delete?:{name?:string, using?:string}
|
|
293
302
|
}
|
|
294
303
|
join?:string
|
|
295
304
|
constraintsDeferred?:boolean
|
|
296
|
-
otherTableDefs?:
|
|
305
|
+
otherTableDefs?:OtherTableDefs
|
|
306
|
+
setExpectedPkValues?:boolean
|
|
297
307
|
}
|
|
298
308
|
foreignKeys?:ForeignKey[]
|
|
299
309
|
softForeignKeys?:ForeignKey[]
|
|
@@ -319,10 +329,9 @@ export type TableDefinition = EditableDbDefinition & {
|
|
|
319
329
|
specialValidator?:string
|
|
320
330
|
saveAfter?:boolean
|
|
321
331
|
selfRefresh?:boolean
|
|
322
|
-
filterColumns?:{column:string, operator:string, value:any}[]
|
|
332
|
+
filterColumns?:{column:string, operator:string, value:any}[]
|
|
323
333
|
gridAlias?:string /* front-end css my-table = gridAlias */
|
|
324
334
|
}
|
|
325
|
-
export type OtherTableDefs = TableDefinition['sql']['otherTableDefs']
|
|
326
335
|
export interface DetailTable { table?: string, fields: FieldsForConnectDetailTable, abr: string, label?: string, refreshParent?:boolean, refreshFromParent?:boolean, wScreen?:string, condition?:string }
|
|
327
336
|
export type TableDefinitionFunction = (context: ContextForDump, opts?:any) => TableDefinition;
|
|
328
337
|
export type TableItemDef=string|{name:string, path?:string, tableGenerator?:(context:TableContext)=>TableDefinition}
|
|
@@ -365,6 +374,129 @@ export interface Caches {
|
|
|
365
374
|
procedures:Record<string, {timestamp:number, result:any}>
|
|
366
375
|
}
|
|
367
376
|
|
|
377
|
+
export interface AppConfigBin { // executables in SO
|
|
378
|
+
"zip-password-parameter-flag": string // parameter to pass the password to the zipper
|
|
379
|
+
"zip-password-prefix": string // password prefix
|
|
380
|
+
"zip-fixed-parameters":string // fixed parameters to pass to zipper
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export interface AppConfig {
|
|
384
|
+
package: {
|
|
385
|
+
version: string
|
|
386
|
+
}
|
|
387
|
+
server: {
|
|
388
|
+
"base-url": string // rool path in the url
|
|
389
|
+
port: number // port of the API services
|
|
390
|
+
"session-store": string // strategies to store session info
|
|
391
|
+
"ip-replacer": string // ip that can be not showed or deduced in logs
|
|
392
|
+
"silent-startup": boolean // less logs when startup
|
|
393
|
+
"kill-9": string // a way to kill from URL with a token
|
|
394
|
+
bitacoraSchema: string
|
|
395
|
+
bitacoraTableName: string
|
|
396
|
+
}
|
|
397
|
+
db: {
|
|
398
|
+
motor: 'postgresql'
|
|
399
|
+
database: string
|
|
400
|
+
user: string
|
|
401
|
+
password: string
|
|
402
|
+
schema: string
|
|
403
|
+
search_path: string
|
|
404
|
+
tablespace: string // for creation scripts
|
|
405
|
+
"min-version": string // min version of the motor needed
|
|
406
|
+
nodb: boolean // if there is no database needed in the app
|
|
407
|
+
no_login: boolean // if no login is needed. Used only for all public sites
|
|
408
|
+
"downloadable-backup-path": string // OS path of the encrypted downloadable backup
|
|
409
|
+
}
|
|
410
|
+
login: {
|
|
411
|
+
schema: string // schema of the user table
|
|
412
|
+
table: string // user table
|
|
413
|
+
userFieldname: string // fieldname in user table that stores the user name
|
|
414
|
+
passFieldname: string // fieldname in user table that stores the password hash
|
|
415
|
+
rolFieldname: string // fieldname in user table that stores the rol
|
|
416
|
+
unloggedLandPage: string // land page when there is no user logged when the backend has public services
|
|
417
|
+
noLoggedUrlPath: string // path of non logged users when the backend has no public services
|
|
418
|
+
"preserve-case": boolean // preserve the case of the user name
|
|
419
|
+
activeClausule: string // SQL expression over the user table to check if a user is active
|
|
420
|
+
lockedClausule: string // SQL expression over the user table to check if a user is locked
|
|
421
|
+
disableChangePassword: boolean // disallow password change
|
|
422
|
+
skipBitacora: boolean // don't register logins
|
|
423
|
+
keepAlive: number // secs to keep alive a session if only keep alive request where received
|
|
424
|
+
plus: {
|
|
425
|
+
userFieldName:string
|
|
426
|
+
store:{
|
|
427
|
+
module: string
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
forget: { // forget password configurations:
|
|
431
|
+
urlPath: string // url sent by mail. default: `/new-pass`
|
|
432
|
+
urlPathOk: string // confirmation page
|
|
433
|
+
mailFields: string[] // fields for the forget pass mail
|
|
434
|
+
|
|
435
|
+
}
|
|
436
|
+
"double-dragon": boolean // app user must match db user
|
|
437
|
+
}
|
|
438
|
+
install: {
|
|
439
|
+
"table-data-dir": string // SO path to the .tab files in the db creation script
|
|
440
|
+
dump: { // configuration of --dump-db, the db creation script
|
|
441
|
+
"drop-his": boolean // include drop schema his in the db creation script
|
|
442
|
+
db: {
|
|
443
|
+
owner: string
|
|
444
|
+
extensions: string[] // extensions to be installed (gist, pg_trgm, pgcrypto)
|
|
445
|
+
enances: 'file' // if the enances must be dumped in a separate file
|
|
446
|
+
// from here info to set the owner and replace owner and user used in devel when script creation
|
|
447
|
+
"owner4special-scripts": string
|
|
448
|
+
"user4special-scripts": string
|
|
449
|
+
"apply-generic-user-replaces": string
|
|
450
|
+
}
|
|
451
|
+
"admin-can-create-tables": boolean // for apps that allows the user to create tables
|
|
452
|
+
"skip-content": boolean // don't create data from "table-data-dir"
|
|
453
|
+
folders: string //
|
|
454
|
+
scripts: {
|
|
455
|
+
prepare: string // SO path to the prepare scripts that will be run before the functions creations and inserts
|
|
456
|
+
"post-adapt": string // SO path to the post-adapt scripts that will be run after data inserts (of .tab tables)
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
"client-setup": { // front-end config
|
|
461
|
+
title:string // title of the app (common sufix of the title bar)
|
|
462
|
+
}
|
|
463
|
+
log: {
|
|
464
|
+
"serve-content": never
|
|
465
|
+
req: {
|
|
466
|
+
"keep-alive": boolean
|
|
467
|
+
}
|
|
468
|
+
db: {
|
|
469
|
+
"last-error": boolean // store last db error in a log file
|
|
470
|
+
devel: boolean //
|
|
471
|
+
"on-demand": string // if log db level can be changed on the fly
|
|
472
|
+
until: string | Date // full log until...
|
|
473
|
+
results: boolean // if query results must be included in full db logs
|
|
474
|
+
}
|
|
475
|
+
session: boolean // if all session activity must be logged
|
|
476
|
+
}
|
|
477
|
+
devel: {
|
|
478
|
+
delay: number // msec avg random delay in API responses (to emulate slow nets)
|
|
479
|
+
"cache-content": boolean // if the cache header must be sent to the client (when no devel config the default is true)
|
|
480
|
+
forceShowAsEditable: boolean // force "editable" behavior in grids
|
|
481
|
+
}
|
|
482
|
+
mailer: { // config to send mails
|
|
483
|
+
conn: string // connection string
|
|
484
|
+
"mail-info": {} // static mail config
|
|
485
|
+
supervise: {
|
|
486
|
+
to: string // email addres of the supervisor
|
|
487
|
+
event: {
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
bin: AppConfigBin
|
|
492
|
+
data: {
|
|
493
|
+
transformers: {
|
|
494
|
+
text: string // define the inputTransformers for text comming from the fron-end via the API
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
skipUnknownFieldsAtImport: boolean // if unknown fields must be skipped by default in import
|
|
498
|
+
}
|
|
499
|
+
|
|
368
500
|
export class AppBackend{
|
|
369
501
|
procedures:ProcedureDef[]
|
|
370
502
|
procedure:{ [key:string]:ProcedureDef }
|
|
@@ -372,7 +504,7 @@ export class AppBackend{
|
|
|
372
504
|
getTableDefinition: TableDefinitionsGetters
|
|
373
505
|
tableStructures: TableDefinitions
|
|
374
506
|
db: MotorDb
|
|
375
|
-
config:
|
|
507
|
+
config: AppConfig
|
|
376
508
|
rootPath: string
|
|
377
509
|
caches:Caches
|
|
378
510
|
fieldDomain:{[k:string]:Partial<FieldDefinition>}
|
|
@@ -398,10 +530,10 @@ export class AppBackend{
|
|
|
398
530
|
isAdmin():boolean
|
|
399
531
|
canChangePass():Promise<boolean>
|
|
400
532
|
getMenu(context?:Context):MenuDefinition
|
|
401
|
-
inDbClient<T>(req:
|
|
402
|
-
inTransaction<T>(req:
|
|
533
|
+
inDbClient<T>(req:RequestDb|null, doThisWithDbClient:(client:Client)=>Promise<T>):Promise<T>
|
|
534
|
+
inTransaction<T>(req:RequestDb|null, doThisWithDbTransaction:(client:Client)=>Promise<T>):Promise<T>
|
|
403
535
|
inTransactionProcedureContext<T>(req:Request|null, coreFunction:(context:ProcedureContext)=>Promise<T>):Promise<T>
|
|
404
|
-
procedureDefCompleter(procedureDef:ProcedureDef):ProcedureDef
|
|
536
|
+
procedureDefCompleter<T>(procedureDef:ProcedureDef):ProcedureDef<T>
|
|
405
537
|
tableDefAdapt(tableDef:TableDefinition, context:Context):TableDefinition
|
|
406
538
|
pushApp(dirname:string):void
|
|
407
539
|
dumpDbTableFields(tableDefinition:TableDefinition):string[]
|
|
@@ -420,7 +552,8 @@ export class AppBackend{
|
|
|
420
552
|
i18n:{
|
|
421
553
|
messages:Record<LangId,Record<string, string>>
|
|
422
554
|
}
|
|
423
|
-
|
|
555
|
+
shutdownCallbackListAdd(param:{message:string, fun:()=>Promise<void>}):void
|
|
556
|
+
shutdownBackend():Promise<void>
|
|
424
557
|
setLog(opts:{until:string, results?:boolean}):void
|
|
425
558
|
getDataDumpTransformations(rawData:string):Promise<{rawData:string, prepareTransformationSql:string[], endTransformationSql:string[]}>
|
|
426
559
|
}
|