@exyconn/common 2.3.2 → 2.3.4

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.
Files changed (40) hide show
  1. package/README.md +117 -12
  2. package/dist/client/http/index.d.mts +280 -49
  3. package/dist/client/http/index.d.ts +280 -49
  4. package/dist/client/http/index.js +564 -90
  5. package/dist/client/http/index.js.map +1 -1
  6. package/dist/client/http/index.mjs +520 -80
  7. package/dist/client/http/index.mjs.map +1 -1
  8. package/dist/client/index.d.mts +3 -3
  9. package/dist/client/index.d.ts +3 -3
  10. package/dist/client/index.js +573 -316
  11. package/dist/client/index.js.map +1 -1
  12. package/dist/client/index.mjs +529 -287
  13. package/dist/client/index.mjs.map +1 -1
  14. package/dist/client/utils/index.d.mts +3 -279
  15. package/dist/client/utils/index.d.ts +3 -279
  16. package/dist/{index-D9a9oxQy.d.ts → index-CdbQ8YPt.d.ts} +51 -39
  17. package/dist/{index-D3yCCjBZ.d.mts → index-Ckhm_HaX.d.mts} +21 -2
  18. package/dist/{index-01hoqibP.d.ts → index-br6POSyA.d.ts} +21 -2
  19. package/dist/{index-DuxL84IW.d.mts → index-guYdqefq.d.mts} +51 -39
  20. package/dist/index.d.mts +3 -3
  21. package/dist/index.d.ts +3 -3
  22. package/dist/index.js +1214 -326
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.mjs +1226 -338
  25. package/dist/index.mjs.map +1 -1
  26. package/dist/packageCheck-B_qfsD6R.d.ts +280 -0
  27. package/dist/packageCheck-C2_FT_Rl.d.mts +280 -0
  28. package/dist/server/index.d.mts +1 -1
  29. package/dist/server/index.d.ts +1 -1
  30. package/dist/server/index.js +631 -0
  31. package/dist/server/index.js.map +1 -1
  32. package/dist/server/index.mjs +625 -2
  33. package/dist/server/index.mjs.map +1 -1
  34. package/dist/server/middleware/index.d.mts +283 -2
  35. package/dist/server/middleware/index.d.ts +283 -2
  36. package/dist/server/middleware/index.js +761 -0
  37. package/dist/server/middleware/index.js.map +1 -1
  38. package/dist/server/middleware/index.mjs +751 -1
  39. package/dist/server/middleware/index.mjs.map +1 -1
  40. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -73,6 +73,7 @@ __export(server_exports, {
73
73
  authenticateJWT: () => authenticateJWT,
74
74
  badRequestResponse: () => badRequestResponse,
75
75
  buildConfig: () => buildConfig,
76
+ buildDeleteFilter: () => buildDeleteFilter,
76
77
  buildFilter: () => buildFilter,
77
78
  buildPagination: () => buildPagination,
78
79
  buildPaginationMeta: () => buildPaginationMeta,
@@ -83,12 +84,15 @@ __export(server_exports, {
83
84
  createApiKeyGenerator: () => createApiKeyGenerator,
84
85
  createApiRateLimiter: () => createApiRateLimiter,
85
86
  createBrandCorsOptions: () => createBrandCorsOptions,
87
+ createBulkDeleteHandler: () => createBulkDeleteHandler,
86
88
  createConfig: () => createConfig,
87
89
  createCorsOptions: () => createCorsOptions,
90
+ createCrudControllers: () => createCrudControllers,
88
91
  createDdosRateLimiter: () => createDdosRateLimiter,
89
92
  createLogger: () => createLogger,
90
93
  createMorganStream: () => createMorganStream,
91
94
  createMultiBrandCorsOptions: () => createMultiBrandCorsOptions,
95
+ createPaginationMiddleware: () => createPaginationMiddleware,
92
96
  createPrefixedKeyGenerator: () => createPrefixedKeyGenerator,
93
97
  createRateLimiter: () => createRateLimiter,
94
98
  createStandardRateLimiter: () => createStandardRateLimiter,
@@ -101,6 +105,7 @@ __export(server_exports, {
101
105
  errorResponse: () => errorResponse,
102
106
  extractColumns: () => extractColumns,
103
107
  extractOrganization: () => extractOrganization,
108
+ extractSchemaMeta: () => extractSchemaMeta,
104
109
  forbiddenResponse: () => forbiddenResponse,
105
110
  formatPackageCheckResult: () => formatPackageCheckResult,
106
111
  generateNcuCommand: () => generateNcuCommand,
@@ -115,8 +120,11 @@ __export(server_exports, {
115
120
  omitFields: () => omitFields,
116
121
  optionalAuthenticateJWT: () => optionalAuthenticateJWT,
117
122
  packageCheckServer: () => packageCheckServer,
123
+ parseBulkDelete: () => parseBulkDelete,
118
124
  pickFields: () => pickFields,
119
125
  printPackageCheckSummary: () => printPackageCheckSummary,
126
+ queryPagination: () => queryPagination,
127
+ queryParser: () => queryParser,
120
128
  rateLimitResponse: () => rateLimitResponse,
121
129
  rateLimiter: () => rateLimiter,
122
130
  requireOrganization: () => requireOrganization,
@@ -410,37 +418,37 @@ var defaultOptions = {
410
418
  retryReads: true,
411
419
  w: "majority"
412
420
  };
413
- var connectDB = async (mongoUri, options = {}, logger2) => {
421
+ var connectDB = async (mongoUri, options = {}, logger3) => {
414
422
  if (mongoose__default.default.connection.readyState === 1) {
415
- logger2?.info("Database already connected, reusing connection");
423
+ logger3?.info("Database already connected, reusing connection");
416
424
  return mongoose__default.default;
417
425
  }
418
426
  const finalOptions = { ...defaultOptions, ...options };
419
427
  try {
420
428
  await mongoose__default.default.connect(mongoUri, finalOptions);
421
- logger2?.info("MongoDB connected successfully");
429
+ logger3?.info("MongoDB connected successfully");
422
430
  mongoose__default.default.connection.on("error", (err) => {
423
- logger2?.error("MongoDB connection error", err);
431
+ logger3?.error("MongoDB connection error", err);
424
432
  });
425
433
  mongoose__default.default.connection.on("disconnected", () => {
426
- logger2?.info("MongoDB disconnected");
434
+ logger3?.info("MongoDB disconnected");
427
435
  });
428
436
  mongoose__default.default.connection.on("reconnected", () => {
429
- logger2?.info("MongoDB reconnected");
437
+ logger3?.info("MongoDB reconnected");
430
438
  });
431
439
  return mongoose__default.default;
432
440
  } catch (error) {
433
441
  const errorMessage = error instanceof Error ? error.message : String(error);
434
- logger2?.error("MongoDB connection failed", { error: errorMessage });
442
+ logger3?.error("MongoDB connection failed", { error: errorMessage });
435
443
  throw error;
436
444
  }
437
445
  };
438
- var disconnectDB = async (logger2) => {
446
+ var disconnectDB = async (logger3) => {
439
447
  try {
440
448
  await mongoose__default.default.disconnect();
441
- logger2?.info("MongoDB disconnected successfully");
449
+ logger3?.info("MongoDB disconnected successfully");
442
450
  } catch (error) {
443
- logger2?.error("Error disconnecting from MongoDB", error);
451
+ logger3?.error("Error disconnecting from MongoDB", error);
444
452
  throw error;
445
453
  }
446
454
  };
@@ -545,6 +553,629 @@ var requireOrganization = (req, res, next) => {
545
553
  next();
546
554
  };
547
555
 
556
+ // src/server/middleware/queryParser.middleware.ts
557
+ var queryParser = (req, _, next) => {
558
+ const { page, limit, sort, sortBy, sortOrder, search, filter, ...otherParams } = req.query;
559
+ const parsed = {
560
+ page: Math.max(Number(page) || 1, 1),
561
+ limit: Math.min(Number(limit) || 10, 100),
562
+ filter: {}
563
+ };
564
+ if (typeof sort === "string") {
565
+ const [field, order] = sort.split(":");
566
+ parsed.sort = {
567
+ field,
568
+ order: order === "asc" ? "asc" : "desc"
569
+ };
570
+ } else if (typeof sortBy === "string") {
571
+ parsed.sort = {
572
+ field: sortBy,
573
+ order: sortOrder === "asc" ? "asc" : "desc"
574
+ };
575
+ }
576
+ if (typeof search === "string") {
577
+ parsed.search = search;
578
+ }
579
+ if (typeof filter === "object" && filter !== null) {
580
+ Object.entries(filter).forEach(([key, value]) => {
581
+ if (value !== "all") {
582
+ parsed.filter[key] = value;
583
+ }
584
+ });
585
+ }
586
+ Object.entries(otherParams).forEach(([key, value]) => {
587
+ if (typeof value === "string" && value !== "all" && !["page", "limit", "sort", "sortBy", "sortOrder", "search"].includes(key)) {
588
+ parsed.filter[key] = value;
589
+ }
590
+ });
591
+ req.parsedQuery = parsed;
592
+ next();
593
+ };
594
+
595
+ // src/server/middleware/utils/schemaMeta.util.ts
596
+ var getZodTypeName = (schema) => {
597
+ const typeName = schema._def?.typeName;
598
+ switch (typeName) {
599
+ case "ZodString":
600
+ return "string";
601
+ case "ZodNumber":
602
+ return "number";
603
+ case "ZodBoolean":
604
+ return "boolean";
605
+ case "ZodDate":
606
+ return "date";
607
+ case "ZodArray":
608
+ return "array";
609
+ case "ZodObject":
610
+ return "object";
611
+ case "ZodOptional":
612
+ case "ZodNullable":
613
+ return schema._def?.innerType ? getZodTypeName(schema._def.innerType) : "unknown";
614
+ case "ZodDefault":
615
+ return schema._def?.innerType ? getZodTypeName(schema._def.innerType) : "unknown";
616
+ case "ZodEnum":
617
+ return "enum";
618
+ case "ZodUnion":
619
+ return "union";
620
+ default:
621
+ return "unknown";
622
+ }
623
+ };
624
+ var isZodRequired = (schema) => {
625
+ const typeName = schema._def?.typeName;
626
+ return typeName !== "ZodOptional" && typeName !== "ZodNullable";
627
+ };
628
+ var extractSchemaMeta = (model, zodSchema) => {
629
+ const columns = [];
630
+ if (zodSchema && zodSchema.shape) {
631
+ const shape = zodSchema.shape;
632
+ for (const [key, value] of Object.entries(shape)) {
633
+ if (key.startsWith("_")) continue;
634
+ columns.push({
635
+ name: key,
636
+ datatype: getZodTypeName(value),
637
+ required: isZodRequired(value)
638
+ });
639
+ }
640
+ return columns;
641
+ }
642
+ try {
643
+ const schema = model.schema;
644
+ const paths = schema.paths;
645
+ for (const [key, pathInfo] of Object.entries(paths)) {
646
+ if (key.startsWith("_") || key === "__v") continue;
647
+ const schemaType = pathInfo;
648
+ columns.push({
649
+ name: key,
650
+ datatype: (schemaType.instance || "unknown").toLowerCase(),
651
+ required: schemaType.isRequired || false
652
+ });
653
+ }
654
+ } catch {
655
+ }
656
+ return columns;
657
+ };
658
+
659
+ // src/server/middleware/pagination.middleware.ts
660
+ var queryPagination = (model, options = {}, withOrgId = true) => {
661
+ return async (req, res, next) => {
662
+ try {
663
+ const { page, limit, sort, search, filter } = req.parsedQuery;
664
+ const query = {};
665
+ Object.entries(filter).forEach(([key, value]) => {
666
+ if (options.regexFilterFields?.includes(key)) {
667
+ query[key] = { $regex: value, $options: "i" };
668
+ } else {
669
+ query[key] = value;
670
+ }
671
+ });
672
+ const organizationId = req.headers["x-organization-id"];
673
+ if (organizationId && typeof organizationId === "string" && withOrgId) {
674
+ query.organizationId = organizationId;
675
+ }
676
+ if (search && options.searchFields?.length) {
677
+ query.$or = options.searchFields.map((field) => ({
678
+ [field]: { $regex: search, $options: "i" }
679
+ }));
680
+ }
681
+ const sortQuery = sort ? { [sort.field]: sort.order } : { createdAt: "desc" };
682
+ const skip = (page - 1) * limit;
683
+ const [data, total] = await Promise.all([
684
+ model.find(query).sort(sortQuery).skip(skip).limit(limit),
685
+ model.countDocuments(query)
686
+ ]);
687
+ res.paginatedResult = {
688
+ data,
689
+ meta: {
690
+ page,
691
+ limit,
692
+ total,
693
+ totalPages: Math.ceil(total / limit)
694
+ },
695
+ columns: extractSchemaMeta(model, options.validatorSchema)
696
+ };
697
+ next();
698
+ } catch (error) {
699
+ next(error);
700
+ }
701
+ };
702
+ };
703
+ var isZodError = (error) => {
704
+ return error !== null && typeof error === "object" && "errors" in error && Array.isArray(error.errors);
705
+ };
706
+ var getOrgId = (req, orgField = "organizationId") => {
707
+ const orgReq = req;
708
+ return orgReq.organizationId || req.headers["x-organization-id"] || req.query[orgField];
709
+ };
710
+ var buildOrgFilter = (req, config) => {
711
+ const filter = {};
712
+ if (config.withOrganization !== false) {
713
+ const orgId = getOrgId(req, config.orgField);
714
+ if (orgId) {
715
+ filter[config.orgField || "organizationId"] = orgId;
716
+ }
717
+ }
718
+ return filter;
719
+ };
720
+ var formatZodError = (error) => {
721
+ return error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
722
+ };
723
+ function createCrudControllers(config) {
724
+ const {
725
+ model,
726
+ resourceName,
727
+ createSchema,
728
+ updateSchema,
729
+ searchFields = [],
730
+ regexFilterFields = [],
731
+ withOrganization = true,
732
+ orgField = "organizationId",
733
+ transformCreate,
734
+ transformUpdate,
735
+ afterCreate,
736
+ afterUpdate,
737
+ afterDelete,
738
+ excludeFields = [],
739
+ populateFields = [],
740
+ buildQuery
741
+ } = config;
742
+ const getAll = async (req, res, _next) => {
743
+ try {
744
+ const paginatedRes = res;
745
+ if (paginatedRes.paginatedResult) {
746
+ successResponse(res, paginatedRes.paginatedResult, `${resourceName} list fetched successfully`);
747
+ return;
748
+ }
749
+ const page = parseInt(req.query.page) || 1;
750
+ const limit = parseInt(req.query.limit) || 10;
751
+ const sortField = req.query.sortBy || "createdAt";
752
+ const sortOrder = req.query.sortOrder || "desc";
753
+ const search = req.query.search;
754
+ let query = {};
755
+ if (withOrganization) {
756
+ const orgId = getOrgId(req, orgField);
757
+ if (orgId) {
758
+ query[orgField] = orgId;
759
+ }
760
+ }
761
+ if (search && searchFields.length > 0) {
762
+ query.$or = searchFields.map((field) => ({
763
+ [field]: { $regex: search, $options: "i" }
764
+ }));
765
+ }
766
+ const filterableParams = Object.keys(req.query).filter(
767
+ (key) => !["page", "limit", "sortBy", "sortOrder", "search"].includes(key)
768
+ );
769
+ filterableParams.forEach((key) => {
770
+ const value = req.query[key];
771
+ if (value !== void 0 && value !== "" && value !== "all") {
772
+ if (regexFilterFields.includes(key)) {
773
+ query[key] = { $regex: value, $options: "i" };
774
+ } else {
775
+ query[key] = value;
776
+ }
777
+ }
778
+ });
779
+ if (buildQuery) {
780
+ query = buildQuery(req, query);
781
+ }
782
+ const sortQuery = { [sortField]: sortOrder };
783
+ const skip = (page - 1) * limit;
784
+ let projection = {};
785
+ if (excludeFields.length > 0) {
786
+ projection = excludeFields.reduce(
787
+ (acc, field) => ({ ...acc, [field]: 0 }),
788
+ {}
789
+ );
790
+ }
791
+ let dbQuery = model.find(query, projection);
792
+ if (populateFields.length > 0) {
793
+ populateFields.forEach((field) => {
794
+ dbQuery = dbQuery.populate(field);
795
+ });
796
+ }
797
+ const [data, total] = await Promise.all([
798
+ dbQuery.sort(sortQuery).skip(skip).limit(limit),
799
+ model.countDocuments(query)
800
+ ]);
801
+ successResponse(
802
+ res,
803
+ {
804
+ data,
805
+ meta: {
806
+ page,
807
+ limit,
808
+ total,
809
+ totalPages: Math.ceil(total / limit)
810
+ },
811
+ columns: extractSchemaMeta(model, createSchema)
812
+ },
813
+ `${resourceName} list fetched successfully`
814
+ );
815
+ } catch (error) {
816
+ logger.error(`Error in getAll ${resourceName}`, {
817
+ error: error instanceof Error ? error.message : "Unknown error"
818
+ });
819
+ errorResponse(res, `Failed to fetch ${resourceName.toLowerCase()} list`);
820
+ }
821
+ };
822
+ const getById = async (req, res, _next) => {
823
+ try {
824
+ const { id } = req.params;
825
+ if (!id || !mongoose.Types.ObjectId.isValid(id)) {
826
+ badRequestResponse(res, "Invalid ID format");
827
+ return;
828
+ }
829
+ const query = {
830
+ _id: new mongoose.Types.ObjectId(id),
831
+ ...buildOrgFilter(req, { ...config, withOrganization, orgField })
832
+ };
833
+ let dbQuery = model.findOne(query);
834
+ if (populateFields.length > 0) {
835
+ populateFields.forEach((field) => {
836
+ dbQuery = dbQuery.populate(field);
837
+ });
838
+ }
839
+ const doc = await dbQuery;
840
+ if (!doc) {
841
+ notFoundResponse(res, `${resourceName} not found`);
842
+ return;
843
+ }
844
+ successResponse(res, doc, `${resourceName} fetched successfully`);
845
+ } catch (error) {
846
+ logger.error(`Error in getById ${resourceName}`, {
847
+ error: error instanceof Error ? error.message : "Unknown error",
848
+ id: req.params.id
849
+ });
850
+ errorResponse(res, `Failed to fetch ${resourceName.toLowerCase()}`);
851
+ }
852
+ };
853
+ const create = async (req, res, _next) => {
854
+ try {
855
+ let input = req.body;
856
+ if (createSchema) {
857
+ try {
858
+ input = createSchema.parse(input);
859
+ } catch (error) {
860
+ if (isZodError(error)) {
861
+ badRequestResponse(res, formatZodError(error));
862
+ return;
863
+ }
864
+ throw error;
865
+ }
866
+ }
867
+ if (transformCreate) {
868
+ input = transformCreate(input, req);
869
+ }
870
+ if (withOrganization) {
871
+ const orgId = getOrgId(req, orgField);
872
+ if (orgId) {
873
+ input[orgField] = orgId;
874
+ }
875
+ }
876
+ const doc = new model(input);
877
+ await doc.save();
878
+ if (afterCreate) {
879
+ await afterCreate(doc, req);
880
+ }
881
+ logger.info(`${resourceName} created successfully`, {
882
+ id: doc._id,
883
+ [orgField]: input[orgField]
884
+ });
885
+ createdResponse(res, doc, `${resourceName} created successfully`);
886
+ } catch (error) {
887
+ logger.error(`Error in create ${resourceName}`, {
888
+ error: error instanceof Error ? error.message : "Unknown error"
889
+ });
890
+ if (error.code === 11e3) {
891
+ badRequestResponse(res, `A ${resourceName.toLowerCase()} with this data already exists`);
892
+ return;
893
+ }
894
+ errorResponse(res, `Failed to create ${resourceName.toLowerCase()}`);
895
+ }
896
+ };
897
+ const update = async (req, res, _next) => {
898
+ try {
899
+ const { id } = req.params;
900
+ if (!id || !mongoose.Types.ObjectId.isValid(id)) {
901
+ badRequestResponse(res, "Invalid ID format");
902
+ return;
903
+ }
904
+ let input = req.body;
905
+ if (updateSchema) {
906
+ try {
907
+ input = updateSchema.parse(input);
908
+ } catch (error) {
909
+ if (isZodError(error)) {
910
+ badRequestResponse(res, formatZodError(error));
911
+ return;
912
+ }
913
+ throw error;
914
+ }
915
+ }
916
+ if (transformUpdate) {
917
+ input = transformUpdate(input, req);
918
+ }
919
+ const query = {
920
+ _id: new mongoose.Types.ObjectId(id),
921
+ ...buildOrgFilter(req, { ...config, withOrganization, orgField })
922
+ };
923
+ const doc = await model.findOneAndUpdate(query, { $set: input }, { new: true });
924
+ if (!doc) {
925
+ notFoundResponse(res, `${resourceName} not found`);
926
+ return;
927
+ }
928
+ if (afterUpdate) {
929
+ await afterUpdate(doc, req);
930
+ }
931
+ logger.info(`${resourceName} updated successfully`, { id });
932
+ successResponse(res, doc, `${resourceName} updated successfully`);
933
+ } catch (error) {
934
+ logger.error(`Error in update ${resourceName}`, {
935
+ error: error instanceof Error ? error.message : "Unknown error",
936
+ id: req.params.id
937
+ });
938
+ errorResponse(res, `Failed to update ${resourceName.toLowerCase()}`);
939
+ }
940
+ };
941
+ const deleteOne = async (req, res, _next) => {
942
+ try {
943
+ const { id } = req.params;
944
+ if (!id || !mongoose.Types.ObjectId.isValid(id)) {
945
+ badRequestResponse(res, "Invalid ID format");
946
+ return;
947
+ }
948
+ const query = {
949
+ _id: new mongoose.Types.ObjectId(id),
950
+ ...buildOrgFilter(req, { ...config, withOrganization, orgField })
951
+ };
952
+ const result = await model.deleteOne(query);
953
+ if (result.deletedCount === 0) {
954
+ notFoundResponse(res, `${resourceName} not found`);
955
+ return;
956
+ }
957
+ if (afterDelete) {
958
+ await afterDelete(id, req);
959
+ }
960
+ logger.info(`${resourceName} deleted successfully`, { id });
961
+ noContentResponse(res, null, `${resourceName} deleted successfully`);
962
+ } catch (error) {
963
+ logger.error(`Error in delete ${resourceName}`, {
964
+ error: error instanceof Error ? error.message : "Unknown error",
965
+ id: req.params.id
966
+ });
967
+ errorResponse(res, `Failed to delete ${resourceName.toLowerCase()}`);
968
+ }
969
+ };
970
+ const bulkDelete = async (req, res, _next) => {
971
+ try {
972
+ const bulkReq = req;
973
+ const { deleteIds = [], deleteAll = false } = bulkReq;
974
+ const baseFilter = buildOrgFilter(req, { ...config, withOrganization, orgField });
975
+ let filter;
976
+ if (deleteAll) {
977
+ filter = baseFilter;
978
+ } else if (deleteIds.length > 0) {
979
+ filter = {
980
+ ...baseFilter,
981
+ _id: { $in: deleteIds.map((id) => new mongoose.Types.ObjectId(id)) }
982
+ };
983
+ } else {
984
+ badRequestResponse(res, "No IDs provided for deletion");
985
+ return;
986
+ }
987
+ const result = await model.deleteMany(filter);
988
+ if (afterDelete && deleteIds.length > 0) {
989
+ await Promise.all(deleteIds.map((id) => afterDelete(id, req)));
990
+ }
991
+ logger.info(`${resourceName}(s) bulk deleted successfully`, {
992
+ deletedCount: result.deletedCount,
993
+ deleteAll
994
+ });
995
+ successResponse(
996
+ res,
997
+ { deletedCount: result.deletedCount },
998
+ `${result.deletedCount} ${resourceName.toLowerCase()}(s) deleted successfully`
999
+ );
1000
+ } catch (error) {
1001
+ logger.error(`Error in bulkDelete ${resourceName}`, {
1002
+ error: error instanceof Error ? error.message : "Unknown error"
1003
+ });
1004
+ errorResponse(res, `Failed to delete ${resourceName.toLowerCase()}(s)`);
1005
+ }
1006
+ };
1007
+ return {
1008
+ getAll,
1009
+ getById,
1010
+ create,
1011
+ update,
1012
+ deleteOne,
1013
+ bulkDelete
1014
+ };
1015
+ }
1016
+ function createPaginationMiddleware(model, config = {}) {
1017
+ const {
1018
+ searchFields = [],
1019
+ regexFilterFields = [],
1020
+ withOrganization = true,
1021
+ orgField = "organizationId"
1022
+ } = config;
1023
+ return async (req, res, next) => {
1024
+ try {
1025
+ const page = parseInt(req.query.page) || 1;
1026
+ const limit = parseInt(req.query.limit) || 10;
1027
+ const sortField = req.query.sortBy || "createdAt";
1028
+ const sortOrder = req.query.sortOrder || "desc";
1029
+ const search = req.query.search;
1030
+ const query = {};
1031
+ if (withOrganization) {
1032
+ const orgId = getOrgId(req, orgField);
1033
+ if (orgId) {
1034
+ query[orgField] = orgId;
1035
+ }
1036
+ }
1037
+ if (search && searchFields.length > 0) {
1038
+ query.$or = searchFields.map((field) => ({
1039
+ [field]: { $regex: search, $options: "i" }
1040
+ }));
1041
+ }
1042
+ const filterableParams = Object.keys(req.query).filter(
1043
+ (key) => !["page", "limit", "sortBy", "sortOrder", "search"].includes(key)
1044
+ );
1045
+ filterableParams.forEach((key) => {
1046
+ const value = req.query[key];
1047
+ if (value !== void 0 && value !== "" && value !== "all") {
1048
+ if (regexFilterFields.includes(key)) {
1049
+ query[key] = { $regex: value, $options: "i" };
1050
+ } else {
1051
+ query[key] = value;
1052
+ }
1053
+ }
1054
+ });
1055
+ const sortQuery = { [sortField]: sortOrder };
1056
+ const skip = (page - 1) * limit;
1057
+ const [data, total] = await Promise.all([
1058
+ model.find(query).sort(sortQuery).skip(skip).limit(limit),
1059
+ model.countDocuments(query)
1060
+ ]);
1061
+ const paginatedRes = res;
1062
+ paginatedRes.paginatedResult = {
1063
+ data,
1064
+ meta: {
1065
+ page,
1066
+ limit,
1067
+ total,
1068
+ totalPages: Math.ceil(total / limit)
1069
+ },
1070
+ columns: extractSchemaMeta(model, config.createSchema)
1071
+ };
1072
+ next();
1073
+ } catch (error) {
1074
+ next(error);
1075
+ }
1076
+ };
1077
+ }
1078
+ var parseBulkDelete = (req, res, next) => {
1079
+ try {
1080
+ const bulkReq = req;
1081
+ let ids = [];
1082
+ if (Array.isArray(req.body)) {
1083
+ ids = req.body;
1084
+ } else if (req.body && Array.isArray(req.body.ids)) {
1085
+ ids = req.body.ids;
1086
+ } else if (req.body && typeof req.body === "object") {
1087
+ if (Array.isArray(req.body.data)) {
1088
+ ids = req.body.data;
1089
+ }
1090
+ }
1091
+ if (ids.length === 0) {
1092
+ return badRequestResponse(
1093
+ res,
1094
+ 'Request body must contain an array of IDs. Use ["*"] to delete all records or ["id1", "id2"] to delete specific records.'
1095
+ );
1096
+ }
1097
+ if (ids.length === 1 && ids[0] === "*") {
1098
+ bulkReq.deleteAll = true;
1099
+ bulkReq.deleteIds = [];
1100
+ logger.info("Bulk delete: Deleting all records");
1101
+ return next();
1102
+ }
1103
+ const validIds = [];
1104
+ const invalidIds = [];
1105
+ for (const id of ids) {
1106
+ if (typeof id === "string" && mongoose.Types.ObjectId.isValid(id)) {
1107
+ validIds.push(id);
1108
+ } else {
1109
+ invalidIds.push(id);
1110
+ }
1111
+ }
1112
+ if (invalidIds.length > 0) {
1113
+ return badRequestResponse(
1114
+ res,
1115
+ `Invalid ID format(s): ${invalidIds.slice(0, 5).join(", ")}${invalidIds.length > 5 ? "..." : ""}. All IDs must be valid MongoDB ObjectIds.`
1116
+ );
1117
+ }
1118
+ if (validIds.length === 0) {
1119
+ return badRequestResponse(res, "No valid IDs provided for deletion.");
1120
+ }
1121
+ bulkReq.deleteAll = false;
1122
+ bulkReq.deleteIds = validIds;
1123
+ logger.info(`Bulk delete: Deleting ${validIds.length} record(s)`);
1124
+ next();
1125
+ } catch (error) {
1126
+ logger.error("Error in parseBulkDelete middleware", error);
1127
+ return badRequestResponse(res, "Failed to parse delete request");
1128
+ }
1129
+ };
1130
+ var buildDeleteFilter = (req, organizationId) => {
1131
+ const filter = {
1132
+ organizationId: new mongoose.Types.ObjectId(organizationId)
1133
+ };
1134
+ if (!req.deleteAll && req.deleteIds && req.deleteIds.length > 0) {
1135
+ filter._id = {
1136
+ $in: req.deleteIds.map((id) => new mongoose.Types.ObjectId(id))
1137
+ };
1138
+ }
1139
+ return filter;
1140
+ };
1141
+ var createBulkDeleteHandler = (Model2, modelName) => {
1142
+ return async (req, res) => {
1143
+ const bulkReq = req;
1144
+ const organizationId = req.headers["x-organization-id"];
1145
+ if (!organizationId) {
1146
+ return badRequestResponse(res, "Organization ID is required");
1147
+ }
1148
+ try {
1149
+ const filter = buildDeleteFilter(bulkReq, organizationId);
1150
+ const result = await Model2.deleteMany(filter);
1151
+ const deletedCount = result.deletedCount || 0;
1152
+ logger.info(`Bulk delete completed: ${deletedCount} ${modelName}(s) deleted`, {
1153
+ organizationId,
1154
+ deleteAll: bulkReq.deleteAll,
1155
+ requestedIds: bulkReq.deleteIds?.length || "all",
1156
+ deletedCount
1157
+ });
1158
+ return res.status(200).json({
1159
+ message: `Successfully deleted ${deletedCount} ${modelName}(s)`,
1160
+ data: {
1161
+ deletedCount,
1162
+ deleteAll: bulkReq.deleteAll
1163
+ },
1164
+ status: "success",
1165
+ statusCode: 200
1166
+ });
1167
+ } catch (error) {
1168
+ logger.error(`Error in bulk delete ${modelName}`, error);
1169
+ return res.status(500).json({
1170
+ message: `Failed to delete ${modelName}(s)`,
1171
+ data: null,
1172
+ status: "error",
1173
+ statusCode: 500
1174
+ });
1175
+ }
1176
+ };
1177
+ };
1178
+
548
1179
  // src/server/utils/filter-builder.ts
549
1180
  var buildFilter = (options) => {
550
1181
  const {
@@ -1502,34 +2133,34 @@ var getDatabaseOptions = (config) => {
1502
2133
  // src/client/index.ts
1503
2134
  var client_exports = {};
1504
2135
  __export(client_exports, {
1505
- ApiUrlBuilder: () => ApiUrlBuilder,
2136
+ API_BASE_URL: () => API_BASE_URL,
2137
+ API_PREFIX: () => API_PREFIX,
1506
2138
  ClientLogger: () => ClientLogger,
1507
2139
  ContactForm: () => ContactForm,
1508
- EventEmitter: () => EventEmitter,
2140
+ ERROR_CODES: () => ERROR_CODES,
1509
2141
  LoginForm: () => LoginForm,
1510
2142
  NewsletterForm: () => NewsletterForm,
1511
2143
  RegisterForm: () => RegisterForm,
2144
+ STATUS_CODES: () => STATUS_CODES,
2145
+ STATUS_MESSAGES: () => STATUS_MESSAGES,
2146
+ SUCCESS_CODES: () => SUCCESS_CODES,
1512
2147
  ThemeContext: () => ThemeContext,
1513
2148
  ThemeProvider: () => ThemeProvider,
1514
2149
  ThemeToggle: () => ThemeToggle,
1515
2150
  VALIDATION_MESSAGES: () => VALIDATION_MESSAGES,
1516
- addDays: () => addDays,
1517
2151
  adjustColor: () => adjustColor,
1518
- appEvents: () => appEvents,
2152
+ axios: () => axiosInstance,
1519
2153
  camelToKebab: () => camelToKebab,
1520
2154
  capitalize: () => capitalize,
1521
2155
  capitalizeWords: () => capitalizeWords,
1522
- checkPackage: () => checkPackage,
2156
+ clearCustomHeaders: () => clearCustomHeaders,
1523
2157
  clientLogger: () => clientLogger,
2158
+ configureHttp: () => configureHttp,
1524
2159
  contactFormSchema: () => contactFormSchema,
1525
2160
  copyToClipboard: () => copyToClipboard,
1526
- createApiEndpoints: () => createApiEndpoints,
1527
- createApiUrlBuilder: () => createApiUrlBuilder,
1528
2161
  createClientLogger: () => createClientLogger,
1529
2162
  createEmptyPaginationMeta: () => createEmptyPaginationMeta,
1530
2163
  createErrorResponse: () => createErrorResponse,
1531
- createEventEmitter: () => createEventEmitter,
1532
- createHttpClient: () => createHttpClient,
1533
2164
  createRegisterFormSchema: () => createRegisterFormSchema,
1534
2165
  createSuccessResponse: () => createSuccessResponse,
1535
2166
  createTheme: () => createTheme,
@@ -1538,6 +2169,7 @@ __export(client_exports, {
1538
2169
  deepMerge: () => deepMerge2,
1539
2170
  defaultDarkTheme: () => defaultDarkTheme,
1540
2171
  defaultLightTheme: () => defaultLightTheme,
2172
+ deleteRequest: () => deleteRequest,
1541
2173
  dummyBannerData: () => dummyBannerData,
1542
2174
  dummyFaqItems: () => dummyFaqItems,
1543
2175
  dummyFeatures: () => dummyFeatures,
@@ -1546,59 +2178,76 @@ __export(client_exports, {
1546
2178
  dummyImage: () => dummyImage,
1547
2179
  dummyPricingPlans: () => dummyPricingPlans,
1548
2180
  dummyTestimonials: () => dummyTestimonials,
1549
- endOfDay: () => endOfDay,
2181
+ extractData: () => extractData,
2182
+ extractMessage: () => extractMessage,
2183
+ extractNestedData: () => extractNestedData,
2184
+ extractPaginatedData: () => extractPaginatedData,
1550
2185
  flattenToCssVars: () => flattenToCssVars,
1551
2186
  formatDate: () => formatDate,
1552
- formatDateForInput: () => formatDateForInput,
1553
2187
  formatDateTime: () => formatDateTime,
1554
- formatDateTimeForInput: () => formatDateTimeForInput,
1555
- formatPackageCheckResult: () => formatPackageCheckResult2,
1556
2188
  formatRelativeTime: () => formatRelativeTime,
1557
2189
  generateCssVars: () => generateCssVars,
1558
- generateNcuCommand: () => generateNcuCommand2,
2190
+ generateSlug: () => generateSlug,
2191
+ generateSnakeSlug: () => generateSnakeSlug,
2192
+ generateUrlSlug: () => generateUrlSlug,
2193
+ getApiBaseUrl: () => getApiBaseUrl,
2194
+ getApiPrefix: () => getApiPrefix,
1559
2195
  getContrastColor: () => getContrastColor,
2196
+ getCustomHeaders: () => getCustomHeaders,
1560
2197
  getErrorMessage: () => getErrorMessage,
2198
+ getHttpConfig: () => getHttpConfig,
1561
2199
  getNextPage: () => getNextPage,
1562
2200
  getPrevPage: () => getPrevPage,
2201
+ getRequest: () => getRequest,
1563
2202
  getResponseData: () => getResponseData,
1564
2203
  getSystemColorScheme: () => getSystemColorScheme,
1565
2204
  hasData: () => hasData,
1566
2205
  hasMorePages: () => hasMorePages,
1567
2206
  hexToRgba: () => hexToRgba,
1568
2207
  injectCssVars: () => injectCssVars,
1569
- isClipboardAvailable: () => isClipboardAvailable,
1570
2208
  isErrorResponse: () => isErrorResponse,
1571
- isForbidden: () => isForbidden,
1572
- isFuture: () => isFuture,
1573
- isNotFound: () => isNotFound,
1574
- isPast: () => isPast,
1575
- isServerError: () => isServerError,
1576
- isStatusError: () => isStatusError,
1577
2209
  isSuccess: () => isSuccess,
1578
2210
  isSuccessResponse: () => isSuccessResponse,
1579
- isToday: () => isToday,
1580
- isUnauthorized: () => isUnauthorized,
2211
+ isUtilErrorResponse: () => isErrorResponse2,
2212
+ isUtilSuccessResponse: () => isSuccessResponse2,
1581
2213
  kebabToCamel: () => kebabToCamel,
1582
2214
  loadThemeFromUrl: () => loadThemeFromUrl,
1583
2215
  loadThemeMode: () => loadThemeMode,
2216
+ logger: () => logger2,
1584
2217
  loginFormSchema: () => loginFormSchema,
1585
2218
  loremIpsum: () => loremIpsum,
1586
2219
  newsletterFormSchema: () => newsletterFormSchema,
1587
2220
  packageCheck: () => packageCheck,
2221
+ parseAxiosErrorMessage: () => parseAxiosErrorMessage,
1588
2222
  parseError: () => parseError,
1589
- parseFullResponse: () => parseFullResponse,
1590
- parseResponse: () => parseResponse,
1591
- readFromClipboard: () => readFromClipboard,
2223
+ parsePaginatedResponse: () => parsePaginatedResponse,
2224
+ parseResponseData: () => parseResponseData,
2225
+ parseResponseMessage: () => parseResponseMessage,
2226
+ parseResponseStatus: () => parseResponseStatus,
2227
+ parseResponseStatusMessage: () => parseResponseStatusMessage,
2228
+ patchRequest: () => patchRequest,
2229
+ postRequest: () => postRequest,
2230
+ putRequest: () => putRequest,
1592
2231
  registerFormSchema: () => registerFormSchema,
1593
2232
  removeCssVars: () => removeCssVars,
2233
+ removeCustomHeader: () => removeCustomHeader,
2234
+ resetHttpConfig: () => resetHttpConfig,
1594
2235
  resolveThemeMode: () => resolveThemeMode,
2236
+ safeJsonParse: () => safeJsonParse,
1595
2237
  saveThemeMode: () => saveThemeMode,
2238
+ setApiBaseUrl: () => setApiBaseUrl,
2239
+ setApiPrefix: () => setApiPrefix,
2240
+ setCustomHeader: () => setCustomHeader,
2241
+ setCustomHeaders: () => setCustomHeaders,
2242
+ simpleMetaParseResponse: () => simpleMetaParseResponse,
2243
+ simpleParseDualDataResponse: () => simpleParseDualDataResponse,
2244
+ simpleParseResponse: () => simpleParseResponse,
1596
2245
  slugify: () => slugify,
1597
2246
  slugifyUnique: () => slugifyUnique,
1598
- startOfDay: () => startOfDay,
1599
2247
  truncate: () => truncate,
1600
2248
  truncateWords: () => truncateWords,
1601
2249
  unslugify: () => unslugify,
2250
+ uploadFile: () => uploadFile,
1602
2251
  useBattery: () => useBattery_default,
1603
2252
  useClickAway: () => useClickAway_default,
1604
2253
  useContinuousRetry: () => useContinuousRetry_default,
@@ -1658,112 +2307,549 @@ __export(client_exports, {
1658
2307
  useToggle: () => useToggle_default,
1659
2308
  useVisibilityChange: () => useVisibilityChange_default,
1660
2309
  useWindowScroll: () => useWindowScroll_default,
1661
- useWindowSize: () => useWindowSize_default,
1662
- withAbortSignal: () => withAbortSignal,
1663
- withFormData: () => withFormData,
1664
- withTimeout: () => withTimeout
2310
+ useWindowSize: () => useWindowSize_default
1665
2311
  });
1666
- var createHttpClient = (options) => {
1667
- const {
1668
- baseURL,
1669
- timeout = 3e4,
1670
- withCredentials = true,
1671
- getAuthToken,
1672
- onUnauthorized,
1673
- onServerError
1674
- } = options;
1675
- const instance = axios__default.default.create({
1676
- baseURL,
1677
- timeout,
1678
- withCredentials,
1679
- headers: {
1680
- "Content-Type": "application/json"
2312
+
2313
+ // src/client/http/logger.ts
2314
+ var Logger = class {
2315
+ constructor() {
2316
+ this.isDevelopment = typeof window !== "undefined" && window.location.hostname === "localhost";
2317
+ }
2318
+ /**
2319
+ * Log informational messages
2320
+ */
2321
+ info(message, data, options) {
2322
+ if (this.isDevelopment) {
2323
+ const prefix = options?.context ? `[${options.context}]` : "";
2324
+ console.log(`${prefix} ${message}`, data ?? "");
1681
2325
  }
1682
- });
1683
- instance.interceptors.request.use(
1684
- (config) => {
1685
- if (getAuthToken) {
1686
- const token = getAuthToken();
1687
- if (token && config.headers) {
1688
- config.headers.Authorization = `Bearer ${token}`;
1689
- }
2326
+ }
2327
+ /**
2328
+ * Log warning messages
2329
+ */
2330
+ warn(message, data, options) {
2331
+ if (this.isDevelopment) {
2332
+ const prefix = options?.context ? `[${options.context}]` : "";
2333
+ console.warn(`${prefix} ${message}`, data ?? "");
2334
+ }
2335
+ }
2336
+ /**
2337
+ * Log error messages
2338
+ */
2339
+ error(message, error, options) {
2340
+ const prefix = options?.context ? `[${options.context}]` : "";
2341
+ if (this.isDevelopment) {
2342
+ console.error(`${prefix} ${message}`, error, options?.metadata || "");
2343
+ }
2344
+ }
2345
+ /**
2346
+ * Log debug messages (only in development)
2347
+ */
2348
+ debug(message, data, options) {
2349
+ if (this.isDevelopment) {
2350
+ const prefix = options?.context ? `[${options.context}]` : "";
2351
+ console.debug(`${prefix} ${message}`, data || "");
2352
+ }
2353
+ }
2354
+ /**
2355
+ * Log API errors with structured information
2356
+ */
2357
+ apiError(endpoint, error, metadata) {
2358
+ this.error(`API Error: ${endpoint}`, error, {
2359
+ context: "API",
2360
+ metadata: {
2361
+ endpoint,
2362
+ ...metadata
1690
2363
  }
1691
- return config;
1692
- },
1693
- (error) => Promise.reject(error)
1694
- );
1695
- instance.interceptors.response.use(
1696
- (response) => response,
1697
- (error) => {
1698
- if (error.response) {
1699
- const status = error.response.status;
1700
- if (status === 401 && onUnauthorized) {
1701
- onUnauthorized();
2364
+ });
2365
+ }
2366
+ };
2367
+ var logger2 = new Logger();
2368
+
2369
+ // src/client/http/response-parser.ts
2370
+ var STATUS_CODES = {
2371
+ SUCCESS: 200,
2372
+ CREATED: 201,
2373
+ NO_CONTENT: 204,
2374
+ BAD_REQUEST: 400,
2375
+ UNAUTHORIZED: 401,
2376
+ FORBIDDEN: 403,
2377
+ NOT_FOUND: 404,
2378
+ CONFLICT: 409,
2379
+ ERROR: 500
2380
+ };
2381
+ var STATUS_MESSAGES = {
2382
+ SUCCESS: "success",
2383
+ CREATED: "created",
2384
+ NO_CONTENT: "no_content",
2385
+ BAD_REQUEST: "bad_request",
2386
+ UNAUTHORIZED: "unauthorized",
2387
+ FORBIDDEN: "forbidden",
2388
+ NOT_FOUND: "not_found",
2389
+ CONFLICT: "conflict",
2390
+ ERROR: "error"
2391
+ };
2392
+ var SUCCESS_CODES = [200, 201, 204];
2393
+ var ERROR_CODES = [400, 401, 403, 404, 409, 500];
2394
+ var parseResponseData = (response, fallback = null) => {
2395
+ try {
2396
+ if (!response || typeof response !== "object") {
2397
+ return fallback;
2398
+ }
2399
+ const resp = response;
2400
+ if ("data" in resp) {
2401
+ return resp["data"] ?? fallback;
2402
+ }
2403
+ return response;
2404
+ } catch (error) {
2405
+ logger2.error("Error parsing response data", error);
2406
+ return fallback;
2407
+ }
2408
+ };
2409
+ var parseResponseMessage = (response, fallback = "") => {
2410
+ try {
2411
+ if (!response || typeof response !== "object") {
2412
+ return fallback;
2413
+ }
2414
+ const resp = response;
2415
+ if ("message" in resp && typeof resp["message"] === "string") {
2416
+ return resp["message"];
2417
+ }
2418
+ return fallback;
2419
+ } catch (error) {
2420
+ logger2.error("Error parsing response message", error);
2421
+ return fallback;
2422
+ }
2423
+ };
2424
+ var parseResponseStatus = (response) => {
2425
+ try {
2426
+ if (!response || typeof response !== "object") {
2427
+ return null;
2428
+ }
2429
+ const resp = response;
2430
+ if ("statusCode" in resp && typeof resp["statusCode"] === "number") {
2431
+ return resp["statusCode"];
2432
+ }
2433
+ if ("status" in resp && typeof resp["status"] === "number") {
2434
+ return resp["status"];
2435
+ }
2436
+ return null;
2437
+ } catch (error) {
2438
+ logger2.error("Error parsing response status", error);
2439
+ return null;
2440
+ }
2441
+ };
2442
+ var parseResponseStatusMessage = (response, fallback = "") => {
2443
+ try {
2444
+ if (!response || typeof response !== "object") {
2445
+ return fallback;
2446
+ }
2447
+ const resp = response;
2448
+ if ("status" in resp && typeof resp["status"] === "string") {
2449
+ return resp["status"];
2450
+ }
2451
+ return fallback;
2452
+ } catch (error) {
2453
+ logger2.error("Error parsing response status message", error);
2454
+ return fallback;
2455
+ }
2456
+ };
2457
+ var isSuccessResponse = (response) => {
2458
+ try {
2459
+ const statusCode2 = parseResponseStatus(response);
2460
+ if (statusCode2 !== null) {
2461
+ return SUCCESS_CODES.includes(statusCode2);
2462
+ }
2463
+ const status = parseResponseStatusMessage(response);
2464
+ return [STATUS_MESSAGES.SUCCESS, STATUS_MESSAGES.CREATED, STATUS_MESSAGES.NO_CONTENT].includes(
2465
+ status
2466
+ );
2467
+ } catch (error) {
2468
+ logger2.error("Error checking response success", error);
2469
+ return false;
2470
+ }
2471
+ };
2472
+ var isErrorResponse = (response) => {
2473
+ try {
2474
+ const statusCode2 = parseResponseStatus(response);
2475
+ if (statusCode2 !== null) {
2476
+ return ERROR_CODES.includes(statusCode2);
2477
+ }
2478
+ return false;
2479
+ } catch (error) {
2480
+ logger2.error("Error checking response error", error);
2481
+ return false;
2482
+ }
2483
+ };
2484
+ var parsePaginatedResponse = (response) => {
2485
+ try {
2486
+ if (!response || typeof response !== "object") {
2487
+ return { items: [], total: 0, page: 1, limit: 10 };
2488
+ }
2489
+ const resp = response;
2490
+ let items = [];
2491
+ if ("data" in resp && Array.isArray(resp["data"])) {
2492
+ items = resp["data"];
2493
+ }
2494
+ let total = items.length;
2495
+ let page = 1;
2496
+ let limit = 10;
2497
+ let totalPages;
2498
+ if ("paginationData" in resp && resp["paginationData"] && typeof resp["paginationData"] === "object") {
2499
+ const paginationData = resp["paginationData"];
2500
+ if ("total" in paginationData && typeof paginationData["total"] === "number") {
2501
+ total = paginationData["total"];
2502
+ }
2503
+ if ("page" in paginationData && typeof paginationData["page"] === "number") {
2504
+ page = paginationData["page"];
2505
+ }
2506
+ if ("limit" in paginationData && typeof paginationData["limit"] === "number") {
2507
+ limit = paginationData["limit"];
2508
+ }
2509
+ if ("totalPages" in paginationData && typeof paginationData["totalPages"] === "number") {
2510
+ totalPages = paginationData["totalPages"];
2511
+ }
2512
+ }
2513
+ let columns;
2514
+ if ("columns" in resp && Array.isArray(resp["columns"])) {
2515
+ columns = resp["columns"];
2516
+ }
2517
+ return {
2518
+ items,
2519
+ total,
2520
+ page,
2521
+ limit,
2522
+ ...totalPages !== void 0 && { totalPages },
2523
+ ...columns !== void 0 && { columns }
2524
+ };
2525
+ } catch (error) {
2526
+ logger2.error("Error parsing paginated response", error);
2527
+ return { items: [], total: 0, page: 1, limit: 10 };
2528
+ }
2529
+ };
2530
+ var extractNestedData = (response, path2, fallback = null) => {
2531
+ try {
2532
+ const keys = path2.split(".");
2533
+ let current = response;
2534
+ for (const key of keys) {
2535
+ if (current && typeof current === "object" && key in current) {
2536
+ current = current[key];
2537
+ } else {
2538
+ return fallback;
2539
+ }
2540
+ }
2541
+ return current;
2542
+ } catch (error) {
2543
+ logger2.error("Error extracting nested data", error);
2544
+ return fallback;
2545
+ }
2546
+ };
2547
+ var safeJsonParse = (json, fallback = null) => {
2548
+ try {
2549
+ return JSON.parse(json);
2550
+ } catch (error) {
2551
+ logger2.error("Error parsing JSON", error);
2552
+ return fallback;
2553
+ }
2554
+ };
2555
+ var parseAxiosErrorMessage = (error) => {
2556
+ try {
2557
+ if (!error || typeof error !== "object") {
2558
+ return "An unexpected error occurred";
2559
+ }
2560
+ const err = error;
2561
+ if ("response" in err && err["response"] && typeof err["response"] === "object") {
2562
+ const response = err["response"];
2563
+ if ("data" in response && response["data"] && typeof response["data"] === "object") {
2564
+ const data = response["data"];
2565
+ if ("data" in data && data["data"] && typeof data["data"] === "object") {
2566
+ const nestedData = data["data"];
2567
+ if ("message" in nestedData && typeof nestedData["message"] === "string") {
2568
+ return nestedData["message"];
2569
+ }
2570
+ }
2571
+ if ("message" in data && typeof data["message"] === "string") {
2572
+ return data["message"];
1702
2573
  }
1703
- if (status >= 500 && onServerError) {
1704
- onServerError(error);
2574
+ if ("error" in data && typeof data["error"] === "string") {
2575
+ return data["error"];
1705
2576
  }
1706
2577
  }
1707
- return Promise.reject(error);
1708
2578
  }
1709
- );
1710
- return instance;
2579
+ if ("message" in err && typeof err["message"] === "string") {
2580
+ return err["message"];
2581
+ }
2582
+ if (typeof error === "string") {
2583
+ return error;
2584
+ }
2585
+ return "An unexpected error occurred";
2586
+ } catch (parseError2) {
2587
+ logger2.error("Error parsing axios error message", parseError2);
2588
+ return "An unexpected error occurred";
2589
+ }
2590
+ };
2591
+ var parseError = (error) => {
2592
+ try {
2593
+ if (!error || typeof error !== "object") {
2594
+ return {
2595
+ message: "An unexpected error occurred",
2596
+ statusCode: null,
2597
+ data: null
2598
+ };
2599
+ }
2600
+ const err = error;
2601
+ let statusCode2 = null;
2602
+ let data = null;
2603
+ let status;
2604
+ if ("response" in err && err["response"] && typeof err["response"] === "object") {
2605
+ const response = err["response"];
2606
+ if ("status" in response && typeof response["status"] === "number") {
2607
+ statusCode2 = response["status"];
2608
+ }
2609
+ if ("data" in response && response["data"] !== void 0) {
2610
+ data = response["data"];
2611
+ if (data && typeof data === "object" && "status" in data) {
2612
+ const dataObj = data;
2613
+ if (typeof dataObj["status"] === "string") {
2614
+ status = dataObj["status"];
2615
+ }
2616
+ }
2617
+ }
2618
+ }
2619
+ if (statusCode2 === null && "statusCode" in err && typeof err["statusCode"] === "number") {
2620
+ statusCode2 = err["statusCode"];
2621
+ }
2622
+ if (data === null && "data" in err && err["data"] !== void 0) {
2623
+ data = err["data"];
2624
+ }
2625
+ if (!status && "status" in err && typeof err["status"] === "string") {
2626
+ status = err["status"];
2627
+ }
2628
+ return {
2629
+ message: parseAxiosErrorMessage(error),
2630
+ statusCode: statusCode2,
2631
+ data,
2632
+ ...status !== void 0 && { status }
2633
+ };
2634
+ } catch (err) {
2635
+ logger2.error("Error parsing error object", err);
2636
+ return {
2637
+ message: "An unexpected error occurred",
2638
+ statusCode: null,
2639
+ data: null
2640
+ };
2641
+ }
2642
+ };
2643
+ var simpleParseResponse = (response) => {
2644
+ return response?.data?.data?.data;
2645
+ };
2646
+ var simpleMetaParseResponse = (response) => {
2647
+ return response?.data?.data?.meta;
1711
2648
  };
1712
- var withFormData = () => ({
2649
+ var simpleParseDualDataResponse = (response) => {
2650
+ return response?.data?.data;
2651
+ };
2652
+
2653
+ // src/client/http/http.ts
2654
+ var defaultConfig2 = {
2655
+ baseUrl: typeof window !== "undefined" && window.location.hostname === "localhost" ? "http://localhost:4002" : "https://service-api.exyconn.com",
2656
+ apiPrefix: "/v1/api",
2657
+ timeout: 3e4,
2658
+ defaultHeaders: {}
2659
+ };
2660
+ var currentConfig = { ...defaultConfig2 };
2661
+ var axiosInstance = axios__default.default.create({
2662
+ baseURL: defaultConfig2.baseUrl,
2663
+ timeout: defaultConfig2.timeout,
1713
2664
  headers: {
1714
- "Content-Type": "multipart/form-data"
2665
+ "Content-Type": "application/json"
1715
2666
  }
1716
2667
  });
1717
- var withTimeout = (ms) => ({
1718
- timeout: ms
1719
- });
1720
- var withAbortSignal = (signal) => ({
1721
- signal
1722
- });
1723
-
1724
- // src/client/http/response-parser.ts
1725
- var parseResponse = (response) => {
1726
- if (response.data?.success && response.data?.data !== void 0) {
1727
- return response.data.data;
2668
+ var getApiBaseUrl = () => {
2669
+ return currentConfig.baseUrl || defaultConfig2.baseUrl;
2670
+ };
2671
+ var setApiBaseUrl = (baseUrl) => {
2672
+ currentConfig.baseUrl = baseUrl;
2673
+ axiosInstance.defaults.baseURL = baseUrl;
2674
+ logger2.info(`API Base URL updated to: ${baseUrl}`);
2675
+ };
2676
+ var getApiPrefix = () => {
2677
+ return currentConfig.apiPrefix || defaultConfig2.apiPrefix;
2678
+ };
2679
+ var setApiPrefix = (prefix) => {
2680
+ currentConfig.apiPrefix = prefix;
2681
+ logger2.info(`API Prefix updated to: ${prefix}`);
2682
+ };
2683
+ var getCustomHeaders = () => {
2684
+ return { ...currentConfig.defaultHeaders };
2685
+ };
2686
+ var setCustomHeader = (key, value) => {
2687
+ if (!currentConfig.defaultHeaders) {
2688
+ currentConfig.defaultHeaders = {};
1728
2689
  }
1729
- return null;
2690
+ currentConfig.defaultHeaders[key] = value;
2691
+ axiosInstance.defaults.headers.common[key] = value;
2692
+ logger2.info(`Custom header added: ${key}`);
1730
2693
  };
1731
- var parseFullResponse = (response) => {
1732
- return response.data;
2694
+ var removeCustomHeader = (key) => {
2695
+ if (currentConfig.defaultHeaders) {
2696
+ delete currentConfig.defaultHeaders[key];
2697
+ }
2698
+ delete axiosInstance.defaults.headers.common[key];
2699
+ logger2.info(`Custom header removed: ${key}`);
1733
2700
  };
1734
- var parseError = (error) => {
1735
- if (error.response?.data?.message) {
1736
- return error.response.data.message;
2701
+ var setCustomHeaders = (headers) => {
2702
+ currentConfig.defaultHeaders = { ...currentConfig.defaultHeaders, ...headers };
2703
+ Object.entries(headers).forEach(([key, value]) => {
2704
+ axiosInstance.defaults.headers.common[key] = value;
2705
+ });
2706
+ logger2.info(`Multiple custom headers added: ${Object.keys(headers).join(", ")}`);
2707
+ };
2708
+ var clearCustomHeaders = () => {
2709
+ if (currentConfig.defaultHeaders) {
2710
+ Object.keys(currentConfig.defaultHeaders).forEach((key) => {
2711
+ delete axiosInstance.defaults.headers.common[key];
2712
+ });
1737
2713
  }
1738
- if (error.response?.data?.error) {
1739
- return error.response.data.error;
2714
+ currentConfig.defaultHeaders = {};
2715
+ logger2.info("All custom headers cleared");
2716
+ };
2717
+ var configureHttp = (config) => {
2718
+ if (config.baseUrl) {
2719
+ setApiBaseUrl(config.baseUrl);
2720
+ }
2721
+ if (config.apiPrefix) {
2722
+ setApiPrefix(config.apiPrefix);
1740
2723
  }
1741
- if (error.code === "ERR_NETWORK") {
1742
- return "Network error. Please check your connection.";
2724
+ if (config.timeout !== void 0) {
2725
+ currentConfig.timeout = config.timeout;
2726
+ axiosInstance.defaults.timeout = config.timeout;
1743
2727
  }
1744
- if (error.code === "ECONNABORTED") {
1745
- return "Request timed out. Please try again.";
2728
+ if (config.defaultHeaders) {
2729
+ setCustomHeaders(config.defaultHeaders);
1746
2730
  }
1747
- return error.message || "An unexpected error occurred.";
2731
+ logger2.info("HTTP client configured successfully");
1748
2732
  };
1749
- var isSuccess = (response) => {
1750
- return response.data?.success === true;
2733
+ var getHttpConfig = () => {
2734
+ return { ...currentConfig };
2735
+ };
2736
+ var resetHttpConfig = () => {
2737
+ currentConfig = { ...defaultConfig2 };
2738
+ axiosInstance.defaults.baseURL = defaultConfig2.baseUrl;
2739
+ axiosInstance.defaults.timeout = defaultConfig2.timeout;
2740
+ clearCustomHeaders();
2741
+ logger2.info("HTTP configuration reset to defaults");
2742
+ };
2743
+ var API_BASE_URL = getApiBaseUrl();
2744
+ var API_PREFIX = getApiPrefix();
2745
+ axiosInstance.interceptors.request.use(
2746
+ (config) => {
2747
+ try {
2748
+ if (typeof window !== "undefined" && window.localStorage) {
2749
+ const selectedOrg = localStorage.getItem("selectedOrganization");
2750
+ if (selectedOrg) {
2751
+ const org = JSON.parse(selectedOrg);
2752
+ if (org && org._id) {
2753
+ config.headers["x-organization-id"] = org._id;
2754
+ }
2755
+ }
2756
+ }
2757
+ } catch (error) {
2758
+ logger2.warn("Failed to read organization from localStorage", error);
2759
+ }
2760
+ return config;
2761
+ },
2762
+ (error) => {
2763
+ return Promise.reject(error);
2764
+ }
2765
+ );
2766
+ axiosInstance.interceptors.response.use(
2767
+ (response) => response,
2768
+ (error) => {
2769
+ const parsedError = parseError(error);
2770
+ logger2.error("API Error", parsedError);
2771
+ return Promise.reject(parsedError);
2772
+ }
2773
+ );
2774
+ var buildHeaders = (customHeaders) => {
2775
+ const headers = {
2776
+ "Content-Type": "application/json",
2777
+ ...currentConfig.defaultHeaders,
2778
+ // Add global custom headers
2779
+ ...customHeaders
2780
+ // Request-specific headers override global ones
2781
+ };
2782
+ return headers;
2783
+ };
2784
+ var buildConfig2 = (params, customHeaders) => {
2785
+ const config = {
2786
+ headers: buildHeaders(customHeaders)
2787
+ };
2788
+ if (params) {
2789
+ config.params = params;
2790
+ }
2791
+ return config;
2792
+ };
2793
+ var getRequest = async (url, params, customHeaders) => {
2794
+ const config = buildConfig2(params, customHeaders);
2795
+ return axiosInstance.get(url, config);
1751
2796
  };
1752
- var isStatusError = (error, statusCode2) => {
1753
- return error.response?.status === statusCode2;
2797
+ var postRequest = async (url, data, customHeaders) => {
2798
+ const config = buildConfig2(void 0, customHeaders);
2799
+ return axiosInstance.post(url, data, config);
1754
2800
  };
1755
- var isUnauthorized = (error) => {
1756
- return isStatusError(error, 401);
2801
+ var putRequest = async (url, data, customHeaders) => {
2802
+ const config = buildConfig2(void 0, customHeaders);
2803
+ return axiosInstance.put(url, data, config);
1757
2804
  };
1758
- var isForbidden = (error) => {
1759
- return isStatusError(error, 403);
2805
+ var patchRequest = async (url, data, customHeaders) => {
2806
+ const config = buildConfig2(void 0, customHeaders);
2807
+ return axiosInstance.patch(url, data, config);
1760
2808
  };
1761
- var isNotFound = (error) => {
1762
- return isStatusError(error, 404);
2809
+ var deleteRequest = async (url, params, customHeaders) => {
2810
+ const config = buildConfig2(params, customHeaders);
2811
+ return axiosInstance.delete(url, config);
1763
2812
  };
1764
- var isServerError = (error) => {
1765
- const status = error.response?.status;
1766
- return status !== void 0 && status >= 500;
2813
+ var uploadFile = async (url, file, additionalData) => {
2814
+ const formData = new FormData();
2815
+ formData.append("file", file);
2816
+ if (additionalData) {
2817
+ Object.entries(additionalData).forEach(([key, value]) => {
2818
+ formData.append(key, String(value));
2819
+ });
2820
+ }
2821
+ const config = {
2822
+ headers: {
2823
+ "Content-Type": "multipart/form-data"
2824
+ }
2825
+ };
2826
+ return axiosInstance.post(url, formData, config);
2827
+ };
2828
+ var extractData = (response) => {
2829
+ return parseResponseData(response.data);
2830
+ };
2831
+ var extractMessage = (response) => {
2832
+ return parseResponseMessage(response, "");
2833
+ };
2834
+ var isSuccess = (response) => {
2835
+ return response.status >= 200 && response.status < 300;
2836
+ };
2837
+ var extractPaginatedData = (response) => {
2838
+ return parsePaginatedResponse(response.data);
2839
+ };
2840
+
2841
+ // src/client/http/slug.ts
2842
+ var generateSlug = (text) => {
2843
+ if (!text) return "";
2844
+ return text.trim().replace(/[^\w\s]/g, "").replace(/\s+(.)/g, (_, char) => char.toUpperCase()).replace(/\s+/g, "").replace(/^(.)/, (_, char) => char.toLowerCase());
2845
+ };
2846
+ var generateUrlSlug = (text) => {
2847
+ if (!text) return "";
2848
+ return text.trim().toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
2849
+ };
2850
+ var generateSnakeSlug = (text) => {
2851
+ if (!text) return "";
2852
+ return text.trim().toLowerCase().replace(/[^\w\s]/g, "").replace(/\s+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
1767
2853
  };
1768
2854
 
1769
2855
  // src/client/logger/client-logger.ts
@@ -1919,40 +3005,6 @@ var formatRelativeTime = (date) => {
1919
3005
  }
1920
3006
  return "just now";
1921
3007
  };
1922
- var formatDateForInput = (date) => {
1923
- const dateObj = new Date(date);
1924
- return dateObj.toISOString().split("T")[0];
1925
- };
1926
- var formatDateTimeForInput = (date) => {
1927
- const dateObj = new Date(date);
1928
- return dateObj.toISOString().slice(0, 16);
1929
- };
1930
- var isToday = (date) => {
1931
- const dateObj = new Date(date);
1932
- const today = /* @__PURE__ */ new Date();
1933
- return dateObj.getDate() === today.getDate() && dateObj.getMonth() === today.getMonth() && dateObj.getFullYear() === today.getFullYear();
1934
- };
1935
- var isPast = (date) => {
1936
- return new Date(date).getTime() < Date.now();
1937
- };
1938
- var isFuture = (date) => {
1939
- return new Date(date).getTime() > Date.now();
1940
- };
1941
- var addDays = (date, days) => {
1942
- const dateObj = new Date(date);
1943
- dateObj.setDate(dateObj.getDate() + days);
1944
- return dateObj;
1945
- };
1946
- var startOfDay = (date) => {
1947
- const dateObj = new Date(date);
1948
- dateObj.setHours(0, 0, 0, 0);
1949
- return dateObj;
1950
- };
1951
- var endOfDay = (date) => {
1952
- const dateObj = new Date(date);
1953
- dateObj.setHours(23, 59, 59, 999);
1954
- return dateObj;
1955
- };
1956
3008
 
1957
3009
  // src/client/utils/clipboard.ts
1958
3010
  var copyToClipboard = async (text) => {
@@ -1977,20 +3029,6 @@ var copyToClipboard = async (text) => {
1977
3029
  return false;
1978
3030
  }
1979
3031
  };
1980
- var readFromClipboard = async () => {
1981
- try {
1982
- if (navigator.clipboard && window.isSecureContext) {
1983
- return await navigator.clipboard.readText();
1984
- }
1985
- return null;
1986
- } catch (error) {
1987
- console.error("Failed to read from clipboard:", error);
1988
- return null;
1989
- }
1990
- };
1991
- var isClipboardAvailable = () => {
1992
- return !!(navigator.clipboard && window.isSecureContext);
1993
- };
1994
3032
 
1995
3033
  // src/client/utils/slug.ts
1996
3034
  var slugify = (text) => {
@@ -2027,165 +3065,15 @@ var kebabToCamel = (text) => {
2027
3065
  return text.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
2028
3066
  };
2029
3067
 
2030
- // src/client/utils/events.ts
2031
- var EventEmitter = class {
2032
- constructor() {
2033
- this.handlers = /* @__PURE__ */ new Map();
2034
- }
2035
- /**
2036
- * Subscribe to an event
2037
- * @returns Unsubscribe function
2038
- */
2039
- on(event, handler) {
2040
- if (!this.handlers.has(event)) {
2041
- this.handlers.set(event, /* @__PURE__ */ new Set());
2042
- }
2043
- this.handlers.get(event).add(handler);
2044
- return () => this.off(event, handler);
2045
- }
2046
- /**
2047
- * Subscribe to an event once
2048
- */
2049
- once(event, handler) {
2050
- const wrappedHandler = (data) => {
2051
- this.off(event, wrappedHandler);
2052
- handler(data);
2053
- };
2054
- return this.on(event, wrappedHandler);
2055
- }
2056
- /**
2057
- * Unsubscribe from an event
2058
- */
2059
- off(event, handler) {
2060
- const eventHandlers = this.handlers.get(event);
2061
- if (eventHandlers) {
2062
- eventHandlers.delete(handler);
2063
- }
2064
- }
2065
- /**
2066
- * Emit an event
2067
- */
2068
- emit(event, data) {
2069
- const eventHandlers = this.handlers.get(event);
2070
- if (eventHandlers) {
2071
- eventHandlers.forEach((handler) => {
2072
- try {
2073
- handler(data);
2074
- } catch (error) {
2075
- console.error(`Error in event handler for "${String(event)}":`, error);
2076
- }
2077
- });
2078
- }
2079
- }
2080
- /**
2081
- * Remove all handlers for an event (or all events)
2082
- */
2083
- removeAllListeners(event) {
2084
- if (event) {
2085
- this.handlers.delete(event);
2086
- } else {
2087
- this.handlers.clear();
2088
- }
2089
- }
2090
- /**
2091
- * Get count of listeners for an event
2092
- */
2093
- listenerCount(event) {
2094
- return this.handlers.get(event)?.size ?? 0;
2095
- }
2096
- };
2097
- var createEventEmitter = () => {
2098
- return new EventEmitter();
2099
- };
2100
- var appEvents = new EventEmitter();
2101
-
2102
- // src/client/utils/api-urls.ts
2103
- var ApiUrlBuilder = class {
2104
- constructor(config) {
2105
- this.baseUrl = config.baseUrl.replace(/\/$/, "");
2106
- this.version = config.version || "";
2107
- }
2108
- /**
2109
- * Build full URL from path
2110
- */
2111
- build(path2) {
2112
- const normalizedPath = path2.startsWith("/") ? path2 : `/${path2}`;
2113
- const versionPath = this.version ? `/${this.version}` : "";
2114
- return `${this.baseUrl}${versionPath}${normalizedPath}`;
2115
- }
2116
- /**
2117
- * Build URL with query parameters
2118
- */
2119
- buildWithParams(path2, params) {
2120
- const url = this.build(path2);
2121
- const filteredParams = Object.entries(params).filter(([, value]) => value !== void 0).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`).join("&");
2122
- return filteredParams ? `${url}?${filteredParams}` : url;
2123
- }
2124
- /**
2125
- * Build URL with path parameters
2126
- */
2127
- buildWithPathParams(template, params) {
2128
- let path2 = template;
2129
- Object.entries(params).forEach(([key, value]) => {
2130
- path2 = path2.replace(`:${key}`, String(value));
2131
- path2 = path2.replace(`{${key}}`, String(value));
2132
- });
2133
- return this.build(path2);
2134
- }
2135
- /**
2136
- * Get base URL
2137
- */
2138
- getBaseUrl() {
2139
- return this.baseUrl;
2140
- }
2141
- /**
2142
- * Set new base URL
2143
- */
2144
- setBaseUrl(baseUrl) {
2145
- this.baseUrl = baseUrl.replace(/\/$/, "");
2146
- }
2147
- };
2148
- var createApiUrlBuilder = (config) => {
2149
- return new ApiUrlBuilder(config);
2150
- };
2151
- var createApiEndpoints = (builder) => ({
2152
- // Auth endpoints
2153
- auth: {
2154
- login: () => builder.build("/auth/login"),
2155
- register: () => builder.build("/auth/register"),
2156
- logout: () => builder.build("/auth/logout"),
2157
- refresh: () => builder.build("/auth/refresh"),
2158
- me: () => builder.build("/auth/me"),
2159
- forgotPassword: () => builder.build("/auth/forgot-password"),
2160
- resetPassword: () => builder.build("/auth/reset-password")
2161
- },
2162
- // User endpoints
2163
- users: {
2164
- list: () => builder.build("/users"),
2165
- get: (id) => builder.buildWithPathParams("/users/:id", { id }),
2166
- create: () => builder.build("/users"),
2167
- update: (id) => builder.buildWithPathParams("/users/:id", { id }),
2168
- delete: (id) => builder.buildWithPathParams("/users/:id", { id })
2169
- },
2170
- // Generic CRUD factory
2171
- crud: (resource) => ({
2172
- list: () => builder.build(`/${resource}`),
2173
- get: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id }),
2174
- create: () => builder.build(`/${resource}`),
2175
- update: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id }),
2176
- delete: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id })
2177
- })
2178
- });
2179
-
2180
3068
  // src/client/utils/response-parser.ts
2181
- var isSuccessResponse = (response) => {
3069
+ var isSuccessResponse2 = (response) => {
2182
3070
  return response.success === true;
2183
3071
  };
2184
- var isErrorResponse = (response) => {
3072
+ var isErrorResponse2 = (response) => {
2185
3073
  return response.success === false;
2186
3074
  };
2187
3075
  var getResponseData = (response, defaultValue) => {
2188
- if (isSuccessResponse(response) && response.data !== void 0) {
3076
+ if (isSuccessResponse2(response) && response.data !== void 0) {
2189
3077
  return response.data;
2190
3078
  }
2191
3079
  return defaultValue;
@@ -4426,18 +5314,18 @@ function useLogger(componentName, props, options = {}) {
4426
5314
  const {
4427
5315
  logProps = true,
4428
5316
  logLifecycle = true,
4429
- logger: logger2 = console.log
5317
+ logger: logger3 = console.log
4430
5318
  } = options;
4431
5319
  const previousProps = react.useRef(props);
4432
5320
  const renderCount = react.useRef(0);
4433
5321
  renderCount.current++;
4434
5322
  react.useEffect(() => {
4435
5323
  if (logLifecycle) {
4436
- logger2(`[${componentName}] Mounted`);
5324
+ logger3(`[${componentName}] Mounted`);
4437
5325
  }
4438
5326
  return () => {
4439
5327
  if (logLifecycle) {
4440
- logger2(`[${componentName}] Unmounted (rendered ${renderCount.current} times)`);
5328
+ logger3(`[${componentName}] Unmounted (rendered ${renderCount.current} times)`);
4441
5329
  }
4442
5330
  };
4443
5331
  }, []);
@@ -4469,12 +5357,12 @@ function useLogger(componentName, props, options = {}) {
4469
5357
  });
4470
5358
  }
4471
5359
  if (hasChanges) {
4472
- logger2(`[${componentName}] Props changed:`, changedProps);
5360
+ logger3(`[${componentName}] Props changed:`, changedProps);
4473
5361
  }
4474
5362
  previousProps.current = props;
4475
- }, [componentName, props, logProps, logger2]);
5363
+ }, [componentName, props, logProps, logger3]);
4476
5364
  if (process.env.NODE_ENV === "development") {
4477
- logger2(`[${componentName}] Render #${renderCount.current}`);
5365
+ logger3(`[${componentName}] Render #${renderCount.current}`);
4478
5366
  }
4479
5367
  }
4480
5368
  var useLogger_default = useLogger;