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/DboBuilder/TableHandler/insert.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/insert.js +17 -7
- package/dist/DboBuilder/TableHandler/insert.js.map +1 -1
- package/dist/DboBuilder/TableHandler/update.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/update.js +6 -3
- package/dist/DboBuilder/TableHandler/update.js.map +1 -1
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +0 -2
- package/dist/Prostgles.js.map +1 -1
- package/dist/initProstgles.d.ts +2 -2
- package/dist/initProstgles.d.ts.map +1 -1
- package/dist/my.d copy.ts +1020 -0
- package/dist/my.d.ts +1655 -0
- package/lib/DboBuilder/TableHandler/insert.ts +16 -10
- package/lib/DboBuilder/TableHandler/update.ts +6 -4
- package/lib/Prostgles.ts +0 -1
- package/lib/initProstgles.ts +2 -2
- package/package.json +2 -2
- package/tests/isomorphic_queries.ts +10 -0
- package/tests/server/package-lock.json +3 -3
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 {};
|