@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.mjs CHANGED
@@ -4,6 +4,7 @@ import path, { resolve } from 'path';
4
4
  import mongoose from 'mongoose';
5
5
  import jwt from 'jsonwebtoken';
6
6
  import { existsSync, readFileSync } from 'fs';
7
+ import rateLimit from 'express-rate-limit';
7
8
  import axios from 'axios';
8
9
  import { createContext, useState, useCallback, useMemo, useRef, useEffect, useContext } from 'react';
9
10
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -21,20 +22,50 @@ var __export = (target, all) => {
21
22
  // src/server/index.ts
22
23
  var server_exports = {};
23
24
  __export(server_exports, {
25
+ ConfigBuilder: () => ConfigBuilder,
26
+ DEFAULT_AUTH_CONFIG: () => DEFAULT_AUTH_CONFIG,
27
+ DEFAULT_CORS_CONFIG: () => DEFAULT_CORS_CONFIG,
28
+ DEFAULT_CORS_ORIGINS: () => DEFAULT_CORS_ORIGINS,
29
+ DEFAULT_DATABASE_CONFIG: () => DEFAULT_DATABASE_CONFIG,
30
+ DEFAULT_LOGGING_CONFIG: () => DEFAULT_LOGGING_CONFIG,
31
+ DEFAULT_RATE_LIMIT_CONFIG: () => DEFAULT_RATE_LIMIT_CONFIG,
32
+ DEFAULT_RATE_LIMIT_TIERS: () => DEFAULT_RATE_LIMIT_TIERS,
33
+ DEFAULT_SERVER_CONFIG: () => DEFAULT_SERVER_CONFIG,
34
+ EXYCONN_CORS_CONFIG: () => EXYCONN_CORS_CONFIG,
35
+ PERMISSIVE_CORS_CONFIG: () => PERMISSIVE_CORS_CONFIG,
36
+ RATE_LIMIT_CONFIG: () => RATE_LIMIT_CONFIG,
37
+ RateLimiterBuilder: () => RateLimiterBuilder,
38
+ STRICT_CORS_CONFIG: () => STRICT_CORS_CONFIG,
24
39
  StatusCode: () => StatusCode,
25
40
  StatusMessage: () => StatusMessage,
26
41
  authenticateApiKey: () => authenticateApiKey,
27
42
  authenticateJWT: () => authenticateJWT,
28
43
  badRequestResponse: () => badRequestResponse,
44
+ buildConfig: () => buildConfig,
29
45
  buildFilter: () => buildFilter,
30
46
  buildPagination: () => buildPagination,
31
47
  buildPaginationMeta: () => buildPaginationMeta,
32
48
  checkPackageServer: () => checkPackageServer,
33
49
  conflictResponse: () => conflictResponse,
34
50
  connectDB: () => connectDB,
51
+ corsOptions: () => corsOptions,
52
+ createApiKeyGenerator: () => createApiKeyGenerator,
53
+ createApiRateLimiter: () => createApiRateLimiter,
54
+ createBrandCorsOptions: () => createBrandCorsOptions,
55
+ createConfig: () => createConfig,
56
+ createCorsOptions: () => createCorsOptions,
57
+ createDdosRateLimiter: () => createDdosRateLimiter,
35
58
  createLogger: () => createLogger,
36
59
  createMorganStream: () => createMorganStream,
60
+ createMultiBrandCorsOptions: () => createMultiBrandCorsOptions,
61
+ createPrefixedKeyGenerator: () => createPrefixedKeyGenerator,
62
+ createRateLimiter: () => createRateLimiter,
63
+ createStandardRateLimiter: () => createStandardRateLimiter,
64
+ createStrictRateLimiter: () => createStrictRateLimiter,
65
+ createUserKeyGenerator: () => createUserKeyGenerator,
37
66
  createdResponse: () => createdResponse,
67
+ ddosProtectionLimiter: () => ddosProtectionLimiter,
68
+ defaultKeyGenerator: () => defaultKeyGenerator,
38
69
  disconnectDB: () => disconnectDB,
39
70
  errorResponse: () => errorResponse,
40
71
  extractColumns: () => extractColumns,
@@ -43,6 +74,10 @@ __export(server_exports, {
43
74
  formatPackageCheckResult: () => formatPackageCheckResult,
44
75
  generateNcuCommand: () => generateNcuCommand,
45
76
  getConnectionStatus: () => getConnectionStatus,
77
+ getDatabaseOptions: () => getDatabaseOptions,
78
+ isDevelopment: () => isDevelopment,
79
+ isProduction: () => isProduction,
80
+ isTest: () => isTest,
46
81
  logger: () => logger,
47
82
  noContentResponse: () => noContentResponse,
48
83
  notFoundResponse: () => notFoundResponse,
@@ -52,13 +87,16 @@ __export(server_exports, {
52
87
  pickFields: () => pickFields,
53
88
  printPackageCheckSummary: () => printPackageCheckSummary,
54
89
  rateLimitResponse: () => rateLimitResponse,
90
+ rateLimiter: () => rateLimiter,
55
91
  requireOrganization: () => requireOrganization,
56
92
  sanitizeDocument: () => sanitizeDocument,
57
93
  sanitizeUser: () => sanitizeUser,
58
94
  simpleLogger: () => simpleLogger,
95
+ standardRateLimiter: () => standardRateLimiter,
59
96
  statusCode: () => statusCode,
60
97
  statusMessage: () => statusMessage,
61
98
  stream: () => stream,
99
+ strictRateLimiter: () => strictRateLimiter,
62
100
  successResponse: () => successResponse,
63
101
  successResponseArr: () => successResponseArr,
64
102
  unauthorizedResponse: () => unauthorizedResponse,
@@ -770,6 +808,666 @@ var packageCheckServer = {
770
808
  print: printPackageCheckSummary
771
809
  };
772
810
 
811
+ // src/server/configs/cors.config.ts
812
+ var DEFAULT_CORS_CONFIG = {
813
+ productionOrigins: [],
814
+ developmentOrigins: [
815
+ "http://localhost:3000",
816
+ "http://localhost:4000",
817
+ "http://localhost:5000",
818
+ "http://localhost:5173",
819
+ "http://localhost:8080",
820
+ "http://127.0.0.1:3000",
821
+ "http://127.0.0.1:4000",
822
+ "http://127.0.0.1:5000",
823
+ "http://127.0.0.1:5173",
824
+ "http://127.0.0.1:8080"
825
+ ],
826
+ allowedSubdomains: [],
827
+ originPatterns: [],
828
+ allowNoOrigin: true,
829
+ allowAllInDev: true,
830
+ credentials: true,
831
+ methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"],
832
+ allowedHeaders: [
833
+ "Content-Type",
834
+ "Authorization",
835
+ "X-Requested-With",
836
+ "Accept",
837
+ "Origin",
838
+ "X-API-Key",
839
+ "X-Organization-Id",
840
+ "X-Request-Id"
841
+ ],
842
+ exposedHeaders: [
843
+ "Content-Range",
844
+ "X-Content-Range",
845
+ "X-Total-Count",
846
+ "X-Request-Id"
847
+ ],
848
+ maxAge: 86400
849
+ // 24 hours
850
+ };
851
+ var createCorsOptions = (config = {}) => {
852
+ const finalConfig = { ...DEFAULT_CORS_CONFIG, ...config };
853
+ const {
854
+ productionOrigins,
855
+ developmentOrigins,
856
+ allowedSubdomains,
857
+ originPatterns,
858
+ allowNoOrigin,
859
+ allowAllInDev,
860
+ customValidator,
861
+ credentials,
862
+ methods,
863
+ allowedHeaders,
864
+ exposedHeaders,
865
+ maxAge
866
+ } = finalConfig;
867
+ const allOrigins = /* @__PURE__ */ new Set([...productionOrigins, ...developmentOrigins]);
868
+ const originHandler = (origin, callback) => {
869
+ if (!origin) {
870
+ callback(null, allowNoOrigin);
871
+ return;
872
+ }
873
+ if (allOrigins.has(origin)) {
874
+ callback(null, true);
875
+ return;
876
+ }
877
+ if (allowedSubdomains.some((subdomain) => origin.endsWith(subdomain))) {
878
+ callback(null, true);
879
+ return;
880
+ }
881
+ if (originPatterns.some((pattern) => pattern.test(origin))) {
882
+ callback(null, true);
883
+ return;
884
+ }
885
+ if (customValidator && customValidator(origin)) {
886
+ callback(null, true);
887
+ return;
888
+ }
889
+ if (process.env.NODE_ENV !== "production" && allowAllInDev) {
890
+ callback(null, true);
891
+ return;
892
+ }
893
+ if (process.env.NODE_ENV === "production") {
894
+ callback(new Error(`Origin ${origin} not allowed by CORS`));
895
+ return;
896
+ }
897
+ callback(null, true);
898
+ };
899
+ return {
900
+ origin: originHandler,
901
+ credentials,
902
+ methods,
903
+ allowedHeaders,
904
+ exposedHeaders,
905
+ maxAge
906
+ };
907
+ };
908
+ var createBrandCorsOptions = (brandDomain, additionalConfig = {}) => {
909
+ const productionOrigins = [
910
+ `https://${brandDomain}`,
911
+ `https://www.${brandDomain}`
912
+ ];
913
+ const allowedSubdomains = [`.${brandDomain}`];
914
+ return createCorsOptions({
915
+ productionOrigins,
916
+ allowedSubdomains,
917
+ ...additionalConfig
918
+ });
919
+ };
920
+ var createMultiBrandCorsOptions = (domains, additionalConfig = {}) => {
921
+ const productionOrigins = domains.flatMap((domain) => [
922
+ `https://${domain}`,
923
+ `https://www.${domain}`
924
+ ]);
925
+ const allowedSubdomains = domains.map((domain) => `.${domain}`);
926
+ return createCorsOptions({
927
+ productionOrigins,
928
+ allowedSubdomains,
929
+ ...additionalConfig
930
+ });
931
+ };
932
+ var EXYCONN_CORS_CONFIG = {
933
+ productionOrigins: [
934
+ "https://exyconn.com",
935
+ "https://www.exyconn.com",
936
+ "https://botify.life",
937
+ "https://www.botify.life",
938
+ "https://partywings.fun",
939
+ "https://www.partywings.fun",
940
+ "https://sibera.work",
941
+ "https://www.sibera.work",
942
+ "https://spentiva.com",
943
+ "https://www.spentiva.com"
944
+ ],
945
+ allowedSubdomains: [
946
+ ".exyconn.com",
947
+ ".botify.life",
948
+ ".partywings.fun",
949
+ ".sibera.work",
950
+ ".spentiva.com"
951
+ ],
952
+ developmentOrigins: [
953
+ "http://localhost:3000",
954
+ "http://localhost:4000",
955
+ "http://localhost:4001",
956
+ "http://localhost:4002",
957
+ "http://localhost:4003",
958
+ "http://localhost:4004",
959
+ "http://localhost:4005",
960
+ "http://localhost:5173",
961
+ "http://127.0.0.1:3000",
962
+ "http://127.0.0.1:4000",
963
+ "http://127.0.0.1:5173"
964
+ ]
965
+ };
966
+ var STRICT_CORS_CONFIG = {
967
+ allowNoOrigin: false,
968
+ allowAllInDev: false,
969
+ methods: ["GET", "POST", "PUT", "DELETE"]
970
+ };
971
+ var PERMISSIVE_CORS_CONFIG = {
972
+ allowNoOrigin: true,
973
+ allowAllInDev: true,
974
+ originPatterns: [/localhost/, /127\.0\.0\.1/]
975
+ };
976
+ var corsOptions = createCorsOptions(EXYCONN_CORS_CONFIG);
977
+ var DEFAULT_RATE_LIMIT_TIERS = {
978
+ STANDARD: {
979
+ windowMs: 15 * 60 * 1e3,
980
+ // 15 minutes
981
+ maxRequests: 100,
982
+ message: "Too many requests, please try again later.",
983
+ skipSuccessfulRequests: false,
984
+ skipFailedRequests: false
985
+ },
986
+ STRICT: {
987
+ windowMs: 15 * 60 * 1e3,
988
+ // 15 minutes
989
+ maxRequests: 20,
990
+ message: "Too many requests, please try again later.",
991
+ skipSuccessfulRequests: false,
992
+ skipFailedRequests: false
993
+ },
994
+ DDOS: {
995
+ windowMs: 60 * 1e3,
996
+ // 1 minute
997
+ maxRequests: 60,
998
+ message: "Rate limit exceeded. Please slow down.",
999
+ skipSuccessfulRequests: false,
1000
+ skipFailedRequests: false
1001
+ },
1002
+ // Additional presets
1003
+ VERY_STRICT: {
1004
+ windowMs: 60 * 60 * 1e3,
1005
+ // 1 hour
1006
+ maxRequests: 5,
1007
+ message: "Too many attempts. Please try again in an hour.",
1008
+ skipSuccessfulRequests: false,
1009
+ skipFailedRequests: false
1010
+ },
1011
+ RELAXED: {
1012
+ windowMs: 15 * 60 * 1e3,
1013
+ // 15 minutes
1014
+ maxRequests: 500,
1015
+ message: "Rate limit exceeded.",
1016
+ skipSuccessfulRequests: false,
1017
+ skipFailedRequests: false
1018
+ },
1019
+ API: {
1020
+ windowMs: 60 * 1e3,
1021
+ // 1 minute
1022
+ maxRequests: 30,
1023
+ message: "API rate limit exceeded.",
1024
+ skipSuccessfulRequests: false,
1025
+ skipFailedRequests: false
1026
+ }
1027
+ };
1028
+ var defaultKeyGenerator = (req) => {
1029
+ const forwarded = req.headers["x-forwarded-for"];
1030
+ const ip = forwarded ? Array.isArray(forwarded) ? forwarded[0] : forwarded.split(",")[0].trim() : req.ip || req.socket.remoteAddress || "unknown";
1031
+ return ip;
1032
+ };
1033
+ var createPrefixedKeyGenerator = (prefix) => (req) => {
1034
+ return `${prefix}:${defaultKeyGenerator(req)}`;
1035
+ };
1036
+ var createUserKeyGenerator = (getUserId) => (req) => {
1037
+ const userId = getUserId(req);
1038
+ return userId || defaultKeyGenerator(req);
1039
+ };
1040
+ var createApiKeyGenerator = (headerName = "x-api-key") => (req) => {
1041
+ const apiKey = req.headers[headerName.toLowerCase()];
1042
+ return apiKey || defaultKeyGenerator(req);
1043
+ };
1044
+ var createRateLimitResponse = (message, retryAfter) => ({
1045
+ status: "error",
1046
+ statusCode: 429,
1047
+ message,
1048
+ ...retryAfter
1049
+ });
1050
+ var createRateLimiter = (tierConfig, options = {}) => {
1051
+ const {
1052
+ standardHeaders = true,
1053
+ legacyHeaders = false,
1054
+ keyGenerator = defaultKeyGenerator,
1055
+ skip,
1056
+ handler
1057
+ } = options;
1058
+ return rateLimit({
1059
+ windowMs: tierConfig.windowMs,
1060
+ max: tierConfig.maxRequests,
1061
+ message: createRateLimitResponse(tierConfig.message),
1062
+ standardHeaders,
1063
+ legacyHeaders,
1064
+ keyGenerator,
1065
+ skip,
1066
+ handler,
1067
+ skipSuccessfulRequests: tierConfig.skipSuccessfulRequests,
1068
+ skipFailedRequests: tierConfig.skipFailedRequests
1069
+ });
1070
+ };
1071
+ var createStandardRateLimiter = (config = {}, options = {}) => {
1072
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.STANDARD, ...config };
1073
+ return createRateLimiter(tierConfig, options);
1074
+ };
1075
+ var createStrictRateLimiter = (config = {}, options = {}) => {
1076
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.STRICT, ...config };
1077
+ return createRateLimiter(tierConfig, options);
1078
+ };
1079
+ var createDdosRateLimiter = (config = {}, options = {}) => {
1080
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.DDOS, ...config };
1081
+ return createRateLimiter(tierConfig, options);
1082
+ };
1083
+ var createApiRateLimiter = (config = {}, options = {}) => {
1084
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.API, ...config };
1085
+ return createRateLimiter(tierConfig, {
1086
+ keyGenerator: createApiKeyGenerator(),
1087
+ ...options
1088
+ });
1089
+ };
1090
+ var RateLimiterBuilder = class {
1091
+ constructor(preset = "STANDARD") {
1092
+ const presetConfig = DEFAULT_RATE_LIMIT_TIERS[preset];
1093
+ this.config = {
1094
+ windowMs: presetConfig.windowMs,
1095
+ maxRequests: presetConfig.maxRequests,
1096
+ message: presetConfig.message,
1097
+ skipSuccessfulRequests: presetConfig.skipSuccessfulRequests ?? false,
1098
+ skipFailedRequests: presetConfig.skipFailedRequests ?? false
1099
+ };
1100
+ this.options = {};
1101
+ }
1102
+ /**
1103
+ * Set window duration
1104
+ */
1105
+ windowMs(ms) {
1106
+ this.config.windowMs = ms;
1107
+ return this;
1108
+ }
1109
+ /**
1110
+ * Set window duration in minutes
1111
+ */
1112
+ windowMinutes(minutes) {
1113
+ this.config.windowMs = minutes * 60 * 1e3;
1114
+ return this;
1115
+ }
1116
+ /**
1117
+ * Set window duration in hours
1118
+ */
1119
+ windowHours(hours) {
1120
+ this.config.windowMs = hours * 60 * 60 * 1e3;
1121
+ return this;
1122
+ }
1123
+ /**
1124
+ * Set maximum requests
1125
+ */
1126
+ max(requests) {
1127
+ this.config.maxRequests = requests;
1128
+ return this;
1129
+ }
1130
+ /**
1131
+ * Set error message
1132
+ */
1133
+ message(msg) {
1134
+ this.config.message = msg;
1135
+ return this;
1136
+ }
1137
+ /**
1138
+ * Skip successful requests
1139
+ */
1140
+ skipSuccessful(skip = true) {
1141
+ this.config.skipSuccessfulRequests = skip;
1142
+ return this;
1143
+ }
1144
+ /**
1145
+ * Skip failed requests
1146
+ */
1147
+ skipFailed(skip = true) {
1148
+ this.config.skipFailedRequests = skip;
1149
+ return this;
1150
+ }
1151
+ /**
1152
+ * Set key generator
1153
+ */
1154
+ keyBy(generator) {
1155
+ this.options.keyGenerator = generator;
1156
+ return this;
1157
+ }
1158
+ /**
1159
+ * Key by IP (default)
1160
+ */
1161
+ keyByIp() {
1162
+ this.options.keyGenerator = defaultKeyGenerator;
1163
+ return this;
1164
+ }
1165
+ /**
1166
+ * Key by API key
1167
+ */
1168
+ keyByApiKey(headerName) {
1169
+ this.options.keyGenerator = createApiKeyGenerator(headerName);
1170
+ return this;
1171
+ }
1172
+ /**
1173
+ * Skip certain requests
1174
+ */
1175
+ skipWhen(predicate) {
1176
+ this.options.skip = predicate;
1177
+ return this;
1178
+ }
1179
+ /**
1180
+ * Build the rate limiter
1181
+ */
1182
+ build() {
1183
+ return createRateLimiter(this.config, this.options);
1184
+ }
1185
+ };
1186
+ var rateLimiter = (preset) => {
1187
+ return new RateLimiterBuilder(preset);
1188
+ };
1189
+ var RATE_LIMIT_CONFIG = {
1190
+ STANDARD: DEFAULT_RATE_LIMIT_TIERS.STANDARD,
1191
+ STRICT: DEFAULT_RATE_LIMIT_TIERS.STRICT,
1192
+ DDOS: DEFAULT_RATE_LIMIT_TIERS.DDOS
1193
+ };
1194
+ var standardRateLimiter = createStandardRateLimiter();
1195
+ var strictRateLimiter = createStrictRateLimiter();
1196
+ var ddosProtectionLimiter = createDdosRateLimiter();
1197
+
1198
+ // src/server/configs/server.config.ts
1199
+ var DEFAULT_SERVER_CONFIG = {
1200
+ name: "app-server",
1201
+ version: "1.0.0",
1202
+ environment: process.env.NODE_ENV || "development",
1203
+ port: parseInt(process.env.PORT || "3000", 10),
1204
+ host: process.env.HOST || "0.0.0.0",
1205
+ basePath: "/api",
1206
+ debug: process.env.DEBUG === "true",
1207
+ trustProxy: true
1208
+ };
1209
+ var DEFAULT_DATABASE_CONFIG = {
1210
+ uri: process.env.DATABASE_URL || process.env.MONGODB_URI || "",
1211
+ name: process.env.DATABASE_NAME || "app_db",
1212
+ maxPoolSize: process.env.NODE_ENV === "production" ? 50 : 10,
1213
+ minPoolSize: process.env.NODE_ENV === "production" ? 10 : 5,
1214
+ socketTimeoutMS: 45e3,
1215
+ serverSelectionTimeoutMS: 1e4,
1216
+ maxIdleTimeMS: 1e4,
1217
+ retryWrites: true,
1218
+ retryReads: true,
1219
+ writeConcern: "majority"
1220
+ };
1221
+ var DEFAULT_AUTH_CONFIG = {
1222
+ jwtSecret: process.env.JWT_SECRET || "",
1223
+ jwtExpiresIn: process.env.JWT_EXPIRES_IN || "7d",
1224
+ refreshTokenExpiresIn: process.env.REFRESH_TOKEN_EXPIRES_IN || "30d",
1225
+ enableRefreshTokens: true,
1226
+ apiKeyHeader: "x-api-key",
1227
+ orgHeader: "x-organization-id"
1228
+ };
1229
+ var DEFAULT_LOGGING_CONFIG = {
1230
+ level: process.env.LOG_LEVEL || "info",
1231
+ logsDir: process.env.LOGS_DIR || "logs",
1232
+ maxSize: "20m",
1233
+ maxFiles: "14d",
1234
+ errorMaxFiles: "30d",
1235
+ console: true,
1236
+ file: process.env.NODE_ENV === "production",
1237
+ json: process.env.NODE_ENV === "production"
1238
+ };
1239
+ var DEFAULT_CORS_ORIGINS = {
1240
+ production: [],
1241
+ development: [
1242
+ "http://localhost:3000",
1243
+ "http://localhost:4000",
1244
+ "http://localhost:5173",
1245
+ "http://127.0.0.1:3000",
1246
+ "http://127.0.0.1:4000",
1247
+ "http://127.0.0.1:5173"
1248
+ ],
1249
+ patterns: []
1250
+ };
1251
+ var DEFAULT_RATE_LIMIT_CONFIG = {
1252
+ enabled: true,
1253
+ standard: {
1254
+ windowMs: 15 * 60 * 1e3,
1255
+ // 15 minutes
1256
+ maxRequests: 100,
1257
+ message: "Too many requests, please try again later."
1258
+ },
1259
+ strict: {
1260
+ windowMs: 15 * 60 * 1e3,
1261
+ // 15 minutes
1262
+ maxRequests: 20,
1263
+ message: "Too many requests, please try again later."
1264
+ },
1265
+ ddos: {
1266
+ windowMs: 60 * 1e3,
1267
+ // 1 minute
1268
+ maxRequests: 60,
1269
+ message: "Rate limit exceeded. Please slow down.",
1270
+ skipSuccessfulRequests: false
1271
+ }
1272
+ };
1273
+ function deepMerge(target, source) {
1274
+ const result = { ...target };
1275
+ for (const key in source) {
1276
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1277
+ const sourceValue = source[key];
1278
+ const targetValue = target[key];
1279
+ if (sourceValue !== void 0 && typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) {
1280
+ result[key] = deepMerge(
1281
+ targetValue,
1282
+ sourceValue
1283
+ );
1284
+ } else if (sourceValue !== void 0) {
1285
+ result[key] = sourceValue;
1286
+ }
1287
+ }
1288
+ }
1289
+ return result;
1290
+ }
1291
+ var ConfigBuilder = class {
1292
+ constructor() {
1293
+ this.config = {
1294
+ server: { ...DEFAULT_SERVER_CONFIG },
1295
+ database: { ...DEFAULT_DATABASE_CONFIG },
1296
+ auth: { ...DEFAULT_AUTH_CONFIG },
1297
+ logging: { ...DEFAULT_LOGGING_CONFIG },
1298
+ cors: { ...DEFAULT_CORS_ORIGINS },
1299
+ rateLimit: { ...DEFAULT_RATE_LIMIT_CONFIG }
1300
+ };
1301
+ }
1302
+ /**
1303
+ * Set server configuration
1304
+ */
1305
+ setServer(config) {
1306
+ this.config.server = deepMerge(this.config.server, config);
1307
+ return this;
1308
+ }
1309
+ /**
1310
+ * Set database configuration
1311
+ */
1312
+ setDatabase(config) {
1313
+ this.config.database = deepMerge(this.config.database, config);
1314
+ return this;
1315
+ }
1316
+ /**
1317
+ * Set auth configuration
1318
+ */
1319
+ setAuth(config) {
1320
+ this.config.auth = deepMerge(this.config.auth, config);
1321
+ return this;
1322
+ }
1323
+ /**
1324
+ * Set logging configuration
1325
+ */
1326
+ setLogging(config) {
1327
+ this.config.logging = deepMerge(this.config.logging, config);
1328
+ return this;
1329
+ }
1330
+ /**
1331
+ * Set CORS origins
1332
+ */
1333
+ setCorsOrigins(config) {
1334
+ this.config.cors = deepMerge(this.config.cors, config);
1335
+ return this;
1336
+ }
1337
+ /**
1338
+ * Add CORS production origin
1339
+ */
1340
+ addProductionOrigin(origin) {
1341
+ if (!this.config.cors.production.includes(origin)) {
1342
+ this.config.cors.production.push(origin);
1343
+ }
1344
+ return this;
1345
+ }
1346
+ /**
1347
+ * Add CORS development origin
1348
+ */
1349
+ addDevelopmentOrigin(origin) {
1350
+ if (!this.config.cors.development.includes(origin)) {
1351
+ this.config.cors.development.push(origin);
1352
+ }
1353
+ return this;
1354
+ }
1355
+ /**
1356
+ * Add CORS pattern
1357
+ */
1358
+ addCorsPattern(pattern) {
1359
+ if (!this.config.cors.patterns.includes(pattern)) {
1360
+ this.config.cors.patterns.push(pattern);
1361
+ }
1362
+ return this;
1363
+ }
1364
+ /**
1365
+ * Set rate limit configuration
1366
+ */
1367
+ setRateLimit(config) {
1368
+ this.config.rateLimit = deepMerge(this.config.rateLimit, config);
1369
+ return this;
1370
+ }
1371
+ /**
1372
+ * Add custom rate limit tier
1373
+ */
1374
+ addRateLimitTier(name, tier) {
1375
+ if (!this.config.rateLimit.custom) {
1376
+ this.config.rateLimit.custom = {};
1377
+ }
1378
+ this.config.rateLimit.custom[name] = tier;
1379
+ return this;
1380
+ }
1381
+ /**
1382
+ * Set custom configuration
1383
+ */
1384
+ setCustom(key, value) {
1385
+ if (!this.config.custom) {
1386
+ this.config.custom = {};
1387
+ }
1388
+ this.config.custom[key] = value;
1389
+ return this;
1390
+ }
1391
+ /**
1392
+ * Load configuration from environment variables
1393
+ */
1394
+ loadFromEnv() {
1395
+ if (process.env.SERVER_NAME) this.config.server.name = process.env.SERVER_NAME;
1396
+ if (process.env.SERVER_VERSION) this.config.server.version = process.env.SERVER_VERSION;
1397
+ if (process.env.PORT) this.config.server.port = parseInt(process.env.PORT, 10);
1398
+ if (process.env.HOST) this.config.server.host = process.env.HOST;
1399
+ if (process.env.BASE_PATH) this.config.server.basePath = process.env.BASE_PATH;
1400
+ if (process.env.DATABASE_URL) this.config.database.uri = process.env.DATABASE_URL;
1401
+ if (process.env.MONGODB_URI) this.config.database.uri = process.env.MONGODB_URI;
1402
+ if (process.env.DATABASE_NAME) this.config.database.name = process.env.DATABASE_NAME;
1403
+ if (process.env.JWT_SECRET) this.config.auth.jwtSecret = process.env.JWT_SECRET;
1404
+ if (process.env.JWT_EXPIRES_IN) this.config.auth.jwtExpiresIn = process.env.JWT_EXPIRES_IN;
1405
+ if (process.env.LOG_LEVEL) this.config.logging.level = process.env.LOG_LEVEL;
1406
+ if (process.env.LOGS_DIR) this.config.logging.logsDir = process.env.LOGS_DIR;
1407
+ if (process.env.CORS_ORIGINS) {
1408
+ const origins = process.env.CORS_ORIGINS.split(",").map((o) => o.trim());
1409
+ this.config.cors.production.push(...origins);
1410
+ }
1411
+ return this;
1412
+ }
1413
+ /**
1414
+ * Validate configuration
1415
+ */
1416
+ validate() {
1417
+ const errors = [];
1418
+ if (!this.config.server.name) errors.push("Server name is required");
1419
+ if (this.config.server.port < 1 || this.config.server.port > 65535) {
1420
+ errors.push("Server port must be between 1 and 65535");
1421
+ }
1422
+ if (this.config.server.environment === "production") {
1423
+ if (!this.config.auth.jwtSecret || this.config.auth.jwtSecret.length < 32) {
1424
+ errors.push("JWT secret must be at least 32 characters in production");
1425
+ }
1426
+ }
1427
+ return { valid: errors.length === 0, errors };
1428
+ }
1429
+ /**
1430
+ * Build the final configuration
1431
+ */
1432
+ build() {
1433
+ return { ...this.config };
1434
+ }
1435
+ };
1436
+ var createConfig = () => {
1437
+ return new ConfigBuilder();
1438
+ };
1439
+ var buildConfig = (partial = {}) => {
1440
+ const builder = createConfig().loadFromEnv();
1441
+ if (partial.server) builder.setServer(partial.server);
1442
+ if (partial.database) builder.setDatabase(partial.database);
1443
+ if (partial.auth) builder.setAuth(partial.auth);
1444
+ if (partial.logging) builder.setLogging(partial.logging);
1445
+ if (partial.cors) builder.setCorsOrigins(partial.cors);
1446
+ if (partial.rateLimit) builder.setRateLimit(partial.rateLimit);
1447
+ return builder.build();
1448
+ };
1449
+ var isProduction = (config) => {
1450
+ return (config?.environment || process.env.NODE_ENV) === "production";
1451
+ };
1452
+ var isDevelopment = (config) => {
1453
+ return (config?.environment || process.env.NODE_ENV) === "development";
1454
+ };
1455
+ var isTest = (config) => {
1456
+ return (config?.environment || process.env.NODE_ENV) === "test";
1457
+ };
1458
+ var getDatabaseOptions = (config) => {
1459
+ return {
1460
+ maxPoolSize: config.maxPoolSize,
1461
+ minPoolSize: config.minPoolSize,
1462
+ socketTimeoutMS: config.socketTimeoutMS,
1463
+ serverSelectionTimeoutMS: config.serverSelectionTimeoutMS,
1464
+ maxIdleTimeMS: config.maxIdleTimeMS,
1465
+ retryWrites: config.retryWrites,
1466
+ retryReads: config.retryReads,
1467
+ w: config.writeConcern
1468
+ };
1469
+ };
1470
+
773
1471
  // src/client/index.ts
774
1472
  var client_exports = {};
775
1473
  __export(client_exports, {
@@ -806,7 +1504,7 @@ __export(client_exports, {
806
1504
  createTheme: () => createTheme,
807
1505
  createThemeFromBrand: () => createThemeFromBrand,
808
1506
  cssVar: () => cssVar,
809
- deepMerge: () => deepMerge,
1507
+ deepMerge: () => deepMerge2,
810
1508
  defaultDarkTheme: () => defaultDarkTheme,
811
1509
  defaultLightTheme: () => defaultLightTheme,
812
1510
  dummyBannerData: () => dummyBannerData,
@@ -4943,14 +5641,14 @@ var defaultDarkTheme = {
4943
5641
  };
4944
5642
 
4945
5643
  // src/client/web/theme/theme-utils.ts
4946
- function deepMerge(target, source) {
5644
+ function deepMerge2(target, source) {
4947
5645
  const output = { ...target };
4948
5646
  for (const key in source) {
4949
5647
  if (Object.prototype.hasOwnProperty.call(source, key)) {
4950
5648
  const sourceValue = source[key];
4951
5649
  const targetValue = target[key];
4952
5650
  if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue)) {
4953
- output[key] = deepMerge(
5651
+ output[key] = deepMerge2(
4954
5652
  targetValue,
4955
5653
  sourceValue
4956
5654
  );
@@ -5016,7 +5714,7 @@ function createThemeFromBrand(brand, baseTheme = defaultLightTheme) {
5016
5714
  }
5017
5715
  }
5018
5716
  };
5019
- return deepMerge(baseTheme, brandOverrides);
5717
+ return deepMerge2(baseTheme, brandOverrides);
5020
5718
  }
5021
5719
  function adjustColor(hex, percent) {
5022
5720
  hex = hex.replace(/^#/, "");
@@ -5110,8 +5808,8 @@ async function createTheme(config = {}) {
5110
5808
  if (config.themeUrl) {
5111
5809
  const urlTheme = await loadThemeFromUrl(config.themeUrl);
5112
5810
  if (urlTheme) {
5113
- lightTheme = deepMerge(lightTheme, urlTheme);
5114
- darkTheme = deepMerge(darkTheme, urlTheme);
5811
+ lightTheme = deepMerge2(lightTheme, urlTheme);
5812
+ darkTheme = deepMerge2(darkTheme, urlTheme);
5115
5813
  }
5116
5814
  }
5117
5815
  if (config.brandIdentity) {
@@ -5119,10 +5817,10 @@ async function createTheme(config = {}) {
5119
5817
  darkTheme = createThemeFromBrand(config.brandIdentity, darkTheme);
5120
5818
  }
5121
5819
  if (config.light) {
5122
- lightTheme = deepMerge(lightTheme, config.light);
5820
+ lightTheme = deepMerge2(lightTheme, config.light);
5123
5821
  }
5124
5822
  if (config.dark) {
5125
- darkTheme = deepMerge(darkTheme, config.dark);
5823
+ darkTheme = deepMerge2(darkTheme, config.dark);
5126
5824
  }
5127
5825
  return { light: lightTheme, dark: darkTheme };
5128
5826
  }
@@ -5196,7 +5894,7 @@ function ThemeProvider({
5196
5894
  theme2 = createThemeFromBrand(brandIdentity, theme2);
5197
5895
  }
5198
5896
  if (lightOverrides) {
5199
- theme2 = deepMerge(theme2, lightOverrides);
5897
+ theme2 = deepMerge2(theme2, lightOverrides);
5200
5898
  }
5201
5899
  return theme2;
5202
5900
  });
@@ -5207,7 +5905,7 @@ function ThemeProvider({
5207
5905
  theme2 = createThemeFromBrand(brandIdentity, theme2);
5208
5906
  }
5209
5907
  if (darkOverrides) {
5210
- theme2 = deepMerge(theme2, darkOverrides);
5908
+ theme2 = deepMerge2(theme2, darkOverrides);
5211
5909
  }
5212
5910
  return theme2;
5213
5911
  });
@@ -5226,8 +5924,8 @@ function ThemeProvider({
5226
5924
  setError(null);
5227
5925
  loadThemeFromUrl(themeUrl).then((urlTheme) => {
5228
5926
  if (urlTheme) {
5229
- setLightTheme((prev) => deepMerge(prev, urlTheme));
5230
- setDarkTheme((prev) => deepMerge(prev, urlTheme));
5927
+ setLightTheme((prev) => deepMerge2(prev, urlTheme));
5928
+ setDarkTheme((prev) => deepMerge2(prev, urlTheme));
5231
5929
  }
5232
5930
  }).catch((err) => {
5233
5931
  setError(err instanceof Error ? err.message : "Failed to load theme");
@@ -5272,8 +5970,8 @@ function ThemeProvider({
5272
5970
  });
5273
5971
  }, []);
5274
5972
  const updateTheme = useCallback((updates) => {
5275
- setLightTheme((prev) => deepMerge(prev, updates));
5276
- setDarkTheme((prev) => deepMerge(prev, updates));
5973
+ setLightTheme((prev) => deepMerge2(prev, updates));
5974
+ setDarkTheme((prev) => deepMerge2(prev, updates));
5277
5975
  }, []);
5278
5976
  const resetTheme = useCallback(() => {
5279
5977
  let light = defaultLightTheme;
@@ -5283,10 +5981,10 @@ function ThemeProvider({
5283
5981
  dark = createThemeFromBrand(brandIdentity, dark);
5284
5982
  }
5285
5983
  if (lightOverrides) {
5286
- light = deepMerge(light, lightOverrides);
5984
+ light = deepMerge2(light, lightOverrides);
5287
5985
  }
5288
5986
  if (darkOverrides) {
5289
- dark = deepMerge(dark, darkOverrides);
5987
+ dark = deepMerge2(dark, darkOverrides);
5290
5988
  }
5291
5989
  setLightTheme(light);
5292
5990
  setDarkTheme(dark);
@@ -6641,7 +7339,7 @@ __export(shared_exports, {
6641
7339
  isSameMonth: () => isSameMonth,
6642
7340
  isSameWeek: () => isSameWeek,
6643
7341
  isSameYear: () => isSameYear,
6644
- isTest: () => isTest,
7342
+ isTest: () => isTest2,
6645
7343
  isThisMonth: () => isThisMonth,
6646
7344
  isThisWeek: () => isThisWeek,
6647
7345
  isThisYear: () => isThisYear,
@@ -6720,7 +7418,7 @@ var isProd = () => {
6720
7418
  var isDev = () => {
6721
7419
  return process.env.NODE_ENV === "development";
6722
7420
  };
6723
- var isTest = () => {
7421
+ var isTest2 = () => {
6724
7422
  return process.env.NODE_ENV === "test";
6725
7423
  };
6726
7424
  var validateEnv = (requiredVars) => {