prostgles-server 2.0.189 → 2.0.192

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 (48) hide show
  1. package/dist/DboBuilder/insertDataParse.d.ts.map +1 -1
  2. package/dist/DboBuilder/insertDataParse.js +12 -3
  3. package/dist/DboBuilder/insertDataParse.js.map +1 -1
  4. package/dist/DboBuilder.d.ts +5 -4
  5. package/dist/DboBuilder.d.ts.map +1 -1
  6. package/dist/DboBuilder.js +54 -153
  7. package/dist/DboBuilder.js.map +1 -1
  8. package/dist/FileManager.d.ts +20 -72
  9. package/dist/FileManager.d.ts.map +1 -1
  10. package/dist/FileManager.js +233 -164
  11. package/dist/FileManager.js.map +1 -1
  12. package/dist/PostgresNotifListenManager.d.ts.map +1 -1
  13. package/dist/PostgresNotifListenManager.js +3 -1
  14. package/dist/PostgresNotifListenManager.js.map +1 -1
  15. package/dist/Prostgles.d.ts +13 -2
  16. package/dist/Prostgles.d.ts.map +1 -1
  17. package/dist/Prostgles.js +8 -4
  18. package/dist/Prostgles.js.map +1 -1
  19. package/dist/TableConfig.d.ts +1 -2
  20. package/dist/TableConfig.d.ts.map +1 -1
  21. package/dist/TableConfig.js.map +1 -1
  22. package/lib/DboBuilder/insertDataParse.d.ts.map +1 -1
  23. package/lib/DboBuilder/insertDataParse.js +12 -3
  24. package/lib/DboBuilder/insertDataParse.ts +12 -3
  25. package/lib/DboBuilder.d.ts +5 -4
  26. package/lib/DboBuilder.d.ts.map +1 -1
  27. package/lib/DboBuilder.js +54 -153
  28. package/lib/DboBuilder.ts +67 -181
  29. package/lib/FileManager.d.ts +19 -71
  30. package/lib/FileManager.d.ts.map +1 -1
  31. package/lib/FileManager.js +233 -164
  32. package/lib/FileManager.ts +274 -191
  33. package/lib/PostgresNotifListenManager.d.ts.map +1 -1
  34. package/lib/PostgresNotifListenManager.js +3 -1
  35. package/lib/PostgresNotifListenManager.ts +4 -1
  36. package/lib/Prostgles.d.ts +13 -2
  37. package/lib/Prostgles.d.ts.map +1 -1
  38. package/lib/Prostgles.js +8 -4
  39. package/lib/Prostgles.ts +9 -5
  40. package/lib/TableConfig.d.ts +1 -2
  41. package/lib/TableConfig.d.ts.map +1 -1
  42. package/lib/TableConfig.ts +2 -4
  43. package/lib/fileType/core.js +1527 -0
  44. package/lib/fileType/supported.js +278 -0
  45. package/package.json +3 -3
  46. package/tests/client/PID.txt +1 -1
  47. package/tests/server/DBoGenerated.d.ts +1 -1
  48. package/tests/server/package-lock.json +5 -5
package/lib/DboBuilder.js CHANGED
@@ -390,16 +390,16 @@ class ViewHandler {
390
390
  };
391
391
  });
392
392
  let expectOne = false;
393
- paths.map(({ source, target, on }, i) => {
394
- // if(expectOne && on.length === 1){
395
- // const sourceCol = on[0][1];
396
- // const targetCol = on[0][0];
397
- // const sCol = this.dboBuilder.dbo[source].columns.find(c => c.name === sourceCol)
398
- // const tCol = this.dboBuilder.dbo[target].columns.find(c => c.name === targetCol)
399
- // console.log({ sourceCol, targetCol, sCol, source, tCol, target, on})
400
- // expectOne = sCol.is_pkey && tCol.is_pkey
401
- // }
402
- });
393
+ // paths.map(({ source, target, on }, i) => {
394
+ // if(expectOne && on.length === 1){
395
+ // const sourceCol = on[0][1];
396
+ // const targetCol = on[0][0];
397
+ // const sCol = this.dboBuilder.dbo[source].columns.find(c => c.name === sourceCol)
398
+ // const tCol = this.dboBuilder.dbo[target].columns.find(c => c.name === targetCol)
399
+ // console.log({ sourceCol, targetCol, sCol, source, tCol, target, on})
400
+ // expectOne = sCol.is_pkey && tCol.is_pkey
401
+ // }
402
+ // })
403
403
  return {
404
404
  paths,
405
405
  expectOne
@@ -414,31 +414,32 @@ class ViewHandler {
414
414
  if (!p.getInfo)
415
415
  throw "Not allowed";
416
416
  let has_media = undefined;
417
- /**
418
- * Media is directly related to this table (does not come from a deeply joined table)
419
- */
420
- let has_direct_media = false;
421
417
  const mediaTable = this.dboBuilder.prostgles?.opts?.fileTable?.tableName;
422
418
  if (!this.is_media && mediaTable) {
423
- if (this.dboBuilder.prostgles?.opts?.fileTable?.referencedTables?.[this.name]) {
424
- has_media = this.dboBuilder.prostgles?.opts?.fileTable?.referencedTables?.[this.name];
425
- has_direct_media = true;
419
+ const joinConf = this.dboBuilder.prostgles?.opts?.fileTable?.referencedTables?.[this.name];
420
+ if (joinConf) {
421
+ has_media = typeof joinConf === "string" ? joinConf : "one";
426
422
  }
427
423
  else {
428
424
  const jp = this.dboBuilder.joinPaths.find(jp => jp.t1 === this.name && jp.t2 === mediaTable);
429
425
  if (jp && jp.path.length <= 3) {
430
- await Promise.all(jp.path.map(async (tableName) => {
431
- const cols = (await this?.dboBuilder?.dbo?.[tableName]?.getColumns?.())?.filter(c => jp.path.includes(c?.references?.ftable));
432
- if (cols && cols.length && has_media !== "many") {
433
- if (cols.find(c => !c.is_pkey)) {
434
- has_media = "many";
435
- }
436
- else {
437
- has_media = "one";
426
+ if (jp.path.length <= 2) {
427
+ has_media = "one";
428
+ }
429
+ else {
430
+ await Promise.all(jp.path.map(async (tableName) => {
431
+ const pkeyFcols = this?.dboBuilder?.dbo?.[tableName]?.columns?.filter(c => c.is_pkey).map(c => c.name);
432
+ const cols = this?.dboBuilder?.dbo?.[tableName]?.columns?.filter(c => c?.references && jp.path.includes(c?.references?.ftable));
433
+ if (cols && cols.length && has_media !== "many") {
434
+ if (cols.some(c => !pkeyFcols?.includes(c.name))) {
435
+ has_media = "many";
436
+ }
437
+ else {
438
+ has_media = "one";
439
+ }
438
440
  }
439
- has_direct_media = jp.path.length === 2;
440
- }
441
- }));
441
+ }));
442
+ }
442
443
  }
443
444
  }
444
445
  }
@@ -448,7 +449,6 @@ class ViewHandler {
448
449
  info: this.dboBuilder.prostgles?.tableConfigurator?.getTableInfo({ tableName: this.name, lang }),
449
450
  is_media: this.is_media,
450
451
  has_media,
451
- has_direct_media,
452
452
  media_table_name: mediaTable,
453
453
  dynamicRules: {
454
454
  update: Boolean(tableRules?.update?.dynamicFields?.length)
@@ -485,6 +485,8 @@ class ViewHandler {
485
485
  let label = c.comment || capitalizeFirstLetter(c.name, " ");
486
486
  const select = c.privileges.some(p => p.privilege_type === "SELECT"), insert = c.privileges.some(p => p.privilege_type === "INSERT"), update = c.privileges.some(p => p.privilege_type === "UPDATE"), _delete = this.tableOrViewInfo.privileges.delete; // c.privileges.some(p => p.privilege_type === "DELETE");
487
487
  delete c.privileges;
488
+ const prostgles = this.dboBuilder?.prostgles;
489
+ const fileConfig = prostgles.fileManager?.getColInfo({ colName: c.name, tableName: this.name });
488
490
  let result = {
489
491
  ...c,
490
492
  label,
@@ -494,7 +496,8 @@ class ViewHandler {
494
496
  filter: Boolean(p.select && p.select.filterFields && p.select.filterFields.includes(c.name)),
495
497
  update: update && Boolean(p.update && p.update.fields && p.update.fields.includes(c.name)),
496
498
  delete: _delete && Boolean(p.delete && p.delete.filterFields && p.delete.filterFields.includes(c.name)),
497
- ...(this.dboBuilder?.prostgles?.tableConfigurator?.getColInfo({ table: this.name, col: c.name, lang }) || {})
499
+ ...(prostgles?.tableConfigurator?.getColInfo({ table: this.name, col: c.name, lang }) || {}),
500
+ ...(fileConfig && { file: fileConfig })
498
501
  };
499
502
  if (dynamicUpdateFields) {
500
503
  result.update = dynamicUpdateFields.includes(c.name);
@@ -1381,8 +1384,8 @@ class ViewHandler {
1381
1384
  */
1382
1385
  }
1383
1386
  else if (isPlainObject(fieldParams)) {
1384
- if (Object.keys(fieldParams).length) {
1385
- let keys = Object.keys(fieldParams);
1387
+ if ((0, prostgles_types_1.getKeys)(fieldParams).length) {
1388
+ let keys = (0, prostgles_types_1.getKeys)(fieldParams);
1386
1389
  if (keys[0] === "") {
1387
1390
  if (allow_empty) {
1388
1391
  return [""];
@@ -1997,20 +2000,9 @@ class DboBuilder {
1997
2000
  return this.db.tx((t) => {
1998
2001
  let dbTX = {};
1999
2002
  this.tablesOrViews?.map(tov => {
2000
- if (tov.is_view) {
2001
- dbTX[tov.name] = new ViewHandler(this.db, tov, this, t, dbTX, this.joinPaths);
2002
- }
2003
- else {
2004
- dbTX[tov.name] = new TableHandler(this.db, tov, this, t, dbTX, this.joinPaths);
2005
- /**
2006
- * Pass only the transaction object to ensure consistency
2007
- */
2008
- // dbTX[tov.name] = new ViewHandler(t, tov, this.pubSubManager, this, t, this.joinPaths);
2009
- // } else {
2010
- // dbTX[tov.name] = new TableHandler(t as any, tov, this.pubSubManager, this, t, this.joinPaths);
2011
- }
2003
+ dbTX[tov.name] = new (tov.is_view ? ViewHandler : TableHandler)(this.db, tov, this, t, dbTX, this.joinPaths);
2012
2004
  });
2013
- Object.keys(dbTX).map(k => {
2005
+ (0, prostgles_types_1.getKeys)(dbTX).map(k => {
2014
2006
  dbTX[k].dbTX = dbTX;
2015
2007
  });
2016
2008
  return cb(dbTX, t);
@@ -2125,24 +2117,10 @@ class DboBuilder {
2125
2117
  }
2126
2118
  return this.joinPaths;
2127
2119
  }
2128
- buildJoinPaths() {
2129
- }
2130
2120
  async build() {
2131
- // await this.pubSubManager.init()
2132
- this.tablesOrViews = await getTablesForSchemaPostgresSQL(this.db); //, this.schema
2133
- // console.log(this.tablesOrViews.map(t => `${t.name} (${t.columns.map(c => c.name).join(", ")})`))
2121
+ this.tablesOrViews = await getTablesForSchemaPostgresSQL(this.db);
2134
2122
  this.constraints = await getConstraints(this.db);
2135
2123
  await this.parseJoins();
2136
- // const common_types =
2137
- // `
2138
- // import { ViewHandler, TableHandler, JoinMaker } from "prostgles-types";
2139
- // export type TxCB = {
2140
- // (t: DBObj): (any | void | Promise<(any | void)>)
2141
- // };
2142
- // `
2143
- // this.dboDefinition = `export type DBObj = {\n`;
2144
- // let joinTableNames: string[] = [];
2145
- // let allDataDefs = "";
2146
2124
  this.tablesOrViews.map(tov => {
2147
2125
  const columnsForTypes = tov.columns.slice(0).sort((a, b) => a.name.localeCompare(b.name));
2148
2126
  const filterKeywords = Object.values(this.prostgles.keywords);
@@ -2152,23 +2130,9 @@ class DboBuilder {
2152
2130
  Please provide a replacement keyword name using the $filter_keyName init option.
2153
2131
  Alternatively you can rename the table column\n`;
2154
2132
  }
2155
- const TSTableDataName = snakify(tov.name, true);
2156
- const TSTableHandlerName = escapeTSNames(tov.name);
2157
- if (tov.is_view) {
2158
- this.dbo[tov.name] = new ViewHandler(this.db, tov, this, undefined, undefined, this.joinPaths);
2159
- // this.dboDefinition += ` ${TSTableHandlerName}: ViewHandler<${TSTableDataName}> \n`;
2160
- }
2161
- else {
2162
- this.dbo[tov.name] = new TableHandler(this.db, tov, this, undefined, undefined, this.joinPaths);
2163
- // this.dboDefinition += ` ${TSTableHandlerName}: TableHandler<${TSTableDataName}> \n`;
2164
- }
2165
- // allDataDefs += `export type ${TSTableDataName} = { \n` +
2166
- // (this.dbo[tov.name] as ViewHandler).tsColumnDefs.map(str => ` ` + str).join("\n") +
2167
- // `\n}\n`;
2168
- // this.dboDefinition += ` ${escapeTSNames(tov.name, false)}: ${(this.dbo[tov.name] as TableHandler).tsDboName};\n`;
2133
+ this.dbo[tov.name] = new (tov.is_view ? ViewHandler : TableHandler)(this.db, tov, this, undefined, undefined, this.joinPaths);
2169
2134
  if (this.joinPaths && this.joinPaths.find(jp => [jp.t1, jp.t2].includes(tov.name))) {
2170
2135
  let table = tov.name;
2171
- // joinTableNames.push(table);
2172
2136
  const makeJoin = (isLeft = true, filter, select, options) => {
2173
2137
  return {
2174
2138
  [isLeft ? "$leftJoin" : "$innerJoin"]: table,
@@ -2195,17 +2159,6 @@ class DboBuilder {
2195
2159
  };
2196
2160
  }
2197
2161
  });
2198
- // let joinBuilderDef = "";
2199
- // if(joinTableNames.length){
2200
- // joinBuilderDef += "export type JoinMakerTables = {\n";
2201
- // joinTableNames.map(tname => {
2202
- // joinBuilderDef += ` ${escapeTSNames(tname)}: JoinMaker<${snakify(tname, true)}>;\n`
2203
- // })
2204
- // joinBuilderDef += "};\n";
2205
- // ["leftJoin", "innerJoin", "leftJoinOne", "innerJoinOne"].map(joinType => {
2206
- // this.dboDefinition += ` ${joinType}: JoinMakerTables;\n`;
2207
- // });
2208
- // }
2209
2162
  if (this.prostgles.opts.transactions) {
2210
2163
  let txKey = "tx";
2211
2164
  if (typeof this.prostgles.opts.transactions === "string")
@@ -2214,7 +2167,7 @@ class DboBuilder {
2214
2167
  this.dbo[txKey] = (cb) => this.getTX(cb);
2215
2168
  }
2216
2169
  if (!this.dbo.sql) {
2217
- let needType = true; // this.publishRawSQL && typeof this.publishRawSQL === "function";
2170
+ let needType = true;
2218
2171
  let DATA_TYPES = !needType ? [] : await this.db.any("SELECT oid, typname FROM pg_type");
2219
2172
  let USER_TABLES = !needType ? [] : await this.db.any("SELECT relid, relname FROM pg_catalog.pg_statio_user_tables");
2220
2173
  this.dbo.sql = async (query, params, options, localParams) => {
@@ -2312,16 +2265,11 @@ class DboBuilder {
2312
2265
  }
2313
2266
  this.dboDefinition += "};\n";
2314
2267
  this.tsTypesDefinition = [
2315
- // common_types,
2316
2268
  `/* SCHEMA DEFINITON. Table names have been altered to work with Typescript */`,
2317
- // allDataDefs,
2318
- // joinBuilderDef,
2319
- `/* DBO Definition. Isomorphic */`,
2320
- // this.dboDefinition,
2269
+ `/* DBO Definition */`,
2321
2270
  (0, DBSchemaBuilder_1.getDBSchema)(this)
2322
2271
  ].join("\n");
2323
2272
  return this.dbo;
2324
- // let dbo = makeDBO(db, allTablesViews, pubSubManager, true);
2325
2273
  }
2326
2274
  }
2327
2275
  exports.DboBuilder = DboBuilder;
@@ -2458,15 +2406,6 @@ async function getTablesForSchemaPostgresSQL(db, schema = "public") {
2458
2406
  `;
2459
2407
  // console.log(pgp.as.format(query, { schema }), schema);
2460
2408
  let res = await db.any(query, { schema });
2461
- // res = await Promise.all(res.map(async tbl => {
2462
- // tbl.columns = await Promise.all(tbl.columns.map(async col => {
2463
- // if(col.has_default){
2464
- // col.column_default = !col.column_default.startsWith("nextval(")? (await db.oneOrNone(`SELECT ${col.column_default} as val`)).val : null;
2465
- // }
2466
- // return col;
2467
- // }))
2468
- // return tbl;
2469
- // }))
2470
2409
  res = res.map(tbl => {
2471
2410
  tbl.columns = tbl.columns.map(col => {
2472
2411
  if (col.has_default) {
@@ -2481,8 +2420,6 @@ async function getTablesForSchemaPostgresSQL(db, schema = "public") {
2481
2420
  }
2482
2421
  /**
2483
2422
  * Throw error if illegal keys found in object
2484
- * @param {Object} obj - Object to be checked
2485
- * @param {string[]} allowedKeys - The name of the employee.
2486
2423
  */
2487
2424
  function validateObj(obj, allowedKeys) {
2488
2425
  if (obj && Object.keys(obj).length) {
@@ -2756,13 +2693,16 @@ function sqlErrCodeToMsg(code) {
2756
2693
  }
2757
2694
  async function getInferredJoins2(schema) {
2758
2695
  let joins = [];
2759
- const upsertJoin = (t1, t2, cols) => {
2696
+ const upsertJoin = (t1, t2, cols, type) => {
2760
2697
  let existingIdx = joins.findIndex(j => j.tables.slice(0).sort().join() === [t1, t2].sort().join());
2761
2698
  let existing = joins[existingIdx];
2762
2699
  const normalCond = cols.reduce((a, v) => ({ ...a, [v.col1]: v.col2 }), {});
2763
2700
  const revertedCond = cols.reduce((a, v) => ({ ...a, [v.col2]: v.col1 }), {});
2764
2701
  if (existing) {
2765
- const cond = existing.tables[0] === t1 ? normalCond : revertedCond;
2702
+ const isLTR = existing.tables[0] === t1;
2703
+ const cond = isLTR ? normalCond : revertedCond;
2704
+ /** At some point we should add relationship type to EACH JOIN CONDITION GROUP */
2705
+ // const fixedType = isLTR? type : type.split("").reverse().join("") as Join["type"];
2766
2706
  /** Avoid duplicates */
2767
2707
  if (!existing.on.some(_cond => JSON.stringify(_cond) === JSON.stringify(cond))) {
2768
2708
  existing.on.push(cond);
@@ -2773,7 +2713,7 @@ async function getInferredJoins2(schema) {
2773
2713
  joins.push({
2774
2714
  tables: [t1, t2],
2775
2715
  on: [normalCond],
2776
- type: "many-many"
2716
+ type
2777
2717
  });
2778
2718
  }
2779
2719
  };
@@ -2781,54 +2721,15 @@ async function getInferredJoins2(schema) {
2781
2721
  tov.columns.map(col => {
2782
2722
  if (col.references) {
2783
2723
  const r = col.references;
2784
- upsertJoin(tov.name, r.ftable, r.cols.map((c, i) => ({ col1: c, col2: r.fcols[i] })));
2724
+ const joinCols = r.cols.map((c, i) => ({ col1: c, col2: r.fcols[i] }));
2725
+ let type = "one-many";
2726
+ const ftablePkeys = schema.find(_tov => _tov.name === r.ftable)?.columns.filter(fcol => fcol.is_pkey);
2727
+ if (ftablePkeys?.length && ftablePkeys.every(fkey => r.fcols.includes(fkey.name))) {
2728
+ type = "one-one";
2729
+ }
2730
+ upsertJoin(tov.name, r.ftable, joinCols, type);
2785
2731
  }
2786
2732
  });
2787
2733
  });
2788
2734
  return joins;
2789
2735
  }
2790
- // async function getInferredJoins(db: DB, schema: string = "public"): Promise<Join[]>{
2791
- // let joins: Join[] = [];
2792
- // let res = await db.any(`SELECT
2793
- // tc.table_schema,
2794
- // tc.constraint_name,
2795
- // tc.table_name,
2796
- // kcu.column_name,
2797
- // ccu.table_schema AS foreign_table_schema,
2798
- // ccu.table_name AS foreign_table_name,
2799
- // ccu.column_name AS foreign_column_name,
2800
- // tc.constraint_type IN ('UNIQUE', 'PRIMARY KEY') as foreign_is_unique
2801
- // FROM
2802
- // information_schema.table_constraints AS tc
2803
- // JOIN information_schema.key_column_usage AS kcu
2804
- // ON tc.constraint_name = kcu.constraint_name
2805
- // AND tc.table_schema = kcu.table_schema
2806
- // JOIN information_schema.constraint_column_usage AS ccu
2807
- // ON ccu.constraint_name = tc.constraint_name
2808
- // AND ccu.table_schema = tc.table_schema
2809
- // WHERE tc.table_schema=` + "${schema}" + `
2810
- // AND tc.constraint_type = 'FOREIGN KEY'
2811
- // AND tc.table_name <> ccu.table_name -- Exclude self-referencing tables
2812
- // `, { schema });
2813
- // res.map((d: any) => {
2814
- // let eIdx = joins.findIndex(j => j.tables.includes(d.table_name) && j.tables.includes(d.foreign_table_name));
2815
- // let existing = joins[eIdx];
2816
- // if(existing){
2817
- // if(existing.tables[0] === d.table_name){
2818
- // existing.on = { ...existing.on, [d.column_name]: d.foreign_column_name }
2819
- // } else {
2820
- // existing.on = { ...existing.on, [d.foreign_column_name]: d.column_name }
2821
- // }
2822
- // joins[eIdx] = existing;
2823
- // } else {
2824
- // joins.push({
2825
- // tables: [d.table_name, d.foreign_table_name],
2826
- // on: {
2827
- // [d.column_name]: d.foreign_column_name
2828
- // },
2829
- // type: "many-many"
2830
- // })
2831
- // }
2832
- // });
2833
- // return joins;
2834
- // }