@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.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import winston from 'winston';
2
2
  import DailyRotateFile from 'winston-daily-rotate-file';
3
3
  import path, { resolve } from 'path';
4
- import mongoose from 'mongoose';
4
+ import mongoose, { Types } from 'mongoose';
5
5
  import jwt from 'jsonwebtoken';
6
6
  import { existsSync, readFileSync } from 'fs';
7
7
  import rateLimit from 'express-rate-limit';
@@ -10,7 +10,7 @@ import { createContext, useState, useCallback, useMemo, useRef, useEffect, useCo
10
10
  import { jsx, jsxs } from 'react/jsx-runtime';
11
11
  import * as Yup from 'yup';
12
12
  import { Formik, Form, Field, ErrorMessage } from 'formik';
13
- import { subYears, subWeeks, subMonths, subMinutes, subHours, subDays, startOfYear, startOfWeek, startOfMonth, startOfDay as startOfDay$1, setSeconds, setMinutes, setHours, parseISO, isYesterday, isValid, isTomorrow, isToday as isToday$1, isThisYear, isThisWeek, isThisMonth, isSameYear, isSameWeek, isSameMonth, isSameDay, isPast as isPast$1, isFuture as isFuture$1, isEqual, isBefore, isAfter, intervalToDuration, getYear, getSeconds, getMonth, getMinutes, getHours, getDay, getDate, formatRelative, formatDuration, formatDistanceToNow, formatDistance, format, endOfYear, endOfWeek, endOfMonth, endOfDay as endOfDay$1, eachWeekOfInterval, eachMonthOfInterval, eachDayOfInterval, differenceInYears, differenceInWeeks, differenceInSeconds, differenceInMonths, differenceInMinutes, differenceInHours, differenceInDays, addYears, addWeeks, addMonths, addMinutes, addHours, addDays as addDays$1 } from 'date-fns';
13
+ import { subYears, subWeeks, subMonths, subMinutes, subHours, subDays, startOfYear, startOfWeek, startOfMonth, startOfDay, setSeconds, setMinutes, setHours, parseISO, isYesterday, isValid, isTomorrow, isToday, isThisYear, isThisWeek, isThisMonth, isSameYear, isSameWeek, isSameMonth, isSameDay, isPast, isFuture, isEqual, isBefore, isAfter, intervalToDuration, getYear, getSeconds, getMonth, getMinutes, getHours, getDay, getDate, formatRelative, formatDuration, formatDistanceToNow, formatDistance, format, endOfYear, endOfWeek, endOfMonth, endOfDay, eachWeekOfInterval, eachMonthOfInterval, eachDayOfInterval, differenceInYears, differenceInWeeks, differenceInSeconds, differenceInMonths, differenceInMinutes, differenceInHours, differenceInDays, addYears, addWeeks, addMonths, addMinutes, addHours, addDays } from 'date-fns';
14
14
  import { toZonedTime, fromZonedTime, formatInTimeZone } from 'date-fns-tz';
15
15
 
16
16
  var __defProp = Object.defineProperty;
@@ -42,6 +42,7 @@ __export(server_exports, {
42
42
  authenticateJWT: () => authenticateJWT,
43
43
  badRequestResponse: () => badRequestResponse,
44
44
  buildConfig: () => buildConfig,
45
+ buildDeleteFilter: () => buildDeleteFilter,
45
46
  buildFilter: () => buildFilter,
46
47
  buildPagination: () => buildPagination,
47
48
  buildPaginationMeta: () => buildPaginationMeta,
@@ -52,12 +53,15 @@ __export(server_exports, {
52
53
  createApiKeyGenerator: () => createApiKeyGenerator,
53
54
  createApiRateLimiter: () => createApiRateLimiter,
54
55
  createBrandCorsOptions: () => createBrandCorsOptions,
56
+ createBulkDeleteHandler: () => createBulkDeleteHandler,
55
57
  createConfig: () => createConfig,
56
58
  createCorsOptions: () => createCorsOptions,
59
+ createCrudControllers: () => createCrudControllers,
57
60
  createDdosRateLimiter: () => createDdosRateLimiter,
58
61
  createLogger: () => createLogger,
59
62
  createMorganStream: () => createMorganStream,
60
63
  createMultiBrandCorsOptions: () => createMultiBrandCorsOptions,
64
+ createPaginationMiddleware: () => createPaginationMiddleware,
61
65
  createPrefixedKeyGenerator: () => createPrefixedKeyGenerator,
62
66
  createRateLimiter: () => createRateLimiter,
63
67
  createStandardRateLimiter: () => createStandardRateLimiter,
@@ -70,6 +74,7 @@ __export(server_exports, {
70
74
  errorResponse: () => errorResponse,
71
75
  extractColumns: () => extractColumns,
72
76
  extractOrganization: () => extractOrganization,
77
+ extractSchemaMeta: () => extractSchemaMeta,
73
78
  forbiddenResponse: () => forbiddenResponse,
74
79
  formatPackageCheckResult: () => formatPackageCheckResult,
75
80
  generateNcuCommand: () => generateNcuCommand,
@@ -84,8 +89,11 @@ __export(server_exports, {
84
89
  omitFields: () => omitFields,
85
90
  optionalAuthenticateJWT: () => optionalAuthenticateJWT,
86
91
  packageCheckServer: () => packageCheckServer,
92
+ parseBulkDelete: () => parseBulkDelete,
87
93
  pickFields: () => pickFields,
88
94
  printPackageCheckSummary: () => printPackageCheckSummary,
95
+ queryPagination: () => queryPagination,
96
+ queryParser: () => queryParser,
89
97
  rateLimitResponse: () => rateLimitResponse,
90
98
  rateLimiter: () => rateLimiter,
91
99
  requireOrganization: () => requireOrganization,
@@ -379,37 +387,37 @@ var defaultOptions = {
379
387
  retryReads: true,
380
388
  w: "majority"
381
389
  };
382
- var connectDB = async (mongoUri, options = {}, logger2) => {
390
+ var connectDB = async (mongoUri, options = {}, logger3) => {
383
391
  if (mongoose.connection.readyState === 1) {
384
- logger2?.info("Database already connected, reusing connection");
392
+ logger3?.info("Database already connected, reusing connection");
385
393
  return mongoose;
386
394
  }
387
395
  const finalOptions = { ...defaultOptions, ...options };
388
396
  try {
389
397
  await mongoose.connect(mongoUri, finalOptions);
390
- logger2?.info("MongoDB connected successfully");
398
+ logger3?.info("MongoDB connected successfully");
391
399
  mongoose.connection.on("error", (err) => {
392
- logger2?.error("MongoDB connection error", err);
400
+ logger3?.error("MongoDB connection error", err);
393
401
  });
394
402
  mongoose.connection.on("disconnected", () => {
395
- logger2?.info("MongoDB disconnected");
403
+ logger3?.info("MongoDB disconnected");
396
404
  });
397
405
  mongoose.connection.on("reconnected", () => {
398
- logger2?.info("MongoDB reconnected");
406
+ logger3?.info("MongoDB reconnected");
399
407
  });
400
408
  return mongoose;
401
409
  } catch (error) {
402
410
  const errorMessage = error instanceof Error ? error.message : String(error);
403
- logger2?.error("MongoDB connection failed", { error: errorMessage });
411
+ logger3?.error("MongoDB connection failed", { error: errorMessage });
404
412
  throw error;
405
413
  }
406
414
  };
407
- var disconnectDB = async (logger2) => {
415
+ var disconnectDB = async (logger3) => {
408
416
  try {
409
417
  await mongoose.disconnect();
410
- logger2?.info("MongoDB disconnected successfully");
418
+ logger3?.info("MongoDB disconnected successfully");
411
419
  } catch (error) {
412
- logger2?.error("Error disconnecting from MongoDB", error);
420
+ logger3?.error("Error disconnecting from MongoDB", error);
413
421
  throw error;
414
422
  }
415
423
  };
@@ -514,6 +522,629 @@ var requireOrganization = (req, res, next) => {
514
522
  next();
515
523
  };
516
524
 
525
+ // src/server/middleware/queryParser.middleware.ts
526
+ var queryParser = (req, _, next) => {
527
+ const { page, limit, sort, sortBy, sortOrder, search, filter, ...otherParams } = req.query;
528
+ const parsed = {
529
+ page: Math.max(Number(page) || 1, 1),
530
+ limit: Math.min(Number(limit) || 10, 100),
531
+ filter: {}
532
+ };
533
+ if (typeof sort === "string") {
534
+ const [field, order] = sort.split(":");
535
+ parsed.sort = {
536
+ field,
537
+ order: order === "asc" ? "asc" : "desc"
538
+ };
539
+ } else if (typeof sortBy === "string") {
540
+ parsed.sort = {
541
+ field: sortBy,
542
+ order: sortOrder === "asc" ? "asc" : "desc"
543
+ };
544
+ }
545
+ if (typeof search === "string") {
546
+ parsed.search = search;
547
+ }
548
+ if (typeof filter === "object" && filter !== null) {
549
+ Object.entries(filter).forEach(([key, value]) => {
550
+ if (value !== "all") {
551
+ parsed.filter[key] = value;
552
+ }
553
+ });
554
+ }
555
+ Object.entries(otherParams).forEach(([key, value]) => {
556
+ if (typeof value === "string" && value !== "all" && !["page", "limit", "sort", "sortBy", "sortOrder", "search"].includes(key)) {
557
+ parsed.filter[key] = value;
558
+ }
559
+ });
560
+ req.parsedQuery = parsed;
561
+ next();
562
+ };
563
+
564
+ // src/server/middleware/utils/schemaMeta.util.ts
565
+ var getZodTypeName = (schema) => {
566
+ const typeName = schema._def?.typeName;
567
+ switch (typeName) {
568
+ case "ZodString":
569
+ return "string";
570
+ case "ZodNumber":
571
+ return "number";
572
+ case "ZodBoolean":
573
+ return "boolean";
574
+ case "ZodDate":
575
+ return "date";
576
+ case "ZodArray":
577
+ return "array";
578
+ case "ZodObject":
579
+ return "object";
580
+ case "ZodOptional":
581
+ case "ZodNullable":
582
+ return schema._def?.innerType ? getZodTypeName(schema._def.innerType) : "unknown";
583
+ case "ZodDefault":
584
+ return schema._def?.innerType ? getZodTypeName(schema._def.innerType) : "unknown";
585
+ case "ZodEnum":
586
+ return "enum";
587
+ case "ZodUnion":
588
+ return "union";
589
+ default:
590
+ return "unknown";
591
+ }
592
+ };
593
+ var isZodRequired = (schema) => {
594
+ const typeName = schema._def?.typeName;
595
+ return typeName !== "ZodOptional" && typeName !== "ZodNullable";
596
+ };
597
+ var extractSchemaMeta = (model, zodSchema) => {
598
+ const columns = [];
599
+ if (zodSchema && zodSchema.shape) {
600
+ const shape = zodSchema.shape;
601
+ for (const [key, value] of Object.entries(shape)) {
602
+ if (key.startsWith("_")) continue;
603
+ columns.push({
604
+ name: key,
605
+ datatype: getZodTypeName(value),
606
+ required: isZodRequired(value)
607
+ });
608
+ }
609
+ return columns;
610
+ }
611
+ try {
612
+ const schema = model.schema;
613
+ const paths = schema.paths;
614
+ for (const [key, pathInfo] of Object.entries(paths)) {
615
+ if (key.startsWith("_") || key === "__v") continue;
616
+ const schemaType = pathInfo;
617
+ columns.push({
618
+ name: key,
619
+ datatype: (schemaType.instance || "unknown").toLowerCase(),
620
+ required: schemaType.isRequired || false
621
+ });
622
+ }
623
+ } catch {
624
+ }
625
+ return columns;
626
+ };
627
+
628
+ // src/server/middleware/pagination.middleware.ts
629
+ var queryPagination = (model, options = {}, withOrgId = true) => {
630
+ return async (req, res, next) => {
631
+ try {
632
+ const { page, limit, sort, search, filter } = req.parsedQuery;
633
+ const query = {};
634
+ Object.entries(filter).forEach(([key, value]) => {
635
+ if (options.regexFilterFields?.includes(key)) {
636
+ query[key] = { $regex: value, $options: "i" };
637
+ } else {
638
+ query[key] = value;
639
+ }
640
+ });
641
+ const organizationId = req.headers["x-organization-id"];
642
+ if (organizationId && typeof organizationId === "string" && withOrgId) {
643
+ query.organizationId = organizationId;
644
+ }
645
+ if (search && options.searchFields?.length) {
646
+ query.$or = options.searchFields.map((field) => ({
647
+ [field]: { $regex: search, $options: "i" }
648
+ }));
649
+ }
650
+ const sortQuery = sort ? { [sort.field]: sort.order } : { createdAt: "desc" };
651
+ const skip = (page - 1) * limit;
652
+ const [data, total] = await Promise.all([
653
+ model.find(query).sort(sortQuery).skip(skip).limit(limit),
654
+ model.countDocuments(query)
655
+ ]);
656
+ res.paginatedResult = {
657
+ data,
658
+ meta: {
659
+ page,
660
+ limit,
661
+ total,
662
+ totalPages: Math.ceil(total / limit)
663
+ },
664
+ columns: extractSchemaMeta(model, options.validatorSchema)
665
+ };
666
+ next();
667
+ } catch (error) {
668
+ next(error);
669
+ }
670
+ };
671
+ };
672
+ var isZodError = (error) => {
673
+ return error !== null && typeof error === "object" && "errors" in error && Array.isArray(error.errors);
674
+ };
675
+ var getOrgId = (req, orgField = "organizationId") => {
676
+ const orgReq = req;
677
+ return orgReq.organizationId || req.headers["x-organization-id"] || req.query[orgField];
678
+ };
679
+ var buildOrgFilter = (req, config) => {
680
+ const filter = {};
681
+ if (config.withOrganization !== false) {
682
+ const orgId = getOrgId(req, config.orgField);
683
+ if (orgId) {
684
+ filter[config.orgField || "organizationId"] = orgId;
685
+ }
686
+ }
687
+ return filter;
688
+ };
689
+ var formatZodError = (error) => {
690
+ return error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
691
+ };
692
+ function createCrudControllers(config) {
693
+ const {
694
+ model,
695
+ resourceName,
696
+ createSchema,
697
+ updateSchema,
698
+ searchFields = [],
699
+ regexFilterFields = [],
700
+ withOrganization = true,
701
+ orgField = "organizationId",
702
+ transformCreate,
703
+ transformUpdate,
704
+ afterCreate,
705
+ afterUpdate,
706
+ afterDelete,
707
+ excludeFields = [],
708
+ populateFields = [],
709
+ buildQuery
710
+ } = config;
711
+ const getAll = async (req, res, _next) => {
712
+ try {
713
+ const paginatedRes = res;
714
+ if (paginatedRes.paginatedResult) {
715
+ successResponse(res, paginatedRes.paginatedResult, `${resourceName} list fetched successfully`);
716
+ return;
717
+ }
718
+ const page = parseInt(req.query.page) || 1;
719
+ const limit = parseInt(req.query.limit) || 10;
720
+ const sortField = req.query.sortBy || "createdAt";
721
+ const sortOrder = req.query.sortOrder || "desc";
722
+ const search = req.query.search;
723
+ let query = {};
724
+ if (withOrganization) {
725
+ const orgId = getOrgId(req, orgField);
726
+ if (orgId) {
727
+ query[orgField] = orgId;
728
+ }
729
+ }
730
+ if (search && searchFields.length > 0) {
731
+ query.$or = searchFields.map((field) => ({
732
+ [field]: { $regex: search, $options: "i" }
733
+ }));
734
+ }
735
+ const filterableParams = Object.keys(req.query).filter(
736
+ (key) => !["page", "limit", "sortBy", "sortOrder", "search"].includes(key)
737
+ );
738
+ filterableParams.forEach((key) => {
739
+ const value = req.query[key];
740
+ if (value !== void 0 && value !== "" && value !== "all") {
741
+ if (regexFilterFields.includes(key)) {
742
+ query[key] = { $regex: value, $options: "i" };
743
+ } else {
744
+ query[key] = value;
745
+ }
746
+ }
747
+ });
748
+ if (buildQuery) {
749
+ query = buildQuery(req, query);
750
+ }
751
+ const sortQuery = { [sortField]: sortOrder };
752
+ const skip = (page - 1) * limit;
753
+ let projection = {};
754
+ if (excludeFields.length > 0) {
755
+ projection = excludeFields.reduce(
756
+ (acc, field) => ({ ...acc, [field]: 0 }),
757
+ {}
758
+ );
759
+ }
760
+ let dbQuery = model.find(query, projection);
761
+ if (populateFields.length > 0) {
762
+ populateFields.forEach((field) => {
763
+ dbQuery = dbQuery.populate(field);
764
+ });
765
+ }
766
+ const [data, total] = await Promise.all([
767
+ dbQuery.sort(sortQuery).skip(skip).limit(limit),
768
+ model.countDocuments(query)
769
+ ]);
770
+ successResponse(
771
+ res,
772
+ {
773
+ data,
774
+ meta: {
775
+ page,
776
+ limit,
777
+ total,
778
+ totalPages: Math.ceil(total / limit)
779
+ },
780
+ columns: extractSchemaMeta(model, createSchema)
781
+ },
782
+ `${resourceName} list fetched successfully`
783
+ );
784
+ } catch (error) {
785
+ logger.error(`Error in getAll ${resourceName}`, {
786
+ error: error instanceof Error ? error.message : "Unknown error"
787
+ });
788
+ errorResponse(res, `Failed to fetch ${resourceName.toLowerCase()} list`);
789
+ }
790
+ };
791
+ const getById = async (req, res, _next) => {
792
+ try {
793
+ const { id } = req.params;
794
+ if (!id || !Types.ObjectId.isValid(id)) {
795
+ badRequestResponse(res, "Invalid ID format");
796
+ return;
797
+ }
798
+ const query = {
799
+ _id: new Types.ObjectId(id),
800
+ ...buildOrgFilter(req, { ...config, withOrganization, orgField })
801
+ };
802
+ let dbQuery = model.findOne(query);
803
+ if (populateFields.length > 0) {
804
+ populateFields.forEach((field) => {
805
+ dbQuery = dbQuery.populate(field);
806
+ });
807
+ }
808
+ const doc = await dbQuery;
809
+ if (!doc) {
810
+ notFoundResponse(res, `${resourceName} not found`);
811
+ return;
812
+ }
813
+ successResponse(res, doc, `${resourceName} fetched successfully`);
814
+ } catch (error) {
815
+ logger.error(`Error in getById ${resourceName}`, {
816
+ error: error instanceof Error ? error.message : "Unknown error",
817
+ id: req.params.id
818
+ });
819
+ errorResponse(res, `Failed to fetch ${resourceName.toLowerCase()}`);
820
+ }
821
+ };
822
+ const create = async (req, res, _next) => {
823
+ try {
824
+ let input = req.body;
825
+ if (createSchema) {
826
+ try {
827
+ input = createSchema.parse(input);
828
+ } catch (error) {
829
+ if (isZodError(error)) {
830
+ badRequestResponse(res, formatZodError(error));
831
+ return;
832
+ }
833
+ throw error;
834
+ }
835
+ }
836
+ if (transformCreate) {
837
+ input = transformCreate(input, req);
838
+ }
839
+ if (withOrganization) {
840
+ const orgId = getOrgId(req, orgField);
841
+ if (orgId) {
842
+ input[orgField] = orgId;
843
+ }
844
+ }
845
+ const doc = new model(input);
846
+ await doc.save();
847
+ if (afterCreate) {
848
+ await afterCreate(doc, req);
849
+ }
850
+ logger.info(`${resourceName} created successfully`, {
851
+ id: doc._id,
852
+ [orgField]: input[orgField]
853
+ });
854
+ createdResponse(res, doc, `${resourceName} created successfully`);
855
+ } catch (error) {
856
+ logger.error(`Error in create ${resourceName}`, {
857
+ error: error instanceof Error ? error.message : "Unknown error"
858
+ });
859
+ if (error.code === 11e3) {
860
+ badRequestResponse(res, `A ${resourceName.toLowerCase()} with this data already exists`);
861
+ return;
862
+ }
863
+ errorResponse(res, `Failed to create ${resourceName.toLowerCase()}`);
864
+ }
865
+ };
866
+ const update = async (req, res, _next) => {
867
+ try {
868
+ const { id } = req.params;
869
+ if (!id || !Types.ObjectId.isValid(id)) {
870
+ badRequestResponse(res, "Invalid ID format");
871
+ return;
872
+ }
873
+ let input = req.body;
874
+ if (updateSchema) {
875
+ try {
876
+ input = updateSchema.parse(input);
877
+ } catch (error) {
878
+ if (isZodError(error)) {
879
+ badRequestResponse(res, formatZodError(error));
880
+ return;
881
+ }
882
+ throw error;
883
+ }
884
+ }
885
+ if (transformUpdate) {
886
+ input = transformUpdate(input, req);
887
+ }
888
+ const query = {
889
+ _id: new Types.ObjectId(id),
890
+ ...buildOrgFilter(req, { ...config, withOrganization, orgField })
891
+ };
892
+ const doc = await model.findOneAndUpdate(query, { $set: input }, { new: true });
893
+ if (!doc) {
894
+ notFoundResponse(res, `${resourceName} not found`);
895
+ return;
896
+ }
897
+ if (afterUpdate) {
898
+ await afterUpdate(doc, req);
899
+ }
900
+ logger.info(`${resourceName} updated successfully`, { id });
901
+ successResponse(res, doc, `${resourceName} updated successfully`);
902
+ } catch (error) {
903
+ logger.error(`Error in update ${resourceName}`, {
904
+ error: error instanceof Error ? error.message : "Unknown error",
905
+ id: req.params.id
906
+ });
907
+ errorResponse(res, `Failed to update ${resourceName.toLowerCase()}`);
908
+ }
909
+ };
910
+ const deleteOne = async (req, res, _next) => {
911
+ try {
912
+ const { id } = req.params;
913
+ if (!id || !Types.ObjectId.isValid(id)) {
914
+ badRequestResponse(res, "Invalid ID format");
915
+ return;
916
+ }
917
+ const query = {
918
+ _id: new Types.ObjectId(id),
919
+ ...buildOrgFilter(req, { ...config, withOrganization, orgField })
920
+ };
921
+ const result = await model.deleteOne(query);
922
+ if (result.deletedCount === 0) {
923
+ notFoundResponse(res, `${resourceName} not found`);
924
+ return;
925
+ }
926
+ if (afterDelete) {
927
+ await afterDelete(id, req);
928
+ }
929
+ logger.info(`${resourceName} deleted successfully`, { id });
930
+ noContentResponse(res, null, `${resourceName} deleted successfully`);
931
+ } catch (error) {
932
+ logger.error(`Error in delete ${resourceName}`, {
933
+ error: error instanceof Error ? error.message : "Unknown error",
934
+ id: req.params.id
935
+ });
936
+ errorResponse(res, `Failed to delete ${resourceName.toLowerCase()}`);
937
+ }
938
+ };
939
+ const bulkDelete = async (req, res, _next) => {
940
+ try {
941
+ const bulkReq = req;
942
+ const { deleteIds = [], deleteAll = false } = bulkReq;
943
+ const baseFilter = buildOrgFilter(req, { ...config, withOrganization, orgField });
944
+ let filter;
945
+ if (deleteAll) {
946
+ filter = baseFilter;
947
+ } else if (deleteIds.length > 0) {
948
+ filter = {
949
+ ...baseFilter,
950
+ _id: { $in: deleteIds.map((id) => new Types.ObjectId(id)) }
951
+ };
952
+ } else {
953
+ badRequestResponse(res, "No IDs provided for deletion");
954
+ return;
955
+ }
956
+ const result = await model.deleteMany(filter);
957
+ if (afterDelete && deleteIds.length > 0) {
958
+ await Promise.all(deleteIds.map((id) => afterDelete(id, req)));
959
+ }
960
+ logger.info(`${resourceName}(s) bulk deleted successfully`, {
961
+ deletedCount: result.deletedCount,
962
+ deleteAll
963
+ });
964
+ successResponse(
965
+ res,
966
+ { deletedCount: result.deletedCount },
967
+ `${result.deletedCount} ${resourceName.toLowerCase()}(s) deleted successfully`
968
+ );
969
+ } catch (error) {
970
+ logger.error(`Error in bulkDelete ${resourceName}`, {
971
+ error: error instanceof Error ? error.message : "Unknown error"
972
+ });
973
+ errorResponse(res, `Failed to delete ${resourceName.toLowerCase()}(s)`);
974
+ }
975
+ };
976
+ return {
977
+ getAll,
978
+ getById,
979
+ create,
980
+ update,
981
+ deleteOne,
982
+ bulkDelete
983
+ };
984
+ }
985
+ function createPaginationMiddleware(model, config = {}) {
986
+ const {
987
+ searchFields = [],
988
+ regexFilterFields = [],
989
+ withOrganization = true,
990
+ orgField = "organizationId"
991
+ } = config;
992
+ return async (req, res, next) => {
993
+ try {
994
+ const page = parseInt(req.query.page) || 1;
995
+ const limit = parseInt(req.query.limit) || 10;
996
+ const sortField = req.query.sortBy || "createdAt";
997
+ const sortOrder = req.query.sortOrder || "desc";
998
+ const search = req.query.search;
999
+ const query = {};
1000
+ if (withOrganization) {
1001
+ const orgId = getOrgId(req, orgField);
1002
+ if (orgId) {
1003
+ query[orgField] = orgId;
1004
+ }
1005
+ }
1006
+ if (search && searchFields.length > 0) {
1007
+ query.$or = searchFields.map((field) => ({
1008
+ [field]: { $regex: search, $options: "i" }
1009
+ }));
1010
+ }
1011
+ const filterableParams = Object.keys(req.query).filter(
1012
+ (key) => !["page", "limit", "sortBy", "sortOrder", "search"].includes(key)
1013
+ );
1014
+ filterableParams.forEach((key) => {
1015
+ const value = req.query[key];
1016
+ if (value !== void 0 && value !== "" && value !== "all") {
1017
+ if (regexFilterFields.includes(key)) {
1018
+ query[key] = { $regex: value, $options: "i" };
1019
+ } else {
1020
+ query[key] = value;
1021
+ }
1022
+ }
1023
+ });
1024
+ const sortQuery = { [sortField]: sortOrder };
1025
+ const skip = (page - 1) * limit;
1026
+ const [data, total] = await Promise.all([
1027
+ model.find(query).sort(sortQuery).skip(skip).limit(limit),
1028
+ model.countDocuments(query)
1029
+ ]);
1030
+ const paginatedRes = res;
1031
+ paginatedRes.paginatedResult = {
1032
+ data,
1033
+ meta: {
1034
+ page,
1035
+ limit,
1036
+ total,
1037
+ totalPages: Math.ceil(total / limit)
1038
+ },
1039
+ columns: extractSchemaMeta(model, config.createSchema)
1040
+ };
1041
+ next();
1042
+ } catch (error) {
1043
+ next(error);
1044
+ }
1045
+ };
1046
+ }
1047
+ var parseBulkDelete = (req, res, next) => {
1048
+ try {
1049
+ const bulkReq = req;
1050
+ let ids = [];
1051
+ if (Array.isArray(req.body)) {
1052
+ ids = req.body;
1053
+ } else if (req.body && Array.isArray(req.body.ids)) {
1054
+ ids = req.body.ids;
1055
+ } else if (req.body && typeof req.body === "object") {
1056
+ if (Array.isArray(req.body.data)) {
1057
+ ids = req.body.data;
1058
+ }
1059
+ }
1060
+ if (ids.length === 0) {
1061
+ return badRequestResponse(
1062
+ res,
1063
+ 'Request body must contain an array of IDs. Use ["*"] to delete all records or ["id1", "id2"] to delete specific records.'
1064
+ );
1065
+ }
1066
+ if (ids.length === 1 && ids[0] === "*") {
1067
+ bulkReq.deleteAll = true;
1068
+ bulkReq.deleteIds = [];
1069
+ logger.info("Bulk delete: Deleting all records");
1070
+ return next();
1071
+ }
1072
+ const validIds = [];
1073
+ const invalidIds = [];
1074
+ for (const id of ids) {
1075
+ if (typeof id === "string" && Types.ObjectId.isValid(id)) {
1076
+ validIds.push(id);
1077
+ } else {
1078
+ invalidIds.push(id);
1079
+ }
1080
+ }
1081
+ if (invalidIds.length > 0) {
1082
+ return badRequestResponse(
1083
+ res,
1084
+ `Invalid ID format(s): ${invalidIds.slice(0, 5).join(", ")}${invalidIds.length > 5 ? "..." : ""}. All IDs must be valid MongoDB ObjectIds.`
1085
+ );
1086
+ }
1087
+ if (validIds.length === 0) {
1088
+ return badRequestResponse(res, "No valid IDs provided for deletion.");
1089
+ }
1090
+ bulkReq.deleteAll = false;
1091
+ bulkReq.deleteIds = validIds;
1092
+ logger.info(`Bulk delete: Deleting ${validIds.length} record(s)`);
1093
+ next();
1094
+ } catch (error) {
1095
+ logger.error("Error in parseBulkDelete middleware", error);
1096
+ return badRequestResponse(res, "Failed to parse delete request");
1097
+ }
1098
+ };
1099
+ var buildDeleteFilter = (req, organizationId) => {
1100
+ const filter = {
1101
+ organizationId: new Types.ObjectId(organizationId)
1102
+ };
1103
+ if (!req.deleteAll && req.deleteIds && req.deleteIds.length > 0) {
1104
+ filter._id = {
1105
+ $in: req.deleteIds.map((id) => new Types.ObjectId(id))
1106
+ };
1107
+ }
1108
+ return filter;
1109
+ };
1110
+ var createBulkDeleteHandler = (Model2, modelName) => {
1111
+ return async (req, res) => {
1112
+ const bulkReq = req;
1113
+ const organizationId = req.headers["x-organization-id"];
1114
+ if (!organizationId) {
1115
+ return badRequestResponse(res, "Organization ID is required");
1116
+ }
1117
+ try {
1118
+ const filter = buildDeleteFilter(bulkReq, organizationId);
1119
+ const result = await Model2.deleteMany(filter);
1120
+ const deletedCount = result.deletedCount || 0;
1121
+ logger.info(`Bulk delete completed: ${deletedCount} ${modelName}(s) deleted`, {
1122
+ organizationId,
1123
+ deleteAll: bulkReq.deleteAll,
1124
+ requestedIds: bulkReq.deleteIds?.length || "all",
1125
+ deletedCount
1126
+ });
1127
+ return res.status(200).json({
1128
+ message: `Successfully deleted ${deletedCount} ${modelName}(s)`,
1129
+ data: {
1130
+ deletedCount,
1131
+ deleteAll: bulkReq.deleteAll
1132
+ },
1133
+ status: "success",
1134
+ statusCode: 200
1135
+ });
1136
+ } catch (error) {
1137
+ logger.error(`Error in bulk delete ${modelName}`, error);
1138
+ return res.status(500).json({
1139
+ message: `Failed to delete ${modelName}(s)`,
1140
+ data: null,
1141
+ status: "error",
1142
+ statusCode: 500
1143
+ });
1144
+ }
1145
+ };
1146
+ };
1147
+
517
1148
  // src/server/utils/filter-builder.ts
518
1149
  var buildFilter = (options) => {
519
1150
  const {
@@ -1471,34 +2102,34 @@ var getDatabaseOptions = (config) => {
1471
2102
  // src/client/index.ts
1472
2103
  var client_exports = {};
1473
2104
  __export(client_exports, {
1474
- ApiUrlBuilder: () => ApiUrlBuilder,
2105
+ API_BASE_URL: () => API_BASE_URL,
2106
+ API_PREFIX: () => API_PREFIX,
1475
2107
  ClientLogger: () => ClientLogger,
1476
2108
  ContactForm: () => ContactForm,
1477
- EventEmitter: () => EventEmitter,
2109
+ ERROR_CODES: () => ERROR_CODES,
1478
2110
  LoginForm: () => LoginForm,
1479
2111
  NewsletterForm: () => NewsletterForm,
1480
2112
  RegisterForm: () => RegisterForm,
2113
+ STATUS_CODES: () => STATUS_CODES,
2114
+ STATUS_MESSAGES: () => STATUS_MESSAGES,
2115
+ SUCCESS_CODES: () => SUCCESS_CODES,
1481
2116
  ThemeContext: () => ThemeContext,
1482
2117
  ThemeProvider: () => ThemeProvider,
1483
2118
  ThemeToggle: () => ThemeToggle,
1484
2119
  VALIDATION_MESSAGES: () => VALIDATION_MESSAGES,
1485
- addDays: () => addDays,
1486
2120
  adjustColor: () => adjustColor,
1487
- appEvents: () => appEvents,
2121
+ axios: () => axiosInstance,
1488
2122
  camelToKebab: () => camelToKebab,
1489
2123
  capitalize: () => capitalize,
1490
2124
  capitalizeWords: () => capitalizeWords,
1491
- checkPackage: () => checkPackage,
2125
+ clearCustomHeaders: () => clearCustomHeaders,
1492
2126
  clientLogger: () => clientLogger,
2127
+ configureHttp: () => configureHttp,
1493
2128
  contactFormSchema: () => contactFormSchema,
1494
2129
  copyToClipboard: () => copyToClipboard,
1495
- createApiEndpoints: () => createApiEndpoints,
1496
- createApiUrlBuilder: () => createApiUrlBuilder,
1497
2130
  createClientLogger: () => createClientLogger,
1498
2131
  createEmptyPaginationMeta: () => createEmptyPaginationMeta,
1499
2132
  createErrorResponse: () => createErrorResponse,
1500
- createEventEmitter: () => createEventEmitter,
1501
- createHttpClient: () => createHttpClient,
1502
2133
  createRegisterFormSchema: () => createRegisterFormSchema,
1503
2134
  createSuccessResponse: () => createSuccessResponse,
1504
2135
  createTheme: () => createTheme,
@@ -1507,6 +2138,7 @@ __export(client_exports, {
1507
2138
  deepMerge: () => deepMerge2,
1508
2139
  defaultDarkTheme: () => defaultDarkTheme,
1509
2140
  defaultLightTheme: () => defaultLightTheme,
2141
+ deleteRequest: () => deleteRequest,
1510
2142
  dummyBannerData: () => dummyBannerData,
1511
2143
  dummyFaqItems: () => dummyFaqItems,
1512
2144
  dummyFeatures: () => dummyFeatures,
@@ -1515,59 +2147,76 @@ __export(client_exports, {
1515
2147
  dummyImage: () => dummyImage,
1516
2148
  dummyPricingPlans: () => dummyPricingPlans,
1517
2149
  dummyTestimonials: () => dummyTestimonials,
1518
- endOfDay: () => endOfDay,
2150
+ extractData: () => extractData,
2151
+ extractMessage: () => extractMessage,
2152
+ extractNestedData: () => extractNestedData,
2153
+ extractPaginatedData: () => extractPaginatedData,
1519
2154
  flattenToCssVars: () => flattenToCssVars,
1520
2155
  formatDate: () => formatDate,
1521
- formatDateForInput: () => formatDateForInput,
1522
2156
  formatDateTime: () => formatDateTime,
1523
- formatDateTimeForInput: () => formatDateTimeForInput,
1524
- formatPackageCheckResult: () => formatPackageCheckResult2,
1525
2157
  formatRelativeTime: () => formatRelativeTime,
1526
2158
  generateCssVars: () => generateCssVars,
1527
- generateNcuCommand: () => generateNcuCommand2,
2159
+ generateSlug: () => generateSlug,
2160
+ generateSnakeSlug: () => generateSnakeSlug,
2161
+ generateUrlSlug: () => generateUrlSlug,
2162
+ getApiBaseUrl: () => getApiBaseUrl,
2163
+ getApiPrefix: () => getApiPrefix,
1528
2164
  getContrastColor: () => getContrastColor,
2165
+ getCustomHeaders: () => getCustomHeaders,
1529
2166
  getErrorMessage: () => getErrorMessage,
2167
+ getHttpConfig: () => getHttpConfig,
1530
2168
  getNextPage: () => getNextPage,
1531
2169
  getPrevPage: () => getPrevPage,
2170
+ getRequest: () => getRequest,
1532
2171
  getResponseData: () => getResponseData,
1533
2172
  getSystemColorScheme: () => getSystemColorScheme,
1534
2173
  hasData: () => hasData,
1535
2174
  hasMorePages: () => hasMorePages,
1536
2175
  hexToRgba: () => hexToRgba,
1537
2176
  injectCssVars: () => injectCssVars,
1538
- isClipboardAvailable: () => isClipboardAvailable,
1539
2177
  isErrorResponse: () => isErrorResponse,
1540
- isForbidden: () => isForbidden,
1541
- isFuture: () => isFuture,
1542
- isNotFound: () => isNotFound,
1543
- isPast: () => isPast,
1544
- isServerError: () => isServerError,
1545
- isStatusError: () => isStatusError,
1546
2178
  isSuccess: () => isSuccess,
1547
2179
  isSuccessResponse: () => isSuccessResponse,
1548
- isToday: () => isToday,
1549
- isUnauthorized: () => isUnauthorized,
2180
+ isUtilErrorResponse: () => isErrorResponse2,
2181
+ isUtilSuccessResponse: () => isSuccessResponse2,
1550
2182
  kebabToCamel: () => kebabToCamel,
1551
2183
  loadThemeFromUrl: () => loadThemeFromUrl,
1552
2184
  loadThemeMode: () => loadThemeMode,
2185
+ logger: () => logger2,
1553
2186
  loginFormSchema: () => loginFormSchema,
1554
2187
  loremIpsum: () => loremIpsum,
1555
2188
  newsletterFormSchema: () => newsletterFormSchema,
1556
2189
  packageCheck: () => packageCheck,
2190
+ parseAxiosErrorMessage: () => parseAxiosErrorMessage,
1557
2191
  parseError: () => parseError,
1558
- parseFullResponse: () => parseFullResponse,
1559
- parseResponse: () => parseResponse,
1560
- readFromClipboard: () => readFromClipboard,
2192
+ parsePaginatedResponse: () => parsePaginatedResponse,
2193
+ parseResponseData: () => parseResponseData,
2194
+ parseResponseMessage: () => parseResponseMessage,
2195
+ parseResponseStatus: () => parseResponseStatus,
2196
+ parseResponseStatusMessage: () => parseResponseStatusMessage,
2197
+ patchRequest: () => patchRequest,
2198
+ postRequest: () => postRequest,
2199
+ putRequest: () => putRequest,
1561
2200
  registerFormSchema: () => registerFormSchema,
1562
2201
  removeCssVars: () => removeCssVars,
2202
+ removeCustomHeader: () => removeCustomHeader,
2203
+ resetHttpConfig: () => resetHttpConfig,
1563
2204
  resolveThemeMode: () => resolveThemeMode,
2205
+ safeJsonParse: () => safeJsonParse,
1564
2206
  saveThemeMode: () => saveThemeMode,
2207
+ setApiBaseUrl: () => setApiBaseUrl,
2208
+ setApiPrefix: () => setApiPrefix,
2209
+ setCustomHeader: () => setCustomHeader,
2210
+ setCustomHeaders: () => setCustomHeaders,
2211
+ simpleMetaParseResponse: () => simpleMetaParseResponse,
2212
+ simpleParseDualDataResponse: () => simpleParseDualDataResponse,
2213
+ simpleParseResponse: () => simpleParseResponse,
1565
2214
  slugify: () => slugify,
1566
2215
  slugifyUnique: () => slugifyUnique,
1567
- startOfDay: () => startOfDay,
1568
2216
  truncate: () => truncate,
1569
2217
  truncateWords: () => truncateWords,
1570
2218
  unslugify: () => unslugify,
2219
+ uploadFile: () => uploadFile,
1571
2220
  useBattery: () => useBattery_default,
1572
2221
  useClickAway: () => useClickAway_default,
1573
2222
  useContinuousRetry: () => useContinuousRetry_default,
@@ -1627,112 +2276,549 @@ __export(client_exports, {
1627
2276
  useToggle: () => useToggle_default,
1628
2277
  useVisibilityChange: () => useVisibilityChange_default,
1629
2278
  useWindowScroll: () => useWindowScroll_default,
1630
- useWindowSize: () => useWindowSize_default,
1631
- withAbortSignal: () => withAbortSignal,
1632
- withFormData: () => withFormData,
1633
- withTimeout: () => withTimeout
2279
+ useWindowSize: () => useWindowSize_default
1634
2280
  });
1635
- var createHttpClient = (options) => {
1636
- const {
1637
- baseURL,
1638
- timeout = 3e4,
1639
- withCredentials = true,
1640
- getAuthToken,
1641
- onUnauthorized,
1642
- onServerError
1643
- } = options;
1644
- const instance = axios.create({
1645
- baseURL,
1646
- timeout,
1647
- withCredentials,
1648
- headers: {
1649
- "Content-Type": "application/json"
2281
+
2282
+ // src/client/http/logger.ts
2283
+ var Logger = class {
2284
+ constructor() {
2285
+ this.isDevelopment = typeof window !== "undefined" && window.location.hostname === "localhost";
2286
+ }
2287
+ /**
2288
+ * Log informational messages
2289
+ */
2290
+ info(message, data, options) {
2291
+ if (this.isDevelopment) {
2292
+ const prefix = options?.context ? `[${options.context}]` : "";
2293
+ console.log(`${prefix} ${message}`, data ?? "");
1650
2294
  }
1651
- });
1652
- instance.interceptors.request.use(
1653
- (config) => {
1654
- if (getAuthToken) {
1655
- const token = getAuthToken();
1656
- if (token && config.headers) {
1657
- config.headers.Authorization = `Bearer ${token}`;
1658
- }
2295
+ }
2296
+ /**
2297
+ * Log warning messages
2298
+ */
2299
+ warn(message, data, options) {
2300
+ if (this.isDevelopment) {
2301
+ const prefix = options?.context ? `[${options.context}]` : "";
2302
+ console.warn(`${prefix} ${message}`, data ?? "");
2303
+ }
2304
+ }
2305
+ /**
2306
+ * Log error messages
2307
+ */
2308
+ error(message, error, options) {
2309
+ const prefix = options?.context ? `[${options.context}]` : "";
2310
+ if (this.isDevelopment) {
2311
+ console.error(`${prefix} ${message}`, error, options?.metadata || "");
2312
+ }
2313
+ }
2314
+ /**
2315
+ * Log debug messages (only in development)
2316
+ */
2317
+ debug(message, data, options) {
2318
+ if (this.isDevelopment) {
2319
+ const prefix = options?.context ? `[${options.context}]` : "";
2320
+ console.debug(`${prefix} ${message}`, data || "");
2321
+ }
2322
+ }
2323
+ /**
2324
+ * Log API errors with structured information
2325
+ */
2326
+ apiError(endpoint, error, metadata) {
2327
+ this.error(`API Error: ${endpoint}`, error, {
2328
+ context: "API",
2329
+ metadata: {
2330
+ endpoint,
2331
+ ...metadata
1659
2332
  }
1660
- return config;
1661
- },
1662
- (error) => Promise.reject(error)
1663
- );
1664
- instance.interceptors.response.use(
1665
- (response) => response,
1666
- (error) => {
1667
- if (error.response) {
1668
- const status = error.response.status;
1669
- if (status === 401 && onUnauthorized) {
1670
- onUnauthorized();
2333
+ });
2334
+ }
2335
+ };
2336
+ var logger2 = new Logger();
2337
+
2338
+ // src/client/http/response-parser.ts
2339
+ var STATUS_CODES = {
2340
+ SUCCESS: 200,
2341
+ CREATED: 201,
2342
+ NO_CONTENT: 204,
2343
+ BAD_REQUEST: 400,
2344
+ UNAUTHORIZED: 401,
2345
+ FORBIDDEN: 403,
2346
+ NOT_FOUND: 404,
2347
+ CONFLICT: 409,
2348
+ ERROR: 500
2349
+ };
2350
+ var STATUS_MESSAGES = {
2351
+ SUCCESS: "success",
2352
+ CREATED: "created",
2353
+ NO_CONTENT: "no_content",
2354
+ BAD_REQUEST: "bad_request",
2355
+ UNAUTHORIZED: "unauthorized",
2356
+ FORBIDDEN: "forbidden",
2357
+ NOT_FOUND: "not_found",
2358
+ CONFLICT: "conflict",
2359
+ ERROR: "error"
2360
+ };
2361
+ var SUCCESS_CODES = [200, 201, 204];
2362
+ var ERROR_CODES = [400, 401, 403, 404, 409, 500];
2363
+ var parseResponseData = (response, fallback = null) => {
2364
+ try {
2365
+ if (!response || typeof response !== "object") {
2366
+ return fallback;
2367
+ }
2368
+ const resp = response;
2369
+ if ("data" in resp) {
2370
+ return resp["data"] ?? fallback;
2371
+ }
2372
+ return response;
2373
+ } catch (error) {
2374
+ logger2.error("Error parsing response data", error);
2375
+ return fallback;
2376
+ }
2377
+ };
2378
+ var parseResponseMessage = (response, fallback = "") => {
2379
+ try {
2380
+ if (!response || typeof response !== "object") {
2381
+ return fallback;
2382
+ }
2383
+ const resp = response;
2384
+ if ("message" in resp && typeof resp["message"] === "string") {
2385
+ return resp["message"];
2386
+ }
2387
+ return fallback;
2388
+ } catch (error) {
2389
+ logger2.error("Error parsing response message", error);
2390
+ return fallback;
2391
+ }
2392
+ };
2393
+ var parseResponseStatus = (response) => {
2394
+ try {
2395
+ if (!response || typeof response !== "object") {
2396
+ return null;
2397
+ }
2398
+ const resp = response;
2399
+ if ("statusCode" in resp && typeof resp["statusCode"] === "number") {
2400
+ return resp["statusCode"];
2401
+ }
2402
+ if ("status" in resp && typeof resp["status"] === "number") {
2403
+ return resp["status"];
2404
+ }
2405
+ return null;
2406
+ } catch (error) {
2407
+ logger2.error("Error parsing response status", error);
2408
+ return null;
2409
+ }
2410
+ };
2411
+ var parseResponseStatusMessage = (response, fallback = "") => {
2412
+ try {
2413
+ if (!response || typeof response !== "object") {
2414
+ return fallback;
2415
+ }
2416
+ const resp = response;
2417
+ if ("status" in resp && typeof resp["status"] === "string") {
2418
+ return resp["status"];
2419
+ }
2420
+ return fallback;
2421
+ } catch (error) {
2422
+ logger2.error("Error parsing response status message", error);
2423
+ return fallback;
2424
+ }
2425
+ };
2426
+ var isSuccessResponse = (response) => {
2427
+ try {
2428
+ const statusCode2 = parseResponseStatus(response);
2429
+ if (statusCode2 !== null) {
2430
+ return SUCCESS_CODES.includes(statusCode2);
2431
+ }
2432
+ const status = parseResponseStatusMessage(response);
2433
+ return [STATUS_MESSAGES.SUCCESS, STATUS_MESSAGES.CREATED, STATUS_MESSAGES.NO_CONTENT].includes(
2434
+ status
2435
+ );
2436
+ } catch (error) {
2437
+ logger2.error("Error checking response success", error);
2438
+ return false;
2439
+ }
2440
+ };
2441
+ var isErrorResponse = (response) => {
2442
+ try {
2443
+ const statusCode2 = parseResponseStatus(response);
2444
+ if (statusCode2 !== null) {
2445
+ return ERROR_CODES.includes(statusCode2);
2446
+ }
2447
+ return false;
2448
+ } catch (error) {
2449
+ logger2.error("Error checking response error", error);
2450
+ return false;
2451
+ }
2452
+ };
2453
+ var parsePaginatedResponse = (response) => {
2454
+ try {
2455
+ if (!response || typeof response !== "object") {
2456
+ return { items: [], total: 0, page: 1, limit: 10 };
2457
+ }
2458
+ const resp = response;
2459
+ let items = [];
2460
+ if ("data" in resp && Array.isArray(resp["data"])) {
2461
+ items = resp["data"];
2462
+ }
2463
+ let total = items.length;
2464
+ let page = 1;
2465
+ let limit = 10;
2466
+ let totalPages;
2467
+ if ("paginationData" in resp && resp["paginationData"] && typeof resp["paginationData"] === "object") {
2468
+ const paginationData = resp["paginationData"];
2469
+ if ("total" in paginationData && typeof paginationData["total"] === "number") {
2470
+ total = paginationData["total"];
2471
+ }
2472
+ if ("page" in paginationData && typeof paginationData["page"] === "number") {
2473
+ page = paginationData["page"];
2474
+ }
2475
+ if ("limit" in paginationData && typeof paginationData["limit"] === "number") {
2476
+ limit = paginationData["limit"];
2477
+ }
2478
+ if ("totalPages" in paginationData && typeof paginationData["totalPages"] === "number") {
2479
+ totalPages = paginationData["totalPages"];
2480
+ }
2481
+ }
2482
+ let columns;
2483
+ if ("columns" in resp && Array.isArray(resp["columns"])) {
2484
+ columns = resp["columns"];
2485
+ }
2486
+ return {
2487
+ items,
2488
+ total,
2489
+ page,
2490
+ limit,
2491
+ ...totalPages !== void 0 && { totalPages },
2492
+ ...columns !== void 0 && { columns }
2493
+ };
2494
+ } catch (error) {
2495
+ logger2.error("Error parsing paginated response", error);
2496
+ return { items: [], total: 0, page: 1, limit: 10 };
2497
+ }
2498
+ };
2499
+ var extractNestedData = (response, path2, fallback = null) => {
2500
+ try {
2501
+ const keys = path2.split(".");
2502
+ let current = response;
2503
+ for (const key of keys) {
2504
+ if (current && typeof current === "object" && key in current) {
2505
+ current = current[key];
2506
+ } else {
2507
+ return fallback;
2508
+ }
2509
+ }
2510
+ return current;
2511
+ } catch (error) {
2512
+ logger2.error("Error extracting nested data", error);
2513
+ return fallback;
2514
+ }
2515
+ };
2516
+ var safeJsonParse = (json, fallback = null) => {
2517
+ try {
2518
+ return JSON.parse(json);
2519
+ } catch (error) {
2520
+ logger2.error("Error parsing JSON", error);
2521
+ return fallback;
2522
+ }
2523
+ };
2524
+ var parseAxiosErrorMessage = (error) => {
2525
+ try {
2526
+ if (!error || typeof error !== "object") {
2527
+ return "An unexpected error occurred";
2528
+ }
2529
+ const err = error;
2530
+ if ("response" in err && err["response"] && typeof err["response"] === "object") {
2531
+ const response = err["response"];
2532
+ if ("data" in response && response["data"] && typeof response["data"] === "object") {
2533
+ const data = response["data"];
2534
+ if ("data" in data && data["data"] && typeof data["data"] === "object") {
2535
+ const nestedData = data["data"];
2536
+ if ("message" in nestedData && typeof nestedData["message"] === "string") {
2537
+ return nestedData["message"];
2538
+ }
1671
2539
  }
1672
- if (status >= 500 && onServerError) {
1673
- onServerError(error);
2540
+ if ("message" in data && typeof data["message"] === "string") {
2541
+ return data["message"];
2542
+ }
2543
+ if ("error" in data && typeof data["error"] === "string") {
2544
+ return data["error"];
1674
2545
  }
1675
2546
  }
1676
- return Promise.reject(error);
1677
2547
  }
1678
- );
1679
- return instance;
2548
+ if ("message" in err && typeof err["message"] === "string") {
2549
+ return err["message"];
2550
+ }
2551
+ if (typeof error === "string") {
2552
+ return error;
2553
+ }
2554
+ return "An unexpected error occurred";
2555
+ } catch (parseError2) {
2556
+ logger2.error("Error parsing axios error message", parseError2);
2557
+ return "An unexpected error occurred";
2558
+ }
2559
+ };
2560
+ var parseError = (error) => {
2561
+ try {
2562
+ if (!error || typeof error !== "object") {
2563
+ return {
2564
+ message: "An unexpected error occurred",
2565
+ statusCode: null,
2566
+ data: null
2567
+ };
2568
+ }
2569
+ const err = error;
2570
+ let statusCode2 = null;
2571
+ let data = null;
2572
+ let status;
2573
+ if ("response" in err && err["response"] && typeof err["response"] === "object") {
2574
+ const response = err["response"];
2575
+ if ("status" in response && typeof response["status"] === "number") {
2576
+ statusCode2 = response["status"];
2577
+ }
2578
+ if ("data" in response && response["data"] !== void 0) {
2579
+ data = response["data"];
2580
+ if (data && typeof data === "object" && "status" in data) {
2581
+ const dataObj = data;
2582
+ if (typeof dataObj["status"] === "string") {
2583
+ status = dataObj["status"];
2584
+ }
2585
+ }
2586
+ }
2587
+ }
2588
+ if (statusCode2 === null && "statusCode" in err && typeof err["statusCode"] === "number") {
2589
+ statusCode2 = err["statusCode"];
2590
+ }
2591
+ if (data === null && "data" in err && err["data"] !== void 0) {
2592
+ data = err["data"];
2593
+ }
2594
+ if (!status && "status" in err && typeof err["status"] === "string") {
2595
+ status = err["status"];
2596
+ }
2597
+ return {
2598
+ message: parseAxiosErrorMessage(error),
2599
+ statusCode: statusCode2,
2600
+ data,
2601
+ ...status !== void 0 && { status }
2602
+ };
2603
+ } catch (err) {
2604
+ logger2.error("Error parsing error object", err);
2605
+ return {
2606
+ message: "An unexpected error occurred",
2607
+ statusCode: null,
2608
+ data: null
2609
+ };
2610
+ }
1680
2611
  };
1681
- var withFormData = () => ({
2612
+ var simpleParseResponse = (response) => {
2613
+ return response?.data?.data?.data;
2614
+ };
2615
+ var simpleMetaParseResponse = (response) => {
2616
+ return response?.data?.data?.meta;
2617
+ };
2618
+ var simpleParseDualDataResponse = (response) => {
2619
+ return response?.data?.data;
2620
+ };
2621
+
2622
+ // src/client/http/http.ts
2623
+ var defaultConfig2 = {
2624
+ baseUrl: typeof window !== "undefined" && window.location.hostname === "localhost" ? "http://localhost:4002" : "https://service-api.exyconn.com",
2625
+ apiPrefix: "/v1/api",
2626
+ timeout: 3e4,
2627
+ defaultHeaders: {}
2628
+ };
2629
+ var currentConfig = { ...defaultConfig2 };
2630
+ var axiosInstance = axios.create({
2631
+ baseURL: defaultConfig2.baseUrl,
2632
+ timeout: defaultConfig2.timeout,
1682
2633
  headers: {
1683
- "Content-Type": "multipart/form-data"
2634
+ "Content-Type": "application/json"
1684
2635
  }
1685
2636
  });
1686
- var withTimeout = (ms) => ({
1687
- timeout: ms
1688
- });
1689
- var withAbortSignal = (signal) => ({
1690
- signal
1691
- });
1692
-
1693
- // src/client/http/response-parser.ts
1694
- var parseResponse = (response) => {
1695
- if (response.data?.success && response.data?.data !== void 0) {
1696
- return response.data.data;
2637
+ var getApiBaseUrl = () => {
2638
+ return currentConfig.baseUrl || defaultConfig2.baseUrl;
2639
+ };
2640
+ var setApiBaseUrl = (baseUrl) => {
2641
+ currentConfig.baseUrl = baseUrl;
2642
+ axiosInstance.defaults.baseURL = baseUrl;
2643
+ logger2.info(`API Base URL updated to: ${baseUrl}`);
2644
+ };
2645
+ var getApiPrefix = () => {
2646
+ return currentConfig.apiPrefix || defaultConfig2.apiPrefix;
2647
+ };
2648
+ var setApiPrefix = (prefix) => {
2649
+ currentConfig.apiPrefix = prefix;
2650
+ logger2.info(`API Prefix updated to: ${prefix}`);
2651
+ };
2652
+ var getCustomHeaders = () => {
2653
+ return { ...currentConfig.defaultHeaders };
2654
+ };
2655
+ var setCustomHeader = (key, value) => {
2656
+ if (!currentConfig.defaultHeaders) {
2657
+ currentConfig.defaultHeaders = {};
1697
2658
  }
1698
- return null;
2659
+ currentConfig.defaultHeaders[key] = value;
2660
+ axiosInstance.defaults.headers.common[key] = value;
2661
+ logger2.info(`Custom header added: ${key}`);
1699
2662
  };
1700
- var parseFullResponse = (response) => {
1701
- return response.data;
2663
+ var removeCustomHeader = (key) => {
2664
+ if (currentConfig.defaultHeaders) {
2665
+ delete currentConfig.defaultHeaders[key];
2666
+ }
2667
+ delete axiosInstance.defaults.headers.common[key];
2668
+ logger2.info(`Custom header removed: ${key}`);
1702
2669
  };
1703
- var parseError = (error) => {
1704
- if (error.response?.data?.message) {
1705
- return error.response.data.message;
2670
+ var setCustomHeaders = (headers) => {
2671
+ currentConfig.defaultHeaders = { ...currentConfig.defaultHeaders, ...headers };
2672
+ Object.entries(headers).forEach(([key, value]) => {
2673
+ axiosInstance.defaults.headers.common[key] = value;
2674
+ });
2675
+ logger2.info(`Multiple custom headers added: ${Object.keys(headers).join(", ")}`);
2676
+ };
2677
+ var clearCustomHeaders = () => {
2678
+ if (currentConfig.defaultHeaders) {
2679
+ Object.keys(currentConfig.defaultHeaders).forEach((key) => {
2680
+ delete axiosInstance.defaults.headers.common[key];
2681
+ });
1706
2682
  }
1707
- if (error.response?.data?.error) {
1708
- return error.response.data.error;
2683
+ currentConfig.defaultHeaders = {};
2684
+ logger2.info("All custom headers cleared");
2685
+ };
2686
+ var configureHttp = (config) => {
2687
+ if (config.baseUrl) {
2688
+ setApiBaseUrl(config.baseUrl);
2689
+ }
2690
+ if (config.apiPrefix) {
2691
+ setApiPrefix(config.apiPrefix);
1709
2692
  }
1710
- if (error.code === "ERR_NETWORK") {
1711
- return "Network error. Please check your connection.";
2693
+ if (config.timeout !== void 0) {
2694
+ currentConfig.timeout = config.timeout;
2695
+ axiosInstance.defaults.timeout = config.timeout;
1712
2696
  }
1713
- if (error.code === "ECONNABORTED") {
1714
- return "Request timed out. Please try again.";
2697
+ if (config.defaultHeaders) {
2698
+ setCustomHeaders(config.defaultHeaders);
1715
2699
  }
1716
- return error.message || "An unexpected error occurred.";
2700
+ logger2.info("HTTP client configured successfully");
1717
2701
  };
1718
- var isSuccess = (response) => {
1719
- return response.data?.success === true;
2702
+ var getHttpConfig = () => {
2703
+ return { ...currentConfig };
1720
2704
  };
1721
- var isStatusError = (error, statusCode2) => {
1722
- return error.response?.status === statusCode2;
2705
+ var resetHttpConfig = () => {
2706
+ currentConfig = { ...defaultConfig2 };
2707
+ axiosInstance.defaults.baseURL = defaultConfig2.baseUrl;
2708
+ axiosInstance.defaults.timeout = defaultConfig2.timeout;
2709
+ clearCustomHeaders();
2710
+ logger2.info("HTTP configuration reset to defaults");
1723
2711
  };
1724
- var isUnauthorized = (error) => {
1725
- return isStatusError(error, 401);
2712
+ var API_BASE_URL = getApiBaseUrl();
2713
+ var API_PREFIX = getApiPrefix();
2714
+ axiosInstance.interceptors.request.use(
2715
+ (config) => {
2716
+ try {
2717
+ if (typeof window !== "undefined" && window.localStorage) {
2718
+ const selectedOrg = localStorage.getItem("selectedOrganization");
2719
+ if (selectedOrg) {
2720
+ const org = JSON.parse(selectedOrg);
2721
+ if (org && org._id) {
2722
+ config.headers["x-organization-id"] = org._id;
2723
+ }
2724
+ }
2725
+ }
2726
+ } catch (error) {
2727
+ logger2.warn("Failed to read organization from localStorage", error);
2728
+ }
2729
+ return config;
2730
+ },
2731
+ (error) => {
2732
+ return Promise.reject(error);
2733
+ }
2734
+ );
2735
+ axiosInstance.interceptors.response.use(
2736
+ (response) => response,
2737
+ (error) => {
2738
+ const parsedError = parseError(error);
2739
+ logger2.error("API Error", parsedError);
2740
+ return Promise.reject(parsedError);
2741
+ }
2742
+ );
2743
+ var buildHeaders = (customHeaders) => {
2744
+ const headers = {
2745
+ "Content-Type": "application/json",
2746
+ ...currentConfig.defaultHeaders,
2747
+ // Add global custom headers
2748
+ ...customHeaders
2749
+ // Request-specific headers override global ones
2750
+ };
2751
+ return headers;
2752
+ };
2753
+ var buildConfig2 = (params, customHeaders) => {
2754
+ const config = {
2755
+ headers: buildHeaders(customHeaders)
2756
+ };
2757
+ if (params) {
2758
+ config.params = params;
2759
+ }
2760
+ return config;
2761
+ };
2762
+ var getRequest = async (url, params, customHeaders) => {
2763
+ const config = buildConfig2(params, customHeaders);
2764
+ return axiosInstance.get(url, config);
2765
+ };
2766
+ var postRequest = async (url, data, customHeaders) => {
2767
+ const config = buildConfig2(void 0, customHeaders);
2768
+ return axiosInstance.post(url, data, config);
2769
+ };
2770
+ var putRequest = async (url, data, customHeaders) => {
2771
+ const config = buildConfig2(void 0, customHeaders);
2772
+ return axiosInstance.put(url, data, config);
2773
+ };
2774
+ var patchRequest = async (url, data, customHeaders) => {
2775
+ const config = buildConfig2(void 0, customHeaders);
2776
+ return axiosInstance.patch(url, data, config);
2777
+ };
2778
+ var deleteRequest = async (url, params, customHeaders) => {
2779
+ const config = buildConfig2(params, customHeaders);
2780
+ return axiosInstance.delete(url, config);
2781
+ };
2782
+ var uploadFile = async (url, file, additionalData) => {
2783
+ const formData = new FormData();
2784
+ formData.append("file", file);
2785
+ if (additionalData) {
2786
+ Object.entries(additionalData).forEach(([key, value]) => {
2787
+ formData.append(key, String(value));
2788
+ });
2789
+ }
2790
+ const config = {
2791
+ headers: {
2792
+ "Content-Type": "multipart/form-data"
2793
+ }
2794
+ };
2795
+ return axiosInstance.post(url, formData, config);
2796
+ };
2797
+ var extractData = (response) => {
2798
+ return parseResponseData(response.data);
2799
+ };
2800
+ var extractMessage = (response) => {
2801
+ return parseResponseMessage(response, "");
2802
+ };
2803
+ var isSuccess = (response) => {
2804
+ return response.status >= 200 && response.status < 300;
1726
2805
  };
1727
- var isForbidden = (error) => {
1728
- return isStatusError(error, 403);
2806
+ var extractPaginatedData = (response) => {
2807
+ return parsePaginatedResponse(response.data);
1729
2808
  };
1730
- var isNotFound = (error) => {
1731
- return isStatusError(error, 404);
2809
+
2810
+ // src/client/http/slug.ts
2811
+ var generateSlug = (text) => {
2812
+ if (!text) return "";
2813
+ return text.trim().replace(/[^\w\s]/g, "").replace(/\s+(.)/g, (_, char) => char.toUpperCase()).replace(/\s+/g, "").replace(/^(.)/, (_, char) => char.toLowerCase());
2814
+ };
2815
+ var generateUrlSlug = (text) => {
2816
+ if (!text) return "";
2817
+ return text.trim().toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
1732
2818
  };
1733
- var isServerError = (error) => {
1734
- const status = error.response?.status;
1735
- return status !== void 0 && status >= 500;
2819
+ var generateSnakeSlug = (text) => {
2820
+ if (!text) return "";
2821
+ return text.trim().toLowerCase().replace(/[^\w\s]/g, "").replace(/\s+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
1736
2822
  };
1737
2823
 
1738
2824
  // src/client/logger/client-logger.ts
@@ -1888,40 +2974,6 @@ var formatRelativeTime = (date) => {
1888
2974
  }
1889
2975
  return "just now";
1890
2976
  };
1891
- var formatDateForInput = (date) => {
1892
- const dateObj = new Date(date);
1893
- return dateObj.toISOString().split("T")[0];
1894
- };
1895
- var formatDateTimeForInput = (date) => {
1896
- const dateObj = new Date(date);
1897
- return dateObj.toISOString().slice(0, 16);
1898
- };
1899
- var isToday = (date) => {
1900
- const dateObj = new Date(date);
1901
- const today = /* @__PURE__ */ new Date();
1902
- return dateObj.getDate() === today.getDate() && dateObj.getMonth() === today.getMonth() && dateObj.getFullYear() === today.getFullYear();
1903
- };
1904
- var isPast = (date) => {
1905
- return new Date(date).getTime() < Date.now();
1906
- };
1907
- var isFuture = (date) => {
1908
- return new Date(date).getTime() > Date.now();
1909
- };
1910
- var addDays = (date, days) => {
1911
- const dateObj = new Date(date);
1912
- dateObj.setDate(dateObj.getDate() + days);
1913
- return dateObj;
1914
- };
1915
- var startOfDay = (date) => {
1916
- const dateObj = new Date(date);
1917
- dateObj.setHours(0, 0, 0, 0);
1918
- return dateObj;
1919
- };
1920
- var endOfDay = (date) => {
1921
- const dateObj = new Date(date);
1922
- dateObj.setHours(23, 59, 59, 999);
1923
- return dateObj;
1924
- };
1925
2977
 
1926
2978
  // src/client/utils/clipboard.ts
1927
2979
  var copyToClipboard = async (text) => {
@@ -1946,20 +2998,6 @@ var copyToClipboard = async (text) => {
1946
2998
  return false;
1947
2999
  }
1948
3000
  };
1949
- var readFromClipboard = async () => {
1950
- try {
1951
- if (navigator.clipboard && window.isSecureContext) {
1952
- return await navigator.clipboard.readText();
1953
- }
1954
- return null;
1955
- } catch (error) {
1956
- console.error("Failed to read from clipboard:", error);
1957
- return null;
1958
- }
1959
- };
1960
- var isClipboardAvailable = () => {
1961
- return !!(navigator.clipboard && window.isSecureContext);
1962
- };
1963
3001
 
1964
3002
  // src/client/utils/slug.ts
1965
3003
  var slugify = (text) => {
@@ -1996,165 +3034,15 @@ var kebabToCamel = (text) => {
1996
3034
  return text.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
1997
3035
  };
1998
3036
 
1999
- // src/client/utils/events.ts
2000
- var EventEmitter = class {
2001
- constructor() {
2002
- this.handlers = /* @__PURE__ */ new Map();
2003
- }
2004
- /**
2005
- * Subscribe to an event
2006
- * @returns Unsubscribe function
2007
- */
2008
- on(event, handler) {
2009
- if (!this.handlers.has(event)) {
2010
- this.handlers.set(event, /* @__PURE__ */ new Set());
2011
- }
2012
- this.handlers.get(event).add(handler);
2013
- return () => this.off(event, handler);
2014
- }
2015
- /**
2016
- * Subscribe to an event once
2017
- */
2018
- once(event, handler) {
2019
- const wrappedHandler = (data) => {
2020
- this.off(event, wrappedHandler);
2021
- handler(data);
2022
- };
2023
- return this.on(event, wrappedHandler);
2024
- }
2025
- /**
2026
- * Unsubscribe from an event
2027
- */
2028
- off(event, handler) {
2029
- const eventHandlers = this.handlers.get(event);
2030
- if (eventHandlers) {
2031
- eventHandlers.delete(handler);
2032
- }
2033
- }
2034
- /**
2035
- * Emit an event
2036
- */
2037
- emit(event, data) {
2038
- const eventHandlers = this.handlers.get(event);
2039
- if (eventHandlers) {
2040
- eventHandlers.forEach((handler) => {
2041
- try {
2042
- handler(data);
2043
- } catch (error) {
2044
- console.error(`Error in event handler for "${String(event)}":`, error);
2045
- }
2046
- });
2047
- }
2048
- }
2049
- /**
2050
- * Remove all handlers for an event (or all events)
2051
- */
2052
- removeAllListeners(event) {
2053
- if (event) {
2054
- this.handlers.delete(event);
2055
- } else {
2056
- this.handlers.clear();
2057
- }
2058
- }
2059
- /**
2060
- * Get count of listeners for an event
2061
- */
2062
- listenerCount(event) {
2063
- return this.handlers.get(event)?.size ?? 0;
2064
- }
2065
- };
2066
- var createEventEmitter = () => {
2067
- return new EventEmitter();
2068
- };
2069
- var appEvents = new EventEmitter();
2070
-
2071
- // src/client/utils/api-urls.ts
2072
- var ApiUrlBuilder = class {
2073
- constructor(config) {
2074
- this.baseUrl = config.baseUrl.replace(/\/$/, "");
2075
- this.version = config.version || "";
2076
- }
2077
- /**
2078
- * Build full URL from path
2079
- */
2080
- build(path2) {
2081
- const normalizedPath = path2.startsWith("/") ? path2 : `/${path2}`;
2082
- const versionPath = this.version ? `/${this.version}` : "";
2083
- return `${this.baseUrl}${versionPath}${normalizedPath}`;
2084
- }
2085
- /**
2086
- * Build URL with query parameters
2087
- */
2088
- buildWithParams(path2, params) {
2089
- const url = this.build(path2);
2090
- const filteredParams = Object.entries(params).filter(([, value]) => value !== void 0).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`).join("&");
2091
- return filteredParams ? `${url}?${filteredParams}` : url;
2092
- }
2093
- /**
2094
- * Build URL with path parameters
2095
- */
2096
- buildWithPathParams(template, params) {
2097
- let path2 = template;
2098
- Object.entries(params).forEach(([key, value]) => {
2099
- path2 = path2.replace(`:${key}`, String(value));
2100
- path2 = path2.replace(`{${key}}`, String(value));
2101
- });
2102
- return this.build(path2);
2103
- }
2104
- /**
2105
- * Get base URL
2106
- */
2107
- getBaseUrl() {
2108
- return this.baseUrl;
2109
- }
2110
- /**
2111
- * Set new base URL
2112
- */
2113
- setBaseUrl(baseUrl) {
2114
- this.baseUrl = baseUrl.replace(/\/$/, "");
2115
- }
2116
- };
2117
- var createApiUrlBuilder = (config) => {
2118
- return new ApiUrlBuilder(config);
2119
- };
2120
- var createApiEndpoints = (builder) => ({
2121
- // Auth endpoints
2122
- auth: {
2123
- login: () => builder.build("/auth/login"),
2124
- register: () => builder.build("/auth/register"),
2125
- logout: () => builder.build("/auth/logout"),
2126
- refresh: () => builder.build("/auth/refresh"),
2127
- me: () => builder.build("/auth/me"),
2128
- forgotPassword: () => builder.build("/auth/forgot-password"),
2129
- resetPassword: () => builder.build("/auth/reset-password")
2130
- },
2131
- // User endpoints
2132
- users: {
2133
- list: () => builder.build("/users"),
2134
- get: (id) => builder.buildWithPathParams("/users/:id", { id }),
2135
- create: () => builder.build("/users"),
2136
- update: (id) => builder.buildWithPathParams("/users/:id", { id }),
2137
- delete: (id) => builder.buildWithPathParams("/users/:id", { id })
2138
- },
2139
- // Generic CRUD factory
2140
- crud: (resource) => ({
2141
- list: () => builder.build(`/${resource}`),
2142
- get: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id }),
2143
- create: () => builder.build(`/${resource}`),
2144
- update: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id }),
2145
- delete: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id })
2146
- })
2147
- });
2148
-
2149
3037
  // src/client/utils/response-parser.ts
2150
- var isSuccessResponse = (response) => {
3038
+ var isSuccessResponse2 = (response) => {
2151
3039
  return response.success === true;
2152
3040
  };
2153
- var isErrorResponse = (response) => {
3041
+ var isErrorResponse2 = (response) => {
2154
3042
  return response.success === false;
2155
3043
  };
2156
3044
  var getResponseData = (response, defaultValue) => {
2157
- if (isSuccessResponse(response) && response.data !== void 0) {
3045
+ if (isSuccessResponse2(response) && response.data !== void 0) {
2158
3046
  return response.data;
2159
3047
  }
2160
3048
  return defaultValue;
@@ -4395,18 +5283,18 @@ function useLogger(componentName, props, options = {}) {
4395
5283
  const {
4396
5284
  logProps = true,
4397
5285
  logLifecycle = true,
4398
- logger: logger2 = console.log
5286
+ logger: logger3 = console.log
4399
5287
  } = options;
4400
5288
  const previousProps = useRef(props);
4401
5289
  const renderCount = useRef(0);
4402
5290
  renderCount.current++;
4403
5291
  useEffect(() => {
4404
5292
  if (logLifecycle) {
4405
- logger2(`[${componentName}] Mounted`);
5293
+ logger3(`[${componentName}] Mounted`);
4406
5294
  }
4407
5295
  return () => {
4408
5296
  if (logLifecycle) {
4409
- logger2(`[${componentName}] Unmounted (rendered ${renderCount.current} times)`);
5297
+ logger3(`[${componentName}] Unmounted (rendered ${renderCount.current} times)`);
4410
5298
  }
4411
5299
  };
4412
5300
  }, []);
@@ -4438,12 +5326,12 @@ function useLogger(componentName, props, options = {}) {
4438
5326
  });
4439
5327
  }
4440
5328
  if (hasChanges) {
4441
- logger2(`[${componentName}] Props changed:`, changedProps);
5329
+ logger3(`[${componentName}] Props changed:`, changedProps);
4442
5330
  }
4443
5331
  previousProps.current = props;
4444
- }, [componentName, props, logProps, logger2]);
5332
+ }, [componentName, props, logProps, logger3]);
4445
5333
  if (process.env.NODE_ENV === "development") {
4446
- logger2(`[${componentName}] Render #${renderCount.current}`);
5334
+ logger3(`[${componentName}] Render #${renderCount.current}`);
4447
5335
  }
4448
5336
  }
4449
5337
  var useLogger_default = useLogger;
@@ -7267,7 +8155,7 @@ __export(shared_exports, {
7267
8155
  VALIDATION_PATTERNS: () => VALIDATION_PATTERNS,
7268
8156
  VALIDATION_RULES: () => VALIDATION_RULES,
7269
8157
  VISIBILITY: () => VISIBILITY,
7270
- addDays: () => addDays$1,
8158
+ addDays: () => addDays,
7271
8159
  addHours: () => addHours,
7272
8160
  addMinutes: () => addMinutes,
7273
8161
  addMonths: () => addMonths,
@@ -7289,7 +8177,7 @@ __export(shared_exports, {
7289
8177
  eachDayOfInterval: () => eachDayOfInterval,
7290
8178
  eachMonthOfInterval: () => eachMonthOfInterval,
7291
8179
  eachWeekOfInterval: () => eachWeekOfInterval,
7292
- endOfDay: () => endOfDay$1,
8180
+ endOfDay: () => endOfDay,
7293
8181
  endOfMonth: () => endOfMonth,
7294
8182
  endOfWeek: () => endOfWeek,
7295
8183
  endOfYear: () => endOfYear,
@@ -7332,8 +8220,8 @@ __export(shared_exports, {
7332
8220
  isDateBetween: () => isDateBetween,
7333
8221
  isDev: () => isDev,
7334
8222
  isEqual: () => isEqual,
7335
- isFuture: () => isFuture$1,
7336
- isPast: () => isPast$1,
8223
+ isFuture: () => isFuture,
8224
+ isPast: () => isPast,
7337
8225
  isProd: () => isProd,
7338
8226
  isSameDay: () => isSameDay,
7339
8227
  isSameMonth: () => isSameMonth,
@@ -7343,7 +8231,7 @@ __export(shared_exports, {
7343
8231
  isThisMonth: () => isThisMonth,
7344
8232
  isThisWeek: () => isThisWeek,
7345
8233
  isThisYear: () => isThisYear,
7346
- isToday: () => isToday$1,
8234
+ isToday: () => isToday,
7347
8235
  isTomorrow: () => isTomorrow,
7348
8236
  isValid: () => isValid,
7349
8237
  isValidDate: () => isValidDate,
@@ -7363,7 +8251,7 @@ __export(shared_exports, {
7363
8251
  setMinutes: () => setMinutes,
7364
8252
  setSeconds: () => setSeconds,
7365
8253
  setTime: () => setTime,
7366
- startOfDay: () => startOfDay$1,
8254
+ startOfDay: () => startOfDay,
7367
8255
  startOfMonth: () => startOfMonth,
7368
8256
  startOfWeek: () => startOfWeek,
7369
8257
  startOfYear: () => startOfYear,
@@ -7857,7 +8745,7 @@ var formatRelativeTime2 = (date, baseDate) => {
7857
8745
  };
7858
8746
  var formatSmartDate = (date) => {
7859
8747
  const parsed = parseDate(date);
7860
- if (isToday$1(parsed)) {
8748
+ if (isToday(parsed)) {
7861
8749
  return `Today at ${format(parsed, DATE_FORMATS.TIME_SHORT)}`;
7862
8750
  }
7863
8751
  if (isYesterday(parsed)) {
@@ -7913,7 +8801,7 @@ var addTime = (date, amount, unit) => {
7913
8801
  case "hours":
7914
8802
  return addHours(parsed, amount);
7915
8803
  case "days":
7916
- return addDays$1(parsed, amount);
8804
+ return addDays(parsed, amount);
7917
8805
  case "weeks":
7918
8806
  return addWeeks(parsed, amount);
7919
8807
  case "months":
@@ -7980,8 +8868,8 @@ var getMonthsInRange = (start, end) => {
7980
8868
  var getDayBoundaries = (date) => {
7981
8869
  const parsed = parseDate(date);
7982
8870
  return {
7983
- start: startOfDay$1(parsed),
7984
- end: endOfDay$1(parsed)
8871
+ start: startOfDay(parsed),
8872
+ end: endOfDay(parsed)
7985
8873
  };
7986
8874
  };
7987
8875
  var getWeekBoundaries = (date, weekStartsOn = 0) => {