@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.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAWA,QAAA,MAAM,MAAM,KAA8D,CAAC;AAqC3E,eAAe,MAAM,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?.NODE_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;AAyC7E,iBAAe,MAAM,CAAC,OAAO,EAAE,eAAe,iBAwC7C;AACD,eAAe,MAAM,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
- throw err; // keep normal behavior
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,iBAsNtC;AAGD,eAAe,IAAI,CAAC"}
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;AAW/C,iBAAe,MAAM,CAAC,OAAO,EAAE,eAAe,iBAE7C;AAED,eAAe,MAAM,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).forEach((key) => {
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,eAyDjD"}
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
- return payload;
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;AA0B5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKzD;;;;;;;;;;;;;;;;;;;;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,gBA8WpB"}
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
- if (cacheFile)
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 jsonFileExists = existsSync(filePathJSON);
215
- // convert from json to format
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);
@@ -11,6 +11,7 @@ export default function resize({ query, }: {
11
11
  h?: string;
12
12
  nocache?: any;
13
13
  format?: string;
14
+ noimage?: any;
14
15
  };
15
16
  }, reply: FastifyReply): Promise<never>;
16
17
  //# sourceMappingURL=resize.d.ts.map
@@ -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;AA+B5C;;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;KACjB,CAAC;CACH,EACD,KAAK,EAAE,YAAY,kBAmIpB"}
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,2 @@
1
+ export default function jsonlToJsonFile(inputPath: string): Promise<string>;
2
+ //# sourceMappingURL=jsonlToJsonFile.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test.setup.d.ts.map
@@ -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
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/fastify-table",
3
- "version": "2.0.109",
3
+ "version": "2.0.111",
4
4
  "type": "module",
5
5
  "description": "core-plugins",
6
6
  "keywords": [