zet-lib 1.5.13 → 1.5.15
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/Mail.js +4 -0
- package/lib/Util.js +36 -0
- package/lib/connection.js +103 -3
- package/lib/zAppRouter.js +4 -0
- package/lib/zDropbox.js +4 -0
- package/lib/zGeneratorRouter.js +4 -0
- package/lib/zMenuRouter.js +3 -0
- package/lib/zPage.js +3 -0
- package/lib/zReport.js +3 -0
- package/lib/zRoute.js +3 -0
- package/lib/zViewGenerator.js +4 -0
- package/package.json +1 -1
package/lib/Mail.js
CHANGED
|
@@ -6,6 +6,10 @@ const io = require('./io')
|
|
|
6
6
|
const moment = require('moment')
|
|
7
7
|
const config = require('dotenv').config()
|
|
8
8
|
|
|
9
|
+
if (typeof global.dirRoot === 'undefined') {
|
|
10
|
+
global.dirRoot = Util.dirRoot;
|
|
11
|
+
}
|
|
12
|
+
|
|
9
13
|
const MAIL = {}
|
|
10
14
|
//process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
11
15
|
|
package/lib/Util.js
CHANGED
|
@@ -7,6 +7,42 @@ const sha256 = require("js-sha256");
|
|
|
7
7
|
|
|
8
8
|
const Util = {};
|
|
9
9
|
|
|
10
|
+
|
|
11
|
+
// Global directory root - automatically detect application root
|
|
12
|
+
Util.dirRoot = (() => {
|
|
13
|
+
// Start from the zet-lib directory and navigate up to find the main application root
|
|
14
|
+
let currentDir = __dirname; // This is zet-lib/lib/
|
|
15
|
+
|
|
16
|
+
// Navigate up 3 levels: lib/ -> zet-lib/ -> node_modules/ -> fins_node/
|
|
17
|
+
currentDir = path.dirname(currentDir); // zet-lib/
|
|
18
|
+
currentDir = path.dirname(currentDir); // node_modules/
|
|
19
|
+
currentDir = path.dirname(currentDir); // fins_node/ (main app root)
|
|
20
|
+
|
|
21
|
+
// Verify this is the correct application root
|
|
22
|
+
const hasPackageJson = fs.existsSync(path.join(currentDir, 'package.json'));
|
|
23
|
+
const hasAppJs = fs.existsSync(path.join(currentDir, 'app.js'));
|
|
24
|
+
|
|
25
|
+
if (hasPackageJson && hasAppJs) {
|
|
26
|
+
return currentDir;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Fallback: try to find the app root by looking for typical Node.js app files
|
|
30
|
+
let searchDir = currentDir;
|
|
31
|
+
while (searchDir !== path.dirname(searchDir)) {
|
|
32
|
+
const hasPackageJson = fs.existsSync(path.join(searchDir, 'package.json'));
|
|
33
|
+
const hasAppJs = fs.existsSync(path.join(searchDir, 'app.js'));
|
|
34
|
+
|
|
35
|
+
if (hasPackageJson && hasAppJs) {
|
|
36
|
+
return searchDir;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
searchDir = path.dirname(searchDir);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Final fallback to the calculated directory
|
|
43
|
+
return currentDir;
|
|
44
|
+
})();
|
|
45
|
+
|
|
10
46
|
// Constants
|
|
11
47
|
Util.tab = "\t";
|
|
12
48
|
Util.NEW_LINE = "\n";
|
package/lib/connection.js
CHANGED
|
@@ -324,7 +324,7 @@ connection.delete = async (obj) => {
|
|
|
324
324
|
}
|
|
325
325
|
wherequery = arr.length ? wherequery.join(' AND ') : ''
|
|
326
326
|
const wheres = arr.length ? ' WHERE ' + wherequery : ''
|
|
327
|
-
const sql = `DELETE FROM "${table}" ${wheres}
|
|
327
|
+
const sql = `DELETE FROM "${table}" ${wheres} RETURNING *`
|
|
328
328
|
/*console.log(sql);
|
|
329
329
|
console.log(arr)*/
|
|
330
330
|
try {
|
|
@@ -337,14 +337,114 @@ connection.delete = async (obj) => {
|
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
339
|
|
|
340
|
+
connection.insertData = async(tableName, data) => {
|
|
341
|
+
let pgPool;
|
|
342
|
+
try {
|
|
343
|
+
// Validasi input
|
|
344
|
+
if (!data || typeof data !== 'object') {
|
|
345
|
+
throw new Error('Invalid data provided for insert');
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
pgPool = new Pool(configPG);
|
|
349
|
+
|
|
350
|
+
const columns = Object.keys(data);
|
|
351
|
+
if (columns.length === 0) {
|
|
352
|
+
throw new Error('No columns found in the data object');
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const placeholders = columns.map((_, index) => `$${index + 1}`).join(',');
|
|
356
|
+
const insertQuery = `
|
|
357
|
+
INSERT INTO "${tableName}" (${columns.map(col => `"${col}"`).join(',')})
|
|
358
|
+
VALUES (${placeholders})
|
|
359
|
+
RETURNING *
|
|
360
|
+
`;
|
|
361
|
+
const values = columns.map(col => data[col]);
|
|
362
|
+
const result = await pgPool.query(insertQuery, values);
|
|
363
|
+
console.log(`Successfully inserted 1 record into ${tableName}`);
|
|
364
|
+
return result.rows[0];
|
|
365
|
+
} catch (error) {
|
|
366
|
+
console.error(`Error inserting record into ${tableName}:`, error);
|
|
367
|
+
throw error;
|
|
368
|
+
} finally {
|
|
369
|
+
if (pgPool) {
|
|
370
|
+
await pgPool.end();
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
connection.deleteData = async(tableName, where) => {
|
|
376
|
+
let pgPool;
|
|
377
|
+
try {
|
|
378
|
+
// Validasi input
|
|
379
|
+
if (!where || typeof where !== 'object') {
|
|
380
|
+
throw new Error('Invalid where clause provided for delete');
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
pgPool = new Pool(configPG);
|
|
384
|
+
|
|
385
|
+
const whereColumns = Object.keys(where);
|
|
386
|
+
if (whereColumns.length === 0) {
|
|
387
|
+
throw new Error('No where conditions provided for delete');
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const whereConditions = whereColumns.map((col, index) => `"${col}" = $${index + 1}`).join(' AND ');
|
|
391
|
+
const deleteQuery = `
|
|
392
|
+
DELETE FROM "${tableName}"
|
|
393
|
+
WHERE ${whereConditions}
|
|
394
|
+
RETURNING *
|
|
395
|
+
`;
|
|
396
|
+
const values = whereColumns.map(col => where[col]);
|
|
397
|
+
const result = await pgPool.query(deleteQuery, values);
|
|
398
|
+
console.log(`Successfully deleted ${result.rowCount} records from ${tableName}`);
|
|
399
|
+
return result.rowCount;
|
|
400
|
+
} catch (error) {
|
|
401
|
+
console.error(`Error deleting records from ${tableName}:`, error);
|
|
402
|
+
throw error;
|
|
403
|
+
} finally {
|
|
404
|
+
if (pgPool) {
|
|
405
|
+
await pgPool.end();
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
340
410
|
connection.insertMultipleRecords = async(tableName,records) => {
|
|
341
411
|
let pgPool;
|
|
342
412
|
try {
|
|
413
|
+
// Validasi input
|
|
414
|
+
if (!records || !Array.isArray(records) || records.length === 0) {
|
|
415
|
+
console.warn(`No records to insert into ${tableName}`);
|
|
416
|
+
return [];
|
|
417
|
+
}
|
|
418
|
+
|
|
343
419
|
pgPool = new Pool(configPG);
|
|
344
|
-
|
|
420
|
+
|
|
421
|
+
// Validasi bahwa semua records memiliki struktur yang sama
|
|
422
|
+
const firstRecord = records[0];
|
|
423
|
+
if (!firstRecord || typeof firstRecord !== 'object') {
|
|
424
|
+
throw new Error('First record is invalid or empty');
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
const columns = Object.keys(firstRecord);
|
|
428
|
+
if (columns.length === 0) {
|
|
429
|
+
throw new Error('No columns found in the first record');
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Validasi bahwa semua records memiliki kolom yang sama
|
|
433
|
+
for (let i = 1; i < records.length; i++) {
|
|
434
|
+
const record = records[i];
|
|
435
|
+
if (!record || typeof record !== 'object') {
|
|
436
|
+
throw new Error(`Record at index ${i} is invalid`);
|
|
437
|
+
}
|
|
438
|
+
const recordColumns = Object.keys(record);
|
|
439
|
+
if (recordColumns.length !== columns.length || !recordColumns.every(col => columns.includes(col))) {
|
|
440
|
+
throw new Error(`Record at index ${i} has different structure than the first record`);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
345
444
|
const placeholders = records.map((_, rowIndex) =>
|
|
346
445
|
`(${columns.map((_, colIndex) => `$${rowIndex * columns.length + colIndex + 1}`).join(',')})`
|
|
347
446
|
).join(',');
|
|
447
|
+
|
|
348
448
|
// Create the INSERT query
|
|
349
449
|
const insertQuery = `
|
|
350
450
|
INSERT INTO "${tableName}" (${columns.map(col => `"${col}"`).join(',')})
|
|
@@ -353,7 +453,7 @@ connection.insertMultipleRecords = async(tableName,records) => {
|
|
|
353
453
|
`;
|
|
354
454
|
const values = records.flatMap(record => columns.map(col => record[col]));
|
|
355
455
|
const result = await pgPool.query(insertQuery, values);
|
|
356
|
-
|
|
456
|
+
console.log(`Successfully inserted ${records.length} records into ${tableName}`);
|
|
357
457
|
return result.rows;
|
|
358
458
|
} catch (error) {
|
|
359
459
|
console.error(`Error inserting multiple records into ${tableName}:`, error);
|
package/lib/zAppRouter.js
CHANGED
package/lib/zDropbox.js
CHANGED
package/lib/zGeneratorRouter.js
CHANGED
package/lib/zMenuRouter.js
CHANGED
|
@@ -12,6 +12,9 @@ const moduleLib = require('./moduleLib');
|
|
|
12
12
|
const config = require('dotenv').config();
|
|
13
13
|
const ejs = require('ejs');
|
|
14
14
|
|
|
15
|
+
if (typeof global.dirRoot === 'undefined') {
|
|
16
|
+
global.dirRoot = Util.dirRoot;
|
|
17
|
+
}
|
|
15
18
|
/*
|
|
16
19
|
icons list for tabler and set to /public/js
|
|
17
20
|
*/
|
package/lib/zPage.js
CHANGED
|
@@ -12,6 +12,9 @@ const connection = require('./connection');
|
|
|
12
12
|
const Util = require('./Util');
|
|
13
13
|
const myCache = require('./cache');
|
|
14
14
|
|
|
15
|
+
if (typeof global.dirRoot === 'undefined') {
|
|
16
|
+
global.dirRoot = Util.dirRoot;
|
|
17
|
+
}
|
|
15
18
|
const zpage = {};
|
|
16
19
|
|
|
17
20
|
zpage.build = async (req, res) => {
|
package/lib/zReport.js
CHANGED
package/lib/zRoute.js
CHANGED
|
@@ -24,6 +24,9 @@ const readXlsxFile = require("read-excel-file/node");
|
|
|
24
24
|
//const { Dropbox } = require("dropbox");
|
|
25
25
|
const zDropbox = require("./zDropbox");
|
|
26
26
|
|
|
27
|
+
if (typeof global.dirRoot === 'undefined') {
|
|
28
|
+
global.dirRoot = Util.dirRoot;
|
|
29
|
+
}
|
|
27
30
|
const zRoute = {};
|
|
28
31
|
|
|
29
32
|
zRoute.tableHasNoCompanyId = ["zcompany", "zrole", "zgrid"];
|
package/lib/zViewGenerator.js
CHANGED
|
@@ -11,6 +11,10 @@ const Model = require('./Model')
|
|
|
11
11
|
const ejs = require('ejs')
|
|
12
12
|
const pm2 = require("pm2");
|
|
13
13
|
|
|
14
|
+
if (typeof global.dirRoot === 'undefined') {
|
|
15
|
+
global.dirRoot = Util.dirRoot;
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
router.get('/', csrfProtection, async (req, res) => {
|
|
15
19
|
const nots = ['index', 'uploads', 'js', 'css', 'log', 'generator', 'zmenu', 'zgenerator', 'zfields', 'zrole', 'zfunction', 'zgrid', 'zgrid_default', 'zpage', 'zlayout', 'zerror', 'zuser_company']
|
|
16
20
|
let table = req.query.table || '';
|