backend-plus 2.0.0-rc.8 → 2.0.1

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.
@@ -161,5 +161,9 @@ a.disabled
161
161
  font-size 80%
162
162
  text-align right
163
163
  color #777
164
+ > .json-container
165
+ position sticky
166
+ top 5%
167
+ bottom 5%
164
168
 
165
169
 
@@ -0,0 +1,8 @@
1
+ [0924/161727.965:ERROR:registration_protocol_win.cc(103)] CreateFile: The system cannot find the file specified. (0x2)
2
+ [0924/161728.263:ERROR:registration_protocol_win.cc(103)] CreateFile: The system cannot find the file specified. (0x2)
3
+ [0927/134140.352:ERROR:registration_protocol_win.cc(103)] CreateFile: The system cannot find the file specified. (0x2)
4
+ [0927/134141.126:ERROR:registration_protocol_win.cc(103)] CreateFile: The system cannot find the file specified. (0x2)
5
+ [1002/192319.079:ERROR:registration_protocol_win.cc(103)] CreateFile: The system cannot find the file specified. (0x2)
6
+ [1002/192319.182:ERROR:registration_protocol_win.cc(103)] CreateFile: The system cannot find the file specified. (0x2)
7
+ [1002/195154.689:ERROR:registration_protocol_win.cc(103)] CreateFile: The system cannot find the file specified. (0x2)
8
+ [1002/195155.067:ERROR:registration_protocol_win.cc(103)] CreateFile: The system cannot find the file specified. (0x2)
@@ -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 = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), 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.");
@@ -291,9 +291,11 @@ myOwn.showPage = function showPage(pageDef){
291
291
  rightMenu.style.zIndex=300;
292
292
  totalLayout.appendChild(rightMenu);
293
293
  }
294
- rightMenu.onclick=function(){
295
- if(!my.offline.mode){
296
- my.rightMenu();
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
- var skin=((my.config||{}).config||{}).skin;
562
- if(my.offline.mode){
563
- imgLight.src=my.path.img+'airplane-on.png';
564
- }else{
565
- imgLight.src=my.path.img+'airplane-off.png';
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
 
@@ -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,'[cçÇ]')
190
- .replace(/[áÁàÀäÄãÃ]/gi,'[AáÁàÀäÄãÃ]')
191
- .replace(/[éÉèÈëË]/gi,'[EéÉèÈëË]')
192
- .replace(/[íÍìÌïÏ]/gi,'[IíÍìÌïÏ]')
193
- .replace(/[óÓòÒöÖõÕ]/gi,'[OóÓòÒöÖõÕ]')
194
- .replace(/[úÚùÙüÜ]/gi,'[UúÚùÙüÜ]')
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 == condition;},
216
- '~':function(valueToCheck,condition){return condition==null || regex4search(condition.toString()).test(valueToCheck);},
217
- '!~':function(valueToCheck,condition){return condition==null || !regex4search(condition.toString()).test(valueToCheck);},
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
@@ -1005,7 +1000,7 @@ myOwn.DataColumnGrid.prototype.thFilter = function thFilter(depot, iColumn){
1005
1000
  var grid = this.grid;
1006
1001
  var fieldDef = this.fieldDef;
1007
1002
  var fieldName=fieldDef.name;
1008
- depot.rowSymbols[fieldDef.name]=depot.rowSymbols[fieldDef.name]||'~';
1003
+ depot.rowSymbols[fieldDef.name]=depot.rowSymbols[fieldDef.name]||(fieldDef.typeName == 'text' ? '~' : '=');
1009
1004
  var filterImage=my.path.img+my.comparator.traductor[depot.rowSymbols[fieldDef.name]]+'.png';
1010
1005
  var th=html.td(this.cellAttributes({class:"autoFilter", "typed-controls-direct-input":true},{skipMandatory:true})).create();
1011
1006
  var symbolFilter=th;
@@ -1622,7 +1617,7 @@ myOwn.dialogDownload = function dialogDownload(grid){
1622
1617
  }else{
1623
1618
  separator='|';
1624
1619
  var trans={
1625
- '|':'\\|',
1620
+ '|':'\\x7C',
1626
1621
  '\\':'\\\\',
1627
1622
  '\r':'\\r',
1628
1623
  '\n':'\\n',
@@ -2253,7 +2248,8 @@ myOwn.TableGrid.prototype.createRowInsertElements = function createRowInsertElem
2253
2248
  }
2254
2249
  var depotForInsert = grid.createDepotFromRow({$allow:{delete:true, update:true}}, 'new');
2255
2250
  grid.connector.fixedFields.forEach(function(pair){
2256
- if(!pair.range && grid.def.field[pair.fieldName].inTable !== false){
2251
+ var fieldDef = grid.def.field[pair.fieldName];
2252
+ if(!pair.range && (fieldDef.inTable !== false || fieldDef.isPk && pair.value !=null)){
2257
2253
  depotForInsert.row[pair.fieldName] = pair.value;
2258
2254
  depotForInsert.rowPendingForUpdate[pair.fieldName] = pair.value;
2259
2255
  }
@@ -1,4 +1,3 @@
1
- /// <reference types="websql" />
2
1
  import { TableDefinition } from "backend-plus";
3
2
  export type Key = string[];
4
3
  type DetectFeatures = {
@@ -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 = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), 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.");
@@ -12,9 +12,7 @@ export type LangId = 'en'|'es'|'etc...';
12
12
 
13
13
  export type Server=net.Server;
14
14
 
15
- export interface CoreFunctionParameters{
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
- | ((context: ProcedureContext, parameters: CoreFunctionParameters, files?:UploadedFileInfo[]) => Promise<any>);
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)
@@ -163,7 +166,7 @@ export interface TableContext extends Context{
163
166
  superuser?:true
164
167
  forDump?:boolean
165
168
  }
166
- export type PgKnownTypes='decimal'|'text'|'boolean'|'integer'|'bigint'|'date'|'interval'|'timestamp'|'jsonb'|'double'|'bytea'|'jsona';
169
+ export type PgKnownTypes='decimal'|'text'|'boolean'|'integer'|'bigint'|'date'|'interval'|'timestamp'|'jsonb'|'double'|'bytea'|'jsona'|'time'|'tsrange'|'time_range';
167
170
  export type PgKnownDbValues='current_timestamp'|'current_user'|'session_user';
168
171
  export type SequenceDefinition = {
169
172
  name:string
@@ -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
- allowEmtpyText?:boolean /* if a text field accepts '' as a valid value */
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
@@ -250,7 +256,8 @@ export type ForeignKey = {
250
256
  }
251
257
  export type Constraint = {constraintType:string, consName?:string} & (
252
258
  {constraintType:'unique', fields:string[], where?:string} |
253
- {constraintType:'check', expr?:string}
259
+ {constraintType:'check', expr?:string} |
260
+ {constraintType:'exclude', using:'GIST', fields:(string|{fieldName:string, operator:'='|'&&'})[]}
254
261
  )
255
262
  export type OtherTableDefs = Record<string,Partial<TableDefinition & {prefilledField:Record<string,any>}>>
256
263
  export type TableDefinition = EditableDbDefinition & {
@@ -259,16 +266,17 @@ export type TableDefinition = EditableDbDefinition & {
259
266
  tableName?:string
260
267
  schema?:string
261
268
  title?:string
262
- fields:FieldDefinition[],
263
- primaryKey:string[],
264
- refrescable?: boolean;
269
+ fields:FieldDefinition[]
270
+ primaryKey:string[]
271
+ refrescable?: boolean
265
272
  sql?:{
273
+ primaryKey4Delete?:string[]
266
274
  isTable?:boolean
267
275
  from?:string
268
276
  where?:string
269
277
  postCreateSqls?:string
270
- skipEnance?: boolean,
271
- isReferable?: boolean,
278
+ skipEnance?: boolean
279
+ isReferable?: boolean
272
280
  logicalDeletes?:{
273
281
  fieldName:string
274
282
  valueToDelete:string
@@ -277,11 +285,12 @@ export type TableDefinition = EditableDbDefinition & {
277
285
  fieldName:string
278
286
  }
279
287
  tableName?:string
288
+ tableName4Delete?:string
280
289
  fields?:{
281
290
  [k:string]:{
282
291
  expr:string
283
292
  }
284
- },
293
+ }
285
294
  orderBy?:string[]
286
295
  viewBody?:string
287
296
  insertIfNotUpdate?:boolean
@@ -295,6 +304,7 @@ export type TableDefinition = EditableDbDefinition & {
295
304
  join?:string
296
305
  constraintsDeferred?:boolean
297
306
  otherTableDefs?:OtherTableDefs
307
+ setExpectedPkValues?:boolean
298
308
  }
299
309
  foreignKeys?:ForeignKey[]
300
310
  softForeignKeys?:ForeignKey[]
@@ -320,7 +330,7 @@ export type TableDefinition = EditableDbDefinition & {
320
330
  specialValidator?:string
321
331
  saveAfter?:boolean
322
332
  selfRefresh?:boolean
323
- filterColumns?:{column:string, operator:string, value:any}[],
333
+ filterColumns?:{column:string, operator:string, value:any}[]
324
334
  gridAlias?:string /* front-end css my-table = gridAlias */
325
335
  }
326
336
  export interface DetailTable { table?: string, fields: FieldsForConnectDetailTable, abr: string, label?: string, refreshParent?:boolean, refreshFromParent?:boolean, wScreen?:string, condition?:string }
@@ -365,6 +375,129 @@ export interface Caches {
365
375
  procedures:Record<string, {timestamp:number, result:any}>
366
376
  }
367
377
 
378
+ export interface AppConfigBin { // executables in SO
379
+ "zip-password-parameter-flag": string // parameter to pass the password to the zipper
380
+ "zip-password-prefix": string // password prefix
381
+ "zip-fixed-parameters":string // fixed parameters to pass to zipper
382
+ }
383
+
384
+ export interface AppConfig {
385
+ package: {
386
+ version: string
387
+ }
388
+ server: {
389
+ "base-url": string // rool path in the url
390
+ port: number // port of the API services
391
+ "session-store": string // strategies to store session info
392
+ "ip-replacer": string // ip that can be not showed or deduced in logs
393
+ "silent-startup": boolean // less logs when startup
394
+ "kill-9": string // a way to kill from URL with a token
395
+ bitacoraSchema: string
396
+ bitacoraTableName: string
397
+ }
398
+ db: {
399
+ motor: 'postgresql'
400
+ database: string
401
+ user: string
402
+ password: string
403
+ schema: string
404
+ search_path: string
405
+ tablespace: string // for creation scripts
406
+ "min-version": string // min version of the motor needed
407
+ nodb: boolean // if there is no database needed in the app
408
+ no_login: boolean // if no login is needed. Used only for all public sites
409
+ "downloadable-backup-path": string // OS path of the encrypted downloadable backup
410
+ }
411
+ login: {
412
+ schema: string // schema of the user table
413
+ table: string // user table
414
+ userFieldname: string // fieldname in user table that stores the user name
415
+ passFieldname: string // fieldname in user table that stores the password hash
416
+ rolFieldname: string // fieldname in user table that stores the rol
417
+ unloggedLandPage: string // land page when there is no user logged when the backend has public services
418
+ noLoggedUrlPath: string // path of non logged users when the backend has no public services
419
+ "preserve-case": boolean // preserve the case of the user name
420
+ activeClausule: string // SQL expression over the user table to check if a user is active
421
+ lockedClausule: string // SQL expression over the user table to check if a user is locked
422
+ disableChangePassword: boolean // disallow password change
423
+ skipBitacora: boolean // don't register logins
424
+ keepAlive: number // secs to keep alive a session if only keep alive request where received
425
+ plus: {
426
+ userFieldName:string
427
+ store:{
428
+ module: string
429
+ }
430
+ }
431
+ forget: { // forget password configurations:
432
+ urlPath: string // url sent by mail. default: `/new-pass`
433
+ urlPathOk: string // confirmation page
434
+ mailFields: string[] // fields for the forget pass mail
435
+
436
+ }
437
+ "double-dragon": boolean // app user must match db user
438
+ }
439
+ install: {
440
+ "table-data-dir": string // SO path to the .tab files in the db creation script
441
+ dump: { // configuration of --dump-db, the db creation script
442
+ "drop-his": boolean // include drop schema his in the db creation script
443
+ db: {
444
+ owner: string
445
+ extensions: string[] // extensions to be installed (gist, pg_trgm, pgcrypto)
446
+ enances: 'file' // if the enances must be dumped in a separate file
447
+ // from here info to set the owner and replace owner and user used in devel when script creation
448
+ "owner4special-scripts": string
449
+ "user4special-scripts": string
450
+ "apply-generic-user-replaces": string
451
+ }
452
+ "admin-can-create-tables": boolean // for apps that allows the user to create tables
453
+ "skip-content": boolean // don't create data from "table-data-dir"
454
+ folders: string //
455
+ scripts: {
456
+ prepare: string // SO path to the prepare scripts that will be run before the functions creations and inserts
457
+ "post-adapt": string // SO path to the post-adapt scripts that will be run after data inserts (of .tab tables)
458
+ }
459
+ }
460
+ }
461
+ "client-setup": { // front-end config
462
+ title:string // title of the app (common sufix of the title bar)
463
+ }
464
+ log: {
465
+ "serve-content": never
466
+ req: {
467
+ "keep-alive": boolean
468
+ }
469
+ db: {
470
+ "last-error": boolean // store last db error in a log file
471
+ devel: boolean //
472
+ "on-demand": string // if log db level can be changed on the fly
473
+ until: string | Date // full log until...
474
+ results: boolean // if query results must be included in full db logs
475
+ }
476
+ session: boolean // if all session activity must be logged
477
+ }
478
+ devel: {
479
+ delay: number // msec avg random delay in API responses (to emulate slow nets)
480
+ "cache-content": boolean // if the cache header must be sent to the client (when no devel config the default is true)
481
+ forceShowAsEditable: boolean // force "editable" behavior in grids
482
+ }
483
+ mailer: { // config to send mails
484
+ conn: string // connection string
485
+ "mail-info": {} // static mail config
486
+ supervise: {
487
+ to: string // email addres of the supervisor
488
+ event: {
489
+ }
490
+ }
491
+ }
492
+ bin: AppConfigBin
493
+ data: {
494
+ transformers: {
495
+ text: string // define the inputTransformers for text comming from the fron-end via the API
496
+ }
497
+ }
498
+ skipUnknownFieldsAtImport: boolean // if unknown fields must be skipped by default in import
499
+ }
500
+
368
501
  export class AppBackend{
369
502
  procedures:ProcedureDef[]
370
503
  procedure:{ [key:string]:ProcedureDef }
@@ -372,7 +505,7 @@ export class AppBackend{
372
505
  getTableDefinition: TableDefinitionsGetters
373
506
  tableStructures: TableDefinitions
374
507
  db: MotorDb
375
- config: any
508
+ config: AppConfig
376
509
  rootPath: string
377
510
  caches:Caches
378
511
  fieldDomain:{[k:string]:Partial<FieldDefinition>}
@@ -398,10 +531,10 @@ export class AppBackend{
398
531
  isAdmin():boolean
399
532
  canChangePass():Promise<boolean>
400
533
  getMenu(context?:Context):MenuDefinition
401
- inDbClient<T>(req:Request|null, doThisWithDbClient:(client:Client)=>Promise<T>):Promise<T>
402
- inTransaction<T>(req:Request|null, doThisWithDbTransaction:(client:Client)=>Promise<T>):Promise<T>
534
+ inDbClient<T>(req:RequestDb|null, doThisWithDbClient:(client:Client)=>Promise<T>):Promise<T>
535
+ inTransaction<T>(req:RequestDb|null, doThisWithDbTransaction:(client:Client)=>Promise<T>):Promise<T>
403
536
  inTransactionProcedureContext<T>(req:Request|null, coreFunction:(context:ProcedureContext)=>Promise<T>):Promise<T>
404
- procedureDefCompleter(procedureDef:ProcedureDef):ProcedureDef
537
+ procedureDefCompleter<T>(procedureDef:ProcedureDef):ProcedureDef<T>
405
538
  tableDefAdapt(tableDef:TableDefinition, context:Context):TableDefinition
406
539
  pushApp(dirname:string):void
407
540
  dumpDbTableFields(tableDefinition:TableDefinition):string[]
@@ -420,7 +553,8 @@ export class AppBackend{
420
553
  i18n:{
421
554
  messages:Record<LangId,Record<string, string>>
422
555
  }
423
- shootDownBackend():Promise<void>
556
+ shutdownCallbackListAdd(param:{message:string, fun:()=>Promise<void>}):void
557
+ shutdownBackend():Promise<void>
424
558
  setLog(opts:{until:string, results?:boolean}):void
425
559
  getDataDumpTransformations(rawData:string):Promise<{rawData:string, prepareTransformationSql:string[], endTransformationSql:string[]}>
426
560
  }