@opengis/fastify-table 2.0.149 → 2.0.150
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.
|
@@ -3,7 +3,7 @@ import getRedis from "../../redis/funcs/getRedis.js";
|
|
|
3
3
|
import pgClients from "../../pg/pgClients.js";
|
|
4
4
|
import getTemplate from "../../table/funcs/getTemplate.js";
|
|
5
5
|
import config from "../../../../config.js";
|
|
6
|
-
|
|
6
|
+
import logChanges from "./utils/logChanges.js";
|
|
7
7
|
import getInsertQuery from "./utils/getInsertQuery.js";
|
|
8
8
|
import logger from "../../logger/getLogger.js";
|
|
9
9
|
import extraData from "../../extra/extraData.js";
|
|
@@ -95,16 +95,16 @@ export default async function dataInsert({ id, table: table1, referer, data, pg:
|
|
|
95
95
|
Object.assign(res.rows[0], { [key]: parentRows.filter(Boolean) });
|
|
96
96
|
}));
|
|
97
97
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
98
|
+
await logChanges({
|
|
99
|
+
pg: client,
|
|
100
|
+
table,
|
|
101
|
+
tokenData,
|
|
102
|
+
referer,
|
|
103
|
+
data,
|
|
104
|
+
id: id1,
|
|
105
|
+
uid,
|
|
106
|
+
type: "INSERT",
|
|
107
|
+
});
|
|
108
108
|
if (config.redis && rclient?.status !== "end") {
|
|
109
109
|
rclient.incr(`pg:${client.options?.database}:${table}:crud`);
|
|
110
110
|
}
|
|
@@ -16,6 +16,7 @@ export default function logChanges({ pg, table: table1, tokenData, referer, id,
|
|
|
16
16
|
change_type: string;
|
|
17
17
|
old: any;
|
|
18
18
|
new: any;
|
|
19
|
+
titles: Record<string, string>;
|
|
19
20
|
error?: undefined;
|
|
20
21
|
} | {
|
|
21
22
|
error: any;
|
|
@@ -26,5 +27,6 @@ export default function logChanges({ pg, table: table1, tokenData, referer, id,
|
|
|
26
27
|
change_id?: undefined;
|
|
27
28
|
old?: undefined;
|
|
28
29
|
new?: undefined;
|
|
30
|
+
titles?: undefined;
|
|
29
31
|
} | null>;
|
|
30
32
|
//# sourceMappingURL=logChanges.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logChanges.d.ts","sourceRoot":"","sources":["../../../../../../server/plugins/crud/funcs/utils/logChanges.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"logChanges.d.ts","sourceRoot":"","sources":["../../../../../../server/plugins/crud/funcs/utils/logChanges.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;AA8C5D,wBAA8B,UAAU,CAAC,EACvC,EAAE,EACF,KAAK,EAAE,MAAM,EACb,SAAS,EACT,OAAO,EACP,EAAE,EACF,IAAI,EACJ,GAAO,EACP,IAAI,GACL,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;;;;;;;;;;;;;;;;;;;;UA8MA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import getTemplate from "../../../table/funcs/getTemplate.js";
|
|
3
3
|
import metaFormat from "../../../table/funcs/metaFormat/index.js";
|
|
4
|
+
import getMeta from "../../../pg/funcs/getMeta.js";
|
|
4
5
|
const defaultTitles = {
|
|
5
6
|
editor_date: "Дата оновлення",
|
|
6
7
|
editor_id: "Редактор",
|
|
@@ -14,15 +15,26 @@ const defaultTitles = {
|
|
|
14
15
|
size: "Розмір файлу",
|
|
15
16
|
ext: "Розширення файлу",
|
|
16
17
|
};
|
|
17
|
-
|
|
18
|
+
// skip log of system columns changes made by CRUD functions - log only changes of data
|
|
19
|
+
const systemColumns = [
|
|
20
|
+
"cdate",
|
|
21
|
+
"editor_date",
|
|
22
|
+
"created_at",
|
|
23
|
+
"updated_at",
|
|
24
|
+
"editor_id",
|
|
25
|
+
"uid",
|
|
26
|
+
"updated_by",
|
|
27
|
+
"created_by",
|
|
28
|
+
];
|
|
29
|
+
function getValue(val, tableName, columnTypes) {
|
|
30
|
+
if (typeof val === "boolean")
|
|
31
|
+
return val;
|
|
18
32
|
if (!val)
|
|
19
33
|
return null;
|
|
20
34
|
if (["crm.files"].includes(tableName)) {
|
|
21
35
|
return typeof val === "object" ? JSON.stringify(val) : val;
|
|
22
36
|
}
|
|
23
|
-
return typeof val === "object"
|
|
24
|
-
? JSON.stringify(val)?.substring?.(0, 30)
|
|
25
|
-
: val?.toString?.()?.substring?.(0, 30);
|
|
37
|
+
return typeof val === "object" ? null : val?.toString?.()?.substring?.(0, 30);
|
|
26
38
|
}
|
|
27
39
|
// extract titles and cls from form schema
|
|
28
40
|
// alt: extract table template from referer -> form
|
|
@@ -75,35 +87,70 @@ export default async function logChanges({ pg, table: table1, tokenData, referer
|
|
|
75
87
|
const body = await getTemplate("form", tokenData?.form);
|
|
76
88
|
const schema = body?.schema || body || {};
|
|
77
89
|
const titles = Object.keys(schema).reduce((acc, curr) => Object.assign(acc, { [curr]: schema[curr].title || schema[curr].ua }), {});
|
|
90
|
+
Object.assign(titles, defaultTitles);
|
|
78
91
|
const cls = Object.keys(schema)
|
|
79
92
|
.filter((el) => schema[el]?.data)
|
|
80
93
|
.reduce((acc, curr) => Object.assign(acc, { [curr]: schema[curr].data }), {});
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
// const original = JSON.parse(JSON.stringify(data));
|
|
95
|
+
const row = await metaFormat({
|
|
96
|
+
rows: [data].filter(Boolean),
|
|
97
|
+
cls,
|
|
98
|
+
sufix: false,
|
|
99
|
+
reassign: false,
|
|
100
|
+
}, pg).then((el) => el[0]);
|
|
101
|
+
const newObj1 = {};
|
|
102
|
+
const meta = await getMeta({ pg, table });
|
|
103
|
+
const columnTypes = (meta?.columns || []).reduce((acc, curr) => ({
|
|
104
|
+
...acc,
|
|
105
|
+
[curr.name]: pg?.pgType?.[curr.dataTypeID],
|
|
106
|
+
}), {});
|
|
107
|
+
if (type !== "DELETE") {
|
|
108
|
+
Object.keys(row || {})
|
|
109
|
+
.filter((key) => !systemColumns.includes(key))
|
|
110
|
+
.reduce((acc, curr) => {
|
|
111
|
+
Object.assign(newObj1, {
|
|
112
|
+
[titles[curr] || curr]: columnTypes[curr] === "geometry"
|
|
113
|
+
? {}
|
|
114
|
+
: {
|
|
115
|
+
value: getValue(row[curr], table, columnTypes),
|
|
116
|
+
hash: typeof row[curr] === "boolean" || row[curr]
|
|
117
|
+
? createHash("md5")
|
|
118
|
+
.update(JSON.stringify(row[curr]))
|
|
119
|
+
.digest("hex")
|
|
120
|
+
: null,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
return acc;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const newGeoms = await Promise.all(Object.keys(newObj1)
|
|
127
|
+
.filter((key) => row[key] && columnTypes[key] === "geometry")
|
|
128
|
+
.map(async (key) => pg
|
|
129
|
+
.query(typeof row[key] === "string" // binary geometry as string via update?
|
|
130
|
+
? "select st_asgeojson(st_pointonsurface($1))::json"
|
|
131
|
+
: "select st_asgeojson(st_pointonsurface(st_geomfromgeojson($1)))::json", [row[key]])
|
|
132
|
+
.then((el) => ({ key, geometry: el.rows[0].st_asgeojson })))).then((r) => r.reduce((acc, curr) => {
|
|
133
|
+
const value = curr.geometry.coordinates.join(",");
|
|
134
|
+
const hash = createHash("md5")
|
|
135
|
+
.update(JSON.stringify(value))
|
|
136
|
+
.digest("hex");
|
|
137
|
+
newObj1[curr.key] = { value, hash };
|
|
138
|
+
return { ...acc, [curr.key]: { value, hash } };
|
|
139
|
+
}, {}));
|
|
140
|
+
const changesData = Object.keys(newObj1 || {})
|
|
141
|
+
.filter((key) => typeof newObj1?.[key] === "boolean" || newObj1?.[key])
|
|
142
|
+
.filter((key) => old[key] ? old[key].hash !== newObj1[key]?.hash : newObj1[key]?.hash)
|
|
143
|
+
.map((key) => ({
|
|
95
144
|
change_id: changeId,
|
|
96
|
-
entity_key:
|
|
97
|
-
value_old:
|
|
98
|
-
value_new:
|
|
99
|
-
value_hash:
|
|
100
|
-
? createHash("md5").update(JSON.stringify(newObj?.[el])).digest("hex")
|
|
101
|
-
: null,
|
|
145
|
+
entity_key: key,
|
|
146
|
+
value_old: old?.[key]?.value,
|
|
147
|
+
value_new: newObj1?.[key]?.value,
|
|
148
|
+
value_hash: newObj1?.[key]?.hash,
|
|
102
149
|
uid,
|
|
103
|
-
}))
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
150
|
+
}));
|
|
151
|
+
if (process.env.NODE_ENV === "test") {
|
|
152
|
+
console.log("changesData", changesData);
|
|
153
|
+
}
|
|
107
154
|
const res = await Promise.all(changesData.map(async (el) => {
|
|
108
155
|
const insertQuery = `insert into log.table_changes_data (${Object.entries(el)
|
|
109
156
|
?.map((key) => `"${key[0]}"`)
|
|
@@ -111,18 +158,18 @@ export default async function logChanges({ pg, table: table1, tokenData, referer
|
|
|
111
158
|
values (${Object.entries(el)
|
|
112
159
|
?.map((key, i) => `$${i + 1}`)
|
|
113
160
|
.join(",")}) returning *`;
|
|
114
|
-
const
|
|
161
|
+
const row1 = await pg
|
|
162
|
+
.query(insertQuery, [
|
|
115
163
|
...Object.entries(el).map((el1) => el1[1] &&
|
|
116
164
|
typeof el1[1] === "object" &&
|
|
117
165
|
(!Array.isArray(el1[1]) || typeof el1[1]?.[0] === "object")
|
|
118
166
|
? JSON.stringify(el1[1])
|
|
119
167
|
: el1[1]),
|
|
120
|
-
])
|
|
121
|
-
|
|
168
|
+
])
|
|
169
|
+
.then((el) => el.rows?.[0] || {});
|
|
170
|
+
return row1;
|
|
122
171
|
}));
|
|
123
|
-
const newData =
|
|
124
|
-
? {}
|
|
125
|
-
: (Array.isArray(res) ? res : [res]).reduce((acc, curr) => Object.assign(acc, { [curr.entity_key]: curr.value_new }), {});
|
|
172
|
+
const newData = (Array.isArray(res) ? res : [res]).reduce((acc, curr) => Object.assign(acc, { [curr.entity_key]: curr.value_new }), {});
|
|
126
173
|
// console.log('logChanges OK', type);
|
|
127
174
|
return {
|
|
128
175
|
change_id: changeId,
|
|
@@ -132,6 +179,7 @@ export default async function logChanges({ pg, table: table1, tokenData, referer
|
|
|
132
179
|
change_type: type,
|
|
133
180
|
old,
|
|
134
181
|
new: newData,
|
|
182
|
+
titles,
|
|
135
183
|
};
|
|
136
184
|
}
|
|
137
185
|
catch (err) {
|