backend-plus 2.1.3 → 2.1.4

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.
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -436,6 +436,19 @@ myOwn.displayMenu = function displayMenu(layout, menu, addrParams, parents){
436
436
  {underElement:this}
437
437
  );
438
438
  }),
439
+ my.light('airplane', function(){
440
+ if(my.ldb && my.offline){
441
+ if(my.offline.mode && !my.server.connected){
442
+ promptPromise("Si desea salir del modo avión puede forzarlo").then(function(texto){
443
+ if (texto == 'forzar') {
444
+ my.changeOfflineMode();
445
+ }
446
+ });
447
+ }else{
448
+ my.changeOfflineMode();
449
+ }
450
+ }
451
+ }, {hidden:true})
439
452
  ]));
440
453
  elements.push(status);
441
454
  }
@@ -488,6 +501,9 @@ myOwn.displayMainMenu = function(addrParams){
488
501
  }
489
502
  }
490
503
  setTimeout(my.doMenuRealigns,10);
504
+ setTimeout(function(){
505
+ my.offlineModeRefresh();
506
+ },10);
491
507
  return menu;
492
508
  };
493
509
 
@@ -531,37 +547,101 @@ myOwn.informDetectedStatus = function informDetectedStatus(statusCode, logged) {
531
547
  }
532
548
  }
533
549
 
534
- var lastUrl = window.location.href;
535
- //TODO: desacoplar de BP
536
- window.addEventListener('popstate', function(){
537
- function checkReactUrl(url){
538
- const regex = /\/react(\/.*)?$/;
539
- return regex.test(url);
550
+ myOwn.setOnlineOfflineUrl = function setOnlineOfflineUrl(){
551
+ var actualHref=location.href;
552
+ var hrefSplit = actualHref.split(my.menuSeparator)
553
+ var newHref = my.offline.mode?'ext':my.menuName;
554
+ newHref = (hrefSplit.length > 1)?newHref+my.menuSeparator+hrefSplit[1]:newHref;
555
+ history.pushState(null, null, newHref);
556
+ }
557
+
558
+ myOwn.offlineModeRefresh = function offlineModeRefresh(){
559
+ var my=this;
560
+ /** @type {HTMLImageElement} */
561
+ // @ts-ignore
562
+ var imgLight = document.getElementById('light-airplane');
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
+ }
570
+ }
571
+ }
572
+
573
+ myOwn.changeOfflineMode = function changeOfflineMode(){
574
+ my.offline.mode=!my.offline.mode;
575
+ my.offlineModeRefresh();
576
+ my.setOnlineOfflineUrl();
577
+ if(my.offline.mode){
578
+ var fkToStoreData = [];
579
+ var promiseArray1 = [];
580
+ var promiseChain = my.ldb.getAllStructures().then(function(tablesDef){
581
+ tablesDef.forEach(function(tableDef){
582
+ promiseArray1.push(
583
+ my.ldb.isEmpty(tableDef.name).then(function(isEmpty){
584
+ if(!isEmpty){
585
+ var fkToStoreSearch = tableDef.foreignKeys.filter(function(fk){
586
+ return fk.fields.find(function(field){
587
+ return !tableDef.primaryKey.includes(field.source)
588
+ })
589
+ });
590
+ fkToStoreData = fkToStoreData.concat(fkToStoreSearch);
591
+ }
592
+ })
593
+ );
594
+ });
595
+ });
596
+ var promiseArray2 = [];
597
+ promiseChain = promiseChain.then(function(){
598
+ return Promise.all(promiseArray1).then(function(){
599
+ return fkToStoreData.forEach(function(fk){
600
+ var conn = new my.TableConnector({tableName: fk.references, my:my});
601
+ var opts = { registerInLocalDB: false };
602
+ conn.getStructure(opts)
603
+ promiseArray2.push(
604
+ Promise.resolve().then(function(){
605
+ return conn.getData().then(function(rows){
606
+ return my.ldb.putMany(fk.references, rows)
607
+ })
608
+ })
609
+ );
610
+ });
611
+ });
612
+ });
613
+ promiseChain = promiseChain.then(function(){
614
+ Promise.all(promiseArray2).then(function(){
615
+ location.reload();
616
+ })
617
+ });
618
+ }else{
619
+ my.showPage();
620
+ location.reload();
540
621
  }
541
- const currentUrl = window.location.href;
542
- if(checkReactUrl(currentUrl)){
543
- if(!checkReactUrl(lastUrl))
544
- location.reload();
622
+ }
623
+
624
+ window.addEventListener('popstate', function(){
625
+ if(!my.config){
626
+ my.autoSetup().then(function(){
627
+ my.setOnlineOfflineUrl();
628
+ my.showPage();
629
+ })
545
630
  }else{
546
- setTimeout(function(){
547
- if(!my.config){
548
- my.autoSetup().then(function(){
549
- my.showPage();
550
- })
551
- }else{
552
- my.showPage();
553
- }
554
- },10)
555
- }
556
- lastUrl = currentUrl;
631
+ my.showPage();
632
+ }
557
633
  });
558
634
 
559
635
  window.addEventListener('load', function(){
560
636
  window.my = myOwn;
561
637
  my.autoSetup().then(function(){
638
+ my.setOnlineOfflineUrl();
562
639
  my.showPage();
563
640
  })
564
641
  document.body.appendChild(html.div({id:'cached-images'},[
642
+ html.img({src:my.path.img+'airplane-on.png'}),
643
+ html.img({src:my.path.img+'airplane-off.png'}),
644
+ html.img({src:my.path.img+'airplane.png'}),
565
645
  html.img({src:my.path.img+'server.png'}),
566
646
  html.img({src:my.path.img+'network-signal.png'}),
567
647
  html.img({src:my.path.img+'server-error.png'}),
@@ -341,6 +341,7 @@ export interface TableDefinitions {
341
341
  [k: string]: TableDefinitionFunction
342
342
  }
343
343
  export interface ClientSetup {
344
+ config:AppConfigClientSetup
344
345
  setup:Record<string, any>
345
346
  procedures:ProcedureDef[]
346
347
  }
@@ -367,7 +368,6 @@ export interface OptsClientPage {
367
368
  extraFiles?:ClientModuleDefinition[]
368
369
  icon?:string
369
370
  icons?:Record<string,string>
370
- baseUrlForRelativePaths?:boolean
371
371
  }
372
372
 
373
373
  export type DumpOptions={complete?:boolean, skipEnance?:boolean, disableDBFunctions?:boolean}
@@ -382,11 +382,8 @@ export interface AppConfigBin { // executable
382
382
  "zip-fixed-parameters":string // fixed parameters to pass to zipper
383
383
  }
384
384
 
385
- export interface AppConfig {
386
- package: {
387
- version: string
388
- }
389
- server: {
385
+ export interface AppConfigServer
386
+ {
390
387
  "base-url": string // rool path in the url
391
388
  port: number // port of the API services
392
389
  "session-store": string // strategies to store session info
@@ -396,7 +393,8 @@ export interface AppConfig {
396
393
  bitacoraSchema: string
397
394
  bitacoraTableName: string
398
395
  }
399
- db: {
396
+ export interface AppConfigDb
397
+ {
400
398
  motor: 'postgresql'
401
399
  database: string
402
400
  user: string
@@ -409,7 +407,8 @@ export interface AppConfig {
409
407
  no_login: boolean // if no login is needed. Used only for all public sites
410
408
  "downloadable-backup-path": string // OS path of the encrypted downloadable backup
411
409
  }
412
- login: {
410
+ export interface AppConfigLogin
411
+ {
413
412
  schema: string // schema of the user table
414
413
  table: string // user table
415
414
  userFieldname: string // fieldname in user table that stores the user name
@@ -437,7 +436,8 @@ export interface AppConfig {
437
436
  }
438
437
  "double-dragon": boolean // app user must match db user
439
438
  }
440
- install: {
439
+ export interface AppConfigInstall
440
+ {
441
441
  "table-data-dir": string // SO path to the .tab files in the db creation script
442
442
  dump: { // configuration of --dump-db, the db creation script
443
443
  "drop-his": boolean // include drop schema his in the db creation script
@@ -459,9 +459,29 @@ export interface AppConfig {
459
459
  }
460
460
  }
461
461
  }
462
- "client-setup": { // front-end config
462
+ export interface AppConfigClientSetup // front-end config
463
+ {
463
464
  title:string // title of the app (common sufix of the title bar)
465
+ lang:string
466
+ version?:string
467
+ menu?:boolean
468
+ "background-img"?:string
469
+ devel?:boolean
470
+ deviceWidthForMobile?:string
471
+ "initial-scale"?:string
472
+ "minimum-scale"?:string
473
+ "maximum-scale"?:string
474
+ "user-scalable"?:string
475
+ }
476
+ export interface AppConfig {
477
+ package: {
478
+ version: string
464
479
  }
480
+ server: AppConfigServer
481
+ db: AppConfigDb
482
+ login: AppConfigLogin
483
+ install: AppConfigInstall
484
+ "client-setup": AppConfigClientSetup
465
485
  log: {
466
486
  "serve-content": never
467
487
  req: {
@@ -2240,13 +2240,11 @@ AppBackend.prototype.mainPage = function mainPage(req, offlineMode, opts){
2240
2240
  if(offlineMode){
2241
2241
  cssList.push('css/offline-mode.css');
2242
2242
  }
2243
- cssList = cssList.concat((opts.extraFiles ?? []).filter((extraFile)=>extraFile.type == 'css').map((extraFile)=>extraFile.file));
2244
2243
  return html.html(attr,[
2245
2244
  html.head([
2246
2245
  html.title(be.config["client-setup"]?.title),
2247
2246
  html.meta({charset:"utf-8"}),
2248
2247
  viewportAttrs?html.meta(viewportAttrs):null,
2249
- opts.baseUrlForRelativePaths?html.base({href:`${be.config.server["base-url"]}/`}):null,
2250
2248
  html.link({href: opts.icons.iconShortcut , rel: "shortcut icon", type: "image/png"}),
2251
2249
  html.link({href: opts.icons.icon , rel: "icon", type: "image/png"}),
2252
2250
  html.link({href: opts.icons.iconApple , rel: "apple-touch-icon"}),
@@ -2270,9 +2268,7 @@ AppBackend.prototype.mainPage = function mainPage(req, offlineMode, opts){
2270
2268
  html.div(be.messages.unlogged.loading),
2271
2269
  req.useragent.os=='iOS'&&req.useragent.version.split('.')[0]<9?html.div(`La versión del dispositivo ${req.useragent.version} no es compatible`):null
2272
2270
  ]),
2273
- html.div({id: "total-scripts"}, be.clientModules(req,opts).scripts.concat(
2274
- (opts?.extraFiles ?? []).filter((extraFile)=>be.esJavascript(extraFile.type)).map((extraFile)=>({...extraFile,type:null}))
2275
- ).map(function(scriptDef){
2271
+ html.div({id: "total-scripts"}, be.clientModules(req,opts).scripts.map(function(scriptDef){
2276
2272
  return html.script(scriptDef);
2277
2273
  }).concat([html.script({src:'client/menu.js'})]))
2278
2274
  ]),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "backend-plus",
3
3
  "description": "Backend for the anti Pareto rule",
4
- "version": "2.1.3",
4
+ "version": "2.1.4",
5
5
  "author": "Codenautas <codenautas@googlegroups.com>",
6
6
  "license": "MIT",
7
7
  "repository": "codenautas/backend-plus",
@@ -41,10 +41,10 @@
41
41
  "cookie-parser": "^1.4.7",
42
42
  "dialog-promise": "^0.10.0",
43
43
  "discrepances": "^0.2.8",
44
- "express": "^4.21.1",
44
+ "express": "^4.21.2",
45
45
  "express-session": "^1.18.1",
46
46
  "express-useragent": "^1.0.15",
47
- "fs-extra": "^11.2.0",
47
+ "fs-extra": "^11.3.0",
48
48
  "js-to-html": "^1.3.2",
49
49
  "js-yaml": "^4.1.0",
50
50
  "json4all": "^1.4.0",
@@ -52,10 +52,10 @@
52
52
  "like-ar": "^0.5.1",
53
53
  "login-plus": "^1.7.2",
54
54
  "memorystore": "^1.6.7",
55
- "mini-tools": "^1.12.2",
55
+ "mini-tools": "^1.13.2",
56
56
  "moment": "^2.30.1",
57
57
  "multiparty": "^4.2.3",
58
- "nodemailer": "^6.9.16",
58
+ "nodemailer": "^6.10.0",
59
59
  "numeral": "^2.0.6",
60
60
  "pg-promise-strict": "^1.4.2",
61
61
  "pikaday": "^1.8.2",
@@ -64,7 +64,7 @@
64
64
  "regexplicit": "^0.1.3",
65
65
  "require-bro": "^0.3.1",
66
66
  "self-explain": "^0.11.0",
67
- "serve-content": "^0.3.20",
67
+ "serve-content": "^0.4.0",
68
68
  "session-file-store": "^1.5.0",
69
69
  "sql-tools": "^0.1.2",
70
70
  "stack-trace": "^0.0.10",
@@ -82,7 +82,7 @@
82
82
  "@types/js-yaml": "^4.0.9",
83
83
  "@types/mocha": "^10.0.10",
84
84
  "@types/multiparty": "~4.2.1",
85
- "@types/node": "^22.9.3",
85
+ "@types/node": "^22.10.10",
86
86
  "@types/nodemailer": "^6.4.17",
87
87
  "@types/numeral": "~2.0.5",
88
88
  "@types/session-file-store": "^1.2.5",
@@ -97,14 +97,14 @@
97
97
  "karma-ie-launcher": "^1.0.0",
98
98
  "karma-mocha": "^2.0.1",
99
99
  "kill-9": "~0.4.3",
100
- "mocha": "^10.8.2",
100
+ "mocha": "^11.1.0",
101
101
  "nyc": "^17.1.0",
102
- "puppeteer": "^23.9.0",
102
+ "puppeteer": "^24.1.1",
103
103
  "sinon": "^19.0.2",
104
104
  "supertest": "^7.0.0",
105
105
  "types.d.ts": "~0.6.22",
106
- "typescript": "^5.7.2",
107
- "why-is-node-running": "^3.2.1"
106
+ "typescript": "^5.7.3",
107
+ "why-is-node-running": "^3.2.2"
108
108
  },
109
109
  "engines": {
110
110
  "node": ">= 18"