zet-lib 1.4.19 → 1.4.21

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/lib/index.js CHANGED
@@ -1,38 +1,39 @@
1
- 'use strict'
1
+ "use strict";
2
2
 
3
3
  module.exports = {
4
- access: require('./access'),
5
- Util: require('./Util'),
6
- myCache: require('./cache'),
7
- connection: require('./connection'),
8
- zDataTable: require('./zdataTable'),
9
- zDebug: require('./debug'),
10
- zForm: require('./Form'),
11
- io: require('./io'),
12
- zMail: require('./Mail'),
13
- moduleLib: require('./moduleLib'),
14
- Model:require('./Model'),
15
- zApp: require('./zapp'),
16
- zAppRouter: require('./zAppRouter'),
17
- zComponent: require('./zComponent'),
18
- zFn: require('./zFn'),
19
- zFunction: require('./zFunction'),
20
- zMenuRouter: require('./zMenuRouter'),
21
- zGeneratorRouter: require('./zGeneratorRouter'),
22
- zViewGenerator:require('./zViewGenerator'),
23
- zReport: require('./zReport'),
24
- zRoute: require('./zRoute'),
25
- zRole: require('./zRole'),
26
- zRoleRouter: require('./zRoleRouter'),
27
- zPage: require('./zPage'),
28
- zTester: require('./zTester'),
29
- zCache: require('./zCache'),
30
- puppeteer: require('puppeteer'),
31
- moment: require('moment'),
32
- ejs: require('ejs'),
33
- axios: require('axios'),
34
- Excel: require('exceljs'),
35
- pm2: require('pm2'),
36
- nodemailer: require('nodemailer'),
37
- readXlsxFile: require('read-excel-file/node')
38
- }
4
+ access: require("./access"),
5
+ Util: require("./Util"),
6
+ myCache: require("./cache"),
7
+ connection: require("./connection"),
8
+ zDataTable: require("./zdataTable"),
9
+ zDebug: require("./debug"),
10
+ zForm: require("./Form"),
11
+ io: require("./io"),
12
+ zMail: require("./Mail"),
13
+ moduleLib: require("./moduleLib"),
14
+ Model: require("./Model"),
15
+ zApp: require("./zapp"),
16
+ zAppRouter: require("./zAppRouter"),
17
+ zComponent: require("./zComponent"),
18
+ zFn: require("./zFn"),
19
+ zFunction: require("./zFunction"),
20
+ zMenuRouter: require("./zMenuRouter"),
21
+ zGeneratorRouter: require("./zGeneratorRouter"),
22
+ zViewGenerator: require("./zViewGenerator"),
23
+ zReport: require("./zReport"),
24
+ zRoute: require("./zRoute"),
25
+ zRole: require("./zRole"),
26
+ zRoleRouter: require("./zRoleRouter"),
27
+ zPage: require("./zPage"),
28
+ zTester: require("./zTester"),
29
+ zCache: require("./zCache"),
30
+ puppeteer: require("puppeteer"),
31
+ moment: require("moment"),
32
+ ejs: require("ejs"),
33
+ axios: require("axios"),
34
+ Excel: require("exceljs"),
35
+ pm2: require("pm2"),
36
+ nodemailer: require("nodemailer"),
37
+ readXlsxFile: require("read-excel-file/node"),
38
+ JSZip: require("jszip"),
39
+ };
package/lib/zAppRouter.js CHANGED
@@ -26,6 +26,8 @@ const sharp = require("sharp");
26
26
  const path = require("path");
27
27
  const { Dropbox } = require("dropbox");
28
28
  const fetch = require("isomorphic-fetch");
29
+ const JSZip = require("jszip");
30
+
29
31
  /*
30
32
  ajax Post
31
33
  */
@@ -405,8 +407,8 @@ router.post("/signup-custom", async (req, res) => {
405
407
  },
406
408
  });
407
409
  /* await zRoute.loginAjax(dataUser.username, body.password, req, res);
408
- //refresh cache
409
- await zCache.renew();*/
410
+ //refresh cache
411
+ await zCache.renew();*/
410
412
 
411
413
  res.json(Util.jsonSuccess("Successfuly"));
412
414
  } catch (e) {
@@ -710,15 +712,15 @@ router.post("/zzapproval", async (req, res) => {
710
712
  if (data.status == 2) {
711
713
  //send activity
712
714
  /* await zRoute.insertSQL(req, res, "zactivity", {
713
- user_id: res.locals.userId,
714
- table: MYMODEL.table,
715
- id_data: data.id,
716
- status: data.status,
717
- status_label: MYMODEL.widgets.status.fields[data.status],
718
- title: MYMODEL.widgets.status.fields[data.status],
719
- description: users[res.locals.userId].fname + " " +users[res.locals.userId].lname ,
720
- data: JSON.stringify(data)
721
- });*/
715
+ user_id: res.locals.userId,
716
+ table: MYMODEL.table,
717
+ id_data: data.id,
718
+ status: data.status,
719
+ status_label: MYMODEL.widgets.status.fields[data.status],
720
+ title: MYMODEL.widgets.status.fields[data.status],
721
+ description: users[res.locals.userId].fname + " " +users[res.locals.userId].lname ,
722
+ data: JSON.stringify(data)
723
+ });*/
722
724
  //if serial
723
725
  if (data.type == 2) {
724
726
  approvers = [approvers[0]];
@@ -788,38 +790,38 @@ router.post("/zzapproval", async (req, res) => {
788
790
  textWa += `Please click the link above to view the document.\r\n${link}`;
789
791
 
790
792
  /* await whatsapp({
791
- to: phone,
792
- text: textWa,
793
- sections: JSON.stringify(sections),
794
- buttonText: "Click me for details"
795
- });*/
793
+ to: phone,
794
+ text: textWa,
795
+ sections: JSON.stringify(sections),
796
+ buttonText: "Click me for details"
797
+ });*/
796
798
  }
797
799
 
798
800
  //send notification
799
801
  /* await zRoute.insertSQL(req, res, "znotification", {
800
- user_id: item,
801
- table: MYMODEL.table,
802
- id_data: data.id,
803
- status: 1,
804
- link: "/za/" + post.token,
805
- status_label: MYMODEL.widgets.status.fields[1],
806
- title: `Need Approve`,
807
- description: data.title,
808
- token: post.token
809
- });*/
802
+ user_id: item,
803
+ table: MYMODEL.table,
804
+ id_data: data.id,
805
+ status: 1,
806
+ link: "/za/" + post.token,
807
+ status_label: MYMODEL.widgets.status.fields[1],
808
+ title: `Need Approve`,
809
+ description: data.title,
810
+ token: post.token
811
+ });*/
810
812
 
811
813
  //send todolist
812
814
  /* await zRoute.insertSQL(req, res, "ztodolist", {
813
- user_id: item,
814
- table: MYMODEL.table,
815
- id_data: data.id,
816
- status: 1,
817
- link: "/za/" + post.token,
818
- status_label: MYMODEL.widgets.status.fields[1],
819
- title: `Need Approve`,
820
- description: data.title,
821
- users: JSON.stringify(allUsers)
822
- });*/
815
+ user_id: item,
816
+ table: MYMODEL.table,
817
+ id_data: data.id,
818
+ status: 1,
819
+ link: "/za/" + post.token,
820
+ status_label: MYMODEL.widgets.status.fields[1],
821
+ title: `Need Approve`,
822
+ description: data.title,
823
+ users: JSON.stringify(allUsers)
824
+ });*/
823
825
 
824
826
  //send toastr using socket.io
825
827
  io.to(users[item].token).emit("message", "Need Approve " + data.title);
@@ -865,50 +867,50 @@ router.post("/zzapproval", async (req, res) => {
865
867
  textWa += "We have some document for you.\r\n";
866
868
  textWa += `Please click the link above to view the document.\r\n${link}`;
867
869
  /* await whatsapp({
868
- to: phone,
869
- text: textWa,
870
- sections: JSON.stringify(sections),
871
- buttonText: "Click me for details"
872
- });*/
870
+ to: phone,
871
+ text: textWa,
872
+ sections: JSON.stringify(sections),
873
+ buttonText: "Click me for details"
874
+ });*/
873
875
  }
874
876
 
875
877
  //send activity
876
878
  /* await cRoute.insertSQL(req, res, "zactivity",{
877
- user_id:item,
878
- table:MYMODEL.table,
879
- id_data:data.id,
880
- status:7,
881
- status_label: MYMODEL.widgets.status.fields[7],
882
- title : MYMODEL.widgets.status.fields[7],
883
- description: data.title,
884
- data:JSON.stringify(data)
885
- });*/
879
+ user_id:item,
880
+ table:MYMODEL.table,
881
+ id_data:data.id,
882
+ status:7,
883
+ status_label: MYMODEL.widgets.status.fields[7],
884
+ title : MYMODEL.widgets.status.fields[7],
885
+ description: data.title,
886
+ data:JSON.stringify(data)
887
+ });*/
886
888
 
887
889
  //send notification
888
890
  /* await zRoute.insertSQL(req, res, "znotification", {
889
- user_id: item,
890
- table: MYMODEL.table,
891
- id_data: data.id,
892
- status: 1,
893
- link: "/za/" + post.token,
894
- status_label: MYMODEL.widgets.status.fields[1],
895
- title: `Need Acknowledge`,
896
- description: data.title,
897
- token: post.token
898
- });
899
-
900
- //send todolist
901
- await zRoute.insertSQL(req, res, "ztodolist", {
902
- user_id: item,
903
- table: MYMODEL.table,
904
- id_data: data.id,
905
- status: 1,
906
- link: "/za/" + post.token,
907
- status_label: MYMODEL.widgets.status.fields[1],
908
- title: `Need Acknowledge`,
909
- description: data.title,
910
- users: JSON.stringify(allUsers)
911
- });*/
891
+ user_id: item,
892
+ table: MYMODEL.table,
893
+ id_data: data.id,
894
+ status: 1,
895
+ link: "/za/" + post.token,
896
+ status_label: MYMODEL.widgets.status.fields[1],
897
+ title: `Need Acknowledge`,
898
+ description: data.title,
899
+ token: post.token
900
+ });
901
+
902
+ //send todolist
903
+ await zRoute.insertSQL(req, res, "ztodolist", {
904
+ user_id: item,
905
+ table: MYMODEL.table,
906
+ id_data: data.id,
907
+ status: 1,
908
+ link: "/za/" + post.token,
909
+ status_label: MYMODEL.widgets.status.fields[1],
910
+ title: `Need Acknowledge`,
911
+ description: data.title,
912
+ users: JSON.stringify(allUsers)
913
+ });*/
912
914
  io.to(users[item].token).emit(
913
915
  "message",
914
916
  "Need Acknowledge " + data.title
@@ -1044,23 +1046,23 @@ router.get("/za/:token", csrfProtection, async (req, res) => {
1044
1046
  if (result.mystatus == 7) {
1045
1047
  MYMODEL = MYMODELS["zapprovals"];
1046
1048
  /* await connection.insert({
1047
- table: "zactivity",
1048
- data: {
1049
- company_id: result.company_id,
1050
- created_at: Util.now(),
1051
- created_by: result.user_id,
1052
- updated_by: result.user_id,
1053
- user_id: result.user_id,
1054
- table: MYMODEL.table,
1055
- id_data: result.ide,
1056
- status: 6,
1057
- status_label: MYMODEL.widgets.status.fields[6],
1058
- title: `${MYMODEL.widgets.status.fields[6]}`,
1059
- description: `Ok `,
1060
- data: JSON.stringify(data)
1061
- }
1062
- });
1063
- */
1049
+ table: "zactivity",
1050
+ data: {
1051
+ company_id: result.company_id,
1052
+ created_at: Util.now(),
1053
+ created_by: result.user_id,
1054
+ updated_by: result.user_id,
1055
+ user_id: result.user_id,
1056
+ table: MYMODEL.table,
1057
+ id_data: result.ide,
1058
+ status: 6,
1059
+ status_label: MYMODEL.widgets.status.fields[6],
1060
+ title: `${MYMODEL.widgets.status.fields[6]}`,
1061
+ description: `Ok `,
1062
+ data: JSON.stringify(data)
1063
+ }
1064
+ });
1065
+ */
1064
1066
 
1065
1067
  await connection.update({
1066
1068
  table: "zapprovals_details",
@@ -1763,16 +1765,15 @@ router.post("/zcompress-dropzone", async (req, res) => {
1763
1765
  },
1764
1766
  });
1765
1767
  //check for temp dir
1766
-
1767
1768
  if (result.lock == 1) {
1768
1769
  let message = `Data has been locked, please unlock first to compress images `;
1769
1770
  io.to(room).emit("errormessage", message);
1770
1771
  res.json(Util.flashError(message));
1771
1772
  } else {
1772
1773
  const config = {
1773
- jpeg: { quality: 50, compressionLevel: 5 },
1774
- webp: { quality: 50, compressionLevel: 5 },
1775
- png: { quality: 50, compressionLevel: 5 },
1774
+ jpeg: { quality: 60, compressionLevel: 9 },
1775
+ webp: { quality: 60, compressionLevel: 9 },
1776
+ png: { quality: 60, compressionLevel: 9 },
1776
1777
  };
1777
1778
  const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1778
1779
  const timeExcecute = 200;
@@ -1804,7 +1805,12 @@ router.post("/zcompress-dropzone", async (req, res) => {
1804
1805
  await wait(timeExcecute); // Wait for file system
1805
1806
  let image;
1806
1807
  try {
1807
- image = sharp(tempPath);
1808
+ image = sharp(tempPath).resize({
1809
+ width: 1024,
1810
+ height: null, // Maintain aspect ratio
1811
+ fit: "inside",
1812
+ withoutEnlargement: true, // Don't enlarge if image is smaller than 1024px
1813
+ });
1808
1814
  } catch (error) {
1809
1815
  console.log(`Skipping ${filename} - not a valid image file`);
1810
1816
  io.to(room).emit(
@@ -1969,7 +1975,6 @@ router.post("/zdropbox/:table/:field", handleTokenRefresh, async (req, res) => {
1969
1975
  if (!req.files || !req.files.file) {
1970
1976
  return res.status(400).json({ error: "No file uploaded" });
1971
1977
  }
1972
-
1973
1978
  const userId = res.locals.userId;
1974
1979
  const table = req.params.table;
1975
1980
  const field = req.params.field;
@@ -1979,10 +1984,9 @@ router.post("/zdropbox/:table/:field", handleTokenRefresh, async (req, res) => {
1979
1984
  const dir = `/temps/${table}/${field}/${userId}`;
1980
1985
  await ensureFolder(dir);
1981
1986
  const filePath = `${dir}/${fileName}`;
1982
-
1983
- console.log("Uploading file to path:", filePath);
1987
+ /*console.log("Uploading file to path:", filePath);
1984
1988
  console.log("File size:", file.size);
1985
- console.log("File name:", fileName);
1989
+ console.log("File name:", fileName);*/
1986
1990
 
1987
1991
  const response = await dbx.filesUpload({
1988
1992
  path: filePath,
@@ -1992,7 +1996,6 @@ router.post("/zdropbox/:table/:field", handleTokenRefresh, async (req, res) => {
1992
1996
  });
1993
1997
  res.json("ok");
1994
1998
  } catch (error) {
1995
- console.error("Upload error:", error);
1996
1999
  console.error("Error details:", {
1997
2000
  message: error.message,
1998
2001
  stack: error.stack,
@@ -2057,6 +2060,7 @@ router.post("/zdropbox-files", async (req, res) => {
2057
2060
  }
2058
2061
  res.json(datas);
2059
2062
  });
2063
+
2060
2064
  router.post("/zdropbox-file/:index", handleTokenRefresh, async (req, res) => {
2061
2065
  let datas = {};
2062
2066
  const room = res.locals.token;
@@ -2197,4 +2201,178 @@ router.get(
2197
2201
  }
2198
2202
  );
2199
2203
 
2204
+ // Download and zip files endpoint
2205
+ router.get("/zdownloads-dropbox/:table/:field/:id", async (req, res) => {
2206
+ try {
2207
+ let table = req.params.table;
2208
+ let field = req.params.field;
2209
+ let id = req.params.id;
2210
+ const room = res.locals.token;
2211
+ let result = await connection.result({
2212
+ table: table,
2213
+ where: {
2214
+ id: id,
2215
+ },
2216
+ });
2217
+ let dir = `${dirRoot}/public/uploads/${table}/${field}/`;
2218
+ let arr = [];
2219
+ let files = result[field];
2220
+ const jsZip = new JSZip();
2221
+ const filesToZip = [];
2222
+ // Download each file and add to zip
2223
+ let i = 0;
2224
+ let filePath = "";
2225
+ let fileName = "";
2226
+ const count = files.length || 0;
2227
+ for (const file of files) {
2228
+ try {
2229
+ filePath = `/${table}/${field}/${file}`;
2230
+ const response = await dbx.filesDownload({
2231
+ path: filePath,
2232
+ });
2233
+ // Get the file name from the path
2234
+ fileName = filePath.split("/").pop();
2235
+ // Add file to zip array
2236
+ jsZip.file(fileName, response.result.fileBinary);
2237
+ io.to(room).emit("progress", {
2238
+ value: Math.round(((i + 1) / count) * 100),
2239
+ style: `progress-bar progress-bar-striped bg-success`,
2240
+ data: `Download ${fileName} successfully`,
2241
+ });
2242
+ } catch (error) {
2243
+ console.error(`Error downloading file ${filePath}:`, error);
2244
+ io.to(room).emit("errormessage", `Error downloading file ${fileName} `);
2245
+ continue;
2246
+ }
2247
+ i++;
2248
+ }
2249
+ io.to(room).emit("progress", {
2250
+ value: 100,
2251
+ style: `progress-bar progress-bar-striped bg-success`,
2252
+ data: `Zip all images complete...`,
2253
+ });
2254
+ let time = new Date().getTime();
2255
+ let zipname = `${table}_${field}_${time}.zip`;
2256
+ // Generate zip file
2257
+ const zipBuffer = await jsZip.generateAsync({ type: "nodebuffer" });
2258
+ // Set response headers
2259
+ res.setHeader("Content-Type", "application/zip");
2260
+ res.setHeader(`Content-Disposition`, `attachment; filename=${zipname}`);
2261
+ // Send the zip file
2262
+ res.send(zipBuffer);
2263
+ } catch (error) {
2264
+ console.error("Error creating zip file:", error);
2265
+ res.status(500).json({
2266
+ error: "Failed to create zip file",
2267
+ details: error.message,
2268
+ });
2269
+ }
2270
+ });
2271
+
2272
+ //compress image di dropzone
2273
+ router.post("/zcompress-dropbox", async (req, res) => {
2274
+ let table = req.body.table;
2275
+ let field = req.body.field;
2276
+ let id = req.body.id;
2277
+ const room = res.locals.token;
2278
+ let userId = res.locals.userId;
2279
+ try {
2280
+ let result = await connection.result({
2281
+ table: table,
2282
+ where: {
2283
+ id: id,
2284
+ },
2285
+ });
2286
+ //check for temp dir
2287
+ if (result.lock == 1) {
2288
+ let message = `Data has been locked, please unlock first to compress images `;
2289
+ io.to(room).emit("errormessage", message);
2290
+ res.json(Util.flashError(message));
2291
+ } else {
2292
+ let arr = [];
2293
+ let files = result[field];
2294
+ const count = files.length || 0;
2295
+ let i = 0;
2296
+ for (const file of files) {
2297
+ const filePath = `/${table}/${field}/${file}`;
2298
+ let ext = file.toLowerCase().split(".").pop();
2299
+ if (ext == "png" || ext == "jpg" || ext == "jpeg") {
2300
+ try {
2301
+ // Download the file from Dropbox
2302
+ const response = await dbx.filesDownload({
2303
+ path: filePath,
2304
+ });
2305
+ // Get the file name from the path
2306
+ const fileName = file;
2307
+ // Process the image with sharp
2308
+ const processedImage = await sharp(response.result.fileBinary)
2309
+ .resize({
2310
+ width: 1024,
2311
+ height: null, // Maintain aspect ratio
2312
+ fit: "inside",
2313
+ withoutEnlargement: true, // Don't enlarge if image is smaller than 1024px
2314
+ })
2315
+ .toBuffer()
2316
+ .then((buffer) => {
2317
+ // Check if the file is PNG
2318
+ if (fileName.toLowerCase().endsWith(".png")) {
2319
+ return sharp(buffer)
2320
+ .png({
2321
+ quality: 60,
2322
+ compressionLevel: 9, // Maximum compression for PNG
2323
+ })
2324
+ .toBuffer();
2325
+ } else {
2326
+ // For JPEG files
2327
+ return sharp(buffer)
2328
+ .jpeg({
2329
+ quality: 60,
2330
+ mozjpeg: true, // Better compression
2331
+ })
2332
+ .toBuffer();
2333
+ }
2334
+ });
2335
+
2336
+ // Upload the compressed image back to Dropbox
2337
+ await dbx.filesUpload({
2338
+ path: filePath,
2339
+ contents: processedImage,
2340
+ mode: { ".tag": "overwrite" }, // This will replace the existing file
2341
+ });
2342
+ io.to(room).emit("progress", {
2343
+ value: Math.round(((i + 1) / count) * 100),
2344
+ style: `progress-bar progress-bar-striped bg-success`,
2345
+ data: `Compress ${fileName} Successfully..`,
2346
+ });
2347
+ } catch (error) {
2348
+ console.error(`Error processing file ${filePath}:`, error);
2349
+ io.to(room).emit("progress", {
2350
+ value: Math.round(((i + 1) / count) * 100),
2351
+ style: `progress-bar progress-bar-striped bg-danger`,
2352
+ data: `Error Compress ${fileName} ${error.message}..`,
2353
+ });
2354
+ continue;
2355
+ }
2356
+ } else {
2357
+ io.to(room).emit("progress", {
2358
+ value: Math.round(((i + 1) / count) * 100),
2359
+ style: `progress-bar progress-bar-striped bg-danger`,
2360
+ data: `Skip Compress ${fileName} skip..`,
2361
+ });
2362
+ }
2363
+ i++;
2364
+ }
2365
+ }
2366
+ } catch (e) {
2367
+ console.log(e);
2368
+ res.json(e + "");
2369
+ }
2370
+ io.to(room).emit("progress", {
2371
+ value: 100,
2372
+ style: `progress-bar progress-bar-striped bg-success`,
2373
+ data: `Compress all images complete...`,
2374
+ });
2375
+ res.json(Util.jsonSuccess("Compress all images completed..."));
2376
+ });
2377
+
2200
2378
  module.exports = router;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zet-lib",
3
- "version": "1.4.19",
3
+ "version": "1.4.21",
4
4
  "description": "zet is a library that part of zet generator.",
5
5
  "engines": {
6
6
  "node": ">=18"
@@ -40,6 +40,7 @@
40
40
  "html-minifier-terser": "^7.2.0",
41
41
  "isomorphic-fetch": "^3.0.0",
42
42
  "js-sha256": "^0.9.0",
43
+ "jszip": "^3.10.1",
43
44
  "moment": "^2.30.1",
44
45
  "node-cache": "^5.1.2",
45
46
  "nodemailer": "^6.9.4",