@opengis/fastify-table 2.0.109 → 2.0.111
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/config.d.ts.map +1 -1
- package/dist/config.js +2 -1
- package/dist/server/plugins/logger/index.d.ts.map +1 -1
- package/dist/server/plugins/logger/index.js +11 -1
- package/dist/server/plugins/pg/funcs/init.d.ts.map +1 -1
- package/dist/server/plugins/pg/funcs/init.js +1 -1
- package/dist/server/plugins/redis/index.d.ts.map +1 -1
- package/dist/server/plugins/redis/index.js +3 -1
- package/dist/server/routes/auth/controllers/core/getUserInfo.d.ts.map +1 -1
- package/dist/server/routes/auth/controllers/core/getUserInfo.js +4 -2
- package/dist/server/routes/file/controllers/export.d.ts.map +1 -1
- package/dist/server/routes/file/controllers/export.js +23 -19
- package/dist/server/routes/file/controllers/resize.d.ts +1 -0
- package/dist/server/routes/file/controllers/resize.d.ts.map +1 -1
- package/dist/server/routes/file/controllers/resize.js +5 -1
- package/dist/server/routes/file/controllers/utils/jsonlToJsonFile.d.ts +2 -0
- package/dist/server/routes/file/controllers/utils/jsonlToJsonFile.d.ts.map +1 -0
- package/dist/server/routes/file/controllers/utils/jsonlToJsonFile.js +32 -0
- package/dist/test.setup.d.ts +2 -0
- package/dist/test.setup.d.ts.map +1 -0
- package/dist/test.setup.js +18 -0
- package/package.json +1 -1
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAWA,QAAA,MAAM,MAAM,KAA8D,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAWA,QAAA,MAAM,MAAM,KAA8D,CAAC;AAsC3E,eAAe,MAAM,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -9,7 +9,8 @@ const { skipKeys = ["windir"] } = config;
|
|
|
9
9
|
Object.assign(config, {
|
|
10
10
|
storageList: {},
|
|
11
11
|
allTemplates: config?.allTemplates || {},
|
|
12
|
-
env: process.env
|
|
12
|
+
env: process.env.NODE_ENV,
|
|
13
|
+
port: process.env.PORT,
|
|
13
14
|
});
|
|
14
15
|
if (existsSync(`.env.local`)) {
|
|
15
16
|
dotenv.config({ path: `.env.local` }); // ! load .env.local
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/logger/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/logger/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAmD7E,iBAAe,MAAM,CAAC,OAAO,EAAE,eAAe,iBAwC7C;AACD,eAAe,MAAM,CAAC"}
|
|
@@ -9,7 +9,8 @@ process.on("uncaughtException", (err) => {
|
|
|
9
9
|
console.warn("⚠️ Ignored pg connection drop:", err.toString());
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
logger.file("uncaughtException", { error: err.toString(), stack: err.stack });
|
|
13
|
+
// throw err; // keep normal behavior
|
|
13
14
|
});
|
|
14
15
|
// avoid process exit with rejection during client connect at process start
|
|
15
16
|
process.on("unhandledRejection", (err) => {
|
|
@@ -27,6 +28,15 @@ process.on("unhandledRejection", (err) => {
|
|
|
27
28
|
console.warn("⚠️ Ignored redis connection close:", err.toString());
|
|
28
29
|
return;
|
|
29
30
|
}
|
|
31
|
+
if (err.code === "ERR_HTTP_HEADERS_SENT") {
|
|
32
|
+
logger.file("fastify", { error: err.code, stack: err.stack });
|
|
33
|
+
console.warn("Ignored fastify reply sent exception:", err.toString());
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
logger.file("unhandledRejection", {
|
|
37
|
+
error: err.toString(),
|
|
38
|
+
stack: err.stack,
|
|
39
|
+
});
|
|
30
40
|
throw err;
|
|
31
41
|
});
|
|
32
42
|
async function plugin(fastify) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/pg/funcs/init.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIpD,iBAAe,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/pg/funcs/init.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIpD,iBAAe,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,iBA0NtC;AAGD,eAAe,IAAI,CAAC"}
|
|
@@ -176,7 +176,7 @@ async function init(client) {
|
|
|
176
176
|
queryNotice,
|
|
177
177
|
querySafe,
|
|
178
178
|
});
|
|
179
|
-
console.log("New client init finished", client.database);
|
|
179
|
+
console.log("New client init finished", client.database, new Date().toISOString());
|
|
180
180
|
logger.file("pg", {
|
|
181
181
|
message: "client init finished",
|
|
182
182
|
database: client.database,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAa/C,iBAAe,MAAM,CAAC,OAAO,EAAE,eAAe,iBAE7C;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import redisClients from "./funcs/redisClients.js";
|
|
2
2
|
function close() {
|
|
3
|
-
Object.keys(redisClients)
|
|
3
|
+
Object.keys(redisClients)
|
|
4
|
+
.filter((key) => redisClients[key]?.status !== "end")
|
|
5
|
+
.forEach((key) => {
|
|
4
6
|
console.log("Closing redis client", key);
|
|
5
7
|
redisClients[key].quit();
|
|
6
8
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getUserInfo.d.ts","sourceRoot":"","sources":["../../../../../../server/routes/auth/controllers/core/getUserInfo.ts"],"names":[],"mappings":"AAiCA,wBAA8B,WAAW,CAAC,GAAG,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"getUserInfo.d.ts","sourceRoot":"","sources":["../../../../../../server/routes/auth/controllers/core/getUserInfo.ts"],"names":[],"mappings":"AAiCA,wBAA8B,WAAW,CAAC,GAAG,EAAE,GAAG,eA4DjD"}
|
|
@@ -39,8 +39,10 @@ export default async function getUserInfo(req) {
|
|
|
39
39
|
cookies: req.cookies,
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
|
-
if (!req.user)
|
|
43
|
-
|
|
42
|
+
if (!req.user) {
|
|
43
|
+
const hookData1 = await applyHook("afterUser", { payload });
|
|
44
|
+
return hookData1 || payload;
|
|
45
|
+
}
|
|
44
46
|
const userInfo = Object.fromEntries(Object.entries(req.user).filter(([key]) => !["salt", "password"].includes(key)));
|
|
45
47
|
const { rows = [] } = req.pg?.pk?.["admin.properties"]
|
|
46
48
|
? await req.pg.query(`select property_key as key,property_text as val from admin.properties where property_key~'^(${config.settingKeys || "site|map|admin"})'`)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../../../server/routes/file/controllers/export.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../../../server/routes/file/controllers/export.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA+BzD;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,wBAA8B,WAAW,CACvC,EACE,EAAqB,EACrB,OAAO,EACP,IAAI,EACJ,OAAO,EAAE,QAAQ,EACjB,GAAG,EACH,KAAU,EACV,IAAkB,EAClB,QAAQ,EACR,UAAU,GACX,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EACD,KAAK,EAAE,YAAY,gBAyXpB"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
8
|
import { existsSync } from "node:fs";
|
|
9
|
-
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
9
|
+
import { appendFile, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
10
10
|
import config from "../../../../config.js";
|
|
11
11
|
import logger from "../../../plugins/logger/getLogger.js";
|
|
12
12
|
import getTemplate from "../../../plugins/table/funcs/getTemplate.js";
|
|
@@ -19,6 +19,7 @@ import metaFormat from "../../../plugins/table/funcs/metaFormat/index.js";
|
|
|
19
19
|
import jsonToXls from "./utils/jsonToXls.js";
|
|
20
20
|
import jsonToCsv from "./utils/jsonToCsv.js";
|
|
21
21
|
import formatResult from "./utils/formatResult.js";
|
|
22
|
+
import jsonlToJsonFile from "./utils/jsonlToJsonFile.js";
|
|
22
23
|
const startStreamWithTotal = 10000;
|
|
23
24
|
const rootDir = getFolder(config, "local");
|
|
24
25
|
/**
|
|
@@ -84,12 +85,11 @@ export default async function exportTable({ pg = pgClients.client, headers, user
|
|
|
84
85
|
});
|
|
85
86
|
}
|
|
86
87
|
// delete old file, prevent append
|
|
87
|
-
if (nocache || config.disableCache) {
|
|
88
|
-
|
|
89
|
-
await rm(filePath);
|
|
90
|
-
if (cacheFileJSON && format !== "json")
|
|
91
|
-
await rm(filePathJSON);
|
|
88
|
+
if (cacheFile && (nocache || config.disableCache)) {
|
|
89
|
+
await rm(filePath);
|
|
92
90
|
}
|
|
91
|
+
// create directory if not exists
|
|
92
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
93
93
|
const loadTable = await getTemplate("table", table);
|
|
94
94
|
const meta = await getMeta({ pg, table: loadTable?.table || table });
|
|
95
95
|
const viewSql = await getTemplate("view", loadTable?.table || table);
|
|
@@ -183,6 +183,19 @@ export default async function exportTable({ pg = pgClients.client, headers, user
|
|
|
183
183
|
let seq = 0;
|
|
184
184
|
send(`Всього в реєстрі: ${result.total} (${filtered} з урахуванням фільтрів)`);
|
|
185
185
|
if (!cacheFileJSON || nocache || config.disableCache) {
|
|
186
|
+
// delete old json line file, prevent append
|
|
187
|
+
if (existsSync(filePathJSON.replace(/.json$/, ".jsonl"))) {
|
|
188
|
+
await rm(filePathJSON.replace(/.json$/, ".jsonl"), {
|
|
189
|
+
recursive: true,
|
|
190
|
+
force: true,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
// delete old file, prevent append
|
|
194
|
+
if (existsSync(filePathJSON)) {
|
|
195
|
+
await rm(filePathJSON, { recursive: true, force: true });
|
|
196
|
+
}
|
|
197
|
+
// create empty temporary json lines file to append to
|
|
198
|
+
await writeFile(filePathJSON.replace(/.json$/, ".jsonl"), "");
|
|
186
199
|
while (+filtered - offset > 0 && !res?.error) {
|
|
187
200
|
try {
|
|
188
201
|
send(`Оброблено: ${offset}/${filtered}`);
|
|
@@ -211,19 +224,8 @@ export default async function exportTable({ pg = pgClients.client, headers, user
|
|
|
211
224
|
.forEach((key) => delete row[key]);
|
|
212
225
|
});
|
|
213
226
|
}
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
if (!jsonFileExists) {
|
|
217
|
-
// if json not exists
|
|
218
|
-
await mkdir(path.dirname(filePath), { recursive: true });
|
|
219
|
-
await writeFile(filePathJSON, JSON.stringify(rows));
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
// if json exists
|
|
223
|
-
const jsonData = JSON.parse((await readFile(filePathJSON, "utf8")) || "{}");
|
|
224
|
-
const moreData = jsonData.concat(rows); // rewrite to appendFile?
|
|
225
|
-
await writeFile(filePathJSON, JSON.stringify(moreData));
|
|
226
|
-
}
|
|
227
|
+
const data = rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
|
|
228
|
+
await appendFile(filePathJSON.replace(/.json$/, ".jsonl"), data);
|
|
227
229
|
offset += rows.length;
|
|
228
230
|
page++;
|
|
229
231
|
}
|
|
@@ -242,6 +244,8 @@ export default async function exportTable({ pg = pgClients.client, headers, user
|
|
|
242
244
|
}
|
|
243
245
|
}
|
|
244
246
|
}
|
|
247
|
+
// convert json line to json array
|
|
248
|
+
await jsonlToJsonFile(filePathJSON.replace(/.json$/, ".jsonl"));
|
|
245
249
|
clearInterval(interval);
|
|
246
250
|
if (res.error) {
|
|
247
251
|
send(res.error, 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../../../../server/routes/file/controllers/resize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../../../../server/routes/file/controllers/resize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAoC5C;;GAEG;AAEH,wBAA8B,MAAM,CAClC,EACE,KAAK,GACN,EAAE;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAC1B,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,OAAO,CAAC,EAAE,GAAG,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,GAAG,CAAC;KACf,CAAC;CACH,EACD,KAAK,EAAE,YAAY,kBAwIpB"}
|
|
@@ -15,11 +15,15 @@ const getHeight = (width, size, ratio = 1) => {
|
|
|
15
15
|
return defaultHeight;
|
|
16
16
|
};
|
|
17
17
|
const { resizeImage } = grpc();
|
|
18
|
+
const transparentGif = Buffer.from("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7", "base64");
|
|
18
19
|
/**
|
|
19
20
|
* Апі використовується для зміни розміру фото за шляхом
|
|
20
21
|
*/
|
|
21
22
|
export default async function resize({ query, }, reply) {
|
|
22
|
-
const { filepath, quality, size, w, h, nocache, format } = query || {};
|
|
23
|
+
const { filepath, quality, size, w, h, nocache, format, noimage } = query || {};
|
|
24
|
+
if (noimage) {
|
|
25
|
+
return reply.headers({ "Content-Type": "image/gif" }).send(transparentGif);
|
|
26
|
+
}
|
|
23
27
|
if (!filepath) {
|
|
24
28
|
return reply
|
|
25
29
|
.status(400)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonlToJsonFile.d.ts","sourceRoot":"","sources":["../../../../../../server/routes/file/controllers/utils/jsonlToJsonFile.ts"],"names":[],"mappings":"AAKA,wBAA8B,eAAe,CAAC,SAAS,EAAE,MAAM,mBAiC9D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { once } from "node:events";
|
|
2
|
+
import { rm } from "node:fs/promises";
|
|
3
|
+
import { createInterface } from "node:readline";
|
|
4
|
+
import { createReadStream, createWriteStream } from "node:fs";
|
|
5
|
+
export default async function jsonlToJsonFile(inputPath) {
|
|
6
|
+
const outputPath = inputPath.replace(/.jsonl$/g, ".json");
|
|
7
|
+
const input = createReadStream(inputPath);
|
|
8
|
+
const output = createWriteStream(outputPath);
|
|
9
|
+
const stream = createInterface({ input, crlfDelay: Infinity });
|
|
10
|
+
output.write("[\n");
|
|
11
|
+
let first = true;
|
|
12
|
+
stream.on("line", (line) => {
|
|
13
|
+
if (!line.trim())
|
|
14
|
+
return;
|
|
15
|
+
if (!first)
|
|
16
|
+
output.write(",\n");
|
|
17
|
+
output.write(JSON.stringify(JSON.parse(line)));
|
|
18
|
+
first = false;
|
|
19
|
+
});
|
|
20
|
+
// await stream to close /until convert finished
|
|
21
|
+
await once(stream, "close");
|
|
22
|
+
output.write("\n]");
|
|
23
|
+
output.end();
|
|
24
|
+
// wait for write stream to finish flushing
|
|
25
|
+
await once(output, "finish");
|
|
26
|
+
// rm temporary json line
|
|
27
|
+
await rm(inputPath, {
|
|
28
|
+
recursive: true,
|
|
29
|
+
force: true,
|
|
30
|
+
});
|
|
31
|
+
return outputPath;
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.setup.d.ts","sourceRoot":"","sources":["../test.setup.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { beforeEach, afterEach, afterAll } from "vitest";
|
|
2
|
+
// @ts-expect-error required for unit tests only
|
|
3
|
+
import { build, teardown } from "./helper.js";
|
|
4
|
+
beforeEach(async () => {
|
|
5
|
+
console.log("build after each bun test start...");
|
|
6
|
+
await build();
|
|
7
|
+
console.log("build after each bun test finished");
|
|
8
|
+
});
|
|
9
|
+
afterEach(async () => {
|
|
10
|
+
console.log("teardown after each bun test start...");
|
|
11
|
+
// await teardown();
|
|
12
|
+
console.log("teardown after each bun test finished");
|
|
13
|
+
});
|
|
14
|
+
afterAll(async () => {
|
|
15
|
+
console.log("teardown after all bun test start...");
|
|
16
|
+
await teardown();
|
|
17
|
+
console.log("teardown after all bun test finished");
|
|
18
|
+
});
|