backend-plus 2.0.0-rc.4 → 2.0.0-rc.6

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 CHANGED
@@ -6,11 +6,11 @@ Backend for the anti Pareto rule.
6
6
 
7
7
 
8
8
  ![stable](https://img.shields.io/badge/stability-stable-blue.svg)
9
- [![npm-version](https://img.shields.io/npm/v/backend-star.svg)](https://npmjs.org/package/backend-star)
10
- [![downloads](https://img.shields.io/npm/dm/backend-star.svg)](https://npmjs.org/package/backend-star)
11
- [![build](https://img.shields.io/travis/codenautas/backend-star/master.svg)](https://travis-ci.org/codenautas/backend-star)
12
- [![coverage](https://img.shields.io/coveralls/codenautas/backend-star/master.svg)](https://coveralls.io/r/codenautas/backend-star)
13
- [![dependencies](https://img.shields.io/david/codenautas/backend-star.svg)](https://david-dm.org/codenautas/backend-star)
9
+ [![npm-version](https://img.shields.io/npm/v/backend-plus.svg)](https://npmjs.org/package/backend-plus)
10
+ [![downloads](https://img.shields.io/npm/dm/backend-plus.svg)](https://npmjs.org/package/backend-plus)
11
+ [![build](https://img.shields.io/travis/codenautas/backend-plus/master.svg)](https://travis-ci.org/codenautas/backend-plus)
12
+ [![coverage](https://img.shields.io/coveralls/codenautas/backend-plus/master.svg)](https://coveralls.io/r/codenautas/backend-plus)
13
+ [![dependencies](https://img.shields.io/david/codenautas/backend-plus.svg)](https://david-dm.org/codenautas/backend-plus)
14
14
 
15
15
 
16
16
  language: ![English](https://raw.githubusercontent.com/codenautas/multilang/master/img/lang-en.png)
@@ -205,7 +205,7 @@ entry | usage
205
205
  -----------------------------|---------------
206
206
  server |
207
207
  .port | port where is listening
208
- .base-rul | base url added to domain name
208
+ .base-url | base url added to domain name
209
209
  .module-store |
210
210
  install | (see Spanish)
211
211
  .dump | (see Spanish)
@@ -690,11 +690,18 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
690
690
  if (myOwn.config.config['grid-row-retain-moved-or-deleted'] && !force) {
691
691
  var depotsToRetain = grid.depots.filter(depot => depot.tick == tick);
692
692
  for (depot of depotsToRetain) {
693
+ depot.row['$refreshed'] = false
693
694
  if (depot.tr && depot.tr.getAttribute('not-here')) depot.tr.removeAttribute('not-here')
694
695
  }
695
696
  }
696
697
  while (depot = depotsToDelete.pop()) {
697
698
  depot.manager.displayAsDeleted(depot, force ? 'change-ff' : 'unknown');
699
+ if (myOwn.config.config['grid-row-retain-moved-or-deleted']) {
700
+ if(!depot.row['$refreshed']){
701
+ grid.retrieveRowAndRefresh(depot,{retrieveIgnoringWhere:true})
702
+ depot.row['$refreshed'] = true
703
+ }
704
+ }
698
705
  }
699
706
  }
700
707
  })
@@ -2385,7 +2392,8 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2385
2392
  fixedFields:grid.def.primaryKey.map(function(fieldName, i){
2386
2393
  return {fieldName:fieldName, value:depot.primaryKeyValues[i]};
2387
2394
  }),
2388
- pick:grid.def.pick
2395
+ pick:grid.def.pick,
2396
+ retrieveIgnoringWhere: opts.retrieveIgnoringWhere
2389
2397
  }).then(function(result){
2390
2398
  grid.depotRefresh(depot,{updatedRow:result[0], sendedForUpdate:{}}, opts);
2391
2399
  })
@@ -0,0 +1,6 @@
1
+ create or replace function get_app_user() returns text
2
+ stable language sql
3
+ as
4
+ $sql$
5
+ select split_part(current_setting('application_name'),' ',1);
6
+ $sql$;
@@ -286,11 +286,11 @@ export type TableDefinition = EditableDbDefinition & {
286
286
  viewBody?:string
287
287
  insertIfNotUpdate?:boolean
288
288
  policies?:{
289
- all ?:{using?:string, check?:string}
290
- select?:{using?:string}
291
- insert?:{ check?:string}
292
- update?:{using?:string, check?:string}
293
- delete?:{using?:string}
289
+ all ?:{name?:string, using?:string, check?:string}
290
+ select?:{name?:string, using?:string}
291
+ insert?:{name?:string, check?:string}
292
+ update?:{name?:string, using?:string, check?:string}
293
+ delete?:{name?:string, using?:string}
294
294
  }
295
295
  join?:string
296
296
  constraintsDeferred?:boolean
@@ -704,7 +704,7 @@ AppBackend.prototype.start = function start(opts){
704
704
  throw new Error("backend-plus: Motor not recongnized: "+be.config.db.motor);
705
705
  }
706
706
  be.db = pg;
707
- be.dbUserNameExpr="split_part(current_setting('application_name'),' ',1)";
707
+ be.dbUserNameExpr="get_app_user()";
708
708
  be.dbUserRolExpr=`(select ${be.db.quoteIdent(be.config.login.rolFieldName)}
709
709
  from ${be.config.login.schema?be.db.quoteIdent(be.config.login.schema)+'.':''}${be.db.quoteIdent(be.config.login.table)}
710
710
  where ${be.db.quoteIdent(be.config.login.userFieldName)} = ${be.dbUserNameExpr})`
@@ -760,6 +760,7 @@ AppBackend.prototype.start = function start(opts){
760
760
  pg.log.inFileName = 'last-pg-error-local.sql'
761
761
  pg.logLastError.inFileName = 'last-pg-error-local.sql'
762
762
  }
763
+ be.config.db.search_path = be.config.db.search_path ?? [be.config.db.schema, 'public'];
763
764
  be.getDbClient = function getDbClient(req){
764
765
  var paramsDb = be.DoubleDragon?.dbParams?.[req?.user?.[be.config.login.userFieldName]] ?? be.config.db;
765
766
  return pg.connect(paramsDb).then(function(client){
@@ -771,7 +772,7 @@ AppBackend.prototype.start = function start(opts){
771
772
  return client.query(
772
773
  "SET application_name = "+be.db.quoteLiteral(dbAppName)
773
774
  ).execute().then(function(){
774
- var search_path = be.config.db.search_path || [be.config.db.schema, 'public'];
775
+ var search_path = be.config.db.search_path;
775
776
  if(search_path.length>0){
776
777
  return client.query("set SEARCH_PATH TO "+be.db.quoteIdentList(search_path)).execute().then(function(){
777
778
  return client;
@@ -1253,6 +1254,21 @@ AppBackend.prototype.checkDatabaseStructure = async function checkDatabaseStruct
1253
1254
  `;
1254
1255
  throw new Error(message);
1255
1256
  }
1257
+ var {rows: sql_routines} = await client.query(`SELECT routine_name, routine_schema, routine_definition
1258
+ FROM information_schema.routines
1259
+ WHERE routine_schema in (${be.config.db.search_path.map(path => be.db.quoteLiteral(path)).join(', ')})
1260
+ `).fetchAll();
1261
+ var sqlRoutines = likeAr.toPlainObject(sql_routines, 'routine_name');
1262
+ var message = ''
1263
+ likeAr(AppBackend.prototype.sql_routines).forEach((routine_name, def) => {
1264
+ if (sqlRoutines[routine_name] && def.dump.includes(sqlRoutines[routine_name].routine_definition)) {
1265
+ message += `
1266
+ ----- hay que crear o actualizar la rutina ${routine_name}:
1267
+ ${dump}
1268
+ `;
1269
+ }
1270
+ })
1271
+ if (message) throw new Error(message);
1256
1272
  };
1257
1273
 
1258
1274
  AppBackend.prototype.postConfig = function postConfig(){
@@ -2804,10 +2820,11 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
2804
2820
  lines.push('');
2805
2821
  if(tableDef.sql.policies.enabled){
2806
2822
  policyLines.push(`ALTER TABLE ${cualQuoteTableName} ENABLE ROW LEVEL SECURITY;`);
2807
- ['all', 'select', 'insert', 'update', 'delete'].forEach((command)=>{
2808
- var polcom=tableDef.sql.policies[command];
2809
- if(polcom.using || polcom.check){
2810
- policyLines.push(`CREATE POLICY bp_pol_${command} ON ${cualQuoteTableName} AS PERMISSIVE FOR ${command}`+
2823
+ [null, 'all', 'select', 'insert', 'update', 'delete'].forEach((command)=>{
2824
+ var polcom=tableDef.sql.policies[command] ?? {using: `true`, permissive:true};
2825
+ if(polcom?.using || polcom?.check){
2826
+ policyLines.push(`CREATE POLICY ${be.db.quoteIdent(polcom.name ?? `bp ${command ?? `base`}`)} ON ${cualQuoteTableName} `+
2827
+ `AS ${polcom.permissive ? `PERMISSIVE` : `RESTRICTIVE`} FOR ${command ?? `all`} TO ${be.config.db.user}`+
2811
2828
  (polcom.using? ` USING ( ${polcom.using} )`:'')+
2812
2829
  (polcom.check?` WITH CHECK ( ${polcom.check} )`:'')+';'
2813
2830
  );
@@ -2990,10 +3007,36 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
2990
3007
  };
2991
3008
  })
2992
3009
  );
3010
+
3011
+ var common = (await Promise.all(be.appStack.map(async function(stackNode){
3012
+ var common = [];
3013
+ for (var prefix of ['../', '../../']) {
3014
+ try {
3015
+ var dirName = Path.join(stackNode.path,prefix+'install').replace(regexpDistReplacer,'$1$2')
3016
+ console.log('********** buscando en', dirName, 'de', stackNode.path)
3017
+ var list = await fs.readdir(dirName);
3018
+ } catch (err) {
3019
+ if (err.code != 'ENOENT') throw err;
3020
+ console.log(err);
3021
+ var list = [];
3022
+ }
3023
+ console.log(list)
3024
+ for(var fileName of list){
3025
+ if (fileName.endsWith('-fun.sql')) {
3026
+ common.push(await fs.readFile(Path.join(dirName,fileName), 'utf-8'));
3027
+ }
3028
+ }
3029
+ }
3030
+ console.log(common)
3031
+ return common.join('\n');
3032
+ }))).join('\n');
3033
+
2993
3034
  var prepareList=(be.config.install.dump.scripts['prepare']||[]);
2994
3035
  var mainSql=(
2995
3036
  (complete? linesCreate.join('\n'): '')+
2996
3037
  (complete||opts.forDump? searchPathline.join('\n'): '')+
3038
+ '\n-- common'+
3039
+ common+'\n'+
2997
3040
  (complete? '\n\n--prepare.sql\n'+ texts[0]+'\n\n' :'' )+
2998
3041
  (complete? texts.slice(3,3+prepareList.length).join('\n\n')+'\n\n' : '' )+
2999
3042
  '\n-- functions\n' + functionLines.join('\n')+
@@ -78,13 +78,14 @@ ProcedureTables = [
78
78
  {name: 'table', encoding:'plain'},
79
79
  {name: 'fixedFields', defaultValue:[]},
80
80
  {name: 'paramfun', defaultValue:[]},
81
- {name: 'pick', defaultValue:'', encoding:'plain'}
81
+ {name: 'pick', defaultValue:'', encoding:'plain'},
82
+ {name: 'retrieveIgnoringWhere', defaultValue:false}
82
83
  ],
83
84
  coreFunction:
84
85
  /**
85
86
  *
86
87
  * @param {*} context
87
- * @param {{table:string, fixedFields:{fieldName:string, value:any, range:string}[], paramfun:string[], pick:string}} parameters
88
+ * @param {{table:string, fixedFields:{fieldName:string, value:any, range:string}[], paramfun:string[], pick:string, retrieveIgnoringWhere:boolean}} parameters * @param {{table:string, fixedFields:{fieldName:string, value:any, range:string}[], paramfun:string[], pick:string}} parameters
88
89
  */
89
90
  async function tableDatum(context, parameters){
90
91
  var be=context.be;
@@ -148,7 +149,7 @@ ProcedureTables = [
148
149
  /** @type {string} */
149
150
  var sql="SELECT "+[...defTable.sql.select].join(', ')+
150
151
  "\n FROM "+defTable.sql.from+
151
- "\n WHERE "+(defTable.sql.where||(defTable.allow.select && !defTable.forInsertOnlyMode?'true':'false'))+fixedClausule.join("")+
152
+ "\n WHERE "+((parameters.retrieveIgnoringWhere?'true':defTable.sql.where)||(defTable.allow.select && !defTable.forInsertOnlyMode?'true':'false'))+fixedClausule.join("")+
152
153
  // " ORDER BY "+defTable.primaryKey.map(be.db.quoteIdent.bind(be.db)).join(',')
153
154
  "\n ORDER BY "+(defTable.sql.orderBy||defTable.primaryKey).map(function(fieldName){ return be.db.quoteIdent(fieldName); }).join(',')
154
155
  if(specialFixedClause.length){
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.0.0-rc.4",
4
+ "version": "2.0.0-rc.6",
5
5
  "author": "Codenautas <codenautas@googlegroups.com>",
6
6
  "license": "MIT",
7
7
  "repository": "codenautas/backend-plus",
@@ -11,7 +11,8 @@
11
11
  "lib",
12
12
  "for-client",
13
13
  "unlogged",
14
- "src"
14
+ "src",
15
+ "install"
15
16
  ],
16
17
  "contributors": [
17
18
  {
@@ -34,7 +35,7 @@
34
35
  "best-globals": "^1.1.2",
35
36
  "big.js": "^6.2.1",
36
37
  "body-parser": "^1.20.2",
37
- "cast-error": "^0.1.0",
38
+ "cast-error": "^0.1.1",
38
39
  "castellano": "^0.1.3",
39
40
  "connect-pg-simple": "^9.0.1",
40
41
  "cookie-parser": "^1.4.6",
@@ -81,7 +82,7 @@
81
82
  "@types/js-yaml": "^4.0.9",
82
83
  "@types/mocha": "^10.0.6",
83
84
  "@types/multiparty": "~0.0.36",
84
- "@types/node": "^20.11.17",
85
+ "@types/node": "^20.11.19",
85
86
  "@types/nodemailer": "^6.4.14",
86
87
  "@types/numeral": "~2.0.5",
87
88
  "@types/session-file-store": "^1.2.5",
@@ -98,7 +99,7 @@
98
99
  "kill-9": "~0.4.3",
99
100
  "mocha": "^10.3.0",
100
101
  "nyc": "^15.1.0",
101
- "puppeteer": "^22.0.0",
102
+ "puppeteer": "^22.1.0",
102
103
  "sinon": "^17.0.1",
103
104
  "supertest": "^6.3.4",
104
105
  "types.d.ts": "~0.6.21",