prostgles-server 2.0.173 → 2.0.176
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.
- package/.vscode/settings.json +3 -0
- package/dist/AuthHandler.d.ts +13 -12
- package/dist/AuthHandler.d.ts.map +1 -1
- package/dist/AuthHandler.js +5 -2
- package/dist/AuthHandler.js.map +1 -1
- package/dist/DBSchemaBuilder.d.ts +11 -0
- package/dist/DBSchemaBuilder.d.ts.map +1 -0
- package/dist/DBSchemaBuilder.js +56 -0
- package/dist/DBSchemaBuilder.js.map +1 -0
- package/dist/DboBuilder.d.ts +23 -22
- package/dist/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder.js +36 -61
- package/dist/DboBuilder.js.map +1 -1
- package/dist/FileManager.d.ts +2 -2
- package/dist/FileManager.d.ts.map +1 -1
- package/dist/Filtering.d.ts.map +1 -1
- package/dist/Filtering.js.map +1 -1
- package/dist/Prostgles.d.ts +25 -257
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +12 -376
- package/dist/Prostgles.js.map +1 -1
- package/dist/PubSubManager.d.ts +6 -5
- package/dist/PubSubManager.d.ts.map +1 -1
- package/dist/PubSubManager.js.map +1 -1
- package/dist/PublishParser.d.ts +262 -0
- package/dist/PublishParser.d.ts.map +1 -0
- package/dist/PublishParser.js +391 -0
- package/dist/PublishParser.js.map +1 -0
- package/dist/QueryBuilder.d.ts +20 -4
- package/dist/QueryBuilder.d.ts.map +1 -1
- package/dist/QueryBuilder.js.map +1 -1
- package/dist/TableConfig.d.ts +6 -3
- package/dist/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig.js +28 -1
- package/dist/TableConfig.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/lib/AuthHandler.ts +25 -19
- package/lib/DBSchemaBuilder.ts +91 -0
- package/lib/DboBuilder.ts +84 -98
- package/lib/FileManager.ts +2 -2
- package/lib/Filtering.ts +3 -3
- package/lib/Prostgles.ts +33 -704
- package/lib/PubSubManager.ts +6 -5
- package/lib/PublishParser.ts +723 -0
- package/lib/QueryBuilder.ts +6 -5
- package/lib/TableConfig.ts +36 -5
- package/lib/index.ts +4 -4
- package/package.json +2 -2
- package/tests/client/PID.txt +1 -1
- package/tests/client/index.js +2 -2
- package/tests/client/index.ts +2 -2
- package/tests/client/package-lock.json +15 -15
- package/tests/client/package.json +1 -1
- package/tests/client_only_queries.js +24 -1
- package/tests/client_only_queries.ts +23 -1
- package/tests/isomorphic_queries.js +3 -0
- package/tests/isomorphic_queries.ts +5 -2
- package/tests/server/DBoGenerated.d.ts +428 -286
- package/tests/server/index.js +1 -14
- package/tests/server/index.ts +5 -19
- package/tests/server/package-lock.json +3 -3
package/lib/Prostgles.ts
CHANGED
|
@@ -16,19 +16,19 @@ 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,
|
|
19
|
+
import { DboBuilder, DBHandlerServer, isPlainObject, LocalParams, TableSchema, PRGLIOSocket } from "./DboBuilder";
|
|
20
20
|
import { PubSubManager, DEFAULT_SYNC_BATCH_SIZE, asValue } from "./PubSubManager";
|
|
21
|
-
export {
|
|
21
|
+
export { DBHandlerServer }
|
|
22
22
|
export type PGP = pgPromise.IMain<{}, pg.IClient>;
|
|
23
23
|
|
|
24
|
-
import { SQLRequest, TableSchemaForClient,
|
|
25
|
-
|
|
24
|
+
import { SQLRequest, TableSchemaForClient, CHANNELS, AnyObject, ClientSchema, getKeys, DBSchemaTable, DBSchema } from "prostgles-types";
|
|
25
|
+
import { Publish, PublishMethods, PublishParams, PublishParser } from "./PublishParser";
|
|
26
26
|
import { DBEventsManager } from "./DBEventsManager";
|
|
27
27
|
|
|
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
|
-
const TABLE_METHODS = ["update", "find", "findOne", "insert", "delete", "upsert"];
|
|
31
|
+
export const TABLE_METHODS = ["update", "find", "findOne", "insert", "delete", "upsert"] as const;
|
|
32
32
|
function getDbConnection(dbConnection: DbConnection, options: DbConnectionOpts | undefined, debugQueries = false, onNotice: ProstglesInitOptions["onNotice"]): { db: DB, pgp: PGP } {
|
|
33
33
|
let pgp: PGP = pgPromise({
|
|
34
34
|
|
|
@@ -76,238 +76,6 @@ function getDbConnection(dbConnection: DbConnection, options: DbConnectionOpts |
|
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
import { Socket } from "dgram";
|
|
81
|
-
import { FieldFilter, SelectParamsBasic as SelectParams } from "prostgles-types";
|
|
82
|
-
|
|
83
|
-
export type InsertRequestData = {
|
|
84
|
-
data: object | object[]
|
|
85
|
-
returning: FieldFilter;
|
|
86
|
-
}
|
|
87
|
-
export type SelectRequestData = {
|
|
88
|
-
filter: object;
|
|
89
|
-
params: SelectParams;
|
|
90
|
-
}
|
|
91
|
-
export type DeleteRequestData = {
|
|
92
|
-
filter: object;
|
|
93
|
-
returning: FieldFilter;
|
|
94
|
-
}
|
|
95
|
-
export type UpdateRequestDataOne = {
|
|
96
|
-
filter: object;
|
|
97
|
-
data: object;
|
|
98
|
-
returning: FieldFilter;
|
|
99
|
-
}
|
|
100
|
-
export type UpdateReq = {
|
|
101
|
-
filter: object;
|
|
102
|
-
data: object;
|
|
103
|
-
}
|
|
104
|
-
export type UpdateRequestDataBatch = {
|
|
105
|
-
data: UpdateReq[];
|
|
106
|
-
}
|
|
107
|
-
export type UpdateRequestData = UpdateRequestDataOne | UpdateRequestDataBatch;
|
|
108
|
-
|
|
109
|
-
export type ValidateRow = (row: AnyObject) => AnyObject | Promise<AnyObject>;
|
|
110
|
-
export type ValidateUpdateRow = (args: { update: AnyObject, filter: AnyObject }) => AnyObject | Promise<AnyObject>;
|
|
111
|
-
|
|
112
|
-
export type SelectRule = {
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Fields allowed to be selected. Tip: Use false to exclude field
|
|
116
|
-
*/
|
|
117
|
-
fields: FieldFilter;
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* The maximum number of rows a user can get in a select query. null by default. Unless a null or higher limit is specified 100 rows will be returned by the default
|
|
121
|
-
*/
|
|
122
|
-
maxLimit?: number | null;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Filter added to every query (e.g. user_id) to restrict access
|
|
126
|
-
*/
|
|
127
|
-
forcedFilter?: AnyObject;
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Fields user can filter by
|
|
131
|
-
* */
|
|
132
|
-
filterFields?: FieldFilter;
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Validation logic to check/update data for each request
|
|
136
|
-
*/
|
|
137
|
-
validate?(args: SelectRequestData): SelectRequestData | Promise<SelectRequestData>;
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
export type InsertRule = {
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Fields allowed to be inserted. Tip: Use false to exclude field
|
|
144
|
-
*/
|
|
145
|
-
fields: FieldFilter;
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Data to include/overwrite on each insert
|
|
149
|
-
*/
|
|
150
|
-
forcedData?: AnyObject;
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Fields user can view after inserting
|
|
154
|
-
*/
|
|
155
|
-
returningFields?: FieldFilter;
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Validation logic to check/update data for each request. Happens before publish rule checks (for fields, forcedData/forcedFilter)
|
|
159
|
-
*/
|
|
160
|
-
preValidate?: ValidateRow
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Validation logic to check/update data for each request. Happens after publish rule checks (for fields, forcedData/forcedFilter)
|
|
164
|
-
*/
|
|
165
|
-
validate?: ValidateRow
|
|
166
|
-
}
|
|
167
|
-
export type UpdateRule = {
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Fields allowed to be updated. Tip: Use false/0 to exclude field
|
|
171
|
-
*/
|
|
172
|
-
fields: FieldFilter;
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Row level FGAC
|
|
176
|
-
* Used when the editable fields change based on the updated row
|
|
177
|
-
* If specified then the fields from the first matching filter table.count({ ...filter, ...updateFilter }) > 0 will be used
|
|
178
|
-
* If none matching then the "fields" will be used
|
|
179
|
-
* Specify in decreasing order of specificity otherwise a more general filter will match first
|
|
180
|
-
*/
|
|
181
|
-
dynamicFields?: {
|
|
182
|
-
filter: AnyObject;
|
|
183
|
-
fields: FieldFilter;
|
|
184
|
-
}[];
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Filter added to every query (e.g. user_id) to restrict access
|
|
188
|
-
* This filter cannot be updated
|
|
189
|
-
*/
|
|
190
|
-
forcedFilter?: AnyObject;
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Data to include/overwrite on each updatDBe
|
|
194
|
-
*/
|
|
195
|
-
forcedData?: AnyObject;
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Fields user can use to find the updates
|
|
199
|
-
*/
|
|
200
|
-
filterFields?: FieldFilter;
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Fields user can view after updating
|
|
204
|
-
*/
|
|
205
|
-
returningFields?: FieldFilter;
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Validation logic to check/update data for each request
|
|
209
|
-
*/
|
|
210
|
-
validate?: ValidateUpdateRow;
|
|
211
|
-
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
export type DeleteRule = {
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Filter added to every query (e.g. user_id) to restrict access
|
|
218
|
-
*/
|
|
219
|
-
forcedFilter?: AnyObject;
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Fields user can filter by
|
|
223
|
-
*/
|
|
224
|
-
filterFields?: FieldFilter;
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Fields user can view after deleting
|
|
228
|
-
*/
|
|
229
|
-
returningFields?: FieldFilter;
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Validation logic to check/update data for each request
|
|
233
|
-
*/
|
|
234
|
-
validate?(...args: any[]): UpdateRequestData
|
|
235
|
-
}
|
|
236
|
-
export type SyncRule = {
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Primary keys used in updating data
|
|
240
|
-
*/
|
|
241
|
-
id_fields: string[];
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Numerical incrementing fieldname (last updated timestamp) used to sync items
|
|
245
|
-
*/
|
|
246
|
-
synced_field: string;
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* EXPERIMENTAL. Disabled by default. If true then server will attempt to delete any records missing from client.
|
|
250
|
-
*/
|
|
251
|
-
allow_delete?: boolean;
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Throttle replication transmission in milliseconds. Defaults to 100
|
|
255
|
-
*/
|
|
256
|
-
throttle?: number;
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Number of rows to send per trip. Defaults to 50
|
|
260
|
-
*/
|
|
261
|
-
batch_size?: number;
|
|
262
|
-
}
|
|
263
|
-
export type SubscribeRule = {
|
|
264
|
-
throttle?: number;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
export type TableRule = CommonTableRules & {
|
|
268
|
-
select?: SelectRule;
|
|
269
|
-
insert?: InsertRule;
|
|
270
|
-
update?: UpdateRule;
|
|
271
|
-
delete?: DeleteRule;
|
|
272
|
-
sync?: SyncRule;
|
|
273
|
-
subscribe?: SubscribeRule;
|
|
274
|
-
};
|
|
275
|
-
export type ViewRule = {
|
|
276
|
-
select: SelectRule;
|
|
277
|
-
};
|
|
278
|
-
export type PublishTableRule = {
|
|
279
|
-
select?: SelectRule | "*" | false | null;
|
|
280
|
-
insert?: InsertRule | "*" | false | null;
|
|
281
|
-
update?: UpdateRule | "*" | false | null;
|
|
282
|
-
delete?: DeleteRule | "*" | false | null;
|
|
283
|
-
sync?: SyncRule;
|
|
284
|
-
subscribe?: SubscribeRule | "*";
|
|
285
|
-
};
|
|
286
|
-
export type PublishViewRule = {
|
|
287
|
-
select: SelectRule | "*" | false | null;
|
|
288
|
-
};
|
|
289
|
-
// export type Publish = {
|
|
290
|
-
// tablesOrViews: {[key:string]: TableRule | ViewRule | "*" }
|
|
291
|
-
// }
|
|
292
|
-
export type RequestParams = { dbo?: DbHandler, socket?: any };
|
|
293
|
-
export type PublishAllOrNothing = "*" | false | null;
|
|
294
|
-
export type PublishObject = {
|
|
295
|
-
[table_name: string]: (PublishTableRule | PublishViewRule | PublishAllOrNothing )
|
|
296
|
-
};
|
|
297
|
-
export type PublishTable = {
|
|
298
|
-
[table_name: string]: (PublishTableRule | PublishViewRule)
|
|
299
|
-
};
|
|
300
|
-
export type PublishedResult = PublishAllOrNothing | PublishObject ;
|
|
301
|
-
export type PublishParams<DBO = DbHandler> = {
|
|
302
|
-
sid?: string;
|
|
303
|
-
dbo?: DBO;
|
|
304
|
-
db?: DB;
|
|
305
|
-
user?: AnyObject;
|
|
306
|
-
socket: PRGLIOSocket
|
|
307
|
-
}
|
|
308
|
-
export type Publish<DBO> = PublishedResult | ((params: PublishParams<DBO>) => (PublishedResult | Promise<PublishedResult>));
|
|
309
|
-
|
|
310
|
-
export type Method = (...args: any) => ( any | Promise<any> );
|
|
311
79
|
export const JOIN_TYPES = ["one-many", "many-one", "one-one", "many-many"] as const;
|
|
312
80
|
export type Join = {
|
|
313
81
|
tables: [string, string];
|
|
@@ -316,7 +84,6 @@ export type Join = {
|
|
|
316
84
|
};
|
|
317
85
|
export type Joins = Join[] | "inferred";
|
|
318
86
|
|
|
319
|
-
export type PublishMethods<DBO> = (params: PublishParams<DBO>) => { [key:string]: Method } | Promise<{ [key:string]: Method }>;
|
|
320
87
|
|
|
321
88
|
|
|
322
89
|
type Keywords = {
|
|
@@ -398,23 +165,23 @@ export type FileTableConfig = {
|
|
|
398
165
|
imageOptions?: ImageOptions
|
|
399
166
|
};
|
|
400
167
|
|
|
401
|
-
export type ProstglesInitOptions<
|
|
168
|
+
export type ProstglesInitOptions<S extends DBSchema = never> = {
|
|
402
169
|
dbConnection: DbConnection;
|
|
403
170
|
dbOptions?: DbConnectionOpts;
|
|
404
171
|
tsGeneratedTypesDir?: string;
|
|
405
172
|
io?: any;
|
|
406
|
-
publish?: Publish<
|
|
407
|
-
publishMethods?: PublishMethods<
|
|
408
|
-
publishRawSQL?(params: PublishParams<
|
|
173
|
+
publish?: Publish<S>;
|
|
174
|
+
publishMethods?: PublishMethods<S>;
|
|
175
|
+
publishRawSQL?(params: PublishParams<S>): ( (boolean | "*") | Promise<(boolean | "*")>);
|
|
409
176
|
joins?: Joins;
|
|
410
177
|
schema?: string;
|
|
411
178
|
sqlFilePath?: string;
|
|
412
|
-
onReady(dbo:
|
|
179
|
+
onReady(dbo: DBOFullyTyped<S>, db: DB): void;
|
|
413
180
|
transactions?: string | boolean;
|
|
414
181
|
wsChannelNamePrefix?: string;
|
|
415
|
-
onSocketConnect?(socket: PRGLIOSocket, dbo:
|
|
416
|
-
onSocketDisconnect?(socket: PRGLIOSocket, dbo:
|
|
417
|
-
auth?: Auth<
|
|
182
|
+
onSocketConnect?(socket: PRGLIOSocket, dbo: DBOFullyTyped<S>, db?: DB): any;
|
|
183
|
+
onSocketDisconnect?(socket: PRGLIOSocket, dbo: DBOFullyTyped<S>, db?: DB): any;
|
|
184
|
+
auth?: Auth<S>;
|
|
418
185
|
DEBUG_MODE?: boolean;
|
|
419
186
|
watchSchemaType?:
|
|
420
187
|
|
|
@@ -466,7 +233,7 @@ export type ProstglesInitOptions<DBO = DbHandler> = {
|
|
|
466
233
|
*/
|
|
467
234
|
|
|
468
235
|
export type OnReady = {
|
|
469
|
-
dbo:
|
|
236
|
+
dbo: DBHandlerServer;
|
|
470
237
|
db: DB;
|
|
471
238
|
}
|
|
472
239
|
|
|
@@ -478,9 +245,10 @@ const DEFAULT_KEYWORDS = {
|
|
|
478
245
|
};
|
|
479
246
|
|
|
480
247
|
import * as fs from 'fs';
|
|
481
|
-
|
|
248
|
+
import { DBOFullyTyped } from "./DBSchemaBuilder";
|
|
249
|
+
export class Prostgles<S extends DBSchema = any> {
|
|
482
250
|
|
|
483
|
-
opts: ProstglesInitOptions<
|
|
251
|
+
opts: ProstglesInitOptions<S> = {
|
|
484
252
|
DEBUG_MODE: false,
|
|
485
253
|
dbConnection: {
|
|
486
254
|
host: "localhost",
|
|
@@ -501,7 +269,7 @@ export class Prostgles<DBO = DbHandler> {
|
|
|
501
269
|
// dbOptions: DbConnectionOpts;
|
|
502
270
|
db?: DB;
|
|
503
271
|
pgp?: PGP;
|
|
504
|
-
dbo?:
|
|
272
|
+
dbo?: DBHandlerServer;
|
|
505
273
|
_dboBuilder?: DboBuilder;
|
|
506
274
|
get dboBuilder(): DboBuilder {
|
|
507
275
|
if(!this._dboBuilder) throw "get dboBuilder: it's undefined"
|
|
@@ -512,7 +280,7 @@ export class Prostgles<DBO = DbHandler> {
|
|
|
512
280
|
}
|
|
513
281
|
publishParser?: PublishParser;
|
|
514
282
|
|
|
515
|
-
authHandler?: AuthHandler
|
|
283
|
+
authHandler?: AuthHandler<S>;
|
|
516
284
|
|
|
517
285
|
|
|
518
286
|
keywords = DEFAULT_KEYWORDS;
|
|
@@ -641,8 +409,8 @@ export class Prostgles<DBO = DbHandler> {
|
|
|
641
409
|
|
|
642
410
|
isSuperUser = false;
|
|
643
411
|
schema_checkIntervalMillis: any;
|
|
644
|
-
async init(onReady: (dbo:
|
|
645
|
-
db:
|
|
412
|
+
async init(onReady: (dbo: DBOFullyTyped<S>, db: DB) => any): Promise<{
|
|
413
|
+
db: DBOFullyTyped<S>;
|
|
646
414
|
_db: DB;
|
|
647
415
|
pgp: PGP;
|
|
648
416
|
io?: any;
|
|
@@ -766,7 +534,7 @@ export class Prostgles<DBO = DbHandler> {
|
|
|
766
534
|
|
|
767
535
|
this.loaded = true;
|
|
768
536
|
return {
|
|
769
|
-
db: this.dbo
|
|
537
|
+
db: this.dbo! as any,
|
|
770
538
|
_db: db,
|
|
771
539
|
pgp,
|
|
772
540
|
io: this.opts.io,
|
|
@@ -935,24 +703,26 @@ export class Prostgles<DBO = DbHandler> {
|
|
|
935
703
|
// let DATA_TYPES = !needType? [] : await this.db.any("SELECT oid, typname FROM pg_type");
|
|
936
704
|
// let USER_TABLES = !needType? [] : await this.db.any("SELECT relid, relname FROM pg_catalog.pg_statio_user_tables");
|
|
937
705
|
|
|
938
|
-
|
|
706
|
+
const { dbo, db, pgp, publishParser } = this;
|
|
707
|
+
let fullSchema: {
|
|
708
|
+
schema: TableSchemaForClient;
|
|
709
|
+
tables: DBSchemaTable[];
|
|
710
|
+
} | undefined;
|
|
939
711
|
let publishValidationError;
|
|
940
712
|
let rawSQL = false;
|
|
941
713
|
|
|
942
|
-
const { dbo, db, pgp, publishParser } = this;
|
|
943
714
|
try {
|
|
944
715
|
if(!publishParser) throw "publishParser undefined";
|
|
945
|
-
|
|
716
|
+
fullSchema = await publishParser.getSchemaFromPublish(socket);
|
|
946
717
|
} catch(e){
|
|
947
718
|
publishValidationError = "Server Error: PUBLISH VALIDATION ERROR";
|
|
948
719
|
console.error(`\nProstgles PUBLISH VALIDATION ERROR (after socket connected):\n ->`, e);
|
|
949
720
|
}
|
|
950
721
|
socket.prostgles = socket.prostgles || {};
|
|
951
|
-
socket.prostgles.schema = schema;
|
|
722
|
+
socket.prostgles.schema = fullSchema?.schema;
|
|
952
723
|
/* RUN Raw sql from client IF PUBLISHED
|
|
953
724
|
*/
|
|
954
|
-
|
|
955
|
-
let allTablesViews = this.dboBuilder.tablesOrViews ?? [];
|
|
725
|
+
|
|
956
726
|
if(this.opts.publishRawSQL && typeof this.opts.publishRawSQL === "function"){
|
|
957
727
|
const canRunSQL = async () => {
|
|
958
728
|
const publishParams = await this.publishParser?.getPublishParams({ socket })
|
|
@@ -974,13 +744,13 @@ export class Prostgles<DBO = DbHandler> {
|
|
|
974
744
|
});
|
|
975
745
|
if(db){
|
|
976
746
|
// let allTablesViews = await db.any(STEP2_GET_ALL_TABLES_AND_COLUMNS);
|
|
977
|
-
fullSchema = allTablesViews;
|
|
747
|
+
// fullSchema = allTablesViews;
|
|
978
748
|
rawSQL = true;
|
|
979
749
|
} else console.error("db missing");
|
|
980
750
|
}
|
|
981
751
|
}
|
|
982
752
|
|
|
983
|
-
|
|
753
|
+
const { schema, tables } = fullSchema ?? { schema: {}, tables: [] };
|
|
984
754
|
let joinTables2: string[][] = [];
|
|
985
755
|
if(this.opts.joins){
|
|
986
756
|
// joinTables = Array.from(new Set(flat(this.dboBuilder.getJoins().map(j => j.tables)).filter(t => schema[t])));
|
|
@@ -999,7 +769,7 @@ export class Prostgles<DBO = DbHandler> {
|
|
|
999
769
|
const clientSchema: ClientSchema = {
|
|
1000
770
|
schema,
|
|
1001
771
|
methods: getKeys(methods),
|
|
1002
|
-
|
|
772
|
+
tableSchema: tables,
|
|
1003
773
|
rawSQL,
|
|
1004
774
|
joinTables: joinTables2,
|
|
1005
775
|
auth,
|
|
@@ -1031,95 +801,6 @@ type SocketMethodRequest = {
|
|
|
1031
801
|
params: any;
|
|
1032
802
|
}
|
|
1033
803
|
|
|
1034
|
-
|
|
1035
|
-
type Request = {
|
|
1036
|
-
socket?: any;
|
|
1037
|
-
httpReq?: any;
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
type DboTable = Request & {
|
|
1041
|
-
tableName: string;
|
|
1042
|
-
localParams: LocalParams;
|
|
1043
|
-
}
|
|
1044
|
-
type DboTableCommand = Request & DboTable & {
|
|
1045
|
-
command: string;
|
|
1046
|
-
localParams: LocalParams;
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
const RULE_TO_METHODS = [
|
|
1050
|
-
{
|
|
1051
|
-
rule: "getColumns",
|
|
1052
|
-
sqlRule: "select",
|
|
1053
|
-
methods: RULE_METHODS.getColumns,
|
|
1054
|
-
no_limits: true,
|
|
1055
|
-
allowed_params: [],
|
|
1056
|
-
table_only: false,
|
|
1057
|
-
hint: ` expecting false | true | undefined`
|
|
1058
|
-
},
|
|
1059
|
-
{
|
|
1060
|
-
rule: "getInfo",
|
|
1061
|
-
sqlRule: "select",
|
|
1062
|
-
methods: RULE_METHODS.getInfo,
|
|
1063
|
-
no_limits: true,
|
|
1064
|
-
allowed_params: [],
|
|
1065
|
-
table_only: false,
|
|
1066
|
-
hint: ` expecting false | true | undefined`
|
|
1067
|
-
},
|
|
1068
|
-
{
|
|
1069
|
-
rule: "insert",
|
|
1070
|
-
sqlRule: "insert",
|
|
1071
|
-
methods: RULE_METHODS.insert,
|
|
1072
|
-
no_limits: <SelectRule>{ fields: "*" },
|
|
1073
|
-
table_only: true,
|
|
1074
|
-
allowed_params: <Array<keyof InsertRule>>["fields", "forcedData", "returningFields", "validate", "preValidate"] ,
|
|
1075
|
-
hint: ` expecting "*" | true | { fields: string | string[] | {} }`
|
|
1076
|
-
},
|
|
1077
|
-
{
|
|
1078
|
-
rule: "update",
|
|
1079
|
-
sqlRule: "update",
|
|
1080
|
-
methods: RULE_METHODS.update,
|
|
1081
|
-
no_limits: <UpdateRule>{ fields: "*", filterFields: "*", returningFields: "*" },
|
|
1082
|
-
table_only: true,
|
|
1083
|
-
allowed_params: <Array<keyof UpdateRule>>["fields", "filterFields", "forcedFilter", "forcedData", "returningFields", "validate", "dynamicFields"] ,
|
|
1084
|
-
hint: ` expecting "*" | true | { fields: string | string[] | {} }`
|
|
1085
|
-
},
|
|
1086
|
-
{
|
|
1087
|
-
rule: "select",
|
|
1088
|
-
sqlRule: "select",
|
|
1089
|
-
methods: RULE_METHODS.select,
|
|
1090
|
-
no_limits: <SelectRule>{ fields: "*", filterFields: "*" },
|
|
1091
|
-
table_only: false,
|
|
1092
|
-
allowed_params: <Array<keyof SelectRule>>["fields", "filterFields", "forcedFilter", "validate", "maxLimit"] ,
|
|
1093
|
-
hint: ` expecting "*" | true | { fields: ( string | string[] | {} ) }`
|
|
1094
|
-
},
|
|
1095
|
-
{
|
|
1096
|
-
rule: "delete",
|
|
1097
|
-
sqlRule: "delete",
|
|
1098
|
-
methods: RULE_METHODS.delete,
|
|
1099
|
-
no_limits: <DeleteRule>{ filterFields: "*" } ,
|
|
1100
|
-
table_only: true,
|
|
1101
|
-
allowed_params: <Array<keyof DeleteRule>>["filterFields", "forcedFilter", "returningFields", "validate"] ,
|
|
1102
|
-
hint: ` expecting "*" | true | { filterFields: ( string | string[] | {} ) } \n Will use "select", "update", "delete" and "insert" rules`
|
|
1103
|
-
},
|
|
1104
|
-
{
|
|
1105
|
-
rule: "sync",
|
|
1106
|
-
sqlRule: "select",
|
|
1107
|
-
methods: RULE_METHODS.sync,
|
|
1108
|
-
no_limits: null,
|
|
1109
|
-
table_only: true,
|
|
1110
|
-
allowed_params: <Array<keyof SyncRule>>["id_fields", "synced_field", "sync_type", "allow_delete", "throttle", "batch_size"],
|
|
1111
|
-
hint: ` expecting "*" | true | { id_fields: string[], synced_field: string }`
|
|
1112
|
-
},
|
|
1113
|
-
{
|
|
1114
|
-
rule: "subscribe",
|
|
1115
|
-
sqlRule: "select",
|
|
1116
|
-
methods: RULE_METHODS.subscribe,
|
|
1117
|
-
no_limits: <SubscribeRule>{ throttle: 0 },
|
|
1118
|
-
table_only: true,
|
|
1119
|
-
allowed_params: <Array<keyof SubscribeRule>>["throttle"],
|
|
1120
|
-
hint: ` expecting "*" | true | { throttle: number } \n Will use "select" rules`
|
|
1121
|
-
}
|
|
1122
|
-
] as const;
|
|
1123
804
|
// const ALL_PUBLISH_METHODS = ["update", "upsert", "delete", "insert", "find", "findOne", "subscribe", "unsubscribe", "sync", "unsync", "remove"];
|
|
1124
805
|
// const ALL_PUBLISH_METHODS = RULE_TO_METHODS.map(r => r.methods).flat();
|
|
1125
806
|
|
|
@@ -1132,359 +813,7 @@ const RULE_TO_METHODS = [
|
|
|
1132
813
|
// return res;
|
|
1133
814
|
// }
|
|
1134
815
|
|
|
1135
|
-
export class PublishParser {
|
|
1136
|
-
publish: any;
|
|
1137
|
-
publishMethods?: any;
|
|
1138
|
-
publishRawSQL?: any;
|
|
1139
|
-
dbo: DbHandler;
|
|
1140
|
-
db: DB
|
|
1141
|
-
prostgles: Prostgles;
|
|
1142
|
-
|
|
1143
|
-
constructor(publish: any, publishMethods: any, publishRawSQL: any, dbo: DbHandler, db: DB, prostgles: Prostgles){
|
|
1144
|
-
this.publish = publish;
|
|
1145
|
-
this.publishMethods = publishMethods;
|
|
1146
|
-
this.publishRawSQL = publishRawSQL;
|
|
1147
|
-
this.dbo = dbo;
|
|
1148
|
-
this.db = db;
|
|
1149
|
-
this.prostgles = prostgles;
|
|
1150
|
-
|
|
1151
|
-
if(!this.dbo || !this.publish) throw "INTERNAL ERROR: dbo and/or publish missing";
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
async getPublishParams(localParams: LocalParams, clientInfo?: ClientInfo): Promise<PublishParams> {
|
|
1155
|
-
return {
|
|
1156
|
-
...(clientInfo || await this.prostgles.authHandler?.getClientInfo(localParams)),
|
|
1157
|
-
dbo: this.dbo,
|
|
1158
|
-
db: this.db,
|
|
1159
|
-
socket: localParams.socket!
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
async getMethods(socket: any){
|
|
1164
|
-
let methods = {};
|
|
1165
|
-
|
|
1166
|
-
const publishParams = await this.getPublishParams({ socket });
|
|
1167
|
-
const _methods = await applyParamsIfFunc(this.publishMethods, publishParams);
|
|
1168
|
-
|
|
1169
|
-
if(_methods && Object.keys(_methods).length){
|
|
1170
|
-
getKeys(_methods).map(key => {
|
|
1171
|
-
if(_methods[key] && (typeof _methods[key] === "function" || typeof _methods[key].then === "function")){
|
|
1172
|
-
//@ts-ignore
|
|
1173
|
-
methods[key] = _methods[key];
|
|
1174
|
-
} else {
|
|
1175
|
-
throw `invalid publishMethods item -> ${key} \n Expecting a function or promise`
|
|
1176
|
-
}
|
|
1177
|
-
});
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
return methods;
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
/**
|
|
1184
|
-
* Parses the first level of publish. (If false then nothing if * then all tables and views)
|
|
1185
|
-
* @param socket
|
|
1186
|
-
* @param user
|
|
1187
|
-
*/
|
|
1188
|
-
async getPublish(localParams: LocalParams, clientInfo?: ClientInfo): Promise<PublishObject> {
|
|
1189
|
-
const publishParams: PublishParams = await this.getPublishParams(localParams, clientInfo)
|
|
1190
|
-
let _publish = await applyParamsIfFunc(this.publish, publishParams );
|
|
1191
|
-
|
|
1192
|
-
if(_publish === "*"){
|
|
1193
|
-
let publish = {} as any;
|
|
1194
|
-
this.prostgles.dboBuilder.tablesOrViews?.map(tov => {
|
|
1195
|
-
publish[tov.name] = "*";
|
|
1196
|
-
});
|
|
1197
|
-
return publish;
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
return _publish;
|
|
1201
|
-
}
|
|
1202
|
-
async getValidatedRequestRuleWusr({ tableName, command, localParams }: DboTableCommand): Promise<TableRule>{
|
|
1203
|
-
const clientInfo = await this.prostgles.authHandler!.getClientInfo(localParams);
|
|
1204
|
-
return await this.getValidatedRequestRule({ tableName, command, localParams }, clientInfo);
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
async getValidatedRequestRule({ tableName, command, localParams }: DboTableCommand, clientInfo?: ClientInfo): Promise<TableRule>{
|
|
1208
|
-
if(!this.dbo) throw "INTERNAL ERROR: dbo is missing";
|
|
1209
|
-
|
|
1210
|
-
if(!command || !tableName) throw "command OR tableName are missing";
|
|
1211
816
|
|
|
1212
|
-
let rtm = RULE_TO_METHODS.find(rtms => (rtms.methods as any).includes(command));
|
|
1213
|
-
if(!rtm){
|
|
1214
|
-
throw "Invalid command: " + command;
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
|
-
/* Must be local request -> allow everything */
|
|
1218
|
-
if(!localParams || (!localParams.socket && !localParams.httpReq)){
|
|
1219
|
-
return RULE_TO_METHODS.reduce((a, v) => ({
|
|
1220
|
-
...a,
|
|
1221
|
-
[v.rule]: v.no_limits
|
|
1222
|
-
}), {})
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
/* Must be from socket. Must have a publish */
|
|
1226
|
-
if(!this.publish) throw "publish is missing";
|
|
1227
|
-
|
|
1228
|
-
/* Get any publish errors for socket */
|
|
1229
|
-
const schm = localParams?.socket?.prostgles?.schema?.[tableName]?.[command];
|
|
1230
|
-
|
|
1231
|
-
if(schm && schm.err) throw schm.err;
|
|
1232
|
-
|
|
1233
|
-
let table_rule = await this.getTableRules({ tableName, localParams }, clientInfo);
|
|
1234
|
-
if(!table_rule) throw "Invalid or disallowed table: " + tableName;
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
if(command === "upsert"){
|
|
1238
|
-
if(!table_rule.update || !table_rule.insert){
|
|
1239
|
-
throw `Invalid or disallowed command: upsert`;
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
if(rtm && table_rule && table_rule[rtm.rule]){
|
|
1244
|
-
return table_rule;
|
|
1245
|
-
} else throw `Invalid or disallowed command: ${tableName}.${command}`;
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
async getTableRules({ tableName, localParams }: DboTable, clientInfo?: ClientInfo): Promise<PublishTable> {
|
|
1249
|
-
|
|
1250
|
-
try {
|
|
1251
|
-
if(!localParams || !tableName) throw "publish OR socket OR dbo OR tableName are missing";
|
|
1252
|
-
|
|
1253
|
-
let _publish = await this.getPublish(localParams, clientInfo);
|
|
1254
|
-
|
|
1255
|
-
let table_rules = _publish[tableName];// applyParamsIfFunc(_publish[tableName], localParams, this.dbo, this.db, user);
|
|
1256
|
-
|
|
1257
|
-
/* Get view or table specific rules */
|
|
1258
|
-
const tHandler = (this.dbo[tableName] as TableHandler | ViewHandler);
|
|
1259
|
-
|
|
1260
|
-
const is_view = tHandler.is_view,
|
|
1261
|
-
MY_RULES = RULE_TO_METHODS.filter(r => !is_view || !r.table_only);
|
|
1262
|
-
|
|
1263
|
-
// if(tableName === "various") console.warn(1033, MY_RULES)
|
|
1264
|
-
if(table_rules){
|
|
1265
|
-
|
|
1266
|
-
/* All methods allowed. Add no limits for table rules */
|
|
1267
|
-
if([true, "*"].includes(table_rules as any)){
|
|
1268
|
-
table_rules = {};
|
|
1269
|
-
MY_RULES.map(r => {
|
|
1270
|
-
/** Check PG User privileges */
|
|
1271
|
-
if(
|
|
1272
|
-
tHandler.tableOrViewInfo.privileges[r.sqlRule]
|
|
1273
|
-
){
|
|
1274
|
-
// @ts-ignore
|
|
1275
|
-
table_rules[r.rule] = { ...(r as any).no_limits } as any;
|
|
1276
|
-
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
});
|
|
1280
|
-
// if(tableName === "various") console.warn(1042, table_rules)
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
|
-
/* Add missing implied rules */
|
|
1284
|
-
MY_RULES.map(r => {
|
|
1285
|
-
|
|
1286
|
-
if(["getInfo", "getColumns"].includes(r.rule) && ![null, false, 0].includes((table_rules as any)[r.rule])){
|
|
1287
|
-
// @ts-ignore
|
|
1288
|
-
table_rules[r.rule] = r.no_limits;
|
|
1289
|
-
return ;
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
/* Add nested properties for fully allowed rules */
|
|
1293
|
-
// @ts-ignore
|
|
1294
|
-
if ([true, "*"].includes(table_rules[r.rule]) && r.no_limits) {
|
|
1295
|
-
// @ts-ignore
|
|
1296
|
-
table_rules[r.rule] = Object.assign({}, r.no_limits);
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
|
-
// @ts-ignore
|
|
1300
|
-
if(table_rules[r.rule]){
|
|
1301
|
-
/* Add implied methods if not falsy */
|
|
1302
|
-
// @ts-ignore
|
|
1303
|
-
r.methods.forEach(method => {
|
|
1304
|
-
// @ts-ignore
|
|
1305
|
-
if(table_rules[method] === undefined){
|
|
1306
|
-
const publishedTable = (table_rules as PublishTable);
|
|
1307
|
-
if(method === "updateBatch" && !publishedTable.update){
|
|
1308
|
-
|
|
1309
|
-
} else if(method === "upsert" && (!publishedTable.update || !publishedTable.insert)){
|
|
1310
|
-
// return;
|
|
1311
|
-
} else {
|
|
1312
|
-
// @ts-ignore
|
|
1313
|
-
table_rules[method] = {};
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
});
|
|
1317
|
-
}
|
|
1318
|
-
// if(tableName === "v_various") console.warn(table_rules, r)
|
|
1319
|
-
});
|
|
1320
|
-
|
|
1321
|
-
/*
|
|
1322
|
-
Add defaults
|
|
1323
|
-
Check for invalid params
|
|
1324
|
-
*/
|
|
1325
|
-
if(table_rules && getKeys(table_rules).length && table_rules !== "*"){
|
|
1326
|
-
const ruleKeys = getKeys(table_rules as PublishTableRule | PublishViewRule)
|
|
1327
|
-
|
|
1328
|
-
// @ts-ignore
|
|
1329
|
-
ruleKeys.filter(m => table_rules[m])
|
|
1330
|
-
.find(method => {
|
|
1331
|
-
let rm = MY_RULES.find(r => r.rule === method || (r.methods as any).includes(method));
|
|
1332
|
-
if(!rm){
|
|
1333
|
-
throw `Invalid rule in publish.${tableName} -> ${method} \nExpecting any of: ${MY_RULES.flatMap(r => [r.rule, ...r.methods]).join(", ")}`;
|
|
1334
|
-
}
|
|
1335
|
-
|
|
1336
|
-
/** Check user privileges */
|
|
1337
|
-
if(!tHandler.tableOrViewInfo.privileges[rm.sqlRule]){
|
|
1338
|
-
// @ts-ignore
|
|
1339
|
-
delete table_rules![method];
|
|
1340
|
-
return;
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1343
|
-
/* Check RULES for invalid params */
|
|
1344
|
-
/* Methods do not have params -> They use them from rules */
|
|
1345
|
-
if(method === rm.rule){
|
|
1346
|
-
// @ts-ignore
|
|
1347
|
-
let method_params = getKeys(table_rules![method]);
|
|
1348
|
-
let iparam = method_params.find(p => !rm?.allowed_params.includes(<never>p));
|
|
1349
|
-
if(iparam){
|
|
1350
|
-
throw `Invalid setting in publish.${tableName}.${method} -> ${iparam}. \n Expecting any of: ${rm.allowed_params.join(", ")}`;
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
/* Add default params (if missing) */
|
|
1355
|
-
// @ts-ignore
|
|
1356
|
-
if(method === "sync"){
|
|
1357
|
-
|
|
1358
|
-
// @ts-ignore
|
|
1359
|
-
if([true, "*"].includes(table_rules![method])){
|
|
1360
|
-
throw "Invalid sync rule. Expecting { id_fields: string[], synced_field: string } ";
|
|
1361
|
-
}
|
|
1362
|
-
if(typeof get(table_rules, [method, "throttle"]) !== "number"){
|
|
1363
|
-
// @ts-ignore
|
|
1364
|
-
table_rules![method].throttle = 100;
|
|
1365
|
-
}
|
|
1366
|
-
if(typeof get(table_rules, [method, "batch_size"]) !== "number"){
|
|
1367
|
-
// @ts-ignore
|
|
1368
|
-
table_rules![method].batch_size = DEFAULT_SYNC_BATCH_SIZE;
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
/* Enable subscribe if not explicitly disabled */
|
|
1373
|
-
// @ts-ignore
|
|
1374
|
-
if(method === "select" && !ruleKeys.includes("subscribe")){
|
|
1375
|
-
const sr = MY_RULES.find(r => r.rule === "subscribe");
|
|
1376
|
-
if(sr){
|
|
1377
|
-
// @ts-ignore
|
|
1378
|
-
table_rules[sr.rule] = { ...sr.no_limits };
|
|
1379
|
-
// @ts-ignore
|
|
1380
|
-
(table_rules as PublishTable).subscribeOne = { ...sr.no_limits };
|
|
1381
|
-
}
|
|
1382
|
-
}
|
|
1383
|
-
});
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
return table_rules as PublishTable;
|
|
1388
|
-
} catch (e) {
|
|
1389
|
-
throw e;
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
/* Prepares schema for client. Only allowed views and commands will be present */
|
|
1396
|
-
async getSchemaFromPublish(socket: any): Promise<TableSchemaForClient> {
|
|
1397
|
-
let schema: TableSchemaForClient = {};
|
|
1398
|
-
|
|
1399
|
-
try {
|
|
1400
|
-
/* Publish tables and views based on socket */
|
|
1401
|
-
const clientInfo = await this.prostgles.authHandler?.getClientInfo({ socket });
|
|
1402
|
-
let _publish = await this.getPublish(socket, clientInfo);
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
if(_publish && Object.keys(_publish).length){
|
|
1406
|
-
let txKey = "tx";
|
|
1407
|
-
if(!this.prostgles.opts.transactions) txKey = "";
|
|
1408
|
-
if(typeof this.prostgles.opts.transactions === "string") txKey = this.prostgles.opts.transactions;
|
|
1409
|
-
|
|
1410
|
-
const tableNames = Object.keys(_publish).filter(k => !txKey || txKey !== k);
|
|
1411
|
-
|
|
1412
|
-
await Promise.all(tableNames
|
|
1413
|
-
.map(async tableName => {
|
|
1414
|
-
if(!this.dbo[tableName]) {
|
|
1415
|
-
throw `Table ${tableName} does not exist
|
|
1416
|
-
Expecting one of: ${this.prostgles.dboBuilder.tablesOrViews?.map(tov => tov.name).join(", ")}
|
|
1417
|
-
DBO tables: ${Object.keys(this.dbo).filter(k => (this.dbo[k] as any).find).join(", ")}
|
|
1418
|
-
`;
|
|
1419
|
-
}
|
|
1420
|
-
|
|
1421
|
-
const table_rules = await this.getTableRules({ localParams: {socket}, tableName }, clientInfo);
|
|
1422
|
-
|
|
1423
|
-
// if(tableName === "insert_rule") throw {table_rules}
|
|
1424
|
-
if(table_rules && Object.keys(table_rules).length){
|
|
1425
|
-
schema[tableName] = {};
|
|
1426
|
-
let methods: Array<MethodKey> = [];
|
|
1427
|
-
|
|
1428
|
-
if(typeof table_rules === "object"){
|
|
1429
|
-
methods = getKeys(table_rules) as any;
|
|
1430
|
-
}
|
|
1431
|
-
|
|
1432
|
-
await Promise.all(methods.filter(m => m !== "select" as any).map(async method => {
|
|
1433
|
-
if(method === "sync" && table_rules[method]){
|
|
1434
|
-
|
|
1435
|
-
/* Pass sync info */
|
|
1436
|
-
schema[tableName][method] = table_rules[method];
|
|
1437
|
-
} else if(table_rules[method]) {
|
|
1438
|
-
|
|
1439
|
-
schema[tableName][method] = {};
|
|
1440
|
-
|
|
1441
|
-
/* Test for issues with the publish rules */
|
|
1442
|
-
if(TABLE_METHODS.includes(method)){
|
|
1443
|
-
|
|
1444
|
-
let err = null;
|
|
1445
|
-
try {
|
|
1446
|
-
let valid_table_command_rules = await this.getValidatedRequestRule({ tableName, command: method, localParams: {socket} }, clientInfo);
|
|
1447
|
-
await (this.dbo[tableName] as any)[method]({}, {}, {}, valid_table_command_rules, { socket, has_rules: true, testRule: true });
|
|
1448
|
-
|
|
1449
|
-
} catch(e) {
|
|
1450
|
-
err = "INTERNAL PUBLISH ERROR";
|
|
1451
|
-
schema[tableName][method] = { err };
|
|
1452
|
-
|
|
1453
|
-
throw `publish.${tableName}.${method}: \n -> ${e}`;
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
|
-
}));
|
|
1458
|
-
}
|
|
1459
|
-
|
|
1460
|
-
return true;
|
|
1461
|
-
})
|
|
1462
|
-
);
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
} catch (e) {
|
|
1467
|
-
console.error("Prostgles \nERRORS IN PUBLISH: ", JSON.stringify(e));
|
|
1468
|
-
throw e;
|
|
1469
|
-
}
|
|
1470
|
-
|
|
1471
|
-
return schema;
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
}
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
function applyParamsIfFunc(maybeFunc: any, ...params: any): any{
|
|
1479
|
-
if(
|
|
1480
|
-
(maybeFunc !== null && maybeFunc !== undefined) &&
|
|
1481
|
-
(typeof maybeFunc === "function" || typeof maybeFunc.then === "function")
|
|
1482
|
-
){
|
|
1483
|
-
return maybeFunc(...params);
|
|
1484
|
-
}
|
|
1485
|
-
|
|
1486
|
-
return maybeFunc;
|
|
1487
|
-
}
|
|
1488
817
|
|
|
1489
818
|
export async function isSuperUser(db: DB): Promise<boolean>{
|
|
1490
819
|
return db.oneOrNone("select usesuper from pg_user where usename = CURRENT_USER;").then(r => r.usesuper);
|