prostgles-server 2.0.144 → 2.0.147

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 (77) hide show
  1. package/dist/AuthHandler.d.ts +15 -13
  2. package/dist/AuthHandler.d.ts.map +1 -1
  3. package/dist/AuthHandler.js +41 -43
  4. package/dist/AuthHandler.js.map +1 -1
  5. package/dist/DBEventsManager.d.ts +6 -5
  6. package/dist/DBEventsManager.d.ts.map +1 -1
  7. package/dist/DBEventsManager.js +8 -2
  8. package/dist/DBEventsManager.js.map +1 -1
  9. package/dist/DboBuilder.d.ts +62 -50
  10. package/dist/DboBuilder.d.ts.map +1 -1
  11. package/dist/DboBuilder.js +229 -170
  12. package/dist/DboBuilder.js.map +1 -1
  13. package/dist/FileManager.d.ts +5 -5
  14. package/dist/FileManager.d.ts.map +1 -1
  15. package/dist/FileManager.js +48 -21
  16. package/dist/FileManager.js.map +1 -1
  17. package/dist/Filtering.d.ts.map +1 -1
  18. package/dist/Filtering.js +11 -9
  19. package/dist/Filtering.js.map +1 -1
  20. package/dist/PostgresNotifListenManager.d.ts +3 -3
  21. package/dist/PostgresNotifListenManager.d.ts.map +1 -1
  22. package/dist/PostgresNotifListenManager.js +7 -5
  23. package/dist/PostgresNotifListenManager.js.map +1 -1
  24. package/dist/Prostgles.d.ts +6 -9
  25. package/dist/Prostgles.d.ts.map +1 -1
  26. package/dist/Prostgles.js +122 -83
  27. package/dist/Prostgles.js.map +1 -1
  28. package/dist/PubSubManager.d.ts +9 -9
  29. package/dist/PubSubManager.d.ts.map +1 -1
  30. package/dist/PubSubManager.js +10 -9
  31. package/dist/PubSubManager.js.map +1 -1
  32. package/dist/QueryBuilder.d.ts +26 -8
  33. package/dist/QueryBuilder.d.ts.map +1 -1
  34. package/dist/QueryBuilder.js +114 -46
  35. package/dist/QueryBuilder.js.map +1 -1
  36. package/dist/SyncReplication.d.ts +1 -1
  37. package/dist/SyncReplication.d.ts.map +1 -1
  38. package/dist/SyncReplication.js +31 -29
  39. package/dist/SyncReplication.js.map +1 -1
  40. package/dist/TableConfig.d.ts +0 -1
  41. package/dist/TableConfig.d.ts.map +1 -1
  42. package/dist/TableConfig.js +25 -17
  43. package/dist/TableConfig.js.map +1 -1
  44. package/dist/shortestPath.d.ts.map +1 -1
  45. package/dist/shortestPath.js.map +1 -1
  46. package/dist/utils.d.ts +2 -0
  47. package/dist/utils.d.ts.map +1 -1
  48. package/dist/utils.js +6 -0
  49. package/dist/utils.js.map +1 -1
  50. package/lib/AuthHandler.ts +50 -40
  51. package/lib/DBEventsManager.ts +14 -7
  52. package/lib/DboBuilder.ts +265 -199
  53. package/lib/FileManager.ts +30 -21
  54. package/lib/Filtering.ts +19 -16
  55. package/lib/PostgresNotifListenManager.ts +11 -10
  56. package/lib/Prostgles.ts +89 -73
  57. package/lib/PubSubManager.ts +13 -11
  58. package/lib/QueryBuilder.ts +135 -54
  59. package/lib/SyncReplication.ts +10 -10
  60. package/lib/TableConfig.ts +23 -15
  61. package/lib/shortestPath.ts +6 -4
  62. package/lib/utils.ts +7 -1
  63. package/package.json +7 -8
  64. package/tests/client/PID.txt +1 -1
  65. package/tests/client/index.js +10 -7
  66. package/tests/client/index.ts +12 -8
  67. package/tests/client/package-lock.json +14 -14
  68. package/tests/client/package.json +2 -2
  69. package/tests/client/tsconfig.json +2 -2
  70. package/tests/client_only_queries.js +127 -104
  71. package/tests/client_only_queries.ts +43 -17
  72. package/tests/isomorphic_queries.js +44 -6
  73. package/tests/isomorphic_queries.ts +42 -6
  74. package/tests/server/package-lock.json +27 -29
  75. package/tests/server/package.json +2 -2
  76. package/tests/server/tsconfig.json +2 -2
  77. package/tsconfig.json +3 -2
package/lib/Prostgles.ts CHANGED
@@ -16,7 +16,7 @@ console.log("Add a basic auth mode where user and sessions table are created");
16
16
  import TableConfigurator, { TableConfig } from "./TableConfig";
17
17
 
18
18
  import { get } from "./utils";
19
- import { DboBuilder, DbHandler, TableHandler, ViewHandler, isPlainObject, LocalParams, CommonTableRules, TableSchema, PRGLIOSocket } from "./DboBuilder";
19
+ import { DboBuilder, DbHandler, TableHandler, ViewHandler, isPlainObject, LocalParams, CommonTableRules, TableSchema, PRGLIOSocket, getKeys } from "./DboBuilder";
20
20
  import { PubSubManager, DEFAULT_SYNC_BATCH_SIZE, asValue } from "./PubSubManager";
21
21
  export { DbHandler }
22
22
  export type PGP = pgPromise.IMain<{}, pg.IClient>;
@@ -28,8 +28,7 @@ import { DBEventsManager } from "./DBEventsManager";
28
28
  export type DB = pgPromise.IDatabase<{}, pg.IClient>;
29
29
  type DbConnection = string | pg.IConnectionParameters<pg.IClient>;
30
30
  type DbConnectionOpts = pg.IDefaults;
31
-
32
- let currConnection: { db: DB, pgp: PGP };
31
+ const TABLE_METHODS = ["update", "find", "findOne", "insert", "delete", "upsert"];
33
32
  function getDbConnection(dbConnection: DbConnection, options: DbConnectionOpts | undefined, debugQueries = false, onNotice: ProstglesInitOptions["onNotice"]): { db: DB, pgp: PGP } {
34
33
  let pgp: PGP = pgPromise({
35
34
 
@@ -398,8 +397,8 @@ export type ProstglesInitOptions<DBO = DbHandler> = {
398
397
  onReady(dbo: DBO, db: DB): void;
399
398
  transactions?: string | boolean;
400
399
  wsChannelNamePrefix?: string;
401
- onSocketConnect?(socket: Socket, dbo: DBO, db?: DB): any;
402
- onSocketDisconnect?(socket: Socket, dbo: DBO, db?: DB): any;
400
+ onSocketConnect?(socket: PRGLIOSocket, dbo: DBO, db?: DB): any;
401
+ onSocketDisconnect?(socket: PRGLIOSocket, dbo: DBO, db?: DB): any;
403
402
  auth?: Auth<DBO>;
404
403
  DEBUG_MODE?: boolean;
405
404
  watchSchemaType?:
@@ -673,7 +672,8 @@ export class Prostgles<DBO = DbHandler> {
673
672
  this.isSuperUser = await isSuperUser(db);
674
673
  }
675
674
  this.checkDb();
676
- const { db, pgp } = this;
675
+ const db = this.db!;
676
+ const pgp = this.pgp!;
677
677
 
678
678
  /* 2. Execute any SQL file if provided */
679
679
  if(this.opts.sqlFilePath){
@@ -722,7 +722,7 @@ export class Prostgles<DBO = DbHandler> {
722
722
  this.authHandler = new AuthHandler(this as any);
723
723
  await this.authHandler.init();
724
724
 
725
- this.publishParser = new PublishParser(this.opts.publish, this.opts.publishMethods, this.opts.publishRawSQL, this.dbo, this.db, this as any);
725
+ this.publishParser = new PublishParser(this.opts.publish, this.opts.publishMethods, this.opts.publishRawSQL, this.dbo!, this.db, this as any);
726
726
  this.dboBuilder.publishParser = this.publishParser;
727
727
 
728
728
  /* 4. Set publish and auth listeners */
@@ -751,7 +751,7 @@ export class Prostgles<DBO = DbHandler> {
751
751
 
752
752
  this.loaded = true;
753
753
  return {
754
- db: this.dbo,
754
+ db: this.dbo!,
755
755
  _db: db,
756
756
  pgp,
757
757
  io: this.opts.io,
@@ -778,6 +778,7 @@ export class Prostgles<DBO = DbHandler> {
778
778
  };
779
779
  } catch (e) {
780
780
  console.trace(e)
781
+ // @ts-ignore
781
782
  throw "init issues: " + e.toString();
782
783
  }
783
784
  }
@@ -786,7 +787,7 @@ export class Prostgles<DBO = DbHandler> {
786
787
 
787
788
  const fileContent = await this.getFileText(filePath);//.then(console.log);
788
789
 
789
- return this.db.multi(fileContent).then((data)=>{
790
+ return this.db?.multi(fileContent).then((data)=>{
790
791
  console.log("Prostgles: SQL file executed successfuly \n -> " + filePath);
791
792
  return data
792
793
  }).catch((err) => {
@@ -814,7 +815,7 @@ export class Prostgles<DBO = DbHandler> {
814
815
 
815
816
  if(!this.dbo) throw "dbo missing";
816
817
 
817
- let publishParser = new PublishParser(this.opts.publish, this.opts.publishMethods, this.opts.publishRawSQL, this.dbo, this.db, this as any);
818
+ let publishParser = new PublishParser(this.opts.publish, this.opts.publishMethods, this.opts.publishRawSQL, this.dbo, this.db!, this as any);
818
819
  this.publishParser = publishParser;
819
820
 
820
821
  if(!this.opts.io) return;
@@ -829,7 +830,7 @@ export class Prostgles<DBO = DbHandler> {
829
830
  }
830
831
 
831
832
  /* Initialise */
832
- this.opts.io.on('connection', async (socket) => {
833
+ this.opts.io.on('connection', async (socket: PRGLIOSocket) => {
833
834
  if(this.destroyed){
834
835
  console.log("Socket connected to destroyed instance");
835
836
  socket.disconnect();
@@ -848,18 +849,19 @@ export class Prostgles<DBO = DbHandler> {
848
849
  Checks request against publish and if OK run it with relevant publish functions. Local (server) requests do not check the policy
849
850
  */
850
851
  socket.removeAllListeners(CHANNELS.DEFAULT)
851
- socket.on(CHANNELS.DEFAULT, async ({ tableName, command, param1, param2, param3 }: SocketRequestParams, cb = (...callback) => {} ) => {
852
+ socket.on(CHANNELS.DEFAULT, async ({ tableName, command, param1, param2, param3 }: SocketRequestParams, cb = (...callback: any[]) => {} ) => {
852
853
 
853
854
  try { /* Channel name will only include client-sent params so we ignore table_rules enforced params */
854
- if(!socket) {
855
- console.error("socket missing??!!")
856
- throw "socket missing??!!";
855
+ if(!socket || !this.authHandler || !this.publishParser || !this.dbo) {
856
+ console.error("socket or authhandler missing??!!")
857
+ throw "socket or authhandler missing??!!";
857
858
  }
858
859
 
859
860
  const clientInfo = await this.authHandler.getClientInfo({ socket });
860
861
  let valid_table_command_rules = await this.publishParser.getValidatedRequestRule({ tableName, command, localParams: { socket } }, clientInfo);
861
862
  if(valid_table_command_rules){
862
- let res = await this.dbo[tableName][command](param1, param2, param3, valid_table_command_rules, { socket, has_rules: true });
863
+ //@ts-ignore
864
+ let res = await this.dbo[tableName][command]!(param1, param2, param3, valid_table_command_rules, { socket, has_rules: true });
863
865
  cb(null, res);
864
866
  } else throw `Invalid OR disallowed request: ${tableName}.${command} `;
865
867
 
@@ -873,8 +875,8 @@ export class Prostgles<DBO = DbHandler> {
873
875
  });
874
876
 
875
877
  socket.on("disconnect", () => {
876
- this.dbEventsManager.removeNotice(socket);
877
- this.dbEventsManager.removeNotify(socket);
878
+ this.dbEventsManager?.removeNotice(socket);
879
+ this.dbEventsManager?.removeNotify(undefined, socket);
878
880
  this.connectedSockets = this.connectedSockets.filter(s => s.id !== socket.id);
879
881
  // subscriptions = subscriptions.filter(sub => sub.socket.id !== socket.id);
880
882
  if(this.opts.onSocketDisconnect){
@@ -883,9 +885,9 @@ export class Prostgles<DBO = DbHandler> {
883
885
  });
884
886
 
885
887
  socket.removeAllListeners(CHANNELS.METHOD)
886
- socket.on(CHANNELS.METHOD, async ({ method, params }: SocketMethodRequest, cb = (...callback) => {} ) => {
888
+ socket.on(CHANNELS.METHOD, async ({ method, params }: SocketMethodRequest, cb = (...callback: any) => {} ) => {
887
889
  try {
888
- const methods = await this.publishParser.getMethods(socket);
890
+ const methods = await this.publishParser?.getMethods(socket) as any;
889
891
 
890
892
  if(!methods || !methods[method]){
891
893
  cb("Disallowed/missing method " + JSON.stringify(method));
@@ -924,7 +926,7 @@ export class Prostgles<DBO = DbHandler> {
924
926
 
925
927
  const { dbo, db, pgp, publishParser } = this;
926
928
  try {
927
- schema = await publishParser.getSchemaFromPublish(socket);
929
+ schema = await publishParser?.getSchemaFromPublish(socket);
928
930
  } catch(e){
929
931
  publishValidationError = "Server Error: PUBLISH VALIDATION ERROR";
930
932
  console.error(`\nProstgles PUBLISH VALIDATION ERROR (after socket connected):\n ->`, e);
@@ -934,19 +936,19 @@ export class Prostgles<DBO = DbHandler> {
934
936
  /* RUN Raw sql from client IF PUBLISHED
935
937
  */
936
938
  let fullSchema: TableSchema[] = [];
937
- let allTablesViews = this.dboBuilder.tablesOrViews;
939
+ let allTablesViews = this.dboBuilder.tablesOrViews ?? [];
938
940
  if(this.opts.publishRawSQL && typeof this.opts.publishRawSQL === "function"){
939
941
  const canRunSQL = async () => {
940
- const publishParams = await this.publishParser.getPublishParams({ socket })
941
- let res = await this.opts.publishRawSQL(publishParams as any);
942
+ const publishParams = await this.publishParser?.getPublishParams({ socket })
943
+ let res = await this.opts.publishRawSQL?.(publishParams as any);
942
944
  return Boolean(res && typeof res === "boolean" || res === "*");
943
945
  }
944
946
 
945
947
  if(await canRunSQL()){
946
948
  socket.removeAllListeners(CHANNELS.SQL)
947
- socket.on(CHANNELS.SQL, async ({ query, params, options }: SQLRequest, cb = (...callback) => {}) => {
949
+ socket.on(CHANNELS.SQL, async ({ query, params, options }: SQLRequest, cb = (...callback: any) => {}) => {
948
950
 
949
- if(!this.dbo.sql) throw "Internal error: sql handler missing";
951
+ if(!this.dbo?.sql) throw "Internal error: sql handler missing";
950
952
 
951
953
  this.dbo.sql(query, params, options, { socket }).then(res => {
952
954
  cb(null, res)
@@ -963,7 +965,7 @@ export class Prostgles<DBO = DbHandler> {
963
965
  }
964
966
 
965
967
  // let joinTables = [];
966
- let joinTables2 = [];
968
+ let joinTables2: string[][] = [];
967
969
  if(this.opts.joins){
968
970
  // joinTables = Array.from(new Set(flat(this.dboBuilder.getJoins().map(j => j.tables)).filter(t => schema[t])));
969
971
  let _joinTables2 = this.dboBuilder.getJoinPaths()
@@ -977,11 +979,11 @@ export class Prostgles<DBO = DbHandler> {
977
979
  });
978
980
  }
979
981
 
980
- const methods = await publishParser.getMethods(socket);
982
+ const methods = await publishParser?.getMethods(socket);
981
983
 
982
984
  socket.emit(CHANNELS.SCHEMA, {
983
985
  schema,
984
- methods: Object.keys(methods),
986
+ methods: getKeys(methods),
985
987
  ...(fullSchema? { fullSchema } : {}),
986
988
  rawSQL,
987
989
  joinTables: joinTables2,
@@ -991,19 +993,19 @@ export class Prostgles<DBO = DbHandler> {
991
993
  });
992
994
  }
993
995
  }
994
- function makeSocketError(cb, err){
996
+ function makeSocketError(cb: Function, err: any){
995
997
  const err_msg = (err instanceof Error)?
996
998
  err.toString() :
997
999
  isPlainObject(err)?
998
1000
  JSON.stringify(err, null, 2) :
999
- err.toString(),
1001
+ (err as any).toString(),
1000
1002
  e = { err_msg, err };
1001
1003
  cb(e);
1002
1004
  }
1003
1005
 
1004
1006
  type SocketRequestParams = {
1005
1007
  tableName: string;
1006
- command: string;
1008
+ command: typeof TABLE_METHODS[number];
1007
1009
  param1: any;
1008
1010
  param2: any;
1009
1011
  param3: any;
@@ -1014,11 +1016,6 @@ type SocketMethodRequest = {
1014
1016
  }
1015
1017
 
1016
1018
 
1017
- type callback = {
1018
- (err: { err: any, err_msg: string }, res: any)
1019
- }
1020
-
1021
-
1022
1019
  type Request = {
1023
1020
  socket?: any;
1024
1021
  httpReq?: any;
@@ -1112,14 +1109,14 @@ const RULE_TO_METHODS = [
1112
1109
  // const ALL_PUBLISH_METHODS = ["update", "upsert", "delete", "insert", "find", "findOne", "subscribe", "unsubscribe", "sync", "unsync", "remove"];
1113
1110
  // const ALL_PUBLISH_METHODS = RULE_TO_METHODS.map(r => r.methods).flat();
1114
1111
 
1115
- export function flat(arr){
1116
- // let res = arr.reduce((acc, val) => [ ...acc, ...val ], []);
1117
- let res = arr.reduce(function (farr, toFlatten) {
1118
- return farr.concat(Array.isArray(toFlatten) ? flat(toFlatten) : toFlatten);
1119
- }, []);
1112
+ // export function flat(arr){
1113
+ // // let res = arr.reduce((acc, val) => [ ...acc, ...val ], []);
1114
+ // let res = arr.reduce(function (farr, toFlatten) {
1115
+ // return farr.concat(Array.isArray(toFlatten) ? flat(toFlatten) : toFlatten);
1116
+ // }, []);
1120
1117
 
1121
- return res;
1122
- }
1118
+ // return res;
1119
+ // }
1123
1120
 
1124
1121
  export class PublishParser {
1125
1122
  publish: any;
@@ -1142,10 +1139,10 @@ export class PublishParser {
1142
1139
 
1143
1140
  async getPublishParams(localParams: LocalParams, clientInfo?: ClientInfo): Promise<PublishParams> {
1144
1141
  return {
1145
- ...(clientInfo || await this.prostgles.authHandler.getClientInfo(localParams)),
1142
+ ...(clientInfo || await this.prostgles.authHandler?.getClientInfo(localParams)),
1146
1143
  dbo: this.dbo,
1147
1144
  db: this.db,
1148
- socket: localParams.socket
1145
+ socket: localParams.socket!
1149
1146
  }
1150
1147
  }
1151
1148
 
@@ -1156,8 +1153,9 @@ export class PublishParser {
1156
1153
  const _methods = await applyParamsIfFunc(this.publishMethods, publishParams);
1157
1154
 
1158
1155
  if(_methods && Object.keys(_methods).length){
1159
- Object.keys(_methods).map(key => {
1156
+ getKeys(_methods).map(key => {
1160
1157
  if(_methods[key] && (typeof _methods[key] === "function" || typeof _methods[key].then === "function")){
1158
+ //@ts-ignore
1161
1159
  methods[key] = _methods[key];
1162
1160
  } else {
1163
1161
  throw `invalid publishMethods item -> ${key} \n Expecting a function or promise`
@@ -1178,8 +1176,8 @@ export class PublishParser {
1178
1176
  let _publish = await applyParamsIfFunc(this.publish, publishParams );
1179
1177
 
1180
1178
  if(_publish === "*"){
1181
- let publish = {}
1182
- this.prostgles.dboBuilder.tablesOrViews.map(tov => {
1179
+ let publish = {} as any;
1180
+ this.prostgles.dboBuilder.tablesOrViews?.map(tov => {
1183
1181
  publish[tov.name] = "*";
1184
1182
  });
1185
1183
  return publish;
@@ -1188,11 +1186,11 @@ export class PublishParser {
1188
1186
  return _publish;
1189
1187
  }
1190
1188
  async getValidatedRequestRuleWusr({ tableName, command, localParams }: DboTableCommand): Promise<TableRule>{
1191
- const clientInfo = await this.prostgles.authHandler.getClientInfo(localParams);
1189
+ const clientInfo = await this.prostgles.authHandler!.getClientInfo(localParams);
1192
1190
  return await this.getValidatedRequestRule({ tableName, command, localParams }, clientInfo);
1193
1191
  }
1194
1192
 
1195
- async getValidatedRequestRule({ tableName, command, localParams }: DboTableCommand, clientInfo: ClientInfo): Promise<TableRule>{
1193
+ async getValidatedRequestRule({ tableName, command, localParams }: DboTableCommand, clientInfo?: ClientInfo): Promise<TableRule>{
1196
1194
  if(!this.dbo) throw "INTERNAL ERROR: dbo is missing";
1197
1195
 
1198
1196
  if(!command || !tableName) throw "command OR tableName are missing";
@@ -1233,7 +1231,7 @@ export class PublishParser {
1233
1231
  } else throw `Invalid or disallowed command: ${tableName}.${command}`;
1234
1232
  }
1235
1233
 
1236
- async getTableRules({ tableName, localParams }: DboTable, clientInfo: ClientInfo): Promise<PublishTable> {
1234
+ async getTableRules({ tableName, localParams }: DboTable, clientInfo?: ClientInfo): Promise<PublishTable> {
1237
1235
 
1238
1236
  try {
1239
1237
  if(!localParams || !tableName) throw "publish OR socket OR dbo OR tableName are missing";
@@ -1259,7 +1257,8 @@ export class PublishParser {
1259
1257
  if(
1260
1258
  tHandler.tableOrViewInfo.privileges[r.sqlRule]
1261
1259
  ){
1262
- table_rules[r.rule] = { ...r.no_limits };
1260
+ // @ts-ignore
1261
+ table_rules[r.rule] = { ...(r as any).no_limits } as any;
1263
1262
  }
1264
1263
 
1265
1264
 
@@ -1270,19 +1269,25 @@ export class PublishParser {
1270
1269
  /* Add missing implied rules */
1271
1270
  MY_RULES.map(r => {
1272
1271
 
1273
- if(["getInfo", "getColumns"].includes(r.rule) && ![null, false, 0].includes(table_rules[r.rule])){
1272
+ if(["getInfo", "getColumns"].includes(r.rule) && ![null, false, 0].includes((table_rules as any)[r.rule])){
1273
+ // @ts-ignore
1274
1274
  table_rules[r.rule] = r.no_limits;
1275
1275
  return ;
1276
1276
  }
1277
1277
 
1278
1278
  /* Add nested properties for fully allowed rules */
1279
+ // @ts-ignore
1279
1280
  if ([true, "*"].includes(table_rules[r.rule]) && r.no_limits) {
1281
+ // @ts-ignore
1280
1282
  table_rules[r.rule] = Object.assign({}, r.no_limits);
1281
1283
  }
1282
1284
 
1285
+ // @ts-ignore
1283
1286
  if(table_rules[r.rule]){
1284
1287
  /* Add implied methods if not falsy */
1285
- (r.methods as any).map(method => {
1288
+ // @ts-ignore
1289
+ r.methods.forEach(method => {
1290
+ // @ts-ignore
1286
1291
  if(table_rules[method] === undefined){
1287
1292
  const publishedTable = (table_rules as PublishTable);
1288
1293
  if(method === "updateBatch" && !publishedTable.update){
@@ -1290,6 +1295,7 @@ export class PublishParser {
1290
1295
  } else if(method === "upsert" && (!publishedTable.update || !publishedTable.insert)){
1291
1296
  // return;
1292
1297
  } else {
1298
+ // @ts-ignore
1293
1299
  table_rules[method] = {};
1294
1300
  }
1295
1301
  }
@@ -1302,51 +1308,61 @@ export class PublishParser {
1302
1308
  Add defaults
1303
1309
  Check for invalid params
1304
1310
  */
1305
- if(Object.keys(table_rules).length){
1306
- const ruleKeys = Object.keys(table_rules)
1311
+ if(table_rules && getKeys(table_rules).length && table_rules !== "*"){
1312
+ const ruleKeys = getKeys(table_rules as PublishTableRule | PublishViewRule)
1307
1313
 
1314
+ // @ts-ignore
1308
1315
  ruleKeys.filter(m => table_rules[m])
1309
1316
  .find(method => {
1310
1317
  let rm = MY_RULES.find(r => r.rule === method || (r.methods as any).includes(method));
1311
1318
  if(!rm){
1312
- throw `Invalid rule in publish.${tableName} -> ${method} \nExpecting any of: ${flat(MY_RULES.map(r => [r.rule, ...r.methods])).join(", ")}`;
1319
+ throw `Invalid rule in publish.${tableName} -> ${method} \nExpecting any of: ${MY_RULES.flatMap(r => [r.rule, ...r.methods]).join(", ")}`;
1313
1320
  }
1314
1321
 
1315
1322
  /** Check user privileges */
1316
1323
  if(!tHandler.tableOrViewInfo.privileges[rm.sqlRule]){
1317
- delete table_rules[method];
1324
+ // @ts-ignore
1325
+ delete table_rules![method];
1318
1326
  return;
1319
1327
  }
1320
1328
 
1321
1329
  /* Check RULES for invalid params */
1322
1330
  /* Methods do not have params -> They use them from rules */
1323
1331
  if(method === rm.rule){
1324
- let method_params = Object.keys(table_rules[method]);
1325
- let iparam = method_params.find(p => !rm.allowed_params.includes(<never>p));
1332
+ // @ts-ignore
1333
+ let method_params = getKeys(table_rules![method]);
1334
+ let iparam = method_params.find(p => !rm?.allowed_params.includes(<never>p));
1326
1335
  if(iparam){
1327
1336
  throw `Invalid setting in publish.${tableName}.${method} -> ${iparam}. \n Expecting any of: ${rm.allowed_params.join(", ")}`;
1328
1337
  }
1329
1338
  }
1330
1339
 
1331
1340
  /* Add default params (if missing) */
1341
+ // @ts-ignore
1332
1342
  if(method === "sync"){
1333
1343
 
1334
- if([true, "*"].includes(table_rules[method])){
1344
+ // @ts-ignore
1345
+ if([true, "*"].includes(table_rules![method])){
1335
1346
  throw "Invalid sync rule. Expecting { id_fields: string[], synced_field: string } ";
1336
1347
  }
1337
1348
  if(typeof get(table_rules, [method, "throttle"]) !== "number"){
1338
- table_rules[method].throttle = 100;
1349
+ // @ts-ignore
1350
+ table_rules![method].throttle = 100;
1339
1351
  }
1340
1352
  if(typeof get(table_rules, [method, "batch_size"]) !== "number"){
1341
- table_rules[method].batch_size = DEFAULT_SYNC_BATCH_SIZE;
1353
+ // @ts-ignore
1354
+ table_rules![method].batch_size = DEFAULT_SYNC_BATCH_SIZE;
1342
1355
  }
1343
1356
  }
1344
1357
 
1345
1358
  /* Enable subscribe if not explicitly disabled */
1359
+ // @ts-ignore
1346
1360
  if(method === "select" && !ruleKeys.includes("subscribe")){
1347
1361
  const sr = MY_RULES.find(r => r.rule === "subscribe");
1348
1362
  if(sr){
1363
+ // @ts-ignore
1349
1364
  table_rules[sr.rule] = { ...sr.no_limits };
1365
+ // @ts-ignore
1350
1366
  (table_rules as PublishTable).subscribeOne = { ...sr.no_limits };
1351
1367
  }
1352
1368
  }
@@ -1364,11 +1380,11 @@ export class PublishParser {
1364
1380
 
1365
1381
  /* Prepares schema for client. Only allowed views and commands will be present */
1366
1382
  async getSchemaFromPublish(socket: any): Promise<AnyObject> {
1367
- let schema = {};
1383
+ let schema: AnyObject = {};
1368
1384
 
1369
1385
  try {
1370
1386
  /* Publish tables and views based on socket */
1371
- const clientInfo = await this.prostgles.authHandler.getClientInfo({ socket });
1387
+ const clientInfo = await this.prostgles.authHandler?.getClientInfo({ socket });
1372
1388
  let _publish = await this.getPublish(socket, clientInfo);
1373
1389
 
1374
1390
 
@@ -1383,7 +1399,7 @@ export class PublishParser {
1383
1399
  .map(async tableName => {
1384
1400
  if(!this.dbo[tableName]) {
1385
1401
  throw `Table ${tableName} does not exist
1386
- Expecting one of: ${this.prostgles.dboBuilder.tablesOrViews.map(tov => tov.name).join(", ")}
1402
+ Expecting one of: ${this.prostgles.dboBuilder.tablesOrViews?.map(tov => tov.name).join(", ")}
1387
1403
  DBO tables: ${Object.keys(this.dbo).filter(k => (this.dbo[k] as any).find).join(", ")}
1388
1404
  `;
1389
1405
  }
@@ -1393,13 +1409,13 @@ export class PublishParser {
1393
1409
  // if(tableName === "insert_rule") throw {table_rules}
1394
1410
  if(table_rules && Object.keys(table_rules).length){
1395
1411
  schema[tableName] = {};
1396
- let methods = [];
1412
+ let methods: Array<typeof TABLE_METHODS[number]> = [];
1397
1413
 
1398
1414
  if(typeof table_rules === "object"){
1399
- methods = Object.keys(table_rules);
1415
+ methods = getKeys(table_rules) as any;
1400
1416
  }
1401
1417
 
1402
- await Promise.all(methods.filter(m => m !== "select").map(async method => {
1418
+ await Promise.all(methods.filter(m => m !== "select" as any).map(async method => {
1403
1419
  if(method === "sync" && table_rules[method]){
1404
1420
 
1405
1421
  /* Pass sync info */
@@ -1409,12 +1425,12 @@ export class PublishParser {
1409
1425
  schema[tableName][method] = {};
1410
1426
 
1411
1427
  /* Test for issues with the publish rules */
1412
- if(["update", "find", "findOne", "insert", "delete", "upsert"].includes(method)){
1428
+ if(TABLE_METHODS.includes(method)){
1413
1429
 
1414
1430
  let err = null;
1415
1431
  try {
1416
1432
  let valid_table_command_rules = await this.getValidatedRequestRule({ tableName, command: method, localParams: {socket} }, clientInfo);
1417
- await this.dbo[tableName][method]({}, {}, {}, valid_table_command_rules, { socket, has_rules: true, testRule: true });
1433
+ await (this.dbo[tableName] as any)[method]({}, {}, {}, valid_table_command_rules, { socket, has_rules: true, testRule: true });
1418
1434
 
1419
1435
  } catch(e) {
1420
1436
  err = "INTERNAL PUBLISH ERROR";
@@ -1461,7 +1477,7 @@ export async function isSuperUser(db: DB): Promise<boolean>{
1461
1477
  }
1462
1478
 
1463
1479
 
1464
- function sleep(ms) {
1480
+ function sleep(ms: number) {
1465
1481
  return new Promise((resolve) => {
1466
1482
  setTimeout(resolve, ms);
1467
1483
  });
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { PostgresNotifListenManager } from "./PostgresNotifListenManager";
7
7
  import { get } from "./utils";
8
- import { TableOrViewInfo, TableInfo, DbHandler, TableHandler, DboBuilder } from "./DboBuilder";
8
+ import { TableOrViewInfo, TableInfo, DbHandler, TableHandler, DboBuilder, PRGLIOSocket } from "./DboBuilder";
9
9
  import { TableRule, DB, isSuperUser } from "./Prostgles";
10
10
 
11
11
  import * as Bluebird from "bluebird";
@@ -57,7 +57,7 @@ type AddSyncParams = {
57
57
  table_info: TableInfo;
58
58
  table_rules: TableRule;
59
59
  synced_field: string;
60
- allow_delete: boolean;
60
+ allow_delete?: boolean;
61
61
  id_fields: string[];
62
62
  filter: object;
63
63
  params: {
@@ -68,12 +68,12 @@ type AddSyncParams = {
68
68
  }
69
69
 
70
70
  type SubscriptionParams = {
71
- socket_id: string;
71
+ socket_id?: string;
72
72
  channel_name: string;
73
73
  table_name: string;
74
- socket: any;
74
+ socket: PRGLIOSocket | undefined;
75
75
  table_info: TableOrViewInfo;
76
- table_rules: TableRule;
76
+ table_rules?: TableRule;
77
77
  filter: object;
78
78
  params: SelectParams;
79
79
  func?: (data: any) => any;
@@ -1106,7 +1106,9 @@ export class PubSubManager {
1106
1106
  sub.last_throttled = Date.now();
1107
1107
 
1108
1108
  if(err){
1109
- this.sockets[socket_id].emit(channel_name, { err });
1109
+ if(socket_id){
1110
+ this.sockets[socket_id].emit(channel_name, { err });
1111
+ }
1110
1112
  return true;
1111
1113
  }
1112
1114
 
@@ -1115,7 +1117,7 @@ export class PubSubManager {
1115
1117
  // this.dbo[table_name][subOne? "findOne" : "find"](filter, params, null, table_rules)
1116
1118
  if(!this.dbo?.[table_name]?.find) throw "1107 this.dbo[table_name].find";
1117
1119
 
1118
- this.dbo?.[table_name]?.find?.(filter, params, null, table_rules)
1120
+ this.dbo?.[table_name]?.find?.(filter, params, undefined, table_rules)
1119
1121
  .then(data => {
1120
1122
 
1121
1123
  if(socket_id && this.sockets[socket_id]){
@@ -1276,9 +1278,9 @@ export class PubSubManager {
1276
1278
 
1277
1279
  /* Must return a channel for socket */
1278
1280
  /* The distinct list of channel names must have a corresponding trigger in the database */
1279
- async addSub(subscriptionParams: AddSubscriptionParams){
1281
+ async addSub(subscriptionParams: Omit<AddSubscriptionParams, "channel_name">){
1280
1282
  const {
1281
- socket = null, func = null, table_info = null, table_rules, filter = {},
1283
+ socket, func = null, table_info = null, table_rules, filter = {},
1282
1284
  params = {}, condition = "", throttle = 0 //subOne = false,
1283
1285
  } = subscriptionParams || {};
1284
1286
 
@@ -1300,7 +1302,7 @@ export class PubSubManager {
1300
1302
  const upsertSub = (newSubData: { table_name: string, condition: string, is_ready: boolean }) => {
1301
1303
  const { table_name, condition: _cond, is_ready = false } = newSubData,
1302
1304
  condition = this.parseCondition(_cond),
1303
- newSub = {
1305
+ newSub: SubscriptionParams = {
1304
1306
  socket,
1305
1307
  table_name: table_info.name,
1306
1308
  table_info,
@@ -1309,7 +1311,7 @@ export class PubSubManager {
1309
1311
  table_rules,
1310
1312
  channel_name,
1311
1313
  func: func? func : undefined,
1312
- socket_id: socket? socket.id : null,
1314
+ socket_id: socket?.id,
1313
1315
  throttle: validated_throttle,
1314
1316
  is_throttling: null,
1315
1317
  last_throttled: 0,