backend-plus 2.5.2-betha.6 → 2.5.2-betha.8

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.
@@ -172,6 +172,9 @@ export type SequenceDefinition = {
172
172
  name:string
173
173
  firstValue:number
174
174
  prefix?:string /* Prefix for the generated value */
175
+ }
176
+ export type SequenceMadMaxDefinition = {
177
+ madMax: [] // Si se necesita una secuencia por grupo acá estará la lista de campos group by de la secuencia. Y habrá que modificar la funión de pg-triggers para que lo tome.
175
178
  }
176
179
  export type ExportMetadataDefinition={ /* TODO: define */ }
177
180
  export type PostInputOptions='upperSpanish' | 'upperWithoutDiacritics' | 'parseDecimal'
@@ -218,11 +221,21 @@ export type FieldDefinition = EditableDbDefinition & {
218
221
  alwaysShow?:boolean /* show when appears in fixed fields */
219
222
  suggestingKeys?:string[]
220
223
  postInput?:PostInputOptions
221
- } & ({} | {
222
- sequence:SequenceDefinition
223
- nullable:true
224
- editable:false
225
- })
224
+ } & (
225
+ {
226
+ sequence?: undefined
227
+ nullable?: boolean
228
+ editable?: boolean
229
+ } | {
230
+ sequence: SequenceDefinition
231
+ nullable: true
232
+ editable: false
233
+ } | {
234
+ sequence: SequenceMadMaxDefinition
235
+ nullable: true
236
+ editable: boolean
237
+ }
238
+ );
226
239
  export type EditableDbDefinition = {
227
240
  editable?:boolean
228
241
  allow?:{
@@ -415,7 +428,6 @@ export interface AppConfigLogin
415
428
  {
416
429
  schema: string // schema of the user table
417
430
  table: string // user table
418
- from: string // complete expression to get table or join where get the user
419
431
  userFieldname: string // fieldname in user table that stores the user name
420
432
  passFieldname: string // fieldname in user table that stores the password hash
421
433
  rolFieldname: string // fieldname in user table that stores the rol
@@ -20,6 +20,7 @@ MiniTools.globalOpts.serveErr.propertiesWhiteList=['message','detail','code','ta
20
20
  var crypto = require('crypto');
21
21
  var serveContent = require('serve-content');
22
22
  var pg = require('pg-promise-strict');
23
+ var pgTriggers = require('pg-triggers');
23
24
  var SessionFileStore = require('session-file-store');
24
25
  var memorystore = require('memorystore');
25
26
  var jsToHtml=require('js-to-html');
@@ -2653,7 +2654,16 @@ AppBackend.prototype.dumpFkConstraint = function dumpFkConstraint(fk, tableDef,
2653
2654
  return {consName, clause, sourceFieldList};
2654
2655
  }
2655
2656
 
2657
+ AppBackend.prototype.isGeneratedSequence = function isGeneratedSequence(sequence, not){
2658
+ return sequence && ((!sequence.name && !sequence.madMax) == !not)
2659
+ }
2660
+
2661
+ AppBackend.prototype.isSequenceNonGenerated = function isSequenceNonGenerated(sequence){
2662
+ return this.isGeneratedSequence(sequence, true);
2663
+ }
2664
+
2656
2665
  AppBackend.prototype.dumpDbTableFields = function dumpDbTableFields(tableDef, opts = {}, complements = null){
2666
+ var be = this;
2657
2667
  var db = this.db;
2658
2668
  var fields=[];
2659
2669
  tableDef.fields.forEach(function(fieldDef){
@@ -2667,7 +2677,7 @@ AppBackend.prototype.dumpDbTableFields = function dumpDbTableFields(tableDef, op
2667
2677
  ' '+(fieldDef.dataLength?(fieldType=='text'?'varchar':fieldType)+'('+fieldDef.dataLength+')':fieldType)+
2668
2678
  (fieldDef.defaultValue!=null?' default '+db.quoteLiteral(fieldDef.defaultValue):'')+
2669
2679
  (fieldDef.defaultDbValue!=null?' default '+fieldDef.defaultDbValue:'')+
2670
- (fieldDef.sequence && !fieldDef.sequence.name?' generated always as identity':'')+
2680
+ (be.isGeneratedSequence(fieldDef.sequence)?' generated always as identity':'')+
2671
2681
  (fieldDef.generatedAs!=null?` generated always as (${fieldDef.generatedAs}) stored`:'')
2672
2682
  );
2673
2683
  if(complements){
@@ -2774,7 +2784,7 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
2774
2784
  lines.push('create table '+cualQuoteTableName+' (');
2775
2785
  var fields = be.dumpDbTableFields(tableDef, opts,
2776
2786
  function complements(fieldDef){
2777
- if(fieldDef.sequence && !fieldDef.sequence.name){
2787
+ if(be.isGeneratedSequence(fieldDef.sequence)){
2778
2788
  tablesWithStrictSequence[tableName]={}
2779
2789
  }
2780
2790
  if(fieldDef.typeName==='text' && !fieldDef.allowEmptyText){
@@ -2798,7 +2808,7 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
2798
2808
  ' alter column '+db.quoteIdent(fieldDef.name)+' set not null;'
2799
2809
  );
2800
2810
  }
2801
- if(fieldDef.sequence && fieldDef.sequence.name){
2811
+ if(be.isSequenceNonGenerated(fieldDef.sequence)){
2802
2812
  fieldsForSequences.push(fieldDef);
2803
2813
  }
2804
2814
  }
@@ -2901,19 +2911,26 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
2901
2911
  });
2902
2912
  lines.push(tableDef.sql.postCreateSqls);
2903
2913
  lines.push('');
2904
- fieldsForSequences.forEach(function(fieldDef) {
2914
+ await Promise.all(fieldsForSequences.map(async function(fieldDef) {
2905
2915
  var sequence = fieldDef.sequence;
2906
- lines.push("CREATE SEQUENCE "+db.quoteIdent(sequence.name)+" START "+db.quoteInteger(sequence.firstValue||1)+";");
2907
- lines.push(
2908
- "ALTER TABLE "+cualQuoteTableName+
2909
- " ALTER COLUMN "+db.quoteIdent(fieldDef.name)+
2910
- (sequence.prefix==null
2911
- ?" SET DEFAULT nextval("+db.quoteLiteral(sequence.name)+"::regclass);"
2912
- :" SET DEFAULT ("+db.quoteLiteral(sequence.prefix)+" || nextval("+db.quoteLiteral(sequence.name)+"::regclass)::text);"
2913
- )
2914
- );
2915
- lines.push('GRANT USAGE, SELECT ON SEQUENCE '+db.quoteIdent(sequence.name)+' TO '+user+';');
2916
- });
2916
+ if (sequence.name) {
2917
+ if (sequence.madMax) throw new Error('a sequence with madMax cannot have name');
2918
+ lines.push("CREATE SEQUENCE "+db.quoteIdent(sequence.name)+" START "+db.quoteInteger(sequence.firstValue||1)+";");
2919
+ lines.push(
2920
+ "ALTER TABLE "+cualQuoteTableName+
2921
+ " ALTER COLUMN "+db.quoteIdent(fieldDef.name)+
2922
+ (sequence.prefix==null
2923
+ ?" SET DEFAULT nextval("+db.quoteLiteral(sequence.name)+"::regclass);"
2924
+ :" SET DEFAULT ("+db.quoteLiteral(sequence.prefix)+" || nextval("+db.quoteLiteral(sequence.name)+"::regclass)::text);"
2925
+ )
2926
+ );
2927
+ lines.push('GRANT USAGE, SELECT ON SEQUENCE '+db.quoteIdent(sequence.name)+' TO '+user+';');
2928
+ } else if (sequence.madMax) {
2929
+ lines.push(await pgTriggers.dumpMaxIdTrigger(tableDef.sql.tableName, fieldDef.name));
2930
+ } else {
2931
+ throw new Error('a sequence without madMax nor name');
2932
+ }
2933
+ }));
2917
2934
  lines.push('');
2918
2935
  if(tableDef.sql.policies.enabled){
2919
2936
  policyLines.push(`ALTER TABLE ${cualQuoteTableName} ENABLE ROW LEVEL SECURITY;`);
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.5.2-betha.6",
4
+ "version": "2.5.2-betha.8",
5
5
  "author": "Codenautas <codenautas@googlegroups.com>",
6
6
  "license": "MIT",
7
7
  "repository": "codenautas/backend-plus",
@@ -59,6 +59,7 @@
59
59
  "nodemailer": "^7.0.3",
60
60
  "numeral": "^2.0.6",
61
61
  "pg-promise-strict": "^1.4.2",
62
+ "pg-triggers": "0.4.2",
62
63
  "pikaday": "^1.8.2",
63
64
  "pug": "^3.0.3",
64
65
  "read-yaml-promise": "^1.0.2",
@@ -77,13 +78,13 @@
77
78
  "devDependencies": {
78
79
  "@types/big.js": "^6.2.2",
79
80
  "@types/expect.js": "~0.3.32",
80
- "@types/express": "^5.0.2",
81
+ "@types/express": "^5.0.3",
81
82
  "@types/express-useragent": "^1.0.5",
82
83
  "@types/fs-extra": "^11.0.4",
83
84
  "@types/js-yaml": "^4.0.9",
84
85
  "@types/mocha": "^10.0.10",
85
86
  "@types/multiparty": "~4.2.1",
86
- "@types/node": "^22.15.29",
87
+ "@types/node": "^24.0.3",
87
88
  "@types/nodemailer": "^6.4.17",
88
89
  "@types/numeral": "~2.0.5",
89
90
  "@types/session-file-store": "^1.2.5",
@@ -98,10 +99,10 @@
98
99
  "karma-ie-launcher": "^1.0.0",
99
100
  "karma-mocha": "^2.0.1",
100
101
  "kill-9": "~0.4.3",
101
- "mocha": "^11.5.0",
102
+ "mocha": "^11.7.0",
102
103
  "nyc": "^17.1.0",
103
- "puppeteer": "^24.9.0",
104
- "sinon": "^20.0.0",
104
+ "puppeteer": "^24.10.2",
105
+ "sinon": "^21.0.0",
105
106
  "supertest": "^7.1.1",
106
107
  "types.d.ts": "~0.6.22",
107
108
  "typescript": "^5.8.3",