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.
Files changed (223) hide show
  1. package/dist/Audit/AuditTable.d.ts +4 -2
  2. package/dist/Audit/AuditTable.d.ts.map +1 -1
  3. package/dist/Audit/AuditTable.js +3 -2
  4. package/dist/Audit/AuditTable.js.map +1 -1
  5. package/dist/Audit/getAuditTableRules.d.ts +7 -0
  6. package/dist/Audit/getAuditTableRules.d.ts.map +1 -0
  7. package/dist/Audit/getAuditTableRules.js +191 -0
  8. package/dist/Audit/getAuditTableRules.js.map +1 -0
  9. package/dist/Audit/getAuditTriggerConfig.d.ts.map +1 -1
  10. package/dist/Audit/getAuditTriggerConfig.js +14 -1
  11. package/dist/Audit/getAuditTriggerConfig.js.map +1 -1
  12. package/dist/DBSchemaBuilder/getClientDBGeneratedSchemas.d.ts.map +1 -1
  13. package/dist/DBSchemaBuilder/getClientDBGeneratedSchemas.js +7 -1
  14. package/dist/DBSchemaBuilder/getClientDBGeneratedSchemas.js.map +1 -1
  15. package/dist/DBSchemaBuilder/getDBGeneratedSchema.d.ts.map +1 -1
  16. package/dist/DBSchemaBuilder/getDBGeneratedSchema.js +1 -2
  17. package/dist/DBSchemaBuilder/getDBGeneratedSchema.js.map +1 -1
  18. package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts +10 -5
  19. package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts.map +1 -1
  20. package/dist/DboBuilder/QueryBuilder/QueryBuilder.js +90 -71
  21. package/dist/DboBuilder/QueryBuilder/QueryBuilder.js.map +1 -1
  22. package/dist/DboBuilder/QueryBuilder/getJoinQuery.d.ts.map +1 -1
  23. package/dist/DboBuilder/QueryBuilder/getJoinQuery.js +3 -2
  24. package/dist/DboBuilder/QueryBuilder/getJoinQuery.js.map +1 -1
  25. package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts +2 -2
  26. package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts.map +1 -1
  27. package/dist/DboBuilder/QueryBuilder/getNewQuery.js +53 -116
  28. package/dist/DboBuilder/QueryBuilder/getNewQuery.js.map +1 -1
  29. package/dist/DboBuilder/QueryBuilder/getQuerySource.d.ts +18 -0
  30. package/dist/DboBuilder/QueryBuilder/getQuerySource.d.ts.map +1 -0
  31. package/dist/DboBuilder/QueryBuilder/getQuerySource.js +29 -0
  32. package/dist/DboBuilder/QueryBuilder/getQuerySource.js.map +1 -0
  33. package/dist/DboBuilder/QueryBuilder/getSelectQuery.d.ts.map +1 -1
  34. package/dist/DboBuilder/QueryBuilder/getSelectQuery.js +6 -2
  35. package/dist/DboBuilder/QueryBuilder/getSelectQuery.js.map +1 -1
  36. package/dist/DboBuilder/QueryBuilder/parseJoinSelect.d.ts +13 -0
  37. package/dist/DboBuilder/QueryBuilder/parseJoinSelect.d.ts.map +1 -0
  38. package/dist/DboBuilder/QueryBuilder/parseJoinSelect.js +57 -0
  39. package/dist/DboBuilder/QueryBuilder/parseJoinSelect.js.map +1 -0
  40. package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
  41. package/dist/DboBuilder/TableHandler/TableHandler.js +2 -1
  42. package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
  43. package/dist/DboBuilder/TableHandler/delete.d.ts.map +1 -1
  44. package/dist/DboBuilder/TableHandler/delete.js +2 -1
  45. package/dist/DboBuilder/TableHandler/delete.js.map +1 -1
  46. package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.d.ts +3 -1
  47. package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.d.ts.map +1 -1
  48. package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js +19 -5
  49. package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js.map +1 -1
  50. package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.d.ts.map +1 -1
  51. package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js +2 -1
  52. package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js.map +1 -1
  53. package/dist/DboBuilder/TableHandler/update.d.ts.map +1 -1
  54. package/dist/DboBuilder/TableHandler/update.js +2 -1
  55. package/dist/DboBuilder/TableHandler/update.js.map +1 -1
  56. package/dist/DboBuilder/TableHandler/updateFile.d.ts +2 -39
  57. package/dist/DboBuilder/TableHandler/updateFile.d.ts.map +1 -1
  58. package/dist/DboBuilder/TableHandler/updateFile.js +1 -0
  59. package/dist/DboBuilder/TableHandler/updateFile.js.map +1 -1
  60. package/dist/DboBuilder/TableHandler/uploadFile.d.ts +2 -1
  61. package/dist/DboBuilder/TableHandler/uploadFile.d.ts.map +1 -1
  62. package/dist/DboBuilder/TableHandler/uploadFile.js +2 -1
  63. package/dist/DboBuilder/TableHandler/uploadFile.js.map +1 -1
  64. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +6 -16
  65. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
  66. package/dist/DboBuilder/ViewHandler/ViewHandler.js +2 -7
  67. package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
  68. package/dist/DboBuilder/ViewHandler/find.d.ts.map +1 -1
  69. package/dist/DboBuilder/ViewHandler/find.js +1 -1
  70. package/dist/DboBuilder/ViewHandler/find.js.map +1 -1
  71. package/dist/DboBuilder/ViewHandler/getExistsCondition.d.ts +1 -1
  72. package/dist/DboBuilder/ViewHandler/getExistsCondition.d.ts.map +1 -1
  73. package/dist/DboBuilder/ViewHandler/getExistsCondition.js +24 -13
  74. package/dist/DboBuilder/ViewHandler/getExistsCondition.js.map +1 -1
  75. package/dist/DboBuilder/ViewHandler/getRawInfo.d.ts.map +1 -1
  76. package/dist/DboBuilder/ViewHandler/getRawInfo.js +6 -2
  77. package/dist/DboBuilder/ViewHandler/getRawInfo.js.map +1 -1
  78. package/dist/DboBuilder/ViewHandler/getTableJoinQuery.d.ts +4 -1
  79. package/dist/DboBuilder/ViewHandler/getTableJoinQuery.d.ts.map +1 -1
  80. package/dist/DboBuilder/ViewHandler/getTableJoinQuery.js +20 -14
  81. package/dist/DboBuilder/ViewHandler/getTableJoinQuery.js.map +1 -1
  82. package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts +7 -3
  83. package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts.map +1 -1
  84. package/dist/DboBuilder/ViewHandler/prepareWhere.js +30 -23
  85. package/dist/DboBuilder/ViewHandler/prepareWhere.js.map +1 -1
  86. package/dist/DboBuilder/getColumns.d.ts.map +1 -1
  87. package/dist/DboBuilder/getColumns.js +3 -0
  88. package/dist/DboBuilder/getColumns.js.map +1 -1
  89. package/dist/DboBuilder/getCondition.d.ts +2 -1
  90. package/dist/DboBuilder/getCondition.d.ts.map +1 -1
  91. package/dist/DboBuilder/getCondition.js +9 -8
  92. package/dist/DboBuilder/getCondition.js.map +1 -1
  93. package/dist/DboBuilder/getSubscribeRelatedTables.d.ts.map +1 -1
  94. package/dist/DboBuilder/getSubscribeRelatedTables.js +3 -2
  95. package/dist/DboBuilder/getSubscribeRelatedTables.js.map +1 -1
  96. package/dist/DboBuilder/parseUpdateRules.d.ts.map +1 -1
  97. package/dist/DboBuilder/parseUpdateRules.js +3 -2
  98. package/dist/DboBuilder/parseUpdateRules.js.map +1 -1
  99. package/dist/DboBuilder/schema/getTablesForSchemaPostgresSQL.d.ts +2 -2
  100. package/dist/Prostgles.d.ts.map +1 -1
  101. package/dist/Prostgles.js +2 -0
  102. package/dist/Prostgles.js.map +1 -1
  103. package/dist/ProstglesContext.spec.js +25 -0
  104. package/dist/ProstglesContext.spec.js.map +1 -1
  105. package/dist/ProstglesTypes.d.ts +10 -0
  106. package/dist/ProstglesTypes.d.ts.map +1 -1
  107. package/dist/ProstglesTypes.js.map +1 -1
  108. package/dist/PubSubManager/PubSubManager.d.ts +1 -1
  109. package/dist/PublishParser/PublishParser.d.ts.map +1 -1
  110. package/dist/PublishParser/PublishParser.js +22 -4
  111. package/dist/PublishParser/PublishParser.js.map +1 -1
  112. package/dist/PublishParser/applyScopeToTableRules.d.ts +0 -1
  113. package/dist/PublishParser/applyScopeToTableRules.d.ts.map +1 -1
  114. package/dist/PublishParser/applyScopeToTableRules.js +3 -7
  115. package/dist/PublishParser/applyScopeToTableRules.js.map +1 -1
  116. package/dist/PublishParser/getFileTableRules.d.ts.map +1 -1
  117. package/dist/PublishParser/getFileTableRules.js +4 -1
  118. package/dist/PublishParser/getFileTableRules.js.map +1 -1
  119. package/dist/PublishParser/getFileVersionTableRules.d.ts +7 -0
  120. package/dist/PublishParser/getFileVersionTableRules.d.ts.map +1 -0
  121. package/dist/PublishParser/getFileVersionTableRules.js +77 -0
  122. package/dist/PublishParser/getFileVersionTableRules.js.map +1 -0
  123. package/dist/PublishParser/getFileVersionTableRules.spec.d.ts +2 -0
  124. package/dist/PublishParser/getFileVersionTableRules.spec.d.ts.map +1 -0
  125. package/dist/PublishParser/getFileVersionTableRules.spec.js +50 -0
  126. package/dist/PublishParser/getFileVersionTableRules.spec.js.map +1 -0
  127. package/dist/PublishParser/getPublishedTableNames.d.ts.map +1 -1
  128. package/dist/PublishParser/getPublishedTableNames.js +24 -1
  129. package/dist/PublishParser/getPublishedTableNames.js.map +1 -1
  130. package/dist/PublishParser/publishTypesAndUtils.d.ts +0 -4
  131. package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
  132. package/dist/PublishParser/publishTypesAndUtils.js.map +1 -1
  133. package/dist/StorageClient/deleteUnreferencedFile.d.ts.map +1 -1
  134. package/dist/StorageClient/deleteUnreferencedFile.js +17 -1
  135. package/dist/StorageClient/deleteUnreferencedFile.js.map +1 -1
  136. package/dist/StorageClient/fileTableDefinitions.d.ts +54 -0
  137. package/dist/StorageClient/fileTableDefinitions.d.ts.map +1 -0
  138. package/dist/StorageClient/fileTableDefinitions.js +38 -0
  139. package/dist/StorageClient/fileTableDefinitions.js.map +1 -0
  140. package/dist/StorageClient/fileVersionUtils.d.ts +18 -0
  141. package/dist/StorageClient/fileVersionUtils.d.ts.map +1 -0
  142. package/dist/StorageClient/fileVersionUtils.js +22 -0
  143. package/dist/StorageClient/fileVersionUtils.js.map +1 -0
  144. package/dist/StorageClient/getFileStorageKey.d.ts +3 -1
  145. package/dist/StorageClient/getFileStorageKey.d.ts.map +1 -1
  146. package/dist/StorageClient/getFileStorageKey.js +9 -1
  147. package/dist/StorageClient/getFileStorageKey.js.map +1 -1
  148. package/dist/StorageClient/getFileTableConfig.d.ts +1 -23
  149. package/dist/StorageClient/getFileTableConfig.d.ts.map +1 -1
  150. package/dist/StorageClient/getFileTableConfig.js +63 -25
  151. package/dist/StorageClient/getFileTableConfig.js.map +1 -1
  152. package/dist/StorageClient/getFileTableConfig.spec.js +6 -1
  153. package/dist/StorageClient/getFileTableConfig.spec.js.map +1 -1
  154. package/dist/StorageClient/saveFileVersion.d.ts +7 -0
  155. package/dist/StorageClient/saveFileVersion.d.ts.map +1 -0
  156. package/dist/StorageClient/saveFileVersion.js +71 -0
  157. package/dist/StorageClient/saveFileVersion.js.map +1 -0
  158. package/dist/StorageClient/setupFileServeHandler.d.ts.map +1 -1
  159. package/dist/StorageClient/setupFileServeHandler.js +38 -21
  160. package/dist/StorageClient/setupFileServeHandler.js.map +1 -1
  161. package/dist/TableConfig/TableRowFromColumnDefinitions.d.ts +11 -4
  162. package/dist/TableConfig/TableRowFromColumnDefinitions.d.ts.map +1 -1
  163. package/dist/TableConfig/getColumnSQLDefinitionQuery.d.ts.map +1 -1
  164. package/dist/TableConfig/getColumnSQLDefinitionQuery.js +1 -2
  165. package/dist/TableConfig/getColumnSQLDefinitionQuery.js.map +1 -1
  166. package/dist/TableConfig/initTableConfig.d.ts.map +1 -1
  167. package/dist/TableConfig/initTableConfig.js +9 -6
  168. package/dist/TableConfig/initTableConfig.js.map +1 -1
  169. package/dist/index.d.ts +2 -2
  170. package/dist/index.d.ts.map +1 -1
  171. package/dist/index.js +2 -1
  172. package/dist/index.js.map +1 -1
  173. package/lib/Audit/AuditTable.ts +8 -4
  174. package/lib/Audit/getAuditTableRules.ts +292 -0
  175. package/lib/Audit/getAuditTriggerConfig.ts +14 -1
  176. package/lib/DBSchemaBuilder/getClientDBGeneratedSchemas.ts +9 -1
  177. package/lib/DBSchemaBuilder/getDBGeneratedSchema.ts +1 -2
  178. package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +118 -90
  179. package/lib/DboBuilder/QueryBuilder/getJoinQuery.ts +3 -2
  180. package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +111 -194
  181. package/lib/DboBuilder/QueryBuilder/getQuerySource.ts +55 -0
  182. package/lib/DboBuilder/QueryBuilder/getSelectQuery.ts +8 -2
  183. package/lib/DboBuilder/QueryBuilder/parseJoinSelect.ts +73 -0
  184. package/lib/DboBuilder/TableHandler/TableHandler.ts +3 -6
  185. package/lib/DboBuilder/TableHandler/delete.ts +2 -1
  186. package/lib/DboBuilder/TableHandler/onDeleteFromFileTable.ts +31 -5
  187. package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +2 -1
  188. package/lib/DboBuilder/TableHandler/update.ts +2 -1
  189. package/lib/DboBuilder/TableHandler/updateFile.ts +1 -0
  190. package/lib/DboBuilder/TableHandler/uploadFile.ts +3 -0
  191. package/lib/DboBuilder/ViewHandler/ViewHandler.ts +6 -12
  192. package/lib/DboBuilder/ViewHandler/find.ts +0 -1
  193. package/lib/DboBuilder/ViewHandler/getExistsCondition.ts +35 -28
  194. package/lib/DboBuilder/ViewHandler/getRawInfo.ts +6 -2
  195. package/lib/DboBuilder/ViewHandler/getTableJoinQuery.ts +22 -14
  196. package/lib/DboBuilder/ViewHandler/prepareWhere.ts +48 -27
  197. package/lib/DboBuilder/getColumns.ts +2 -0
  198. package/lib/DboBuilder/getCondition.ts +11 -10
  199. package/lib/DboBuilder/getSubscribeRelatedTables.ts +3 -2
  200. package/lib/DboBuilder/parseUpdateRules.ts +3 -2
  201. package/lib/Prostgles.ts +1 -0
  202. package/lib/ProstglesContext.spec.ts +30 -0
  203. package/lib/ProstglesTypes.ts +11 -0
  204. package/lib/PublishParser/PublishParser.ts +47 -4
  205. package/lib/PublishParser/applyScopeToTableRules.ts +1 -7
  206. package/lib/PublishParser/getFileTableRules.ts +7 -1
  207. package/lib/PublishParser/getFileVersionTableRules.spec.ts +57 -0
  208. package/lib/PublishParser/getFileVersionTableRules.ts +106 -0
  209. package/lib/PublishParser/getPublishedTableNames.ts +33 -2
  210. package/lib/PublishParser/publishTypesAndUtils.ts +0 -5
  211. package/lib/StorageClient/deleteUnreferencedFile.ts +20 -2
  212. package/lib/StorageClient/fileTableDefinitions.ts +52 -0
  213. package/lib/StorageClient/fileVersionUtils.ts +37 -0
  214. package/lib/StorageClient/getFileStorageKey.ts +11 -2
  215. package/lib/StorageClient/getFileTableConfig.spec.ts +6 -1
  216. package/lib/StorageClient/getFileTableConfig.ts +85 -30
  217. package/lib/StorageClient/saveFileVersion.ts +82 -0
  218. package/lib/StorageClient/setupFileServeHandler.ts +51 -28
  219. package/lib/TableConfig/TableRowFromColumnDefinitions.ts +37 -13
  220. package/lib/TableConfig/getColumnSQLDefinitionQuery.ts +8 -2
  221. package/lib/TableConfig/initTableConfig.ts +10 -6
  222. package/lib/index.ts +3 -1
  223. package/package.json +1 -1
@@ -9,6 +9,7 @@ import { getReferenceColumnInserts } from "./insert/getReferenceColumnInserts";
9
9
  import { runInsertUpdateQuery } from "./runInsertUpdateQuery";
10
10
  import { lockFileForUpdate } from "./updateFile";
11
11
  import type { TableHandler } from "./TableHandler";
12
+ import { prepareWhere } from "../ViewHandler/prepareWhere";
12
13
 
13
14
  export async function update(
14
15
  this: TableHandler,
@@ -66,7 +67,7 @@ export async function update(
66
67
  );
67
68
  }
68
69
 
69
- const updateFilter = await this.prepareWhere({
70
+ const updateFilter = await prepareWhere(this, {
70
71
  select: undefined,
71
72
  filter,
72
73
  forcedFilter,
@@ -33,6 +33,7 @@ export const updateFile = async (
33
33
  data,
34
34
  localParams,
35
35
  mediaId: existingFile.id,
36
+ version: Number(existingFile.version ?? 1) + 1,
36
37
  original_last_modified,
37
38
  });
38
39
  return { newData: omitKeys(newFile, ["id"]) };
@@ -44,6 +44,7 @@ export type UploadFileArgs = TransactionCallbacks & {
44
44
  * Used to update an existing file
45
45
  */
46
46
  mediaId: string | undefined;
47
+ version?: number;
47
48
  };
48
49
 
49
50
  export const uploadFile = async (
@@ -54,6 +55,7 @@ export const uploadFile = async (
54
55
  original_last_modified,
55
56
  localParams,
56
57
  mediaId,
58
+ version,
57
59
  onCommit,
58
60
  onRollback,
59
61
  }: UploadFileArgs,
@@ -115,6 +117,7 @@ export const uploadFile = async (
115
117
  url: [fileServeRoute, coreInfo.id].join("/"),
116
118
  content_length: String(contentLength),
117
119
  data: Buffer.from([0x01]),
120
+ ...(config.versioning ? { version: version ?? 1 } : {}),
118
121
  };
119
122
 
120
123
  const isInsert = !mediaId;
@@ -13,26 +13,25 @@ import type { TableEvent } from "../../Logging";
13
13
  import type { DB } from "../../Prostgles";
14
14
  import type { Join } from "../../ProstglesTypes";
15
15
  import type { ParsedTableRule } from "../../PublishParser/PublishParser";
16
- import type { Graph } from "../joins/shortestPath";
16
+ import type { VoidFunction } from "../../SchemaWatch/SchemaWatch";
17
+ import type { TableDefinition } from "../../TableConfig/TableConfigTypes";
18
+ import type { TableHooksDefinition } from "../../TableHooks/TableHooks";
19
+ import { escapeTSNames } from "../../utils/utils";
17
20
  import type { DboBuilder, Filter, LocalParams, TableHandlers } from "../DboBuilder";
18
21
  import { getSerializedClientErrorFromPGError } from "../DboBuilder";
19
22
  import type { TableSchema } from "../DboBuilderTypes";
20
23
  import { getValidatedTableRules } from "../TableRules/getValidatedTableRules";
21
24
  import { getColumns } from "../getColumns";
25
+ import type { Graph } from "../joins/shortestPath";
22
26
  import { count } from "./count";
23
27
  import { find, type Param3 } from "./find";
28
+ import { getDbHandlerWithAbort } from "./getDbHandlerWithAbort";
24
29
  import { getInfo } from "./getInfo";
25
30
  import { parseFieldFilter } from "./parseFieldFilter";
26
- import { prepareWhere } from "./prepareWhere";
27
31
  import { size } from "./size";
28
32
  import type { OnData } from "./subscribe";
29
33
  import { subscribe } from "./subscribe";
30
34
  import { validateViewRules } from "./validateViewRules";
31
- import { escapeTSNames } from "../../utils/utils";
32
- import type { TableDefinition } from "../../TableConfig/TableConfigTypes";
33
- import { getDbHandlerWithAbort } from "./getDbHandlerWithAbort";
34
- import type { VoidFunction } from "../../SchemaWatch/SchemaWatch";
35
- import type { TableHooksDefinition } from "../../TableHooks/TableHooks";
36
35
 
37
36
  export type JoinPaths = {
38
37
  t1: string;
@@ -338,11 +337,6 @@ export class ViewHandler {
338
337
  return col_names;
339
338
  }
340
339
 
341
- /**
342
- * Parses group or simple filter
343
- */
344
- prepareWhere = prepareWhere.bind(this);
345
-
346
340
  intersectColumns(
347
341
  allowedFields: FieldFilter,
348
342
  disallowedFields: FieldFilter,
@@ -101,7 +101,6 @@ export const find = async function (
101
101
  this,
102
102
  filter,
103
103
  selectParamsLimitCheck,
104
- undefined,
105
104
  tableRules,
106
105
  localParams,
107
106
  );
@@ -1,10 +1,11 @@
1
- import type { AnyObject, EXISTS_KEY, FieldFilter } from "prostgles-types";
2
- import { EXISTS_KEYS, asName } from "prostgles-types";
3
- import type { LocalParams, ExistsFilterConfig } from "../DboBuilder";
4
- import type { ViewHandler } from "./ViewHandler";
1
+ import type { EXISTS_KEY } from "prostgles-types";
2
+ import { EXISTS_KEYS } from "prostgles-types";
5
3
  import type { ParsedTableRule } from "../../PublishParser/PublishParser";
6
- import type { TableHandler } from "../TableHandler/TableHandler";
7
- import { getTableJoinQuery } from "./getTableJoinQuery";
4
+ import type { ExistsFilterConfig, LocalParams } from "../DboBuilder";
5
+ import { getQuerySourceSQL } from "../QueryBuilder/getQuerySource";
6
+ import { getTableJoinAlias, getTableJoinQuery } from "./getTableJoinQuery";
7
+ import type { ViewHandler } from "./ViewHandler";
8
+ import { prepareWhere } from "./prepareWhere";
8
9
 
9
10
  export async function getExistsCondition(
10
11
  this: ViewHandler,
@@ -25,17 +26,22 @@ export async function getExistsCondition(
25
26
  };
26
27
  }
27
28
 
28
- let t2Rules: ParsedTableRule | undefined = undefined,
29
- forcedFilter: AnyObject | undefined,
30
- filterFields: FieldFilter | undefined;
31
-
32
29
  /* Check if allowed to view data - forcedFilters will bypass this check through isForcedFilterBypass */
33
30
  if (localParams?.isRemoteRequest && !localParams.clientReq) {
34
31
  throw "Unexpected: localParams isRemoteRequest and missing clientReq";
35
32
  }
33
+
34
+ let targetTableRules: ParsedTableRule | undefined = undefined;
36
35
  const targetTable = eConfig.isJoined ? eConfig.parsedPath.at(-1)!.table : eConfig.targetTable;
37
- if (localParams?.clientReq && this.dboBuilder.publishParser) {
38
- t2Rules = await this.dboBuilder.publishParser.getValidatedRequestRuleWusr(
36
+ const tableHandler = this.dboBuilder.dboMap.get(targetTable);
37
+ if (!tableHandler) {
38
+ throw `Table handler for ${targetTable} not found`;
39
+ }
40
+ if (localParams?.clientReq) {
41
+ if (!this.dboBuilder.publishParser) {
42
+ throw "Unexpected: missing publishParser";
43
+ }
44
+ targetTableRules = await this.dboBuilder.publishParser.getValidatedRequestRuleWusr(
39
45
  {
40
46
  tableName: targetTable,
41
47
  command: "find",
@@ -44,27 +50,27 @@ export async function getExistsCondition(
44
50
  localParams.scope,
45
51
  );
46
52
 
47
- if (!t2Rules.select) throw "Disallowed";
48
- ({ forcedFilter, filterFields } = t2Rules.select);
53
+ if (!targetTableRules.select) throw "Disallowed";
49
54
  }
50
55
 
51
- const tableHandler = this.dboBuilder.dbo[targetTable] as TableHandler;
52
- const finalWhere = (
53
- await tableHandler.prepareWhere({
54
- select: undefined,
55
- filter: targetTableFilter,
56
- forcedFilter,
57
- filterFields,
58
- addWhere: false,
59
- tableAlias: undefined,
60
- localParams,
61
- tableRule: t2Rules,
62
- })
63
- ).where;
56
+ const targetAlias =
57
+ eConfig.isJoined ? getTableJoinAlias(targetTable, eConfig.parsedPath.length - 1) : undefined;
58
+ const whereOpts = await prepareWhere(tableHandler, {
59
+ select: undefined,
60
+ selectParams: {},
61
+ filter: targetTableFilter,
62
+ forcedFilter: targetTableRules?.select?.forcedFilter,
63
+ filterFields: targetTableRules?.select?.filterFields,
64
+ tableRule: targetTableRules,
65
+ addWhere: false,
66
+ tableAlias: targetAlias,
67
+ localParams,
68
+ });
69
+ const { source: targetSource, where: finalWhere } = whereOpts;
64
70
 
65
71
  let innerQuery = [
66
72
  `SELECT 1`,
67
- `FROM ${asName(targetTable)}`,
73
+ `FROM ${getQuerySourceSQL(targetSource)}`,
68
74
  `${finalWhere ? `WHERE ${finalWhere}` : ""}`,
69
75
  ].join("\n");
70
76
 
@@ -74,6 +80,7 @@ export async function getExistsCondition(
74
80
  rootTableAlias: rootTableAlias ?? rootTable,
75
81
  type: "EXISTS",
76
82
  finalWhere,
83
+ finalTableExpression: targetSource.expression,
77
84
  });
78
85
  innerQuery = query;
79
86
  }
@@ -2,6 +2,7 @@ import { type TableInfo as TInfo } from "prostgles-types/dist";
2
2
  import type { ParsedTableRule } from "../../PublishParser/PublishParser";
3
3
  import type { LocalParams } from "../DboBuilder";
4
4
  import type { ViewHandler } from "./ViewHandler";
5
+ import { isFileVersionTable } from "../../StorageClient/fileVersionUtils";
5
6
 
6
7
  /** Table metadata before client schema customisation. */
7
8
  export function getRawInfo(
@@ -11,7 +12,9 @@ export function getRawInfo(
11
12
  localParams?: LocalParams,
12
13
  ): TInfo {
13
14
  const validatedTableRules = this.getValidatedRules(tableRules, localParams);
14
- const fileTableName = this.dboBuilder.prostgles.opts.fileTable?.tableName;
15
+ const fileTableConfig = this.dboBuilder.prostgles.opts.fileTable;
16
+ const fileTableName = fileTableConfig?.tableName;
17
+ const isVersionTable = isFileVersionTable(fileTableConfig, this.name);
15
18
  const allowedFieldsToSelect = this.parseFieldFilter(tableRules?.select?.fields);
16
19
  const { requiredNestedInserts, allowedNestedInserts } = tableRules?.insert ?? {};
17
20
  const label = this.dboBuilder.prostgles.tableConfigurator?.getTableLabel({
@@ -32,10 +35,11 @@ export function getRawInfo(
32
35
  isView: this.isView,
33
36
  hasFiles: Boolean(
34
37
  !this.is_media &&
38
+ !isVersionTable &&
35
39
  fileTableName &&
36
40
  this.columns.some((c) => c.references?.some((r) => r.ftable === fileTableName)),
37
41
  ),
38
- fileTableName,
42
+ fileTableName: isVersionTable ? undefined : fileTableName,
39
43
  dynamicRules: {
40
44
  update: Boolean(tableRules?.update?.dynamicFields?.length),
41
45
  },
@@ -1,10 +1,12 @@
1
1
  import { asName } from "prostgles-types";
2
+ import type { PGIdentifier } from "../DboBuilder";
2
3
  import type { ParsedJoinPath } from "./parseJoinPath";
3
4
 
4
5
  type getTableJoinsArgs = {
5
6
  rootTableAlias: string;
6
7
  type: "INNER" | "LEFT" | "EXISTS";
7
8
  finalWhere?: string;
9
+ finalTableExpression?: string;
8
10
  path: ParsedJoinPath[];
9
11
  };
10
12
  export const getTableJoinQuery = ({
@@ -12,14 +14,14 @@ export const getTableJoinQuery = ({
12
14
  type,
13
15
  rootTableAlias,
14
16
  finalWhere,
17
+ finalTableExpression,
15
18
  }: getTableJoinsArgs): { targetAlias: string; query: string } => {
16
19
  const [firstPath] = path;
17
20
  if (!firstPath) {
18
21
  throw `Cannot create join query for empty path`;
19
22
  }
20
- const aliasSufix = "jd";
21
23
  const getTableAlias = (table: string, pathIndex: number) =>
22
- asName(`${aliasSufix}_${pathIndex}_${table}`);
24
+ getTableJoinAlias(table, pathIndex).escaped;
23
25
 
24
26
  const query = path
25
27
  .map(({ table, on }, i) => {
@@ -45,19 +47,19 @@ export const getTableJoinQuery = ({
45
47
  */
46
48
  const whereJoinCondition =
47
49
  isLast && isExists ?
48
- `WHERE (${getJoinOnCondition({
49
- on: firstPath.on,
50
- leftAlias: rootTableAlias,
51
- rightAlias: getTableAlias(firstPath.table, 0),
52
- })})`
50
+ `WHERE (${[
51
+ getJoinOnCondition({
52
+ on: firstPath.on,
53
+ leftAlias: rootTableAlias,
54
+ rightAlias: getTableAlias(firstPath.table, 0),
55
+ }),
56
+ finalWhere,
57
+ ]
58
+ .filter(Boolean)
59
+ .join(") AND (")})`
53
60
  : "";
54
61
 
55
- const tableSelect =
56
- isExists && isLast ?
57
- [`(`, ` SELECT *`, ` FROM ${tableName}`, finalWhere ? ` WHERE ${finalWhere}` : "", `)`]
58
- .filter((v) => v)
59
- .join("\n")
60
- : tableName;
62
+ const tableSelect = isLast ? (finalTableExpression ?? tableName) : tableName;
61
63
  if (isExists && isFirst) {
62
64
  return [`SELECT 1`, `FROM ${tableSelect} ${tableAlias}`, whereJoinCondition]
63
65
  .filter((v) => v)
@@ -76,6 +78,12 @@ export const getTableJoinQuery = ({
76
78
  };
77
79
  };
78
80
 
81
+ export const getTableJoinAlias = (table: string, pathIndex: number): PGIdentifier => {
82
+ const prefix = "jd";
83
+ const raw = `${prefix}_${pathIndex}_${table}`;
84
+ return { raw, escaped: asName(raw) };
85
+ };
86
+
79
87
  type GetJoinOnConditionArgs = {
80
88
  on: Record<string, string>[];
81
89
  leftAlias: string;
@@ -95,7 +103,7 @@ export const getJoinOnConditions = ({
95
103
  .map(([leftCol, rightCol]) => {
96
104
  return `${leftAlias}.${getLeftColName(leftCol)} = ${rightAlias}.${getRightColName(rightCol)}`;
97
105
  })
98
- .join(" AND ")
106
+ .join(" AND "),
99
107
  );
100
108
  };
101
109
 
@@ -1,9 +1,10 @@
1
- import type { AnyObject, FieldFilter } from "prostgles-types/dist";
1
+ import type { AnyObject, FieldFilter, SelectParams } from "prostgles-types/dist";
2
2
  import { getKeys, isDefined, isObject } from "prostgles-types/dist";
3
3
  import type { ParsedTableRule } from "../../PublishParser/PublishParser";
4
4
  import type { ExistsFilterConfig, Filter, LocalParams, PGIdentifier } from "../DboBuilder";
5
5
  import { getCondition } from "../getCondition";
6
6
  import { type SelectItemValidated } from "../QueryBuilder/QueryBuilder";
7
+ import { getQuerySource, type QuerySource } from "../QueryBuilder/getQuerySource";
7
8
  import type { ViewHandler } from "./ViewHandler";
8
9
 
9
10
  export type PrepareWhereParams = {
@@ -16,46 +17,61 @@ export type PrepareWhereParams = {
16
17
  localParams: LocalParams | undefined;
17
18
  tableRule: ParsedTableRule | undefined;
18
19
  isHaving?: boolean;
20
+ selectParams?: SelectParams;
19
21
  };
20
22
 
21
- export async function prepareWhere(
22
- this: ViewHandler,
23
- params: PrepareWhereParams,
24
- ): Promise<{
23
+ export type WhereOptions = {
25
24
  columnsUsed: string[];
26
25
  condition: string;
27
26
  where: string;
28
27
  filter: AnyObject;
29
28
  exists: ExistsFilterConfig[];
30
- }> {
31
- const {
29
+ source: QuerySource;
30
+ };
31
+
32
+ export const prepareWhere = async (
33
+ viewHandler: ViewHandler,
34
+ {
32
35
  filter,
33
36
  select,
34
37
  forcedFilter,
35
- filterFields: ff,
36
38
  addWhere: addKeywords = true,
37
39
  tableAlias,
38
40
  localParams,
39
41
  tableRule,
40
- } = params;
41
- const { $and: $and_key, $or: $or_key } = this.dboBuilder.prostgles.keywords;
42
+ /* Local update allow all. TODO: tidy all calls */
43
+ filterFields = !tableRule ? "*" : undefined,
44
+ isHaving,
45
+ selectParams,
46
+ }: PrepareWhereParams,
47
+ ): Promise<WhereOptions> => {
48
+ const { $and: $and_key, $or: $or_key } = viewHandler.dboBuilder.prostgles.keywords;
49
+
50
+ if (localParams?.isRemoteRequest && !tableRule) {
51
+ throw "Unexpected: localParams isRemoteRequest and missing tableRule";
52
+ }
42
53
 
43
- let filterFields = ff;
44
- /* Local update allow all. TODO -> FIX THIS */
45
- if (!ff && !tableRule) filterFields = "*";
54
+ const source = await getQuerySource(
55
+ viewHandler,
56
+ selectParams ? tableRule : undefined,
57
+ filter ?? {},
58
+ selectParams ?? {},
59
+ tableAlias,
60
+ );
46
61
 
47
62
  const exists: ExistsFilterConfig[] = [];
48
63
 
49
64
  type FilterItemResult = { condition: string; columnsUsed: string[] };
50
65
  const parseFullFilter = async (
51
- f: any,
66
+ fullFilter: any,
52
67
  parentFilter: AnyObject | null = null,
53
68
  isForcedFilterBypass: boolean,
54
69
  ): Promise<FilterItemResult | undefined> => {
55
- if (!f) throw "Invalid/missing group filter provided";
56
- if (!isObject(f)) throw "\nInvalid filter\nExpecting an object but got -> " + JSON.stringify(f);
70
+ if (!fullFilter) throw "Invalid/missing group filter provided";
71
+ if (!isObject(fullFilter))
72
+ throw "\nInvalid filter\nExpecting an object but got -> " + JSON.stringify(fullFilter);
57
73
 
58
- const keys = getKeys(f);
74
+ const keys = getKeys(fullFilter);
59
75
  if (!keys.length) {
60
76
  return;
61
77
  }
@@ -66,8 +82,8 @@ export async function prepareWhere(
66
82
  throw "group filter ($and/$or) can only be placed at the root or within another group filter";
67
83
  }
68
84
 
69
- const { [$and_key]: $and, [$or_key]: $or } = f,
70
- group: AnyObject[] | undefined = $and || $or;
85
+ const { [$and_key]: $and, [$or_key]: $or } = fullFilter;
86
+ const group = ($and || $or) as AnyObject[] | undefined;
71
87
 
72
88
  if (group && group.length) {
73
89
  const operand = $and ? " AND " : " OR ";
@@ -82,20 +98,24 @@ export async function prepareWhere(
82
98
  if (conditionItems.length) {
83
99
  const conditions = conditionItems.map((c) => c.condition);
84
100
  const columnsUsed = conditionItems.map((c) => c.columnsUsed).flat();
85
- if (conditions.length === 1) return { columnsUsed, condition: conditions.join(operand) };
86
- else return { columnsUsed, condition: ` ( ${conditions.sort().join(operand)} ) ` };
101
+ if (conditions.length === 1) {
102
+ return { columnsUsed, condition: conditions.join(operand) };
103
+ }
104
+ return { columnsUsed, condition: ` ( ${conditions.sort().join(operand)} ) ` };
87
105
  }
88
106
  } else if (!group) {
89
107
  /** forcedFilters do not get checked against publish and are treated as server-side requests */
90
- const itemInfo = await getCondition.bind(this)({
91
- filter: { ...f },
108
+ const itemInfo = await getCondition.bind(viewHandler)({
109
+ filter: { ...fullFilter },
92
110
  select,
93
111
  allowed_colnames:
94
- isForcedFilterBypass ? this.column_names.slice(0) : this.parseFieldFilter(filterFields),
95
- tableAlias,
112
+ isForcedFilterBypass ?
113
+ viewHandler.column_names.slice(0)
114
+ : viewHandler.parseFieldFilter(filterFields),
115
+ tableAlias: source.alias,
96
116
  localParams: isForcedFilterBypass ? undefined : localParams,
97
117
  tableRules: isForcedFilterBypass ? undefined : tableRule,
98
- isHaving: params.isHaving,
118
+ isHaving,
99
119
  });
100
120
  exists.push(...itemInfo.exists);
101
121
  return {
@@ -135,5 +155,6 @@ export async function prepareWhere(
135
155
  where: combinedConditions || "",
136
156
  filter: finalFilter,
137
157
  exists,
158
+ source,
138
159
  };
139
- }
160
+ };
@@ -6,6 +6,7 @@ import { getErrorAsObject, getSerializedClientErrorFromPGError } from "./DboBuil
6
6
  import type { TableHandler } from "./TableHandler/TableHandler";
7
7
  import type { ViewHandler } from "./ViewHandler/ViewHandler";
8
8
  import { getRawInfo } from "./ViewHandler/getRawInfo";
9
+ import { isFileVersionTable } from "../StorageClient/fileVersionUtils";
9
10
 
10
11
  export const isTableHandler = (v: any): v is TableHandler => "parseUpdateRules" in v;
11
12
 
@@ -173,6 +174,7 @@ const getFileColumnInfo = (args: {
173
174
  if (!fileTableConfig) return undefined;
174
175
  const { colName, tableHandler } = args;
175
176
  const tableName = tableHandler.name;
177
+ if (isFileVersionTable(fileTableConfig, tableName)) return undefined;
176
178
  const tableConfig = fileTableConfig.referencedTables?.[tableName];
177
179
  const isReferencingFileTable = tableHandler.columns.some(
178
180
  (c) =>
@@ -1,4 +1,4 @@
1
- import { pickKeys } from "prostgles-types";
1
+ import { pickKeys, type AnyObject } from "prostgles-types";
2
2
  import { parseFilterItem } from "../Filtering/Filtering";
3
3
  import type { ParsedTableRule } from "../PublishParser/PublishParser";
4
4
  import type { ExistsFilterConfig, LocalParams, PGIdentifier } from "./DboBuilder";
@@ -9,6 +9,7 @@ import type { ViewHandler } from "./ViewHandler/ViewHandler";
9
9
  import { getExistsCondition } from "./ViewHandler/getExistsCondition";
10
10
  import { getExistsFilters } from "./ViewHandler/getExistsFilters";
11
11
  import { parseComplexFilter } from "./ViewHandler/parseComplexFilter";
12
+ import { isArray } from "../utils/utils";
12
13
 
13
14
  const FILTER_FUNCS = FUNCTIONS.filter((f) => f.canBeUsedForFilter);
14
15
 
@@ -21,7 +22,7 @@ const FILTER_FUNCS = FUNCTIONS.filter((f) => f.canBeUsedForFilter);
21
22
  export async function getCondition(
22
23
  this: ViewHandler,
23
24
  params: {
24
- filter: any;
25
+ filter: AnyObject;
25
26
  select: SelectItemValidated[] | undefined;
26
27
  allowed_colnames: string[];
27
28
  tableAlias?: PGIdentifier;
@@ -44,21 +45,21 @@ export async function getCondition(
44
45
 
45
46
  const existsConfigs = getExistsFilters(filter, this);
46
47
 
47
- const funcConds: string[] = [];
48
+ const functionConditions: string[] = [];
48
49
  const funcFilter = FILTER_FUNCS.filter((f) => f.name in filter);
49
50
 
50
51
  funcFilter.map((f) => {
51
52
  const funcArgs = filter[f.name];
52
- if (!Array.isArray(funcArgs)) {
53
+ if (!isArray(funcArgs)) {
53
54
  throw `A function filter must contain an array. E.g: { $funcFilterName: ["col1"] } \n but got: ${JSON.stringify(pickKeys(filter, [f.name]))} `;
54
55
  }
55
56
  const fields = this.parseFieldFilter(f.getFields(funcArgs), true, allowed_colnames);
56
57
 
57
- const dissallowedCols = fields.filter((fname) => !allowed_colnames.includes(fname));
58
- if (dissallowedCols.length) {
59
- throw `Invalid/disallowed columns found in function filter: ${dissallowedCols}`;
58
+ const disallowedCols = fields.filter((fname) => !allowed_colnames.includes(fname));
59
+ if (disallowedCols.length) {
60
+ throw `Invalid/disallowed columns found in function filter: ${disallowedCols}`;
60
61
  }
61
- funcConds.push(
62
+ functionConditions.push(
62
63
  f.getQuery({
63
64
  args: funcArgs,
64
65
  allColumns: this.columns,
@@ -84,7 +85,7 @@ export async function getCondition(
84
85
  const p = this.getValidatedRules(tableRules, localParams);
85
86
  const computedFields = p.allColumns.filter((c) => c.type === "computed");
86
87
  const computedColConditions: string[] = [];
87
- Object.keys(filter || {}).map((key) => {
88
+ Object.keys(filter).map((key) => {
88
89
  const compCol = computedFields.find((cf) => cf.name === key);
89
90
  if (compCol) {
90
91
  if (!p.select) throw new Error("Computed column filter requires p.select.fields");
@@ -231,7 +232,7 @@ export async function getCondition(
231
232
  let templates: string[] = q?.condition ? [q.condition] : [];
232
233
 
233
234
  if (existsCond) templates.push(existsCond);
234
- templates = templates.concat(funcConds);
235
+ templates = templates.concat(functionConditions);
235
236
  templates = templates.concat(computedColConditions);
236
237
  templates = templates.concat(complexFilters);
237
238
 
@@ -8,6 +8,7 @@ import type { TableHandler } from "./TableHandler/TableHandler";
8
8
  import type { ViewHandler } from "./ViewHandler/ViewHandler";
9
9
  import { getViewRelatedTables } from "./ViewRelatedTables/getViewRelatedTables";
10
10
  import type { AddTriggerParams } from "../PubSubManager/addTrigger";
11
+ import { prepareWhere } from "./ViewHandler/prepareWhere";
11
12
 
12
13
  type Args = {
13
14
  selectParams: Omit<SubscribeParams, "throttle">;
@@ -66,9 +67,9 @@ export async function getSubscribeRelatedTables(
66
67
  isEmpty(targetTableFilter) ? reversedJoinFilter : (
67
68
  { $and: [targetTableFilter, reversedJoinFilter] }
68
69
  );
69
- const joinConditionInfo = await relatedTableOrViewHandler.prepareWhere({
70
- select: undefined,
70
+ const joinConditionInfo = await prepareWhere(relatedTableOrViewHandler, {
71
71
  filter,
72
+ select: undefined,
72
73
  addWhere: false,
73
74
  localParams: undefined,
74
75
  tableRule: undefined,
@@ -9,6 +9,7 @@ import { type ParsedTableRule } from "../PublishParser/PublishParser";
9
9
  import type { Filter, LocalParams } from "./DboBuilder";
10
10
  import { prepareNewData } from "./TableHandler/DataValidator";
11
11
  import type { TableHandler } from "./TableHandler/TableHandler";
12
+ import { prepareWhere } from "./ViewHandler/prepareWhere";
12
13
 
13
14
  /**
14
15
  * 1) Check if publish is valid
@@ -57,7 +58,7 @@ export async function parseUpdateRules(
57
58
  throw ` Invalid update rule fo r ${this.name}. fields missing `;
58
59
  }
59
60
  finalUpdateFilter = (
60
- await this.prepareWhere({
61
+ await prepareWhere(this, {
61
62
  select: undefined,
62
63
  filter,
63
64
  forcedFilter,
@@ -77,7 +78,7 @@ export async function parseUpdateRules(
77
78
  /**
78
79
  * Validated filter and fields
79
80
  */
80
- const condition = await this.prepareWhere({
81
+ const condition = await prepareWhere(this, {
81
82
  select: undefined,
82
83
  filterFields: this.column_names,
83
84
  filter: dfRule.filter,
package/lib/Prostgles.ts CHANGED
@@ -320,6 +320,7 @@ export class Prostgles {
320
320
  this.dboBuilder = await DboBuilder.create(this);
321
321
  }
322
322
  this.dbo = this.dboBuilder.dbo;
323
+ if (this.publishParser) this.initPublishParser();
323
324
  await this.opts.onLog?.({
324
325
  type: "debug",
325
326
  command: "refreshDBO.end",
@@ -2,6 +2,7 @@ import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
3
  import type { DboBuilder } from "./DboBuilder/DboBuilder";
4
4
  import { Prostgles } from "./Prostgles";
5
+ import type { PublishParser } from "./PublishParser/PublishParser";
5
6
 
6
7
  void describe("Prostgles context", async () => {
7
8
  await test("recreates context and runs cleanups in reverse order", async () => {
@@ -47,6 +48,35 @@ void describe("Prostgles context", async () => {
47
48
  assert.equal(prostgles.context, undefined);
48
49
  });
49
50
 
51
+ await test("recreates the publish parser with the rebuilt DBO", async () => {
52
+ const prostgles = new Prostgles({
53
+ dbConnection: "postgres://unused",
54
+ onReady: () => {},
55
+ });
56
+ prostgles.db = {} as typeof prostgles.db;
57
+ const rebuiltDbo = {};
58
+ const dboBuilder = {
59
+ build: () => {
60
+ dboBuilder.dbo = rebuiltDbo;
61
+ return Promise.resolve();
62
+ },
63
+ dbo: {},
64
+ sql: {},
65
+ tables: [],
66
+ };
67
+ prostgles.dboBuilder = dboBuilder as unknown as DboBuilder;
68
+
69
+ // PublishParser captures the DBO on construction, so it must be recreated after a rebuild.
70
+ const initialPublishParser = {} as PublishParser;
71
+ prostgles.publishParser = initialPublishParser;
72
+
73
+ await prostgles.rebuildDBO();
74
+
75
+ assert.equal(prostgles.dbo, rebuiltDbo);
76
+ assert.notEqual(prostgles.publishParser, initialPublishParser);
77
+ assert.equal(prostgles.publishParser.dbo, prostgles.dbo);
78
+ });
79
+
50
80
  await test("cleans partially-created context after an error", async () => {
51
81
  const events: string[] = [];
52
82
  const prostgles = new Prostgles({
@@ -70,6 +70,17 @@ export type FileTableConfig = {
70
70
  checkIntervalHours?: number;
71
71
  };
72
72
 
73
+ /**
74
+ * Keeps immutable metadata records for every uploaded file revision.
75
+ * Existing file IDs and URLs continue to resolve to the latest version.
76
+ */
77
+ versioning?: {
78
+ /** Defaults to `${tableName}_versions`. */
79
+ tableName?: string;
80
+ /** Maximum versions kept per file. Undefined keeps every version. */
81
+ maxVersions?: number;
82
+ };
83
+
73
84
  /**
74
85
  * Specifying referencedTables with referenceColumns allows restricting the
75
86
  * allowed file types that can be inserted and referenced in the specified tables.