prostgles-server 4.2.2 → 4.2.4

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/dist/my.d.ts ADDED
@@ -0,0 +1,1655 @@
1
+ // Generated by dts-bundle-generator v9.2.1
2
+
3
+ import { Express as Express$1, NextFunction, Request, Response } from 'express';
4
+ import * as pg from 'pg';
5
+ import CursorType from 'pg-cursor';
6
+ import {
7
+ ALLOWED_CONTENT_TYPE, ALLOWED_EXTENSION, ClientSchema, ColumnInfo, DBSchema, DbJoinMaker, DeleteParams, EXISTS_KEY, FieldFilter, FileColumnConfig,
8
+ FullFilter, InsertParams, JSONB, Method, PG_COLUMN_UDT_DATA_TYPE, RawJoinPath, SQLHandler, SQLOptions, Select, SelectParams, SocketSQLStreamServer, SubscribeParams, TableHandler, TableInfo, TableInfo as TInfo, UpdateParams, ValidatedColumnInfo, ViewHandler, WAL
9
+ } from 'prostgles-types';
10
+ type AnyObject = Record<string, any>;
11
+ import { Server } from 'socket.io';
12
+ import * as stream from 'stream';
13
+
14
+ export type Awaitable<T> = T | Promise<T>;
15
+ export type AuthSocketSchema = {
16
+ user?: AnyObject;
17
+ register?: boolean;
18
+ login?: boolean;
19
+ logout?: boolean;
20
+ pathGuard?: boolean;
21
+ };
22
+ export type ExpressReq = Request;
23
+ export type ExpressRes = Response;
24
+ export type LoginClientInfo = {
25
+ ip_address: string;
26
+ ip_address_remote: string | undefined;
27
+ x_real_ip: string | undefined;
28
+ user_agent: string | undefined;
29
+ };
30
+ export type BasicSession = {
31
+ /** Must be hard to bruteforce */
32
+ sid: string;
33
+ /** UNIX millisecond timestamp */
34
+ expires: number;
35
+ /** On expired */
36
+ onExpiration: "redirect" | "show_error";
37
+ };
38
+ export type AuthClientRequest = {
39
+ socket: PRGLIOSocket;
40
+ } | {
41
+ httpReq: ExpressReq;
42
+ };
43
+ export type UserLike = {
44
+ id: string;
45
+ type: string;
46
+ [key: string]: any;
47
+ };
48
+ export type SessionUser<ServerUser extends UserLike = UserLike, ClientUser extends AnyObject = AnyObject> = {
49
+ /**
50
+ * This user will be available in all serverside prostgles options
51
+ * id and type values will be available in the prostgles.user session variable in postgres
52
+ * */
53
+ user: ServerUser;
54
+ /**
55
+ * Controls which fields from user are available in postgres session variable
56
+ */
57
+ sessionFields?: FieldFilter<ServerUser>;
58
+ /**
59
+ * User data sent to the authenticated client
60
+ */
61
+ clientUser: ClientUser;
62
+ };
63
+ export type AuthResult<SU = SessionUser> = SU & {
64
+ sid: string;
65
+ } | {
66
+ user?: undefined;
67
+ clientUser?: undefined;
68
+ sid?: string;
69
+ } | undefined;
70
+ export type AuthRequestParams<S, SUser extends SessionUser> = {
71
+ db: DB$1;
72
+ dbo: DBOFullyTyped<S>;
73
+ getUser: () => Promise<AuthResult<SUser>>;
74
+ };
75
+ export type ParsedJoinPath = {
76
+ table: string;
77
+ on: Record<string, string>[];
78
+ };
79
+ export type GetQueryArgs = {
80
+ allColumns: ColumnInfo[];
81
+ allowedFields: string[];
82
+ args: any[];
83
+ tableAlias?: string;
84
+ ctidField?: string;
85
+ };
86
+ export type FieldSpec = {
87
+ name: string;
88
+ type: "column" | "computed";
89
+ /**
90
+ * allowedFields passed for multicol functions (e.g.: $rowhash)
91
+ */
92
+ getQuery: (params: Omit<GetQueryArgs, "args">) => string;
93
+ };
94
+ declare class TableHandler$1 extends ViewHandler$1 {
95
+ constructor(db: DB$1, tableOrViewInfo: TableSchema, dboBuilder: DboBuilder, tx?: {
96
+ t: any
97
+ dbTX: TableHandlers;
98
+ }, joinPaths?: JoinPaths);
99
+ getFinalDBtx: (localParams: LocalParams | undefined) => TableHandlers | undefined;
100
+ getFinalDbo: (localParams: LocalParams | undefined) => TableHandlers;
101
+ parseUpdateRules: (filter: Filter, newData: AnyObject, params?: UpdateParams | undefined, tableRules?: TableRule | undefined, localParams?: LocalParams | undefined) => Promise<{
102
+ fields: string[];
103
+ validateRow?: ValidateRow | undefined;
104
+ finalUpdateFilter: AnyObject;
105
+ forcedData?: AnyObject | undefined;
106
+ forcedFilter?: AnyObject | undefined;
107
+ returningFields: FieldFilter;
108
+ filterFields?: FieldFilter | undefined;
109
+ }>;
110
+ update: (filter: Filter, _newData: AnyObject, params?: UpdateParams | undefined, tableRules?: TableRule | undefined, localParams?: LocalParams | undefined) => Promise<void | AnyObject>;
111
+ updateBatch: (updates: [
112
+ Filter,
113
+ AnyObject
114
+ ][], params?: UpdateParams | undefined, tableRules?: TableRule | undefined, localParams?: LocalParams | undefined) => Promise<any>;
115
+ validateNewData({ row, forcedData, allowedFields, tableRules, fixIssues }: ValidatedParams): {
116
+ data: AnyObject;
117
+ allowedCols: string[];
118
+ };
119
+ insert(rowOrRows: (AnyObject | AnyObject[]), param2?: InsertParams, param3_unused?: undefined, tableRules?: TableRule, _localParams?: LocalParams): Promise<any | any[] | boolean>;
120
+ prepareReturning: (returning: Select | undefined, allowedFields: string[]) => Promise<SelectItem[]>;
121
+ makeReturnQuery(items?: SelectItem[]): string;
122
+ delete(filter?: Filter, params?: DeleteParams, param3_unused?: undefined, table_rules?: TableRule, localParams?: LocalParams): Promise<any>;
123
+ remove(filter: Filter, params?: UpdateParams, param3_unused?: undefined, tableRules?: TableRule, localParams?: LocalParams): Promise<any>;
124
+ upsert(filter: Filter, newData: AnyObject, params?: UpdateParams, table_rules?: TableRule, localParams?: LocalParams): Promise<any>;
125
+ sync(filter: Filter, params: {
126
+ select?: FieldFilter;
127
+ }, param3_unused: undefined, table_rules: TableRule, localParams: LocalParams): Promise<{
128
+ channelName: string | undefined;
129
+ id_fields: string[];
130
+ synced_field: string;
131
+ }>;
132
+ }
133
+ export type ClientInfo = {
134
+ socketId: string;
135
+ sid: string | undefined;
136
+ };
137
+ export type Graph = {
138
+ [key: string]: {
139
+ [key: string]: number;
140
+ };
141
+ };
142
+ declare class ColSet {
143
+ opts: {
144
+ columns: ColumnInfo[];
145
+ tableName: string;
146
+ colNames: string[];
147
+ };
148
+ constructor(columns: ColumnInfo[], tableName: string);
149
+ private getRow;
150
+ getInsertQuery(data: AnyObject[], allowedCols: string[], dbTx: DBHandlerServer, validate: ValidateRowBasic | undefined, localParams: LocalParams | undefined): Promise<string>;
151
+ getUpdateQuery(data: AnyObject | AnyObject[], allowedCols: string[], dbTx: DBHandlerServer, validate: ValidateRowBasic | undefined, localParams: LocalParams | undefined): Promise<string>;
152
+ }
153
+ export type JoinPaths = {
154
+ t1: string;
155
+ t2: string;
156
+ path: string[];
157
+ }[];
158
+ declare class ViewHandler$1 {
159
+ db: DB$1;
160
+ name: string;
161
+ escapedName: string;
162
+ columns: TableSchema["columns"];
163
+ columnsForTypes: ColumnInfo[];
164
+ column_names: string[];
165
+ tableOrViewInfo: TableSchema;
166
+ colSet: ColSet;
167
+ tsColumnDefs: string[];
168
+ joins: Join[];
169
+ joinGraph?: Graph;
170
+ joinPaths?: JoinPaths;
171
+ dboBuilder: DboBuilder;
172
+ tx?: {
173
+ t: any
174
+ dbTX: TableHandlers;
175
+ };
176
+ get dbHandler(): DB$1 | any
177
+ is_view: boolean;
178
+ filterDef: string;
179
+ is_media: boolean;
180
+ constructor(db: DB$1, tableOrViewInfo: TableSchema, dboBuilder: DboBuilder, tx?: {
181
+ t: any
182
+ dbTX: TableHandlers;
183
+ }, joinPaths?: JoinPaths);
184
+ _log: ({ command, data, localParams }: Pick<TableEvent, "command" | "data" | "localParams">) => Promise<void> | undefined;
185
+ getRowHashSelect(allowedFields: FieldFilter, alias?: string, tableAlias?: string): string;
186
+ validateViewRules: (args: {
187
+ fields?: FieldFilter | undefined;
188
+ filterFields?: FieldFilter | undefined;
189
+ returningFields?: FieldFilter | undefined;
190
+ forcedFilter?: AnyObject | undefined;
191
+ dynamicFields?: {
192
+ filter: import("prostgles-types").FullFilter<AnyObject, void>;
193
+ fields: FieldFilter<AnyObject>;
194
+ }[] | undefined;
195
+ rule: "update" | "insert" | "delete" | "select";
196
+ }) => Promise<boolean>;
197
+ getShortestJoin(table1: string, table2: string, startAlias: number, isInner?: boolean): {
198
+ query: string;
199
+ toOne: boolean;
200
+ };
201
+ checkFilter(filter: any): void;
202
+ getInfo: (lang?: string | undefined, param2?: any, param3?: any, tableRules?: TableRule | undefined, localParams?: LocalParams | undefined) => Promise<import("prostgles-types").TableInfo>;
203
+ getColumns: (lang?: string | undefined, params?: {
204
+ rule: "update";
205
+ filter: AnyObject;
206
+ data: AnyObject;
207
+ } | undefined, _param3?: undefined, tableRules?: TableRule | undefined, localParams?: LocalParams | undefined) => Promise<import("prostgles-types").ValidatedColumnInfo[]>;
208
+ getValidatedRules(tableRules?: TableRule, localParams?: LocalParams): ValidatedTableRules;
209
+ find: (filter?: Filter | undefined, selectParams?: SelectParams | undefined, _?: undefined, tableRules?: TableRule | undefined, localParams?: LocalParams | undefined) => Promise<any[]>;
210
+ findOne(filter?: Filter, selectParams?: SelectParams, param3_unused?: undefined, table_rules?: TableRule, localParams?: LocalParams): Promise<any>;
211
+ subscribe(filter: Filter, params: SubscribeParams, localFuncs: LocalFuncs): Promise<{
212
+ unsubscribe: () => any;
213
+ }>;
214
+ subscribe(filter: Filter, params: SubscribeParams, localFuncs: undefined, table_rules: TableRule | undefined, localParams: LocalParams): Promise<string>;
215
+ subscribeOne(filter: Filter, params: SubscribeParams, localFunc: (item: AnyObject) => any): Promise<{
216
+ unsubscribe: () => any;
217
+ }>;
218
+ subscribeOne(filter: Filter, params: SubscribeParams, localFunc: undefined, table_rules: TableRule, localParams: LocalParams): Promise<string>;
219
+ count(_filter?: Filter, selectParams?: SelectParams, param3_unused?: undefined, table_rules?: TableRule, localParams?: LocalParams): Promise<number>;
220
+ size(_filter?: Filter, selectParams?: SelectParams, param3_unused?: undefined, table_rules?: TableRule, localParams?: LocalParams): Promise<string>;
221
+ getAllowedSelectFields(selectParams: FieldFilter | undefined, allowed_cols: FieldFilter, allow_empty?: boolean): string[];
222
+ /**
223
+ * Parses group or simple filter
224
+ */
225
+ prepareWhere: (params: {
226
+ filter?: Filter | undefined;
227
+ select?: SelectItem[] | undefined;
228
+ forcedFilter?: AnyObject | undefined;
229
+ filterFields?: FieldFilter | undefined;
230
+ addWhere?: boolean | undefined;
231
+ tableAlias?: string | undefined;
232
+ localParams: LocalParams | undefined;
233
+ tableRule: TableRule | undefined;
234
+ }) => Promise<{
235
+ condition: string;
236
+ where: string;
237
+ filter: AnyObject;
238
+ exists: ExistsFilterConfig[];
239
+ }>;
240
+ prepareLimitQuery(limit: number | null | undefined, p: ValidatedTableRules): number | null;
241
+ prepareOffsetQuery(offset?: number): number;
242
+ intersectColumns(allowedFields: FieldFilter, dissallowedFields: FieldFilter, fixIssues?: boolean): string[];
243
+ /**
244
+ * Prepare and validate field object:
245
+ * @example ({ item_id: 1 }, { user_id: 32 }) => { item_id: 1, user_id: 32 }
246
+ * OR
247
+ * ({ a: 1 }, { b: 32 }, ["c", "d"]) => throw "a field is not allowed"
248
+ * @param {Object} obj - initial data
249
+ * @param {Object} forcedData - set/override property
250
+ * @param {string[]} allowed_cols - allowed columns (excluding forcedData) from table rules
251
+ */
252
+ prepareFieldValues(obj: AnyObject | undefined, forcedData: AnyObject | undefined, allowed_cols: FieldFilter | undefined, removeDisallowedColumns?: boolean): AnyObject;
253
+ parseFieldFilter(fieldParams?: FieldFilter, allow_empty?: boolean, allowed_cols?: string[]): string[];
254
+ }
255
+ export type OnData = (items: AnyObject[]) => any;
256
+ export type LocalFuncs = {
257
+ onData: OnData;
258
+ onError?: (error: any) => void;
259
+ } | OnData;
260
+ export type ClientSyncInfo = Partial<{
261
+ c_fr: AnyObject;
262
+ c_lr: AnyObject;
263
+ /**
264
+ * PG count is ussually string due to bigint
265
+ */
266
+ c_count: number | string;
267
+ }>;
268
+ export type ClientExpressData = ClientSyncInfo & {
269
+ data?: AnyObject[];
270
+ deleted?: AnyObject[];
271
+ };
272
+ export type BasicCallback = (err?: any, res?: any) => void;
273
+ export type SyncParams = {
274
+ socket_id: string;
275
+ channel_name: string;
276
+ table_name: string;
277
+ table_rules?: TableRule;
278
+ synced_field: string;
279
+ allow_delete: boolean;
280
+ id_fields: string[];
281
+ batch_size: number;
282
+ filter: object;
283
+ params: {
284
+ select: FieldFilter;
285
+ };
286
+ condition: string;
287
+ wal?: WAL;
288
+ throttle?: number;
289
+ lr?: AnyObject;
290
+ last_synced: number;
291
+ is_syncing: boolean;
292
+ };
293
+ export type AddSyncParams = {
294
+ socket: PRGLIOSocket;
295
+ table_info: TableInfo$1;
296
+ table_rules: TableRule;
297
+ synced_field: string;
298
+ allow_delete?: boolean;
299
+ id_fields: string[];
300
+ filter: object;
301
+ params: {
302
+ select: FieldFilter;
303
+ };
304
+ condition: string;
305
+ throttle?: number;
306
+ };
307
+ export type ViewSubscriptionOptions = ({
308
+ type: "view";
309
+ viewName: string;
310
+ definition: string;
311
+ } | {
312
+ type: "table";
313
+ viewName?: undefined;
314
+ definition?: undefined;
315
+ }) & {
316
+ relatedTables: {
317
+ tableName: string;
318
+ tableNameEscaped: string;
319
+ condition: string;
320
+ }[];
321
+ };
322
+ export type SubscriptionParams = Pick<SubscribeParams, "throttle" | "throttleOpts"> & {
323
+ socket_id?: string;
324
+ channel_name: string;
325
+ /**
326
+ * If this is a view then an array with all related tables will be
327
+ * */
328
+ viewOptions?: ViewSubscriptionOptions;
329
+ parentSubParams: Omit<SubscriptionParams, "parentSubParams"> | undefined;
330
+ table_info: TableOrViewInfo;
331
+ table_rules?: TableRule;
332
+ filter: object;
333
+ params: SelectParams;
334
+ localFuncs?: LocalFuncs;
335
+ socket: PRGLIOSocket | undefined;
336
+ last_throttled: number;
337
+ is_throttling?: any;
338
+ is_ready?: boolean;
339
+ };
340
+ export type PubSubManagerOptions = {
341
+ dboBuilder: DboBuilder;
342
+ wsChannelNamePrefix?: string;
343
+ pgChannelName?: string;
344
+ onSchemaChange?: (event: {
345
+ command: string;
346
+ query: string;
347
+ }) => void;
348
+ };
349
+ export type Subscription = Pick<SubscriptionParams, "throttle" | "is_throttling" | "last_throttled" | "throttleOpts" | "channel_name" | "is_ready" | "localFuncs" | "socket" | "socket_id" | "table_info" | "filter" | "params" | "table_rules"> & {
350
+ triggers: {
351
+ table_name: string;
352
+ condition: string;
353
+ is_related: boolean;
354
+ }[];
355
+ };
356
+ declare class PubSubManager {
357
+ static DELIMITER: "|$prstgls$|";
358
+ static SCHEMA_ALTERING_QUERIES: readonly [
359
+ "CREATE TABLE",
360
+ "ALTER TABLE",
361
+ "DROP TABLE",
362
+ "CREATE VIEW",
363
+ "DROP VIEW",
364
+ "ALTER VIEW",
365
+ "CREATE TABLE AS",
366
+ "SELECT INTO",
367
+ "REVOKE",
368
+ "GRANT",
369
+ "CREATE POLICY",
370
+ "DROP POLICY"
371
+ ];
372
+ static EXCLUDE_QUERY_FROM_SCHEMA_WATCH_ID: "prostgles internal query that should be excluded from schema watch ";
373
+ static canCreate: (db: DB$1) => Promise<{
374
+ canExecute: boolean;
375
+ isSuperUs: boolean;
376
+ yes: boolean;
377
+ }>;
378
+ static create: (options: PubSubManagerOptions) => Promise<PubSubManager | undefined>;
379
+ get db(): DB$1;
380
+ get dbo(): DBHandlerServer;
381
+ dboBuilder: DboBuilder;
382
+ _triggers?: Record<string, string[]>;
383
+ sockets: AnyObject;
384
+ subs: Subscription[];
385
+ syncs: SyncParams[];
386
+ socketChannelPreffix: string;
387
+ onSchemaChange?: ((event: {
388
+ command: string;
389
+ query: string;
390
+ }) => void);
391
+ postgresNotifListenManager?: PostgresNotifListenManager;
392
+ private constructor();
393
+ NOTIF_TYPE: {
394
+ readonly data: "data_has_changed";
395
+ readonly data_trigger_change: "data_watch_triggers_have_changed";
396
+ readonly schema: "schema_has_changed";
397
+ };
398
+ NOTIF_CHANNEL: {
399
+ preffix: "prostgles_";
400
+ getFull: (appID?: string) => string;
401
+ };
402
+ /**
403
+ * Used facilitate concurrent prostgles connections to the same database
404
+ */
405
+ appID?: string;
406
+ appCheckFrequencyMS: number;
407
+ appCheck?: ReturnType<typeof setInterval>;
408
+ destroyed: boolean;
409
+ destroy: () => void;
410
+ canContinue: () => boolean;
411
+ appChecking: boolean;
412
+ checkedListenerTableCond?: string[];
413
+ init: () => Promise<PubSubManager | undefined>;
414
+ initialiseEventTriggers: () => Promise<boolean>;
415
+ isReady(): any;
416
+ getClientSubs(client: Pick<Subscription, "localFuncs" | "socket_id" | "channel_name">): Subscription[];
417
+ getTriggerSubs(table_name: string, condition: string): Subscription[];
418
+ removeLocalSub(channelName: string, localFuncs: LocalFuncs): void;
419
+ getSyncs(table_name: string, condition: string): SyncParams[];
420
+ notifListener: (data: {
421
+ payload: string;
422
+ }) => Promise<void>;
423
+ getSubData: (sub: Subscription) => Promise<{
424
+ data: any[];
425
+ err?: undefined;
426
+ } | {
427
+ data?: undefined;
428
+ err: any;
429
+ }>;
430
+ pushSubData: (sub: Subscription, err?: any) => Promise<unknown>;
431
+ upsertSocket(socket: PRGLIOSocket | undefined): void;
432
+ get connectedSocketIds(): string[];
433
+ _log: (params: EventTypes.Sync) => Promise<void> | undefined;
434
+ syncTimeout?: ReturnType<typeof setTimeout>;
435
+ syncData: (sync: SyncParams, clientData: ClientExpressData | undefined, source: "client" | "trigger") => Promise<void>;
436
+ addSync: (syncParams: AddSyncParams) => Promise<string | undefined>;
437
+ addSub: (subscriptionParams: Omit<Pick<SubscribeParams, "throttle" | "throttleOpts"> & {
438
+ socket_id?: string | undefined;
439
+ channel_name: string;
440
+ /**
441
+ * If this is a view then an array with all related tables will be
442
+ * */
443
+ viewOptions?: ViewSubscriptionOptions | undefined;
444
+ parentSubParams: Omit<SubscriptionParams, "parentSubParams"> | undefined;
445
+ table_info: TableOrViewInfo;
446
+ table_rules?: TableRule | undefined;
447
+ filter: object;
448
+ params: SelectParams;
449
+ localFuncs?: LocalFuncs | undefined;
450
+ socket: PRGLIOSocket | undefined;
451
+ last_throttled: number;
452
+ is_throttling?: any;
453
+ is_ready?: boolean | undefined;
454
+ } & {
455
+ condition: string;
456
+ }, "channel_name" | "parentSubParams">) => Promise<import("prostgles-types").SubscriptionChannels>;
457
+ getActiveListeners: () => {
458
+ table_name: string;
459
+ condition: string;
460
+ }[];
461
+ /**
462
+ * Sync triggers with database
463
+ * */
464
+ refreshTriggers: () => Promise<void>;
465
+ addingTrigger: any;
466
+ addTriggerPool?: Record<string, string[]>;
467
+ addTrigger(params: {
468
+ table_name: string;
469
+ condition: string;
470
+ }, viewOptions: ViewSubscriptionOptions | undefined, socket: PRGLIOSocket | undefined): Promise<({
471
+ tbl: string;
472
+ cond: string;
473
+ } & {
474
+ error?: undefined;
475
+ duration: number;
476
+ }) | (Partial<Record<"tbl" | "cond", undefined>> & {
477
+ error: unknown;
478
+ duration: number;
479
+ })>;
480
+ }
481
+ export type TableSchemaColumn = ColumnInfo & {
482
+ privileges: Partial<Record<"INSERT" | "REFERENCES" | "SELECT" | "UPDATE", true>>;
483
+ };
484
+ export type TableSchema = {
485
+ schema: string;
486
+ name: string;
487
+ escaped_identifier: string;
488
+ oid: number;
489
+ comment: string;
490
+ columns: TableSchemaColumn[];
491
+ is_view: boolean;
492
+ view_definition: string | null;
493
+ parent_tables: string[];
494
+ privileges: {
495
+ insert: boolean;
496
+ select: boolean;
497
+ update: boolean;
498
+ delete: boolean;
499
+ };
500
+ /** Cannot add triggers to hyperTables */
501
+ isHyperTable?: boolean;
502
+ };
503
+ export type TxCB<TH = DbTxTableHandlers> = {
504
+ (t: TH & Pick<DBHandlerServer, "sql">, _t: pgPromise.ITask<{}>): (any | void);
505
+ };
506
+ export type TX<TH = TableHandlers> = {
507
+ (t: TxCB<TH>): Promise<(any | void)>;
508
+ };
509
+ export type TableHandlers = {
510
+ [key: string]: Partial<TableHandler$1> | TableHandler$1;
511
+ };
512
+ export type DbTxTableHandlers = {
513
+ [key: string]: Omit<Partial<TableHandler$1>, "dbTx"> | Omit<TableHandler$1, "dbTx">;
514
+ };
515
+ export type DBHandlerServer<TH = TableHandlers> = TH & Partial<DbJoinMaker> & {
516
+ sql?: SQLHandler;
517
+ } & {
518
+ tx?: TX<TH>;
519
+ };
520
+ export type TableInfo$1 = TInfo & {
521
+ schema: string;
522
+ name: string;
523
+ oid: number;
524
+ comment: string;
525
+ columns: ColumnInfo[];
526
+ };
527
+ export type ViewInfo = TableInfo$1 & {
528
+ parent_tables: string[];
529
+ };
530
+ export type TableOrViewInfo = TableInfo$1 & ViewInfo & {
531
+ is_view: boolean;
532
+ };
533
+ export type PRGLIOSocket = {
534
+ readonly id: string;
535
+ readonly handshake: {
536
+ query?: Record<string, string | string[] | undefined>;
537
+ /**
538
+ * IP Address
539
+ */
540
+ address: string;
541
+ headers?: AnyObject & {
542
+ cookie?: string;
543
+ };
544
+ auth?: Record<string, any>;
545
+ };
546
+ readonly on: (channel: string, params: any, cb?: (err: any, res?: any) => void) => any;
547
+ readonly emit: (channel: string, message?: any, cb?: BasicCallback) => any;
548
+ readonly once: (channel: string, cb: (_data: any, cb: BasicCallback) => void) => void;
549
+ readonly removeAllListeners: (channel: string) => void;
550
+ readonly disconnect: () => void;
551
+ readonly request: {
552
+ url?: string;
553
+ connection: {
554
+ remoteAddress?: string;
555
+ };
556
+ };
557
+ /** Used for session caching */
558
+ __prglCache?: {
559
+ session: BasicSession;
560
+ user: UserLike;
561
+ clientUser: AnyObject;
562
+ };
563
+ _user?: AnyObject;
564
+ /** Used for publish error caching */
565
+ prostgles?: AnyObject;
566
+ };
567
+ export type LocalParams = {
568
+ httpReq?: ExpressReq;
569
+ socket?: PRGLIOSocket;
570
+ func?: () => any;
571
+ isRemoteRequest?: {
572
+ user?: UserLike | undefined;
573
+ };
574
+ testRule?: boolean;
575
+ tableAlias?: string;
576
+ tx?: {
577
+ dbTX: TableHandlers;
578
+ t: any
579
+ };
580
+ returnQuery?: boolean | "noRLS" | "where-condition";
581
+ returnNewQuery?: boolean;
582
+ /** Used for count/size queries */
583
+ bypassLimit?: boolean;
584
+ nestedInsert?: {
585
+ depth: number;
586
+ previousData: AnyObject;
587
+ previousTable: string;
588
+ referencingColumn?: string;
589
+ };
590
+ };
591
+ export type Filter = AnyObject | {
592
+ $and: Filter[];
593
+ } | {
594
+ $or: Filter[];
595
+ };
596
+ export type JoinInfo = {
597
+ /**
598
+ * If true then all joins involve unique columns and the result is a 1 to 1 join
599
+ */
600
+ expectOne?: boolean;
601
+ paths: {
602
+ /**
603
+ * The table that JOIN ON columns refer to.
604
+ * columns in index = 1 refer to this table. index = 0 columns refer to previous JoinInfo.table
605
+ */
606
+ table: string;
607
+ /**
608
+ * Source and target JOIN ON column groups for each existing constraint
609
+ * Each inner array group will be combined with AND and outer arrays with OR to allow multiple references to the same table
610
+ * e.g.: [[source_table_column: string, table_column: string]]
611
+ */
612
+ on: [
613
+ string,
614
+ string
615
+ ][][];
616
+ /**
617
+ * Source table name
618
+ */
619
+ source: string;
620
+ /**
621
+ * Target table name
622
+ */
623
+ target: string;
624
+ }[];
625
+ };
626
+ export type CommonTableRules = {
627
+ /**
628
+ * True by default. Allows clients to get column information on any columns that are allowed in (select, insert, update) field rules.
629
+ */
630
+ getColumns?: PublishAllOrNothing;
631
+ /**
632
+ * True by default. Allows clients to get table information (oid, comment, label, has_media).
633
+ */
634
+ getInfo?: PublishAllOrNothing;
635
+ };
636
+ export type ValidatedTableRules = CommonTableRules & {
637
+ allColumns: FieldSpec[];
638
+ select: {
639
+ fields: string[];
640
+ orderByFields: string[];
641
+ filterFields: string[];
642
+ forcedFilter: any;
643
+ maxLimit: number | null;
644
+ };
645
+ update: {
646
+ fields: string[];
647
+ returningFields: string[];
648
+ filterFields: string[];
649
+ forcedFilter: any;
650
+ forcedData: any;
651
+ };
652
+ insert: {
653
+ fields: string[];
654
+ returningFields: string[];
655
+ forcedData: any;
656
+ };
657
+ delete: {
658
+ filterFields: string[];
659
+ forcedFilter: any;
660
+ returningFields: string[];
661
+ };
662
+ };
663
+ export type ExistsFilterConfig = {
664
+ existType: EXISTS_KEY;
665
+ /**
666
+ * Target table filter. target table is the last table from tables
667
+ */
668
+ targetTableFilter: Filter;
669
+ } & ({
670
+ isJoined: true;
671
+ /**
672
+ * list of join tables in their order
673
+ * If table path starts with "**" then get shortest join to first table
674
+ * e.g.: "**.users" means finding the shortest join from root table to users table
675
+ */
676
+ path: RawJoinPath;
677
+ parsedPath: ParsedJoinPath[];
678
+ } | {
679
+ isJoined: false;
680
+ targetTable: string;
681
+ });
682
+ export type PublishMethods<S = void, SUser extends SessionUser = SessionUser> = (params: PublishParams<S, SUser>) => {
683
+ [key: string]: Method;
684
+ } | Promise<{
685
+ [key: string]: Method;
686
+ } | null>;
687
+ export type Awaitable$1<T> = T | Promise<T>;
688
+ export type Request$1 = {
689
+ socket?: any;
690
+ httpReq?: any;
691
+ };
692
+ export type DboTable = Request$1 & {
693
+ tableName: string;
694
+ localParams: LocalParams;
695
+ };
696
+ export type DboTableCommand = Request$1 & DboTable & {
697
+ command: string;
698
+ localParams: LocalParams;
699
+ };
700
+ export type SelectRequestData = {
701
+ filter: object;
702
+ params: SelectParams;
703
+ };
704
+ export type ValidateRowArgs<R = AnyObject, DBX = DBHandlerServer> = {
705
+ row: R;
706
+ dbx: DBX;
707
+ localParams: LocalParams;
708
+ };
709
+ export type ValidateUpdateRowArgs<U = Partial<AnyObject>, F = Filter, DBX = DBHandlerServer> = {
710
+ update: U;
711
+ filter: F;
712
+ dbx: DBX;
713
+ localParams: LocalParams;
714
+ };
715
+ export type ValidateRow<R extends AnyObject = AnyObject, S = void> = (args: ValidateRowArgs<R, DBOFullyTyped<S>>) => R | Promise<R>;
716
+ export type PostValidateRow<R extends AnyObject = AnyObject, S = void> = (args: ValidateRowArgs<R, DBOFullyTyped<S>>) => void | Promise<void>;
717
+ export type ValidateRowBasic = (args: ValidateRowArgs) => AnyObject | Promise<AnyObject>;
718
+ export type ValidateUpdateRow<R extends AnyObject = AnyObject, S extends DBSchema | void = void> = (args: ValidateUpdateRowArgs<Partial<R>, FullFilter<R, S>, DBOFullyTyped<S>>) => Partial<R> | Promise<Partial<R>>;
719
+ export type SelectRule<Cols extends AnyObject = AnyObject, S extends DBSchema | void = void> = {
720
+ /**
721
+ * Fields allowed to be selected.
722
+ * Tip: Use false to exclude field
723
+ */
724
+ fields: FieldFilter<Cols>;
725
+ /**
726
+ * Fields allowed to sorted
727
+ * Defaults to the "fields". Use empty array/object to disallow sorting
728
+ */
729
+ orderByFields?: FieldFilter<Cols>;
730
+ /**
731
+ * 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
732
+ */
733
+ maxLimit?: number | null;
734
+ /**
735
+ * Filter added to every query (e.g. user_id) to restrict access
736
+ */
737
+ forcedFilter?: FullFilter<Cols, S>;
738
+ /**
739
+ * Fields user can filter by
740
+ * */
741
+ filterFields?: FieldFilter<Cols>;
742
+ /**
743
+ * Validation logic to check/update data for each request
744
+ */
745
+ validate?(args: SelectRequestData): SelectRequestData | Promise<SelectRequestData>;
746
+ };
747
+ export type CommonInsertUpdateRule<Cols extends AnyObject = AnyObject, S extends DBSchema | void = void> = {
748
+ /**
749
+ * Filter that the new records must match or the update/insert will fail
750
+ * Similar to a policy WITH CHECK clause
751
+ */
752
+ checkFilter?: SelectRule<Cols, S>["forcedFilter"];
753
+ /**
754
+ * Data to include and overwrite on each update/insert
755
+ * These fields cannot be updated by the user
756
+ */
757
+ forcedData?: Partial<Cols>;
758
+ };
759
+ export type InsertRule<Cols extends AnyObject = AnyObject, S extends DBSchema | void = void> = CommonInsertUpdateRule<Cols, S> & {
760
+ /**
761
+ * Fields allowed to be inserted. Tip: Use false to exclude field
762
+ */
763
+ fields: SelectRule<Cols>["fields"];
764
+ /**
765
+ * Fields user can view after inserting
766
+ */
767
+ returningFields?: SelectRule<Cols>["fields"];
768
+ /**
769
+ * Validation logic to check/update data for each request. Happens before publish rule checks (for fields, forcedData/forcedFilter)
770
+ */
771
+ preValidate?: ValidateRow<Cols, S>;
772
+ /**
773
+ * Validation logic to check/update data for each request. Happens after publish rule checks (for fields, forcedData/forcedFilter)
774
+ */
775
+ validate?: ValidateRow<Cols, S>;
776
+ /**
777
+ * Validation logic to check/update data after the insert.
778
+ * Happens in the same transaction so upon throwing an error the record will be deleted (not committed)
779
+ */
780
+ postValidate?: PostValidateRow<Required<Cols>, S>;
781
+ /**
782
+ * If defined then only nested inserts from these tables are allowed
783
+ * Direct inserts will fail
784
+ */
785
+ allowedNestedInserts?: {
786
+ table: string;
787
+ column: string;
788
+ }[];
789
+ };
790
+ export type UpdateRule<Cols extends AnyObject = AnyObject, S extends DBSchema | void = void> = CommonInsertUpdateRule<Cols, S> & {
791
+ /**
792
+ * Fields allowed to be updated. Tip: Use false/0 to exclude field
793
+ */
794
+ fields: SelectRule<Cols>["fields"];
795
+ /**
796
+ * Row level FGAC
797
+ * Used when the editable fields change based on the updated row
798
+ * If specified then the fields from the first matching filter table.count({ ...filter, ...updateFilter }) > 0 will be used
799
+ * If none matching then the "fields" will be used
800
+ * Specify in decreasing order of specificity otherwise a more general filter will match first
801
+ */
802
+ dynamicFields?: {
803
+ filter: FullFilter<Cols, S>;
804
+ fields: SelectRule<Cols>["fields"];
805
+ }[];
806
+ /**
807
+ * Filter added to every query (e.g. user_id) to restrict access
808
+ * This filter cannot be updated
809
+ */
810
+ forcedFilter?: SelectRule<Cols, S>["forcedFilter"];
811
+ /**
812
+ * Fields user can use to find the updates
813
+ */
814
+ filterFields?: SelectRule<Cols>["fields"];
815
+ /**
816
+ * Fields user can view after updating
817
+ */
818
+ returningFields?: SelectRule<Cols>["fields"];
819
+ /**
820
+ * Validation logic to check/update data for each request
821
+ */
822
+ validate?: ValidateUpdateRow<Cols, S>;
823
+ /**
824
+ * Validation logic to check/update data after the insert.
825
+ * Happens in the same transaction so upon throwing an error the record will be deleted (not committed)
826
+ */
827
+ postValidate?: PostValidateRow<Required<Cols>, S>;
828
+ };
829
+ export type DeleteRule<Cols extends AnyObject = AnyObject, S extends DBSchema | void = void> = {
830
+ /**
831
+ * Filter added to every query (e.g. user_id) to restrict access
832
+ */
833
+ forcedFilter?: SelectRule<Cols, S>["forcedFilter"];
834
+ /**
835
+ * Fields user can filter by
836
+ */
837
+ filterFields: FieldFilter<Cols>;
838
+ /**
839
+ * Fields user can view after deleting
840
+ */
841
+ returningFields?: SelectRule<Cols>["filterFields"];
842
+ /**
843
+ * Validation logic to check/update data for each request
844
+ */
845
+ validate?(...args: any[]): Awaitable$1<void>;
846
+ };
847
+ export type SyncRule<Cols extends AnyObject = AnyObject> = {
848
+ /**
849
+ * Primary keys used in updating data
850
+ */
851
+ id_fields: (keyof Cols)[];
852
+ /**
853
+ * Numerical incrementing fieldname (last updated timestamp) used to sync items
854
+ */
855
+ synced_field: keyof Cols;
856
+ /**
857
+ * EXPERIMENTAL. Disabled by default. If true then server will attempt to delete any records missing from client.
858
+ */
859
+ allow_delete?: boolean;
860
+ /**
861
+ * Throttle replication transmission in milliseconds. Defaults to 100
862
+ */
863
+ throttle?: number;
864
+ /**
865
+ * Number of rows to send per trip. Defaults to 50
866
+ */
867
+ batch_size?: number;
868
+ };
869
+ export type SubscribeRule = {
870
+ throttle?: number;
871
+ };
872
+ export type ViewRule<S extends AnyObject = AnyObject> = CommonTableRules & {
873
+ /**
874
+ * What can be read from the table
875
+ */
876
+ select?: SelectRule<S>;
877
+ };
878
+ export type TableRule<RowType extends AnyObject = AnyObject, S extends DBSchema | void = void> = ViewRule<RowType> & {
879
+ insert?: InsertRule<RowType, S>;
880
+ update?: UpdateRule<RowType, S>;
881
+ delete?: DeleteRule<RowType, S>;
882
+ sync?: SyncRule<RowType>;
883
+ subscribe?: SubscribeRule;
884
+ };
885
+ export type PublishViewRule<Col extends AnyObject = AnyObject, S extends DBSchema | void = void> = {
886
+ select?: SelectRule<Col, S> | PublishAllOrNothing;
887
+ getColumns?: PublishAllOrNothing;
888
+ getInfo?: PublishAllOrNothing;
889
+ };
890
+ export type PublishTableRule<Col extends AnyObject = AnyObject, S extends DBSchema | void = void> = PublishViewRule<Col, S> & {
891
+ insert?: InsertRule<Col, S> | PublishAllOrNothing;
892
+ update?: UpdateRule<Col, S> | PublishAllOrNothing;
893
+ delete?: DeleteRule<Col, S> | PublishAllOrNothing;
894
+ sync?: SyncRule<Col>;
895
+ subscribe?: SubscribeRule | PublishAllOrNothing;
896
+ };
897
+ export type ParsedPublishTable = {
898
+ select?: SelectRule;
899
+ getColumns?: true;
900
+ getInfo?: true;
901
+ insert?: InsertRule;
902
+ update?: UpdateRule;
903
+ delete?: DeleteRule;
904
+ sync?: SyncRule;
905
+ subscribe?: SubscribeRule;
906
+ subscribeOne?: SubscribeRule;
907
+ };
908
+ export type DbTableInfo = {
909
+ name: string;
910
+ info: TableOrViewInfo;
911
+ columns: TableSchemaColumn[];
912
+ };
913
+ export type PublishParams<S = void, SUser extends SessionUser = SessionUser> = {
914
+ sid?: string;
915
+ dbo: DBOFullyTyped<S>;
916
+ db: DB$1;
917
+ user?: SUser["user"];
918
+ socket: PRGLIOSocket;
919
+ tables: DbTableInfo[];
920
+ };
921
+ export type PublishAllOrNothing = true | "*" | false | null;
922
+ export type PublishObject = {
923
+ [table_name: string]: (PublishTableRule | PublishViewRule | PublishAllOrNothing);
924
+ };
925
+ export type PublishedResult<Schema = void> = PublishAllOrNothing | PublishFullyTyped<Schema>;
926
+ export type Publish<Schema = void, SUser extends SessionUser = SessionUser> = PublishedResult<Schema> | ((params: PublishParams<Schema, SUser>) => Awaitable$1<PublishedResult<Schema>>);
927
+ declare class PublishParser {
928
+ publish: any;
929
+ publishMethods?: PublishMethods<void, SessionUser> | undefined;
930
+ publishRawSQL?: any;
931
+ dbo: DBHandlerServer;
932
+ db: DB$1;
933
+ prostgles: Prostgles;
934
+ constructor(publish: any, publishMethods: PublishMethods<void, SessionUser> | undefined, publishRawSQL: any, dbo: DBHandlerServer, db: DB$1, prostgles: Prostgles);
935
+ getPublishParams(localParams: LocalParams, clientInfo?: AuthResult): Promise<PublishParams>;
936
+ getAllowedMethods(reqInfo: Pick<LocalParams, "httpReq" | "socket">, userData?: AuthResult): Promise<{
937
+ [key: string]: Method;
938
+ }>;
939
+ /**
940
+ * Parses the first level of publish. (If false then nothing if * then all tables and views)
941
+ * @param socket
942
+ * @param user
943
+ */
944
+ getPublish(localParams: LocalParams, clientInfo?: AuthResult): Promise<PublishObject>;
945
+ getValidatedRequestRuleWusr({ tableName, command, localParams }: DboTableCommand): Promise<TableRule>;
946
+ getValidatedRequestRule({ tableName, command, localParams }: DboTableCommand, clientInfo?: AuthResult): Promise<TableRule>;
947
+ getTableRules(args: DboTable, clientInfo?: AuthResult): Promise<ParsedPublishTable | undefined>;
948
+ getTableRulesWithoutFileTable: (args_0: DboTable, args_1?: AuthResult, args_2?: PublishObject | undefined) => Promise<ParsedPublishTable | undefined>;
949
+ getSchemaFromPublish: (args_0: ({
950
+ socket: PRGLIOSocket;
951
+ httpReq?: undefined;
952
+ } | {
953
+ httpReq: ExpressReq;
954
+ socket?: undefined;
955
+ }) & {
956
+ userData: AuthResult;
957
+ }) => Promise<{
958
+ schema: import("prostgles-types").TableSchemaForClient;
959
+ tables: import("prostgles-types").DBSchemaTable[];
960
+ }>;
961
+ }
962
+ export type DbConnection = string | pg$1.IConnectionParameters<pg$1.IClient>;
963
+ export type DbConnectionOpts = pg$1.IDefaults;
964
+ export type PGP = pgPromise.IMain<{}, pg$1.IClient>;
965
+ export type DB = pgPromise.IDatabase<{}, pg$1.IClient>;
966
+ export type OnInitReason = {
967
+ type: "schema change";
968
+ query: string;
969
+ command: string;
970
+ } | {
971
+ type: "init" | "prgl.restart" | "prgl.update" | "TableConfig";
972
+ };
973
+ export type OnReadyParamsCommon = {
974
+ db: DB;
975
+ tables: DbTableInfo[];
976
+ reason: OnInitReason;
977
+ };
978
+ export type OnReadyParamsBasic = OnReadyParamsCommon & {
979
+ dbo: DBHandlerServer;
980
+ };
981
+ export type OnReadyParams<S> = OnReadyParamsCommon & {
982
+ dbo: DBOFullyTyped<S>;
983
+ };
984
+ export type OnReadyCallback<S = void> = (params: OnReadyParams<S>) => any;
985
+ export type OnReadyCallbackBasic = (params: OnReadyParamsBasic) => any;
986
+ export type InitResult = {
987
+ db: DBOFullyTyped;
988
+ _db: DB;
989
+ pgp: PGP;
990
+ io?: any;
991
+ destroy: () => Promise<boolean>;
992
+ /**
993
+ * Generated database public schema TS types for all tables and views
994
+ */
995
+ getTSSchema: () => string;
996
+ update: (newOpts: Pick<ProstglesInitOptions, "fileTable" | "restApi" | "tableConfig">) => Promise<void>;
997
+ restart: () => Promise<InitResult>;
998
+ };
999
+ export type ColExtraInfo = {
1000
+ min?: string | number;
1001
+ max?: string | number;
1002
+ hint?: string;
1003
+ };
1004
+ export type I18N_Config<LANG_IDS> = {
1005
+ [lang_id in keyof LANG_IDS]: string;
1006
+ };
1007
+ export type BaseTableDefinition<LANG_IDS = AnyObject> = {
1008
+ info?: {
1009
+ label?: string | I18N_Config<LANG_IDS>;
1010
+ };
1011
+ dropIfExistsCascade?: boolean;
1012
+ dropIfExists?: boolean;
1013
+ hooks?: {
1014
+ /**
1015
+ * Hook used to run custom logic before inserting a row.
1016
+ * The returned row must satisfy the table schema
1017
+ */
1018
+ getPreInsertRow?: (args: ValidateRowArgs) => Promise<{
1019
+ row: AnyObject;
1020
+ onInserted: Promise<void>;
1021
+ }>;
1022
+ };
1023
+ triggers?: {
1024
+ [triggerName: string]: {
1025
+ /**
1026
+ * Use "before" when you need to change the data before the action
1027
+ */
1028
+ type: "before" | "after" | "instead of";
1029
+ actions: ("insert" | "update" | "delete")[];
1030
+ forEach: "statement" | "row";
1031
+ /**
1032
+ * @example
1033
+ * DECLARE
1034
+ x_rec record;
1035
+ BEGIN
1036
+ raise notice '=operation: % =', TG_OP;
1037
+ IF (TG_OP = 'UPDATE' OR TG_OP = 'DELETE') THEN
1038
+ FOR x_rec IN SELECT * FROM old_table LOOP
1039
+ raise notice 'OLD: %', x_rec;
1040
+ END loop;
1041
+ END IF;
1042
+ IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
1043
+ FOR x_rec IN SELECT * FROM new_table LOOP
1044
+ raise notice 'NEW: %', x_rec;
1045
+ END loop;
1046
+ END IF;
1047
+
1048
+ RETURN NULL;
1049
+ END;
1050
+ */
1051
+ query: string;
1052
+ };
1053
+ };
1054
+ };
1055
+ export type LookupTableDefinition<LANG_IDS> = {
1056
+ isLookupTable: {
1057
+ values: {
1058
+ [id_value: string]: {} | {
1059
+ [lang_id in keyof LANG_IDS]: string;
1060
+ };
1061
+ };
1062
+ };
1063
+ };
1064
+ export type BaseColumn<LANG_IDS> = {
1065
+ /**
1066
+ * Will add these values to .getColumns() result
1067
+ */
1068
+ info?: ColExtraInfo;
1069
+ label?: string | Partial<{
1070
+ [lang_id in keyof LANG_IDS]: string;
1071
+ }>;
1072
+ };
1073
+ export type SQLDefColumn = {
1074
+ /**
1075
+ * Raw sql statement used in creating/adding column
1076
+ */
1077
+ sqlDefinition?: string;
1078
+ };
1079
+ export type BaseColumnTypes = {
1080
+ defaultValue?: any;
1081
+ nullable?: boolean;
1082
+ };
1083
+ export type TextColumn = BaseColumnTypes & {
1084
+ isText: true;
1085
+ /**
1086
+ * Value will be trimmed before update/insert
1087
+ */
1088
+ trimmed?: boolean;
1089
+ /**
1090
+ * Value will be lower cased before update/insert
1091
+ */
1092
+ lowerCased?: boolean;
1093
+ };
1094
+ export type JSONBColumnDef = (BaseColumnTypes & {}) & ({
1095
+ jsonbSchema: JSONB.JSONBSchema;
1096
+ jsonbSchemaType?: undefined;
1097
+ } | {
1098
+ jsonbSchema?: undefined;
1099
+ jsonbSchemaType: JSONB.ObjectType["type"];
1100
+ });
1101
+ /**
1102
+ * Allows referencing media to this table.
1103
+ * Requires this table to have a primary key AND a valid fileTable config
1104
+ */
1105
+ export type MediaColumn = ({
1106
+ name: string;
1107
+ label?: string;
1108
+ files: "one" | "many";
1109
+ } & ({
1110
+ /**
1111
+ * https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept
1112
+ */
1113
+ allowedContentType?: Record<Partial<("audio/*" | "video/*" | "image/*" | "text/*" | ALLOWED_CONTENT_TYPE)>, 1>;
1114
+ } | {
1115
+ allowedExtensions?: Record<Partial<ALLOWED_EXTENSION>, 1>;
1116
+ }));
1117
+ export type ReferencedColumn = {
1118
+ /**
1119
+ * Will create a lookup table that this column will reference
1120
+ */
1121
+ references?: BaseColumnTypes & {
1122
+ tableName: string;
1123
+ /**
1124
+ * Defaults to id
1125
+ */
1126
+ columnName?: string;
1127
+ };
1128
+ };
1129
+ export type JoinDef = {
1130
+ sourceTable: string;
1131
+ targetTable: string;
1132
+ on: JoinInfo["paths"][number]["on"];
1133
+ };
1134
+ /**
1135
+ * Used in specifying a join path to a table. This column name can then be used in select
1136
+ */
1137
+ export type NamedJoinColumn = {
1138
+ label?: string;
1139
+ joinDef: JoinDef[];
1140
+ };
1141
+ export type Enum<T extends string | number = any> = {
1142
+ enum: T[] | readonly T[];
1143
+ nullable?: boolean;
1144
+ defaultValue?: T;
1145
+ };
1146
+ export type ColumnConfig<LANG_IDS = {
1147
+ en: 1;
1148
+ }> = string | StrictUnion<NamedJoinColumn | MediaColumn | (BaseColumn<LANG_IDS> & (SQLDefColumn | ReferencedColumn | TextColumn | JSONBColumnDef | Enum))>;
1149
+ export type UnionKeys<T> = T extends T ? keyof T : never;
1150
+ export type StrictUnionHelper<T, TAll> = T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
1151
+ export type StrictUnion<T> = StrictUnionHelper<T, T>;
1152
+ declare const CONSTRAINT_TYPES: readonly [
1153
+ "PRIMARY KEY",
1154
+ "UNIQUE",
1155
+ "CHECK"
1156
+ ];
1157
+ export type TableDefinition<LANG_IDS> = {
1158
+ onMount?: (params: {
1159
+ dbo: DBHandlerServer;
1160
+ _db: DB$1;
1161
+ }) => Promise<void | {
1162
+ onUnmount: () => void;
1163
+ }>;
1164
+ columns?: {
1165
+ [column_name: string]: ColumnConfig<LANG_IDS>;
1166
+ };
1167
+ constraints?: string[] | {
1168
+ [constraint_name: string]: string | {
1169
+ type: typeof CONSTRAINT_TYPES[number];
1170
+ dropIfExists?: boolean;
1171
+ /**
1172
+ * E.g.:
1173
+ * colname
1174
+ * col1, col2
1175
+ * col1 > col3
1176
+ */
1177
+ content: string;
1178
+ };
1179
+ };
1180
+ /**
1181
+ * Similar to unique constraints but expressions are allowed inside definition
1182
+ */
1183
+ replaceUniqueIndexes?: boolean;
1184
+ indexes?: {
1185
+ [index_name: string]: {
1186
+ /**
1187
+ * If true then will drop any existing index with this name
1188
+ * Overrides replaceUniqueIndexes
1189
+ */
1190
+ replace?: boolean;
1191
+ /**
1192
+ * Causes the system to check for duplicate values in the table when the index is created (if data already exist) and each time data is added.
1193
+ * Attempts to insert or update data which would result in duplicate entries will generate an error.
1194
+ */
1195
+ unique?: boolean;
1196
+ /**
1197
+ * When this option is used, PostgreSQL will build the index without taking any locks that prevent
1198
+ * concurrent inserts, updates, or deletes on the table; whereas a standard index build locks out writes (but not reads) on the table until it's done.
1199
+ * There are several caveats to be aware of when using this option — see Building Indexes Concurrently.
1200
+ */
1201
+ concurrently?: boolean;
1202
+ /**
1203
+ * Table name
1204
+ */
1205
+ /**
1206
+ * Column list
1207
+ * @example: col1, col2
1208
+ */
1209
+ columns: string;
1210
+ /**
1211
+ * Where clause without the "where"
1212
+ * Used to create a partial index. A partial index is an index that contains entries for only a portion of a table
1213
+ * Another possible application is to use WHERE with UNIQUE to enforce uniqueness over a subset of a table
1214
+ */
1215
+ where?: string;
1216
+ /**
1217
+ * The name of the index method to be used.
1218
+ * Choices are btree, hash, gist, and gin. The default method is btree.
1219
+ */
1220
+ using?: "btree" | "hash" | "gist" | "gin";
1221
+ };
1222
+ };
1223
+ };
1224
+ export type GetPreInsertRowArgs = ValidateRowArgs & {
1225
+ preValidate: InsertRule["preValidate"];
1226
+ validate: InsertRule["validate"];
1227
+ };
1228
+ /**
1229
+ * Helper utility to create lookup tables for TEXT columns
1230
+ */
1231
+ export type TableConfig<LANG_IDS = {
1232
+ en: 1;
1233
+ }> = {
1234
+ [table_name: string]: BaseTableDefinition<LANG_IDS> & (TableDefinition<LANG_IDS> | LookupTableDefinition<LANG_IDS>);
1235
+ };
1236
+ declare class TableConfigurator<LANG_IDS = {
1237
+ en: 1;
1238
+ }> {
1239
+ instanceId: number;
1240
+ config: TableConfig<LANG_IDS>;
1241
+ get dbo(): DBHandlerServer;
1242
+ get db(): DB$1;
1243
+ prostgles: Prostgles;
1244
+ constructor(prostgles: Prostgles);
1245
+ destroy: () => Promise<void>;
1246
+ tableOnMounts: Record<string, {
1247
+ onUnmount: () => void;
1248
+ }>;
1249
+ setTableOnMounts: () => Promise<void>;
1250
+ getColumnConfig: (tableName: string, colName: string) => ColumnConfig | undefined;
1251
+ getTableInfo: (params: {
1252
+ tableName: string;
1253
+ lang?: string;
1254
+ }) => TableInfo["info"] | undefined;
1255
+ getColInfo: (params: {
1256
+ col: string;
1257
+ table: string;
1258
+ lang?: string;
1259
+ }) => (ColExtraInfo & {
1260
+ label?: string;
1261
+ } & Pick<ColumnInfo, "jsonbSchema">) | undefined;
1262
+ checkColVal: (params: {
1263
+ col: string;
1264
+ table: string;
1265
+ value: any;
1266
+ }) => void;
1267
+ getJoinInfo: (sourceTable: string, targetTable: string) => JoinInfo | undefined;
1268
+ getPreInsertRow: (tableHandler: TableHandler$1, args: GetPreInsertRowArgs) => Promise<AnyObject>;
1269
+ prevInitQueryHistory?: string[];
1270
+ initialising: boolean;
1271
+ init: () => Promise<undefined>;
1272
+ }
1273
+ declare class DBEventsManager {
1274
+ notifies: {
1275
+ [key: string]: {
1276
+ socketChannel: string;
1277
+ sockets: any[];
1278
+ localFuncs: ((payload: string) => void)[];
1279
+ notifMgr: PostgresNotifListenManager;
1280
+ };
1281
+ };
1282
+ notice: {
1283
+ socketChannel: string;
1284
+ socketUnsubChannel: string;
1285
+ sockets: any[];
1286
+ };
1287
+ notifManager?: PostgresNotifListenManager;
1288
+ db_pg: DB$1;
1289
+ pgp: PGP$1;
1290
+ constructor(db_pg: DB$1, pgp: PGP$1);
1291
+ private onNotif;
1292
+ onNotice: (notice: any) => void;
1293
+ getNotifChannelName: (channel: string) => Promise<any>;
1294
+ addNotify(query: string, socket?: PRGLIOSocket, func?: any): Promise<{
1295
+ socketChannel: string;
1296
+ socketUnsubChannel: string;
1297
+ notifChannel: string;
1298
+ unsubscribe?: () => void;
1299
+ }>;
1300
+ removeNotify(channel?: string, socket?: PRGLIOSocket, func?: any): void;
1301
+ addNotice(socket: PRGLIOSocket): {
1302
+ socketChannel: string;
1303
+ socketUnsubChannel: string;
1304
+ };
1305
+ removeNotice(socket: PRGLIOSocket): void;
1306
+ }
1307
+ export type ColConstraint = {
1308
+ name: string;
1309
+ table: string;
1310
+ type: "c" | "p" | "u" | "f";
1311
+ cols: Array<string>;
1312
+ definition: string;
1313
+ schema: string;
1314
+ };
1315
+ export type PGP$1 = pgPromise.IMain<{}, pg$1.IClient>;
1316
+ export type DB$1 = pgPromise.IDatabase<{}, pg$1.IClient>;
1317
+ declare const JOIN_TYPES: readonly [
1318
+ "one-many",
1319
+ "many-one",
1320
+ "one-one",
1321
+ "many-many"
1322
+ ];
1323
+ export type Join = {
1324
+ tables: [
1325
+ string,
1326
+ string
1327
+ ];
1328
+ on: {
1329
+ [key: string]: string;
1330
+ }[];
1331
+ type: typeof JOIN_TYPES[number];
1332
+ };
1333
+ export type Joins = Join[] | "inferred";
1334
+ export type Keywords = {
1335
+ $and: string;
1336
+ $or: string;
1337
+ $not: string;
1338
+ };
1339
+ /**
1340
+ * Allows uploading and downloading files.
1341
+ * Currently supports only S3.
1342
+ *
1343
+ * @description
1344
+ * Will create a media table that contains file metadata and urls
1345
+ * Inserting a file into this table through prostgles will upload it to S3 and insert the relevant metadata into the media table
1346
+ * Requesting a file from HTTP GET {fileUrlPath}/{fileId} will:
1347
+ * 1. check auth (if provided)
1348
+ * 2. check the permissions in publish (if provided)
1349
+ * 3. redirect the request to the signed url (if allowed)
1350
+ *
1351
+ * Specifying referencedTables will:
1352
+ * 1. create a column in that table called media
1353
+ * 2. create a lookup table lookup_media_{referencedTable} that joins referencedTable to the media table
1354
+ */
1355
+ export type FileTableConfig = {
1356
+ tableName?: string;
1357
+ /**
1358
+ * GET path used in serving media. defaults to /${tableName}
1359
+ */
1360
+ fileServeRoute?: string;
1361
+ cloudClient?: CloudClient;
1362
+ localConfig?: LocalConfig;
1363
+ /**
1364
+ * If defined the the files will not be deleted immediately
1365
+ * Instead, the "deleted" field will be updated to the current timestamp and after the day interval provided in "deleteAfterNDays" the files will be deleted
1366
+ * "checkIntervalMinutes" is the frequency in hours at which the files ready for deletion are deleted
1367
+ */
1368
+ delayedDelete?: {
1369
+ /**
1370
+ * Minimum amount of time measured in days for which the files will not be deleted after requesting delete
1371
+ */
1372
+ deleteAfterNDays: number;
1373
+ /**
1374
+ * How freuquently the files will be checked for deletion delay
1375
+ */
1376
+ checkIntervalHours?: number;
1377
+ };
1378
+ expressApp: ExpressApp;
1379
+ referencedTables?: {
1380
+ [tableName: string]:
1381
+ /**
1382
+ * If defined then will try to create (if necessary) these columns which will reference files_table(id)
1383
+ * Prostgles UI will use these hints (obtained through tableHandler.getInfo())
1384
+ * */
1385
+ {
1386
+ type: "column";
1387
+ referenceColumns: Record<string, FileColumnConfig>;
1388
+ };
1389
+ };
1390
+ imageOptions?: ImageOptions;
1391
+ };
1392
+ export type ProstglesInitOptions<S = void, SUser extends SessionUser = SessionUser> = {
1393
+ dbConnection: DbConnection;
1394
+ dbOptions?: DbConnectionOpts;
1395
+ tsGeneratedTypesDir?: string;
1396
+ io?: Server;
1397
+ publish?: Publish<S, SUser>;
1398
+ publishMethods?: PublishMethods<S, SUser>;
1399
+ publishRawSQL?(params: PublishParams<S, SUser>): ((boolean | "*") | Promise<(boolean | "*")>);
1400
+ joins?: Joins;
1401
+ schema?: Record<string, 1> | Record<string, 0>;
1402
+ sqlFilePath?: string;
1403
+ onReady: OnReadyCallback<S>;
1404
+ transactions?: string | boolean;
1405
+ wsChannelNamePrefix?: string;
1406
+ /**
1407
+ * Use for connection verification. Will disconnect socket on any errors
1408
+ */
1409
+ onSocketConnect?: (args: AuthRequestParams<S, SUser> & {
1410
+ socket: PRGLIOSocket;
1411
+ }) => void | Promise<void>;
1412
+ onSocketDisconnect?: (args: AuthRequestParams<S, SUser> & {
1413
+ socket: PRGLIOSocket;
1414
+ }) => void | Promise<void>;
1415
+ auth?: Auth<S, SUser>;
1416
+ DEBUG_MODE?: boolean;
1417
+ watchSchemaType?:
1418
+ /**
1419
+ * Will set database event trigger for schema changes. Requires superuser
1420
+ * Default
1421
+ */
1422
+ "DDL_trigger"
1423
+ /**
1424
+ * Will check client queries for schema changes
1425
+ * fallback if DDL not possible
1426
+ */
1427
+ | "prostgles_queries"
1428
+ /**
1429
+ * Schema checked for changes every 'checkIntervalMillis" milliseconds
1430
+ */
1431
+ | {
1432
+ checkIntervalMillis: number;
1433
+ };
1434
+ /**
1435
+ * If truthy then DBoGenerated.d.ts will be updated and "onReady" will be called with new schema on both client and server
1436
+ */
1437
+ watchSchema?:
1438
+ /**
1439
+ * Will listen only to few events (create table/view)
1440
+ */
1441
+ boolean
1442
+ /**
1443
+ * Will listen to specified events (or all if "*" is specified)
1444
+ */
1445
+ | EventTriggerTagFilter
1446
+ /**
1447
+ * Will only rewrite the DBoGenerated.d.ts found in tsGeneratedTypesDir
1448
+ * This is meant to be used in development when server restarts on file change
1449
+ */
1450
+ | "hotReloadMode"
1451
+ /**
1452
+ * Function called when schema changes. Nothing else triggered
1453
+ */
1454
+ | ((event: {
1455
+ command: string;
1456
+ query: string;
1457
+ }) => void);
1458
+ keywords?: Keywords;
1459
+ onNotice?: (notice: AnyObject, message?: string) => void;
1460
+ fileTable?: FileTableConfig;
1461
+ restApi?: RestApiConfig;
1462
+ /**
1463
+ * Creates tables and provides UI labels, autocomplete and hints for a given json structure
1464
+ */
1465
+ tableConfig?: TableConfig;
1466
+ tableConfigMigrations?: {
1467
+ /**
1468
+ * If false then prostgles won't start on any tableConfig error
1469
+ * true by default
1470
+ */
1471
+ silentFail?: boolean;
1472
+ version: number;
1473
+ /** Table that will contain the schema version number and the tableConfig
1474
+ * Defaults to schema_version
1475
+ */
1476
+ versionTableName?: string;
1477
+ /**
1478
+ * Script run before tableConfig is loaded IF an older schema_version is present
1479
+ */
1480
+ onMigrate: (args: {
1481
+ db: DB$1;
1482
+ oldVersion: number | undefined;
1483
+ getConstraints: (table: string, column?: string, types?: ColConstraint["type"][]) => Promise<ColConstraint[]>;
1484
+ }) => void;
1485
+ };
1486
+ onLog?: (evt: EventInfo) => Promise<void>;
1487
+ };
1488
+ declare class Prostgles {
1489
+ opts: ProstglesInitOptions;
1490
+ db?: DB$1;
1491
+ pgp?: PGP$1;
1492
+ dbo?: DBHandlerServer;
1493
+ _dboBuilder?: DboBuilder;
1494
+ get dboBuilder(): DboBuilder;
1495
+ set dboBuilder(d: DboBuilder);
1496
+ publishParser?: PublishParser;
1497
+ authHandler?: AuthHandler;
1498
+ schemaWatch?: SchemaWatch;
1499
+ keywords: {
1500
+ $filter: string;
1501
+ $and: string;
1502
+ $or: string;
1503
+ $not: string;
1504
+ };
1505
+ loaded: boolean;
1506
+ dbEventsManager?: DBEventsManager;
1507
+ fileManager?: FileManager;
1508
+ restApi?: RestApi;
1509
+ tableConfigurator?: TableConfigurator;
1510
+ isMedia(tableName: string): boolean;
1511
+ constructor(params: ProstglesInitOptions);
1512
+ destroyed: boolean;
1513
+ onSchemaChange(event: {
1514
+ command: string;
1515
+ query: string;
1516
+ }): Promise<void>;
1517
+ checkDb(): void;
1518
+ getTSFileName(): {
1519
+ fileName: string;
1520
+ fullPath: string;
1521
+ };
1522
+ private getFileText;
1523
+ getTSFileContent: () => string;
1524
+ /**
1525
+ * Will write the Schema Typescript definitions to file (tsGeneratedTypesDir)
1526
+ */
1527
+ writeDBSchema(force?: boolean): void;
1528
+ /**
1529
+ * Will re-create the dbo object
1530
+ */
1531
+ refreshDBO: () => Promise<DBHandlerServer>;
1532
+ initWatchSchema: (onReady: OnReadyCallbackBasic) => void;
1533
+ initRestApi: () => Promise<void>;
1534
+ initTableConfig: (reason: OnInitReason) => Promise<any>;
1535
+ initFileTable: () => Promise<{} | undefined>;
1536
+ isSuperUser: boolean;
1537
+ schema_checkIntervalMillis?: NodeJS.Timeout;
1538
+ init: (onReady: OnReadyCallbackBasic, reason: OnInitReason) => Promise<InitResult>;
1539
+ runSQLFile(filePath: string): Promise<number | undefined>;
1540
+ connectedSockets: PRGLIOSocket[];
1541
+ setSocketEvents(): Promise<void>;
1542
+ onSocketConnected: (socket: PRGLIOSocket) => Promise<void>;
1543
+ getClientSchema: (clientReq: Pick<LocalParams, "socket" | "httpReq">) => Promise<ClientSchema>;
1544
+ pushSocketSchema: (socket: PRGLIOSocket) => Promise<void>;
1545
+ }
1546
+ export type ClientStreamedRequest = {
1547
+ socket: PRGLIOSocket;
1548
+ query: string;
1549
+ options: SQLOptions | undefined;
1550
+ persistConnection?: boolean;
1551
+ };
1552
+ export type StreamedQuery = ClientStreamedRequest & {
1553
+ cursor: CursorType | undefined;
1554
+ client: pg.Client | undefined;
1555
+ stop?: VoidFunction;
1556
+ onError: ((error: any) => void);
1557
+ };
1558
+ declare class QueryStreamer {
1559
+ db: DB;
1560
+ dboBuilder: DboBuilder;
1561
+ socketQueries: Record<string, Record<string, StreamedQuery>>;
1562
+ adminClient: pg.Client;
1563
+ constructor(dboBuilder: DboBuilder);
1564
+ getConnection: (onError: ((err: any) => void) | undefined, extraOptions?: pg.ClientConfig) => pg.Client;
1565
+ onDisconnect: (socketId: string) => void;
1566
+ create: (query: ClientStreamedRequest) => Promise<SocketSQLStreamServer>;
1567
+ }
1568
+ export type PGConstraint = {
1569
+ /**
1570
+ * Constraint type
1571
+ */
1572
+ contype: "u" | "p" | "c";
1573
+ /**
1574
+ * Column ordinal positions
1575
+ */
1576
+ conkey: number[];
1577
+ /**
1578
+ * Constraint name
1579
+ */
1580
+ conname: string;
1581
+ /**
1582
+ * Table name
1583
+ */
1584
+ relname: string;
1585
+ };
1586
+ export type OidInfo = {
1587
+ /**
1588
+ * Oid
1589
+ */
1590
+ relid: number;
1591
+ relname: string;
1592
+ schemaname: string;
1593
+ };
1594
+ export type TableOidInfo = OidInfo & {
1595
+ pkey_columns: string[] | null;
1596
+ };
1597
+ export type TableOidColumnInfo = OidInfo & {
1598
+ column_name: string;
1599
+ udt_name: string;
1600
+ ordinal_position: number;
1601
+ };
1602
+ declare class DboBuilder {
1603
+ tablesOrViews?: TableSchema[];
1604
+ /**
1605
+ * Used in obtaining column names for error messages
1606
+ */
1607
+ constraints?: PGConstraint[];
1608
+ db: DB$1;
1609
+ dbo: DBHandlerServer;
1610
+ _pubSubManager?: PubSubManager;
1611
+ /**
1612
+ * Used for db.sql field type details
1613
+ */
1614
+ DATA_TYPES: {
1615
+ oid: string;
1616
+ typname: PG_COLUMN_UDT_DATA_TYPE;
1617
+ }[] | undefined;
1618
+ USER_TABLES: TableOidInfo[] | undefined;
1619
+ USER_TABLE_COLUMNS: TableOidColumnInfo[] | undefined;
1620
+ queryStreamer: QueryStreamer;
1621
+ get tables(): DbTableInfo[];
1622
+ getPubSubManager: () => Promise<PubSubManager>;
1623
+ tsTypesDefinition?: string;
1624
+ joinGraph?: Graph;
1625
+ private shortestJoinPaths;
1626
+ prostgles: Prostgles;
1627
+ publishParser?: PublishParser;
1628
+ onSchemaChange?: (event: {
1629
+ command: string;
1630
+ query: string;
1631
+ }) => void;
1632
+ private constructor();
1633
+ private init;
1634
+ static create: (prostgles: Prostgles) => Promise<DboBuilder>;
1635
+ destroy(): void;
1636
+ _joins?: Join[];
1637
+ get joins(): Join[];
1638
+ set joins(j: Join[]);
1639
+ getAllJoinPaths(): JoinPaths;
1640
+ prepareShortestJoinPaths: () => Promise<void>;
1641
+ runSQL: (query: string, params: any, options: SQLOptions | undefined, localParams?: LocalParams) => Promise<any>;
1642
+ build(): Promise<DBHandlerServer>;
1643
+ getShortestJoinPath: (viewHandler: ViewHandler$1, target: string) => JoinPaths[number] | undefined;
1644
+ getTX: (cb: TxCB) => Promise<any>;
1645
+ }
1646
+ export declare const getDBSchema: (dboBuilder: DboBuilder) => string;
1647
+ export type DBTableHandlersFromSchema<Schema = void> = Schema extends DBSchema ? {
1648
+ [tov_name in keyof Schema]: Schema[tov_name]["is_view"] extends true ? ViewHandler<Schema[tov_name]["columns"]> : TableHandler<Schema[tov_name]["columns"]>;
1649
+ } : Record<string, TableHandler>;
1650
+ export type DBOFullyTyped<Schema = void> = Schema extends DBSchema ? (DBTableHandlersFromSchema<Schema> & Pick<DBHandlerServer<DBTableHandlersFromSchema<Schema>>, "tx" | "sql">) : DBHandlerServer;
1651
+ export type PublishFullyTyped<Schema = void> = Schema extends DBSchema ? (PublishAllOrNothing | {
1652
+ [tov_name in keyof Partial<Schema>]: PublishAllOrNothing | (Schema[tov_name]["is_view"] extends true ? PublishViewRule<Schema[tov_name]["columns"], Schema> : PublishTableRule<Schema[tov_name]["columns"], Schema>);
1653
+ }) : (PublishAllOrNothing | Record<string, PublishViewRule | PublishTableRule | PublishAllOrNothing>);
1654
+
1655
+ export {};