@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.
- package/README.md +864 -261
- package/dist/client/hooks/index.d.mts +1042 -0
- package/dist/client/hooks/index.d.ts +1042 -0
- package/dist/client/hooks/index.js +2276 -0
- package/dist/client/hooks/index.js.map +1 -0
- package/dist/client/hooks/index.mjs +2217 -0
- package/dist/client/hooks/index.mjs.map +1 -0
- package/dist/client/index.d.mts +3 -1
- package/dist/client/index.d.ts +3 -1
- package/dist/client/web/index.d.mts +1461 -0
- package/dist/client/web/index.d.ts +1461 -0
- package/dist/client/web/index.js +2681 -0
- package/dist/client/web/index.js.map +1 -0
- package/dist/client/web/index.mjs +2618 -0
- package/dist/client/web/index.mjs.map +1 -0
- package/dist/data/brand-identity.d.mts +149 -0
- package/dist/data/brand-identity.d.ts +149 -0
- package/dist/data/brand-identity.js +235 -0
- package/dist/data/brand-identity.js.map +1 -0
- package/dist/data/brand-identity.mjs +220 -0
- package/dist/data/brand-identity.mjs.map +1 -0
- package/dist/data/countries.d.mts +61 -0
- package/dist/data/countries.d.ts +61 -0
- package/dist/data/countries.js +987 -0
- package/dist/data/countries.js.map +1 -0
- package/dist/data/countries.mjs +971 -0
- package/dist/data/countries.mjs.map +1 -0
- package/dist/data/currencies.d.mts +19 -0
- package/dist/data/currencies.d.ts +19 -0
- package/dist/data/currencies.js +162 -0
- package/dist/data/currencies.js.map +1 -0
- package/dist/data/currencies.mjs +153 -0
- package/dist/data/currencies.mjs.map +1 -0
- package/dist/data/index.d.mts +7 -0
- package/dist/data/index.d.ts +7 -0
- package/dist/data/index.js +2087 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data/index.mjs +1948 -0
- package/dist/data/index.mjs.map +1 -0
- package/dist/data/phone-codes.d.mts +15 -0
- package/dist/data/phone-codes.d.ts +15 -0
- package/dist/data/phone-codes.js +219 -0
- package/dist/data/phone-codes.js.map +1 -0
- package/dist/data/phone-codes.mjs +211 -0
- package/dist/data/phone-codes.mjs.map +1 -0
- package/dist/data/regex.d.mts +287 -0
- package/dist/data/regex.d.ts +287 -0
- package/dist/data/regex.js +306 -0
- package/dist/data/regex.js.map +1 -0
- package/dist/data/regex.mjs +208 -0
- package/dist/data/regex.mjs.map +1 -0
- package/dist/data/timezones.d.mts +16 -0
- package/dist/data/timezones.d.ts +16 -0
- package/dist/data/timezones.js +98 -0
- package/dist/data/timezones.js.map +1 -0
- package/dist/data/timezones.mjs +89 -0
- package/dist/data/timezones.mjs.map +1 -0
- package/dist/index-01hoqibP.d.ts +119 -0
- package/dist/index-D3yCCjBZ.d.mts +119 -0
- package/dist/index-D9a9oxQy.d.ts +305 -0
- package/dist/index-DKn4raO7.d.ts +222 -0
- package/dist/index-DuxL84IW.d.mts +305 -0
- package/dist/index-NS8dS0p9.d.mts +222 -0
- package/dist/index-Nqm5_lwT.d.ts +188 -0
- package/dist/index-jBi3V6e5.d.mts +188 -0
- package/dist/index.d.mts +20 -579
- package/dist/index.d.ts +20 -579
- package/dist/index.js +717 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +716 -18
- package/dist/index.mjs.map +1 -1
- package/dist/server/configs/index.d.mts +602 -0
- package/dist/server/configs/index.d.ts +602 -0
- package/dist/server/configs/index.js +707 -0
- package/dist/server/configs/index.js.map +1 -0
- package/dist/server/configs/index.mjs +665 -0
- package/dist/server/configs/index.mjs.map +1 -0
- package/dist/server/index.d.mts +3 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +699 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +662 -1
- package/dist/server/index.mjs.map +1 -1
- package/dist/shared/config/index.d.mts +40 -0
- package/dist/shared/config/index.d.ts +40 -0
- package/dist/shared/config/index.js +58 -0
- package/dist/shared/config/index.js.map +1 -0
- package/dist/shared/config/index.mjs +51 -0
- package/dist/shared/config/index.mjs.map +1 -0
- package/dist/shared/constants/index.d.mts +593 -0
- package/dist/shared/constants/index.d.ts +593 -0
- package/dist/shared/constants/index.js +391 -0
- package/dist/shared/constants/index.js.map +1 -0
- package/dist/shared/constants/index.mjs +360 -0
- package/dist/shared/constants/index.mjs.map +1 -0
- package/dist/shared/index.d.mts +5 -1
- package/dist/shared/index.d.ts +5 -1
- package/dist/shared/types/index.d.mts +140 -0
- package/dist/shared/types/index.d.ts +140 -0
- package/dist/shared/types/index.js +4 -0
- package/dist/shared/types/index.js.map +1 -0
- package/dist/shared/types/index.mjs +3 -0
- package/dist/shared/types/index.mjs.map +1 -0
- package/dist/shared/utils/index.d.mts +255 -0
- package/dist/shared/utils/index.d.ts +255 -0
- package/dist/shared/utils/index.js +623 -0
- package/dist/shared/utils/index.js.map +1 -0
- package/dist/shared/utils/index.mjs +324 -0
- package/dist/shared/utils/index.mjs.map +1 -0
- package/dist/shared/validation/index.d.mts +258 -0
- package/dist/shared/validation/index.d.ts +258 -0
- package/dist/shared/validation/index.js +185 -0
- package/dist/shared/validation/index.js.map +1 -0
- package/dist/shared/validation/index.mjs +172 -0
- package/dist/shared/validation/index.mjs.map +1 -0
- package/package.json +127 -62
- package/dist/index-BcxL4_V4.d.ts +0 -2946
- package/dist/index-DEzgM15j.d.ts +0 -67
- package/dist/index-DNFVgQx8.d.ts +0 -1375
- package/dist/index-DbV04Dx8.d.mts +0 -67
- package/dist/index-DfqEP6Oe.d.mts +0 -1375
- 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: () =>
|
|
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
|
|
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] =
|
|
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
|
|
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 =
|
|
5144
|
-
darkTheme =
|
|
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 =
|
|
5851
|
+
lightTheme = deepMerge2(lightTheme, config.light);
|
|
5153
5852
|
}
|
|
5154
5853
|
if (config.dark) {
|
|
5155
|
-
darkTheme =
|
|
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 =
|
|
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 =
|
|
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) =>
|
|
5260
|
-
setDarkTheme((prev) =>
|
|
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) =>
|
|
5306
|
-
setDarkTheme((prev) =>
|
|
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 =
|
|
6015
|
+
light = deepMerge2(light, lightOverrides);
|
|
5317
6016
|
}
|
|
5318
6017
|
if (darkOverrides) {
|
|
5319
|
-
dark =
|
|
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: () =>
|
|
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
|
|
7452
|
+
var isTest2 = () => {
|
|
6754
7453
|
return process.env.NODE_ENV === "test";
|
|
6755
7454
|
};
|
|
6756
7455
|
var validateEnv = (requiredVars) => {
|