prostgles-server 4.2.624 → 4.2.626
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/Audit/AuditTable.d.ts +4 -2
- package/dist/Audit/AuditTable.d.ts.map +1 -1
- package/dist/Audit/AuditTable.js +3 -2
- package/dist/Audit/AuditTable.js.map +1 -1
- package/dist/Audit/getAuditTableRules.d.ts +7 -0
- package/dist/Audit/getAuditTableRules.d.ts.map +1 -0
- package/dist/Audit/getAuditTableRules.js +191 -0
- package/dist/Audit/getAuditTableRules.js.map +1 -0
- package/dist/Audit/getAuditTriggerConfig.d.ts.map +1 -1
- package/dist/Audit/getAuditTriggerConfig.js +14 -1
- package/dist/Audit/getAuditTriggerConfig.js.map +1 -1
- package/dist/DBSchemaBuilder/getClientDBGeneratedSchemas.d.ts.map +1 -1
- package/dist/DBSchemaBuilder/getClientDBGeneratedSchemas.js +7 -1
- package/dist/DBSchemaBuilder/getClientDBGeneratedSchemas.js.map +1 -1
- package/dist/DBSchemaBuilder/getDBGeneratedSchema.d.ts.map +1 -1
- package/dist/DBSchemaBuilder/getDBGeneratedSchema.js +1 -2
- package/dist/DBSchemaBuilder/getDBGeneratedSchema.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts +10 -5
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.js +90 -71
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.js +3 -2
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts +2 -2
- package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getNewQuery.js +53 -116
- package/dist/DboBuilder/QueryBuilder/getNewQuery.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getQuerySource.d.ts +18 -0
- package/dist/DboBuilder/QueryBuilder/getQuerySource.d.ts.map +1 -0
- package/dist/DboBuilder/QueryBuilder/getQuerySource.js +29 -0
- package/dist/DboBuilder/QueryBuilder/getQuerySource.js.map +1 -0
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.js +6 -2
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/parseJoinSelect.d.ts +13 -0
- package/dist/DboBuilder/QueryBuilder/parseJoinSelect.d.ts.map +1 -0
- package/dist/DboBuilder/QueryBuilder/parseJoinSelect.js +57 -0
- package/dist/DboBuilder/QueryBuilder/parseJoinSelect.js.map +1 -0
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.js +2 -1
- 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 +2 -1
- package/dist/DboBuilder/TableHandler/delete.js.map +1 -1
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.d.ts +3 -1
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js +19 -5
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js.map +1 -1
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js +2 -1
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js.map +1 -1
- package/dist/DboBuilder/TableHandler/update.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/update.js +2 -1
- package/dist/DboBuilder/TableHandler/update.js.map +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.d.ts +2 -39
- package/dist/DboBuilder/TableHandler/updateFile.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.js +1 -0
- package/dist/DboBuilder/TableHandler/updateFile.js.map +1 -1
- package/dist/DboBuilder/TableHandler/uploadFile.d.ts +2 -1
- package/dist/DboBuilder/TableHandler/uploadFile.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/uploadFile.js +2 -1
- package/dist/DboBuilder/TableHandler/uploadFile.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +6 -16
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.js +2 -7
- package/dist/DboBuilder/ViewHandler/ViewHandler.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/getExistsCondition.d.ts +1 -1
- package/dist/DboBuilder/ViewHandler/getExistsCondition.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/getExistsCondition.js +24 -13
- package/dist/DboBuilder/ViewHandler/getExistsCondition.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/getRawInfo.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/getRawInfo.js +6 -2
- package/dist/DboBuilder/ViewHandler/getRawInfo.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/getTableJoinQuery.d.ts +4 -1
- package/dist/DboBuilder/ViewHandler/getTableJoinQuery.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/getTableJoinQuery.js +20 -14
- package/dist/DboBuilder/ViewHandler/getTableJoinQuery.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts +7 -3
- package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareWhere.js +30 -23
- package/dist/DboBuilder/ViewHandler/prepareWhere.js.map +1 -1
- package/dist/DboBuilder/getColumns.d.ts.map +1 -1
- package/dist/DboBuilder/getColumns.js +3 -0
- package/dist/DboBuilder/getColumns.js.map +1 -1
- package/dist/DboBuilder/getCondition.d.ts +2 -1
- package/dist/DboBuilder/getCondition.d.ts.map +1 -1
- package/dist/DboBuilder/getCondition.js +9 -8
- package/dist/DboBuilder/getCondition.js.map +1 -1
- package/dist/DboBuilder/getSubscribeRelatedTables.d.ts.map +1 -1
- package/dist/DboBuilder/getSubscribeRelatedTables.js +3 -2
- package/dist/DboBuilder/getSubscribeRelatedTables.js.map +1 -1
- package/dist/DboBuilder/parseUpdateRules.d.ts.map +1 -1
- package/dist/DboBuilder/parseUpdateRules.js +3 -2
- package/dist/DboBuilder/parseUpdateRules.js.map +1 -1
- package/dist/DboBuilder/schema/getTablesForSchemaPostgresSQL.d.ts +2 -2
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +2 -0
- package/dist/Prostgles.js.map +1 -1
- package/dist/ProstglesContext.spec.js +25 -0
- package/dist/ProstglesContext.spec.js.map +1 -1
- package/dist/ProstglesTypes.d.ts +10 -0
- package/dist/ProstglesTypes.d.ts.map +1 -1
- package/dist/ProstglesTypes.js.map +1 -1
- package/dist/PubSubManager/PubSubManager.d.ts +1 -1
- package/dist/PublishParser/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser/PublishParser.js +22 -4
- package/dist/PublishParser/PublishParser.js.map +1 -1
- package/dist/PublishParser/applyScopeToTableRules.d.ts +0 -1
- package/dist/PublishParser/applyScopeToTableRules.d.ts.map +1 -1
- package/dist/PublishParser/applyScopeToTableRules.js +3 -7
- package/dist/PublishParser/applyScopeToTableRules.js.map +1 -1
- package/dist/PublishParser/getFileTableRules.d.ts.map +1 -1
- package/dist/PublishParser/getFileTableRules.js +4 -1
- package/dist/PublishParser/getFileTableRules.js.map +1 -1
- package/dist/PublishParser/getFileVersionTableRules.d.ts +7 -0
- package/dist/PublishParser/getFileVersionTableRules.d.ts.map +1 -0
- package/dist/PublishParser/getFileVersionTableRules.js +77 -0
- package/dist/PublishParser/getFileVersionTableRules.js.map +1 -0
- package/dist/PublishParser/getFileVersionTableRules.spec.d.ts +2 -0
- package/dist/PublishParser/getFileVersionTableRules.spec.d.ts.map +1 -0
- package/dist/PublishParser/getFileVersionTableRules.spec.js +50 -0
- package/dist/PublishParser/getFileVersionTableRules.spec.js.map +1 -0
- package/dist/PublishParser/getPublishedTableNames.d.ts.map +1 -1
- package/dist/PublishParser/getPublishedTableNames.js +24 -1
- package/dist/PublishParser/getPublishedTableNames.js.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts +0 -4
- package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.js.map +1 -1
- package/dist/StorageClient/deleteUnreferencedFile.d.ts.map +1 -1
- package/dist/StorageClient/deleteUnreferencedFile.js +17 -1
- package/dist/StorageClient/deleteUnreferencedFile.js.map +1 -1
- package/dist/StorageClient/fileTableDefinitions.d.ts +54 -0
- package/dist/StorageClient/fileTableDefinitions.d.ts.map +1 -0
- package/dist/StorageClient/fileTableDefinitions.js +38 -0
- package/dist/StorageClient/fileTableDefinitions.js.map +1 -0
- package/dist/StorageClient/fileVersionUtils.d.ts +18 -0
- package/dist/StorageClient/fileVersionUtils.d.ts.map +1 -0
- package/dist/StorageClient/fileVersionUtils.js +22 -0
- package/dist/StorageClient/fileVersionUtils.js.map +1 -0
- package/dist/StorageClient/getFileStorageKey.d.ts +3 -1
- package/dist/StorageClient/getFileStorageKey.d.ts.map +1 -1
- package/dist/StorageClient/getFileStorageKey.js +9 -1
- package/dist/StorageClient/getFileStorageKey.js.map +1 -1
- package/dist/StorageClient/getFileTableConfig.d.ts +1 -23
- package/dist/StorageClient/getFileTableConfig.d.ts.map +1 -1
- package/dist/StorageClient/getFileTableConfig.js +63 -25
- package/dist/StorageClient/getFileTableConfig.js.map +1 -1
- package/dist/StorageClient/getFileTableConfig.spec.js +6 -1
- package/dist/StorageClient/getFileTableConfig.spec.js.map +1 -1
- package/dist/StorageClient/saveFileVersion.d.ts +7 -0
- package/dist/StorageClient/saveFileVersion.d.ts.map +1 -0
- package/dist/StorageClient/saveFileVersion.js +71 -0
- package/dist/StorageClient/saveFileVersion.js.map +1 -0
- package/dist/StorageClient/setupFileServeHandler.d.ts.map +1 -1
- package/dist/StorageClient/setupFileServeHandler.js +38 -21
- package/dist/StorageClient/setupFileServeHandler.js.map +1 -1
- package/dist/TableConfig/TableRowFromColumnDefinitions.d.ts +11 -4
- package/dist/TableConfig/TableRowFromColumnDefinitions.d.ts.map +1 -1
- package/dist/TableConfig/getColumnSQLDefinitionQuery.d.ts.map +1 -1
- package/dist/TableConfig/getColumnSQLDefinitionQuery.js +1 -2
- package/dist/TableConfig/getColumnSQLDefinitionQuery.js.map +1 -1
- package/dist/TableConfig/initTableConfig.d.ts.map +1 -1
- package/dist/TableConfig/initTableConfig.js +9 -6
- package/dist/TableConfig/initTableConfig.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/lib/Audit/AuditTable.ts +8 -4
- package/lib/Audit/getAuditTableRules.ts +292 -0
- package/lib/Audit/getAuditTriggerConfig.ts +14 -1
- package/lib/DBSchemaBuilder/getClientDBGeneratedSchemas.ts +9 -1
- package/lib/DBSchemaBuilder/getDBGeneratedSchema.ts +1 -2
- package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +118 -90
- package/lib/DboBuilder/QueryBuilder/getJoinQuery.ts +3 -2
- package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +111 -194
- package/lib/DboBuilder/QueryBuilder/getQuerySource.ts +55 -0
- package/lib/DboBuilder/QueryBuilder/getSelectQuery.ts +8 -2
- package/lib/DboBuilder/QueryBuilder/parseJoinSelect.ts +73 -0
- package/lib/DboBuilder/TableHandler/TableHandler.ts +3 -6
- package/lib/DboBuilder/TableHandler/delete.ts +2 -1
- package/lib/DboBuilder/TableHandler/onDeleteFromFileTable.ts +31 -5
- package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +2 -1
- package/lib/DboBuilder/TableHandler/update.ts +2 -1
- package/lib/DboBuilder/TableHandler/updateFile.ts +1 -0
- package/lib/DboBuilder/TableHandler/uploadFile.ts +3 -0
- package/lib/DboBuilder/ViewHandler/ViewHandler.ts +6 -12
- package/lib/DboBuilder/ViewHandler/find.ts +0 -1
- package/lib/DboBuilder/ViewHandler/getExistsCondition.ts +35 -28
- package/lib/DboBuilder/ViewHandler/getRawInfo.ts +6 -2
- package/lib/DboBuilder/ViewHandler/getTableJoinQuery.ts +22 -14
- package/lib/DboBuilder/ViewHandler/prepareWhere.ts +48 -27
- package/lib/DboBuilder/getColumns.ts +2 -0
- package/lib/DboBuilder/getCondition.ts +11 -10
- package/lib/DboBuilder/getSubscribeRelatedTables.ts +3 -2
- package/lib/DboBuilder/parseUpdateRules.ts +3 -2
- package/lib/Prostgles.ts +1 -0
- package/lib/ProstglesContext.spec.ts +30 -0
- package/lib/ProstglesTypes.ts +11 -0
- package/lib/PublishParser/PublishParser.ts +47 -4
- package/lib/PublishParser/applyScopeToTableRules.ts +1 -7
- package/lib/PublishParser/getFileTableRules.ts +7 -1
- package/lib/PublishParser/getFileVersionTableRules.spec.ts +57 -0
- package/lib/PublishParser/getFileVersionTableRules.ts +106 -0
- package/lib/PublishParser/getPublishedTableNames.ts +33 -2
- package/lib/PublishParser/publishTypesAndUtils.ts +0 -5
- package/lib/StorageClient/deleteUnreferencedFile.ts +20 -2
- package/lib/StorageClient/fileTableDefinitions.ts +52 -0
- package/lib/StorageClient/fileVersionUtils.ts +37 -0
- package/lib/StorageClient/getFileStorageKey.ts +11 -2
- package/lib/StorageClient/getFileTableConfig.spec.ts +6 -1
- package/lib/StorageClient/getFileTableConfig.ts +85 -30
- package/lib/StorageClient/saveFileVersion.ts +82 -0
- package/lib/StorageClient/setupFileServeHandler.ts +51 -28
- package/lib/TableConfig/TableRowFromColumnDefinitions.ts +37 -13
- package/lib/TableConfig/getColumnSQLDefinitionQuery.ts +8 -2
- package/lib/TableConfig/initTableConfig.ts +10 -6
- package/lib/index.ts +3 -1
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "prostgles-types";
|
|
7
7
|
import { getClientRequestIPsInfo } from "../Auth/AuthHandler";
|
|
8
8
|
import type { AuthClientRequest, AuthResultWithSID, SessionUser } from "../Auth/AuthTypes";
|
|
9
|
+
import { getAuditTableRules } from "../Audit/getAuditTableRules";
|
|
9
10
|
import type { DBOFullyTyped } from "../DBSchemaBuilder/DBSchemaBuilder";
|
|
10
11
|
import type { DB, DBHandlerServer, Prostgles } from "../Prostgles";
|
|
11
12
|
import { getClientHandlers } from "../WebsocketAPI/getClientHandlers";
|
|
@@ -16,6 +17,8 @@ import type {
|
|
|
16
17
|
UnrestrictedFunctionContext,
|
|
17
18
|
} from "./defineServerFunction";
|
|
18
19
|
import { getFileTableRules } from "./getFileTableRules";
|
|
20
|
+
import { getFileVersionTableRules } from "./getFileVersionTableRules";
|
|
21
|
+
import { isFileVersionTable } from "../StorageClient/fileVersionUtils";
|
|
19
22
|
import { getPublishedObjectFromResult } from "./getPublishedObjectFromResult";
|
|
20
23
|
import { getSchemaFromPublish } from "./getSchemaFromPublish";
|
|
21
24
|
import { getParsedPublishTable } from "./getParsedPublishTable";
|
|
@@ -305,16 +308,56 @@ export class PublishParser {
|
|
|
305
308
|
if (!tableHandler) {
|
|
306
309
|
throw "INTERNAL ERROR: table handler not found for " + tableName;
|
|
307
310
|
}
|
|
308
|
-
const
|
|
311
|
+
const audit = this.prostgles.resolvedAuditConfig;
|
|
312
|
+
const isAuditTable = audit?.tableName === tableName;
|
|
313
|
+
const resolvedPublishObject =
|
|
314
|
+
overriddenPublish ??
|
|
315
|
+
(isAuditTable && clientReq ?
|
|
316
|
+
await this.getPublishObjectForUser(clientReq, clientInfo)
|
|
317
|
+
: undefined);
|
|
318
|
+
const publishRulesExcludingInferredTables = await this.getParsedPublishTable({
|
|
309
319
|
clientReq,
|
|
310
320
|
tableName,
|
|
311
321
|
clientInfo,
|
|
312
|
-
resolvedPublishObject
|
|
322
|
+
resolvedPublishObject,
|
|
313
323
|
});
|
|
324
|
+
if (audit && isAuditTable) {
|
|
325
|
+
const auditTableRules = await getAuditTableRules.bind(this)(
|
|
326
|
+
audit,
|
|
327
|
+
publishRulesExcludingInferredTables,
|
|
328
|
+
clientReq,
|
|
329
|
+
clientInfo,
|
|
330
|
+
scope,
|
|
331
|
+
resolvedPublishObject,
|
|
332
|
+
);
|
|
333
|
+
return applyScopeToTableRules(
|
|
334
|
+
tableName,
|
|
335
|
+
tableHandler,
|
|
336
|
+
parsePublishTableRule(auditTableRules),
|
|
337
|
+
scope,
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
const fileConfig = this.prostgles.opts.fileTable;
|
|
341
|
+
if (isFileVersionTable(fileConfig, tableName)) {
|
|
342
|
+
const versionRules = await getFileVersionTableRules.bind(this)(
|
|
343
|
+
fileConfig,
|
|
344
|
+
publishRulesExcludingInferredTables,
|
|
345
|
+
clientReq,
|
|
346
|
+
clientInfo,
|
|
347
|
+
scope,
|
|
348
|
+
overriddenPublish,
|
|
349
|
+
);
|
|
350
|
+
return applyScopeToTableRules(
|
|
351
|
+
tableName,
|
|
352
|
+
tableHandler,
|
|
353
|
+
parsePublishTableRule(versionRules),
|
|
354
|
+
scope,
|
|
355
|
+
);
|
|
356
|
+
}
|
|
314
357
|
if (this.dbo[tableName]?.is_media) {
|
|
315
358
|
const { rules: fileTableRules } = await getFileTableRules.bind(this)(
|
|
316
359
|
tableName,
|
|
317
|
-
|
|
360
|
+
publishRulesExcludingInferredTables,
|
|
318
361
|
clientReq,
|
|
319
362
|
clientInfo,
|
|
320
363
|
scope,
|
|
@@ -331,7 +374,7 @@ export class PublishParser {
|
|
|
331
374
|
return applyScopeToTableRules(
|
|
332
375
|
tableName,
|
|
333
376
|
tableHandler,
|
|
334
|
-
parsePublishTableRule(
|
|
377
|
+
parsePublishTableRule(publishRulesExcludingInferredTables),
|
|
335
378
|
scope,
|
|
336
379
|
);
|
|
337
380
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getObjectEntries, isDefined, isEmpty } from "prostgles-types";
|
|
1
|
+
import { fromEntries, getObjectEntries, isDefined, isEmpty } from "prostgles-types";
|
|
2
2
|
import type { TableHandler } from "../DboBuilder/TableHandler/TableHandler";
|
|
3
3
|
import { type ParsedTableRule, type PermissionScope } from "./PublishParser";
|
|
4
4
|
export const applyScopeToTableRules = (
|
|
@@ -68,9 +68,3 @@ export const applyScopeToTableRules = (
|
|
|
68
68
|
) as ParsedTableRule;
|
|
69
69
|
return result;
|
|
70
70
|
};
|
|
71
|
-
|
|
72
|
-
export const fromEntries = <K extends string | number | symbol, V>(
|
|
73
|
-
entries: readonly (readonly [K, V])[],
|
|
74
|
-
): Record<K, V> => {
|
|
75
|
-
return Object.fromEntries(entries) as Record<K, V>;
|
|
76
|
-
};
|
|
@@ -5,6 +5,7 @@ import { parseFieldFilter } from "../DboBuilder/ViewHandler/parseFieldFilter";
|
|
|
5
5
|
import type { PublishParser } from "./PublishParser";
|
|
6
6
|
import type { ParsedPublishTable, PublishObject, UpdateRule } from "./publishTypesAndUtils";
|
|
7
7
|
import type { LocalParams } from "../DboBuilder/DboBuilder";
|
|
8
|
+
import { isFileVersionTable } from "../StorageClient/fileVersionUtils";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Permissions for referencedTables columns are propagated to the file table (even if file table has no permissions)
|
|
@@ -28,7 +29,12 @@ export async function getFileTableRules(
|
|
|
28
29
|
const forcedUpdateFilters: FullFilter<AnyObject, void>[] = [];
|
|
29
30
|
const allowedNestedInserts: { table: string; column: string }[] = [];
|
|
30
31
|
const referencedColumns = this.prostgles.dboBuilder.tablesOrViews
|
|
31
|
-
?.filter(
|
|
32
|
+
?.filter(
|
|
33
|
+
(t) =>
|
|
34
|
+
!t.is_view &&
|
|
35
|
+
t.name !== fileTableName &&
|
|
36
|
+
!isFileVersionTable(this.prostgles.opts.fileTable, t.name),
|
|
37
|
+
)
|
|
32
38
|
.map((t) => {
|
|
33
39
|
const refCols = t.columns.filter((c) =>
|
|
34
40
|
c.references?.some((r) => r.ftable === fileTableName),
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import type { FileTableConfig } from "../ProstglesTypes";
|
|
4
|
+
import { parseFieldFilter } from "../DboBuilder/ViewHandler/parseFieldFilter";
|
|
5
|
+
import type { PublishParser } from "./PublishParser";
|
|
6
|
+
import { getFileVersionTableRules } from "./getFileVersionTableRules";
|
|
7
|
+
|
|
8
|
+
void test("file version rules inherit fields and restrictive select options", async () => {
|
|
9
|
+
const fileColumns = ["id", "updated", "metadata"];
|
|
10
|
+
const versionColumns = ["id", "file_id", "created", "metadata"];
|
|
11
|
+
const getHandler = (columns: string[]) => ({
|
|
12
|
+
column_names: columns,
|
|
13
|
+
parseFieldFilter: (fields: any = "*") => parseFieldFilter(fields, true, columns),
|
|
14
|
+
});
|
|
15
|
+
const parser = {
|
|
16
|
+
dbo: {
|
|
17
|
+
files: getHandler(fileColumns),
|
|
18
|
+
files_versions: getHandler(versionColumns),
|
|
19
|
+
},
|
|
20
|
+
getTableRules: () => Promise.resolve({
|
|
21
|
+
select: {
|
|
22
|
+
fields: "*",
|
|
23
|
+
maxLimit: 5,
|
|
24
|
+
subscribeThrottle: 20,
|
|
25
|
+
disableMethods: { subscribe: 1 },
|
|
26
|
+
},
|
|
27
|
+
}),
|
|
28
|
+
} as unknown as PublishParser;
|
|
29
|
+
|
|
30
|
+
const rules = await getFileVersionTableRules.call(
|
|
31
|
+
parser,
|
|
32
|
+
{ tableName: "files", versioning: {} } as FileTableConfig,
|
|
33
|
+
{
|
|
34
|
+
select: {
|
|
35
|
+
fields: "*",
|
|
36
|
+
maxLimit: 10,
|
|
37
|
+
subscribeThrottle: 10,
|
|
38
|
+
disableMethods: { sync: 1 },
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
undefined,
|
|
42
|
+
undefined,
|
|
43
|
+
undefined,
|
|
44
|
+
undefined,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
assert(rules?.select);
|
|
48
|
+
assert.deepEqual(rules.select.fields, {
|
|
49
|
+
id: 1,
|
|
50
|
+
file_id: 1,
|
|
51
|
+
created: 1,
|
|
52
|
+
metadata: 1,
|
|
53
|
+
});
|
|
54
|
+
assert.equal(rules.select.maxLimit, 5);
|
|
55
|
+
assert.equal(rules.select.subscribeThrottle, 20);
|
|
56
|
+
assert.deepEqual(rules.select.disableMethods, { subscribe: 1, sync: 1 });
|
|
57
|
+
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { fromEntries } from "prostgles-types";
|
|
2
|
+
import type { AuthClientRequest, AuthResultWithSID } from "../Auth/AuthTypes";
|
|
3
|
+
import type { LocalParams } from "../DboBuilder/DboBuilder";
|
|
4
|
+
import type { FileTableConfig } from "../ProstglesTypes";
|
|
5
|
+
import type { PublishParser } from "./PublishParser";
|
|
6
|
+
import type { ParsedPublishTable, PublishObject } from "./publishTypesAndUtils";
|
|
7
|
+
import { getFileVersionTableName } from "../StorageClient/fileVersionUtils";
|
|
8
|
+
import type { FileTableRow, FileVersionTableRow } from "../StorageClient/fileTableDefinitions";
|
|
9
|
+
|
|
10
|
+
export const getFileVersionTableRules = async function (
|
|
11
|
+
this: PublishParser,
|
|
12
|
+
config: FileTableConfig,
|
|
13
|
+
explicitRules: ParsedPublishTable | undefined,
|
|
14
|
+
clientReq: AuthClientRequest | undefined,
|
|
15
|
+
clientInfo: AuthResultWithSID | undefined,
|
|
16
|
+
scope: LocalParams["scope"] | undefined,
|
|
17
|
+
resolvedPublishObject: PublishObject | undefined,
|
|
18
|
+
): Promise<ParsedPublishTable | undefined> {
|
|
19
|
+
const versionTableName = getFileVersionTableName(config);
|
|
20
|
+
if (
|
|
21
|
+
resolvedPublishObject &&
|
|
22
|
+
Object.hasOwn(resolvedPublishObject, versionTableName) &&
|
|
23
|
+
!explicitRules?.select
|
|
24
|
+
) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const fileRules = await this.getTableRules({
|
|
29
|
+
tableName: config.tableName,
|
|
30
|
+
clientReq,
|
|
31
|
+
clientInfo,
|
|
32
|
+
scope,
|
|
33
|
+
resolvedPublishObject,
|
|
34
|
+
});
|
|
35
|
+
if (!fileRules?.select) return;
|
|
36
|
+
|
|
37
|
+
const versionHandler = this.dbo[versionTableName];
|
|
38
|
+
if (!versionHandler) throw new Error(`File version table not found: ${versionTableName}`);
|
|
39
|
+
const fileHandler = this.dbo[config.tableName];
|
|
40
|
+
if (!fileHandler) throw new Error(`File table not found: ${config.tableName}`);
|
|
41
|
+
const select = explicitRules?.select;
|
|
42
|
+
const requestedFields = versionHandler.parseFieldFilter(select?.fields ?? "*");
|
|
43
|
+
const fileSelectFields = fileHandler.parseFieldFilter(fileRules.select.fields);
|
|
44
|
+
const fields = (versionHandler.column_names as (keyof FileVersionTableRow)[]).filter(
|
|
45
|
+
(field) =>
|
|
46
|
+
requestedFields.includes(field) &&
|
|
47
|
+
fileSelectFields.includes(getFileVersionSourceField(field)) &&
|
|
48
|
+
(fileHandler.column_names as (keyof FileTableRow)[]).includes(
|
|
49
|
+
getFileVersionSourceField(field),
|
|
50
|
+
),
|
|
51
|
+
);
|
|
52
|
+
const requestedFilterFields = versionHandler.parseFieldFilter(select?.filterFields ?? fields);
|
|
53
|
+
const requestedOrderByFields = versionHandler.parseFieldFilter(select?.orderByFields ?? fields);
|
|
54
|
+
const inheritedFilter = {
|
|
55
|
+
$existsJoined: {
|
|
56
|
+
path: [{ table: config.tableName, on: [{ file_id: "id" }] }],
|
|
57
|
+
filter: fileRules.select.forcedFilter ?? {},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
select: {
|
|
63
|
+
...fileRules.select,
|
|
64
|
+
...select,
|
|
65
|
+
fields: fromEntries(fields.map((field) => [field, 1 as const] as const)),
|
|
66
|
+
filterFields: fromEntries(
|
|
67
|
+
fields
|
|
68
|
+
.filter((field) => requestedFilterFields.includes(field))
|
|
69
|
+
.map((field) => [field, 1 as const] as const),
|
|
70
|
+
),
|
|
71
|
+
orderByFields: fromEntries(
|
|
72
|
+
fields
|
|
73
|
+
.filter((field) => requestedOrderByFields.includes(field))
|
|
74
|
+
.map((field) => [field, 1 as const] as const),
|
|
75
|
+
),
|
|
76
|
+
forcedFilter:
|
|
77
|
+
select?.forcedFilter ? { $and: [inheritedFilter, select.forcedFilter] } : inheritedFilter,
|
|
78
|
+
maxLimit: getMostRestrictiveLimit(fileRules.select.maxLimit, select?.maxLimit),
|
|
79
|
+
subscribeThrottle: Math.max(
|
|
80
|
+
fileRules.select.subscribeThrottle ?? 0,
|
|
81
|
+
select?.subscribeThrottle ?? 0,
|
|
82
|
+
),
|
|
83
|
+
disableMethods: {
|
|
84
|
+
...fileRules.select.disableMethods,
|
|
85
|
+
...select?.disableMethods,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const getFileVersionSourceField = (field: keyof FileVersionTableRow): keyof FileTableRow => {
|
|
92
|
+
if (field === "file_id") return "id";
|
|
93
|
+
if (field === "created") return "updated";
|
|
94
|
+
return field;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const getMostRestrictiveLimit = (
|
|
98
|
+
inheritedLimit: number | null | undefined,
|
|
99
|
+
explicitLimit: number | null | undefined,
|
|
100
|
+
) => {
|
|
101
|
+
const limits = [inheritedLimit, explicitLimit].filter(
|
|
102
|
+
(limit): limit is number => typeof limit === "number",
|
|
103
|
+
);
|
|
104
|
+
if (limits.length) return Math.min(...limits);
|
|
105
|
+
return inheritedLimit === null || explicitLimit === null ? null : undefined;
|
|
106
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { isObject } from "prostgles-types";
|
|
1
2
|
import type { PublishParser } from "./PublishParser";
|
|
2
3
|
import { type PublishObject } from "./PublishParser";
|
|
4
|
+
import { getFileVersionTableName, isFileVersionTable } from "../StorageClient/fileVersionUtils";
|
|
3
5
|
|
|
4
6
|
export const getPublishedTableNames = (
|
|
5
7
|
publishParserInstance: PublishParser,
|
|
@@ -23,12 +25,41 @@ export const getPublishedTableNames = (
|
|
|
23
25
|
publishParserInstance.dbo[fileTableName]?.is_media &&
|
|
24
26
|
!tableNames.includes(fileTableName)
|
|
25
27
|
) {
|
|
26
|
-
const isReferenced = publishParserInstance.prostgles.dboBuilder.tablesOrViews?.some(
|
|
27
|
-
t
|
|
28
|
+
const isReferenced = publishParserInstance.prostgles.dboBuilder.tablesOrViews?.some(
|
|
29
|
+
(t) =>
|
|
30
|
+
!isFileVersionTable(publishParserInstance.prostgles.opts.fileTable, t.name) &&
|
|
31
|
+
t.columns.some((c) => c.references?.some((r) => r.ftable === fileTableName)),
|
|
28
32
|
);
|
|
29
33
|
if (isReferenced) {
|
|
30
34
|
tableNames.unshift(fileTableName);
|
|
31
35
|
}
|
|
32
36
|
}
|
|
37
|
+
|
|
38
|
+
const fileConfig = publishParserInstance.prostgles.opts.fileTable;
|
|
39
|
+
if (fileConfig?.versioning && tableNames.includes(fileConfig.tableName)) {
|
|
40
|
+
const versionTableName = getFileVersionTableName(fileConfig);
|
|
41
|
+
if (!tableNames.includes(versionTableName)) {
|
|
42
|
+
tableNames.unshift(versionTableName);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const audit = publishParserInstance.prostgles.resolvedAuditConfig;
|
|
47
|
+
const publishedFileTableName =
|
|
48
|
+
fileTableName && tableNames.includes(fileTableName) ? fileTableName : undefined;
|
|
49
|
+
if (
|
|
50
|
+
audit &&
|
|
51
|
+
!tableNames.includes(audit.tableName) &&
|
|
52
|
+
Object.keys(audit.tables).some((tableName) => {
|
|
53
|
+
const rule = publishObject[tableName];
|
|
54
|
+
return (
|
|
55
|
+
tableName === publishedFileTableName ||
|
|
56
|
+
rule === "*" ||
|
|
57
|
+
rule === true ||
|
|
58
|
+
(isObject(rule) && Boolean(rule.select))
|
|
59
|
+
);
|
|
60
|
+
})
|
|
61
|
+
) {
|
|
62
|
+
tableNames.unshift(audit.tableName);
|
|
63
|
+
}
|
|
33
64
|
return tableNames;
|
|
34
65
|
};
|
|
@@ -228,11 +228,6 @@ export type SelectRule<Cols extends AnyObject = AnyObject, S extends DBSchema |
|
|
|
228
228
|
* */
|
|
229
229
|
filterFields?: FieldFilter<Cols>;
|
|
230
230
|
|
|
231
|
-
/**
|
|
232
|
-
* Validation logic to check/update data for each request
|
|
233
|
-
*/
|
|
234
|
-
validate?(args: SelectRequestData): SelectRequestData | Promise<SelectRequestData>;
|
|
235
|
-
|
|
236
231
|
subscribeThrottle?: number;
|
|
237
232
|
|
|
238
233
|
disableMethods?: Partial<Record<"sync" | "subscribe", 1>>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DB } from "../Prostgles";
|
|
2
2
|
import type { FileTableConfig } from "../ProstglesTypes";
|
|
3
|
+
import { getFileVersionTableName } from "./fileVersionUtils";
|
|
3
4
|
|
|
4
5
|
export const deleteUnreferencedFile = async (
|
|
5
6
|
db: DB,
|
|
@@ -11,8 +12,25 @@ export const deleteUnreferencedFile = async (
|
|
|
11
12
|
const referenced = await db.tx(async (tx) => {
|
|
12
13
|
await tx.none("SET LOCAL row_security = off");
|
|
13
14
|
return tx.oneOrNone<{ found: number }>(
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
`SELECT 1 AS found
|
|
16
|
+
WHERE EXISTS (
|
|
17
|
+
SELECT 1 FROM \${fileTable:name}
|
|
18
|
+
WHERE storage_key = \${key}::uuid OR (storage_key IS NULL AND id = \${key}::uuid)
|
|
19
|
+
)
|
|
20
|
+
${
|
|
21
|
+
config.versioning ?
|
|
22
|
+
`OR EXISTS (
|
|
23
|
+
SELECT 1 FROM \${versionTable:name}
|
|
24
|
+
WHERE storage_key = \${key}::uuid
|
|
25
|
+
)`
|
|
26
|
+
: ""
|
|
27
|
+
}
|
|
28
|
+
LIMIT 1`,
|
|
29
|
+
{
|
|
30
|
+
fileTable: config.tableName,
|
|
31
|
+
versionTable: getFileVersionTableName(config),
|
|
32
|
+
key: storageKey,
|
|
33
|
+
},
|
|
16
34
|
);
|
|
17
35
|
});
|
|
18
36
|
if (!referenced) await config.storageClient.delete(storageKey);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { omitKeys } from "prostgles-types";
|
|
2
|
+
import type { TableRowFromColumnDefinitions } from "../TableConfig/TableRowFromColumnDefinitions";
|
|
3
|
+
|
|
4
|
+
export const FILE_TABLE_COLUMN_DEFINITIONS = {
|
|
5
|
+
id: `UUID PRIMARY KEY DEFAULT gen_random_uuid()`,
|
|
6
|
+
/**
|
|
7
|
+
* NULL for legacy objects stored under their file ID.
|
|
8
|
+
* */
|
|
9
|
+
storage_key: `UUID UNIQUE`,
|
|
10
|
+
extension: `TEXT NOT NULL DEFAULT ''`,
|
|
11
|
+
content_type: `TEXT NOT NULL DEFAULT ''`,
|
|
12
|
+
content_length: `BIGINT NOT NULL DEFAULT 0`,
|
|
13
|
+
etag: `TEXT NOT NULL DEFAULT ''`,
|
|
14
|
+
original_name: `TEXT NOT NULL`,
|
|
15
|
+
original_last_modified: `TIMESTAMPTZ`,
|
|
16
|
+
description: `TEXT`,
|
|
17
|
+
url: `TEXT NOT NULL DEFAULT ''`,
|
|
18
|
+
cloud_url: `TEXT`,
|
|
19
|
+
signed_url: `TEXT`,
|
|
20
|
+
signed_url_expires: `BIGINT`,
|
|
21
|
+
added: `TIMESTAMP NOT NULL DEFAULT NOW()`,
|
|
22
|
+
updated: `TIMESTAMP NOT NULL DEFAULT NOW()`,
|
|
23
|
+
deleted: `TIMESTAMPTZ`,
|
|
24
|
+
deleted_from_storage: `TIMESTAMPTZ`,
|
|
25
|
+
data: `BYTEA NOT NULL CHECK (data = decode('01', 'hex'))`, // Used as a placeholder to ensure insert types are correct. Actual data is uploaded to storageClient and not stored in the DB
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
export const FILE_TABLE_VERSION_COLUMN_DEFINITIONS = {
|
|
29
|
+
version: `INTEGER NOT NULL DEFAULT 1`,
|
|
30
|
+
} as const;
|
|
31
|
+
|
|
32
|
+
export const FILE_VERSION_TABLE_COLUMN_DEFINITIONS = {
|
|
33
|
+
...omitKeys(FILE_TABLE_COLUMN_DEFINITIONS, ["data"]),
|
|
34
|
+
storage_key: `UUID NOT NULL`,
|
|
35
|
+
file_id: `UUID NOT NULL`, // FK constraint is added later on
|
|
36
|
+
version: `INTEGER NOT NULL`,
|
|
37
|
+
created: `TIMESTAMP NOT NULL DEFAULT NOW()`,
|
|
38
|
+
} as const;
|
|
39
|
+
|
|
40
|
+
export type FileTableInsertRow = TableRowFromColumnDefinitions<
|
|
41
|
+
typeof FILE_TABLE_COLUMN_DEFINITIONS
|
|
42
|
+
> &
|
|
43
|
+
Partial<TableRowFromColumnDefinitions<typeof FILE_TABLE_VERSION_COLUMN_DEFINITIONS>>;
|
|
44
|
+
export type FileTableRow = Required<
|
|
45
|
+
TableRowFromColumnDefinitions<typeof FILE_TABLE_COLUMN_DEFINITIONS>
|
|
46
|
+
> &
|
|
47
|
+
Partial<Required<TableRowFromColumnDefinitions<typeof FILE_TABLE_VERSION_COLUMN_DEFINITIONS>>>;
|
|
48
|
+
|
|
49
|
+
export type FileVersionTableInsertRow = TableRowFromColumnDefinitions<
|
|
50
|
+
typeof FILE_VERSION_TABLE_COLUMN_DEFINITIONS
|
|
51
|
+
>;
|
|
52
|
+
export type FileVersionTableRow = Required<FileVersionTableInsertRow>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { TableHandler } from "prostgles-types";
|
|
2
|
+
import type { TableHandlers } from "../DboBuilder/DboBuilder";
|
|
3
|
+
import type { FileTableConfig } from "../ProstglesTypes";
|
|
4
|
+
import type {
|
|
5
|
+
FileTableRow,
|
|
6
|
+
FileVersionTableInsertRow,
|
|
7
|
+
FileVersionTableRow,
|
|
8
|
+
} from "./fileTableDefinitions";
|
|
9
|
+
|
|
10
|
+
type FileVersionTableSchema = {
|
|
11
|
+
fileVersions: {
|
|
12
|
+
columns: FileVersionTableRow;
|
|
13
|
+
insertColumns: FileVersionTableInsertRow;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const getFileVersionTableName = (config: FileTableConfig) =>
|
|
18
|
+
config.versioning?.tableName ?? `${config.tableName}_versions`;
|
|
19
|
+
|
|
20
|
+
export const isFileVersionTable = (
|
|
21
|
+
config: FileTableConfig | undefined,
|
|
22
|
+
tableName: string,
|
|
23
|
+
): config is FileTableConfig & { versioning: NonNullable<FileTableConfig["versioning"]> } =>
|
|
24
|
+
Boolean(config?.versioning && getFileVersionTableName(config) === tableName);
|
|
25
|
+
|
|
26
|
+
export const getFileTableHandler = (dbo: TableHandlers, config: FileTableConfig) => {
|
|
27
|
+
const handler = dbo[config.tableName] as TableHandler<FileTableRow> | undefined;
|
|
28
|
+
if (!handler) throw new Error(`File table not found: ${config.tableName}`);
|
|
29
|
+
return handler;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const getFileRevisionsTableHandler = (dbo: TableHandlers, config: FileTableConfig) => {
|
|
33
|
+
const handler = dbo[getFileVersionTableName(config)] as
|
|
34
|
+
TableHandler<FileVersionTableRow, FileVersionTableSchema, "fileVersions"> | undefined;
|
|
35
|
+
if (!handler) throw new Error(`File table not found: ${config.tableName}`);
|
|
36
|
+
return handler;
|
|
37
|
+
};
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { FileTableRow } from "./getFileTableConfig";
|
|
2
2
|
|
|
3
3
|
/** Legacy files are stored under their logical ID. */
|
|
4
|
-
export const getFileStorageKey = (
|
|
5
|
-
file
|
|
4
|
+
export const getFileStorageKey = (
|
|
5
|
+
file: Pick<FileTableRow, "id" | "storage_key"> | { storage_key: string },
|
|
6
|
+
) => {
|
|
7
|
+
const { storage_key } = file;
|
|
8
|
+
const id = "id" in file ? file.id : undefined;
|
|
9
|
+
const key = storage_key ?? id;
|
|
10
|
+
if (!key) {
|
|
11
|
+
throw new Error("Unable to determine file storage key");
|
|
12
|
+
}
|
|
13
|
+
return key;
|
|
14
|
+
};
|
|
@@ -5,7 +5,10 @@ import { getFileTableConfig } from "./getFileTableConfig";
|
|
|
5
5
|
|
|
6
6
|
void test("managed files preserve hooks on other tables and append file hooks", () => {
|
|
7
7
|
const guard = { afterEach: [{ commands: { insert: 1 }, validate: async () => {} }] };
|
|
8
|
-
const fileGuard = {
|
|
8
|
+
const fileGuard = {
|
|
9
|
+
beforeEach: [{ commands: { insert: 1 }, validate: async () => {} }],
|
|
10
|
+
afterEach: [{ commands: { insert: 1 }, validate: async () => {} }],
|
|
11
|
+
};
|
|
9
12
|
const prostgles = {
|
|
10
13
|
opts: {
|
|
11
14
|
fileTable: { tableName: "files", storageClient: {}, expressApp: {} },
|
|
@@ -16,4 +19,6 @@ void test("managed files preserve hooks on other tables and append file hooks",
|
|
|
16
19
|
assert.equal(result.tableHooks?.documents, guard);
|
|
17
20
|
assert.equal(result.tableHooks.files?.beforeEach?.length, 2);
|
|
18
21
|
assert.equal(result.tableHooks.files.beforeEach[1], fileGuard.beforeEach[0]);
|
|
22
|
+
assert.equal(result.tableHooks.files.afterEach?.length, 2);
|
|
23
|
+
assert.equal(result.tableHooks.files.afterEach[0], fileGuard.afterEach[0]);
|
|
19
24
|
});
|