prostgles-server 3.0.124 → 3.0.126

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.
Files changed (40) hide show
  1. package/dist/DboBuilder.d.ts.map +1 -1
  2. package/dist/DboBuilder.js +10 -9
  3. package/dist/DboBuilder.js.map +1 -1
  4. package/dist/JSONBValidation/validate_jsonb_schema_sql.js +2 -2
  5. package/dist/JSONBValidation/validate_jsonb_schema_sql.js.map +1 -1
  6. package/dist/PubSubManager/PubSubManager.d.ts.map +1 -1
  7. package/dist/PubSubManager/PubSubManager.js +17 -16
  8. package/dist/PubSubManager/PubSubManager.js.map +1 -1
  9. package/dist/PubSubManager/getInitQuery.d.ts.map +1 -1
  10. package/dist/PubSubManager/getInitQuery.js +5 -4
  11. package/dist/PubSubManager/getInitQuery.js.map +1 -1
  12. package/dist/PubSubManager/initPubSubManager.d.ts.map +1 -1
  13. package/dist/PubSubManager/initPubSubManager.js +4 -1
  14. package/dist/PubSubManager/initPubSubManager.js.map +1 -1
  15. package/dist/TableConfig.d.ts.map +1 -1
  16. package/dist/TableConfig.js +42 -12
  17. package/dist/TableConfig.js.map +1 -1
  18. package/lib/DboBuilder.d.ts.map +1 -1
  19. package/lib/DboBuilder.js +10 -9
  20. package/lib/DboBuilder.ts +10 -9
  21. package/lib/JSONBValidation/validate_jsonb_schema_sql.js +2 -2
  22. package/lib/JSONBValidation/validate_jsonb_schema_sql.ts +2 -2
  23. package/lib/PubSubManager/PubSubManager.d.ts.map +1 -1
  24. package/lib/PubSubManager/PubSubManager.js +17 -16
  25. package/lib/PubSubManager/PubSubManager.ts +17 -16
  26. package/lib/PubSubManager/getInitQuery.d.ts.map +1 -1
  27. package/lib/PubSubManager/getInitQuery.js +5 -4
  28. package/lib/PubSubManager/getInitQuery.ts +5 -4
  29. package/lib/PubSubManager/initPubSubManager.d.ts.map +1 -1
  30. package/lib/PubSubManager/initPubSubManager.js +4 -1
  31. package/lib/PubSubManager/initPubSubManager.ts +4 -1
  32. package/lib/TableConfig.d.ts.map +1 -1
  33. package/lib/TableConfig.js +42 -12
  34. package/lib/TableConfig.ts +49 -13
  35. package/package.json +1 -1
  36. package/tests/client/PID.txt +1 -1
  37. package/tests/server/DBoGenerated.d.ts +1 -1
  38. package/tests/server/index.js +1 -1
  39. package/tests/server/index.ts +1 -1
  40. package/tests/server/package-lock.json +1 -1
@@ -178,7 +178,7 @@ class TableConfigurator {
178
178
  await Promise.all((0, prostgles_types_1.getKeys)(this.config).map(async (tableName) => {
179
179
  const tableConf = this.config[tableName];
180
180
  if ("columns" in tableConf) {
181
- const getColDef = (name, colConf) => {
181
+ const getColDef = async (name, colConf) => {
182
182
  const colNameEsc = asName(name);
183
183
  const getColTypeDef = (colConf, pgType) => {
184
184
  const { nullable, defaultValue } = colConf;
@@ -217,17 +217,46 @@ class TableConfigurator {
217
217
  /** Validate default value against jsonbSchema */
218
218
  const q = `SELECT ${validate_jsonb_schema_sql_1.VALIDATE_SCHEMA_FUNCNAME}(${jsonbSchemaStr}, ${(0, PubSubManager_1.asValue)(colConf.defaultValue) + "::JSONB"}, ARRAY[${(0, PubSubManager_1.asValue)(name)}]) as v`;
219
219
  if (colConf.defaultValue) {
220
- this.log(q);
221
220
  const failedDefault = (err) => {
222
- console.error(`Default value (${colConf.defaultValue}) for ${tableName}.${name} does not satisfy the jsonb constraint check: ${q}`, err);
221
+ return { msg: `Default value (${colConf.defaultValue}) for ${tableName}.${name} does not satisfy the jsonb constraint check: ${q}`, err };
223
222
  };
224
- this.dbo.sql(q, {}, { returnType: "row" }).then(row => {
223
+ try {
224
+ const row = await this.dbo.sql(q, {}, { returnType: "row" });
225
225
  if (!row?.v) {
226
- failedDefault();
226
+ throw "Error";
227
227
  }
228
- }).catch(failedDefault);
228
+ }
229
+ catch (e) {
230
+ throw failedDefault(e);
231
+ }
232
+ }
233
+ const namePreffix = 'prostgles_jsonb_';
234
+ const { val: nameEnding } = await this.db.one("SELECT MD5( ${table} || ${column} || ${schema}) as val", { table: tableName, column: name, schema: jsonbSchemaStr });
235
+ const constraintName = namePreffix + nameEnding;
236
+ const colConstraints = await this.db.manyOrNone(`
237
+ SELECT *
238
+ FROM (
239
+ SELECT distinct c.conname as name,
240
+ (SELECT r.relname from pg_class r where r.oid = c.conrelid) as "table",
241
+ (SELECT array_agg(attname::text) from pg_attribute
242
+ where attrelid = c.conrelid and ARRAY[attnum] <@ c.conkey) as cols
243
+ -- (SELECT array_agg(attname::text) from pg_attribute
244
+ -- where attrelid = c.confrelid and ARRAY[attnum] <@ c.confkey) as fcols,
245
+ -- (SELECT r.relname from pg_class r where r.oid = c.confrelid) as ftable
246
+ FROM pg_catalog.pg_constraint c
247
+ INNER JOIN pg_catalog.pg_class rel
248
+ ON rel.oid = c.conrelid
249
+ INNER JOIN pg_catalog.pg_namespace nsp
250
+ ON nsp.oid = connamespace
251
+ ) t
252
+ WHERE TRUE
253
+ AND "table" = ${(0, PubSubManager_1.asValue)(tableName)} AND cols @> ARRAY[${(0, PubSubManager_1.asValue)(name)}]
254
+ `);
255
+ const existingNonMatchingConstraints = colConstraints.filter(c => c.name.startsWith(namePreffix) && c.name !== constraintName);
256
+ for await (const oldCons of existingNonMatchingConstraints) {
257
+ await this.db.any(`ALTER TABLE ${asName(tableName)} DROP CONSTRAINT ${asName(oldCons.name)}`);
229
258
  }
230
- return ` ${colNameEsc} ${getColTypeDef(colConf, "JSONB")} CHECK(${validate_jsonb_schema_sql_1.VALIDATE_SCHEMA_FUNCNAME}(${jsonbSchemaStr}, ${colNameEsc}, ARRAY[${(0, PubSubManager_1.asValue)(name)}]))`;
259
+ return ` ${colNameEsc} ${getColTypeDef(colConf, "JSONB")}, CONSTRAINT ${asName(constraintName)} CHECK(${validate_jsonb_schema_sql_1.VALIDATE_SCHEMA_FUNCNAME}(${jsonbSchemaStr}, ${colNameEsc}, ARRAY[${(0, PubSubManager_1.asValue)(name)}]))`;
231
260
  }
232
261
  else if ("enum" in colConf) {
233
262
  if (!colConf.enum?.length)
@@ -262,19 +291,20 @@ class TableConfigurator {
262
291
  throw err;
263
292
  }
264
293
  }
265
- (0, prostgles_types_1.getKeys)(tableConf.columns).filter(c => {
294
+ const columns = (0, prostgles_types_1.getKeys)(tableConf.columns).filter(c => {
266
295
  const colDef = tableConf.columns[c];
267
296
  return typeof colDef === "string" || !("joinDef" in colDef);
268
- }).forEach(colName => {
297
+ });
298
+ for await (const colName of columns) {
269
299
  const colConf = tableConf.columns[colName];
270
300
  /* Add columns to create statement */
271
301
  if (!tableHandler) {
272
- colCreateLines.push(getColDef(colName, colConf));
302
+ colCreateLines.push(await getColDef(colName, colConf));
273
303
  }
274
304
  else if (tableHandler && !tableHandler.columns?.find(c => colName === c.name)) {
275
305
  queries.push(`
276
306
  ALTER TABLE ${asName(tableName)}
277
- ADD COLUMN ${getColDef(colName, colConf)};
307
+ ADD COLUMN ${await getColDef(colName, colConf)};
278
308
  `);
279
309
  if ((0, prostgles_types_1.isObject)(colConf) && "references" in colConf && colConf.references) {
280
310
  const { tableName: lookupTable, } = colConf.references;
@@ -284,7 +314,7 @@ class TableConfigurator {
284
314
  this.log(`TableConfigurator: created/added column ${tableName}(${colName}) `);
285
315
  }
286
316
  }
287
- });
317
+ }
288
318
  }
289
319
  if (colCreateLines.length) {
290
320
  queries.push([
@@ -472,7 +472,7 @@ export default class TableConfigurator<LANG_IDS = { en: 1 }> {
472
472
  await Promise.all(getKeys(this.config).map(async tableName => {
473
473
  const tableConf = this.config![tableName];
474
474
  if ("columns" in tableConf) {
475
- const getColDef = (name: string, colConf: ColumnConfig): string => {
475
+ const getColDef = async (name: string, colConf: ColumnConfig): Promise<string> => {
476
476
  const colNameEsc = asName(name);
477
477
  const getColTypeDef = (colConf: BaseColumnTypes, pgType: "TEXT" | "JSONB") => {
478
478
  const { nullable, defaultValue } = colConf;
@@ -518,19 +518,53 @@ export default class TableConfigurator<LANG_IDS = { en: 1 }> {
518
518
  }) + "::TEXT";
519
519
 
520
520
  /** Validate default value against jsonbSchema */
521
- const q = `SELECT ${VALIDATE_SCHEMA_FUNCNAME}(${jsonbSchemaStr}, ${asValue(colConf.defaultValue)+"::JSONB"}, ARRAY[${asValue(name)}]) as v`
521
+ const q = `SELECT ${VALIDATE_SCHEMA_FUNCNAME}(${jsonbSchemaStr}, ${asValue(colConf.defaultValue)+"::JSONB"}, ARRAY[${asValue(name)}]) as v`;
522
522
  if(colConf.defaultValue){
523
- this.log(q);
523
+
524
524
  const failedDefault = (err?: any) => {
525
- console.error(`Default value (${colConf.defaultValue}) for ${tableName}.${name} does not satisfy the jsonb constraint check: ${q}`, err);
525
+ return { msg: `Default value (${colConf.defaultValue}) for ${tableName}.${name} does not satisfy the jsonb constraint check: ${q}`, err };
526
526
  }
527
- this.dbo.sql!(q, {}, { returnType: "row" }).then(row => {
527
+ try {
528
+ const row = await this.dbo.sql!(q, {}, { returnType: "row" });
528
529
  if(!row?.v) {
529
- failedDefault();
530
+ throw "Error";
530
531
  }
531
- }).catch(failedDefault)
532
+ } catch(e){
533
+ throw failedDefault(e);
534
+ }
532
535
  }
533
- return ` ${colNameEsc} ${getColTypeDef(colConf, "JSONB")} CHECK(${VALIDATE_SCHEMA_FUNCNAME}(${jsonbSchemaStr}, ${colNameEsc}, ARRAY[${asValue(name)}]))`;
536
+ const namePreffix = 'prostgles_jsonb_' as const;
537
+ const { val: nameEnding } = await this.db.one("SELECT MD5( ${table} || ${column} || ${schema}) as val", { table: tableName, column: name, schema: jsonbSchemaStr });
538
+ const constraintName = namePreffix + nameEnding;
539
+ const colConstraints: {
540
+ name: string;
541
+ table: string;
542
+ cols: Array<string>;
543
+ }[] = await this.db.manyOrNone(`
544
+ SELECT *
545
+ FROM (
546
+ SELECT distinct c.conname as name,
547
+ (SELECT r.relname from pg_class r where r.oid = c.conrelid) as "table",
548
+ (SELECT array_agg(attname::text) from pg_attribute
549
+ where attrelid = c.conrelid and ARRAY[attnum] <@ c.conkey) as cols
550
+ -- (SELECT array_agg(attname::text) from pg_attribute
551
+ -- where attrelid = c.confrelid and ARRAY[attnum] <@ c.confkey) as fcols,
552
+ -- (SELECT r.relname from pg_class r where r.oid = c.confrelid) as ftable
553
+ FROM pg_catalog.pg_constraint c
554
+ INNER JOIN pg_catalog.pg_class rel
555
+ ON rel.oid = c.conrelid
556
+ INNER JOIN pg_catalog.pg_namespace nsp
557
+ ON nsp.oid = connamespace
558
+ ) t
559
+ WHERE TRUE
560
+ AND "table" = ${asValue(tableName)} AND cols @> ARRAY[${asValue(name)}]
561
+ `);
562
+ const existingNonMatchingConstraints = colConstraints.filter(c => c.name.startsWith(namePreffix) && c.name !== constraintName);
563
+ for await (const oldCons of existingNonMatchingConstraints){
564
+ await this.db.any(`ALTER TABLE ${asName(tableName)} DROP CONSTRAINT ${asName(oldCons.name)}`);
565
+ }
566
+
567
+ return ` ${colNameEsc} ${getColTypeDef(colConf, "JSONB")}, CONSTRAINT ${asName(constraintName)} CHECK(${VALIDATE_SCHEMA_FUNCNAME}(${jsonbSchemaStr}, ${colNameEsc}, ARRAY[${asValue(name)}]))`;
534
568
 
535
569
  } else if("enum" in colConf) {
536
570
  if(!colConf.enum?.length) throw new Error("colConf.enum Must not be empty");
@@ -567,21 +601,23 @@ export default class TableConfigurator<LANG_IDS = { en: 1 }> {
567
601
  }
568
602
  }
569
603
 
570
- getKeys(tableConf.columns).filter(c => {
604
+ const columns = getKeys(tableConf.columns).filter(c => {
571
605
  const colDef = tableConf.columns![c];
572
606
  return typeof colDef === "string" || !("joinDef" in colDef)
573
- }).forEach(colName => {
607
+ });
608
+
609
+ for await(const colName of columns) {
574
610
  const colConf = tableConf.columns![colName];
575
611
 
576
612
  /* Add columns to create statement */
577
613
  if (!tableHandler) {
578
- colCreateLines.push(getColDef(colName, colConf));
614
+ colCreateLines.push(await getColDef(colName, colConf));
579
615
 
580
616
  } else if (tableHandler && !tableHandler.columns?.find(c => colName === c.name)) {
581
617
 
582
618
  queries.push(`
583
619
  ALTER TABLE ${asName(tableName)}
584
- ADD COLUMN ${getColDef(colName, colConf)};
620
+ ADD COLUMN ${await getColDef(colName, colConf)};
585
621
  `)
586
622
  if (isObject(colConf) && "references" in colConf && colConf.references) {
587
623
 
@@ -591,7 +627,7 @@ export default class TableConfigurator<LANG_IDS = { en: 1 }> {
591
627
  this.log(`TableConfigurator: created/added column ${tableName}(${colName}) `)
592
628
  }
593
629
  }
594
- });
630
+ }
595
631
  }
596
632
 
597
633
  if (colCreateLines.length) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prostgles-server",
3
- "version": "3.0.124",
3
+ "version": "3.0.126",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1 +1 @@
1
- 297857
1
+ 178436
@@ -437,7 +437,7 @@ export type DBSchemaGenerated = {
437
437
  columns: {
438
438
  email: string;
439
439
  id?: number;
440
- preferences?: { showIntro?: boolean; theme?: 'light' | 'dark' | 'auto'; others: any[]; };
440
+ preferences: { showIntro?: boolean; theme?: 'light' | 'dark' | 'auto'; others: any[]; };
441
441
  status: "active" | "disabled" | "pending"
442
442
  };
443
443
  };
@@ -90,7 +90,7 @@ function dd() {
90
90
  id: { sqlDefinition: `SERIAL PRIMARY KEY ` },
91
91
  email: { sqlDefinition: `TEXT NOT NULL` },
92
92
  status: { enum: ["active", "disabled", "pending"] },
93
- preferences: { defaultValue: "{}",
93
+ preferences: {
94
94
  jsonbSchemaType: {
95
95
  showIntro: { type: "boolean", optional: true },
96
96
  theme: { enum: ["light", "dark", "auto"], optional: true },
@@ -111,7 +111,7 @@ function dd(){
111
111
  id: { sqlDefinition: `SERIAL PRIMARY KEY ` },
112
112
  email: { sqlDefinition: `TEXT NOT NULL` },
113
113
  status: { enum: ["active", "disabled", "pending"] },
114
- preferences: { defaultValue: "{}",
114
+ preferences: {
115
115
  jsonbSchemaType: {
116
116
  showIntro: { type: "boolean", optional: true },
117
117
  theme: { enum: ["light", "dark", "auto"], optional: true },
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "../..": {
23
23
  "name": "prostgles-server",
24
- "version": "3.0.123",
24
+ "version": "3.0.125",
25
25
  "license": "MIT",
26
26
  "dependencies": {
27
27
  "@aws-sdk/client-s3": "^3.272.0",