prostgles-server 4.2.602 → 4.2.604
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/Auth/utils/getSessionUser.d.ts +4 -0
- package/dist/Auth/utils/getSessionUser.d.ts.map +1 -0
- package/dist/Auth/utils/getSessionUser.js +17 -0
- package/dist/Auth/utils/getSessionUser.js.map +1 -0
- package/dist/Auth/utils/getSessionUser.spec.d.ts +2 -0
- package/dist/Auth/utils/getSessionUser.spec.d.ts.map +1 -0
- package/dist/Auth/utils/getSessionUser.spec.js +42 -0
- package/dist/Auth/utils/getSessionUser.spec.js.map +1 -0
- package/dist/DBSchemaBuilder/getColumnTypescriptDefinition.js +2 -2
- package/dist/DBSchemaBuilder/getColumnTypescriptDefinition.js.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.js +4 -0
- package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
- package/dist/DboBuilder/TableHandler/delete.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/delete.js +4 -1
- package/dist/DboBuilder/TableHandler/delete.js.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/runInsertUpdateQuery.js +1 -1
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js.map +1 -1
- package/dist/DboBuilder/TableHandler/update.js +1 -1
- package/dist/DboBuilder/TableHandler/update.js.map +1 -1
- package/dist/DboBuilder/TableHandler/updateBatch.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/updateBatch.js +4 -1
- package/dist/DboBuilder/TableHandler/updateBatch.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/count.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/count.js +1 -1
- package/dist/DboBuilder/ViewHandler/count.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/find.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/find.js +1 -1
- package/dist/DboBuilder/ViewHandler/find.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/size.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/size.js +1 -1
- package/dist/DboBuilder/ViewHandler/size.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/subscribe.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/subscribe.js +1 -0
- package/dist/DboBuilder/ViewHandler/subscribe.js.map +1 -1
- package/dist/DboBuilder/dboBuilderUtils.d.ts +1 -1
- package/dist/DboBuilder/dboBuilderUtils.d.ts.map +1 -1
- package/dist/DboBuilder/dboBuilderUtils.js +7 -2
- package/dist/DboBuilder/dboBuilderUtils.js.map +1 -1
- package/dist/DboBuilder/prepareShortestJoinPaths.d.ts.map +1 -1
- package/dist/DboBuilder/prepareShortestJoinPaths.js +9 -0
- package/dist/DboBuilder/prepareShortestJoinPaths.js.map +1 -1
- package/dist/DboBuilder/prepareShortestJoinPaths.spec.d.ts +2 -0
- package/dist/DboBuilder/prepareShortestJoinPaths.spec.d.ts.map +1 -0
- package/dist/DboBuilder/prepareShortestJoinPaths.spec.js +30 -0
- package/dist/DboBuilder/prepareShortestJoinPaths.spec.js.map +1 -0
- package/dist/Prostgles.d.ts +1 -0
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +1 -0
- package/dist/Prostgles.js.map +1 -1
- package/dist/PubSubManager/PubSubManager.d.ts +5 -2
- package/dist/PubSubManager/PubSubManager.d.ts.map +1 -1
- package/dist/PubSubManager/PubSubManager.js +2 -4
- package/dist/PubSubManager/PubSubManager.js.map +1 -1
- package/dist/PubSubManager/SyncReplication/fetchSyncServerData.d.ts +3 -3
- package/dist/PubSubManager/SyncReplication/fetchSyncServerData.d.ts.map +1 -1
- package/dist/PubSubManager/SyncReplication/fetchSyncServerData.js +2 -2
- package/dist/PubSubManager/SyncReplication/fetchSyncServerData.js.map +1 -1
- package/dist/PubSubManager/SyncReplication/getSyncUtilFunctions.d.ts +3 -2
- package/dist/PubSubManager/SyncReplication/getSyncUtilFunctions.d.ts.map +1 -1
- package/dist/PubSubManager/SyncReplication/getSyncUtilFunctions.js +8 -8
- package/dist/PubSubManager/SyncReplication/getSyncUtilFunctions.js.map +1 -1
- package/dist/PubSubManager/SyncReplication/syncData.js +1 -0
- package/dist/PubSubManager/SyncReplication/syncData.js.map +1 -1
- package/dist/PubSubManager/addSub.d.ts.map +1 -1
- package/dist/PubSubManager/addSub.js +2 -1
- package/dist/PubSubManager/addSub.js.map +1 -1
- package/dist/PubSubManager/addSync.d.ts.map +1 -1
- package/dist/PubSubManager/addSync.js +2 -0
- package/dist/PubSubManager/addSync.js.map +1 -1
- package/dist/PubSubManager/init/getPubSubManagerInitQuery.js +4 -4
- package/dist/StorageClient/getFileTableConfig.d.ts.map +1 -1
- package/dist/StorageClient/getFileTableConfig.js +1 -0
- package/dist/StorageClient/getFileTableConfig.js.map +1 -1
- package/dist/StorageClient/getFileTableConfig.spec.d.ts +2 -0
- package/dist/StorageClient/getFileTableConfig.spec.d.ts.map +1 -0
- package/dist/StorageClient/getFileTableConfig.spec.js +23 -0
- package/dist/StorageClient/getFileTableConfig.spec.js.map +1 -0
- package/dist/TableConfig/getTableConfigSchemaQueries.js +2 -2
- package/dist/TableConfig/getTableConfigSchemaQueries.js.map +1 -1
- package/dist/TableConfig/initTableConfig.js +6 -6
- package/dist/TableConfig/initTableConfig.js.map +1 -1
- package/dist/initProstgles.d.ts.map +1 -1
- package/dist/initProstgles.js +9 -2
- package/dist/initProstgles.js.map +1 -1
- package/dist/runClientRequest.d.ts.map +1 -1
- package/dist/runClientRequest.js +2 -7
- package/dist/runClientRequest.js.map +1 -1
- package/lib/Auth/utils/getSessionUser.spec.ts +41 -0
- package/lib/Auth/utils/getSessionUser.ts +19 -0
- package/lib/DBSchemaBuilder/getColumnTypescriptDefinition.ts +2 -2
- package/lib/DboBuilder/TableHandler/TableHandler.ts +9 -1
- package/lib/DboBuilder/TableHandler/delete.ts +8 -1
- package/lib/DboBuilder/TableHandler/insert/insert.ts +1 -1
- package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +1 -1
- package/lib/DboBuilder/TableHandler/update.ts +1 -1
- package/lib/DboBuilder/TableHandler/updateBatch.ts +4 -1
- package/lib/DboBuilder/ViewHandler/count.ts +5 -1
- package/lib/DboBuilder/ViewHandler/find.ts +5 -1
- package/lib/DboBuilder/ViewHandler/size.ts +5 -1
- package/lib/DboBuilder/ViewHandler/subscribe.ts +1 -0
- package/lib/DboBuilder/dboBuilderUtils.ts +11 -2
- package/lib/DboBuilder/prepareShortestJoinPaths.spec.ts +29 -0
- package/lib/DboBuilder/prepareShortestJoinPaths.ts +13 -0
- package/lib/Prostgles.ts +1 -0
- package/lib/PubSubManager/PubSubManager.ts +20 -5
- package/lib/PubSubManager/SyncReplication/fetchSyncServerData.ts +4 -4
- package/lib/PubSubManager/SyncReplication/getSyncUtilFunctions.ts +16 -8
- package/lib/PubSubManager/SyncReplication/syncData.ts +1 -1
- package/lib/PubSubManager/addSub.ts +2 -0
- package/lib/PubSubManager/addSync.ts +2 -0
- package/lib/PubSubManager/init/getPubSubManagerInitQuery.ts +4 -4
- package/lib/StorageClient/getFileTableConfig.spec.ts +19 -0
- package/lib/StorageClient/getFileTableConfig.ts +1 -0
- package/lib/TableConfig/getTableConfigSchemaQueries.ts +2 -2
- package/lib/TableConfig/initTableConfig.ts +6 -6
- package/lib/initProstgles.ts +8 -2
- package/lib/runClientRequest.ts +3 -15
- package/package.json +1 -1
|
@@ -125,7 +125,11 @@ export async function _delete(
|
|
|
125
125
|
// }
|
|
126
126
|
// }
|
|
127
127
|
|
|
128
|
-
const queryWithRLS = withUserRLS(
|
|
128
|
+
const queryWithRLS = withUserRLS(
|
|
129
|
+
localParams,
|
|
130
|
+
queryWithoutRLS,
|
|
131
|
+
!!this.getTransaction(localParams),
|
|
132
|
+
);
|
|
129
133
|
|
|
130
134
|
const queryToReturn = await getReturnTypeQuery({
|
|
131
135
|
handler: this,
|
|
@@ -155,6 +159,9 @@ export async function _delete(
|
|
|
155
159
|
"onInsteadOfDelete requires a transaction. Please wrap the delete call in a transaction.",
|
|
156
160
|
);
|
|
157
161
|
}
|
|
162
|
+
if (localParams?.isRemoteRequest) {
|
|
163
|
+
await transaction.t.none(withUserRLS(localParams, ""));
|
|
164
|
+
}
|
|
158
165
|
const result = await onInsteadOfDelete({
|
|
159
166
|
context: this.dboBuilder.prostgles.context,
|
|
160
167
|
queryType,
|
|
@@ -164,7 +164,7 @@ export async function insert(
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
const queryWithoutUserRLS = query;
|
|
167
|
-
const queryWithRLS = withUserRLS(localParams, query);
|
|
167
|
+
const queryWithRLS = withUserRLS(localParams, query, !!this.getTransaction(localParams));
|
|
168
168
|
|
|
169
169
|
const queryToReturn = await getReturnTypeQuery({
|
|
170
170
|
handler: this,
|
|
@@ -65,7 +65,7 @@ export const runInsertUpdateQuery = async (args: RunInsertUpdateQueryArgs) => {
|
|
|
65
65
|
checkCondition = `NOT (${checkCond.where})`;
|
|
66
66
|
}
|
|
67
67
|
const hasReturning = !!returningSelectItems.length;
|
|
68
|
-
const userRLS = withUserRLS(localParams, "");
|
|
68
|
+
const userRLS = withUserRLS(localParams, "", !!tableHandler.getTransaction(localParams));
|
|
69
69
|
const CHECK_CONDITION_ALIAS = "prostgles_check_condition";
|
|
70
70
|
const RETURNING_ALIAS_PREFIX = "prostgles_returning_";
|
|
71
71
|
const returningSelectKeyRemap = new Map<string, string>();
|
|
@@ -166,7 +166,7 @@ export async function update(
|
|
|
166
166
|
).getQuery();
|
|
167
167
|
query += "\n" + updateFilter.where;
|
|
168
168
|
const queryWithoutUserRLS = query;
|
|
169
|
-
query = withUserRLS(localParams, query);
|
|
169
|
+
query = withUserRLS(localParams, query, !!this.getTransaction(localParams));
|
|
170
170
|
|
|
171
171
|
const queryToReturn = await getReturnTypeQuery({
|
|
172
172
|
handler: this,
|
|
@@ -37,7 +37,10 @@ export async function updateBatch(
|
|
|
37
37
|
return query;
|
|
38
38
|
}),
|
|
39
39
|
);
|
|
40
|
-
const queries = [
|
|
40
|
+
const queries = [
|
|
41
|
+
withUserRLS(localParams, "", !!this.getTransaction(localParams)),
|
|
42
|
+
...updateQueries,
|
|
43
|
+
];
|
|
41
44
|
|
|
42
45
|
const queryToReturn = await getReturnTypeQuery({
|
|
43
46
|
handler: this,
|
|
@@ -41,7 +41,11 @@ export async function count(
|
|
|
41
41
|
${findQuery}
|
|
42
42
|
) t
|
|
43
43
|
`;
|
|
44
|
-
const queryWithRLS = withUserRLS(
|
|
44
|
+
const queryWithRLS = withUserRLS(
|
|
45
|
+
localParams,
|
|
46
|
+
queryWithoutUserRLS,
|
|
47
|
+
!!this.getTransaction(localParams),
|
|
48
|
+
);
|
|
45
49
|
|
|
46
50
|
const queryToReturn = await getReturnTypeQuery({
|
|
47
51
|
handler: this,
|
|
@@ -113,7 +113,11 @@ export const find = async function (
|
|
|
113
113
|
!!selectParamsLimitCheck.groupBy,
|
|
114
114
|
);
|
|
115
115
|
|
|
116
|
-
const queryWithRLS = withUserRLS(
|
|
116
|
+
const queryWithRLS = withUserRLS(
|
|
117
|
+
localParams,
|
|
118
|
+
queryWithoutRLS,
|
|
119
|
+
!!this.getTransaction(localParams),
|
|
120
|
+
);
|
|
117
121
|
|
|
118
122
|
const queryToReturn = await getReturnTypeQuery({
|
|
119
123
|
handler: this,
|
|
@@ -44,7 +44,11 @@ export async function size(
|
|
|
44
44
|
${selectQueryWithoutRLS}
|
|
45
45
|
) prgl_size_query
|
|
46
46
|
`;
|
|
47
|
-
const queryWithRLS = withUserRLS(
|
|
47
|
+
const queryWithRLS = withUserRLS(
|
|
48
|
+
localParams,
|
|
49
|
+
queryWithoutUserRLS,
|
|
50
|
+
!!this.getTransaction(localParams),
|
|
51
|
+
);
|
|
48
52
|
|
|
49
53
|
const queryToReturn = await getReturnTypeQuery({
|
|
50
54
|
handler: this,
|
|
@@ -92,6 +92,7 @@ async function subscribe(
|
|
|
92
92
|
{ actions, skipFirst, throttle, throttleOpts, skipChangedColumnsCheck },
|
|
93
93
|
table_rules?.select,
|
|
94
94
|
),
|
|
95
|
+
localParams,
|
|
95
96
|
lastPushed: 0,
|
|
96
97
|
tracked_columns: !firstField ? undefined : [firstField, ...otherFields],
|
|
97
98
|
pushRequestedVersion: 0,
|
|
@@ -178,13 +178,22 @@ export const getCanExecute = async (db: DB) => {
|
|
|
178
178
|
|
|
179
179
|
export const QUERY_ID_PREFIX = "-- prostgles query id: ";
|
|
180
180
|
|
|
181
|
-
export const withUserRLS = (
|
|
181
|
+
export const withUserRLS = (
|
|
182
|
+
localParams: LocalParams | undefined,
|
|
183
|
+
query: string,
|
|
184
|
+
inTransaction = false,
|
|
185
|
+
) => {
|
|
182
186
|
const user = localParams?.isRemoteRequest?.user;
|
|
183
|
-
const queryPrefix = `SET
|
|
187
|
+
const queryPrefix = `SET LOCAL "prostgles.user" \nTO`;
|
|
184
188
|
let firstQuery = `${queryPrefix} '';`;
|
|
185
189
|
if (user) {
|
|
186
190
|
firstQuery = pgp.as.format(`${queryPrefix} \${user};`, { user });
|
|
187
191
|
}
|
|
192
|
+
// Local calls through a transaction's dbx must preserve its request context.
|
|
193
|
+
// Anonymous remote requests still explicitly clear the user.
|
|
194
|
+
if (inTransaction && !localParams?.isRemoteRequest) {
|
|
195
|
+
firstQuery = "";
|
|
196
|
+
}
|
|
188
197
|
|
|
189
198
|
const queryId = crypto.randomUUID();
|
|
190
199
|
return [QUERY_ID_PREFIX + queryId, firstQuery, query].filter(Boolean).join("\n");
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import type { DboBuilder } from "./DboBuilder";
|
|
4
|
+
import { prepareShortestJoinPaths } from "./prepareShortestJoinPaths";
|
|
5
|
+
|
|
6
|
+
void test("configured joins are deferred only during table configuration", async () => {
|
|
7
|
+
const builder = {
|
|
8
|
+
prostgles: { preparingTableConfig: true, opts: { joins: [
|
|
9
|
+
{ tables: ["conditions", "members"], on: [{ project_id: "project_id" }], type: "many-many" },
|
|
10
|
+
] } },
|
|
11
|
+
tablesOrViews: [],
|
|
12
|
+
} as unknown as DboBuilder;
|
|
13
|
+
assert.deepEqual((await prepareShortestJoinPaths(builder)).joins, []);
|
|
14
|
+
builder.prostgles.preparingTableConfig = false;
|
|
15
|
+
await assert.rejects(prepareShortestJoinPaths(builder), (error: unknown) =>
|
|
16
|
+
typeof error === "string" && error.includes("Table not found: conditions")
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
void test("existing configured joins remain available during table configuration", async () => {
|
|
21
|
+
const join = { tables: ["conditions", "members"], on: [{ project_id: "project_id" }], type: "many-many" };
|
|
22
|
+
const builder = {
|
|
23
|
+
prostgles: { preparingTableConfig: true, opts: { joins: [join] } },
|
|
24
|
+
tablesOrViews: ["conditions", "members"].map((name) => ({ name, columns: [{ name: "project_id" }] })),
|
|
25
|
+
} as unknown as DboBuilder;
|
|
26
|
+
assert.deepEqual((await prepareShortestJoinPaths(builder)).joins, [join]);
|
|
27
|
+
builder.prostgles.preparingTableConfig = false;
|
|
28
|
+
assert.deepEqual((await prepareShortestJoinPaths(builder)).joins, [join]);
|
|
29
|
+
});
|
|
@@ -18,6 +18,19 @@ export async function prepareShortestJoinPaths(dboBuilder: DboBuilder): Promise<
|
|
|
18
18
|
throw new Error("Could not create join config. this.tablesOrViews missing");
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
// The initial DBO is needed by tableConfig before its tables/columns exist.
|
|
22
|
+
// Defer only joins that cannot be resolved yet; the final rebuild validates all.
|
|
23
|
+
if (Array.isArray(joinConfig) && dboBuilder.prostgles.preparingTableConfig) {
|
|
24
|
+
const tables = dboBuilder.tablesOrViews;
|
|
25
|
+
joinConfig = joinConfig.filter((join) => join.tables.every((name, index) => {
|
|
26
|
+
const table = tables.find((candidate) => candidate.name === name);
|
|
27
|
+
return table && join.on.every((on) =>
|
|
28
|
+
(index === 0 ? Object.keys(on) : Object.values(on)).every((column) =>
|
|
29
|
+
table.columns.some((candidate) => candidate.name === column)
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
21
34
|
const inferredJoins = await getInferredJoins2(dboBuilder.tablesOrViews);
|
|
22
35
|
if (joinConfig === "inferred") {
|
|
23
36
|
joinConfig = inferredJoins;
|
package/lib/Prostgles.ts
CHANGED
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
* Licensed under the MIT License. See LICENSE in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
DBHandlerServer,
|
|
8
|
+
DboBuilder,
|
|
9
|
+
LocalParams,
|
|
10
|
+
PRGLIOSocket,
|
|
11
|
+
} from "../DboBuilder/DboBuilder";
|
|
7
12
|
import type { PostgresNotifListenManager } from "../PostgresNotifListenManager";
|
|
8
13
|
import type { DB } from "../Prostgles";
|
|
9
14
|
import { addSync } from "./addSync";
|
|
@@ -56,6 +61,7 @@ export type SyncParams = {
|
|
|
56
61
|
lr?: AnyObject;
|
|
57
62
|
is_syncing: boolean;
|
|
58
63
|
handlers: ReturnType<(typeof ReplicationProtocol)["getServerHandlers"]>;
|
|
64
|
+
localParams: LocalParams;
|
|
59
65
|
};
|
|
60
66
|
|
|
61
67
|
export type AddSyncParams = SyncTableInfo & {
|
|
@@ -74,6 +80,7 @@ export type AddSyncParams = SyncTableInfo & {
|
|
|
74
80
|
};
|
|
75
81
|
condition: string;
|
|
76
82
|
throttle?: number;
|
|
83
|
+
localParams: LocalParams;
|
|
77
84
|
};
|
|
78
85
|
|
|
79
86
|
export type ViewSubscriptionOptions = (
|
|
@@ -114,6 +121,7 @@ export type SubscriptionParams = {
|
|
|
114
121
|
|
|
115
122
|
onData?: OnData;
|
|
116
123
|
socket: PRGLIOSocket | undefined;
|
|
124
|
+
localParams?: LocalParams;
|
|
117
125
|
|
|
118
126
|
lastPushed: number;
|
|
119
127
|
/**
|
|
@@ -143,6 +151,7 @@ export type Subscription = Pick<
|
|
|
143
151
|
| "table_info"
|
|
144
152
|
| "filter"
|
|
145
153
|
| "table_rules"
|
|
154
|
+
| "localParams"
|
|
146
155
|
> & {
|
|
147
156
|
triggers: [AddTriggerParams, ...AddTriggerParams[]];
|
|
148
157
|
};
|
|
@@ -321,7 +330,15 @@ export class PubSubManager {
|
|
|
321
330
|
};
|
|
322
331
|
|
|
323
332
|
getSubData = async (sub: Subscription) => {
|
|
324
|
-
const {
|
|
333
|
+
const {
|
|
334
|
+
table_info,
|
|
335
|
+
filter,
|
|
336
|
+
selectParams: params,
|
|
337
|
+
table_rules,
|
|
338
|
+
localParams,
|
|
339
|
+
socket,
|
|
340
|
+
onData,
|
|
341
|
+
} = sub; //, subOne = false
|
|
325
342
|
const { name: table_name } = table_info;
|
|
326
343
|
const tableHandler = this.dbo[table_name];
|
|
327
344
|
if (!onData && !socket) {
|
|
@@ -337,9 +354,7 @@ export class PubSubManager {
|
|
|
337
354
|
params,
|
|
338
355
|
undefined,
|
|
339
356
|
table_rules,
|
|
340
|
-
|
|
341
|
-
clientReq: { socket },
|
|
342
|
-
},
|
|
357
|
+
localParams,
|
|
343
358
|
)) as AnyObject[];
|
|
344
359
|
return { data };
|
|
345
360
|
} catch (err) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AnyObject } from "prostgles-types";
|
|
2
|
-
import type {
|
|
2
|
+
import type { LocalParams } from "../../DboBuilder/DboBuilder";
|
|
3
3
|
import type { TableHandler } from "../../DboBuilder/TableHandler/TableHandler";
|
|
4
4
|
import type { SyncParams } from "../PubSubManager";
|
|
5
5
|
import { getSyncOrderByAndFields } from "./getSyncOrderByAndFields";
|
|
@@ -8,12 +8,12 @@ import { getSyncBatchOptions } from "./getSyncBatchOptions";
|
|
|
8
8
|
export const fetchSyncServerData = async (
|
|
9
9
|
{
|
|
10
10
|
tableHandler,
|
|
11
|
-
|
|
11
|
+
localParams,
|
|
12
12
|
from_synced,
|
|
13
13
|
offset,
|
|
14
14
|
}: {
|
|
15
15
|
tableHandler: TableHandler;
|
|
16
|
-
|
|
16
|
+
localParams: LocalParams;
|
|
17
17
|
from_synced: number | undefined;
|
|
18
18
|
offset: number | undefined;
|
|
19
19
|
},
|
|
@@ -48,7 +48,7 @@ export const fetchSyncServerData = async (
|
|
|
48
48
|
},
|
|
49
49
|
undefined,
|
|
50
50
|
table_rules,
|
|
51
|
-
|
|
51
|
+
localParams,
|
|
52
52
|
);
|
|
53
53
|
|
|
54
54
|
return batchRows as AnyObject[];
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
type AnyObject,
|
|
7
7
|
type SyncBatchParams,
|
|
8
8
|
} from "prostgles-types";
|
|
9
|
-
import type { PRGLIOSocket } from "../../DboBuilder/DboBuilder";
|
|
9
|
+
import type { LocalParams, PRGLIOSocket } from "../../DboBuilder/DboBuilder";
|
|
10
10
|
import type { TableHandler } from "../../DboBuilder/TableHandler/TableHandler";
|
|
11
11
|
import { getSyncOrderByAndFields } from "./getSyncOrderByAndFields";
|
|
12
12
|
import type { PubSubManager, SyncParams } from "../PubSubManager";
|
|
@@ -26,6 +26,7 @@ type Args = {
|
|
|
26
26
|
sync: SyncParams;
|
|
27
27
|
pubSubManager: PubSubManager;
|
|
28
28
|
logSyncData: (state: Extract<EventTypes.Sync, { command: "syncData" }>["state"]) => void;
|
|
29
|
+
localParams: LocalParams;
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
export const getSyncUtilFunctions = ({
|
|
@@ -34,6 +35,7 @@ export const getSyncUtilFunctions = ({
|
|
|
34
35
|
sync,
|
|
35
36
|
pubSubManager,
|
|
36
37
|
logSyncData,
|
|
38
|
+
localParams,
|
|
37
39
|
}: Args) => {
|
|
38
40
|
const {
|
|
39
41
|
synced_field,
|
|
@@ -71,12 +73,18 @@ export const getSyncUtilFunctions = ({
|
|
|
71
73
|
{ orderBy: orderByAsc, select: sync_fields, limit, offset },
|
|
72
74
|
undefined,
|
|
73
75
|
table_rules,
|
|
74
|
-
|
|
76
|
+
localParams,
|
|
75
77
|
)) as AnyObject[];
|
|
76
78
|
|
|
77
79
|
const last_rows = first_rows.slice(-1); // Why not logic below?
|
|
78
80
|
// 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);
|
|
79
|
-
const count = await tableHandler.count(
|
|
81
|
+
const count = await tableHandler.count(
|
|
82
|
+
batchFilter,
|
|
83
|
+
undefined,
|
|
84
|
+
undefined,
|
|
85
|
+
table_rules,
|
|
86
|
+
localParams,
|
|
87
|
+
);
|
|
80
88
|
|
|
81
89
|
return {
|
|
82
90
|
s_fr: first_rows[0],
|
|
@@ -128,7 +136,7 @@ export const getSyncUtilFunctions = ({
|
|
|
128
136
|
},
|
|
129
137
|
getServerData = async (from_synced: number | undefined, offset = 0): Promise<AnyObject[]> => {
|
|
130
138
|
return fetchSyncServerData(
|
|
131
|
-
{ tableHandler,
|
|
139
|
+
{ tableHandler, localParams, from_synced, offset },
|
|
132
140
|
{ filter, id_fields, params, synced_field, batch_size, table_rules },
|
|
133
141
|
);
|
|
134
142
|
},
|
|
@@ -173,7 +181,7 @@ export const getSyncUtilFunctions = ({
|
|
|
173
181
|
},
|
|
174
182
|
undefined,
|
|
175
183
|
table_rules,
|
|
176
|
-
|
|
184
|
+
localParams,
|
|
177
185
|
)) as AnyObject[];
|
|
178
186
|
let rowsToInsert = data.filter(
|
|
179
187
|
(incomingRow) =>
|
|
@@ -201,7 +209,7 @@ export const getSyncUtilFunctions = ({
|
|
|
201
209
|
{ removeDisallowedFields: true },
|
|
202
210
|
undefined,
|
|
203
211
|
table_rules,
|
|
204
|
-
|
|
212
|
+
localParams,
|
|
205
213
|
);
|
|
206
214
|
} else {
|
|
207
215
|
rowsToUpdate = [];
|
|
@@ -213,7 +221,7 @@ export const getSyncUtilFunctions = ({
|
|
|
213
221
|
{ removeDisallowedFields: true },
|
|
214
222
|
undefined,
|
|
215
223
|
table_rules,
|
|
216
|
-
|
|
224
|
+
localParams,
|
|
217
225
|
);
|
|
218
226
|
} else {
|
|
219
227
|
rowsToInsert = [];
|
|
@@ -355,7 +363,7 @@ export const getSyncUtilFunctions = ({
|
|
|
355
363
|
{ select: sync_fields, limit: 1 },
|
|
356
364
|
undefined,
|
|
357
365
|
table_rules,
|
|
358
|
-
|
|
366
|
+
localParams,
|
|
359
367
|
);
|
|
360
368
|
}
|
|
361
369
|
|
|
@@ -82,7 +82,6 @@ export async function syncData(
|
|
|
82
82
|
if (!tableHandler?.find) {
|
|
83
83
|
throw `dbo.${table_name}.find missing or not allowed`;
|
|
84
84
|
}
|
|
85
|
-
|
|
86
85
|
const {
|
|
87
86
|
upsertData,
|
|
88
87
|
updateSyncLR,
|
|
@@ -98,6 +97,7 @@ export async function syncData(
|
|
|
98
97
|
sync,
|
|
99
98
|
pubSubManager: this,
|
|
100
99
|
logSyncData,
|
|
100
|
+
localParams: sync.localParams,
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
/* Used to throttle and merge incoming updates */
|
|
@@ -34,6 +34,7 @@ export async function addSub(
|
|
|
34
34
|
table_info,
|
|
35
35
|
subscribeOptions,
|
|
36
36
|
tracked_columns,
|
|
37
|
+
localParams,
|
|
37
38
|
} = subscriptionParams;
|
|
38
39
|
const table_name = table_info.name;
|
|
39
40
|
|
|
@@ -65,6 +66,7 @@ export async function addSub(
|
|
|
65
66
|
is_throttling: false,
|
|
66
67
|
socket_id: socket?.id,
|
|
67
68
|
table_rules,
|
|
69
|
+
localParams,
|
|
68
70
|
triggers: [mainTrigger],
|
|
69
71
|
};
|
|
70
72
|
|
|
@@ -20,6 +20,7 @@ export async function addSync(
|
|
|
20
20
|
const res = await tryCatchV2(async () => {
|
|
21
21
|
const { socket, rawSelect, table_info, table_rules, filter, params, condition, initialData } =
|
|
22
22
|
syncParams;
|
|
23
|
+
const { localParams } = syncParams;
|
|
23
24
|
const conditionParsed = parseCondition(condition);
|
|
24
25
|
|
|
25
26
|
const { name: table_name } = table_info;
|
|
@@ -84,6 +85,7 @@ export async function addSync(
|
|
|
84
85
|
socket,
|
|
85
86
|
params,
|
|
86
87
|
handlers,
|
|
88
|
+
localParams,
|
|
87
89
|
};
|
|
88
90
|
const unsyncChn = channelName + "unsync";
|
|
89
91
|
socket.removeAllListeners(unsyncChn);
|
|
@@ -162,11 +162,11 @@ BEGIN
|
|
|
162
162
|
END IF;
|
|
163
163
|
|
|
164
164
|
IF length(key) > 0 THEN
|
|
165
|
-
RETURN
|
|
165
|
+
RETURN jsonb_extract_path_text(user_jsonb, key);
|
|
166
166
|
END IF;
|
|
167
167
|
RETURN user_jsonb;
|
|
168
168
|
END;
|
|
169
|
-
$$ LANGUAGE plpgsql;
|
|
169
|
+
$$ LANGUAGE plpgsql STABLE PARALLEL SAFE;
|
|
170
170
|
COMMENT ON FUNCTION prostgles."user" IS 'Used for row level security';
|
|
171
171
|
|
|
172
172
|
CREATE OR REPLACE FUNCTION prostgles.user_id()
|
|
@@ -174,7 +174,7 @@ BEGIN
|
|
|
174
174
|
BEGIN
|
|
175
175
|
RETURN prostgles.user('id')::UUID;
|
|
176
176
|
END;
|
|
177
|
-
$$ LANGUAGE plpgsql;
|
|
177
|
+
$$ LANGUAGE plpgsql STABLE PARALLEL SAFE;
|
|
178
178
|
COMMENT ON FUNCTION prostgles.user_id IS 'Session user id';
|
|
179
179
|
|
|
180
180
|
CREATE OR REPLACE FUNCTION prostgles.user_type()
|
|
@@ -182,7 +182,7 @@ BEGIN
|
|
|
182
182
|
BEGIN
|
|
183
183
|
RETURN prostgles.user('type')::TEXT;
|
|
184
184
|
END;
|
|
185
|
-
$$ LANGUAGE plpgsql;
|
|
185
|
+
$$ LANGUAGE plpgsql STABLE PARALLEL SAFE;
|
|
186
186
|
COMMENT ON FUNCTION prostgles.user_type IS 'Session user type';
|
|
187
187
|
|
|
188
188
|
CREATE TABLE IF NOT EXISTS prostgles.apps (
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import type { Prostgles } from "../Prostgles";
|
|
4
|
+
import { getFileTableConfig } from "./getFileTableConfig";
|
|
5
|
+
|
|
6
|
+
void test("managed files preserve hooks on other tables and append file hooks", () => {
|
|
7
|
+
const guard = { afterEach: [{ commands: { insert: 1 }, validate: async () => {} }] };
|
|
8
|
+
const fileGuard = { beforeEach: [{ commands: { insert: 1 }, validate: async () => {} }] };
|
|
9
|
+
const prostgles = {
|
|
10
|
+
opts: {
|
|
11
|
+
fileTable: { tableName: "files", storageClient: {}, expressApp: {} },
|
|
12
|
+
tableHooks: { documents: guard, files: fileGuard },
|
|
13
|
+
},
|
|
14
|
+
} as unknown as Prostgles;
|
|
15
|
+
const result = getFileTableConfig(prostgles);
|
|
16
|
+
assert.equal(result.tableHooks?.documents, guard);
|
|
17
|
+
assert.equal(result.tableHooks.files?.beforeEach?.length, 2);
|
|
18
|
+
assert.equal(result.tableHooks.files.beforeEach[1], fileGuard.beforeEach[0]);
|
|
19
|
+
});
|
|
@@ -115,7 +115,7 @@ const getTableQueries = async (
|
|
|
115
115
|
`);`,
|
|
116
116
|
].join("\n");
|
|
117
117
|
|
|
118
|
-
const
|
|
118
|
+
const insertQueries = rows.map((row) => {
|
|
119
119
|
const values = allColumns.map((key) => row[key]);
|
|
120
120
|
return as.format(
|
|
121
121
|
`INSERT INTO ${tableName} (${allColumns.map((t) => asName(t)).join(", ")}) ` +
|
|
@@ -123,7 +123,7 @@ const getTableQueries = async (
|
|
|
123
123
|
{ values },
|
|
124
124
|
);
|
|
125
125
|
});
|
|
126
|
-
const queries = [createQuery, ...
|
|
126
|
+
const queries = [createQuery, ...insertQueries];
|
|
127
127
|
return {
|
|
128
128
|
queries,
|
|
129
129
|
colDefs,
|
|
@@ -162,7 +162,7 @@ export const initTableConfig = async function (this: TableConfigurator) {
|
|
|
162
162
|
const ALTER_TABLE_Q = `ALTER TABLE ${asName(tableName)}`;
|
|
163
163
|
|
|
164
164
|
/* isLookupTable table has already been created */
|
|
165
|
-
const
|
|
165
|
+
const tableColumnDefinition =
|
|
166
166
|
"isLookupTable" in tableConf ? undefined : (
|
|
167
167
|
await getTableColumnQueries({
|
|
168
168
|
db: this.db,
|
|
@@ -172,8 +172,8 @@ export const initTableConfig = async function (this: TableConfigurator) {
|
|
|
172
172
|
})
|
|
173
173
|
);
|
|
174
174
|
|
|
175
|
-
if (
|
|
176
|
-
queries.push(
|
|
175
|
+
if (tableColumnDefinition) {
|
|
176
|
+
queries.push(tableColumnDefinition.fullQuery);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
/** CONSTRAINTS */
|
|
@@ -181,13 +181,13 @@ export const initTableConfig = async function (this: TableConfigurator) {
|
|
|
181
181
|
tableName,
|
|
182
182
|
tableConf,
|
|
183
183
|
});
|
|
184
|
-
if (
|
|
184
|
+
if (tableColumnDefinition?.isCreate) {
|
|
185
185
|
queries.push(...(constraintDefs?.map((c) => c.alterQuery) ?? []));
|
|
186
|
-
} else if (
|
|
186
|
+
} else if (tableColumnDefinition) {
|
|
187
187
|
const fullSchema = await getFutureTableSchema({
|
|
188
188
|
db: this.db,
|
|
189
189
|
tableName,
|
|
190
|
-
columnDefs:
|
|
190
|
+
columnDefs: tableColumnDefinition.columnDefs,
|
|
191
191
|
constraintDefs,
|
|
192
192
|
});
|
|
193
193
|
const futureCons = fullSchema.constraints.map((nc) => ({
|
package/lib/initProstgles.ts
CHANGED
|
@@ -223,8 +223,14 @@ export const initProstgles = async function (
|
|
|
223
223
|
|
|
224
224
|
/* 2. Execute any SQL file if provided */
|
|
225
225
|
await runSQLFile(this);
|
|
226
|
-
|
|
227
|
-
|
|
226
|
+
this.preparingTableConfig = true;
|
|
227
|
+
try {
|
|
228
|
+
await this.rebuildDBO();
|
|
229
|
+
await this.initTableConfig(reason);
|
|
230
|
+
} finally {
|
|
231
|
+
this.preparingTableConfig = false;
|
|
232
|
+
}
|
|
233
|
+
// Validate all configured joins against the completed schema before publishing.
|
|
228
234
|
await this.rebuildDBO();
|
|
229
235
|
await this.createContext(reason);
|
|
230
236
|
this.initRestApi();
|
package/lib/runClientRequest.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import type { SQLRequest, TableHandler
|
|
1
|
+
import type { SQLRequest, TableHandler } from "prostgles-types";
|
|
2
2
|
import {
|
|
3
3
|
ABORTABLE_METHODS,
|
|
4
4
|
getJSONBObjectSchemaValidationError,
|
|
5
5
|
getJSONBSchemaValidationErrorAsync,
|
|
6
6
|
getKeys,
|
|
7
|
-
pickKeys,
|
|
8
7
|
type AnyObject,
|
|
9
8
|
} from "prostgles-types";
|
|
10
9
|
import type { AuthClientRequest } from "./Auth/AuthTypes";
|
|
10
|
+
import { getSessionUser } from "./Auth/utils/getSessionUser";
|
|
11
11
|
import type { LocalParams } from "./DboBuilder/DboBuilder";
|
|
12
12
|
import type { TableHandler as TableHandlerServer } from "./DboBuilder/TableHandler/TableHandler";
|
|
13
|
-
import { parseFieldFilter } from "./DboBuilder/ViewHandler/parseFieldFilter";
|
|
14
13
|
import { canRunSQL } from "./DboBuilder/runSql/runSQL";
|
|
15
14
|
import type { Prostgles } from "./Prostgles";
|
|
16
15
|
import type { ParsedTableRule } from "./PublishParser/publishTypesAndUtils";
|
|
@@ -118,18 +117,7 @@ export const runClientRequest = async function (
|
|
|
118
117
|
scope,
|
|
119
118
|
);
|
|
120
119
|
|
|
121
|
-
const sessionUser
|
|
122
|
-
!clientInfo.user ? undefined : (
|
|
123
|
-
{
|
|
124
|
-
...parseFieldFilter(
|
|
125
|
-
//@ts-ignore
|
|
126
|
-
clientInfo.sessionFields ?? [],
|
|
127
|
-
false,
|
|
128
|
-
getKeys(clientInfo.user),
|
|
129
|
-
),
|
|
130
|
-
...(pickKeys(clientInfo.user, ["id", "type"]) as UserLike),
|
|
131
|
-
}
|
|
132
|
-
);
|
|
120
|
+
const sessionUser = getSessionUser(clientInfo);
|
|
133
121
|
const localParams: LocalParams = {
|
|
134
122
|
clientReq,
|
|
135
123
|
isRemoteRequest: { user: sessionUser, clientInfo },
|