prostgles-server 4.2.507 → 4.2.508
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/DBSchemaBuilder/DBSchemaBuilder.d.ts +2 -2
- package/dist/DBSchemaBuilder/DBSchemaBuilder.d.ts.map +1 -1
- package/dist/DBSchemaBuilder/DBSchemaBuilder.spec.js +0 -4
- package/dist/DBSchemaBuilder/DBSchemaBuilder.spec.js.map +1 -1
- package/dist/DboBuilder/DboBuilder.d.ts +4 -5
- package/dist/DboBuilder/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilder.js +13 -22
- package/dist/DboBuilder/DboBuilder.js.map +1 -1
- package/dist/DboBuilder/DboBuilderTypes.d.ts +15 -23
- package/dist/DboBuilder/DboBuilderTypes.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilderTypes.js.map +1 -1
- package/dist/DboBuilder/TableHandler/DataValidator.js +1 -1
- package/dist/DboBuilder/TableHandler/DataValidator.js.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.js +9 -8
- package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
- package/dist/DboBuilder/TableHandler/insert/insert.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/insert/insert.js +1 -1
- package/dist/DboBuilder/TableHandler/insert/insert.js.map +1 -1
- package/dist/DboBuilder/TableHandler/insert/insertRowWithNestedRecords.js +2 -2
- package/dist/DboBuilder/TableHandler/insert/insertRowWithNestedRecords.js.map +1 -1
- package/dist/DboBuilder/TableHandler/insertTest.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/insertTest.js +1 -1
- package/dist/DboBuilder/TableHandler/insertTest.js.map +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.js +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.js.map +1 -1
- package/dist/DboBuilder/TableRules/{getValidatedRules.d.ts → getValidatedTableRules.d.ts} +2 -2
- package/dist/DboBuilder/TableRules/getValidatedTableRules.d.ts.map +1 -0
- package/dist/DboBuilder/TableRules/{getValidatedRules.js → getValidatedTableRules.js} +5 -13
- package/dist/DboBuilder/TableRules/getValidatedTableRules.js.map +1 -0
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +3 -7
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.js +2 -35
- package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/getInfo.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/getInfo.js +20 -16
- package/dist/DboBuilder/ViewHandler/getInfo.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/getValidatedSubscribeOptions.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/getValidatedSubscribeOptions.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/getValidatedSubscribeOptions.js +2 -2
- package/dist/DboBuilder/ViewHandler/getValidatedSubscribeOptions.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/subscribe.js +1 -1
- package/dist/DboBuilder/ViewHandler/subscribe.js.map +1 -1
- package/dist/DboBuilder/getColumns.d.ts.map +1 -1
- package/dist/DboBuilder/getColumns.js +0 -2
- package/dist/DboBuilder/getColumns.js.map +1 -1
- package/dist/FileManager/FileManager.d.ts.map +1 -1
- package/dist/FileManager/FileManager.js +3 -3
- package/dist/FileManager/FileManager.js.map +1 -1
- package/dist/FileManager/initFileManager.js +1 -1
- package/dist/FileManager/initFileManager.js.map +1 -1
- package/dist/Prostgles.d.ts +1 -1
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +9 -1
- package/dist/Prostgles.js.map +1 -1
- package/dist/PubSubManager/PubSubManager.d.ts +5 -7
- package/dist/PubSubManager/PubSubManager.d.ts.map +1 -1
- package/dist/PubSubManager/PubSubManager.js.map +1 -1
- package/dist/PubSubManager/PubSubManagerUtils.d.ts +1 -0
- package/dist/PubSubManager/PubSubManagerUtils.d.ts.map +1 -1
- package/dist/PubSubManager/PubSubManagerUtils.js +2 -1
- package/dist/PubSubManager/PubSubManagerUtils.js.map +1 -1
- package/dist/PubSubManager/addSync.d.ts.map +1 -1
- package/dist/PubSubManager/addSync.js +5 -5
- package/dist/PubSubManager/addSync.js.map +1 -1
- package/dist/PubSubManager/addTrigger.js +1 -1
- package/dist/PubSubManager/addTrigger.js.map +1 -1
- package/dist/PublishParser/PublishParser.d.ts +1 -2
- package/dist/PublishParser/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser/PublishParser.js +23 -12
- package/dist/PublishParser/PublishParser.js.map +1 -1
- package/dist/PublishParser/getDBSchemaTable.d.ts +6 -0
- package/dist/PublishParser/getDBSchemaTable.d.ts.map +1 -0
- package/dist/PublishParser/getDBSchemaTable.js +58 -0
- package/dist/PublishParser/getDBSchemaTable.js.map +1 -0
- package/dist/PublishParser/getSchemaFromPublish.d.ts +1 -2
- package/dist/PublishParser/getSchemaFromPublish.d.ts.map +1 -1
- package/dist/PublishParser/getSchemaFromPublish.js +39 -104
- package/dist/PublishParser/getSchemaFromPublish.js.map +1 -1
- package/dist/PublishParser/getTableRulesWithoutFileTable.d.ts.map +1 -1
- package/dist/PublishParser/getTableRulesWithoutFileTable.js +58 -127
- package/dist/PublishParser/getTableRulesWithoutFileTable.js.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts +31 -140
- package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.js +18 -118
- package/dist/PublishParser/publishTypesAndUtils.js.map +1 -1
- package/dist/SyncReplication.d.ts.map +1 -1
- package/dist/SyncReplication.js +4 -6
- package/dist/SyncReplication.js.map +1 -1
- package/dist/TableConfig/TableConfig.d.ts +12 -5
- package/dist/TableConfig/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig/TableConfig.js +16 -9
- package/dist/TableConfig/TableConfig.js.map +1 -1
- package/dist/TableConfig/getCreateSchemaQueries.d.ts +4 -9
- package/dist/TableConfig/getCreateSchemaQueries.d.ts.map +1 -1
- package/dist/TableConfig/getCreateSchemaQueries.js.map +1 -1
- package/dist/TableConfig/getTableColumnQueries.js +1 -1
- package/dist/TableConfig/getTableColumnQueries.js.map +1 -1
- package/dist/TableConfig/getTableConfigSchemaQueries.d.ts +4 -9
- package/dist/TableConfig/getTableConfigSchemaQueries.d.ts.map +1 -1
- package/dist/WebsocketAPI/getClientSchema.d.ts.map +1 -1
- package/dist/WebsocketAPI/getClientSchema.js +3 -3
- package/dist/WebsocketAPI/getClientSchema.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/initProstgles.d.ts +2 -3
- package/dist/initProstgles.d.ts.map +1 -1
- package/dist/initProstgles.js.map +1 -1
- package/dist/runClientRequest.d.ts.map +1 -1
- package/dist/runClientRequest.js +4 -8
- package/dist/runClientRequest.js.map +1 -1
- package/lib/DBSchemaBuilder/DBSchemaBuilder.spec.ts +1 -5
- package/lib/DBSchemaBuilder/DBSchemaBuilder.ts +2 -8
- package/lib/DboBuilder/DboBuilder.ts +18 -26
- package/lib/DboBuilder/DboBuilderTypes.ts +70 -59
- package/lib/DboBuilder/TableHandler/DataValidator.ts +1 -1
- package/lib/DboBuilder/TableHandler/TableHandler.ts +10 -14
- package/lib/DboBuilder/TableHandler/insert/insert.ts +1 -7
- package/lib/DboBuilder/TableHandler/insert/insertRowWithNestedRecords.ts +3 -3
- package/lib/DboBuilder/TableHandler/insertTest.ts +5 -5
- package/lib/DboBuilder/TableHandler/updateFile.ts +1 -1
- package/lib/DboBuilder/TableRules/{getValidatedRules.ts → getValidatedTableRules.ts} +3 -10
- package/lib/DboBuilder/ViewHandler/ViewHandler.ts +7 -41
- package/lib/DboBuilder/ViewHandler/getInfo.ts +24 -20
- package/lib/DboBuilder/ViewHandler/getValidatedSubscribeOptions.ts +4 -4
- package/lib/DboBuilder/ViewHandler/subscribe.ts +1 -1
- package/lib/DboBuilder/getColumns.ts +4 -14
- package/lib/FileManager/FileManager.ts +5 -6
- package/lib/FileManager/initFileManager.ts +1 -1
- package/lib/Prostgles.ts +10 -1
- package/lib/PubSubManager/PubSubManager.ts +12 -13
- package/lib/PubSubManager/PubSubManagerUtils.ts +1 -0
- package/lib/PubSubManager/addSync.ts +4 -7
- package/lib/PubSubManager/addTrigger.ts +1 -1
- package/lib/PublishParser/PublishParser.ts +30 -17
- package/lib/PublishParser/getDBSchemaTable.ts +73 -0
- package/lib/PublishParser/getSchemaFromPublish.ts +56 -147
- package/lib/PublishParser/getTableRulesWithoutFileTable.ts +74 -162
- package/lib/PublishParser/publishTypesAndUtils.ts +41 -167
- package/lib/SyncReplication.ts +6 -8
- package/lib/TableConfig/TableConfig.ts +25 -11
- package/lib/TableConfig/getCreateSchemaQueries.ts +8 -8
- package/lib/TableConfig/getTableColumnQueries.ts +1 -1
- package/lib/WebsocketAPI/getClientSchema.ts +5 -3
- package/lib/index.ts +1 -1
- package/lib/initProstgles.ts +2 -3
- package/lib/runClientRequest.ts +4 -6
- package/package.json +2 -2
- package/dist/DboBuilder/TableRules/getValidatedRules.d.ts.map +0 -1
- package/dist/DboBuilder/TableRules/getValidatedRules.js.map +0 -1
|
@@ -117,7 +117,7 @@ export async function initFileManager(this: FileManager, prg: Prostgles) {
|
|
|
117
117
|
if (!this.dbo[refTable]) {
|
|
118
118
|
throw `Referenced table (${refTable}) from fileTable.referencedTables prostgles init config does not exist`;
|
|
119
119
|
}
|
|
120
|
-
const cols = await (this.dbo[refTable]
|
|
120
|
+
const cols = await (this.dbo[refTable]).getColumns();
|
|
121
121
|
|
|
122
122
|
for (const [colName] of Object.entries(tableConfig.referenceColumns)) {
|
|
123
123
|
const existingCol = cols.find((c) => c.name === colName);
|
package/lib/Prostgles.ts
CHANGED
|
@@ -27,7 +27,15 @@ import { pushSocketSchema } from "./WebsocketAPI/pushSocketSchema";
|
|
|
27
27
|
export type DB = pgPromise.IDatabase<{}, pg.IClient>;
|
|
28
28
|
export type DBorTx = DB | pgPromise.ITask<{}>;
|
|
29
29
|
|
|
30
|
-
export const TABLE_METHODS = [
|
|
30
|
+
export const TABLE_METHODS = [
|
|
31
|
+
"update",
|
|
32
|
+
"find",
|
|
33
|
+
"findOne",
|
|
34
|
+
"insert",
|
|
35
|
+
"insertMany",
|
|
36
|
+
"delete",
|
|
37
|
+
"upsert",
|
|
38
|
+
] as const satisfies (keyof TableHandler)[];
|
|
31
39
|
|
|
32
40
|
/*
|
|
33
41
|
1. Connect to db
|
|
@@ -51,6 +59,7 @@ const DEFAULT_KEYWORDS = {
|
|
|
51
59
|
|
|
52
60
|
import { randomUUID } from "crypto";
|
|
53
61
|
import * as fs from "fs";
|
|
62
|
+
import type { TableHandler } from "./DboBuilder/TableHandler/TableHandler";
|
|
54
63
|
|
|
55
64
|
export class Prostgles {
|
|
56
65
|
/**
|
|
@@ -3,13 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License. See LICENSE in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
7
|
-
DBHandlerServer,
|
|
8
|
-
DboBuilder,
|
|
9
|
-
PRGLIOSocket,
|
|
10
|
-
TableInfo,
|
|
11
|
-
TableOrViewInfo,
|
|
12
|
-
} from "../DboBuilder/DboBuilder";
|
|
6
|
+
import type { DBHandlerServer, DboBuilder, PRGLIOSocket } from "../DboBuilder/DboBuilder";
|
|
13
7
|
import type { PostgresNotifListenManager } from "../PostgresNotifListenManager";
|
|
14
8
|
import type { DB } from "../Prostgles";
|
|
15
9
|
import { addSync } from "./addSync";
|
|
@@ -19,7 +13,14 @@ import { initPubSubManager } from "./init/initPubSubManager";
|
|
|
19
13
|
import { initialiseEventTriggers } from "./initialiseEventTriggers";
|
|
20
14
|
import { refreshTriggers } from "./refreshTriggers";
|
|
21
15
|
|
|
22
|
-
import type {
|
|
16
|
+
import type {
|
|
17
|
+
AnyObject,
|
|
18
|
+
FieldFilter,
|
|
19
|
+
SelectParams,
|
|
20
|
+
SyncTableInfo,
|
|
21
|
+
TableSchema,
|
|
22
|
+
WAL,
|
|
23
|
+
} from "prostgles-types";
|
|
23
24
|
import { CHANNELS, getSerialisableError, type SubscribeOptions } from "prostgles-types";
|
|
24
25
|
|
|
25
26
|
import { find, pickKeys } from "prostgles-types";
|
|
@@ -56,13 +57,11 @@ export type SyncParams = {
|
|
|
56
57
|
is_syncing: boolean;
|
|
57
58
|
};
|
|
58
59
|
|
|
59
|
-
export type AddSyncParams = {
|
|
60
|
+
export type AddSyncParams = SyncTableInfo & {
|
|
60
61
|
socket: PRGLIOSocket;
|
|
61
|
-
table_info:
|
|
62
|
+
table_info: TableSchema;
|
|
62
63
|
table_rules: ParsedTableRule;
|
|
63
|
-
synced_field: string;
|
|
64
64
|
allow_delete?: boolean;
|
|
65
|
-
id_fields: string[];
|
|
66
65
|
filter: object;
|
|
67
66
|
params: {
|
|
68
67
|
select: FieldFilter;
|
|
@@ -99,7 +98,7 @@ export type SubscriptionParams = {
|
|
|
99
98
|
viewOptions?: ViewSubscriptionOptions;
|
|
100
99
|
parentSubParams: Omit<SubscriptionParams, "parentSubParams"> | undefined;
|
|
101
100
|
|
|
102
|
-
table_info:
|
|
101
|
+
table_info: TableSchema;
|
|
103
102
|
|
|
104
103
|
/* Used as input */
|
|
105
104
|
table_rules?: ParsedTableRule;
|
|
@@ -27,6 +27,7 @@ export const EXCLUDE_QUERY_FROM_SCHEMA_WATCH_ID =
|
|
|
27
27
|
type PGP = pgPromise.IMain<{}, pg.IClient>;
|
|
28
28
|
export const pgp: PGP = pgPromise({});
|
|
29
29
|
export const asValue = (v: any, castAs?: ":csv") => pgp.as.format(`$1${castAs ?? ""}`, [v]);
|
|
30
|
+
export const DEFAULT_SYNC_THROTTLE = 100;
|
|
30
31
|
export const DEFAULT_SYNC_BATCH_SIZE = 50;
|
|
31
32
|
|
|
32
33
|
let lastLog: { count: number; msg: string } | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { find, tryCatchV2 } from "prostgles-types";
|
|
2
2
|
import type { AddSyncParams, BasicCallback, PubSubManager } from "./PubSubManager";
|
|
3
|
-
import {
|
|
3
|
+
import { parseCondition } from "./PubSubManagerUtils";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Returns a sync channel
|
|
@@ -17,11 +17,9 @@ export async function addSync(
|
|
|
17
17
|
table_info = null,
|
|
18
18
|
table_rules,
|
|
19
19
|
synced_field = null,
|
|
20
|
-
id_fields = [],
|
|
21
20
|
filter = {},
|
|
22
21
|
params,
|
|
23
22
|
condition = "",
|
|
24
|
-
throttle = 0,
|
|
25
23
|
} = syncParams;
|
|
26
24
|
const conditionParsed = parseCondition(condition);
|
|
27
25
|
if (!socket || !table_info) throw "socket or table_info missing";
|
|
@@ -33,18 +31,17 @@ export async function addSync(
|
|
|
33
31
|
|
|
34
32
|
this.upsertSocket(socket);
|
|
35
33
|
|
|
34
|
+
const syncConfig = this.dboBuilder.prostgles.tableConfigurator?.getTableSyncConfig(table_name);
|
|
35
|
+
if (!syncConfig) throw `Sync not configured for table ${table_name}`;
|
|
36
36
|
const upsertSync = () => {
|
|
37
37
|
const newSync = {
|
|
38
38
|
channel_name: channelName,
|
|
39
39
|
table_name,
|
|
40
40
|
filter,
|
|
41
41
|
condition: conditionParsed,
|
|
42
|
-
synced_field,
|
|
43
42
|
sid,
|
|
44
|
-
id_fields,
|
|
45
43
|
table_rules,
|
|
46
|
-
|
|
47
|
-
batch_size: table_rules.sync?.batch_size || DEFAULT_SYNC_BATCH_SIZE,
|
|
44
|
+
...syncConfig,
|
|
48
45
|
socket_id: socket.id,
|
|
49
46
|
is_sync: true,
|
|
50
47
|
last_synced: 0,
|
|
@@ -26,7 +26,7 @@ export async function addTrigger(
|
|
|
26
26
|
condition = "TRUE";
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
if (this.dbo[table_name]?.tableOrViewInfo
|
|
29
|
+
if (this.dbo[table_name]?.tableOrViewInfo.isHyperTable) {
|
|
30
30
|
throw "Triggers do not work on timescaledb hypertables due to bug:\nhttps://github.com/timescale/timescaledb/issues/1084";
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { includes } from "prostgles-types";
|
|
1
|
+
import { getObjectEntries, includes, SQL_COMMAND_TABLE_METHODS } from "prostgles-types";
|
|
2
2
|
import { getClientRequestIPsInfo } from "../Auth/AuthHandler";
|
|
3
3
|
import type { AuthClientRequest, AuthResultWithSID } from "../Auth/AuthTypes";
|
|
4
4
|
import type { DBOFullyTyped } from "../DBSchemaBuilder/DBSchemaBuilder";
|
|
@@ -17,7 +17,6 @@ import type {
|
|
|
17
17
|
PublishParams,
|
|
18
18
|
} from "./publishTypesAndUtils";
|
|
19
19
|
import {
|
|
20
|
-
RULE_TO_METHODS,
|
|
21
20
|
parsePublishTableRule,
|
|
22
21
|
type PermissionScope,
|
|
23
22
|
type PublishObject,
|
|
@@ -37,7 +36,9 @@ export class PublishParser {
|
|
|
37
36
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
38
37
|
this.publishRawSQL = prostgles.opts.publishRawSQL;
|
|
39
38
|
const { dbo, db } = prostgles;
|
|
40
|
-
if (!dbo || !db)
|
|
39
|
+
if (!dbo || !db) {
|
|
40
|
+
throw "INTERNAL ERROR: dbo and/or db missing";
|
|
41
|
+
}
|
|
41
42
|
this.dbo = dbo;
|
|
42
43
|
this.db = db;
|
|
43
44
|
}
|
|
@@ -83,14 +84,14 @@ export class PublishParser {
|
|
|
83
84
|
/**
|
|
84
85
|
* Parses the first level of publish. (If false then nothing if * then all tables and views)
|
|
85
86
|
*/
|
|
86
|
-
async
|
|
87
|
+
async getPublishObject(
|
|
87
88
|
clientReq: AuthClientRequest,
|
|
88
89
|
clientInfo: AuthResultWithSID | undefined,
|
|
89
90
|
): Promise<PublishObject | undefined> {
|
|
90
91
|
const publishParams = await this.getPublishParams(clientReq, clientInfo);
|
|
91
|
-
const
|
|
92
|
+
const publish = await applyParamsIfFunc(this.publish, publishParams);
|
|
92
93
|
|
|
93
|
-
if (
|
|
94
|
+
if (publish === "*") {
|
|
94
95
|
const publish: PublishObject = {};
|
|
95
96
|
this.prostgles.dboBuilder.tablesOrViews?.map((tov) => {
|
|
96
97
|
publish[tov.name] = "*";
|
|
@@ -98,7 +99,7 @@ export class PublishParser {
|
|
|
98
99
|
return publish;
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
return
|
|
102
|
+
return publish || undefined;
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
async getValidatedRequestRuleWusr(
|
|
@@ -124,13 +125,12 @@ export class PublishParser {
|
|
|
124
125
|
|
|
125
126
|
/* Must be local request -> allow everything */
|
|
126
127
|
if (!clientReq) {
|
|
127
|
-
return
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
);
|
|
128
|
+
return {
|
|
129
|
+
select: { fields: "*", filterFields: "*", orderByFields: "*" },
|
|
130
|
+
insert: { returningFields: "*", fields: "*" },
|
|
131
|
+
update: { fields: "*", returningFields: "*", filterFields: "*" },
|
|
132
|
+
delete: { returningFields: "*", filterFields: "*" },
|
|
133
|
+
};
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
/* Must be from socket. Must have a publish */
|
|
@@ -160,7 +160,10 @@ export class PublishParser {
|
|
|
160
160
|
) {
|
|
161
161
|
if (!command || !tableName) throw "command OR tableName are missing";
|
|
162
162
|
|
|
163
|
-
const rule =
|
|
163
|
+
const [rule] =
|
|
164
|
+
getObjectEntries(SQL_COMMAND_TABLE_METHODS).find(([_, methods]) =>
|
|
165
|
+
includes(methods, command),
|
|
166
|
+
) ?? [];
|
|
164
167
|
if (!rule) {
|
|
165
168
|
throw "Invalid command: " + command;
|
|
166
169
|
}
|
|
@@ -170,7 +173,15 @@ export class PublishParser {
|
|
|
170
173
|
// Allow all commands
|
|
171
174
|
} else {
|
|
172
175
|
const tableScope = scope.tables;
|
|
173
|
-
|
|
176
|
+
const tableScopeCommands = tableScope?.[tableName];
|
|
177
|
+
const methodAllowedInScope =
|
|
178
|
+
tableScopeCommands &&
|
|
179
|
+
(rule === "schema" ?
|
|
180
|
+
getObjectEntries(tableScopeCommands).some(([_, value]) => {
|
|
181
|
+
return value;
|
|
182
|
+
})
|
|
183
|
+
: tableScopeCommands[rule]);
|
|
184
|
+
if (!methodAllowedInScope) {
|
|
174
185
|
throw `Invalid or disallowed command: ${tableName}.${command}. The PermissionsScope does not allow this command.`;
|
|
175
186
|
}
|
|
176
187
|
}
|
|
@@ -185,7 +196,9 @@ export class PublishParser {
|
|
|
185
196
|
}
|
|
186
197
|
}
|
|
187
198
|
|
|
188
|
-
|
|
199
|
+
const isAllowed =
|
|
200
|
+
rule === "schema" ? getObjectEntries(tableRule).some(([_, value]) => value) : tableRule[rule];
|
|
201
|
+
if (!isAllowed) {
|
|
189
202
|
throw {
|
|
190
203
|
stack: ["getValidatedRequestRule()"],
|
|
191
204
|
message: `Invalid or disallowed command: ${tableName}.${command}`,
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { getObjectEntries, includes, type DBSchemaTable } from "prostgles-types";
|
|
2
|
+
import type { AuthClientRequest } from "../Auth/AuthTypes";
|
|
3
|
+
import { getErrorAsObject } from "../DboBuilder/dboBuilderUtils";
|
|
4
|
+
import type { TableHandler } from "../DboBuilder/TableHandler/TableHandler";
|
|
5
|
+
import { TABLE_METHODS } from "../Prostgles";
|
|
6
|
+
import type { ParsedTableRule, PermissionScope, PublishParser } from "./PublishParser";
|
|
7
|
+
import { getAllowedTableMethods } from "prostgles-types";
|
|
8
|
+
|
|
9
|
+
export const getDBSchemaTable = async (
|
|
10
|
+
publishParser: PublishParser,
|
|
11
|
+
tableHandler: TableHandler,
|
|
12
|
+
parsedTableRule: ParsedTableRule,
|
|
13
|
+
clientReq: AuthClientRequest,
|
|
14
|
+
scope: PermissionScope | undefined,
|
|
15
|
+
): Promise<DBSchemaTable> => {
|
|
16
|
+
const tableName = tableHandler.name;
|
|
17
|
+
|
|
18
|
+
if (getObjectEntries(parsedTableRule).every(([_ruleName, ruleOptions]) => !ruleOptions)) {
|
|
19
|
+
throw new Error("At least one of the rules must be defined for " + tableName);
|
|
20
|
+
}
|
|
21
|
+
const info = await tableHandler.getInfo(undefined, undefined, undefined, parsedTableRule, {
|
|
22
|
+
...clientReq,
|
|
23
|
+
isRemoteRequest: {},
|
|
24
|
+
});
|
|
25
|
+
const columns = await tableHandler.getColumns(undefined, undefined, undefined, parsedTableRule, {
|
|
26
|
+
...clientReq,
|
|
27
|
+
isRemoteRequest: {},
|
|
28
|
+
});
|
|
29
|
+
const allowedCommands = getAllowedTableMethods(info);
|
|
30
|
+
for (const method of allowedCommands) {
|
|
31
|
+
if (method === "getInfo" || method === "getColumns") {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
publishParser.validateRequestRule(
|
|
36
|
+
{
|
|
37
|
+
tableName,
|
|
38
|
+
command: method,
|
|
39
|
+
clientReq,
|
|
40
|
+
},
|
|
41
|
+
parsedTableRule,
|
|
42
|
+
scope,
|
|
43
|
+
);
|
|
44
|
+
} catch (e) {
|
|
45
|
+
console.error(`${tableName}.${method}`, e);
|
|
46
|
+
throw {
|
|
47
|
+
...getErrorAsObject(e),
|
|
48
|
+
publishPath: `publish.${tableName}.${method}`,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** Crucial in ensuring the published client tableHandler methods work without issues */
|
|
52
|
+
if (publishParser.prostgles.opts.testRulesOnConnect && includes(TABLE_METHODS, method)) {
|
|
53
|
+
await tableHandler.dboBuilder.dboMap.get(tableName)?.[method](
|
|
54
|
+
//@ts-expect-error
|
|
55
|
+
method === "insertMany" ? [] : {},
|
|
56
|
+
{},
|
|
57
|
+
undefined,
|
|
58
|
+
parsedTableRule,
|
|
59
|
+
{
|
|
60
|
+
...clientReq,
|
|
61
|
+
isRemoteRequest: {},
|
|
62
|
+
testRule: true,
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
...info,
|
|
70
|
+
name: tableHandler.name,
|
|
71
|
+
columns,
|
|
72
|
+
} satisfies DBSchemaTable;
|
|
73
|
+
};
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
TableInfo,
|
|
4
|
-
TableSchemaErrors,
|
|
5
|
-
TableSchemaForClient,
|
|
6
|
-
} from "prostgles-types";
|
|
7
|
-
import { getKeys, includes, isEmpty, isObject, pickKeys, type AnyObject } from "prostgles-types";
|
|
1
|
+
import type { DBSchemaTable, TableSchemaErrors } from "prostgles-types";
|
|
2
|
+
import { isEmpty, isObject } from "prostgles-types";
|
|
8
3
|
import type { AuthClientRequest, AuthResultWithSID } from "../Auth/AuthTypes";
|
|
9
|
-
import { getErrorAsObject } from "../DboBuilder/DboBuilder";
|
|
10
4
|
import type { TableHandler } from "../DboBuilder/TableHandler/TableHandler";
|
|
11
|
-
import { TABLE_METHODS } from "../Prostgles";
|
|
12
5
|
import type { PublishParser } from "./PublishParser";
|
|
13
6
|
import { type PermissionScope, type PublishObject } from "./PublishParser";
|
|
7
|
+
import { getDBSchemaTable } from "./getDBSchemaTable";
|
|
14
8
|
|
|
15
9
|
type Args = AuthClientRequest & {
|
|
16
10
|
userData: AuthResultWithSID | undefined;
|
|
@@ -22,13 +16,13 @@ export async function getSchemaFromPublish(
|
|
|
22
16
|
{ userData, ...clientReq }: Args,
|
|
23
17
|
scope: PermissionScope | undefined,
|
|
24
18
|
): Promise<{
|
|
25
|
-
schema: TableSchemaForClient;
|
|
26
19
|
tables: DBSchemaTable[];
|
|
27
20
|
tableSchemaErrors: TableSchemaErrors;
|
|
28
21
|
}> {
|
|
29
|
-
const schema: TableSchemaForClient = {};
|
|
30
22
|
const tableSchemaErrors: TableSchemaErrors = {};
|
|
31
|
-
|
|
23
|
+
const tables: DBSchemaTable[] = [];
|
|
24
|
+
|
|
25
|
+
const txKey = !this.prostgles.opts.transactions ? "" : "tx";
|
|
32
26
|
|
|
33
27
|
try {
|
|
34
28
|
/* Publish tables and views based on socket */
|
|
@@ -37,156 +31,71 @@ export async function getSchemaFromPublish(
|
|
|
37
31
|
if (clientInfo === "new-session-redirect") {
|
|
38
32
|
throw "new-session-redirect";
|
|
39
33
|
}
|
|
40
|
-
let
|
|
34
|
+
let publish: PublishObject | undefined;
|
|
41
35
|
try {
|
|
42
|
-
|
|
36
|
+
publish = await this.getPublishObject(clientReq, clientInfo);
|
|
43
37
|
} catch (err) {
|
|
44
38
|
console.error("Error within then Publish function ", err);
|
|
45
39
|
throw err;
|
|
46
40
|
}
|
|
47
41
|
|
|
48
|
-
if (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
txKey = this.prostgles.opts.transactions;
|
|
53
|
-
|
|
54
|
-
const tableNames = Object.keys(_publish).filter((k) => !txKey || txKey !== k);
|
|
42
|
+
if (!publish || !Object.keys(publish).length) {
|
|
43
|
+
return { tables, tableSchemaErrors };
|
|
44
|
+
}
|
|
45
|
+
const tableNames = Object.keys(publish).filter((k) => !txKey || txKey !== k);
|
|
55
46
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
47
|
+
/**
|
|
48
|
+
* Add file table to the list of published tables if it's referenced by other published tables.
|
|
49
|
+
* Access to the file table is controlled through the publish rules of the tables referencing it.
|
|
50
|
+
*/
|
|
51
|
+
const fileTableName = this.prostgles.fileManager?.tableName;
|
|
52
|
+
if (fileTableName && this.dbo[fileTableName]?.is_media && !tableNames.includes(fileTableName)) {
|
|
53
|
+
const isReferenced = this.prostgles.dboBuilder.tablesOrViews?.some((t) =>
|
|
54
|
+
t.columns.some((c) => c.references?.some((r) => r.ftable === fileTableName)),
|
|
55
|
+
);
|
|
56
|
+
if (isReferenced) {
|
|
57
|
+
tableNames.unshift(fileTableName);
|
|
68
58
|
}
|
|
69
|
-
|
|
70
|
-
tableNames.map(async (tableName) => {
|
|
71
|
-
const { canSubscribe, tablesOrViews } = this.prostgles.dboBuilder;
|
|
72
|
-
if (!this.dbo[tableName]) {
|
|
73
|
-
const errMsg = [
|
|
74
|
-
`Table ${tableName} does not exist`,
|
|
75
|
-
`Expecting one of: ${JSON.stringify(tablesOrViews?.map((tov) => tov.name))}`,
|
|
76
|
-
].join("\n");
|
|
77
|
-
throw errMsg;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const parsedTableRule = await this.getTableRules(
|
|
81
|
-
{ clientReq, tableName },
|
|
82
|
-
clientInfo,
|
|
83
|
-
scope,
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
if (!parsedTableRule || isEmpty(parsedTableRule)) return;
|
|
87
|
-
if (!isObject(parsedTableRule)) {
|
|
88
|
-
throw `Invalid tableRules for table ${tableName}. Expecting an object`;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
schema[tableName] = {};
|
|
92
|
-
const tableSchema = schema[tableName];
|
|
93
|
-
const methods = getKeys(parsedTableRule).filter(
|
|
94
|
-
(m) => canSubscribe || !includes(SUBSCRIBE_METHODS, m),
|
|
95
|
-
);
|
|
96
|
-
let tableInfo: TableInfo | undefined;
|
|
97
|
-
let tableColumns: DBSchemaTable["columns"] | undefined;
|
|
98
|
-
|
|
99
|
-
await Promise.all(
|
|
100
|
-
methods
|
|
101
|
-
.filter((m) => m !== "select")
|
|
102
|
-
.map(async (method) => {
|
|
103
|
-
if (method === "sync") {
|
|
104
|
-
/* Pass sync info */
|
|
105
|
-
tableSchema[method] = parsedTableRule[method];
|
|
106
|
-
} else if (includes(getKeys(parsedTableRule), method) && parsedTableRule[method]) {
|
|
107
|
-
//@ts-ignore
|
|
108
|
-
tableSchema[method] =
|
|
109
|
-
method === "insert" ?
|
|
110
|
-
pickKeys(parsedTableRule[method], ["allowedNestedInserts"])
|
|
111
|
-
: ({} as AnyObject);
|
|
59
|
+
}
|
|
112
60
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
);
|
|
125
|
-
if (this.prostgles.opts.testRulesOnConnect) {
|
|
126
|
-
await (this.dbo[tableName] as TableHandler)[method](
|
|
127
|
-
{},
|
|
128
|
-
{},
|
|
129
|
-
undefined,
|
|
130
|
-
parsedTableRule,
|
|
131
|
-
{
|
|
132
|
-
...clientReq,
|
|
133
|
-
isRemoteRequest: {},
|
|
134
|
-
testRule: true,
|
|
135
|
-
},
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
} catch (e) {
|
|
139
|
-
console.error(`${tableName}.${method}`, e);
|
|
140
|
-
tableSchemaErrors[tableName] ??= {};
|
|
141
|
-
tableSchemaErrors[tableName][method] = {
|
|
142
|
-
error: "Internal publish error. Check server logs",
|
|
143
|
-
};
|
|
61
|
+
await Promise.all(
|
|
62
|
+
tableNames.map(async (tableName) => {
|
|
63
|
+
const { tablesOrViews } = this.prostgles.dboBuilder;
|
|
64
|
+
const tableHandler = this.dbo[tableName];
|
|
65
|
+
if (!tableHandler) {
|
|
66
|
+
const errMsg = [
|
|
67
|
+
`Table ${tableName} does not exist`,
|
|
68
|
+
`Expecting one of: ${JSON.stringify(tablesOrViews?.map((tov) => tov.name))}`,
|
|
69
|
+
].join("\n");
|
|
70
|
+
throw errMsg;
|
|
71
|
+
}
|
|
144
72
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
73
|
+
const parsedTableRule = await this.getTableRules(
|
|
74
|
+
{ clientReq, tableName },
|
|
75
|
+
clientInfo,
|
|
76
|
+
scope,
|
|
77
|
+
);
|
|
151
78
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
scope,
|
|
157
|
-
);
|
|
158
|
-
const res = await (this.dbo[tableName] as TableHandler)[method](
|
|
159
|
-
undefined,
|
|
160
|
-
undefined,
|
|
161
|
-
undefined,
|
|
162
|
-
parsedTableRule,
|
|
163
|
-
{ ...clientReq, isRemoteRequest: {} },
|
|
164
|
-
);
|
|
165
|
-
if (method === "getInfo") {
|
|
166
|
-
tableInfo = res as TableInfo;
|
|
167
|
-
} else {
|
|
168
|
-
tableColumns = res as DBSchemaTable["columns"];
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}),
|
|
173
|
-
);
|
|
79
|
+
if (!parsedTableRule || isEmpty(parsedTableRule)) return;
|
|
80
|
+
if (!isObject(parsedTableRule)) {
|
|
81
|
+
throw `Invalid tableRules for table ${tableName}. Expecting an object`;
|
|
82
|
+
}
|
|
174
83
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
)
|
|
184
|
-
|
|
84
|
+
const tableSchema = await getDBSchemaTable(
|
|
85
|
+
this,
|
|
86
|
+
tableHandler,
|
|
87
|
+
parsedTableRule,
|
|
88
|
+
clientReq,
|
|
89
|
+
scope,
|
|
90
|
+
);
|
|
91
|
+
tables.push(tableSchema);
|
|
92
|
+
}),
|
|
93
|
+
);
|
|
185
94
|
} catch (error) {
|
|
186
95
|
console.error("Publish error", error);
|
|
187
96
|
throw error;
|
|
188
97
|
}
|
|
189
98
|
|
|
190
|
-
tables = tables.sort((a, b) => a.name.localeCompare(b.name));
|
|
191
|
-
return {
|
|
99
|
+
// tables = tables.sort((a, b) => a.name.localeCompare(b.name));
|
|
100
|
+
return { tables, tableSchemaErrors };
|
|
192
101
|
}
|