@7365admin1/core 2.51.0 → 2.52.0

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/index.mjs CHANGED
@@ -13093,23 +13093,42 @@ var CameraType = /* @__PURE__ */ ((CameraType2) => {
13093
13093
  })(CameraType || {});
13094
13094
  var schemaUpdateSiteCamera = Joi34.object({
13095
13095
  host: Joi34.string().required(),
13096
- username: Joi34.string().required(),
13097
- password: Joi34.string().required(),
13096
+ username: Joi34.string().when("type", {
13097
+ is: "anpr",
13098
+ then: Joi34.required(),
13099
+ otherwise: Joi34.optional().allow(null, "")
13100
+ }),
13101
+ password: Joi34.string().when("type", {
13102
+ is: "anpr",
13103
+ then: Joi34.required(),
13104
+ otherwise: Joi34.optional().allow(null, "")
13105
+ }),
13098
13106
  category: Joi34.string().allow("standard", "resident", "visitor").required(),
13099
13107
  guardPost: Joi34.number().integer().optional(),
13100
- direction: Joi34.string().optional().allow("entry", "exit", "both", "none")
13108
+ direction: Joi34.string().optional().allow("entry", "exit", "both", "none"),
13109
+ status: Joi34.string().optional().allow("active", "inactive", "deleted"),
13110
+ name: Joi34.string().optional().allow(null, "")
13101
13111
  });
13102
13112
  var schemaSiteCamera = Joi34.object({
13103
13113
  _id: Joi34.string().hex().optional(),
13104
13114
  site: Joi34.string().hex().required(),
13105
13115
  host: Joi34.string().required(),
13106
- username: Joi34.string().required(),
13107
- password: Joi34.string().required(),
13116
+ username: Joi34.string().when("type", {
13117
+ is: "anpr",
13118
+ then: Joi34.required(),
13119
+ otherwise: Joi34.optional().allow(null, "")
13120
+ }),
13121
+ password: Joi34.string().when("type", {
13122
+ is: "anpr",
13123
+ then: Joi34.required(),
13124
+ otherwise: Joi34.optional().allow(null, "")
13125
+ }),
13108
13126
  type: Joi34.string().allow("ip", "anpr").required(),
13109
13127
  category: Joi34.string().allow("standard", "resident", "visitor").required(),
13110
13128
  direction: Joi34.string().required().allow("entry", "exit", "both", "none"),
13111
13129
  guardPost: Joi34.number().integer().optional(),
13112
13130
  status: Joi34.string().optional().allow("active", "inactive", "deleted"),
13131
+ name: Joi34.string().optional().allow(null, ""),
13113
13132
  createdAt: Joi34.date().optional(),
13114
13133
  updatedAt: Joi34.date().optional(),
13115
13134
  deletedAt: Joi34.date().optional()
@@ -13138,6 +13157,7 @@ function MSiteCamera(value) {
13138
13157
  guardPost: value.guardPost ?? 0,
13139
13158
  status: value.status ?? "active",
13140
13159
  direction: value.direction ?? "",
13160
+ name: value.name ?? "",
13141
13161
  createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
13142
13162
  updatedAt: value.updatedAt ?? "",
13143
13163
  deletedAt: value.deletedAt ?? ""
@@ -13458,7 +13478,24 @@ var schemaUpdateVisTrans = Joi36.object({
13458
13478
  checkInRemarks: Joi36.string().optional().allow("", null),
13459
13479
  checkOutRemarks: Joi36.string().optional().allow("", null),
13460
13480
  expectedCheckIn: Joi36.string().isoDate().optional(),
13461
- purpose: Joi36.string().optional().allow(null, "")
13481
+ purpose: Joi36.string().optional().allow(null, ""),
13482
+ members: Joi36.array().items(
13483
+ Joi36.object({
13484
+ name: Joi36.string().optional().allow(null, ""),
13485
+ nric: Joi36.string().optional().allow(null, ""),
13486
+ visitorPass: Joi36.array().items(
13487
+ Joi36.object({
13488
+ keyId: Joi36.string().hex().length(24).required()
13489
+ })
13490
+ ).optional().allow(null),
13491
+ passKeys: Joi36.array().items(
13492
+ Joi36.object({
13493
+ keyId: Joi36.string().hex().length(24).required()
13494
+ })
13495
+ ).optional().allow(null),
13496
+ contact: Joi36.string().optional().allow(null, "")
13497
+ })
13498
+ ).optional().allow(null)
13462
13499
  });
13463
13500
  function MVisitorTransaction(value) {
13464
13501
  const { error } = schemaVisitorTransaction.validate(value, {
@@ -13908,14 +13945,14 @@ function useVisitorTransactionRepo() {
13908
13945
  );
13909
13946
  }
13910
13947
  }
13911
- async function updateById(_id, value, session, isNotManualCheckOut = true) {
13948
+ async function updateById(_id, value, session, isManualCheckOut = true) {
13912
13949
  try {
13913
13950
  _id = new ObjectId40(_id);
13914
13951
  } catch (error) {
13915
13952
  throw new BadRequestError66("Invalid visitor transaction ID format.");
13916
13953
  }
13917
13954
  value.updatedAt = /* @__PURE__ */ new Date();
13918
- if (value.checkOut && isNotManualCheckOut) {
13955
+ if (value.checkOut && isManualCheckOut) {
13919
13956
  value.manualCheckout = true;
13920
13957
  }
13921
13958
  try {
@@ -17371,7 +17408,7 @@ function useDahuaService() {
17371
17408
  );
17372
17409
  }
17373
17410
  }
17374
- if (["entry", "both"].includes(designation) && direction.toLowerCase() === "approach" && plateNumber) {
17411
+ if (["entry"].includes(designation) && plateNumber) {
17375
17412
  await closeOpenTransaction(plateNumber);
17376
17413
  const vehicle = await getVehicleByPlateNumber(plateNumber);
17377
17414
  const visitorTransaction = {
@@ -17426,11 +17463,11 @@ function useDahuaService() {
17426
17463
  } catch (error) {
17427
17464
  console.log("failed to create visitor transaction", error);
17428
17465
  loggerDahua.error(
17429
- `[${site}][${gate}] Error creating visitor transaction:`,
17466
+ `[${site}][${host}] Error creating visitor transaction:`,
17430
17467
  error
17431
17468
  );
17432
17469
  }
17433
- } else if (["exit", "both"].includes(designation) && direction.toLowerCase() === "leave" && plateNumber) {
17470
+ } else if (["exit"].includes(designation) && plateNumber) {
17434
17471
  const vehicle = await getVehicleByPlateNumber(plateNumber);
17435
17472
  const existingOpenTransaction = await getOpenByPlateNumber(
17436
17473
  plateNumber,
@@ -17455,6 +17492,92 @@ function useDahuaService() {
17455
17492
  if (onDetected2) {
17456
17493
  onDetected2({ reload: true, site: existingOpenTransaction?.site?.toString(), host, direction });
17457
17494
  }
17495
+ } else if (["both"].includes(designation) && plateNumber) {
17496
+ if (direction.toLowerCase() === "leave") {
17497
+ const vehicle = await getVehicleByPlateNumber(plateNumber);
17498
+ const existingOpenTransaction = await getOpenByPlateNumber(
17499
+ plateNumber,
17500
+ site
17501
+ );
17502
+ if (existingOpenTransaction?._id) {
17503
+ currentTransactionId = existingOpenTransaction._id.toString();
17504
+ currentSnapshotField = "snapshotExitImage";
17505
+ }
17506
+ if (vehicle?.recNo) {
17507
+ const dahuaPayload = {
17508
+ host,
17509
+ username,
17510
+ password,
17511
+ plateNumber,
17512
+ mode: "TrafficRedList" /* TRAFFIC_REDLIST */,
17513
+ recno: vehicle?.recNo
17514
+ };
17515
+ await removePlateNumber(dahuaPayload);
17516
+ }
17517
+ await closeOpenTransaction(plateNumber);
17518
+ if (onDetected2 && existingOpenTransaction?.site) {
17519
+ onDetected2({ reload: true, site: existingOpenTransaction?.site?.toString(), host, direction });
17520
+ }
17521
+ } else if (direction.toLowerCase() === "approach") {
17522
+ await closeOpenTransaction(plateNumber);
17523
+ const vehicle = await getVehicleByPlateNumber(plateNumber);
17524
+ const visitorTransaction = {
17525
+ site,
17526
+ plateNumber,
17527
+ org,
17528
+ status: "unregistered" /* UNREGISTERED */
17529
+ };
17530
+ const typesForAutoRegister = Object.values(PersonTypes);
17531
+ let startDate = vehicle?.start ? new Date(vehicle?.start) : /* @__PURE__ */ new Date();
17532
+ let endDate = vehicle?.end ? new Date(vehicle?.end) : new Date(startDate.getTime() + 60 * 60 * 1e3);
17533
+ if (vehicle && typeof vehicle.category === "string" && typesForAutoRegister.includes(vehicle.category)) {
17534
+ visitorTransaction.name = vehicle.name;
17535
+ visitorTransaction.nric = vehicle.nric;
17536
+ visitorTransaction.contact = vehicle.phoneNumber;
17537
+ visitorTransaction.block = Number(vehicle.block);
17538
+ visitorTransaction.level = vehicle.level;
17539
+ visitorTransaction.unit = vehicle.unit?.toString();
17540
+ visitorTransaction.unitName = vehicle.unitName;
17541
+ visitorTransaction.type = vehicle.category;
17542
+ visitorTransaction.status = "registered" /* REGISTERED */;
17543
+ visitorTransaction.recNo = vehicle.recNo;
17544
+ visitorTransaction.expiredAt = vehicle.end;
17545
+ }
17546
+ const dahuaPayload = {
17547
+ host,
17548
+ username,
17549
+ password,
17550
+ plateNumber,
17551
+ mode: "TrafficRedList" /* TRAFFIC_REDLIST */,
17552
+ owner: vehicle?.name ?? ""
17553
+ };
17554
+ dahuaPayload.start = formatDahuaDate(startDate);
17555
+ dahuaPayload.end = formatDahuaDate(endDate);
17556
+ const shouldHaveTimeLimit = visitorTransaction.type === "guest" /* GUEST */ || visitorTransaction.status === "unregistered" /* UNREGISTERED */;
17557
+ if (shouldHaveTimeLimit) {
17558
+ const startDate2 = /* @__PURE__ */ new Date();
17559
+ const endDate2 = new Date(startDate2.getTime() + 60 * 60 * 1e3);
17560
+ dahuaPayload.start = formatDahuaDate(startDate2);
17561
+ dahuaPayload.end = formatDahuaDate(endDate2);
17562
+ visitorTransaction.expiredAt = endDate2.toISOString();
17563
+ }
17564
+ try {
17565
+ await addPlateNumber(dahuaPayload);
17566
+ const result = await add(visitorTransaction, void 0, true);
17567
+ const transactionId = result?._id;
17568
+ currentTransactionId = transactionId?.toString();
17569
+ currentSnapshotField = "snapshotEntryImage";
17570
+ if (onDetected2) {
17571
+ onDetected2({ _id: transactionId, site: result?.site?.toString(), plateNumber: result.plateNumber, host, direction });
17572
+ }
17573
+ } catch (error) {
17574
+ console.log("failed to create visitor transaction", error);
17575
+ loggerDahua.error(
17576
+ `[${site}][${host}] Error creating visitor transaction:`,
17577
+ error
17578
+ );
17579
+ }
17580
+ }
17458
17581
  }
17459
17582
  }
17460
17583
  }
@@ -17586,6 +17709,9 @@ function useDahuaService() {
17586
17709
  }
17587
17710
  }
17588
17711
  async function listenToCamera(camera, onDetected) {
17712
+ if (camera?.type != "anpr" && camera?.status != "deleted") {
17713
+ return;
17714
+ }
17589
17715
  if (onDetected) {
17590
17716
  _savedOnDetected = onDetected;
17591
17717
  }
@@ -17594,6 +17720,14 @@ function useDahuaService() {
17594
17720
  return;
17595
17721
  }
17596
17722
  const cameraId = camera._id.toString();
17723
+ if (camera.status !== "active") {
17724
+ if (cameraRegistry.has(cameraId)) {
17725
+ loggerDahua.info(`[${camera?.host ?? camera?._id}] Camera is ${camera.status}. Stopping connection.`);
17726
+ cameraRegistry.get(cameraId)?.abort();
17727
+ cameraRegistry.delete(cameraId);
17728
+ }
17729
+ return;
17730
+ }
17597
17731
  if (cameraRegistry.has(cameraId)) {
17598
17732
  loggerDahua.info(`[${camera.host}] Stopping existing connection for update.`);
17599
17733
  cameraRegistry.get(cameraId)?.abort();
@@ -17741,6 +17875,9 @@ function useDahuaService() {
17741
17875
  continue;
17742
17876
  } else if ([400, 401, 403, 500].includes(response.statusCode)) {
17743
17877
  loggerDahua.error(`[${host}] Connection error: ${response.statusCode}`);
17878
+ if (onDetected) {
17879
+ onDetected({ site, messagePermanent: `Camera with last 3 characters ${host?.slice(-3)} Connection Error. Check username and password.` });
17880
+ }
17744
17881
  return;
17745
17882
  }
17746
17883
  loggerDahua.info(`[${host}] Successfully connected to ANPR.`);
@@ -17793,8 +17930,15 @@ function useDahuaService() {
17793
17930
  break;
17794
17931
  }
17795
17932
  loggerDahua.error(
17796
- `[${host}] Connection lost or error: ${error.message || error}. Retrying in 5s...`
17933
+ `[${host}] Connection lost or error: ${error.message || error}. Retrying in 10 seconds...`
17797
17934
  );
17935
+ if (onDetected) {
17936
+ onDetected({
17937
+ site,
17938
+ host,
17939
+ message: `Camera in ${gate} Connection Lost. Retrying in 10 seconds. Check the camera if this issue persists, Or set the camera to Inactive to stop this notification.`
17940
+ });
17941
+ }
17798
17942
  } finally {
17799
17943
  if (bufferQueue?.destroy) {
17800
17944
  try {
@@ -17815,7 +17959,7 @@ function useDahuaService() {
17815
17959
  }
17816
17960
  }
17817
17961
  if (!signal.aborted) {
17818
- await new Promise((res) => setTimeout(res, 5e3));
17962
+ await new Promise((res) => setTimeout(res, 1e4));
17819
17963
  }
17820
17964
  }
17821
17965
  loggerDahua.info(`[${host}] ANPR Listener stopped.`);
@@ -18317,6 +18461,8 @@ function useSiteCameraRepo() {
18317
18461
  }
18318
18462
  try {
18319
18463
  await collection.deleteOne({ _id }, { session });
18464
+ const { listenToCamera } = useDahuaService();
18465
+ await listenToCamera({ _id, status: "deleted" });
18320
18466
  delCachedData();
18321
18467
  return "Successfully deleted site camera.";
18322
18468
  } catch (error) {
@@ -19168,7 +19314,7 @@ function useBuildingRepo() {
19168
19314
  }
19169
19315
  }
19170
19316
  }
19171
- async function getBuildingLevel(site, block) {
19317
+ async function getBuildingLevel(site, block, isVMS) {
19172
19318
  try {
19173
19319
  site = new ObjectId49(site);
19174
19320
  } catch (error) {
@@ -19178,8 +19324,7 @@ function useBuildingRepo() {
19178
19324
  site,
19179
19325
  block
19180
19326
  };
19181
- const cacheOptions = { ...query };
19182
- const cacheKey = makeCacheKey26(buildings_namespace_collection, cacheOptions);
19327
+ const cacheKey = makeCacheKey26(buildings_namespace_collection, { ...query, isVMS });
19183
19328
  try {
19184
19329
  const cached = await getCache(cacheKey);
19185
19330
  if (cached) {
@@ -19189,7 +19334,24 @@ function useBuildingRepo() {
19189
19334
  });
19190
19335
  return cached;
19191
19336
  }
19192
- const result = await collection.findOne(query);
19337
+ const pipeline = [{ $match: { ...query } }];
19338
+ if (isVMS) {
19339
+ pipeline.push({
19340
+ $lookup: {
19341
+ from: "building-levels",
19342
+ let: { id: "$_id" },
19343
+ pipeline: [
19344
+ {
19345
+ $match: {
19346
+ $expr: { $eq: ["$block", "$$id"] }
19347
+ }
19348
+ }
19349
+ ],
19350
+ as: "building_levels"
19351
+ }
19352
+ });
19353
+ }
19354
+ const result = await collection.aggregate(pipeline).toArray();
19193
19355
  setCache(cacheKey, result, 300).then(() => {
19194
19356
  logger60.log({
19195
19357
  level: "info",
@@ -19382,6 +19544,9 @@ function useBuildingService() {
19382
19544
  // src/controllers/building.controller.ts
19383
19545
  import { BadRequestError as BadRequestError81, logger as logger62 } from "@7365admin1/node-server-utils";
19384
19546
  import Joi44 from "joi";
19547
+ import ExcelJS from "exceljs";
19548
+ import csv from "csv-parser";
19549
+ import fs from "fs";
19385
19550
  function useBuildingController() {
19386
19551
  const {
19387
19552
  getAll: _getAll,
@@ -19403,7 +19568,10 @@ function useBuildingController() {
19403
19568
  serial: Joi44.string().optional().allow("", null),
19404
19569
  status: Joi44.string().optional().allow("", null),
19405
19570
  // buildingFloorPlan: Joi.array().items(Joi.string()).optional(),
19406
- buildingFiles: Joi44.array().items({ id: Joi44.string().hex().optional().allow("", null), name: Joi44.string().optional().allow("", null) }).optional().allow("", null)
19571
+ buildingFiles: Joi44.array().items({
19572
+ id: Joi44.string().hex().optional().allow("", null),
19573
+ name: Joi44.string().optional().allow("", null)
19574
+ }).optional().allow("", null)
19407
19575
  });
19408
19576
  const { error } = validation.validate(value);
19409
19577
  if (error) {
@@ -19523,6 +19691,7 @@ function useBuildingController() {
19523
19691
  async function getBuildingLevel(req, res, next) {
19524
19692
  const site = req.params.site ?? "";
19525
19693
  let block = req.query.block;
19694
+ const isVMS = req.query.isVMS;
19526
19695
  const validation = Joi44.object({
19527
19696
  site: Joi44.string().hex().required(),
19528
19697
  block: Joi44.number().required()
@@ -19534,20 +19703,132 @@ function useBuildingController() {
19534
19703
  }
19535
19704
  block = parseInt(block) ?? 0;
19536
19705
  try {
19537
- const siteBlock = await _getBuildingLevel(site, block);
19706
+ const siteBlock = await _getBuildingLevel(site, block, isVMS);
19538
19707
  res.json(siteBlock);
19539
19708
  return;
19540
19709
  } catch (error2) {
19541
19710
  next(error2);
19542
19711
  }
19543
19712
  }
19713
+ async function uploadSpreadsheetBuilding(req, res, next) {
19714
+ try {
19715
+ if (!req.file) {
19716
+ next(new BadRequestError81("Spreadsheet file is required."));
19717
+ return;
19718
+ }
19719
+ const { originalname, path: path4 } = req.file;
19720
+ const lowerName = originalname.toLowerCase();
19721
+ const rowSchema = Joi44.object({
19722
+ block: Joi44.number().integer().min(0).required(),
19723
+ level: Joi44.string().optional().allow(null, ""),
19724
+ unit: Joi44.string().optional().allow(null, ""),
19725
+ category: Joi44.string().trim().required(),
19726
+ name: Joi44.string().trim().optional().allow(null, ""),
19727
+ email: Joi44.string().email().lowercase().optional().allow(null, ""),
19728
+ phoneNumber: Joi44.string().trim().optional().allow(null, "")
19729
+ });
19730
+ const querySchema = Joi44.object({
19731
+ site: Joi44.string().hex().length(24).required(),
19732
+ org: Joi44.string().hex().length(24).optional().allow(null, "")
19733
+ });
19734
+ const { error: queryError, value: queryValue } = querySchema.validate(
19735
+ req.query,
19736
+ { abortEarly: false, convert: true }
19737
+ );
19738
+ if (queryError) {
19739
+ next(
19740
+ new BadRequestError81(
19741
+ queryError.details.map((d) => d.message).join(", ")
19742
+ )
19743
+ );
19744
+ return;
19745
+ }
19746
+ const { site, org } = queryValue;
19747
+ let rows = [];
19748
+ if (lowerName.endsWith(".xlsx") || lowerName.endsWith(".xls")) {
19749
+ const workbook = new ExcelJS.Workbook();
19750
+ await workbook.xlsx.readFile(path4);
19751
+ const worksheet = workbook.worksheets[0];
19752
+ if (!worksheet) {
19753
+ next(
19754
+ new BadRequestError81("No worksheet found in uploaded Excel file.")
19755
+ );
19756
+ return;
19757
+ }
19758
+ const headerRow = worksheet.getRow(1);
19759
+ const headers = (headerRow.values || []).slice(1).map(
19760
+ (header) => String(header ?? "").trim().replace(/\(.*\)/, "").trim()
19761
+ );
19762
+ worksheet.eachRow((row, rowNumber) => {
19763
+ if (rowNumber === 1)
19764
+ return;
19765
+ const rowData = {};
19766
+ headers.forEach((header, index) => {
19767
+ rowData[header] = row.getCell(index + 1).value ?? "";
19768
+ });
19769
+ if (Object.values(rowData).some(
19770
+ (v) => v !== "" && v !== null && v !== void 0
19771
+ )) {
19772
+ rows.push(rowData);
19773
+ }
19774
+ });
19775
+ } else if (lowerName.endsWith(".csv")) {
19776
+ rows = await new Promise((resolve, reject) => {
19777
+ const parsed = [];
19778
+ fs.createReadStream(path4).pipe(csv()).on("headers", (headers) => {
19779
+ headers = headers.map(
19780
+ (h) => h.trim().replace(/\(.*\)/, "").trim()
19781
+ );
19782
+ }).on("data", (row) => parsed.push(row)).on("end", () => resolve(parsed)).on("error", reject);
19783
+ });
19784
+ } else {
19785
+ next(
19786
+ new BadRequestError81("Only .xlsx, .xls, or .csv files are allowed.")
19787
+ );
19788
+ return;
19789
+ }
19790
+ const validRows = [];
19791
+ const invalidRows = [];
19792
+ rows.forEach((row, index) => {
19793
+ const { error, value } = rowSchema.validate(row, {
19794
+ abortEarly: false,
19795
+ stripUnknown: true
19796
+ });
19797
+ if (error) {
19798
+ invalidRows.push({
19799
+ row: index + 2,
19800
+ data: row,
19801
+ errors: error.details.map((d) => d.message)
19802
+ });
19803
+ } else {
19804
+ validRows.push(value);
19805
+ }
19806
+ });
19807
+ res.status(200).json({
19808
+ message: "Spreadsheet import completed (buildings).",
19809
+ fileName: originalname,
19810
+ totalRows: rows.length,
19811
+ validRows: validRows.length,
19812
+ invalidRows: invalidRows.length,
19813
+ validationErrors: invalidRows,
19814
+ data: validRows
19815
+ // testing: return the validated building rows directly
19816
+ });
19817
+ fs.unlink(path4, () => {
19818
+ });
19819
+ } catch (error) {
19820
+ logger62.log({ level: "error", message: error.message });
19821
+ next(error);
19822
+ }
19823
+ }
19544
19824
  return {
19545
19825
  createBuilding,
19546
19826
  getAll,
19547
19827
  getById,
19548
19828
  updateById,
19549
19829
  deleteById,
19550
- getBuildingLevel
19830
+ getBuildingLevel,
19831
+ uploadSpreadsheetBuilding
19551
19832
  };
19552
19833
  }
19553
19834
 
@@ -19868,9 +20149,9 @@ function useBuildingUnitController() {
19868
20149
  // src/controllers/vehicle.controller.ts
19869
20150
  import { BadRequestError as BadRequestError84, logger as logger65 } from "@7365admin1/node-server-utils";
19870
20151
  import Joi46 from "joi";
19871
- import ExcelJS from "exceljs";
19872
- import csv from "csv-parser";
19873
- import fs from "fs";
20152
+ import ExcelJS2 from "exceljs";
20153
+ import csv2 from "csv-parser";
20154
+ import fs2 from "fs";
19874
20155
  function useVehicleController() {
19875
20156
  const {
19876
20157
  add: _add,
@@ -19990,7 +20271,7 @@ function useVehicleController() {
19990
20271
  const { site, org } = queryValue;
19991
20272
  let rows = [];
19992
20273
  if (lowerName.endsWith(".xlsx") || lowerName.endsWith(".xls")) {
19993
- const workbook = new ExcelJS.Workbook();
20274
+ const workbook = new ExcelJS2.Workbook();
19994
20275
  await workbook.xlsx.readFile(path4);
19995
20276
  const worksheet = workbook.worksheets[0];
19996
20277
  if (!worksheet) {
@@ -20019,7 +20300,7 @@ function useVehicleController() {
20019
20300
  } else if (lowerName.endsWith(".csv")) {
20020
20301
  rows = await new Promise((resolve, reject) => {
20021
20302
  const parsed = [];
20022
- fs.createReadStream(path4).pipe(csv()).on("headers", (headers) => {
20303
+ fs2.createReadStream(path4).pipe(csv2()).on("headers", (headers) => {
20023
20304
  headers = headers.map(
20024
20305
  (h) => h.trim().replace(/\(.*\)/, "").trim()
20025
20306
  );
@@ -20062,7 +20343,7 @@ function useVehicleController() {
20062
20343
  validationErrors: invalidRows,
20063
20344
  data
20064
20345
  });
20065
- fs.unlink(path4, () => {
20346
+ fs2.unlink(path4, () => {
20066
20347
  });
20067
20348
  } catch (error) {
20068
20349
  logger65.log({ level: "error", message: error.message });
@@ -20459,8 +20740,9 @@ function useSiteCameraService() {
20459
20740
  try {
20460
20741
  session.startTransaction();
20461
20742
  await _add(value, session);
20743
+ const message = value.type === "ip" ? "CCTV(s) added successfully." : "ANPR(s) added successfully.";
20462
20744
  await session.commitTransaction();
20463
- return "ANPR(s) added successfully.";
20745
+ return message;
20464
20746
  } catch (error2) {
20465
20747
  await session.abortTransaction();
20466
20748
  throw error2;
@@ -33793,7 +34075,7 @@ import {
33793
34075
  import { ObjectId as ObjectId90 } from "mongodb";
33794
34076
 
33795
34077
  // src/utils/access-management.ts
33796
- import fs2 from "fs";
34078
+ import fs3 from "fs";
33797
34079
  import path2 from "path";
33798
34080
  import axios from "axios";
33799
34081
  import { parseStringPromise } from "xml2js";
@@ -33823,7 +34105,7 @@ var minifyXml = (xml) => {
33823
34105
  return xml.replace(/>\s+</g, "><").replace(/\n/g, "").replace(/\r/g, "").replace(/\t/g, "").trim();
33824
34106
  };
33825
34107
  var readTemplate = (name, params) => {
33826
- const template = fs2.readFileSync(
34108
+ const template = fs3.readFileSync(
33827
34109
  path2.join(__dirname, `../dist/public/xml-templates/${name}.xml`),
33828
34110
  "utf-8"
33829
34111
  );
@@ -33954,14 +34236,14 @@ import { parseStringPromise as parseStringPromise2 } from "xml2js";
33954
34236
 
33955
34237
  // src/utils/rsa-encryption.ts
33956
34238
  import * as crypto2 from "crypto";
33957
- import fs3 from "fs";
34239
+ import fs4 from "fs";
33958
34240
  import path3 from "path";
33959
34241
  var pub = path3.resolve(process.cwd(), "./src/public/rsa-keys/new_rsa_512_pub.pem");
33960
34242
  var priv = path3.resolve(process.cwd(), "./src/public/rsa-keys/new_rsa_512_priv.pem");
33961
34243
  var EncryptionCredentials = class {
33962
34244
  };
33963
- EncryptionCredentials.RAW_PUBLIC_KEY = fs3.readFileSync(pub, "utf8");
33964
- EncryptionCredentials.RAW_PRIVATE_KEY = fs3.readFileSync(priv, "utf8");
34245
+ EncryptionCredentials.RAW_PUBLIC_KEY = fs4.readFileSync(pub, "utf8");
34246
+ EncryptionCredentials.RAW_PRIVATE_KEY = fs4.readFileSync(priv, "utf8");
33965
34247
  var EntrypassRSAEncryption = class extends EncryptionCredentials {
33966
34248
  static hexToCardNumber(hex) {
33967
34249
  if (!/^[0-9A-Fa-f]{8}$/.test(hex)) {