prostgles-server 2.0.188 → 2.0.191

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/insertDataParse.d.ts.map +1 -1
  2. package/dist/DboBuilder/insertDataParse.js +14 -4
  3. package/dist/DboBuilder/insertDataParse.js.map +1 -1
  4. package/dist/DboBuilder.d.ts +5 -3
  5. package/dist/DboBuilder.d.ts.map +1 -1
  6. package/dist/DboBuilder.js +67 -161
  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 +232 -164
  11. package/dist/FileManager.js.map +1 -1
  12. package/dist/Prostgles.d.ts +13 -2
  13. package/dist/Prostgles.d.ts.map +1 -1
  14. package/dist/Prostgles.js.map +1 -1
  15. package/dist/TableConfig.d.ts +1 -2
  16. package/dist/TableConfig.d.ts.map +1 -1
  17. package/dist/TableConfig.js.map +1 -1
  18. package/lib/DboBuilder/insertDataParse.d.ts.map +1 -1
  19. package/lib/DboBuilder/insertDataParse.js +14 -4
  20. package/lib/DboBuilder/insertDataParse.ts +14 -4
  21. package/lib/DboBuilder.d.ts +5 -3
  22. package/lib/DboBuilder.d.ts.map +1 -1
  23. package/lib/DboBuilder.js +67 -161
  24. package/lib/DboBuilder.ts +84 -191
  25. package/lib/FileManager.d.ts +19 -71
  26. package/lib/FileManager.d.ts.map +1 -1
  27. package/lib/FileManager.js +232 -164
  28. package/lib/FileManager.ts +272 -191
  29. package/lib/Prostgles.d.ts +13 -2
  30. package/lib/Prostgles.d.ts.map +1 -1
  31. package/lib/Prostgles.ts +2 -2
  32. package/lib/TableConfig.d.ts +1 -2
  33. package/lib/TableConfig.d.ts.map +1 -1
  34. package/lib/TableConfig.ts +2 -4
  35. package/lib/fileType/core.js +1527 -0
  36. package/lib/fileType/supported.js +278 -0
  37. package/package.json +5 -5
  38. package/tests/client/PID.txt +1 -1
  39. package/tests/server/DBoGenerated.d.ts +1 -1
  40. package/tests/server/package-lock.json +9 -9
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);
@@ -2069,16 +2061,19 @@ class DboBuilder {
2069
2061
  }
2070
2062
  // 3 find incorrect fields
2071
2063
  joins.map(({ tables, on }) => {
2072
- const t1 = tables[0], t2 = tables[1], f1s = Object.keys(on), f2s = Object.values(on);
2073
- [[t1, f1s], [t2, f2s]].map(v => {
2074
- var t = v[0], f = v[1];
2075
- let tov = this.tablesOrViews.find(_t => _t.name === t);
2076
- if (!tov)
2077
- throw "Table not found: " + t;
2078
- const m1 = f.filter(k => !tov.columns.map(c => c.name).includes(k));
2079
- if (m1 && m1.length) {
2080
- throw `Table ${t}(${tov.columns.map(c => c.name).join()}) has no fields named: ${m1.join()}`;
2081
- }
2064
+ const t1 = tables[0], t2 = tables[1];
2065
+ on.map(cond => {
2066
+ const f1s = Object.keys(cond), f2s = Object.values(cond);
2067
+ [[t1, f1s], [t2, f2s]].map(v => {
2068
+ var t = v[0], f = v[1];
2069
+ let tov = this.tablesOrViews.find(_t => _t.name === t);
2070
+ if (!tov)
2071
+ throw "Table not found: " + t;
2072
+ const m1 = f.filter(k => !tov.columns.map(c => c.name).includes(k));
2073
+ if (m1 && m1.length) {
2074
+ throw `Table ${t}(${tov.columns.map(c => c.name).join()}) has no fields named: ${m1.join()}`;
2075
+ }
2076
+ });
2082
2077
  });
2083
2078
  });
2084
2079
  // 4 find incorrect/missing join types
@@ -2125,21 +2120,9 @@ class DboBuilder {
2125
2120
  buildJoinPaths() {
2126
2121
  }
2127
2122
  async build() {
2128
- // await this.pubSubManager.init()
2129
- this.tablesOrViews = await getTablesForSchemaPostgresSQL(this.db); //, this.schema
2130
- // console.log(this.tablesOrViews.map(t => `${t.name} (${t.columns.map(c => c.name).join(", ")})`))
2123
+ this.tablesOrViews = await getTablesForSchemaPostgresSQL(this.db);
2131
2124
  this.constraints = await getConstraints(this.db);
2132
2125
  await this.parseJoins();
2133
- // const common_types =
2134
- // `
2135
- // import { ViewHandler, TableHandler, JoinMaker } from "prostgles-types";
2136
- // export type TxCB = {
2137
- // (t: DBObj): (any | void | Promise<(any | void)>)
2138
- // };
2139
- // `
2140
- // this.dboDefinition = `export type DBObj = {\n`;
2141
- // let joinTableNames: string[] = [];
2142
- // let allDataDefs = "";
2143
2126
  this.tablesOrViews.map(tov => {
2144
2127
  const columnsForTypes = tov.columns.slice(0).sort((a, b) => a.name.localeCompare(b.name));
2145
2128
  const filterKeywords = Object.values(this.prostgles.keywords);
@@ -2149,23 +2132,9 @@ class DboBuilder {
2149
2132
  Please provide a replacement keyword name using the $filter_keyName init option.
2150
2133
  Alternatively you can rename the table column\n`;
2151
2134
  }
2152
- const TSTableDataName = snakify(tov.name, true);
2153
- const TSTableHandlerName = escapeTSNames(tov.name);
2154
- if (tov.is_view) {
2155
- this.dbo[tov.name] = new ViewHandler(this.db, tov, this, undefined, undefined, this.joinPaths);
2156
- // this.dboDefinition += ` ${TSTableHandlerName}: ViewHandler<${TSTableDataName}> \n`;
2157
- }
2158
- else {
2159
- this.dbo[tov.name] = new TableHandler(this.db, tov, this, undefined, undefined, this.joinPaths);
2160
- // this.dboDefinition += ` ${TSTableHandlerName}: TableHandler<${TSTableDataName}> \n`;
2161
- }
2162
- // allDataDefs += `export type ${TSTableDataName} = { \n` +
2163
- // (this.dbo[tov.name] as ViewHandler).tsColumnDefs.map(str => ` ` + str).join("\n") +
2164
- // `\n}\n`;
2165
- // this.dboDefinition += ` ${escapeTSNames(tov.name, false)}: ${(this.dbo[tov.name] as TableHandler).tsDboName};\n`;
2135
+ this.dbo[tov.name] = new (tov.is_view ? ViewHandler : TableHandler)(this.db, tov, this, undefined, undefined, this.joinPaths);
2166
2136
  if (this.joinPaths && this.joinPaths.find(jp => [jp.t1, jp.t2].includes(tov.name))) {
2167
2137
  let table = tov.name;
2168
- // joinTableNames.push(table);
2169
2138
  const makeJoin = (isLeft = true, filter, select, options) => {
2170
2139
  return {
2171
2140
  [isLeft ? "$leftJoin" : "$innerJoin"]: table,
@@ -2192,17 +2161,6 @@ class DboBuilder {
2192
2161
  };
2193
2162
  }
2194
2163
  });
2195
- // let joinBuilderDef = "";
2196
- // if(joinTableNames.length){
2197
- // joinBuilderDef += "export type JoinMakerTables = {\n";
2198
- // joinTableNames.map(tname => {
2199
- // joinBuilderDef += ` ${escapeTSNames(tname)}: JoinMaker<${snakify(tname, true)}>;\n`
2200
- // })
2201
- // joinBuilderDef += "};\n";
2202
- // ["leftJoin", "innerJoin", "leftJoinOne", "innerJoinOne"].map(joinType => {
2203
- // this.dboDefinition += ` ${joinType}: JoinMakerTables;\n`;
2204
- // });
2205
- // }
2206
2164
  if (this.prostgles.opts.transactions) {
2207
2165
  let txKey = "tx";
2208
2166
  if (typeof this.prostgles.opts.transactions === "string")
@@ -2211,7 +2169,7 @@ class DboBuilder {
2211
2169
  this.dbo[txKey] = (cb) => this.getTX(cb);
2212
2170
  }
2213
2171
  if (!this.dbo.sql) {
2214
- let needType = true; // this.publishRawSQL && typeof this.publishRawSQL === "function";
2172
+ let needType = true;
2215
2173
  let DATA_TYPES = !needType ? [] : await this.db.any("SELECT oid, typname FROM pg_type");
2216
2174
  let USER_TABLES = !needType ? [] : await this.db.any("SELECT relid, relname FROM pg_catalog.pg_statio_user_tables");
2217
2175
  this.dbo.sql = async (query, params, options, localParams) => {
@@ -2309,16 +2267,11 @@ class DboBuilder {
2309
2267
  }
2310
2268
  this.dboDefinition += "};\n";
2311
2269
  this.tsTypesDefinition = [
2312
- // common_types,
2313
2270
  `/* SCHEMA DEFINITON. Table names have been altered to work with Typescript */`,
2314
- // allDataDefs,
2315
- // joinBuilderDef,
2316
- `/* DBO Definition. Isomorphic */`,
2317
- // this.dboDefinition,
2271
+ `/* DBO Definition */`,
2318
2272
  (0, DBSchemaBuilder_1.getDBSchema)(this)
2319
2273
  ].join("\n");
2320
2274
  return this.dbo;
2321
- // let dbo = makeDBO(db, allTablesViews, pubSubManager, true);
2322
2275
  }
2323
2276
  }
2324
2277
  exports.DboBuilder = DboBuilder;
@@ -2455,15 +2408,6 @@ async function getTablesForSchemaPostgresSQL(db, schema = "public") {
2455
2408
  `;
2456
2409
  // console.log(pgp.as.format(query, { schema }), schema);
2457
2410
  let res = await db.any(query, { schema });
2458
- // res = await Promise.all(res.map(async tbl => {
2459
- // tbl.columns = await Promise.all(tbl.columns.map(async col => {
2460
- // if(col.has_default){
2461
- // col.column_default = !col.column_default.startsWith("nextval(")? (await db.oneOrNone(`SELECT ${col.column_default} as val`)).val : null;
2462
- // }
2463
- // return col;
2464
- // }))
2465
- // return tbl;
2466
- // }))
2467
2411
  res = res.map(tbl => {
2468
2412
  tbl.columns = tbl.columns.map(col => {
2469
2413
  if (col.has_default) {
@@ -2478,8 +2422,6 @@ async function getTablesForSchemaPostgresSQL(db, schema = "public") {
2478
2422
  }
2479
2423
  /**
2480
2424
  * Throw error if illegal keys found in object
2481
- * @param {Object} obj - Object to be checked
2482
- * @param {string[]} allowedKeys - The name of the employee.
2483
2425
  */
2484
2426
  function validateObj(obj, allowedKeys) {
2485
2427
  if (obj && Object.keys(obj).length) {
@@ -2753,13 +2695,16 @@ function sqlErrCodeToMsg(code) {
2753
2695
  }
2754
2696
  async function getInferredJoins2(schema) {
2755
2697
  let joins = [];
2756
- const upsertJoin = (t1, t2, cols) => {
2698
+ const upsertJoin = (t1, t2, cols, type) => {
2757
2699
  let existingIdx = joins.findIndex(j => j.tables.slice(0).sort().join() === [t1, t2].sort().join());
2758
2700
  let existing = joins[existingIdx];
2759
2701
  const normalCond = cols.reduce((a, v) => ({ ...a, [v.col1]: v.col2 }), {});
2760
2702
  const revertedCond = cols.reduce((a, v) => ({ ...a, [v.col2]: v.col1 }), {});
2761
2703
  if (existing) {
2762
- const cond = existing.tables[0] === t1 ? normalCond : revertedCond;
2704
+ const isLTR = existing.tables[0] === t1;
2705
+ const cond = isLTR ? normalCond : revertedCond;
2706
+ /** At some point we should add relationship type to EACH JOIN CONDITION GROUP */
2707
+ // const fixedType = isLTR? type : type.split("").reverse().join("") as Join["type"];
2763
2708
  /** Avoid duplicates */
2764
2709
  if (!existing.on.some(_cond => JSON.stringify(_cond) === JSON.stringify(cond))) {
2765
2710
  existing.on.push(cond);
@@ -2770,7 +2715,7 @@ async function getInferredJoins2(schema) {
2770
2715
  joins.push({
2771
2716
  tables: [t1, t2],
2772
2717
  on: [normalCond],
2773
- type: "many-many"
2718
+ type
2774
2719
  });
2775
2720
  }
2776
2721
  };
@@ -2778,54 +2723,15 @@ async function getInferredJoins2(schema) {
2778
2723
  tov.columns.map(col => {
2779
2724
  if (col.references) {
2780
2725
  const r = col.references;
2781
- upsertJoin(tov.name, r.ftable, r.cols.map((c, i) => ({ col1: c, col2: r.fcols[i] })));
2726
+ const joinCols = r.cols.map((c, i) => ({ col1: c, col2: r.fcols[i] }));
2727
+ let type = "one-many";
2728
+ const ftablePkeys = schema.find(_tov => _tov.name === r.ftable)?.columns.filter(fcol => fcol.is_pkey);
2729
+ if (ftablePkeys?.length && ftablePkeys.every(fkey => r.fcols.includes(fkey.name))) {
2730
+ type = "one-one";
2731
+ }
2732
+ upsertJoin(tov.name, r.ftable, joinCols, type);
2782
2733
  }
2783
2734
  });
2784
2735
  });
2785
2736
  return joins;
2786
2737
  }
2787
- // async function getInferredJoins(db: DB, schema: string = "public"): Promise<Join[]>{
2788
- // let joins: Join[] = [];
2789
- // let res = await db.any(`SELECT
2790
- // tc.table_schema,
2791
- // tc.constraint_name,
2792
- // tc.table_name,
2793
- // kcu.column_name,
2794
- // ccu.table_schema AS foreign_table_schema,
2795
- // ccu.table_name AS foreign_table_name,
2796
- // ccu.column_name AS foreign_column_name,
2797
- // tc.constraint_type IN ('UNIQUE', 'PRIMARY KEY') as foreign_is_unique
2798
- // FROM
2799
- // information_schema.table_constraints AS tc
2800
- // JOIN information_schema.key_column_usage AS kcu
2801
- // ON tc.constraint_name = kcu.constraint_name
2802
- // AND tc.table_schema = kcu.table_schema
2803
- // JOIN information_schema.constraint_column_usage AS ccu
2804
- // ON ccu.constraint_name = tc.constraint_name
2805
- // AND ccu.table_schema = tc.table_schema
2806
- // WHERE tc.table_schema=` + "${schema}" + `
2807
- // AND tc.constraint_type = 'FOREIGN KEY'
2808
- // AND tc.table_name <> ccu.table_name -- Exclude self-referencing tables
2809
- // `, { schema });
2810
- // res.map((d: any) => {
2811
- // let eIdx = joins.findIndex(j => j.tables.includes(d.table_name) && j.tables.includes(d.foreign_table_name));
2812
- // let existing = joins[eIdx];
2813
- // if(existing){
2814
- // if(existing.tables[0] === d.table_name){
2815
- // existing.on = { ...existing.on, [d.column_name]: d.foreign_column_name }
2816
- // } else {
2817
- // existing.on = { ...existing.on, [d.foreign_column_name]: d.column_name }
2818
- // }
2819
- // joins[eIdx] = existing;
2820
- // } else {
2821
- // joins.push({
2822
- // tables: [d.table_name, d.foreign_table_name],
2823
- // on: {
2824
- // [d.column_name]: d.foreign_column_name
2825
- // },
2826
- // type: "many-many"
2827
- // })
2828
- // }
2829
- // });
2830
- // return joins;
2831
- // }