prostgles-server 4.2.507 → 4.2.509
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
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getObjectEntries, isObject } from "prostgles-types";
|
|
2
2
|
import type { AuthResultWithSID } from "../Auth/AuthTypes";
|
|
3
3
|
import type { TableHandler } from "../DboBuilder/TableHandler/TableHandler";
|
|
4
4
|
import type { ViewHandler } from "../DboBuilder/ViewHandler/ViewHandler";
|
|
5
|
-
import { DEFAULT_SYNC_BATCH_SIZE } from "../PubSubManager/PubSubManagerUtils";
|
|
6
5
|
import type { PublishParser } from "./PublishParser";
|
|
7
|
-
import type {
|
|
8
|
-
|
|
9
|
-
ParsedPublishTable,
|
|
10
|
-
PublishTableRule,
|
|
11
|
-
PublishViewRule,
|
|
12
|
-
} from "./publishTypesAndUtils";
|
|
13
|
-
import { type PublishObject, RULE_TO_METHODS } from "./publishTypesAndUtils";
|
|
6
|
+
import type { DboTable, ParsedPublishTable } from "./publishTypesAndUtils";
|
|
7
|
+
import { TABLE_RULE_NO_LIMITS, type PublishObject } from "./publishTypesAndUtils";
|
|
14
8
|
|
|
15
9
|
export async function getTableRulesWithoutFileTable(
|
|
16
10
|
this: PublishParser,
|
|
@@ -18,182 +12,100 @@ export async function getTableRulesWithoutFileTable(
|
|
|
18
12
|
clientInfo: AuthResultWithSID | undefined,
|
|
19
13
|
overridenPublish?: PublishObject,
|
|
20
14
|
): Promise<ParsedPublishTable | undefined> {
|
|
21
|
-
if (!tableName)
|
|
15
|
+
if (!tableName) {
|
|
16
|
+
throw new Error("tableName is missing in getTableRules");
|
|
17
|
+
}
|
|
22
18
|
|
|
23
19
|
const publish =
|
|
24
|
-
overridenPublish ?? (clientReq && (await this.
|
|
20
|
+
overridenPublish ?? (clientReq && (await this.getPublishObject(clientReq, clientInfo)));
|
|
25
21
|
|
|
26
22
|
const rawTableRule = publish?.[tableName];
|
|
27
23
|
if (!rawTableRule || (isObject(rawTableRule) && Object.values(rawTableRule).every((v) => !v))) {
|
|
28
24
|
return undefined;
|
|
29
25
|
}
|
|
30
26
|
|
|
31
|
-
let parsedTableRule: ParsedPublishTable = {};
|
|
32
|
-
|
|
33
27
|
/* Get view or table specific rules */
|
|
34
|
-
const
|
|
35
|
-
if (!
|
|
28
|
+
const tableHandler = this.dbo[tableName] as TableHandler | ViewHandler | undefined;
|
|
29
|
+
if (!tableHandler) {
|
|
36
30
|
throw {
|
|
37
31
|
stack: ["getTableRules()"],
|
|
38
32
|
message: `${tableName} could not be found in dbo`,
|
|
39
33
|
};
|
|
40
34
|
}
|
|
41
|
-
|
|
35
|
+
|
|
36
|
+
const is_view = tableHandler.is_view;
|
|
37
|
+
|
|
42
38
|
/**
|
|
43
39
|
* Allow subscribing to a view if it has primary key columns from other tables
|
|
44
40
|
*/
|
|
45
|
-
const canSubscribe = !is_view ||
|
|
41
|
+
const canSubscribe = !is_view || tableHandler.columns.some((c) => c.references);
|
|
42
|
+
|
|
43
|
+
const isStarOrTrue = (value: any): value is "*" | true => value === "*" || value === true;
|
|
44
|
+
const { privileges } = tableHandler.tableOrViewInfo;
|
|
45
|
+
const tableRulesObject =
|
|
46
|
+
isStarOrTrue(rawTableRule) ?
|
|
47
|
+
{
|
|
48
|
+
select: privileges.select ? TABLE_RULE_NO_LIMITS.select : undefined,
|
|
49
|
+
insert: privileges.insert ? TABLE_RULE_NO_LIMITS.insert : undefined,
|
|
50
|
+
update: privileges.update ? TABLE_RULE_NO_LIMITS.update : undefined,
|
|
51
|
+
delete: privileges.delete ? TABLE_RULE_NO_LIMITS.delete : undefined,
|
|
52
|
+
}
|
|
53
|
+
: rawTableRule;
|
|
54
|
+
|
|
55
|
+
const selectRule =
|
|
56
|
+
!tableRulesObject.select ? undefined
|
|
57
|
+
: isStarOrTrue(tableRulesObject.select) ? TABLE_RULE_NO_LIMITS.select
|
|
58
|
+
: tableRulesObject.select;
|
|
59
|
+
const insertRule =
|
|
60
|
+
!tableRulesObject.insert ? undefined
|
|
61
|
+
: isStarOrTrue(tableRulesObject.insert) ? TABLE_RULE_NO_LIMITS.insert
|
|
62
|
+
: tableRulesObject.insert;
|
|
63
|
+
const updateRule =
|
|
64
|
+
!tableRulesObject.update ? undefined
|
|
65
|
+
: isStarOrTrue(tableRulesObject.update) ? TABLE_RULE_NO_LIMITS.update
|
|
66
|
+
: tableRulesObject.update;
|
|
67
|
+
const deleteRule =
|
|
68
|
+
!tableRulesObject.delete ? undefined
|
|
69
|
+
: isStarOrTrue(tableRulesObject.delete) ? TABLE_RULE_NO_LIMITS.delete
|
|
70
|
+
: tableRulesObject.delete;
|
|
71
|
+
|
|
72
|
+
const parsedTableRule: ParsedPublishTable = {
|
|
73
|
+
select: selectRule && {
|
|
74
|
+
...selectRule,
|
|
75
|
+
disableMethods:
|
|
76
|
+
canSubscribe ?
|
|
77
|
+
selectRule.disableMethods
|
|
78
|
+
: {
|
|
79
|
+
...selectRule.disableMethods,
|
|
80
|
+
subscribe: 1,
|
|
81
|
+
},
|
|
82
|
+
subscribeThrottle: selectRule.subscribeThrottle ?? 0,
|
|
83
|
+
},
|
|
84
|
+
insert: insertRule,
|
|
85
|
+
update: updateRule,
|
|
86
|
+
delete: deleteRule,
|
|
87
|
+
};
|
|
46
88
|
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
89
|
+
const cannotBatchUpdate =
|
|
90
|
+
!parsedTableRule.update ||
|
|
91
|
+
parsedTableRule.update.checkFilter ||
|
|
92
|
+
parsedTableRule.update.postValidate;
|
|
51
93
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
94
|
+
if (cannotBatchUpdate && parsedTableRule.update) {
|
|
95
|
+
parsedTableRule.update.disableMethods = {
|
|
96
|
+
updateBatch: 1,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
getObjectEntries(parsedTableRule).forEach(([publishCommand, publishValue]) => {
|
|
100
|
+
if (!publishValue) {
|
|
101
|
+
return;
|
|
58
102
|
}
|
|
59
103
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
// if (isObject(raw_table_rules) && (raw_table_rules as PublishTableRule)[r.rule]) {
|
|
64
|
-
// throw `Cannot publish realtime rule ${tableName}.${r.rule}. Superuser is required for this`
|
|
65
|
-
// }
|
|
66
|
-
// }
|
|
67
|
-
|
|
68
|
-
if (r.rule === "subscribe" && !canSubscribe) {
|
|
69
|
-
result = false;
|
|
104
|
+
const pgUserIsAllowedThisCommand = tableHandler.tableOrViewInfo.privileges[publishCommand];
|
|
105
|
+
if (!pgUserIsAllowedThisCommand) {
|
|
106
|
+
throw `Current postgres user is not allowed ${publishCommand} on table ${tableName}`;
|
|
70
107
|
}
|
|
71
|
-
|
|
72
|
-
return result;
|
|
73
108
|
});
|
|
74
109
|
|
|
75
|
-
/* All methods allowed. Add no limits for table rules */
|
|
76
|
-
if (includes([true, "*"], rawTableRule)) {
|
|
77
|
-
parsedTableRule = {};
|
|
78
|
-
MY_RULES.filter((r) => r.no_limits).forEach((r) => {
|
|
79
|
-
parsedTableRule[r.rule] = { ...(r.no_limits as object) } as any;
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
/** Specific rules allowed */
|
|
83
|
-
} else if (isObject(rawTableRule) && getKeys(rawTableRule).length) {
|
|
84
|
-
const allRuleKeys: (keyof PublishViewRule | keyof PublishTableRule)[] = getKeys(rawTableRule);
|
|
85
|
-
const dissallowedRuleKeys = allRuleKeys.filter((m) => !(rawTableRule as PublishTableRule)[m]);
|
|
86
|
-
|
|
87
|
-
MY_RULES.map((r) => {
|
|
88
|
-
/** Unless specifically disabled these are allowed */
|
|
89
|
-
if (
|
|
90
|
-
["getInfo", "getColumns"].includes(r.rule) &&
|
|
91
|
-
!dissallowedRuleKeys.includes(r.rule as any)
|
|
92
|
-
) {
|
|
93
|
-
parsedTableRule[r.rule] = r.no_limits as any;
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/** Add no_limit values for implied/ fully allowed methods */
|
|
98
|
-
if ([true, "*"].includes((rawTableRule as PublishTableRule)[r.rule] as any) && r.no_limits) {
|
|
99
|
-
parsedTableRule[r.rule] = Object.assign({}, r.no_limits) as any;
|
|
100
|
-
|
|
101
|
-
/** Carry over detailed config */
|
|
102
|
-
} else if (isObject((rawTableRule as any)[r.rule])) {
|
|
103
|
-
parsedTableRule[r.rule] = (rawTableRule as any)[r.rule];
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
allRuleKeys
|
|
108
|
-
.filter((m) => parsedTableRule[m])
|
|
109
|
-
.forEach((method) => {
|
|
110
|
-
const rule = parsedTableRule[method];
|
|
111
|
-
|
|
112
|
-
const ruleInfo = MY_RULES.find(
|
|
113
|
-
(r) => r.rule === method || (r.methods as readonly string[]).includes(method),
|
|
114
|
-
);
|
|
115
|
-
if (!ruleInfo) {
|
|
116
|
-
let extraInfo = "";
|
|
117
|
-
if (
|
|
118
|
-
is_view &&
|
|
119
|
-
RULE_TO_METHODS.find(
|
|
120
|
-
(r) =>
|
|
121
|
-
r.table_only &&
|
|
122
|
-
(r.rule === method || (r.methods as readonly string[]).includes(method)),
|
|
123
|
-
)
|
|
124
|
-
) {
|
|
125
|
-
extraInfo = "You've specified table rules to a view\n";
|
|
126
|
-
}
|
|
127
|
-
throw `Invalid rule in publish.${tableName} -> ${method} \n${extraInfo}Expecting any of: ${MY_RULES.flatMap((r) => [r.rule, ...r.methods]).join(", ")}`;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/* Check RULES for invalid params */
|
|
131
|
-
/* Methods do not have params -> They use them from rules */
|
|
132
|
-
if (method === ruleInfo.rule && isObject(rule)) {
|
|
133
|
-
const method_params = Object.keys(rule);
|
|
134
|
-
const allowed_params = Object.keys(ruleInfo.allowed_params);
|
|
135
|
-
const iparam = method_params.find((p) => !allowed_params.includes(p));
|
|
136
|
-
if (iparam) {
|
|
137
|
-
throw `Invalid setting in publish.${tableName}.${method} -> ${iparam}. \n Expecting any of: ${allowed_params.join(", ")}`;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/* Add default params (if missing) */
|
|
142
|
-
if (method === "sync") {
|
|
143
|
-
if ([true, "*"].includes(parsedTableRule[method] as any)) {
|
|
144
|
-
throw "Invalid sync rule. Expecting { id_fields: string[], synced_field: string } ";
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (typeof parsedTableRule[method]?.throttle !== "number") {
|
|
148
|
-
parsedTableRule[method]!.throttle = 100;
|
|
149
|
-
}
|
|
150
|
-
if (typeof parsedTableRule[method]?.batch_size !== "number") {
|
|
151
|
-
parsedTableRule[method]!.batch_size = DEFAULT_SYNC_BATCH_SIZE;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/* Enable subscribe if not explicitly disabled OR if VIEW with referenced tables */
|
|
156
|
-
const subKey = "subscribe";
|
|
157
|
-
|
|
158
|
-
if (method === "select" && !dissallowedRuleKeys.includes(subKey)) {
|
|
159
|
-
const sr = MY_RULES.find((r) => r.rule === subKey);
|
|
160
|
-
if (sr && canSubscribe) {
|
|
161
|
-
parsedTableRule[subKey] = { ...sr.no_limits };
|
|
162
|
-
parsedTableRule.subscribeOne = { ...sr.no_limits };
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
} else {
|
|
167
|
-
throw "Unexpected publish";
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const getImpliedMethods = (tableRules: ParsedPublishTable): ParsedPublishTable => {
|
|
171
|
-
const res = { ...tableRules };
|
|
172
|
-
|
|
173
|
-
/* Add implied methods if not specifically dissallowed */
|
|
174
|
-
MY_RULES.map((r) => {
|
|
175
|
-
/** THIS IS A MESS -> some methods cannot be dissallowed (unsync, unsubscribe...) */
|
|
176
|
-
r.methods.forEach((method) => {
|
|
177
|
-
const isAllowed = tableRules[r.rule] && (tableRules as any)[method] === undefined;
|
|
178
|
-
if (isAllowed) {
|
|
179
|
-
if (
|
|
180
|
-
method === "updateBatch" &&
|
|
181
|
-
(!tableRules.update || tableRules.update.checkFilter || tableRules.update.postValidate)
|
|
182
|
-
) {
|
|
183
|
-
// not allowed
|
|
184
|
-
} else if (method === "upsert" && (!tableRules.update || !tableRules.insert)) {
|
|
185
|
-
// not allowed
|
|
186
|
-
} else {
|
|
187
|
-
(res as any)[method] ??= true;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
return res;
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
parsedTableRule = getImpliedMethods(parsedTableRule);
|
|
197
|
-
|
|
198
110
|
return parsedTableRule;
|
|
199
111
|
}
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
import { RULE_METHODS } from "prostgles-types";
|
|
2
1
|
import type { DBOFullyTyped, PublishFullyTyped } from "../DBSchemaBuilder/DBSchemaBuilder";
|
|
3
|
-
import type {
|
|
4
|
-
CommonTableRules,
|
|
5
|
-
Filter,
|
|
6
|
-
LocalParams,
|
|
7
|
-
TableOrViewInfo,
|
|
8
|
-
} from "../DboBuilder/DboBuilder";
|
|
2
|
+
import type { Filter, LocalParams, TableOrViewInfo } from "../DboBuilder/DboBuilder";
|
|
9
3
|
import type { DB, DBHandlerServer } from "../Prostgles";
|
|
10
4
|
|
|
11
5
|
export type Awaitable<T> = T | Promise<T>;
|
|
@@ -18,132 +12,16 @@ export type DboTableCommand = DboTable & {
|
|
|
18
12
|
command: string;
|
|
19
13
|
};
|
|
20
14
|
|
|
21
|
-
export const RULE_TO_METHODS = [
|
|
22
|
-
{
|
|
23
|
-
rule: "getColumns",
|
|
24
|
-
sqlRule: "select",
|
|
25
|
-
methods: RULE_METHODS.getColumns,
|
|
26
|
-
no_limits: true,
|
|
27
|
-
allowed_params: [],
|
|
28
|
-
table_only: false,
|
|
29
|
-
hint: ` expecting false | true | undefined`,
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
rule: "getInfo",
|
|
33
|
-
sqlRule: "select",
|
|
34
|
-
methods: RULE_METHODS.getInfo,
|
|
35
|
-
no_limits: true,
|
|
36
|
-
allowed_params: [],
|
|
37
|
-
table_only: false,
|
|
38
|
-
hint: ` expecting false | true | undefined`,
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
rule: "insert",
|
|
42
|
-
sqlRule: "insert",
|
|
43
|
-
methods: RULE_METHODS.insert,
|
|
44
|
-
no_limits: <SelectRule>{ fields: "*" },
|
|
45
|
-
table_only: true,
|
|
46
|
-
allowed_params: {
|
|
47
|
-
checkFilter: 1,
|
|
48
|
-
fields: 1,
|
|
49
|
-
forcedData: 1,
|
|
50
|
-
postValidate: 1,
|
|
51
|
-
preValidate: 1,
|
|
52
|
-
returningFields: 1,
|
|
53
|
-
validate: 1,
|
|
54
|
-
allowedNestedInserts: 1,
|
|
55
|
-
requiredNestedInserts: 1,
|
|
56
|
-
} satisfies Record<keyof InsertRule, 1>,
|
|
57
|
-
hint: ` expecting "*" | true | { fields: string | string[] | {} }`,
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
rule: "update",
|
|
61
|
-
sqlRule: "update",
|
|
62
|
-
methods: RULE_METHODS.update,
|
|
63
|
-
no_limits: <UpdateRule>{
|
|
64
|
-
fields: "*",
|
|
65
|
-
filterFields: "*",
|
|
66
|
-
returningFields: "*",
|
|
67
|
-
},
|
|
68
|
-
table_only: true,
|
|
69
|
-
allowed_params: {
|
|
70
|
-
checkFilter: 1,
|
|
71
|
-
dynamicFields: 1,
|
|
72
|
-
fields: 1,
|
|
73
|
-
filterFields: 1,
|
|
74
|
-
forcedData: 1,
|
|
75
|
-
forcedFilter: 1,
|
|
76
|
-
postValidate: 1,
|
|
77
|
-
returningFields: 1,
|
|
78
|
-
validate: 1,
|
|
79
|
-
} satisfies Record<keyof UpdateRule, 1>,
|
|
80
|
-
hint: ` expecting "*" | true | { fields: string | string[] | {} }`,
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
rule: "select",
|
|
84
|
-
sqlRule: "select",
|
|
85
|
-
methods: RULE_METHODS.select,
|
|
86
|
-
no_limits: <SelectRule>{ fields: "*" },
|
|
87
|
-
table_only: false,
|
|
88
|
-
allowed_params: {
|
|
89
|
-
fields: 1,
|
|
90
|
-
filterFields: 1,
|
|
91
|
-
forcedFilter: 1,
|
|
92
|
-
maxLimit: 1,
|
|
93
|
-
orderByFields: 1,
|
|
94
|
-
validate: 1,
|
|
95
|
-
} satisfies Record<keyof SelectRule, 1>,
|
|
96
|
-
hint: ` expecting "*" | true | { fields: ( string | string[] | {} ) }`,
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
rule: "delete",
|
|
100
|
-
sqlRule: "delete",
|
|
101
|
-
methods: RULE_METHODS.delete,
|
|
102
|
-
no_limits: <DeleteRule>{ filterFields: "*" },
|
|
103
|
-
table_only: true,
|
|
104
|
-
allowed_params: {
|
|
105
|
-
returningFields: 1,
|
|
106
|
-
validate: 1,
|
|
107
|
-
filterFields: 1,
|
|
108
|
-
forcedFilter: 1,
|
|
109
|
-
} satisfies Record<keyof DeleteRule, 1>,
|
|
110
|
-
hint: ` expecting "*" | true | { filterFields: ( string | string[] | {} ) } \n Will use "select", "update", "delete" and "insert" rules`,
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
rule: "sync",
|
|
114
|
-
sqlRule: "select",
|
|
115
|
-
methods: RULE_METHODS.sync,
|
|
116
|
-
no_limits: null,
|
|
117
|
-
table_only: true,
|
|
118
|
-
allowed_params: {
|
|
119
|
-
// allow_delete: 1,
|
|
120
|
-
batch_size: 1,
|
|
121
|
-
id_fields: 1,
|
|
122
|
-
synced_field: 1,
|
|
123
|
-
throttle: 1,
|
|
124
|
-
} satisfies Record<keyof SyncRule, 1>,
|
|
125
|
-
hint: ` expecting "*" | true | { id_fields: string[], synced_field: string }`,
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
rule: "subscribe",
|
|
129
|
-
sqlRule: "select",
|
|
130
|
-
methods: RULE_METHODS.subscribe,
|
|
131
|
-
no_limits: <SubscribeRule>{ throttle: 0 },
|
|
132
|
-
table_only: false,
|
|
133
|
-
allowed_params: { throttle: 1 } satisfies Record<keyof SubscribeRule, 1>,
|
|
134
|
-
hint: ` expecting "*" | true | { throttle: number; throttleOpts?: { skipFirst?: boolean; } } \n Will use "select" rules`,
|
|
135
|
-
},
|
|
136
|
-
] as const;
|
|
137
|
-
|
|
138
15
|
import type pgPromise from "pg-promise";
|
|
139
16
|
import type {
|
|
140
17
|
AnyObject,
|
|
141
18
|
DBSchema,
|
|
142
19
|
FieldFilter,
|
|
143
20
|
FullFilter,
|
|
21
|
+
RequiredNestedInsert,
|
|
144
22
|
SelectParams,
|
|
145
23
|
SQLHandler,
|
|
146
|
-
|
|
24
|
+
TableSchema,
|
|
147
25
|
} from "prostgles-types";
|
|
148
26
|
import type { AuthClientRequest, LoginClientInfo, SessionUser } from "../Auth/AuthTypes";
|
|
149
27
|
import type { TableSchemaColumn } from "../DboBuilder/DboBuilderTypes";
|
|
@@ -266,6 +144,10 @@ export type SelectRule<Cols extends AnyObject = AnyObject, S extends DBSchema |
|
|
|
266
144
|
* Validation logic to check/update data for each request
|
|
267
145
|
*/
|
|
268
146
|
validate?(args: SelectRequestData): SelectRequestData | Promise<SelectRequestData>;
|
|
147
|
+
|
|
148
|
+
subscribeThrottle?: number;
|
|
149
|
+
|
|
150
|
+
disableMethods?: Partial<Record<"sync" | "subscribe", 1>>;
|
|
269
151
|
};
|
|
270
152
|
|
|
271
153
|
export type CommonInsertUpdateRule<
|
|
@@ -324,7 +206,7 @@ export type InsertRule<
|
|
|
324
206
|
column: string;
|
|
325
207
|
}[];
|
|
326
208
|
|
|
327
|
-
requiredNestedInserts?:
|
|
209
|
+
requiredNestedInserts?: RequiredNestedInsert[];
|
|
328
210
|
};
|
|
329
211
|
|
|
330
212
|
export type UpdateRule<
|
|
@@ -374,6 +256,8 @@ export type UpdateRule<
|
|
|
374
256
|
* Happens in the same transaction so upon throwing an error the record will be deleted (not committed)
|
|
375
257
|
*/
|
|
376
258
|
postValidate?: S extends DBSchema ? PostValidateRow<Required<Cols>, S> : PostValidateRowBasic;
|
|
259
|
+
|
|
260
|
+
disableMethods?: Partial<Record<"updateBatch", 1>>;
|
|
377
261
|
};
|
|
378
262
|
|
|
379
263
|
export type DeleteRule<Cols extends AnyObject = AnyObject, S extends DBSchema | void = void> = {
|
|
@@ -395,9 +279,10 @@ export type DeleteRule<Cols extends AnyObject = AnyObject, S extends DBSchema |
|
|
|
395
279
|
/**
|
|
396
280
|
* Validation logic to check/update data for each request
|
|
397
281
|
*/
|
|
398
|
-
validate?(filter: FullFilter<Cols, S>): Awaitable<void>;
|
|
282
|
+
validate?(filter: FullFilter<Cols, S>): Awaitable<void>;
|
|
399
283
|
};
|
|
400
|
-
|
|
284
|
+
|
|
285
|
+
export type SyncConfig<Cols extends AnyObject = AnyObject> = {
|
|
401
286
|
/**
|
|
402
287
|
* Primary keys used in updating data
|
|
403
288
|
*/
|
|
@@ -423,9 +308,7 @@ export type SyncRule<Cols extends AnyObject = AnyObject> = {
|
|
|
423
308
|
*/
|
|
424
309
|
batch_size?: number;
|
|
425
310
|
};
|
|
426
|
-
|
|
427
|
-
throttle?: number;
|
|
428
|
-
};
|
|
311
|
+
|
|
429
312
|
/**
|
|
430
313
|
* Required but possibly undefined type
|
|
431
314
|
* */
|
|
@@ -433,24 +316,16 @@ export type Required_ish<T> = {
|
|
|
433
316
|
[K in keyof Required<T>]: T[K];
|
|
434
317
|
};
|
|
435
318
|
export type WithRequired<T, K extends keyof T> = T & { [P in K]-?: NonNullable<T[P]> };
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
*/
|
|
440
|
-
select?: SelectRule<S>;
|
|
441
|
-
};
|
|
442
|
-
export type TableRule<
|
|
443
|
-
RowType extends AnyObject = AnyObject,
|
|
444
|
-
S extends DBSchema | void = void,
|
|
445
|
-
> = ViewRule<RowType> & {
|
|
319
|
+
|
|
320
|
+
export type TableRule<RowType extends AnyObject = AnyObject, S extends DBSchema | void = void> = {
|
|
321
|
+
select?: SelectRule<RowType, S>;
|
|
446
322
|
insert?: InsertRule<RowType, S>;
|
|
447
323
|
update?: UpdateRule<RowType, S>;
|
|
448
324
|
delete?: DeleteRule<RowType, S>;
|
|
449
|
-
sync?:
|
|
450
|
-
subscribe?: SubscribeRule;
|
|
325
|
+
sync?: SyncConfig<RowType>;
|
|
451
326
|
};
|
|
452
327
|
|
|
453
|
-
export type ParsedViewRule<S extends AnyObject = AnyObject> =
|
|
328
|
+
export type ParsedViewRule<S extends AnyObject = AnyObject> = {
|
|
454
329
|
/**
|
|
455
330
|
* What can be read from the table
|
|
456
331
|
*/
|
|
@@ -463,8 +338,6 @@ export type ParsedTableRule<
|
|
|
463
338
|
insert?: WithRequired<InsertRule<RowType, S>, "returningFields">;
|
|
464
339
|
update?: WithRequired<UpdateRule<RowType, S>, "filterFields" | "returningFields">;
|
|
465
340
|
delete?: WithRequired<DeleteRule<RowType, S>, "returningFields">;
|
|
466
|
-
sync?: SyncRule<RowType>;
|
|
467
|
-
subscribe?: SubscribeRule;
|
|
468
341
|
};
|
|
469
342
|
|
|
470
343
|
export const parsePublishTableRule = <R extends ParsedPublishTable>(tableRules: R | undefined) => {
|
|
@@ -500,36 +373,40 @@ export const parsePublishTableRule = <R extends ParsedPublishTable>(tableRules:
|
|
|
500
373
|
return parsedTableRules;
|
|
501
374
|
};
|
|
502
375
|
|
|
503
|
-
export type PublishViewRule<Col extends AnyObject = AnyObject, S extends DBSchema | void = void> = {
|
|
504
|
-
select?: SelectRule<Col, S> | PublishAllOrNothing;
|
|
505
|
-
getColumns?: PublishAllOrNothing;
|
|
506
|
-
getInfo?: PublishAllOrNothing;
|
|
507
|
-
};
|
|
508
376
|
export type PublishTableRule<
|
|
509
377
|
Col extends AnyObject = AnyObject,
|
|
510
378
|
S extends DBSchema | void = void,
|
|
511
|
-
> =
|
|
379
|
+
> = {
|
|
380
|
+
select?: SelectRule<Col, S> | PublishAllOrNothing;
|
|
512
381
|
insert?: InsertRule<Col, S> | PublishAllOrNothing;
|
|
513
382
|
update?: UpdateRule<Col, S> | PublishAllOrNothing;
|
|
514
383
|
delete?: DeleteRule<Col, S> | PublishAllOrNothing;
|
|
515
|
-
/**
|
|
516
|
-
* TODO: move to tableConfig
|
|
517
|
-
*/
|
|
518
|
-
sync?: SyncRule<Col>;
|
|
519
|
-
subscribe?: SubscribeRule | PublishAllOrNothing;
|
|
520
384
|
};
|
|
521
385
|
|
|
386
|
+
export const TABLE_RULE_NO_LIMITS = {
|
|
387
|
+
select: {
|
|
388
|
+
fields: "*",
|
|
389
|
+
disableMethods: undefined,
|
|
390
|
+
subscribeThrottle: 0,
|
|
391
|
+
},
|
|
392
|
+
insert: {
|
|
393
|
+
fields: "*",
|
|
394
|
+
},
|
|
395
|
+
update: {
|
|
396
|
+
fields: "*",
|
|
397
|
+
filterFields: "*",
|
|
398
|
+
},
|
|
399
|
+
delete: {
|
|
400
|
+
filterFields: "*",
|
|
401
|
+
},
|
|
402
|
+
} as const satisfies PublishTableRule;
|
|
403
|
+
|
|
522
404
|
export type ParsedPublishTable = {
|
|
523
405
|
select?: SelectRule;
|
|
524
|
-
getColumns?: true;
|
|
525
|
-
getInfo?: true;
|
|
526
406
|
|
|
527
407
|
insert?: InsertRule;
|
|
528
408
|
update?: UpdateRule;
|
|
529
409
|
delete?: DeleteRule;
|
|
530
|
-
sync?: SyncRule;
|
|
531
|
-
subscribe?: SubscribeRule;
|
|
532
|
-
subscribeOne?: SubscribeRule;
|
|
533
410
|
};
|
|
534
411
|
export type DbTableInfo = {
|
|
535
412
|
name: string;
|
|
@@ -575,7 +452,7 @@ export type PublishParams<S = void, SUser extends SessionUser = SessionUser> = {
|
|
|
575
452
|
user?: SUser["user"];
|
|
576
453
|
clientReq: AuthClientRequest;
|
|
577
454
|
clientInfo: LoginClientInfo;
|
|
578
|
-
tables:
|
|
455
|
+
tables: TableSchema[];
|
|
579
456
|
getClientDBHandlers: (
|
|
580
457
|
/**
|
|
581
458
|
* Used to filter permissions
|
|
@@ -585,10 +462,7 @@ export type PublishParams<S = void, SUser extends SessionUser = SessionUser> = {
|
|
|
585
462
|
};
|
|
586
463
|
export type RequestParams = { dbo?: DBHandlerServer; socket?: any };
|
|
587
464
|
export type PublishAllOrNothing = boolean | "*" | null;
|
|
588
|
-
export type PublishObject = Record<
|
|
589
|
-
string,
|
|
590
|
-
PublishTableRule | PublishViewRule | PublishAllOrNothing
|
|
591
|
-
>;
|
|
465
|
+
export type PublishObject = Record<string, PublishTableRule | PublishAllOrNothing>;
|
|
592
466
|
export type ParsedPublishTables = {
|
|
593
467
|
[table_name: string]: ParsedPublishTable;
|
|
594
468
|
};
|
package/lib/SyncReplication.ts
CHANGED
|
@@ -87,8 +87,8 @@ export async function syncData(
|
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
89
|
const tableHandler = this.dbo[table_name];
|
|
90
|
-
if (!tableHandler?.find
|
|
91
|
-
throw `dbo.${table_name}.find
|
|
90
|
+
if (!tableHandler?.find) {
|
|
91
|
+
throw `dbo.${table_name}.find missing or not allowed`;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
const sync_fields = [synced_field, ...id_fields.sort()],
|
|
@@ -110,7 +110,7 @@ export async function syncData(
|
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
const first_rows = await tableHandler.find
|
|
113
|
+
const first_rows = await tableHandler.find(
|
|
114
114
|
_filter,
|
|
115
115
|
{ orderBy: orderByAsc, select: sync_fields, limit, offset },
|
|
116
116
|
undefined,
|
|
@@ -119,7 +119,7 @@ export async function syncData(
|
|
|
119
119
|
);
|
|
120
120
|
const last_rows = first_rows.slice(-1); // Why not logic below?
|
|
121
121
|
// const last_rows = await _this?.dbo[table_name]?.find?.(_filter, { orderBy: (orderByDesc as OrderBy), select: sync_fields, limit: 1, offset: -offset || 0 }, null, table_rules);
|
|
122
|
-
const count = await tableHandler.count
|
|
122
|
+
const count = await tableHandler.count(_filter, undefined, undefined, table_rules);
|
|
123
123
|
|
|
124
124
|
return {
|
|
125
125
|
s_fr: first_rows[0] || null,
|
|
@@ -189,7 +189,7 @@ export async function syncData(
|
|
|
189
189
|
};
|
|
190
190
|
|
|
191
191
|
try {
|
|
192
|
-
const res = await tableHandler.find
|
|
192
|
+
const res = await tableHandler.find(
|
|
193
193
|
_filter,
|
|
194
194
|
{
|
|
195
195
|
select: params.select,
|
|
@@ -202,8 +202,6 @@ export async function syncData(
|
|
|
202
202
|
{ clientReq: { socket } },
|
|
203
203
|
);
|
|
204
204
|
|
|
205
|
-
if (!res) throw "_this?.dbo?.[table_name]?.find is missing";
|
|
206
|
-
|
|
207
205
|
return res;
|
|
208
206
|
} catch (e) {
|
|
209
207
|
console.error("Sync getServerData failed: ", e);
|
|
@@ -418,7 +416,7 @@ export async function syncData(
|
|
|
418
416
|
sync_fields.map((key) => {
|
|
419
417
|
_filter[key] = c_lr[key];
|
|
420
418
|
});
|
|
421
|
-
server_row = await this.dbo[table_name]?.find
|
|
419
|
+
server_row = await this.dbo[table_name]?.find(
|
|
422
420
|
_filter,
|
|
423
421
|
{ select: sync_fields, limit: 1 },
|
|
424
422
|
undefined,
|