@exyconn/common 2.1.0 → 2.3.2

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 (122) hide show
  1. package/README.md +864 -261
  2. package/dist/client/hooks/index.d.mts +1042 -0
  3. package/dist/client/hooks/index.d.ts +1042 -0
  4. package/dist/client/hooks/index.js +2276 -0
  5. package/dist/client/hooks/index.js.map +1 -0
  6. package/dist/client/hooks/index.mjs +2217 -0
  7. package/dist/client/hooks/index.mjs.map +1 -0
  8. package/dist/client/index.d.mts +3 -1
  9. package/dist/client/index.d.ts +3 -1
  10. package/dist/client/web/index.d.mts +1461 -0
  11. package/dist/client/web/index.d.ts +1461 -0
  12. package/dist/client/web/index.js +2681 -0
  13. package/dist/client/web/index.js.map +1 -0
  14. package/dist/client/web/index.mjs +2618 -0
  15. package/dist/client/web/index.mjs.map +1 -0
  16. package/dist/data/brand-identity.d.mts +149 -0
  17. package/dist/data/brand-identity.d.ts +149 -0
  18. package/dist/data/brand-identity.js +235 -0
  19. package/dist/data/brand-identity.js.map +1 -0
  20. package/dist/data/brand-identity.mjs +220 -0
  21. package/dist/data/brand-identity.mjs.map +1 -0
  22. package/dist/data/countries.d.mts +61 -0
  23. package/dist/data/countries.d.ts +61 -0
  24. package/dist/data/countries.js +987 -0
  25. package/dist/data/countries.js.map +1 -0
  26. package/dist/data/countries.mjs +971 -0
  27. package/dist/data/countries.mjs.map +1 -0
  28. package/dist/data/currencies.d.mts +19 -0
  29. package/dist/data/currencies.d.ts +19 -0
  30. package/dist/data/currencies.js +162 -0
  31. package/dist/data/currencies.js.map +1 -0
  32. package/dist/data/currencies.mjs +153 -0
  33. package/dist/data/currencies.mjs.map +1 -0
  34. package/dist/data/index.d.mts +7 -0
  35. package/dist/data/index.d.ts +7 -0
  36. package/dist/data/index.js +2087 -0
  37. package/dist/data/index.js.map +1 -0
  38. package/dist/data/index.mjs +1948 -0
  39. package/dist/data/index.mjs.map +1 -0
  40. package/dist/data/phone-codes.d.mts +15 -0
  41. package/dist/data/phone-codes.d.ts +15 -0
  42. package/dist/data/phone-codes.js +219 -0
  43. package/dist/data/phone-codes.js.map +1 -0
  44. package/dist/data/phone-codes.mjs +211 -0
  45. package/dist/data/phone-codes.mjs.map +1 -0
  46. package/dist/data/regex.d.mts +287 -0
  47. package/dist/data/regex.d.ts +287 -0
  48. package/dist/data/regex.js +306 -0
  49. package/dist/data/regex.js.map +1 -0
  50. package/dist/data/regex.mjs +208 -0
  51. package/dist/data/regex.mjs.map +1 -0
  52. package/dist/data/timezones.d.mts +16 -0
  53. package/dist/data/timezones.d.ts +16 -0
  54. package/dist/data/timezones.js +98 -0
  55. package/dist/data/timezones.js.map +1 -0
  56. package/dist/data/timezones.mjs +89 -0
  57. package/dist/data/timezones.mjs.map +1 -0
  58. package/dist/index-01hoqibP.d.ts +119 -0
  59. package/dist/index-D3yCCjBZ.d.mts +119 -0
  60. package/dist/index-D9a9oxQy.d.ts +305 -0
  61. package/dist/index-DKn4raO7.d.ts +222 -0
  62. package/dist/index-DuxL84IW.d.mts +305 -0
  63. package/dist/index-NS8dS0p9.d.mts +222 -0
  64. package/dist/index-Nqm5_lwT.d.ts +188 -0
  65. package/dist/index-jBi3V6e5.d.mts +188 -0
  66. package/dist/index.d.mts +20 -579
  67. package/dist/index.d.ts +20 -579
  68. package/dist/index.js +717 -18
  69. package/dist/index.js.map +1 -1
  70. package/dist/index.mjs +716 -18
  71. package/dist/index.mjs.map +1 -1
  72. package/dist/server/configs/index.d.mts +602 -0
  73. package/dist/server/configs/index.d.ts +602 -0
  74. package/dist/server/configs/index.js +707 -0
  75. package/dist/server/configs/index.js.map +1 -0
  76. package/dist/server/configs/index.mjs +665 -0
  77. package/dist/server/configs/index.mjs.map +1 -0
  78. package/dist/server/index.d.mts +3 -0
  79. package/dist/server/index.d.ts +3 -0
  80. package/dist/server/index.js +699 -0
  81. package/dist/server/index.js.map +1 -1
  82. package/dist/server/index.mjs +662 -1
  83. package/dist/server/index.mjs.map +1 -1
  84. package/dist/shared/config/index.d.mts +40 -0
  85. package/dist/shared/config/index.d.ts +40 -0
  86. package/dist/shared/config/index.js +58 -0
  87. package/dist/shared/config/index.js.map +1 -0
  88. package/dist/shared/config/index.mjs +51 -0
  89. package/dist/shared/config/index.mjs.map +1 -0
  90. package/dist/shared/constants/index.d.mts +593 -0
  91. package/dist/shared/constants/index.d.ts +593 -0
  92. package/dist/shared/constants/index.js +391 -0
  93. package/dist/shared/constants/index.js.map +1 -0
  94. package/dist/shared/constants/index.mjs +360 -0
  95. package/dist/shared/constants/index.mjs.map +1 -0
  96. package/dist/shared/index.d.mts +5 -1
  97. package/dist/shared/index.d.ts +5 -1
  98. package/dist/shared/types/index.d.mts +140 -0
  99. package/dist/shared/types/index.d.ts +140 -0
  100. package/dist/shared/types/index.js +4 -0
  101. package/dist/shared/types/index.js.map +1 -0
  102. package/dist/shared/types/index.mjs +3 -0
  103. package/dist/shared/types/index.mjs.map +1 -0
  104. package/dist/shared/utils/index.d.mts +255 -0
  105. package/dist/shared/utils/index.d.ts +255 -0
  106. package/dist/shared/utils/index.js +623 -0
  107. package/dist/shared/utils/index.js.map +1 -0
  108. package/dist/shared/utils/index.mjs +324 -0
  109. package/dist/shared/utils/index.mjs.map +1 -0
  110. package/dist/shared/validation/index.d.mts +258 -0
  111. package/dist/shared/validation/index.d.ts +258 -0
  112. package/dist/shared/validation/index.js +185 -0
  113. package/dist/shared/validation/index.js.map +1 -0
  114. package/dist/shared/validation/index.mjs +172 -0
  115. package/dist/shared/validation/index.mjs.map +1 -0
  116. package/package.json +127 -62
  117. package/dist/index-BcxL4_V4.d.ts +0 -2946
  118. package/dist/index-DEzgM15j.d.ts +0 -67
  119. package/dist/index-DNFVgQx8.d.ts +0 -1375
  120. package/dist/index-DbV04Dx8.d.mts +0 -67
  121. package/dist/index-DfqEP6Oe.d.mts +0 -1375
  122. package/dist/index-bvvCev9Q.d.mts +0 -2946
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ var path = require('path');
6
6
  var mongoose = require('mongoose');
7
7
  var jwt = require('jsonwebtoken');
8
8
  var fs = require('fs');
9
+ var rateLimit = require('express-rate-limit');
9
10
  var axios = require('axios');
10
11
  var react = require('react');
11
12
  var jsxRuntime = require('react/jsx-runtime');
@@ -39,6 +40,7 @@ var DailyRotateFile__default = /*#__PURE__*/_interopDefault(DailyRotateFile);
39
40
  var path__default = /*#__PURE__*/_interopDefault(path);
40
41
  var mongoose__default = /*#__PURE__*/_interopDefault(mongoose);
41
42
  var jwt__default = /*#__PURE__*/_interopDefault(jwt);
43
+ var rateLimit__default = /*#__PURE__*/_interopDefault(rateLimit);
42
44
  var axios__default = /*#__PURE__*/_interopDefault(axios);
43
45
  var Yup__namespace = /*#__PURE__*/_interopNamespace(Yup);
44
46
 
@@ -51,20 +53,50 @@ var __export = (target, all) => {
51
53
  // src/server/index.ts
52
54
  var server_exports = {};
53
55
  __export(server_exports, {
56
+ ConfigBuilder: () => ConfigBuilder,
57
+ DEFAULT_AUTH_CONFIG: () => DEFAULT_AUTH_CONFIG,
58
+ DEFAULT_CORS_CONFIG: () => DEFAULT_CORS_CONFIG,
59
+ DEFAULT_CORS_ORIGINS: () => DEFAULT_CORS_ORIGINS,
60
+ DEFAULT_DATABASE_CONFIG: () => DEFAULT_DATABASE_CONFIG,
61
+ DEFAULT_LOGGING_CONFIG: () => DEFAULT_LOGGING_CONFIG,
62
+ DEFAULT_RATE_LIMIT_CONFIG: () => DEFAULT_RATE_LIMIT_CONFIG,
63
+ DEFAULT_RATE_LIMIT_TIERS: () => DEFAULT_RATE_LIMIT_TIERS,
64
+ DEFAULT_SERVER_CONFIG: () => DEFAULT_SERVER_CONFIG,
65
+ EXYCONN_CORS_CONFIG: () => EXYCONN_CORS_CONFIG,
66
+ PERMISSIVE_CORS_CONFIG: () => PERMISSIVE_CORS_CONFIG,
67
+ RATE_LIMIT_CONFIG: () => RATE_LIMIT_CONFIG,
68
+ RateLimiterBuilder: () => RateLimiterBuilder,
69
+ STRICT_CORS_CONFIG: () => STRICT_CORS_CONFIG,
54
70
  StatusCode: () => StatusCode,
55
71
  StatusMessage: () => StatusMessage,
56
72
  authenticateApiKey: () => authenticateApiKey,
57
73
  authenticateJWT: () => authenticateJWT,
58
74
  badRequestResponse: () => badRequestResponse,
75
+ buildConfig: () => buildConfig,
59
76
  buildFilter: () => buildFilter,
60
77
  buildPagination: () => buildPagination,
61
78
  buildPaginationMeta: () => buildPaginationMeta,
62
79
  checkPackageServer: () => checkPackageServer,
63
80
  conflictResponse: () => conflictResponse,
64
81
  connectDB: () => connectDB,
82
+ corsOptions: () => corsOptions,
83
+ createApiKeyGenerator: () => createApiKeyGenerator,
84
+ createApiRateLimiter: () => createApiRateLimiter,
85
+ createBrandCorsOptions: () => createBrandCorsOptions,
86
+ createConfig: () => createConfig,
87
+ createCorsOptions: () => createCorsOptions,
88
+ createDdosRateLimiter: () => createDdosRateLimiter,
65
89
  createLogger: () => createLogger,
66
90
  createMorganStream: () => createMorganStream,
91
+ createMultiBrandCorsOptions: () => createMultiBrandCorsOptions,
92
+ createPrefixedKeyGenerator: () => createPrefixedKeyGenerator,
93
+ createRateLimiter: () => createRateLimiter,
94
+ createStandardRateLimiter: () => createStandardRateLimiter,
95
+ createStrictRateLimiter: () => createStrictRateLimiter,
96
+ createUserKeyGenerator: () => createUserKeyGenerator,
67
97
  createdResponse: () => createdResponse,
98
+ ddosProtectionLimiter: () => ddosProtectionLimiter,
99
+ defaultKeyGenerator: () => defaultKeyGenerator,
68
100
  disconnectDB: () => disconnectDB,
69
101
  errorResponse: () => errorResponse,
70
102
  extractColumns: () => extractColumns,
@@ -73,6 +105,10 @@ __export(server_exports, {
73
105
  formatPackageCheckResult: () => formatPackageCheckResult,
74
106
  generateNcuCommand: () => generateNcuCommand,
75
107
  getConnectionStatus: () => getConnectionStatus,
108
+ getDatabaseOptions: () => getDatabaseOptions,
109
+ isDevelopment: () => isDevelopment,
110
+ isProduction: () => isProduction,
111
+ isTest: () => isTest,
76
112
  logger: () => logger,
77
113
  noContentResponse: () => noContentResponse,
78
114
  notFoundResponse: () => notFoundResponse,
@@ -82,13 +118,16 @@ __export(server_exports, {
82
118
  pickFields: () => pickFields,
83
119
  printPackageCheckSummary: () => printPackageCheckSummary,
84
120
  rateLimitResponse: () => rateLimitResponse,
121
+ rateLimiter: () => rateLimiter,
85
122
  requireOrganization: () => requireOrganization,
86
123
  sanitizeDocument: () => sanitizeDocument,
87
124
  sanitizeUser: () => sanitizeUser,
88
125
  simpleLogger: () => simpleLogger,
126
+ standardRateLimiter: () => standardRateLimiter,
89
127
  statusCode: () => statusCode,
90
128
  statusMessage: () => statusMessage,
91
129
  stream: () => stream,
130
+ strictRateLimiter: () => strictRateLimiter,
92
131
  successResponse: () => successResponse,
93
132
  successResponseArr: () => successResponseArr,
94
133
  unauthorizedResponse: () => unauthorizedResponse,
@@ -800,6 +839,666 @@ var packageCheckServer = {
800
839
  print: printPackageCheckSummary
801
840
  };
802
841
 
842
+ // src/server/configs/cors.config.ts
843
+ var DEFAULT_CORS_CONFIG = {
844
+ productionOrigins: [],
845
+ developmentOrigins: [
846
+ "http://localhost:3000",
847
+ "http://localhost:4000",
848
+ "http://localhost:5000",
849
+ "http://localhost:5173",
850
+ "http://localhost:8080",
851
+ "http://127.0.0.1:3000",
852
+ "http://127.0.0.1:4000",
853
+ "http://127.0.0.1:5000",
854
+ "http://127.0.0.1:5173",
855
+ "http://127.0.0.1:8080"
856
+ ],
857
+ allowedSubdomains: [],
858
+ originPatterns: [],
859
+ allowNoOrigin: true,
860
+ allowAllInDev: true,
861
+ credentials: true,
862
+ methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"],
863
+ allowedHeaders: [
864
+ "Content-Type",
865
+ "Authorization",
866
+ "X-Requested-With",
867
+ "Accept",
868
+ "Origin",
869
+ "X-API-Key",
870
+ "X-Organization-Id",
871
+ "X-Request-Id"
872
+ ],
873
+ exposedHeaders: [
874
+ "Content-Range",
875
+ "X-Content-Range",
876
+ "X-Total-Count",
877
+ "X-Request-Id"
878
+ ],
879
+ maxAge: 86400
880
+ // 24 hours
881
+ };
882
+ var createCorsOptions = (config = {}) => {
883
+ const finalConfig = { ...DEFAULT_CORS_CONFIG, ...config };
884
+ const {
885
+ productionOrigins,
886
+ developmentOrigins,
887
+ allowedSubdomains,
888
+ originPatterns,
889
+ allowNoOrigin,
890
+ allowAllInDev,
891
+ customValidator,
892
+ credentials,
893
+ methods,
894
+ allowedHeaders,
895
+ exposedHeaders,
896
+ maxAge
897
+ } = finalConfig;
898
+ const allOrigins = /* @__PURE__ */ new Set([...productionOrigins, ...developmentOrigins]);
899
+ const originHandler = (origin, callback) => {
900
+ if (!origin) {
901
+ callback(null, allowNoOrigin);
902
+ return;
903
+ }
904
+ if (allOrigins.has(origin)) {
905
+ callback(null, true);
906
+ return;
907
+ }
908
+ if (allowedSubdomains.some((subdomain) => origin.endsWith(subdomain))) {
909
+ callback(null, true);
910
+ return;
911
+ }
912
+ if (originPatterns.some((pattern) => pattern.test(origin))) {
913
+ callback(null, true);
914
+ return;
915
+ }
916
+ if (customValidator && customValidator(origin)) {
917
+ callback(null, true);
918
+ return;
919
+ }
920
+ if (process.env.NODE_ENV !== "production" && allowAllInDev) {
921
+ callback(null, true);
922
+ return;
923
+ }
924
+ if (process.env.NODE_ENV === "production") {
925
+ callback(new Error(`Origin ${origin} not allowed by CORS`));
926
+ return;
927
+ }
928
+ callback(null, true);
929
+ };
930
+ return {
931
+ origin: originHandler,
932
+ credentials,
933
+ methods,
934
+ allowedHeaders,
935
+ exposedHeaders,
936
+ maxAge
937
+ };
938
+ };
939
+ var createBrandCorsOptions = (brandDomain, additionalConfig = {}) => {
940
+ const productionOrigins = [
941
+ `https://${brandDomain}`,
942
+ `https://www.${brandDomain}`
943
+ ];
944
+ const allowedSubdomains = [`.${brandDomain}`];
945
+ return createCorsOptions({
946
+ productionOrigins,
947
+ allowedSubdomains,
948
+ ...additionalConfig
949
+ });
950
+ };
951
+ var createMultiBrandCorsOptions = (domains, additionalConfig = {}) => {
952
+ const productionOrigins = domains.flatMap((domain) => [
953
+ `https://${domain}`,
954
+ `https://www.${domain}`
955
+ ]);
956
+ const allowedSubdomains = domains.map((domain) => `.${domain}`);
957
+ return createCorsOptions({
958
+ productionOrigins,
959
+ allowedSubdomains,
960
+ ...additionalConfig
961
+ });
962
+ };
963
+ var EXYCONN_CORS_CONFIG = {
964
+ productionOrigins: [
965
+ "https://exyconn.com",
966
+ "https://www.exyconn.com",
967
+ "https://botify.life",
968
+ "https://www.botify.life",
969
+ "https://partywings.fun",
970
+ "https://www.partywings.fun",
971
+ "https://sibera.work",
972
+ "https://www.sibera.work",
973
+ "https://spentiva.com",
974
+ "https://www.spentiva.com"
975
+ ],
976
+ allowedSubdomains: [
977
+ ".exyconn.com",
978
+ ".botify.life",
979
+ ".partywings.fun",
980
+ ".sibera.work",
981
+ ".spentiva.com"
982
+ ],
983
+ developmentOrigins: [
984
+ "http://localhost:3000",
985
+ "http://localhost:4000",
986
+ "http://localhost:4001",
987
+ "http://localhost:4002",
988
+ "http://localhost:4003",
989
+ "http://localhost:4004",
990
+ "http://localhost:4005",
991
+ "http://localhost:5173",
992
+ "http://127.0.0.1:3000",
993
+ "http://127.0.0.1:4000",
994
+ "http://127.0.0.1:5173"
995
+ ]
996
+ };
997
+ var STRICT_CORS_CONFIG = {
998
+ allowNoOrigin: false,
999
+ allowAllInDev: false,
1000
+ methods: ["GET", "POST", "PUT", "DELETE"]
1001
+ };
1002
+ var PERMISSIVE_CORS_CONFIG = {
1003
+ allowNoOrigin: true,
1004
+ allowAllInDev: true,
1005
+ originPatterns: [/localhost/, /127\.0\.0\.1/]
1006
+ };
1007
+ var corsOptions = createCorsOptions(EXYCONN_CORS_CONFIG);
1008
+ var DEFAULT_RATE_LIMIT_TIERS = {
1009
+ STANDARD: {
1010
+ windowMs: 15 * 60 * 1e3,
1011
+ // 15 minutes
1012
+ maxRequests: 100,
1013
+ message: "Too many requests, please try again later.",
1014
+ skipSuccessfulRequests: false,
1015
+ skipFailedRequests: false
1016
+ },
1017
+ STRICT: {
1018
+ windowMs: 15 * 60 * 1e3,
1019
+ // 15 minutes
1020
+ maxRequests: 20,
1021
+ message: "Too many requests, please try again later.",
1022
+ skipSuccessfulRequests: false,
1023
+ skipFailedRequests: false
1024
+ },
1025
+ DDOS: {
1026
+ windowMs: 60 * 1e3,
1027
+ // 1 minute
1028
+ maxRequests: 60,
1029
+ message: "Rate limit exceeded. Please slow down.",
1030
+ skipSuccessfulRequests: false,
1031
+ skipFailedRequests: false
1032
+ },
1033
+ // Additional presets
1034
+ VERY_STRICT: {
1035
+ windowMs: 60 * 60 * 1e3,
1036
+ // 1 hour
1037
+ maxRequests: 5,
1038
+ message: "Too many attempts. Please try again in an hour.",
1039
+ skipSuccessfulRequests: false,
1040
+ skipFailedRequests: false
1041
+ },
1042
+ RELAXED: {
1043
+ windowMs: 15 * 60 * 1e3,
1044
+ // 15 minutes
1045
+ maxRequests: 500,
1046
+ message: "Rate limit exceeded.",
1047
+ skipSuccessfulRequests: false,
1048
+ skipFailedRequests: false
1049
+ },
1050
+ API: {
1051
+ windowMs: 60 * 1e3,
1052
+ // 1 minute
1053
+ maxRequests: 30,
1054
+ message: "API rate limit exceeded.",
1055
+ skipSuccessfulRequests: false,
1056
+ skipFailedRequests: false
1057
+ }
1058
+ };
1059
+ var defaultKeyGenerator = (req) => {
1060
+ const forwarded = req.headers["x-forwarded-for"];
1061
+ const ip = forwarded ? Array.isArray(forwarded) ? forwarded[0] : forwarded.split(",")[0].trim() : req.ip || req.socket.remoteAddress || "unknown";
1062
+ return ip;
1063
+ };
1064
+ var createPrefixedKeyGenerator = (prefix) => (req) => {
1065
+ return `${prefix}:${defaultKeyGenerator(req)}`;
1066
+ };
1067
+ var createUserKeyGenerator = (getUserId) => (req) => {
1068
+ const userId = getUserId(req);
1069
+ return userId || defaultKeyGenerator(req);
1070
+ };
1071
+ var createApiKeyGenerator = (headerName = "x-api-key") => (req) => {
1072
+ const apiKey = req.headers[headerName.toLowerCase()];
1073
+ return apiKey || defaultKeyGenerator(req);
1074
+ };
1075
+ var createRateLimitResponse = (message, retryAfter) => ({
1076
+ status: "error",
1077
+ statusCode: 429,
1078
+ message,
1079
+ ...retryAfter
1080
+ });
1081
+ var createRateLimiter = (tierConfig, options = {}) => {
1082
+ const {
1083
+ standardHeaders = true,
1084
+ legacyHeaders = false,
1085
+ keyGenerator = defaultKeyGenerator,
1086
+ skip,
1087
+ handler
1088
+ } = options;
1089
+ return rateLimit__default.default({
1090
+ windowMs: tierConfig.windowMs,
1091
+ max: tierConfig.maxRequests,
1092
+ message: createRateLimitResponse(tierConfig.message),
1093
+ standardHeaders,
1094
+ legacyHeaders,
1095
+ keyGenerator,
1096
+ skip,
1097
+ handler,
1098
+ skipSuccessfulRequests: tierConfig.skipSuccessfulRequests,
1099
+ skipFailedRequests: tierConfig.skipFailedRequests
1100
+ });
1101
+ };
1102
+ var createStandardRateLimiter = (config = {}, options = {}) => {
1103
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.STANDARD, ...config };
1104
+ return createRateLimiter(tierConfig, options);
1105
+ };
1106
+ var createStrictRateLimiter = (config = {}, options = {}) => {
1107
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.STRICT, ...config };
1108
+ return createRateLimiter(tierConfig, options);
1109
+ };
1110
+ var createDdosRateLimiter = (config = {}, options = {}) => {
1111
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.DDOS, ...config };
1112
+ return createRateLimiter(tierConfig, options);
1113
+ };
1114
+ var createApiRateLimiter = (config = {}, options = {}) => {
1115
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.API, ...config };
1116
+ return createRateLimiter(tierConfig, {
1117
+ keyGenerator: createApiKeyGenerator(),
1118
+ ...options
1119
+ });
1120
+ };
1121
+ var RateLimiterBuilder = class {
1122
+ constructor(preset = "STANDARD") {
1123
+ const presetConfig = DEFAULT_RATE_LIMIT_TIERS[preset];
1124
+ this.config = {
1125
+ windowMs: presetConfig.windowMs,
1126
+ maxRequests: presetConfig.maxRequests,
1127
+ message: presetConfig.message,
1128
+ skipSuccessfulRequests: presetConfig.skipSuccessfulRequests ?? false,
1129
+ skipFailedRequests: presetConfig.skipFailedRequests ?? false
1130
+ };
1131
+ this.options = {};
1132
+ }
1133
+ /**
1134
+ * Set window duration
1135
+ */
1136
+ windowMs(ms) {
1137
+ this.config.windowMs = ms;
1138
+ return this;
1139
+ }
1140
+ /**
1141
+ * Set window duration in minutes
1142
+ */
1143
+ windowMinutes(minutes) {
1144
+ this.config.windowMs = minutes * 60 * 1e3;
1145
+ return this;
1146
+ }
1147
+ /**
1148
+ * Set window duration in hours
1149
+ */
1150
+ windowHours(hours) {
1151
+ this.config.windowMs = hours * 60 * 60 * 1e3;
1152
+ return this;
1153
+ }
1154
+ /**
1155
+ * Set maximum requests
1156
+ */
1157
+ max(requests) {
1158
+ this.config.maxRequests = requests;
1159
+ return this;
1160
+ }
1161
+ /**
1162
+ * Set error message
1163
+ */
1164
+ message(msg) {
1165
+ this.config.message = msg;
1166
+ return this;
1167
+ }
1168
+ /**
1169
+ * Skip successful requests
1170
+ */
1171
+ skipSuccessful(skip = true) {
1172
+ this.config.skipSuccessfulRequests = skip;
1173
+ return this;
1174
+ }
1175
+ /**
1176
+ * Skip failed requests
1177
+ */
1178
+ skipFailed(skip = true) {
1179
+ this.config.skipFailedRequests = skip;
1180
+ return this;
1181
+ }
1182
+ /**
1183
+ * Set key generator
1184
+ */
1185
+ keyBy(generator) {
1186
+ this.options.keyGenerator = generator;
1187
+ return this;
1188
+ }
1189
+ /**
1190
+ * Key by IP (default)
1191
+ */
1192
+ keyByIp() {
1193
+ this.options.keyGenerator = defaultKeyGenerator;
1194
+ return this;
1195
+ }
1196
+ /**
1197
+ * Key by API key
1198
+ */
1199
+ keyByApiKey(headerName) {
1200
+ this.options.keyGenerator = createApiKeyGenerator(headerName);
1201
+ return this;
1202
+ }
1203
+ /**
1204
+ * Skip certain requests
1205
+ */
1206
+ skipWhen(predicate) {
1207
+ this.options.skip = predicate;
1208
+ return this;
1209
+ }
1210
+ /**
1211
+ * Build the rate limiter
1212
+ */
1213
+ build() {
1214
+ return createRateLimiter(this.config, this.options);
1215
+ }
1216
+ };
1217
+ var rateLimiter = (preset) => {
1218
+ return new RateLimiterBuilder(preset);
1219
+ };
1220
+ var RATE_LIMIT_CONFIG = {
1221
+ STANDARD: DEFAULT_RATE_LIMIT_TIERS.STANDARD,
1222
+ STRICT: DEFAULT_RATE_LIMIT_TIERS.STRICT,
1223
+ DDOS: DEFAULT_RATE_LIMIT_TIERS.DDOS
1224
+ };
1225
+ var standardRateLimiter = createStandardRateLimiter();
1226
+ var strictRateLimiter = createStrictRateLimiter();
1227
+ var ddosProtectionLimiter = createDdosRateLimiter();
1228
+
1229
+ // src/server/configs/server.config.ts
1230
+ var DEFAULT_SERVER_CONFIG = {
1231
+ name: "app-server",
1232
+ version: "1.0.0",
1233
+ environment: process.env.NODE_ENV || "development",
1234
+ port: parseInt(process.env.PORT || "3000", 10),
1235
+ host: process.env.HOST || "0.0.0.0",
1236
+ basePath: "/api",
1237
+ debug: process.env.DEBUG === "true",
1238
+ trustProxy: true
1239
+ };
1240
+ var DEFAULT_DATABASE_CONFIG = {
1241
+ uri: process.env.DATABASE_URL || process.env.MONGODB_URI || "",
1242
+ name: process.env.DATABASE_NAME || "app_db",
1243
+ maxPoolSize: process.env.NODE_ENV === "production" ? 50 : 10,
1244
+ minPoolSize: process.env.NODE_ENV === "production" ? 10 : 5,
1245
+ socketTimeoutMS: 45e3,
1246
+ serverSelectionTimeoutMS: 1e4,
1247
+ maxIdleTimeMS: 1e4,
1248
+ retryWrites: true,
1249
+ retryReads: true,
1250
+ writeConcern: "majority"
1251
+ };
1252
+ var DEFAULT_AUTH_CONFIG = {
1253
+ jwtSecret: process.env.JWT_SECRET || "",
1254
+ jwtExpiresIn: process.env.JWT_EXPIRES_IN || "7d",
1255
+ refreshTokenExpiresIn: process.env.REFRESH_TOKEN_EXPIRES_IN || "30d",
1256
+ enableRefreshTokens: true,
1257
+ apiKeyHeader: "x-api-key",
1258
+ orgHeader: "x-organization-id"
1259
+ };
1260
+ var DEFAULT_LOGGING_CONFIG = {
1261
+ level: process.env.LOG_LEVEL || "info",
1262
+ logsDir: process.env.LOGS_DIR || "logs",
1263
+ maxSize: "20m",
1264
+ maxFiles: "14d",
1265
+ errorMaxFiles: "30d",
1266
+ console: true,
1267
+ file: process.env.NODE_ENV === "production",
1268
+ json: process.env.NODE_ENV === "production"
1269
+ };
1270
+ var DEFAULT_CORS_ORIGINS = {
1271
+ production: [],
1272
+ development: [
1273
+ "http://localhost:3000",
1274
+ "http://localhost:4000",
1275
+ "http://localhost:5173",
1276
+ "http://127.0.0.1:3000",
1277
+ "http://127.0.0.1:4000",
1278
+ "http://127.0.0.1:5173"
1279
+ ],
1280
+ patterns: []
1281
+ };
1282
+ var DEFAULT_RATE_LIMIT_CONFIG = {
1283
+ enabled: true,
1284
+ standard: {
1285
+ windowMs: 15 * 60 * 1e3,
1286
+ // 15 minutes
1287
+ maxRequests: 100,
1288
+ message: "Too many requests, please try again later."
1289
+ },
1290
+ strict: {
1291
+ windowMs: 15 * 60 * 1e3,
1292
+ // 15 minutes
1293
+ maxRequests: 20,
1294
+ message: "Too many requests, please try again later."
1295
+ },
1296
+ ddos: {
1297
+ windowMs: 60 * 1e3,
1298
+ // 1 minute
1299
+ maxRequests: 60,
1300
+ message: "Rate limit exceeded. Please slow down.",
1301
+ skipSuccessfulRequests: false
1302
+ }
1303
+ };
1304
+ function deepMerge(target, source) {
1305
+ const result = { ...target };
1306
+ for (const key in source) {
1307
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1308
+ const sourceValue = source[key];
1309
+ const targetValue = target[key];
1310
+ if (sourceValue !== void 0 && typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) {
1311
+ result[key] = deepMerge(
1312
+ targetValue,
1313
+ sourceValue
1314
+ );
1315
+ } else if (sourceValue !== void 0) {
1316
+ result[key] = sourceValue;
1317
+ }
1318
+ }
1319
+ }
1320
+ return result;
1321
+ }
1322
+ var ConfigBuilder = class {
1323
+ constructor() {
1324
+ this.config = {
1325
+ server: { ...DEFAULT_SERVER_CONFIG },
1326
+ database: { ...DEFAULT_DATABASE_CONFIG },
1327
+ auth: { ...DEFAULT_AUTH_CONFIG },
1328
+ logging: { ...DEFAULT_LOGGING_CONFIG },
1329
+ cors: { ...DEFAULT_CORS_ORIGINS },
1330
+ rateLimit: { ...DEFAULT_RATE_LIMIT_CONFIG }
1331
+ };
1332
+ }
1333
+ /**
1334
+ * Set server configuration
1335
+ */
1336
+ setServer(config) {
1337
+ this.config.server = deepMerge(this.config.server, config);
1338
+ return this;
1339
+ }
1340
+ /**
1341
+ * Set database configuration
1342
+ */
1343
+ setDatabase(config) {
1344
+ this.config.database = deepMerge(this.config.database, config);
1345
+ return this;
1346
+ }
1347
+ /**
1348
+ * Set auth configuration
1349
+ */
1350
+ setAuth(config) {
1351
+ this.config.auth = deepMerge(this.config.auth, config);
1352
+ return this;
1353
+ }
1354
+ /**
1355
+ * Set logging configuration
1356
+ */
1357
+ setLogging(config) {
1358
+ this.config.logging = deepMerge(this.config.logging, config);
1359
+ return this;
1360
+ }
1361
+ /**
1362
+ * Set CORS origins
1363
+ */
1364
+ setCorsOrigins(config) {
1365
+ this.config.cors = deepMerge(this.config.cors, config);
1366
+ return this;
1367
+ }
1368
+ /**
1369
+ * Add CORS production origin
1370
+ */
1371
+ addProductionOrigin(origin) {
1372
+ if (!this.config.cors.production.includes(origin)) {
1373
+ this.config.cors.production.push(origin);
1374
+ }
1375
+ return this;
1376
+ }
1377
+ /**
1378
+ * Add CORS development origin
1379
+ */
1380
+ addDevelopmentOrigin(origin) {
1381
+ if (!this.config.cors.development.includes(origin)) {
1382
+ this.config.cors.development.push(origin);
1383
+ }
1384
+ return this;
1385
+ }
1386
+ /**
1387
+ * Add CORS pattern
1388
+ */
1389
+ addCorsPattern(pattern) {
1390
+ if (!this.config.cors.patterns.includes(pattern)) {
1391
+ this.config.cors.patterns.push(pattern);
1392
+ }
1393
+ return this;
1394
+ }
1395
+ /**
1396
+ * Set rate limit configuration
1397
+ */
1398
+ setRateLimit(config) {
1399
+ this.config.rateLimit = deepMerge(this.config.rateLimit, config);
1400
+ return this;
1401
+ }
1402
+ /**
1403
+ * Add custom rate limit tier
1404
+ */
1405
+ addRateLimitTier(name, tier) {
1406
+ if (!this.config.rateLimit.custom) {
1407
+ this.config.rateLimit.custom = {};
1408
+ }
1409
+ this.config.rateLimit.custom[name] = tier;
1410
+ return this;
1411
+ }
1412
+ /**
1413
+ * Set custom configuration
1414
+ */
1415
+ setCustom(key, value) {
1416
+ if (!this.config.custom) {
1417
+ this.config.custom = {};
1418
+ }
1419
+ this.config.custom[key] = value;
1420
+ return this;
1421
+ }
1422
+ /**
1423
+ * Load configuration from environment variables
1424
+ */
1425
+ loadFromEnv() {
1426
+ if (process.env.SERVER_NAME) this.config.server.name = process.env.SERVER_NAME;
1427
+ if (process.env.SERVER_VERSION) this.config.server.version = process.env.SERVER_VERSION;
1428
+ if (process.env.PORT) this.config.server.port = parseInt(process.env.PORT, 10);
1429
+ if (process.env.HOST) this.config.server.host = process.env.HOST;
1430
+ if (process.env.BASE_PATH) this.config.server.basePath = process.env.BASE_PATH;
1431
+ if (process.env.DATABASE_URL) this.config.database.uri = process.env.DATABASE_URL;
1432
+ if (process.env.MONGODB_URI) this.config.database.uri = process.env.MONGODB_URI;
1433
+ if (process.env.DATABASE_NAME) this.config.database.name = process.env.DATABASE_NAME;
1434
+ if (process.env.JWT_SECRET) this.config.auth.jwtSecret = process.env.JWT_SECRET;
1435
+ if (process.env.JWT_EXPIRES_IN) this.config.auth.jwtExpiresIn = process.env.JWT_EXPIRES_IN;
1436
+ if (process.env.LOG_LEVEL) this.config.logging.level = process.env.LOG_LEVEL;
1437
+ if (process.env.LOGS_DIR) this.config.logging.logsDir = process.env.LOGS_DIR;
1438
+ if (process.env.CORS_ORIGINS) {
1439
+ const origins = process.env.CORS_ORIGINS.split(",").map((o) => o.trim());
1440
+ this.config.cors.production.push(...origins);
1441
+ }
1442
+ return this;
1443
+ }
1444
+ /**
1445
+ * Validate configuration
1446
+ */
1447
+ validate() {
1448
+ const errors = [];
1449
+ if (!this.config.server.name) errors.push("Server name is required");
1450
+ if (this.config.server.port < 1 || this.config.server.port > 65535) {
1451
+ errors.push("Server port must be between 1 and 65535");
1452
+ }
1453
+ if (this.config.server.environment === "production") {
1454
+ if (!this.config.auth.jwtSecret || this.config.auth.jwtSecret.length < 32) {
1455
+ errors.push("JWT secret must be at least 32 characters in production");
1456
+ }
1457
+ }
1458
+ return { valid: errors.length === 0, errors };
1459
+ }
1460
+ /**
1461
+ * Build the final configuration
1462
+ */
1463
+ build() {
1464
+ return { ...this.config };
1465
+ }
1466
+ };
1467
+ var createConfig = () => {
1468
+ return new ConfigBuilder();
1469
+ };
1470
+ var buildConfig = (partial = {}) => {
1471
+ const builder = createConfig().loadFromEnv();
1472
+ if (partial.server) builder.setServer(partial.server);
1473
+ if (partial.database) builder.setDatabase(partial.database);
1474
+ if (partial.auth) builder.setAuth(partial.auth);
1475
+ if (partial.logging) builder.setLogging(partial.logging);
1476
+ if (partial.cors) builder.setCorsOrigins(partial.cors);
1477
+ if (partial.rateLimit) builder.setRateLimit(partial.rateLimit);
1478
+ return builder.build();
1479
+ };
1480
+ var isProduction = (config) => {
1481
+ return (config?.environment || process.env.NODE_ENV) === "production";
1482
+ };
1483
+ var isDevelopment = (config) => {
1484
+ return (config?.environment || process.env.NODE_ENV) === "development";
1485
+ };
1486
+ var isTest = (config) => {
1487
+ return (config?.environment || process.env.NODE_ENV) === "test";
1488
+ };
1489
+ var getDatabaseOptions = (config) => {
1490
+ return {
1491
+ maxPoolSize: config.maxPoolSize,
1492
+ minPoolSize: config.minPoolSize,
1493
+ socketTimeoutMS: config.socketTimeoutMS,
1494
+ serverSelectionTimeoutMS: config.serverSelectionTimeoutMS,
1495
+ maxIdleTimeMS: config.maxIdleTimeMS,
1496
+ retryWrites: config.retryWrites,
1497
+ retryReads: config.retryReads,
1498
+ w: config.writeConcern
1499
+ };
1500
+ };
1501
+
803
1502
  // src/client/index.ts
804
1503
  var client_exports = {};
805
1504
  __export(client_exports, {
@@ -836,7 +1535,7 @@ __export(client_exports, {
836
1535
  createTheme: () => createTheme,
837
1536
  createThemeFromBrand: () => createThemeFromBrand,
838
1537
  cssVar: () => cssVar,
839
- deepMerge: () => deepMerge,
1538
+ deepMerge: () => deepMerge2,
840
1539
  defaultDarkTheme: () => defaultDarkTheme,
841
1540
  defaultLightTheme: () => defaultLightTheme,
842
1541
  dummyBannerData: () => dummyBannerData,
@@ -4973,14 +5672,14 @@ var defaultDarkTheme = {
4973
5672
  };
4974
5673
 
4975
5674
  // src/client/web/theme/theme-utils.ts
4976
- function deepMerge(target, source) {
5675
+ function deepMerge2(target, source) {
4977
5676
  const output = { ...target };
4978
5677
  for (const key in source) {
4979
5678
  if (Object.prototype.hasOwnProperty.call(source, key)) {
4980
5679
  const sourceValue = source[key];
4981
5680
  const targetValue = target[key];
4982
5681
  if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue)) {
4983
- output[key] = deepMerge(
5682
+ output[key] = deepMerge2(
4984
5683
  targetValue,
4985
5684
  sourceValue
4986
5685
  );
@@ -5046,7 +5745,7 @@ function createThemeFromBrand(brand, baseTheme = defaultLightTheme) {
5046
5745
  }
5047
5746
  }
5048
5747
  };
5049
- return deepMerge(baseTheme, brandOverrides);
5748
+ return deepMerge2(baseTheme, brandOverrides);
5050
5749
  }
5051
5750
  function adjustColor(hex, percent) {
5052
5751
  hex = hex.replace(/^#/, "");
@@ -5140,8 +5839,8 @@ async function createTheme(config = {}) {
5140
5839
  if (config.themeUrl) {
5141
5840
  const urlTheme = await loadThemeFromUrl(config.themeUrl);
5142
5841
  if (urlTheme) {
5143
- lightTheme = deepMerge(lightTheme, urlTheme);
5144
- darkTheme = deepMerge(darkTheme, urlTheme);
5842
+ lightTheme = deepMerge2(lightTheme, urlTheme);
5843
+ darkTheme = deepMerge2(darkTheme, urlTheme);
5145
5844
  }
5146
5845
  }
5147
5846
  if (config.brandIdentity) {
@@ -5149,10 +5848,10 @@ async function createTheme(config = {}) {
5149
5848
  darkTheme = createThemeFromBrand(config.brandIdentity, darkTheme);
5150
5849
  }
5151
5850
  if (config.light) {
5152
- lightTheme = deepMerge(lightTheme, config.light);
5851
+ lightTheme = deepMerge2(lightTheme, config.light);
5153
5852
  }
5154
5853
  if (config.dark) {
5155
- darkTheme = deepMerge(darkTheme, config.dark);
5854
+ darkTheme = deepMerge2(darkTheme, config.dark);
5156
5855
  }
5157
5856
  return { light: lightTheme, dark: darkTheme };
5158
5857
  }
@@ -5226,7 +5925,7 @@ function ThemeProvider({
5226
5925
  theme2 = createThemeFromBrand(brandIdentity, theme2);
5227
5926
  }
5228
5927
  if (lightOverrides) {
5229
- theme2 = deepMerge(theme2, lightOverrides);
5928
+ theme2 = deepMerge2(theme2, lightOverrides);
5230
5929
  }
5231
5930
  return theme2;
5232
5931
  });
@@ -5237,7 +5936,7 @@ function ThemeProvider({
5237
5936
  theme2 = createThemeFromBrand(brandIdentity, theme2);
5238
5937
  }
5239
5938
  if (darkOverrides) {
5240
- theme2 = deepMerge(theme2, darkOverrides);
5939
+ theme2 = deepMerge2(theme2, darkOverrides);
5241
5940
  }
5242
5941
  return theme2;
5243
5942
  });
@@ -5256,8 +5955,8 @@ function ThemeProvider({
5256
5955
  setError(null);
5257
5956
  loadThemeFromUrl(themeUrl).then((urlTheme) => {
5258
5957
  if (urlTheme) {
5259
- setLightTheme((prev) => deepMerge(prev, urlTheme));
5260
- setDarkTheme((prev) => deepMerge(prev, urlTheme));
5958
+ setLightTheme((prev) => deepMerge2(prev, urlTheme));
5959
+ setDarkTheme((prev) => deepMerge2(prev, urlTheme));
5261
5960
  }
5262
5961
  }).catch((err) => {
5263
5962
  setError(err instanceof Error ? err.message : "Failed to load theme");
@@ -5302,8 +6001,8 @@ function ThemeProvider({
5302
6001
  });
5303
6002
  }, []);
5304
6003
  const updateTheme = react.useCallback((updates) => {
5305
- setLightTheme((prev) => deepMerge(prev, updates));
5306
- setDarkTheme((prev) => deepMerge(prev, updates));
6004
+ setLightTheme((prev) => deepMerge2(prev, updates));
6005
+ setDarkTheme((prev) => deepMerge2(prev, updates));
5307
6006
  }, []);
5308
6007
  const resetTheme = react.useCallback(() => {
5309
6008
  let light = defaultLightTheme;
@@ -5313,10 +6012,10 @@ function ThemeProvider({
5313
6012
  dark = createThemeFromBrand(brandIdentity, dark);
5314
6013
  }
5315
6014
  if (lightOverrides) {
5316
- light = deepMerge(light, lightOverrides);
6015
+ light = deepMerge2(light, lightOverrides);
5317
6016
  }
5318
6017
  if (darkOverrides) {
5319
- dark = deepMerge(dark, darkOverrides);
6018
+ dark = deepMerge2(dark, darkOverrides);
5320
6019
  }
5321
6020
  setLightTheme(light);
5322
6021
  setDarkTheme(dark);
@@ -6671,7 +7370,7 @@ __export(shared_exports, {
6671
7370
  isSameMonth: () => dateFns.isSameMonth,
6672
7371
  isSameWeek: () => dateFns.isSameWeek,
6673
7372
  isSameYear: () => dateFns.isSameYear,
6674
- isTest: () => isTest,
7373
+ isTest: () => isTest2,
6675
7374
  isThisMonth: () => dateFns.isThisMonth,
6676
7375
  isThisWeek: () => dateFns.isThisWeek,
6677
7376
  isThisYear: () => dateFns.isThisYear,
@@ -6750,7 +7449,7 @@ var isProd = () => {
6750
7449
  var isDev = () => {
6751
7450
  return process.env.NODE_ENV === "development";
6752
7451
  };
6753
- var isTest = () => {
7452
+ var isTest2 = () => {
6754
7453
  return process.env.NODE_ENV === "test";
6755
7454
  };
6756
7455
  var validateEnv = (requiredVars) => {