prostgles-server 4.2.158 → 4.2.159

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 (145) hide show
  1. package/dist/Auth/AuthTypes.d.ts +4 -8
  2. package/dist/Auth/AuthTypes.d.ts.map +1 -1
  3. package/dist/Auth/setAuthProviders.d.ts.map +1 -1
  4. package/dist/Auth/setAuthProviders.js +4 -5
  5. package/dist/Auth/setAuthProviders.js.map +1 -1
  6. package/dist/Auth/setEmailProvider.js +1 -1
  7. package/dist/Auth/setEmailProvider.js.map +1 -1
  8. package/package.json +1 -1
  9. package/lib/Auth/AuthHandler.ts +0 -436
  10. package/lib/Auth/AuthTypes.ts +0 -285
  11. package/lib/Auth/getSafeReturnURL.ts +0 -35
  12. package/lib/Auth/sendEmail.ts +0 -83
  13. package/lib/Auth/setAuthProviders.ts +0 -129
  14. package/lib/Auth/setEmailProvider.ts +0 -85
  15. package/lib/Auth/setupAuthRoutes.ts +0 -161
  16. package/lib/DBEventsManager.ts +0 -178
  17. package/lib/DBSchemaBuilder.ts +0 -225
  18. package/lib/DboBuilder/DboBuilder.ts +0 -319
  19. package/lib/DboBuilder/DboBuilderTypes.ts +0 -361
  20. package/lib/DboBuilder/QueryBuilder/Functions.ts +0 -1153
  21. package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +0 -288
  22. package/lib/DboBuilder/QueryBuilder/getJoinQuery.ts +0 -263
  23. package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +0 -271
  24. package/lib/DboBuilder/QueryBuilder/getSelectQuery.ts +0 -136
  25. package/lib/DboBuilder/QueryBuilder/prepareHaving.ts +0 -22
  26. package/lib/DboBuilder/QueryStreamer.ts +0 -250
  27. package/lib/DboBuilder/TableHandler/DataValidator.ts +0 -428
  28. package/lib/DboBuilder/TableHandler/TableHandler.ts +0 -205
  29. package/lib/DboBuilder/TableHandler/delete.ts +0 -115
  30. package/lib/DboBuilder/TableHandler/insert.ts +0 -183
  31. package/lib/DboBuilder/TableHandler/insertTest.ts +0 -78
  32. package/lib/DboBuilder/TableHandler/onDeleteFromFileTable.ts +0 -62
  33. package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +0 -134
  34. package/lib/DboBuilder/TableHandler/update.ts +0 -126
  35. package/lib/DboBuilder/TableHandler/updateBatch.ts +0 -49
  36. package/lib/DboBuilder/TableHandler/updateFile.ts +0 -48
  37. package/lib/DboBuilder/TableHandler/upsert.ts +0 -34
  38. package/lib/DboBuilder/ViewHandler/ViewHandler.ts +0 -393
  39. package/lib/DboBuilder/ViewHandler/count.ts +0 -38
  40. package/lib/DboBuilder/ViewHandler/find.ts +0 -153
  41. package/lib/DboBuilder/ViewHandler/getExistsCondition.ts +0 -73
  42. package/lib/DboBuilder/ViewHandler/getExistsFilters.ts +0 -74
  43. package/lib/DboBuilder/ViewHandler/getInfo.ts +0 -32
  44. package/lib/DboBuilder/ViewHandler/getTableJoinQuery.ts +0 -84
  45. package/lib/DboBuilder/ViewHandler/parseComplexFilter.ts +0 -96
  46. package/lib/DboBuilder/ViewHandler/parseFieldFilter.ts +0 -105
  47. package/lib/DboBuilder/ViewHandler/parseJoinPath.ts +0 -208
  48. package/lib/DboBuilder/ViewHandler/prepareSortItems.ts +0 -163
  49. package/lib/DboBuilder/ViewHandler/prepareWhere.ts +0 -90
  50. package/lib/DboBuilder/ViewHandler/size.ts +0 -37
  51. package/lib/DboBuilder/ViewHandler/subscribe.ts +0 -118
  52. package/lib/DboBuilder/ViewHandler/validateViewRules.ts +0 -70
  53. package/lib/DboBuilder/dboBuilderUtils.ts +0 -222
  54. package/lib/DboBuilder/getColumns.ts +0 -114
  55. package/lib/DboBuilder/getCondition.ts +0 -201
  56. package/lib/DboBuilder/getSubscribeRelatedTables.ts +0 -190
  57. package/lib/DboBuilder/getTablesForSchemaPostgresSQL.ts +0 -426
  58. package/lib/DboBuilder/insertNestedRecords.ts +0 -355
  59. package/lib/DboBuilder/parseUpdateRules.ts +0 -187
  60. package/lib/DboBuilder/prepareShortestJoinPaths.ts +0 -186
  61. package/lib/DboBuilder/runSQL.ts +0 -182
  62. package/lib/DboBuilder/runTransaction.ts +0 -50
  63. package/lib/DboBuilder/sqlErrCodeToMsg.ts +0 -254
  64. package/lib/DboBuilder/uploadFile.ts +0 -69
  65. package/lib/Event_Trigger_Tags.ts +0 -118
  66. package/lib/FileManager/FileManager.ts +0 -358
  67. package/lib/FileManager/getValidatedFileType.ts +0 -69
  68. package/lib/FileManager/initFileManager.ts +0 -187
  69. package/lib/FileManager/upload.ts +0 -62
  70. package/lib/FileManager/uploadStream.ts +0 -79
  71. package/lib/Filtering.ts +0 -463
  72. package/lib/JSONBValidation/validate_jsonb_schema_sql.ts +0 -502
  73. package/lib/JSONBValidation/validation.ts +0 -143
  74. package/lib/Logging.ts +0 -127
  75. package/lib/PostgresNotifListenManager.ts +0 -143
  76. package/lib/Prostgles.ts +0 -485
  77. package/lib/ProstglesTypes.ts +0 -196
  78. package/lib/PubSubManager/PubSubManager.ts +0 -609
  79. package/lib/PubSubManager/addSub.ts +0 -138
  80. package/lib/PubSubManager/addSync.ts +0 -141
  81. package/lib/PubSubManager/getCreatePubSubManagerError.ts +0 -72
  82. package/lib/PubSubManager/getPubSubManagerInitQuery.ts +0 -662
  83. package/lib/PubSubManager/initPubSubManager.ts +0 -79
  84. package/lib/PubSubManager/notifListener.ts +0 -173
  85. package/lib/PubSubManager/orphanTriggerCheck.ts +0 -70
  86. package/lib/PubSubManager/pushSubData.ts +0 -55
  87. package/lib/PublishParser/PublishParser.ts +0 -162
  88. package/lib/PublishParser/getFileTableRules.ts +0 -124
  89. package/lib/PublishParser/getSchemaFromPublish.ts +0 -141
  90. package/lib/PublishParser/getTableRulesWithoutFileTable.ts +0 -177
  91. package/lib/PublishParser/publishTypesAndUtils.ts +0 -399
  92. package/lib/RestApi.ts +0 -127
  93. package/lib/SchemaWatch/SchemaWatch.ts +0 -90
  94. package/lib/SchemaWatch/createSchemaWatchEventTrigger.ts +0 -3
  95. package/lib/SchemaWatch/getValidatedWatchSchemaType.ts +0 -45
  96. package/lib/SchemaWatch/getWatchSchemaTagList.ts +0 -27
  97. package/lib/SyncReplication.ts +0 -557
  98. package/lib/TableConfig/TableConfig.ts +0 -468
  99. package/lib/TableConfig/getColumnDefinitionQuery.ts +0 -111
  100. package/lib/TableConfig/getConstraintDefinitionQueries.ts +0 -95
  101. package/lib/TableConfig/getFutureTableSchema.ts +0 -64
  102. package/lib/TableConfig/getPGIndexes.ts +0 -53
  103. package/lib/TableConfig/getTableColumnQueries.ts +0 -129
  104. package/lib/TableConfig/initTableConfig.ts +0 -326
  105. package/lib/index.ts +0 -13
  106. package/lib/initProstgles.ts +0 -319
  107. package/lib/onSocketConnected.ts +0 -102
  108. package/lib/runClientRequest.ts +0 -129
  109. package/lib/shortestPath.ts +0 -122
  110. package/lib/typeTests/DBoGenerated.d.ts +0 -320
  111. package/lib/typeTests/dboTypeCheck.ts +0 -81
  112. package/lib/utils.ts +0 -15
  113. package/tests/client/hooks.spec.ts +0 -205
  114. package/tests/client/index.ts +0 -139
  115. package/tests/client/package-lock.json +0 -637
  116. package/tests/client/package.json +0 -26
  117. package/tests/client/renderReactHook.ts +0 -177
  118. package/tests/client/tsconfig.json +0 -15
  119. package/tests/client/useProstgles.spec.ts +0 -120
  120. package/tests/clientFileTests.spec.ts +0 -102
  121. package/tests/clientOnlyQueries.spec.ts +0 -667
  122. package/tests/clientRestApi.spec.ts +0 -82
  123. package/tests/config_test/DBoGenerated.d.ts +0 -407
  124. package/tests/config_test/index.html +0 -109
  125. package/tests/config_test/index.js +0 -86
  126. package/tests/config_test/index.js.map +0 -1
  127. package/tests/config_test/index.ts +0 -91
  128. package/tests/config_test/init.sql +0 -48
  129. package/tests/config_test/package.json +0 -29
  130. package/tests/config_test/tsconfig.json +0 -23
  131. package/tests/config_testDBoGenerated.d.ts +0 -407
  132. package/tests/isomorphicQueries.spec.ts +0 -1493
  133. package/tests/server/DBoGenerated.d.ts +0 -537
  134. package/tests/server/index.html +0 -73
  135. package/tests/server/index.ts +0 -289
  136. package/tests/server/init.sql +0 -224
  137. package/tests/server/package-lock.json +0 -2164
  138. package/tests/server/package.json +0 -25
  139. package/tests/server/publishTypeCheck.ts +0 -136
  140. package/tests/server/server.ts +0 -35
  141. package/tests/server/testPublish.ts +0 -147
  142. package/tests/server/testTableConfig.ts +0 -156
  143. package/tests/server/tsconfig.json +0 -22
  144. package/tests/serverOnlyQueries.spec.ts +0 -32
  145. package/tests/test.sh +0 -20
@@ -1,319 +0,0 @@
1
- import * as pgPromise from "pg-promise";
2
- import pg from "pg-promise/typescript/pg-subset";
3
- import { getKeys, isEmpty } from "prostgles-types";
4
- import { AuthHandler } from "./Auth/AuthHandler";
5
- import { DBEventsManager } from "./DBEventsManager";
6
- import { DBOFullyTyped } from "./DBSchemaBuilder";
7
- import { DBHandlerServer, Prostgles, getIsSuperUser } from "./Prostgles";
8
- import { ProstglesInitOptions } from "./ProstglesTypes";
9
- import { DbTableInfo, PublishParser } from "./PublishParser/PublishParser";
10
- import { SchemaWatch } from "./SchemaWatch/SchemaWatch";
11
- import { sleep } from "./utils";
12
-
13
- export type DbConnection = string | pg.IConnectionParameters<pg.IClient>;
14
- export type DbConnectionOpts = pg.IDefaults;
15
-
16
- export type PGP = pgPromise.IMain<{}, pg.IClient>;
17
- export type DB = pgPromise.IDatabase<{}, pg.IClient>;
18
-
19
- export type UpdateableOptions = Pick<ProstglesInitOptions, "fileTable" | "restApi" | "tableConfig" | "schema" | "auth">;
20
- export type OnInitReason =
21
- | {
22
- type: "schema change";
23
- query: string;
24
- command: string;
25
- }
26
- | {
27
- type: "prgl.update";
28
- newOpts: Omit<UpdateableOptions, typeof clientOnlyUpdateKeys[number]>;
29
- }
30
- | {
31
- type: "init" | "prgl.restart" | "TableConfig"
32
- };
33
-
34
- type OnReadyParamsCommon = {
35
- db: DB;
36
- tables: DbTableInfo[];
37
- reason: OnInitReason;
38
- }
39
- export type OnReadyParamsBasic = OnReadyParamsCommon & {
40
- dbo: DBHandlerServer;
41
- }
42
- export type OnReadyParams<S> = OnReadyParamsCommon & {
43
- dbo: DBOFullyTyped<S>;
44
- }
45
-
46
- export type OnReadyCallback<S = void> = (params: OnReadyParams<S>) => any;
47
- export type OnReadyCallbackBasic = (params: OnReadyParamsBasic) => any;
48
-
49
- export type InitResult = {
50
- db: DBOFullyTyped;
51
- _db: DB;
52
- pgp: PGP;
53
- io?: any;
54
- destroy: () => Promise<boolean>;
55
- /**
56
- * Generated database public schema TS types for all tables and views
57
- */
58
- getTSSchema: () => string;
59
- update: (newOpts: UpdateableOptions) => Promise<void>;
60
- restart: () => Promise<InitResult>;
61
- options: ProstglesInitOptions;
62
- }
63
-
64
- const clientOnlyUpdateKeys = ["auth"] as const satisfies (keyof UpdateableOptions)[];
65
-
66
- export const initProstgles = async function(this: Prostgles, onReady: OnReadyCallbackBasic, reason: OnInitReason): Promise<InitResult> {
67
- this.loaded = false;
68
-
69
- if (!this.db) {
70
- let existingAppName = "";
71
- let connString = "";
72
- if(typeof this.opts.dbConnection === "string"){
73
- connString = this.opts.dbConnection;
74
- } else if(this.opts.dbConnection.connectionString){
75
- connString = this.opts.dbConnection.connectionString;
76
- } else {
77
- existingAppName = this.opts.dbConnection.application_name ?? "";
78
- }
79
-
80
- if(connString){
81
- try {
82
- const url = new URL(connString);
83
- existingAppName = url.searchParams.get("application_name") ?? url.searchParams.get("ApplicationName") ?? "";
84
- } catch (e) {
85
-
86
- }
87
- }
88
-
89
- const conObj = typeof this.opts.dbConnection === "string" ? { connectionString: this.opts.dbConnection } : this.opts.dbConnection
90
- const application_name = `prostgles ${this.appId} ${existingAppName}`;
91
-
92
- /* 1. Connect to db */
93
- const { db, pgp } = getDbConnection({
94
- ...this.opts,
95
- dbConnection: { ...conObj, application_name },
96
- onNotice: notice => {
97
- if (this.opts.onNotice) this.opts.onNotice(notice);
98
- if (this.dbEventsManager) {
99
- this.dbEventsManager.onNotice(notice)
100
- }
101
- }
102
- });
103
- this.db = db;
104
- this.pgp = pgp;
105
- this.isSuperUser = await getIsSuperUser(db);
106
- }
107
- this.checkDb();
108
-
109
- const db = this.db!;
110
- const pgp = this.pgp!;
111
-
112
- /* 2. Execute any SQL file if provided */
113
- if (this.opts.sqlFilePath) {
114
- await this.runSQLFile(this.opts.sqlFilePath);
115
- }
116
-
117
- try {
118
-
119
- await this.refreshDBO();
120
- await this.initTableConfig(reason);
121
- await this.initFileTable();
122
- await this.initRestApi();
123
-
124
- this.schemaWatch = await SchemaWatch.create(this.dboBuilder);
125
-
126
- if (this.opts.publish) {
127
-
128
- if (!this.opts.io) {
129
- console.warn("IO missing. Publish has no effect without io");
130
- }
131
-
132
- /* 3.9 Check auth config */
133
- await this.initAuthHandler();
134
-
135
- this.publishParser = new PublishParser(this.opts.publish, this.opts.publishMethods as any, this.opts.publishRawSQL, this.dbo!, this.db, this as any);
136
- this.dboBuilder.publishParser = this.publishParser;
137
-
138
- /* 4. Set publish and auth listeners */
139
- await this.setSocketEvents();
140
-
141
- } else if (this.opts.auth) {
142
- throw "Auth config does not work without publish";
143
- }
144
-
145
- this.dbEventsManager = new DBEventsManager(db, pgp);
146
-
147
-
148
- this.writeDBSchema();
149
-
150
- /* 5. Finish init and provide DBO object */
151
- try {
152
- if (this.destroyed) {
153
- console.trace(1)
154
- }
155
- onReady({
156
- dbo: this.dbo as any,
157
- db: this.db,
158
- tables: this.dboBuilder.tables,
159
- reason
160
- });
161
- } catch (err) {
162
- console.error("Prostgles: Error within onReady: \n", err)
163
- }
164
-
165
- this.loaded = true;
166
- return {
167
- db: this.dbo! as any,
168
- _db: db,
169
- pgp,
170
- io: this.opts.io,
171
- getTSSchema: this.getTSFileContent,
172
- options: this.opts,
173
- update: async (newOpts) => {
174
-
175
- getKeys(newOpts).forEach(k => {
176
- //@ts-ignore
177
- this.opts[k] = newOpts[k];
178
- });
179
-
180
-
181
- if("fileTable" in newOpts){
182
- await this.initFileTable();
183
- }
184
- if("restApi" in newOpts){
185
- await this.initRestApi();
186
- }
187
- if("tableConfig" in newOpts){
188
- await this.initTableConfig({ type: "prgl.update", newOpts });
189
- await this.refreshDBO();
190
- }
191
- if("schema" in newOpts){
192
- await this.initTableConfig({ type: "prgl.update", newOpts });
193
- await this.refreshDBO();
194
- }
195
- if("auth" in newOpts){
196
- await this.initAuthHandler();
197
- }
198
-
199
- if(isEmpty(newOpts)) return;
200
-
201
- /**
202
- * Some of these changes require clients to reconnect
203
- * While others also affect the server and onReady should be called
204
- */
205
- if(getKeys(newOpts).every(updatedKey => clientOnlyUpdateKeys.includes(updatedKey as any))){
206
- await this.setSocketEvents();
207
- } else {
208
- await this.init(onReady, { type: "prgl.update", newOpts });
209
- }
210
- },
211
- restart: () => this.init(onReady, { type: "prgl.restart" }),
212
- destroy: async () => {
213
- console.log("destroying prgl instance")
214
- this.destroyed = true;
215
- if (this.opts.io) {
216
- this.opts.io.on("connection", () => {
217
- console.log("Socket connected to destroyed instance")
218
- });
219
-
220
- /** Try to close IO without stopping http server */
221
- if(this.opts.io.sockets.constructor.name === "Namespace"){
222
- for (const socket of this.opts.io.sockets.sockets.values()) {
223
- socket._onclose("server shutting down");
224
- }
225
- }
226
- if(this.opts.io.engine.constructor.name === 'Server'){
227
- this.opts.io.engine.close();
228
- }
229
- }
230
- this.fileManager?.destroy();
231
- this.dboBuilder?.destroy();
232
- this.authHandler?.destroy();
233
- await this.tableConfigurator?.destroy();
234
- this.dbo = undefined;
235
- this.db = undefined;
236
- await db.$pool.end();
237
- await sleep(1000);
238
- return true;
239
- }
240
- };
241
- } catch (e: any) {
242
- console.trace(e)
243
- throw "init issues: " + e.toString();
244
- }
245
- }
246
-
247
- type GetDbConnectionArgs = Pick<ProstglesInitOptions, "DEBUG_MODE" | "onQuery" | "dbConnection" | "dbOptions" | "onNotice">;
248
- const getDbConnection = function({ dbConnection, onQuery, DEBUG_MODE, dbOptions, onNotice }: GetDbConnectionArgs): { db: DB, pgp: PGP } {
249
-
250
- const onQueryOrError: undefined | ((error: any, ctx: pgPromise.IEventContext<pg.IClient>) => void) = !onQuery && !DEBUG_MODE? undefined : (error, ctx) => {
251
- if (onQuery) {
252
- onQuery(error, ctx);
253
- } else if (DEBUG_MODE) {
254
- if(error){
255
- console.error(error, ctx);
256
- } else {
257
- console.log(ctx)
258
- }
259
- }
260
- };
261
-
262
- const pgp: PGP = pgPromise({
263
- ...(onQueryOrError ? {
264
- query: ctx => onQueryOrError(undefined, ctx),
265
- error: onQueryOrError
266
- } : {}),
267
- ...((onNotice || DEBUG_MODE) ? {
268
- connect: function ({ client, useCount }) {
269
- const isFresh = !useCount;
270
- if (isFresh && !client.listeners('notice').length) {
271
- client.on('notice', function (msg) {
272
- if (onNotice) {
273
- onNotice(msg, msg?.message);
274
- } else {
275
- console.log("notice: %j", msg?.message);
276
- }
277
- });
278
- }
279
- if (isFresh && !client.listeners('error').length) {
280
- client.on('error', function (msg) {
281
- if (onNotice) {
282
- onNotice(msg, msg?.message);
283
- } else {
284
- console.log("error: %j", msg?.message);
285
- }
286
- });
287
- }
288
- },
289
- } : {})
290
- });
291
- // pgp.pg.defaults.max = 70;
292
-
293
- // /* Casts count/sum/max to bigint. Needs rework to remove casting "+count" and other issues; */
294
- // pgp.pg.types.setTypeParser(20, BigInt);
295
-
296
- /**
297
- * Prevent timestamp casting to ensure we don't lose the microseconds.
298
- * This is needed to ensure the filters work as expected for a given row
299
- *
300
- register(1114, parseTimestamp) // timestamp without time zone
301
- register(1184, parseTimestampTz) // timestamp with time zone
302
- */
303
- // pgp.pg.types.setTypeParser(1114, v => v); // timestamp without time zone
304
- // pgp.pg.types.setTypeParser(1184, v => v); // timestamp with time zone
305
- // pgp.pg.types.setTypeParser(1182, v => v); // date
306
- pgp.pg.types.setTypeParser(pgp.pg.types.builtins.TIMESTAMP, v => v); // timestamp without time zone
307
- pgp.pg.types.setTypeParser(pgp.pg.types.builtins.TIMESTAMPTZ, v => v); // timestamp with time zone
308
- pgp.pg.types.setTypeParser(pgp.pg.types.builtins.DATE, v => v); // date
309
-
310
-
311
- if (dbOptions) {
312
- Object.assign(pgp.pg.defaults, dbOptions);
313
- }
314
-
315
- return {
316
- db: pgp(dbConnection),
317
- pgp
318
- };
319
- }
@@ -1,102 +0,0 @@
1
- import { AnyObject, CHANNELS } from "prostgles-types";
2
- import type { Prostgles, TABLE_METHODS } from "./Prostgles";
3
- import { PRGLIOSocket } from "./DboBuilder/DboBuilderTypes";
4
- import { runClientMethod, runClientRequest } from "./runClientRequest";
5
- import { getErrorAsObject } from "./DboBuilder/dboBuilderUtils";
6
-
7
- export async function onSocketConnected(this: Prostgles, socket: PRGLIOSocket) {
8
- if (this.destroyed) {
9
- console.log("Socket connected to destroyed instance");
10
- socket.disconnect();
11
- return
12
- }
13
- this.connectedSockets.push(socket);
14
-
15
- try {
16
- await this.opts.onLog?.({
17
- type: "connect",
18
- sid: this.authHandler?.getSID({ socket }),
19
- socketId: socket.id,
20
- connectedSocketIds: this.connectedSockets.map(s => s.id)
21
- });
22
-
23
- if (!this.db || !this.dbo) throw new Error("db/dbo missing");
24
- const { dbo, db } = this;
25
-
26
- if (this.opts.onSocketConnect) {
27
- try {
28
- const getUser = async () => { return await this.authHandler?.getClientInfo({ socket }); }
29
- await this.opts.onSocketConnect({ socket, dbo: dbo as any, db, getUser });
30
- } catch(error) {
31
- const connectionError = error instanceof Error? error.message : typeof error === "string"? error : JSON.stringify(error);
32
- socket.emit(CHANNELS.CONNECTION, { connectionError });
33
- socket.disconnect();
34
- return;
35
- }
36
- }
37
-
38
- socket.removeAllListeners(CHANNELS.DEFAULT)
39
- socket.on(CHANNELS.DEFAULT, async (args: SocketRequestParams, cb = (..._callback: any[]) => { /* Empty */}) => {
40
- runClientRequest.bind(this)({ ...args, type: "socket", socket })
41
- .then(res => {
42
- cb(null, res)
43
- }).catch(err => {
44
- cb(err);
45
- });
46
- });
47
-
48
- socket.on("disconnect", () => {
49
-
50
- this.dbEventsManager?.removeNotice(socket);
51
- this.dbEventsManager?.removeNotify(undefined, socket);
52
- this.connectedSockets = this.connectedSockets.filter(s => s.id !== socket.id);
53
- this.dboBuilder.queryStreamer.onDisconnect(socket.id);
54
- this.opts.onLog?.({
55
- type: "disconnect",
56
- sid: this.authHandler?.getSID({ socket }),
57
- socketId: socket.id,
58
- connectedSocketIds: this.connectedSockets.map(s => s.id)
59
- });
60
-
61
- if (this.opts.onSocketDisconnect) {
62
- const getUser = async () => { return await this.authHandler?.getClientInfo({ socket }); }
63
- this.opts.onSocketDisconnect({ socket, dbo: dbo as any, db, getUser });
64
- }
65
- });
66
-
67
- socket.removeAllListeners(CHANNELS.METHOD)
68
- socket.on(CHANNELS.METHOD, async ({ method, params }: SocketMethodRequest, cb = (..._callback: any) => { /* Empty */ }) => {
69
- runClientMethod.bind(this)({
70
- type: "socket",
71
- socket,
72
- method,
73
- params
74
- }).then(res => {
75
- cb(null, res)
76
- }).catch(err => {
77
- makeSocketError(cb, err)
78
- });
79
- });
80
-
81
- this.pushSocketSchema(socket);
82
- } catch (e) {
83
- console.trace("setSocketEvents: ", e)
84
- }
85
- }
86
-
87
-
88
- export function makeSocketError(cb: (err: AnyObject) => void, err: any) {
89
- cb(getErrorAsObject(err));
90
- }
91
-
92
- type SocketRequestParams = {
93
- tableName: string;
94
- command: typeof TABLE_METHODS[number];
95
- param1: any;
96
- param2: any;
97
- param3: any;
98
- }
99
- type SocketMethodRequest = {
100
- method: string;
101
- params: any;
102
- }
@@ -1,129 +0,0 @@
1
- import { AnyObject, TableHandler, UserLike, getKeys, pickKeys } from "prostgles-types";
2
- import { ExpressReq } from "./Auth/AuthTypes";
3
- import { LocalParams, PRGLIOSocket } from "./DboBuilder/DboBuilder";
4
- import { parseFieldFilter } from "./DboBuilder/ViewHandler/parseFieldFilter";
5
- import { canRunSQL } from "./DboBuilder/runSQL";
6
- import { Prostgles } from "./Prostgles";
7
-
8
- type ReqInfo = {
9
- type: "socket";
10
- socket: PRGLIOSocket;
11
- httpReq?: undefined;
12
- } | {
13
- type: "http";
14
- httpReq: ExpressReq;
15
- socket?: undefined;
16
- }
17
- type ReqInfoClient = {
18
- socket: PRGLIOSocket;
19
- } | {
20
- httpReq: ExpressReq;
21
- }
22
- type Args = ReqInfo & {
23
- tableName: string;
24
- command: string;
25
- param1: any;
26
- param2: any;
27
- param3: any;
28
- };
29
- const SOCKET_ONLY_COMMANDS = ["subscribe", "subscribeOne", "sync"];
30
-
31
- const getReqInfoClient = (reqInfo: ReqInfo): ReqInfoClient => {
32
- if(reqInfo.type === "socket"){
33
- return { socket: reqInfo.socket };
34
- }
35
- return { httpReq: reqInfo.httpReq };
36
- }
37
- export const runClientRequest = async function(this: Prostgles, args: Args){
38
- /* Channel name will only include client-sent params so we ignore table_rules enforced params */
39
- if ((args.type === "socket" && !args.socket) || (args.type === "http" && !args.httpReq) || !this.authHandler || !this.publishParser || !this.dbo) {
40
- throw "socket/httpReq or authhandler missing";
41
- }
42
-
43
- const { tableName, command, param1, param2, param3 } = args;
44
-
45
- if(args.type !== "socket" && SOCKET_ONLY_COMMANDS.includes(command)){
46
- throw "The following commands cannot be completed over a non-websocket connection: " + SOCKET_ONLY_COMMANDS;
47
- }
48
- const reqInfo = getReqInfoClient(args);
49
- const clientInfo = await this.authHandler.getClientInfo(args);
50
- const valid_table_command_rules = await this.publishParser.getValidatedRequestRule({ tableName, command, localParams: reqInfo }, clientInfo);
51
- if (valid_table_command_rules) {
52
- const sessionUser: UserLike | undefined = !clientInfo?.user? undefined : {
53
- ...parseFieldFilter(clientInfo.sessionFields ?? [] as any, false, Object.keys(clientInfo.user)),
54
- ...pickKeys(clientInfo.user, ["id", "type"]) as UserLike,
55
- }
56
- const localParams: LocalParams = { ...reqInfo, isRemoteRequest: { user: sessionUser } }
57
- if(param3 && (param3 as LocalParams).returnQuery){
58
- const isAllowed = await canRunSQL(this, localParams);
59
- if(isAllowed){
60
- localParams.returnQuery = (param3 as LocalParams).returnQuery;
61
- } else {
62
- throw "Must be allowed to run sql to use returnQuery";
63
- }
64
- }
65
- const tableHandler = this.dbo[tableName];
66
- if(!tableHandler || !tableHandler.column_names) throw `Invalid tableName ${tableName} provided`;
67
- const method = tableHandler[command as keyof TableHandler];
68
- if(!method) throw `Invalid command ${command} provided`;
69
- //@ts-ignore
70
- return this.dbo[tableName][command](param1, param2, param3, valid_table_command_rules, localParams);
71
- } else {
72
- throw `Invalid OR disallowed request: ${tableName}.${command} `;
73
- }
74
- }
75
-
76
- export const clientCanRunSqlRequest = async function(this: Prostgles, args: ReqInfo){
77
- const reqInfo = getReqInfoClient(args);
78
- if(!this.opts.publishRawSQL || typeof this.opts.publishRawSQL !== "function"){
79
- return { allowed: false, reqInfo }
80
- }
81
- const canRunSQL = async () => {
82
- if(!this.authHandler){
83
- throw "authHandler missing";
84
- }
85
- const publishParams = await this.publishParser?.getPublishParams(reqInfo);
86
- const res = await this.opts.publishRawSQL?.(publishParams as any);
87
- return Boolean(res && typeof res === "boolean" || res === "*");
88
- }
89
-
90
- const allowed = await canRunSQL();
91
- return { allowed, reqInfo };
92
- }
93
-
94
- type ArgsSql = ReqInfo & {
95
- query: string;
96
- args?: AnyObject | any[];
97
- options?: any;
98
- }
99
- export const runClientSqlRequest = async function(this: Prostgles, params: ArgsSql){
100
- const { allowed, reqInfo } = await clientCanRunSqlRequest.bind(this)(params);
101
- if(!allowed){
102
- throw "Not allowed to execute sql";
103
- }
104
- if (!this.dbo?.sql) throw "Internal error: sql handler missing";
105
- const { query, args, options } = params;
106
- return this.dbo.sql(query, args, options, reqInfo);
107
- }
108
-
109
-
110
-
111
- type ArgsMethod = ReqInfo & {
112
- method: string;
113
- params?: any[]
114
- }
115
- export const runClientMethod = async function(this: Prostgles, reqArgs: ArgsMethod){
116
-
117
- const reqInfo = getReqInfoClient(reqArgs);
118
- const { method, params = [] } = reqArgs;
119
- const methods = await this.publishParser?.getAllowedMethods(reqInfo);
120
-
121
- if (!methods || !methods[method]) {
122
- throw ("Disallowed/missing method " + JSON.stringify(method));
123
- }
124
-
125
- const methodDef = methods[method]!;
126
- const onRun = (typeof methodDef === "function" || typeof (methodDef as any).then === "function")? (methodDef as (...args: any) => Promise<void>) : methodDef.run;
127
- const res = await onRun(...params);
128
- return res;
129
- }
@@ -1,122 +0,0 @@
1
- import { AnyObject } from "prostgles-types";
2
-
3
- const shortestDistanceNode = (distances: AnyObject, visited: AnyObject) => {
4
- let shortest = null;
5
-
6
- for (const node in distances) {
7
- const currentIsShortest =
8
- shortest === null || distances[node] < distances[shortest];
9
- if (currentIsShortest && !visited.includes(node)) {
10
- shortest = node;
11
- }
12
- }
13
- return shortest;
14
- };
15
- export type Graph = {
16
- [key: string]: { [key: string]: number }
17
- };
18
-
19
- export const findShortestPath = (graph: Graph, startNode: string, endNode: string): { distance: number, path: string[] } => {
20
- // establish object for recording distances from the start node
21
- let distances: AnyObject = {};
22
- distances[endNode] = "Infinity";
23
- distances = Object.assign(distances, graph[startNode]);
24
-
25
- // track paths
26
- const parents: AnyObject = { endNode: null };
27
- for (const child in graph[startNode]) {
28
- parents[child] = startNode;
29
- }
30
-
31
- // track nodes that have already been visited
32
- const visited: AnyObject = [];
33
-
34
- // find the nearest node
35
- let node = shortestDistanceNode(distances, visited);
36
-
37
- // for that node
38
- while (node) {
39
- // find its distance from the start node & its child nodes
40
- const distance = distances[node];
41
- const children = graph[node];
42
- // for each of those child nodes
43
- for (const child in children) {
44
- // make sure each child node is not the start node
45
- if (String(child) === String(startNode)) {
46
- continue;
47
- } else {
48
- // save the distance from the start node to the child node
49
- const newdistance = distance + children[child];
50
- // if there's no recorded distance from the start node to the child node in the distances object
51
- // or if the recorded distance is shorter than the previously stored distance from the start node to the child node
52
- // save the distance to the object
53
- // record the path
54
- if (!distances[child] || distances[child] > newdistance) {
55
- distances[child] = newdistance;
56
- parents[child] = node;
57
- }
58
- }
59
- }
60
- // move the node to the visited set
61
- visited.push(node);
62
- // move to the nearest neighbor node
63
- node = shortestDistanceNode(distances, visited);
64
- }
65
-
66
- // using the stored paths from start node to end node
67
- // record the shortest path
68
- const shortestPath = [endNode];
69
- let parent = parents[endNode];
70
- while (parent) {
71
- shortestPath.push(parent);
72
- parent = parents[parent];
73
- }
74
- shortestPath.reverse();
75
-
76
- // return the shortest path from start node to end node & its distance
77
- const results = {
78
- distance: distances[endNode],
79
- path: shortestPath,
80
- };
81
-
82
- return results;
83
- };
84
-
85
- /* Usage:
86
-
87
- const graph = {
88
- start: { A: 5, B: 2 },
89
- A: { start: 1, C: 4, D: 2 },
90
- B: { A: 8, D: 7 },
91
- C: { D: 6, end: 3 },
92
- D: { end: 1 },
93
- end: {},
94
- };
95
-
96
- findShortestPath(graph, 'start', 'end');
97
-
98
- {
99
- "distance": 8,
100
- "path": [
101
- "start",
102
- "A",
103
- "D",
104
- "end"
105
- ]
106
- }
107
-
108
-
109
-
110
-
111
- // The graph is unidirectional
112
-
113
- const graph = {
114
- start: { A: 5 },
115
- end: { A: 1 },
116
- A: { start: 1, end: 1 },
117
- };
118
-
119
- findShortestPath(graph, 'start', 'end');
120
-
121
-
122
- */