prostgles-server 4.2.607 → 4.2.608
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/README.md +0 -29
- package/dist/Audit/AuditTable.d.ts +5 -4
- package/dist/Audit/AuditTable.d.ts.map +1 -1
- package/dist/Audit/AuditTable.js +1 -1
- package/dist/Audit/AuditTable.js.map +1 -1
- package/dist/Audit/getAuditTableConfig.d.ts +1 -6
- package/dist/Audit/getAuditTableConfig.d.ts.map +1 -1
- package/dist/Audit/getAuditTableConfig.js +21 -29
- package/dist/Audit/getAuditTableConfig.js.map +1 -1
- package/dist/Audit/parseAuditConfig.d.ts +5 -3
- package/dist/Audit/parseAuditConfig.d.ts.map +1 -1
- package/dist/Audit/parseAuditConfig.js +33 -59
- package/dist/Audit/parseAuditConfig.js.map +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.d.ts +37 -2
- package/dist/DboBuilder/TableHandler/updateFile.d.ts.map +1 -1
- package/dist/Prostgles.d.ts +0 -2
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +1 -2
- package/dist/Prostgles.js.map +1 -1
- package/dist/StorageClient/getFileTableConfig.d.ts +2 -4
- package/dist/StorageClient/getFileTableConfig.d.ts.map +1 -1
- package/dist/StorageClient/getFileTableConfig.js.map +1 -1
- package/dist/TableConfig/TableRowFromColumnDefinitions.d.ts +12 -0
- package/dist/TableConfig/TableRowFromColumnDefinitions.d.ts.map +1 -0
- package/dist/TableConfig/TableRowFromColumnDefinitions.js +3 -0
- package/dist/TableConfig/TableRowFromColumnDefinitions.js.map +1 -0
- package/dist/TableConfig/getTableTriggerQueries.d.ts.map +1 -1
- package/dist/TableConfig/getTableTriggerQueries.js +1 -3
- package/dist/TableConfig/getTableTriggerQueries.js.map +1 -1
- package/dist/TableConfig/managedTriggerNames.d.ts.map +1 -1
- package/dist/TableConfig/managedTriggerNames.js +0 -1
- package/dist/TableConfig/managedTriggerNames.js.map +1 -1
- package/dist/TableConfig/syncTableTriggers.d.ts.map +1 -1
- package/dist/TableConfig/syncTableTriggers.js +16 -19
- package/dist/TableConfig/syncTableTriggers.js.map +1 -1
- package/lib/Audit/AuditTable.ts +4 -9
- package/lib/Audit/getAuditTableConfig.ts +21 -41
- package/lib/Audit/parseAuditConfig.ts +41 -98
- package/lib/Prostgles.ts +2 -3
- package/lib/StorageClient/getFileTableConfig.ts +2 -13
- package/lib/TableConfig/TableRowFromColumnDefinitions.ts +19 -0
- package/lib/TableConfig/getTableTriggerQueries.ts +1 -4
- package/lib/TableConfig/managedTriggerNames.ts +0 -1
- package/lib/TableConfig/syncTableTriggers.ts +21 -32
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTableTriggerQueries.d.ts","sourceRoot":"","sources":["../../lib/TableConfig/getTableTriggerQueries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"getTableTriggerQueries.d.ts","sourceRoot":"","sources":["../../lib/TableConfig/getTableTriggerQueries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMtD,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,GACjC,IAAI,EAAE,EACN,YAAY,MAAM,EAClB,aAAa,WAAW,CAAC,MAAM,CAAC,KAC/B,OAAO,CAAC,MAAM,EAAE,CAoGlB,CAAC"}
|
|
@@ -72,9 +72,7 @@ const getTableTriggerQueries = async (db, tableIdent, tableConfig) => {
|
|
|
72
72
|
}
|
|
73
73
|
for (const trigger of existing) {
|
|
74
74
|
const managed = (0, managedTriggerNames_1.isManagedTriggerName)(trigger.name);
|
|
75
|
-
|
|
76
|
-
const protectsHistory = trigger.name.startsWith(managedTriggerNames_1.AUDIT_HISTORY_PROTECTION_PREFIX);
|
|
77
|
-
if (managed && !protectsHistory && !desired.has(trigger.name)) {
|
|
75
|
+
if (managed && !desired.has(trigger.name)) {
|
|
78
76
|
queries.push(`DROP TRIGGER ${(0, prostgles_types_1.asName)(trigger.name)} ON ${tableIdent};`);
|
|
79
77
|
}
|
|
80
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTableTriggerQueries.js","sourceRoot":"","sources":["../../lib/TableConfig/getTableTriggerQueries.ts"],"names":[],"mappings":";;;AAAA,2CAAgC;AAEhC,qDAAyC;AAEzC,+
|
|
1
|
+
{"version":3,"file":"getTableTriggerQueries.js","sourceRoot":"","sources":["../../lib/TableConfig/getTableTriggerQueries.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managedTriggerNames.d.ts","sourceRoot":"","sources":["../../lib/TableConfig/managedTriggerNames.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,2BAA2B,4BAA4B,CAAC;AACrE,eAAO,MAAM,oBAAoB,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"managedTriggerNames.d.ts","sourceRoot":"","sources":["../../lib/TableConfig/managedTriggerNames.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,2BAA2B,4BAA4B,CAAC;AACrE,eAAO,MAAM,oBAAoB,qBAAqB,CAAC;AACvD,eAAO,MAAM,+BAA+B,QAAkC,CAAC;AAC/E,eAAO,MAAM,gCAAgC,QAAkC,CAAC;AAChF,eAAO,MAAM,mBAAmB,QAAkC,CAAC;AAEnE,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,YACsC,CAAC;AAExF,eAAO,MAAM,qBAAqB,GAAI,cAAc,MAAM,EAAE,QAAQ,MAAM,WACqD,CAAC"}
|
|
@@ -6,7 +6,6 @@ const md5_1 = require("prostgles-types/dist/md5");
|
|
|
6
6
|
// Keep generated names within PostgreSQL's 63-byte identifier limit.
|
|
7
7
|
exports.TABLE_CONFIG_TRIGGER_PREFIX = "prostgles_table_config_";
|
|
8
8
|
exports.AUDIT_TRIGGER_PREFIX = "prostgles_audit_";
|
|
9
|
-
// History protection survives removing or changing the audit configuration.
|
|
10
9
|
exports.AUDIT_HISTORY_PROTECTION_PREFIX = exports.AUDIT_TRIGGER_PREFIX + "guard_";
|
|
11
10
|
exports.AUDIT_TRUNCATE_PROTECTION_PREFIX = exports.AUDIT_TRIGGER_PREFIX + "block_";
|
|
12
11
|
exports.AUDIT_WRITER_PREFIX = exports.AUDIT_TRIGGER_PREFIX + "write_";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managedTriggerNames.js","sourceRoot":"","sources":["../../lib/TableConfig/managedTriggerNames.ts"],"names":[],"mappings":";;;AAAA,kDAA+C;AAE/C,6EAA6E;AAC7E,qEAAqE;AACxD,QAAA,2BAA2B,GAAG,yBAAyB,CAAC;AACxD,QAAA,oBAAoB,GAAG,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"managedTriggerNames.js","sourceRoot":"","sources":["../../lib/TableConfig/managedTriggerNames.ts"],"names":[],"mappings":";;;AAAA,kDAA+C;AAE/C,6EAA6E;AAC7E,qEAAqE;AACxD,QAAA,2BAA2B,GAAG,yBAAyB,CAAC;AACxD,QAAA,oBAAoB,GAAG,kBAAkB,CAAC;AAC1C,QAAA,+BAA+B,GAAG,4BAAoB,GAAG,QAAQ,CAAC;AAClE,QAAA,gCAAgC,GAAG,4BAAoB,GAAG,QAAQ,CAAC;AACnE,QAAA,mBAAmB,GAAG,4BAAoB,GAAG,QAAQ,CAAC;AAE5D,MAAM,oBAAoB,GAAG,CAAC,IAAY,EAAE,EAAE,CACnD,IAAI,CAAC,UAAU,CAAC,mCAA2B,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,4BAAoB,CAAC,CAAC;AAD3E,QAAA,oBAAoB,wBACuD;AAEjF,MAAM,qBAAqB,GAAG,CAAC,YAAoB,EAAE,MAAc,EAAE,EAAE,CAC5E,GAAG,YAAY,CAAC,UAAU,CAAC,4BAAoB,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,mCAA2B,GAAG,IAAA,SAAG,EAAC,YAAY,CAAC,IAAI,MAAM,EAAE,CAAC;AADnH,QAAA,qBAAqB,yBAC8F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncTableTriggers.d.ts","sourceRoot":"","sources":["../../lib/TableConfig/syncTableTriggers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,yFAAyF;AACzF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"syncTableTriggers.d.ts","sourceRoot":"","sources":["../../lib/TableConfig/syncTableTriggers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,yFAAyF;AACzF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,SAAS,iBAwBtD"}
|
|
@@ -6,27 +6,24 @@ const PubSubManagerUtils_1 = require("../PubSubManager/PubSubManagerUtils");
|
|
|
6
6
|
const getTableTriggerQueries_1 = require("./getTableTriggerQueries");
|
|
7
7
|
/** Applies application and generated audit triggers together, after all tables exist. */
|
|
8
8
|
async function syncTableTriggers(prgl) {
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
for (const name of Object.keys(config)) {
|
|
16
|
-
if (!prgl.dboBuilder.tables.some((t) => t.name === name)) {
|
|
17
|
-
throw new Error(`Table config name must exactly match a schema table name: ${name}`);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
for (const table of prgl.dboBuilder.tables) {
|
|
21
|
-
queries.push(...(await (0, getTableTriggerQueries_1.getTableTriggerQueries)(prgl.dbForSchema, table.escaped_identifier, { triggers: config[table.name]?.triggers })));
|
|
22
|
-
}
|
|
23
|
-
if (queries.length) {
|
|
24
|
-
await prgl.dbForSchema.tx((tx) => tx.none(`/* ${PubSubManagerUtils_1.EXCLUDE_QUERY_FROM_SCHEMA_WATCH_ID} */\n${queries.join("\n")}`));
|
|
9
|
+
const auditConfig = (0, parseAuditConfig_1.parseAuditConfig)(prgl);
|
|
10
|
+
const config = prgl.mergedTableConfig.tableConfig ?? {};
|
|
11
|
+
const queries = [];
|
|
12
|
+
for (const name of Object.keys(config)) {
|
|
13
|
+
if (!prgl.dboBuilder.tables.some((t) => t.name === name)) {
|
|
14
|
+
throw new Error(`Table config name must exactly match a schema table name: ${name}`);
|
|
25
15
|
}
|
|
26
16
|
}
|
|
27
|
-
|
|
28
|
-
prgl.
|
|
29
|
-
|
|
17
|
+
for (const table of prgl.dboBuilder.tables) {
|
|
18
|
+
queries.push(...(await (0, getTableTriggerQueries_1.getTableTriggerQueries)(prgl.dbForSchema, table.escaped_identifier, {
|
|
19
|
+
triggers: {
|
|
20
|
+
...config[table.name]?.triggers,
|
|
21
|
+
...auditConfig?.[table.name]?.triggers,
|
|
22
|
+
},
|
|
23
|
+
})));
|
|
24
|
+
}
|
|
25
|
+
if (queries.length) {
|
|
26
|
+
await prgl.dbForSchema.tx((tx) => tx.none(`/* ${PubSubManagerUtils_1.EXCLUDE_QUERY_FROM_SCHEMA_WATCH_ID} */\n${queries.join("\n")}`));
|
|
30
27
|
}
|
|
31
28
|
}
|
|
32
29
|
//# sourceMappingURL=syncTableTriggers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncTableTriggers.js","sourceRoot":"","sources":["../../lib/TableConfig/syncTableTriggers.ts"],"names":[],"mappings":";;AAMA,
|
|
1
|
+
{"version":3,"file":"syncTableTriggers.js","sourceRoot":"","sources":["../../lib/TableConfig/syncTableTriggers.ts"],"names":[],"mappings":";;AAMA,8CAwBC;AA9BD,gEAA6D;AAE7D,4EAAyF;AACzF,qEAAkE;AAElE,yFAAyF;AAClF,KAAK,UAAU,iBAAiB,CAAC,IAAe;IACrD,MAAM,WAAW,GAAG,IAAA,mCAAgB,EAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,IAAI,EAAE,CAAC;IACxD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CAAC,6DAA6D,IAAI,EAAE,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QAC3C,OAAO,CAAC,IAAI,CACV,GAAG,CAAC,MAAM,IAAA,+CAAsB,EAAC,IAAI,CAAC,WAAY,EAAE,KAAK,CAAC,kBAAkB,EAAE;YAC5E,QAAQ,EAAE;gBACR,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ;gBAC/B,GAAG,WAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ;aACvC;SACF,CAAC,CAAC,CACJ,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,IAAI,CAAC,WAAY,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAChC,EAAE,CAAC,IAAI,CAAC,MAAM,uDAAkC,QAAQ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAC9E,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/lib/Audit/AuditTable.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import type { TableRowFromColumnDefinitions } from "../TableConfig/TableRowFromColumnDefinitions";
|
|
2
|
+
|
|
1
3
|
export const AUDIT_TABLE_COLUMN_DEFINITIONS = {
|
|
2
4
|
id: "BIGSERIAL PRIMARY KEY",
|
|
3
5
|
created_at: "TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp()",
|
|
4
6
|
schema_name: "TEXT NOT NULL",
|
|
5
7
|
table_name: "TEXT NOT NULL",
|
|
6
8
|
entity_type: "TEXT NOT NULL",
|
|
7
|
-
operation:
|
|
8
|
-
"TEXT NOT NULL CHECK (operation IN ('INSERT', 'UPDATE', 'DELETE'))",
|
|
9
|
+
operation: { enum: ["INSERT", "UPDATE", "DELETE"] },
|
|
9
10
|
old_id: "JSONB",
|
|
10
11
|
new_id: "JSONB",
|
|
11
12
|
old_row: "JSONB",
|
|
@@ -13,13 +14,7 @@ export const AUDIT_TABLE_COLUMN_DEFINITIONS = {
|
|
|
13
14
|
actor: "JSONB",
|
|
14
15
|
} as const;
|
|
15
16
|
|
|
16
|
-
export type AuditTableRow =
|
|
17
|
-
[K in keyof typeof AUDIT_TABLE_COLUMN_DEFINITIONS]: K extends "operation"
|
|
18
|
-
? "INSERT" | "UPDATE" | "DELETE"
|
|
19
|
-
: (typeof AUDIT_TABLE_COLUMN_DEFINITIONS)[K] extends "JSONB"
|
|
20
|
-
? Record<string, unknown> | null
|
|
21
|
-
: string;
|
|
22
|
-
};
|
|
17
|
+
export type AuditTableRow = TableRowFromColumnDefinitions<typeof AUDIT_TABLE_COLUMN_DEFINITIONS>;
|
|
23
18
|
export const AUDIT_TABLE_COLUMNS = Object.keys(
|
|
24
19
|
AUDIT_TABLE_COLUMN_DEFINITIONS,
|
|
25
20
|
) as (keyof AuditTableRow)[];
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { md5 } from "prostgles-types/dist/md5";
|
|
2
2
|
import type { Prostgles } from "../Prostgles";
|
|
3
|
-
import type {
|
|
4
|
-
TableConfig,
|
|
5
|
-
TableDefinition,
|
|
6
|
-
} from "../TableConfig/TableConfigTypes";
|
|
3
|
+
import type { TableConfig, TableDefinition } from "../TableConfig/TableConfigTypes";
|
|
7
4
|
|
|
8
5
|
import { AUDIT_TABLE_COLUMN_DEFINITIONS } from "./AuditTable";
|
|
9
6
|
import {
|
|
@@ -12,20 +9,14 @@ import {
|
|
|
12
9
|
AUDIT_WRITER_PREFIX,
|
|
13
10
|
} from "../TableConfig/managedTriggerNames";
|
|
14
11
|
|
|
15
|
-
export type ParsedAuditConfig = {
|
|
16
|
-
/** Includes previously configured history tables, whose protection is retained. */
|
|
17
|
-
auditTableNames: string[];
|
|
18
|
-
tableConfigs: TableConfig;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
12
|
export function getAuditProtection(
|
|
22
13
|
tableName: string,
|
|
23
14
|
actions: NonNullable<TableDefinition["triggers"]>[string]["actions"],
|
|
24
15
|
): NonNullable<TableDefinition["triggers"]> {
|
|
25
16
|
return {
|
|
26
|
-
[(actions.includes("update")
|
|
27
|
-
|
|
28
|
-
|
|
17
|
+
[(actions.includes("update") ?
|
|
18
|
+
AUDIT_HISTORY_PROTECTION_PREFIX
|
|
19
|
+
: AUDIT_TRUNCATE_PROTECTION_PREFIX) + md5(tableName)]: {
|
|
29
20
|
type: "before",
|
|
30
21
|
actions,
|
|
31
22
|
forEach: "statement",
|
|
@@ -36,40 +27,29 @@ export function getAuditProtection(
|
|
|
36
27
|
}
|
|
37
28
|
|
|
38
29
|
/** Adds audit definitions to the same config used for file tables and application tables. */
|
|
39
|
-
export
|
|
30
|
+
export const getAuditTableConfig = (
|
|
40
31
|
prgl: Prostgles,
|
|
41
32
|
tableConfig: TableConfig | undefined,
|
|
42
|
-
): TableConfig | undefined {
|
|
33
|
+
): TableConfig | undefined => {
|
|
43
34
|
const { audit } = prgl.opts;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
throw new Error("The audit table cannot also be defined in tableConfig");
|
|
51
|
-
}
|
|
52
|
-
result = {
|
|
53
|
-
[tableName]: {
|
|
54
|
-
columns: AUDIT_TABLE_COLUMN_DEFINITIONS,
|
|
55
|
-
triggers: getAuditProtection(tableName, ["update", "delete", "truncate"]),
|
|
56
|
-
},
|
|
57
|
-
...result,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
for (const [name, config] of Object.entries(
|
|
61
|
-
prgl.parsedAuditConfig?.tableConfigs ?? {},
|
|
62
|
-
)) {
|
|
63
|
-
result[name] = {
|
|
64
|
-
...result[name],
|
|
65
|
-
triggers: { ...result[name]?.triggers, ...config.triggers },
|
|
66
|
-
};
|
|
35
|
+
if (!audit) return tableConfig;
|
|
36
|
+
|
|
37
|
+
const { tableName } = audit;
|
|
38
|
+
if (!tableName) throw new Error("audit.tableName is required");
|
|
39
|
+
if (tableConfig?.[tableName]) {
|
|
40
|
+
throw new Error("The audit table cannot also be defined in tableConfig");
|
|
67
41
|
}
|
|
68
|
-
return
|
|
69
|
-
|
|
42
|
+
return {
|
|
43
|
+
[tableName]: {
|
|
44
|
+
columns: AUDIT_TABLE_COLUMN_DEFINITIONS,
|
|
45
|
+
triggers: getAuditProtection(tableName, ["update", "delete", "truncate"]),
|
|
46
|
+
},
|
|
47
|
+
...tableConfig,
|
|
48
|
+
};
|
|
49
|
+
};
|
|
70
50
|
|
|
71
51
|
export function isAuditTable(prgl: Prostgles, tableName: string): boolean {
|
|
72
|
-
return prgl.
|
|
52
|
+
return prgl.opts.audit?.tableName === tableName;
|
|
73
53
|
}
|
|
74
54
|
|
|
75
55
|
export const getAuditWriterName = (auditTable: string, sourceTable: string) =>
|
|
@@ -1,128 +1,71 @@
|
|
|
1
1
|
import { as } from "pg-promise";
|
|
2
|
-
import { asName } from "prostgles-types";
|
|
2
|
+
import { asName, getEntries } from "prostgles-types";
|
|
3
3
|
import type { Prostgles } from "../Prostgles";
|
|
4
|
-
import type {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
getAuditWriterName,
|
|
8
|
-
type ParsedAuditConfig,
|
|
9
|
-
} from "./getAuditTableConfig";
|
|
4
|
+
import type { TableConfig } from "../TableConfig/TableConfigTypes";
|
|
5
|
+
import { isArray } from "../utils/utils";
|
|
6
|
+
import { getAuditProtection, getAuditWriterName } from "./getAuditTableConfig";
|
|
10
7
|
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
):
|
|
8
|
+
/**
|
|
9
|
+
* Resolve column defaults against the completed schema; generate tableConfig entries only.
|
|
10
|
+
* */
|
|
11
|
+
export const parseAuditConfig = (prgl: Prostgles): TableConfig | undefined => {
|
|
15
12
|
const { audit } = prgl.opts;
|
|
13
|
+
if (!audit) return undefined;
|
|
14
|
+
|
|
16
15
|
const tables = prgl.dboBuilder.tables;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
...(prgl.parsedAuditConfig?.auditTableNames ?? []),
|
|
20
|
-
...(audit ? [audit.tableName] : []),
|
|
21
|
-
]),
|
|
22
|
-
];
|
|
23
|
-
const result: ParsedAuditConfig = {
|
|
24
|
-
auditTableNames,
|
|
25
|
-
tableConfigs: {},
|
|
26
|
-
};
|
|
27
|
-
for (const name of auditTableNames) {
|
|
28
|
-
if (!tables.some((t) => t.name === name)) {
|
|
29
|
-
throw new Error(
|
|
30
|
-
`Audit table name must exactly match a schema table name: ${name}`,
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
result.tableConfigs[name] = {
|
|
34
|
-
triggers: getAuditProtection(name, ["update", "delete", "truncate"]),
|
|
35
|
-
};
|
|
16
|
+
if (!tables.some((t) => t.name === audit.tableName)) {
|
|
17
|
+
throw new Error(`Audit table name must exactly match a schema table name: ${audit.tableName}`);
|
|
36
18
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
tableOptions !== undefined &&
|
|
41
|
-
(!tableOptions ||
|
|
42
|
-
typeof tableOptions !== "object" ||
|
|
43
|
-
Array.isArray(tableOptions))
|
|
44
|
-
) {
|
|
45
|
-
throw new Error("audit.tables must be a table map");
|
|
46
|
-
}
|
|
47
|
-
const entries = Object.entries(audit.tables ?? {}).filter(
|
|
48
|
-
([, value]) => value !== undefined,
|
|
49
|
-
);
|
|
19
|
+
const result: TableConfig = {};
|
|
20
|
+
|
|
21
|
+
const entries = getEntries(audit.tables ?? {}).filter(([, value]) => value !== undefined);
|
|
50
22
|
const exclusion = entries.some(([, value]) => value === 0);
|
|
51
|
-
if (exclusion && entries.some(([, value]) => value !== 0))
|
|
23
|
+
if (exclusion && entries.some(([, value]) => value !== 0)) {
|
|
52
24
|
throw new Error("audit.tables cannot mix enabled and disabled entries");
|
|
25
|
+
}
|
|
53
26
|
for (const [name, value] of entries) {
|
|
54
|
-
if (!tables.some((t) => t.name === name))
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
value !== 0 &&
|
|
58
|
-
value !== 1 &&
|
|
59
|
-
(!value || typeof value !== "object" || Array.isArray(value))
|
|
60
|
-
)
|
|
27
|
+
if (!tables.some((t) => t.name === name)) throw new Error(`Unknown audit table: ${name}`);
|
|
28
|
+
if (value !== 0 && value !== 1 && (!value || typeof value !== "object" || Array.isArray(value)))
|
|
61
29
|
throw new Error(`Invalid audit options for ${name}`);
|
|
62
30
|
}
|
|
63
|
-
|
|
64
|
-
oid: number;
|
|
65
|
-
relkind: string;
|
|
66
|
-
relispartition: boolean;
|
|
67
|
-
}>(
|
|
68
|
-
"SELECT oid, relkind, relispartition FROM pg_class WHERE oid = ANY($1::oid[])",
|
|
69
|
-
[tables.map((t) => t.oid)],
|
|
70
|
-
);
|
|
31
|
+
|
|
71
32
|
for (const table of tables) {
|
|
72
33
|
const entry = entries.find(([name]) => name === table.name);
|
|
73
34
|
if (entries.length && (exclusion ? entry?.[1] === 0 : !entry)) continue;
|
|
74
|
-
|
|
75
|
-
const isHistory =
|
|
76
|
-
const eligible =
|
|
77
|
-
!isHistory &&
|
|
78
|
-
table.schema !== "prostgles" &&
|
|
79
|
-
!table.is_view &&
|
|
80
|
-
!table.isHyperTable &&
|
|
81
|
-
relation &&
|
|
82
|
-
relation.relkind === "r" &&
|
|
83
|
-
!relation.relispartition;
|
|
35
|
+
|
|
36
|
+
const isHistory = table.name === audit.tableName;
|
|
37
|
+
const eligible = !isHistory && !table.is_view && !table.isHyperTable;
|
|
84
38
|
if (!eligible) {
|
|
85
|
-
if (entry && entry[1] !== 0)
|
|
39
|
+
if (entry && entry[1] !== 0) {
|
|
86
40
|
throw new Error(
|
|
87
|
-
`Unsupported audit target: ${table.name}
|
|
41
|
+
`Unsupported audit target: ${table.name}`,
|
|
88
42
|
);
|
|
43
|
+
}
|
|
89
44
|
continue;
|
|
90
45
|
}
|
|
91
|
-
const options
|
|
92
|
-
|
|
93
|
-
if (
|
|
94
|
-
Object.keys(options).some(
|
|
95
|
-
(k) => !["entityType", "idColumns", "excludeColumns"].includes(k),
|
|
96
|
-
)
|
|
97
|
-
)
|
|
98
|
-
throw new Error(`Unknown audit option for ${table.name}`);
|
|
99
|
-
const ids =
|
|
100
|
-
options.idColumns ??
|
|
101
|
-
table.columns.filter((c) => c.is_pkey).map((c) => c.name);
|
|
46
|
+
const options = typeof entry?.[1] === "object" ? entry[1] : {};
|
|
47
|
+
const ids = options.idColumns ?? table.columns.filter((c) => c.is_pkey).map((c) => c.name);
|
|
102
48
|
const excluded = options.excludeColumns ?? [];
|
|
103
|
-
if (!
|
|
104
|
-
throw new Error(
|
|
105
|
-
|
|
106
|
-
|
|
49
|
+
if (!isArray(ids) || !ids.length) {
|
|
50
|
+
throw new Error(`audit.idColumns is required for ${table.name} without a primary key`);
|
|
51
|
+
}
|
|
52
|
+
|
|
107
53
|
for (const list of [ids, excluded]) {
|
|
108
54
|
if (
|
|
109
|
-
!Array.isArray(list) ||
|
|
110
55
|
new Set(list).size !== list.length ||
|
|
111
56
|
list.some((c) => !table.columns.some((col) => col.name === c))
|
|
112
|
-
)
|
|
57
|
+
) {
|
|
113
58
|
throw new Error(`Invalid audit columns for ${table.name}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (ids.some((c) => excluded.includes(c))) {
|
|
62
|
+
throw new Error(`Audit identity columns cannot be excluded: ${table.name}`);
|
|
114
63
|
}
|
|
115
|
-
if (
|
|
116
|
-
throw new Error(
|
|
117
|
-
`Audit identity columns cannot be excluded: ${table.name}`,
|
|
118
|
-
);
|
|
119
|
-
if (
|
|
120
|
-
options.entityType !== undefined &&
|
|
121
|
-
(typeof options.entityType !== "string" || !options.entityType)
|
|
122
|
-
)
|
|
64
|
+
if (options.entityType !== undefined && !options.entityType) {
|
|
123
65
|
throw new Error(`Invalid audit entityType for ${table.name}`);
|
|
66
|
+
}
|
|
124
67
|
const functionName = getAuditWriterName(audit.tableName, table.name);
|
|
125
|
-
result
|
|
68
|
+
result[table.name] = {
|
|
126
69
|
triggers: {
|
|
127
70
|
...getAuditProtection(audit.tableName, ["truncate"]),
|
|
128
71
|
[functionName]: {
|
|
@@ -155,4 +98,4 @@ export async function parseAuditConfig(
|
|
|
155
98
|
};
|
|
156
99
|
}
|
|
157
100
|
return result;
|
|
158
|
-
}
|
|
101
|
+
};
|
package/lib/Prostgles.ts
CHANGED
|
@@ -63,7 +63,7 @@ import type { getAdminClient } from "./DboBuilder/runSql/getAdminClient";
|
|
|
63
63
|
import type { TableHandler } from "./DboBuilder/TableHandler/TableHandler";
|
|
64
64
|
import { getFileTableConfig } from "./StorageClient/getFileTableConfig";
|
|
65
65
|
import { dirname } from "path";
|
|
66
|
-
import { getAuditTableConfig
|
|
66
|
+
import { getAuditTableConfig } from "./Audit/getAuditTableConfig";
|
|
67
67
|
import { syncTableTriggers } from "./TableConfig/syncTableTriggers";
|
|
68
68
|
import { isManagedTriggerName } from "./TableConfig/managedTriggerNames";
|
|
69
69
|
|
|
@@ -118,7 +118,6 @@ export class Prostgles {
|
|
|
118
118
|
void this.schemaReady.catch(() => {});
|
|
119
119
|
return this.schemaReady;
|
|
120
120
|
};
|
|
121
|
-
parsedAuditConfig?: ParsedAuditConfig;
|
|
122
121
|
preparingTableConfig = false;
|
|
123
122
|
|
|
124
123
|
dbEventsManager?: DBEventsManager;
|
|
@@ -312,7 +311,7 @@ export class Prostgles {
|
|
|
312
311
|
await this.cleanupContext();
|
|
313
312
|
await this.runSchemaQueries(async () => {
|
|
314
313
|
await this.rebuildDBO();
|
|
315
|
-
if (this.opts.audit
|
|
314
|
+
if (this.opts.audit) {
|
|
316
315
|
await syncTableTriggers(this);
|
|
317
316
|
await this.rebuildDBO();
|
|
318
317
|
}
|
|
@@ -5,6 +5,7 @@ import { assertFileObjectValid, uploadFile } from "../DboBuilder/TableHandler/up
|
|
|
5
5
|
import type { Prostgles } from "../Prostgles";
|
|
6
6
|
import type { BeforeEachTsTrigger } from "../PublishParser/publishTypesAndUtils";
|
|
7
7
|
import type { TableConfig } from "../TableConfig/TableConfigTypes";
|
|
8
|
+
import type { TableRowFromColumnDefinitions } from "../TableConfig/TableRowFromColumnDefinitions";
|
|
8
9
|
import type { TableHooks } from "../TableHooks/TableHooks";
|
|
9
10
|
import { setupFileServeHandler } from "./setupFileServeHandler";
|
|
10
11
|
|
|
@@ -28,19 +29,7 @@ const FILE_TABLE_COLUMN_DEFINITIONS = {
|
|
|
28
29
|
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
|
|
29
30
|
} as const;
|
|
30
31
|
|
|
31
|
-
type
|
|
32
|
-
|
|
33
|
-
export type FileTableRow = {
|
|
34
|
-
[K in keyof FileTableColumnDefinitions as K]: FileTableColumnDefinitions[K] extends (
|
|
35
|
-
`BYTEA NOT NULL${string}`
|
|
36
|
-
) ?
|
|
37
|
-
Buffer
|
|
38
|
-
: FileTableColumnDefinitions[K] extends (
|
|
39
|
-
`${string} NOT NULL${string}` | `${string}PRIMARY KEY${string}`
|
|
40
|
-
) ?
|
|
41
|
-
string
|
|
42
|
-
: string | null;
|
|
43
|
-
};
|
|
32
|
+
export type FileTableRow = TableRowFromColumnDefinitions<typeof FILE_TABLE_COLUMN_DEFINITIONS>;
|
|
44
33
|
|
|
45
34
|
export const getFileTableConfig = (
|
|
46
35
|
prg: Prostgles,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Row types for the column definitions used by managed tables. */
|
|
2
|
+
export type TableRowFromColumnDefinitions<
|
|
3
|
+
T extends Record<
|
|
4
|
+
string,
|
|
5
|
+
string | { enum: readonly (string | number)[]; nullable?: boolean }
|
|
6
|
+
>,
|
|
7
|
+
> = {
|
|
8
|
+
[K in keyof T]: T[K] extends { enum: readonly (infer V)[] }
|
|
9
|
+
? V | (T[K] extends { nullable: true } ? null : never)
|
|
10
|
+
: | (T[K] extends `BYTEA${string}`
|
|
11
|
+
? Buffer
|
|
12
|
+
: T[K] extends `JSONB${string}`
|
|
13
|
+
? Record<string, unknown>
|
|
14
|
+
: string)
|
|
15
|
+
| (T[K] extends
|
|
16
|
+
`${string} NOT NULL${string}` | `${string}PRIMARY KEY${string}`
|
|
17
|
+
? never
|
|
18
|
+
: null);
|
|
19
|
+
};
|
|
@@ -3,7 +3,6 @@ import type { DB } from "../initProstgles";
|
|
|
3
3
|
import { asName } from "prostgles-types";
|
|
4
4
|
import type { TableConfig } from "./TableConfigTypes";
|
|
5
5
|
import {
|
|
6
|
-
AUDIT_HISTORY_PROTECTION_PREFIX,
|
|
7
6
|
getManagedTriggerName,
|
|
8
7
|
isManagedTriggerName,
|
|
9
8
|
} from "./managedTriggerNames";
|
|
@@ -108,9 +107,7 @@ export const getTableTriggerQueries = async (
|
|
|
108
107
|
}
|
|
109
108
|
for (const trigger of existing) {
|
|
110
109
|
const managed = isManagedTriggerName(trigger.name);
|
|
111
|
-
|
|
112
|
-
const protectsHistory = trigger.name.startsWith(AUDIT_HISTORY_PROTECTION_PREFIX);
|
|
113
|
-
if (managed && !protectsHistory && !desired.has(trigger.name)) {
|
|
110
|
+
if (managed && !desired.has(trigger.name)) {
|
|
114
111
|
queries.push(`DROP TRIGGER ${asName(trigger.name)} ON ${tableIdent};`);
|
|
115
112
|
}
|
|
116
113
|
}
|
|
@@ -4,7 +4,6 @@ import { md5 } from "prostgles-types/dist/md5";
|
|
|
4
4
|
// Keep generated names within PostgreSQL's 63-byte identifier limit.
|
|
5
5
|
export const TABLE_CONFIG_TRIGGER_PREFIX = "prostgles_table_config_";
|
|
6
6
|
export const AUDIT_TRIGGER_PREFIX = "prostgles_audit_";
|
|
7
|
-
// History protection survives removing or changing the audit configuration.
|
|
8
7
|
export const AUDIT_HISTORY_PROTECTION_PREFIX = AUDIT_TRIGGER_PREFIX + "guard_";
|
|
9
8
|
export const AUDIT_TRUNCATE_PROTECTION_PREFIX = AUDIT_TRIGGER_PREFIX + "block_";
|
|
10
9
|
export const AUDIT_WRITER_PREFIX = AUDIT_TRIGGER_PREFIX + "write_";
|
|
@@ -5,38 +5,27 @@ import { getTableTriggerQueries } from "./getTableTriggerQueries";
|
|
|
5
5
|
|
|
6
6
|
/** Applies application and generated audit triggers together, after all tables exist. */
|
|
7
7
|
export async function syncTableTriggers(prgl: Prostgles) {
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const queries: string[] = [];
|
|
15
|
-
for (const name of Object.keys(config)) {
|
|
16
|
-
if (!prgl.dboBuilder.tables.some((t) => t.name === name)) {
|
|
17
|
-
throw new Error(
|
|
18
|
-
`Table config name must exactly match a schema table name: ${name}`,
|
|
19
|
-
);
|
|
20
|
-
}
|
|
8
|
+
const auditConfig = parseAuditConfig(prgl);
|
|
9
|
+
const config = prgl.mergedTableConfig.tableConfig ?? {};
|
|
10
|
+
const queries: string[] = [];
|
|
11
|
+
for (const name of Object.keys(config)) {
|
|
12
|
+
if (!prgl.dboBuilder.tables.some((t) => t.name === name)) {
|
|
13
|
+
throw new Error(`Table config name must exactly match a schema table name: ${name}`);
|
|
21
14
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
} catch (error) {
|
|
39
|
-
prgl.parsedAuditConfig = previousAudit;
|
|
40
|
-
throw error;
|
|
15
|
+
}
|
|
16
|
+
for (const table of prgl.dboBuilder.tables) {
|
|
17
|
+
queries.push(
|
|
18
|
+
...(await getTableTriggerQueries(prgl.dbForSchema!, table.escaped_identifier, {
|
|
19
|
+
triggers: {
|
|
20
|
+
...config[table.name]?.triggers,
|
|
21
|
+
...auditConfig?.[table.name]?.triggers,
|
|
22
|
+
},
|
|
23
|
+
})),
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
if (queries.length) {
|
|
27
|
+
await prgl.dbForSchema!.tx((tx) =>
|
|
28
|
+
tx.none(`/* ${EXCLUDE_QUERY_FROM_SCHEMA_WATCH_ID} */\n${queries.join("\n")}`),
|
|
29
|
+
);
|
|
41
30
|
}
|
|
42
31
|
}
|