@xeno-js/core 0.1.4 → 0.1.6
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/dist/index.cjs +214 -122
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -6
- package/dist/index.d.ts +46 -6
- package/dist/index.js +203 -104
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1508,15 +1508,15 @@ var init_logger_utils = __esm({
|
|
|
1508
1508
|
*/
|
|
1509
1509
|
async addLogger(container, opts) {
|
|
1510
1510
|
const loggerDependencies = [];
|
|
1511
|
-
const { Guards:
|
|
1512
|
-
if (!
|
|
1511
|
+
const { Guards: Guards47, LOG_LEVEL: LOG_LEVEL7, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
|
|
1512
|
+
if (!Guards47.isDefined(opts) || opts.console) {
|
|
1513
1513
|
const { ConsoleLogger: ConsoleLogger2 } = await Promise.resolve().then(() => (init_console_logger(), console_logger_exports));
|
|
1514
1514
|
container.addSingleton(TOKENS4.CONSOLE_LOGGER, () => new ConsoleLogger2(opts?.level));
|
|
1515
1515
|
loggerDependencies.push(TOKENS4.CONSOLE_LOGGER);
|
|
1516
1516
|
}
|
|
1517
1517
|
const customLoggerFactories = [];
|
|
1518
|
-
if (
|
|
1519
|
-
if (
|
|
1518
|
+
if (Guards47.isDefined(opts)) {
|
|
1519
|
+
if (Guards47.isDefined(opts.sentry.config)) {
|
|
1520
1520
|
const { SentryLoggerFactory: SentryLoggerFactory2 } = await Promise.resolve().then(() => (init_sentry_logger_factory(), sentry_logger_factory_exports));
|
|
1521
1521
|
container.addSingleton(TOKENS4.SENTRY_LOGGER, () => {
|
|
1522
1522
|
const factory = new SentryLoggerFactory2();
|
|
@@ -1524,7 +1524,7 @@ var init_logger_utils = __esm({
|
|
|
1524
1524
|
});
|
|
1525
1525
|
loggerDependencies.push(TOKENS4.SENTRY_LOGGER);
|
|
1526
1526
|
}
|
|
1527
|
-
if (
|
|
1527
|
+
if (Guards47.isDefined(opts.pino.config)) {
|
|
1528
1528
|
const { PinoLoggerFactory: PinoLoggerFactory2 } = await Promise.resolve().then(() => (init_pino_logger_factory(), pino_logger_factory_exports));
|
|
1529
1529
|
container.addSingleton(TOKENS4.PINO_LOGGER, () => {
|
|
1530
1530
|
const factory = new PinoLoggerFactory2();
|
|
@@ -1532,10 +1532,10 @@ var init_logger_utils = __esm({
|
|
|
1532
1532
|
});
|
|
1533
1533
|
loggerDependencies.push(TOKENS4.PINO_LOGGER);
|
|
1534
1534
|
}
|
|
1535
|
-
if (!
|
|
1535
|
+
if (!Guards47.isNullOrEmpty(opts.customLoggers)) {
|
|
1536
1536
|
const customLoggers = opts.customLoggers;
|
|
1537
1537
|
customLoggers.forEach((f) => {
|
|
1538
|
-
if (
|
|
1538
|
+
if (Guards47.isDefined(f)) {
|
|
1539
1539
|
customLoggerFactories.push(f);
|
|
1540
1540
|
}
|
|
1541
1541
|
});
|
|
@@ -1708,8 +1708,8 @@ var init_cache_utils = __esm({
|
|
|
1708
1708
|
* @link https://github.com/xeno-js/xeno-js
|
|
1709
1709
|
*/
|
|
1710
1710
|
async addCache(container, opts) {
|
|
1711
|
-
const { Guards:
|
|
1712
|
-
if (!opts.inMemory && !
|
|
1711
|
+
const { Guards: Guards47, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
|
|
1712
|
+
if (!opts.inMemory && !Guards47.isDefined(opts.redis)) {
|
|
1713
1713
|
throw new Error(
|
|
1714
1714
|
"No cache strategies are configured. Please provide at least one cache strategy."
|
|
1715
1715
|
);
|
|
@@ -1719,12 +1719,12 @@ var init_cache_utils = __esm({
|
|
|
1719
1719
|
TOKENS4.CACHE_KEY_BUILDER,
|
|
1720
1720
|
(c) => new CacheKeyBuilder(c.resolve(TOKENS4.IDENTITY_ACCESSOR))
|
|
1721
1721
|
);
|
|
1722
|
-
if (opts.inMemory || !
|
|
1722
|
+
if (opts.inMemory || !Guards47.isDefined(opts.redis)) {
|
|
1723
1723
|
const { InMemoryCacheExtended: InMemoryCacheExtended2 } = await Promise.resolve().then(() => (init_inmemory_cache(), inmemory_cache_exports));
|
|
1724
1724
|
container.addSingleton(TOKENS4.CACHE, () => new InMemoryCacheExtended2());
|
|
1725
1725
|
return;
|
|
1726
1726
|
}
|
|
1727
|
-
if (
|
|
1727
|
+
if (Guards47.isDefined(opts.redis)) {
|
|
1728
1728
|
const { RedisCacheFactory: RedisCacheFactory2 } = await Promise.resolve().then(() => (init_redis_cache_factory(), redis_cache_factory_exports));
|
|
1729
1729
|
container.addSingleton(TOKENS4.CACHE, () => {
|
|
1730
1730
|
const config = opts.redis;
|
|
@@ -1763,6 +1763,17 @@ var init_allow_method_service = __esm({
|
|
|
1763
1763
|
}
|
|
1764
1764
|
return false;
|
|
1765
1765
|
}
|
|
1766
|
+
getMethods(path) {
|
|
1767
|
+
const cleanPath = this.normalizePath(path.split("?")[0].split("#")[0]);
|
|
1768
|
+
const methods = this.findMethods(cleanPath);
|
|
1769
|
+
return Guards22.isDefined(methods) ? methods.join(", ").toUpperCase() : "";
|
|
1770
|
+
}
|
|
1771
|
+
findMethods(cleanPath) {
|
|
1772
|
+
const staticMethods = this._staticRoutes.get(cleanPath);
|
|
1773
|
+
if (Guards22.isDefined(staticMethods)) return staticMethods;
|
|
1774
|
+
for (const route of this._dynamicRoutes) if (route.pattern.test(cleanPath)) return route.methods;
|
|
1775
|
+
return void 0;
|
|
1776
|
+
}
|
|
1766
1777
|
isDynamicPath(path) {
|
|
1767
1778
|
return path.includes(":") || path.includes("{") && path.includes("}");
|
|
1768
1779
|
}
|
|
@@ -2789,8 +2800,8 @@ var init_auth_utils = __esm({
|
|
|
2789
2800
|
const { TOKENS: TOKENS4 } = await import("@xeno-js/shared");
|
|
2790
2801
|
const pipelines = [];
|
|
2791
2802
|
const strategies = [];
|
|
2792
|
-
const { Guards:
|
|
2793
|
-
if (
|
|
2803
|
+
const { Guards: Guards47 } = await import("@xeno-js/shared");
|
|
2804
|
+
if (Guards47.isDefined(opts.policies)) {
|
|
2794
2805
|
const { PolicyRegistry: PolicyRegistry2 } = await Promise.resolve().then(() => (init_application(), application_exports));
|
|
2795
2806
|
container.addSingleton(TOKENS4.POLICY_REGISTRY, () => new PolicyRegistry2());
|
|
2796
2807
|
const policyRegistry = opts.policies;
|
|
@@ -2799,16 +2810,16 @@ var init_auth_utils = __esm({
|
|
|
2799
2810
|
for (const [intent, policy] of Object.entries(policyRegistry)) {
|
|
2800
2811
|
const intentLower = intent.toLowerCase();
|
|
2801
2812
|
registryInstance.addPolicy(intentLower, policy);
|
|
2802
|
-
if (!
|
|
2813
|
+
if (!Guards47.isNullOrEmpty(policy.roles)) {
|
|
2803
2814
|
Policies.add("roles");
|
|
2804
2815
|
}
|
|
2805
|
-
if (!
|
|
2816
|
+
if (!Guards47.isNullOrEmpty(policy.permissions)) {
|
|
2806
2817
|
Policies.add("permissions");
|
|
2807
2818
|
}
|
|
2808
|
-
if (!
|
|
2819
|
+
if (!Guards47.isNullOrEmpty(policy.userId)) {
|
|
2809
2820
|
Policies.add("userId");
|
|
2810
2821
|
}
|
|
2811
|
-
if (!
|
|
2822
|
+
if (!Guards47.isNullOrEmpty(policy.tenantId)) {
|
|
2812
2823
|
Policies.add("tenantId");
|
|
2813
2824
|
}
|
|
2814
2825
|
}
|
|
@@ -2857,10 +2868,10 @@ var init_auth_utils = __esm({
|
|
|
2857
2868
|
strategies.push(TOKENS4.TENANT_AUTHORIZATION_PIPELINE);
|
|
2858
2869
|
}
|
|
2859
2870
|
}
|
|
2860
|
-
if (!
|
|
2871
|
+
if (!Guards47.isNullOrEmpty(opts.customAuthorizationStrategy)) {
|
|
2861
2872
|
const customStrategies = opts.customAuthorizationStrategy;
|
|
2862
2873
|
customStrategies.forEach((strategyToken, index) => {
|
|
2863
|
-
if (
|
|
2874
|
+
if (Guards47.isDefined(strategyToken)) {
|
|
2864
2875
|
const token = `CUSTOM_AUTHORIZATION_STRATEGY_${index}`;
|
|
2865
2876
|
container.addSingleton(token, (c) => {
|
|
2866
2877
|
return strategyToken(c);
|
|
@@ -3063,7 +3074,7 @@ var init_db_module = __esm({
|
|
|
3063
3074
|
"use strict";
|
|
3064
3075
|
DbModule = class {
|
|
3065
3076
|
async configure(container, opts) {
|
|
3066
|
-
const { Guards:
|
|
3077
|
+
const { Guards: Guards47, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
|
|
3067
3078
|
const { DbUtils: DbUtils2 } = await Promise.resolve().then(() => (init_db_utils(), db_utils_exports));
|
|
3068
3079
|
const db = opts.enableSqlLite ? await DbUtils2.addSqlLite(opts) : await DbUtils2.addDbClient(opts);
|
|
3069
3080
|
const { TransactionState: TransactionState2 } = await Promise.resolve().then(() => (init_transaction_state(), transaction_state_exports));
|
|
@@ -3080,7 +3091,7 @@ var init_db_module = __esm({
|
|
|
3080
3091
|
return new Proxy(db, {
|
|
3081
3092
|
get(_target, prop, receiver) {
|
|
3082
3093
|
const activeState = ttx.state;
|
|
3083
|
-
if (
|
|
3094
|
+
if (Guards47.isDefined(activeState)) {
|
|
3084
3095
|
if (prop === "transaction") {
|
|
3085
3096
|
return activeState.transaction.bind(activeState);
|
|
3086
3097
|
}
|
|
@@ -3117,14 +3128,14 @@ var init_http_utils = __esm({
|
|
|
3117
3128
|
*/
|
|
3118
3129
|
async addAxios(container, opts) {
|
|
3119
3130
|
const { NodeAxiosFactory: NodeAxiosFactory2 } = await Promise.resolve().then(() => (init_factories(), factories_exports));
|
|
3120
|
-
const { Guards:
|
|
3121
|
-
if (!
|
|
3131
|
+
const { Guards: Guards47 } = await import("@xeno-js/shared");
|
|
3132
|
+
if (!Guards47.isDefined(opts.token)) {
|
|
3122
3133
|
throw new Error("HttpConfig.token is required and must be defined.");
|
|
3123
3134
|
}
|
|
3124
3135
|
container.addSingleton(opts.token, () => {
|
|
3125
3136
|
const factory = new NodeAxiosFactory2();
|
|
3126
3137
|
const instance = factory.create(opts.client);
|
|
3127
|
-
if (!
|
|
3138
|
+
if (!Guards47.hasMethod(instance, "get") || !Guards47.hasMethod(instance, "post") || !Guards47.hasMethod(instance, "put") || !Guards47.hasMethod(instance, "patch") || !Guards47.hasMethod(instance, "delete")) {
|
|
3128
3139
|
throw new Error(
|
|
3129
3140
|
"The created HTTP client instance does not implement the required methods of IHttpClient."
|
|
3130
3141
|
);
|
|
@@ -3151,8 +3162,8 @@ var init_http_utils = __esm({
|
|
|
3151
3162
|
});
|
|
3152
3163
|
},
|
|
3153
3164
|
async addAllowOrigin(container, opts) {
|
|
3154
|
-
const { Guards:
|
|
3155
|
-
if (
|
|
3165
|
+
const { Guards: Guards47 } = await import("@xeno-js/shared");
|
|
3166
|
+
if (Guards47.isNullOrEmpty(opts)) throw new Error("At least an allow origin must be passed");
|
|
3156
3167
|
const { TOKENS: TOKENS4 } = await import("@xeno-js/shared");
|
|
3157
3168
|
const { AllowOrigin: AllowOrigin2 } = await Promise.resolve().then(() => (init_services(), services_exports));
|
|
3158
3169
|
const allowOrigin = [];
|
|
@@ -3212,13 +3223,13 @@ var init_validation_utils = __esm({
|
|
|
3212
3223
|
* @link https://github.com/xeno-js/xeno-js
|
|
3213
3224
|
*/
|
|
3214
3225
|
async addValidation(container, opts, logger) {
|
|
3215
|
-
const { Guards:
|
|
3216
|
-
if (!
|
|
3226
|
+
const { Guards: Guards47, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
|
|
3227
|
+
if (!Guards47.isDefined(opts.zod) && Guards47.isNullOrEmpty(opts.customValidationStrategy)) {
|
|
3217
3228
|
return [];
|
|
3218
3229
|
}
|
|
3219
3230
|
const pipelines = [];
|
|
3220
3231
|
const validationStrategies = [];
|
|
3221
|
-
if (
|
|
3232
|
+
if (Guards47.isDefined(opts.zod)) {
|
|
3222
3233
|
const config = opts.zod;
|
|
3223
3234
|
const { ZodValidatorFactory: ZodValidatorFactory2 } = await Promise.resolve().then(() => (init_zod_validator_factory(), zod_validator_factory_exports));
|
|
3224
3235
|
container.addSingleton(TOKENS4.ZOD_VALIDATOR, () => {
|
|
@@ -3232,9 +3243,9 @@ var init_validation_utils = __esm({
|
|
|
3232
3243
|
validationStrategies.push(TOKENS4.SCHEMA_VALIDATION_STRATEGY);
|
|
3233
3244
|
}
|
|
3234
3245
|
const customValidationFactory = [];
|
|
3235
|
-
if (!
|
|
3246
|
+
if (!Guards47.isNullOrEmpty(opts.customValidationStrategy)) {
|
|
3236
3247
|
for (const strategyToken of opts.customValidationStrategy) {
|
|
3237
|
-
if (
|
|
3248
|
+
if (Guards47.isDefined(strategyToken)) {
|
|
3238
3249
|
customValidationFactory.push(strategyToken);
|
|
3239
3250
|
}
|
|
3240
3251
|
}
|
|
@@ -3337,8 +3348,8 @@ var init_pipeline_utils = __esm({
|
|
|
3337
3348
|
*/
|
|
3338
3349
|
async addCommand(container, opts) {
|
|
3339
3350
|
const pipelines = [];
|
|
3340
|
-
const { Guards:
|
|
3341
|
-
if (
|
|
3351
|
+
const { Guards: Guards47, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
|
|
3352
|
+
if (Guards47.isDefined(opts.idempotency)) {
|
|
3342
3353
|
const { IdempotencyStore: IdempotencyStore2 } = await Promise.resolve().then(() => (init_idempotency_store(), idempotency_store_exports));
|
|
3343
3354
|
container.addSingleton(
|
|
3344
3355
|
TOKENS4.IDEMPOTENCY_STORE,
|
|
@@ -3358,7 +3369,7 @@ var init_pipeline_utils = __esm({
|
|
|
3358
3369
|
});
|
|
3359
3370
|
pipelines.push(TOKENS4.IDEMPOTENCY_PIPELINE);
|
|
3360
3371
|
}
|
|
3361
|
-
if (
|
|
3372
|
+
if (Guards47.isDefined(opts.concurrency)) {
|
|
3362
3373
|
const { ConcurrencyRetryPipeline: ConcurrencyRetryPipeline2 } = await Promise.resolve().then(() => (init_application(), application_exports));
|
|
3363
3374
|
container.addSingleton(TOKENS4.CONCURRENCY_RETRY_PIPELINE, () => {
|
|
3364
3375
|
const config = opts.concurrency;
|
|
@@ -3438,13 +3449,13 @@ var init_cqrs_module = __esm({
|
|
|
3438
3449
|
return new PerformancePipeline2(logger, thresholdMs);
|
|
3439
3450
|
});
|
|
3440
3451
|
pipelines.push(TOKENS4.PERFORMANCE_PIPELINE);
|
|
3441
|
-
const { Guards:
|
|
3442
|
-
if (
|
|
3452
|
+
const { Guards: Guards47 } = await import("@xeno-js/shared");
|
|
3453
|
+
if (Guards47.isDefined(opts.authorization.policies) || Guards47.isDefined(opts.authorization.customAuthorizationStrategy)) {
|
|
3443
3454
|
const { AuthUtils: AuthUtils2 } = await Promise.resolve().then(() => (init_auth_utils(), auth_utils_exports));
|
|
3444
3455
|
const authPipelines = await AuthUtils2.addAuthZ(container, opts.authorization);
|
|
3445
3456
|
pipelines.push(...authPipelines);
|
|
3446
3457
|
}
|
|
3447
|
-
if (
|
|
3458
|
+
if (Guards47.isDefined(opts.validation.zod) || Guards47.isDefined(opts.validation.customValidationStrategy)) {
|
|
3448
3459
|
const { ValidationUtils: ValidationUtils2 } = await Promise.resolve().then(() => (init_validation_utils(), validation_utils_exports));
|
|
3449
3460
|
const logger = container.resolve(TOKENS4.LOGGER);
|
|
3450
3461
|
const validationPipelines = await ValidationUtils2.addValidation(
|
|
@@ -3456,11 +3467,11 @@ var init_cqrs_module = __esm({
|
|
|
3456
3467
|
}
|
|
3457
3468
|
const commandPipelines = pipelines;
|
|
3458
3469
|
const queryPipelines = pipelines;
|
|
3459
|
-
if ((
|
|
3470
|
+
if ((Guards47.isDefined(opts.commandBus.idempotency) || opts.queryBus.isEnabled) && opts.isCache) {
|
|
3460
3471
|
const { CacheUtils: CacheUtils2 } = await Promise.resolve().then(() => (init_cache_utils(), cache_utils_exports));
|
|
3461
3472
|
await CacheUtils2.addCache(container, { inMemory: true, redis: void 0 });
|
|
3462
3473
|
}
|
|
3463
|
-
if (
|
|
3474
|
+
if (Guards47.isDefined(opts.commandBus.idempotency) || Guards47.isDefined(opts.commandBus.concurrency)) {
|
|
3464
3475
|
const { PipelineUtils: PipelineUtils2 } = await Promise.resolve().then(() => (init_pipeline_utils(), pipeline_utils_exports));
|
|
3465
3476
|
const newCommandPipelines = await PipelineUtils2.addCommand(container, {
|
|
3466
3477
|
...opts.commandBus,
|
|
@@ -3649,7 +3660,10 @@ var init_allow_method_middleware = __esm({
|
|
|
3649
3660
|
spanId: tracing?.spanId ?? GuidHelper6.generate(),
|
|
3650
3661
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
3651
3662
|
},
|
|
3652
|
-
STATUS_CODES4.NOT_ALLOWED
|
|
3663
|
+
STATUS_CODES4.NOT_ALLOWED,
|
|
3664
|
+
{
|
|
3665
|
+
Allow: this._allowMethod.getMethods(req.path)
|
|
3666
|
+
}
|
|
3653
3667
|
);
|
|
3654
3668
|
}
|
|
3655
3669
|
return await next();
|
|
@@ -3788,11 +3802,13 @@ var init_cors_middleware = __esm({
|
|
|
3788
3802
|
"src/presentation/middlewares/cors.middleware.ts"() {
|
|
3789
3803
|
"use strict";
|
|
3790
3804
|
CORSMiddleware = class {
|
|
3791
|
-
constructor(_requestContext) {
|
|
3805
|
+
constructor(_requestContext, _withCredentials = "false") {
|
|
3792
3806
|
this._requestContext = _requestContext;
|
|
3807
|
+
this._withCredentials = _withCredentials;
|
|
3793
3808
|
}
|
|
3794
3809
|
_requestContext;
|
|
3795
|
-
|
|
3810
|
+
_withCredentials;
|
|
3811
|
+
async execute(_req, _headers, next) {
|
|
3796
3812
|
const { network } = this._requestContext.getContext() ?? {};
|
|
3797
3813
|
const origin = network?.origin;
|
|
3798
3814
|
const response = await next();
|
|
@@ -3800,7 +3816,7 @@ var init_cors_middleware = __esm({
|
|
|
3800
3816
|
response.headers = {
|
|
3801
3817
|
...response.headers ?? {},
|
|
3802
3818
|
"Access-Control-Allow-Origin": origin,
|
|
3803
|
-
"Access-Control-Allow-Credentials":
|
|
3819
|
+
"Access-Control-Allow-Credentials": this._withCredentials,
|
|
3804
3820
|
"Vary": "Origin"
|
|
3805
3821
|
};
|
|
3806
3822
|
return response;
|
|
@@ -3951,10 +3967,16 @@ var init_options_middleware = __esm({
|
|
|
3951
3967
|
"src/presentation/middlewares/options.middleware.ts"() {
|
|
3952
3968
|
"use strict";
|
|
3953
3969
|
OptionsMiddleware = class {
|
|
3954
|
-
constructor(_requestContext) {
|
|
3970
|
+
constructor(_requestContext, _alloewMethod, _allowHeaders = [], _withCredentials = "false") {
|
|
3955
3971
|
this._requestContext = _requestContext;
|
|
3972
|
+
this._alloewMethod = _alloewMethod;
|
|
3973
|
+
this._allowHeaders = _allowHeaders;
|
|
3974
|
+
this._withCredentials = _withCredentials;
|
|
3956
3975
|
}
|
|
3957
3976
|
_requestContext;
|
|
3977
|
+
_alloewMethod;
|
|
3978
|
+
_allowHeaders;
|
|
3979
|
+
_withCredentials;
|
|
3958
3980
|
async execute(req, _headers, next) {
|
|
3959
3981
|
if (req.method.toUpperCase() === "OPTIONS") {
|
|
3960
3982
|
const network = this._requestContext.getNetworkContext();
|
|
@@ -3962,11 +3984,11 @@ var init_options_middleware = __esm({
|
|
|
3962
3984
|
const headers = {};
|
|
3963
3985
|
if (Guards39.isDefined(origin)) {
|
|
3964
3986
|
headers["Access-Control-Allow-Origin"] = origin;
|
|
3965
|
-
headers["Access-Control-Allow-Credentials"] =
|
|
3987
|
+
headers["Access-Control-Allow-Credentials"] = this._withCredentials;
|
|
3966
3988
|
headers["Vary"] = "Origin";
|
|
3967
3989
|
}
|
|
3968
|
-
headers["Access-Control-Allow-Methods"] =
|
|
3969
|
-
headers["Access-Control-Allow-Headers"] = "
|
|
3990
|
+
headers["Access-Control-Allow-Methods"] = this._alloewMethod.getMethods(req.path);
|
|
3991
|
+
headers["Access-Control-Allow-Headers"] = this._allowHeaders.join(", ");
|
|
3970
3992
|
return HttpHelper7.success(null, STATUS_CODES8.NO_CONTENT, {}, headers);
|
|
3971
3993
|
}
|
|
3972
3994
|
return await next();
|
|
@@ -3976,32 +3998,42 @@ var init_options_middleware = __esm({
|
|
|
3976
3998
|
});
|
|
3977
3999
|
|
|
3978
4000
|
// src/presentation/middlewares/rate-limiter.middleware.ts
|
|
3979
|
-
import {
|
|
4001
|
+
import {
|
|
4002
|
+
ERROR_CODE_MESSAGES as ERROR_CODE_MESSAGES6,
|
|
4003
|
+
ERROR_CODES as ERROR_CODES7,
|
|
4004
|
+
Guards as Guards40,
|
|
4005
|
+
GuidHelper as GuidHelper10,
|
|
4006
|
+
HttpHelper as HttpHelper8,
|
|
4007
|
+
STATUS_CODES as STATUS_CODES9
|
|
4008
|
+
} from "@xeno-js/shared";
|
|
3980
4009
|
var RateLimitMiddleware;
|
|
3981
4010
|
var init_rate_limiter_middleware = __esm({
|
|
3982
4011
|
"src/presentation/middlewares/rate-limiter.middleware.ts"() {
|
|
3983
4012
|
"use strict";
|
|
3984
4013
|
RateLimitMiddleware = class {
|
|
3985
|
-
constructor(_ctxAccessor, _cache, _logger, _opts) {
|
|
4014
|
+
constructor(_ctxAccessor, _cache, _keyBuilder, _logger, _opts) {
|
|
3986
4015
|
this._ctxAccessor = _ctxAccessor;
|
|
3987
4016
|
this._cache = _cache;
|
|
4017
|
+
this._keyBuilder = _keyBuilder;
|
|
3988
4018
|
this._logger = _logger;
|
|
3989
4019
|
this._opts = _opts;
|
|
3990
4020
|
}
|
|
3991
4021
|
_ctxAccessor;
|
|
3992
4022
|
_cache;
|
|
4023
|
+
_keyBuilder;
|
|
3993
4024
|
_logger;
|
|
3994
4025
|
_opts;
|
|
3995
4026
|
async execute(req, _headers, next) {
|
|
4027
|
+
const cacheKey = this._keyBuilder.buildRateLimitKey(req.path);
|
|
3996
4028
|
const { network, tracing } = this._ctxAccessor.getContext() ?? {};
|
|
3997
|
-
if (!Guards40.isDefined(
|
|
4029
|
+
if (!Guards40.isDefined(cacheKey))
|
|
3998
4030
|
return HttpHelper8.error(
|
|
3999
4031
|
{
|
|
4000
4032
|
success: false,
|
|
4001
4033
|
error: {
|
|
4002
4034
|
code: ERROR_CODES7.SYSTEM_ERROR,
|
|
4003
|
-
message:
|
|
4004
|
-
details: `
|
|
4035
|
+
message: ERROR_CODE_MESSAGES6[ERROR_CODES7.SYSTEM_ERROR],
|
|
4036
|
+
details: `Bad Request: Unable to identify client context for rate limiting.`,
|
|
4005
4037
|
path: req.path
|
|
4006
4038
|
},
|
|
4007
4039
|
correlationId: tracing?.correlationId ?? GuidHelper10.generate(),
|
|
@@ -4015,18 +4047,16 @@ var init_rate_limiter_middleware = __esm({
|
|
|
4015
4047
|
"Retry-After": [String(this._opts.windowSeconds)]
|
|
4016
4048
|
}
|
|
4017
4049
|
);
|
|
4018
|
-
const clientIp = network?.clientIp;
|
|
4019
|
-
const cacheKey = `rate_limit:${clientIp}`;
|
|
4020
4050
|
const currentHits = await this._cache.increment(cacheKey, this._opts.windowSeconds);
|
|
4021
4051
|
if (currentHits > this._opts.maxRequests) {
|
|
4022
|
-
this._logger.warn(`[RateLimit]
|
|
4052
|
+
this._logger.warn(`[RateLimit] key ${cacheKey} has been blocked on ${req.path}`);
|
|
4023
4053
|
return HttpHelper8.error(
|
|
4024
4054
|
{
|
|
4025
4055
|
success: false,
|
|
4026
4056
|
error: {
|
|
4027
4057
|
code: ERROR_CODES7.TOO_MANY_REQUESTS,
|
|
4028
|
-
message:
|
|
4029
|
-
details: `
|
|
4058
|
+
message: ERROR_CODE_MESSAGES6[ERROR_CODES7.TOO_MANY_REQUESTS],
|
|
4059
|
+
details: `Rate limit exceeded. Key ${cacheKey} throttled.`,
|
|
4030
4060
|
path: req.path
|
|
4031
4061
|
},
|
|
4032
4062
|
correlationId: tracing?.correlationId ?? GuidHelper10.generate(),
|
|
@@ -4107,7 +4137,7 @@ var init_context_mapper = __esm({
|
|
|
4107
4137
|
|
|
4108
4138
|
// src/presentation/middlewares/request.middleware.ts
|
|
4109
4139
|
import {
|
|
4110
|
-
ERROR_CODE_MESSAGES as
|
|
4140
|
+
ERROR_CODE_MESSAGES as ERROR_CODE_MESSAGES7,
|
|
4111
4141
|
ERROR_CODES as ERROR_CODES8,
|
|
4112
4142
|
GUEST as GUEST3,
|
|
4113
4143
|
GuidHelper as GuidHelper11,
|
|
@@ -4176,7 +4206,7 @@ var init_request_middleware = __esm({
|
|
|
4176
4206
|
success: false,
|
|
4177
4207
|
error: {
|
|
4178
4208
|
code: ERROR_CODES8.SYSTEM_ERROR,
|
|
4179
|
-
message:
|
|
4209
|
+
message: ERROR_CODE_MESSAGES7[ERROR_CODES8.SYSTEM_ERROR],
|
|
4180
4210
|
details: `[Fatal System Error] Exception caught during request handling on path: ${req.path}`,
|
|
4181
4211
|
path: req.path
|
|
4182
4212
|
},
|
|
@@ -4234,13 +4264,57 @@ var init_presentation = __esm({
|
|
|
4234
4264
|
}
|
|
4235
4265
|
});
|
|
4236
4266
|
|
|
4267
|
+
// src/infrastructure/cache/rate-limit-key-builder.cache.ts
|
|
4268
|
+
import { Guards as Guards42 } from "@xeno-js/shared";
|
|
4269
|
+
var RateLimitKeyBuilder;
|
|
4270
|
+
var init_rate_limit_key_builder_cache = __esm({
|
|
4271
|
+
"src/infrastructure/cache/rate-limit-key-builder.cache.ts"() {
|
|
4272
|
+
"use strict";
|
|
4273
|
+
RateLimitKeyBuilder = class {
|
|
4274
|
+
constructor(_contextAccessor) {
|
|
4275
|
+
this._contextAccessor = _contextAccessor;
|
|
4276
|
+
}
|
|
4277
|
+
_contextAccessor;
|
|
4278
|
+
buildRateLimitKey(resource) {
|
|
4279
|
+
const ctx = this._contextAccessor.getContext();
|
|
4280
|
+
const tenantId = ctx?.identity?.tenantId;
|
|
4281
|
+
const userId = ctx?.identity?.userId;
|
|
4282
|
+
const clientIp = ctx?.network?.clientIp;
|
|
4283
|
+
if (!Guards42.isNullOrEmpty(tenantId) && !Guards42.isNullOrEmpty(userId))
|
|
4284
|
+
return `ratelimit:tenant:${tenantId}:user:${userId}:${resource}`;
|
|
4285
|
+
if (!Guards42.isNullOrEmpty(tenantId) && !Guards42.isNullOrEmpty(clientIp))
|
|
4286
|
+
return `ratelimit:tenant:${tenantId}:ip:${clientIp}:${resource}`;
|
|
4287
|
+
if (!Guards42.isNullOrEmpty(userId)) return `ratelimit:user:${userId}:${resource}`;
|
|
4288
|
+
if (!Guards42.isNullOrEmpty(clientIp)) return `ratelimit:ip:${clientIp}:${resource}`;
|
|
4289
|
+
return void 0;
|
|
4290
|
+
}
|
|
4291
|
+
};
|
|
4292
|
+
}
|
|
4293
|
+
});
|
|
4294
|
+
|
|
4295
|
+
// src/infrastructure/cache/index.ts
|
|
4296
|
+
var cache_exports = {};
|
|
4297
|
+
__export(cache_exports, {
|
|
4298
|
+
InMemoryCacheExtended: () => InMemoryCacheExtended,
|
|
4299
|
+
RateLimitKeyBuilder: () => RateLimitKeyBuilder,
|
|
4300
|
+
RedisCache: () => RedisCache
|
|
4301
|
+
});
|
|
4302
|
+
var init_cache = __esm({
|
|
4303
|
+
"src/infrastructure/cache/index.ts"() {
|
|
4304
|
+
"use strict";
|
|
4305
|
+
init_inmemory_cache();
|
|
4306
|
+
init_rate_limit_key_builder_cache();
|
|
4307
|
+
init_redis_cache();
|
|
4308
|
+
}
|
|
4309
|
+
});
|
|
4310
|
+
|
|
4237
4311
|
// src/infrastructure/modules/middleware.module.ts
|
|
4238
4312
|
var middleware_module_exports = {};
|
|
4239
4313
|
__export(middleware_module_exports, {
|
|
4240
4314
|
MiddlewareModule: () => MiddlewareModule
|
|
4241
4315
|
});
|
|
4242
4316
|
import {
|
|
4243
|
-
Guards as
|
|
4317
|
+
Guards as Guards43
|
|
4244
4318
|
} from "@xeno-js/shared";
|
|
4245
4319
|
var MiddlewareModule;
|
|
4246
4320
|
var init_middleware_module = __esm({
|
|
@@ -4289,10 +4363,12 @@ var init_middleware_module = __esm({
|
|
|
4289
4363
|
c.resolve(TOKENS4.LOGGER)
|
|
4290
4364
|
)
|
|
4291
4365
|
);
|
|
4292
|
-
if (!
|
|
4293
|
-
const
|
|
4294
|
-
if (
|
|
4295
|
-
throw new Error(
|
|
4366
|
+
if (!Guards43.isNullOrEmpty(opts.allowOrigins)) {
|
|
4367
|
+
const withCredentials2 = opts.httpConfig.withCredentials ?? false;
|
|
4368
|
+
if (withCredentials2 && opts.allowOrigins.includes("*"))
|
|
4369
|
+
throw new Error(
|
|
4370
|
+
"Wildcard CORS origin is not allowed when withCredentials is set to true in addHttpCore"
|
|
4371
|
+
);
|
|
4296
4372
|
const { AllowOrigin: AllowOrigin2 } = await Promise.resolve().then(() => (init_services(), services_exports));
|
|
4297
4373
|
container.addSingleton("ALLOW_ORIGIN", () => {
|
|
4298
4374
|
return new AllowOrigin2(opts.allowOrigins);
|
|
@@ -4307,22 +4383,28 @@ var init_middleware_module = __esm({
|
|
|
4307
4383
|
});
|
|
4308
4384
|
middlewares.push(TOKENS4.ALLOW_ORIGIN_MIDDLEWARE);
|
|
4309
4385
|
}
|
|
4386
|
+
const withCredentials = Guards43.isDefined(opts.httpConfig.withCredentials) && opts.httpConfig.withCredentials ? "true" : "false";
|
|
4310
4387
|
if (opts.optionsMiddleware) {
|
|
4311
4388
|
const { OptionsMiddleware: OptionsMiddleware2 } = await Promise.resolve().then(() => (init_presentation(), presentation_exports));
|
|
4312
4389
|
container.addSingleton(
|
|
4313
4390
|
TOKENS4.OPTIONS_MIDDLEWARE,
|
|
4314
|
-
(c) => new OptionsMiddleware2(
|
|
4391
|
+
(c) => new OptionsMiddleware2(
|
|
4392
|
+
c.resolve(TOKENS4.NETWORK_CONTEXT_ACCESSOR),
|
|
4393
|
+
c.resolve(TOKENS4.ALLOW_METHOD),
|
|
4394
|
+
opts.allowHeaders,
|
|
4395
|
+
withCredentials
|
|
4396
|
+
)
|
|
4315
4397
|
);
|
|
4316
4398
|
middlewares.push(TOKENS4.OPTIONS_MIDDLEWARE);
|
|
4317
4399
|
}
|
|
4318
4400
|
if (opts.cors) {
|
|
4319
4401
|
const { CORSMiddleware: CORSMiddleware2 } = await Promise.resolve().then(() => (init_presentation(), presentation_exports));
|
|
4320
4402
|
container.addSingleton(TOKENS4.CORS_MIDDLEWARE, (c) => {
|
|
4321
|
-
return new CORSMiddleware2(c.resolve(TOKENS4.CONTEXT_ACCESSOR));
|
|
4403
|
+
return new CORSMiddleware2(c.resolve(TOKENS4.CONTEXT_ACCESSOR), withCredentials);
|
|
4322
4404
|
});
|
|
4323
4405
|
middlewares.push(TOKENS4.CORS_MIDDLEWARE);
|
|
4324
4406
|
}
|
|
4325
|
-
if (
|
|
4407
|
+
if (Guards43.isDefined(opts.routeRegistry)) {
|
|
4326
4408
|
const registry = opts.routeRegistry;
|
|
4327
4409
|
const { AllowMethodFactory: AllowMethodFactory2 } = await Promise.resolve().then(() => (init_factories(), factories_exports));
|
|
4328
4410
|
container.addSingleton(TOKENS4.ALLOW_METHOD, () => new AllowMethodFactory2().create(registry));
|
|
@@ -4346,7 +4428,38 @@ var init_middleware_module = __esm({
|
|
|
4346
4428
|
);
|
|
4347
4429
|
});
|
|
4348
4430
|
middlewares.push(TOKENS4.AUTH_MIDDLEWARE);
|
|
4349
|
-
if (
|
|
4431
|
+
if (Guards43.isDefined(opts.rateLimite.maxRequests) || Guards43.isDefined(opts.rateLimite.windowSeconds)) {
|
|
4432
|
+
const maxRequests = opts.rateLimite.maxRequests ?? 30;
|
|
4433
|
+
Guards43.throwIfNegative(maxRequests, "MaxRequests must be positive");
|
|
4434
|
+
Guards43.throwIfNotInteger(maxRequests, "MaxRequests must be an integer");
|
|
4435
|
+
const windowSeconds = opts.rateLimite.windowSeconds ?? 30;
|
|
4436
|
+
Guards43.throwIfNegative(windowSeconds, "WindowSeconds must be positive");
|
|
4437
|
+
Guards43.throwIfNotInteger(windowSeconds, "WindowSeconds must be an integer");
|
|
4438
|
+
if (!opts.isCache) {
|
|
4439
|
+
const { CacheUtils: CacheUtils2 } = await Promise.resolve().then(() => (init_cache_utils(), cache_utils_exports));
|
|
4440
|
+
await CacheUtils2.addCache(container, { inMemory: true, redis: void 0 });
|
|
4441
|
+
}
|
|
4442
|
+
const { RateLimitKeyBuilder: RateLimitKeyBuilder2 } = await Promise.resolve().then(() => (init_cache(), cache_exports));
|
|
4443
|
+
container.addSingleton(
|
|
4444
|
+
"RATE_LIMIT_KEY_BUILDER",
|
|
4445
|
+
(c) => new RateLimitKeyBuilder2(c.resolve(TOKENS4.REQUEST_CONTEXT))
|
|
4446
|
+
);
|
|
4447
|
+
const { RateLimitMiddleware: RateLimitMiddleware2 } = await Promise.resolve().then(() => (init_presentation(), presentation_exports));
|
|
4448
|
+
container.addSingleton(TOKENS4.RATE_LIMITER_MIDDLEWARE, (c) => {
|
|
4449
|
+
return new RateLimitMiddleware2(
|
|
4450
|
+
c.resolve(TOKENS4.CONTEXT_ACCESSOR),
|
|
4451
|
+
c.resolve(TOKENS4.CACHE),
|
|
4452
|
+
c.resolve("RATE_LIMIT_KEY_BUILDER"),
|
|
4453
|
+
c.resolve(TOKENS4.LOGGER),
|
|
4454
|
+
{
|
|
4455
|
+
maxRequests,
|
|
4456
|
+
windowSeconds
|
|
4457
|
+
}
|
|
4458
|
+
);
|
|
4459
|
+
});
|
|
4460
|
+
middlewares.push(TOKENS4.RATE_LIMITER_MIDDLEWARE);
|
|
4461
|
+
}
|
|
4462
|
+
if (Guards43.isDefined(opts.csrf)) {
|
|
4350
4463
|
const csrf = opts.csrf;
|
|
4351
4464
|
const { CsrfTokenService: CsrfTokenService2 } = await Promise.resolve().then(() => (init_services(), services_exports));
|
|
4352
4465
|
container.addSingleton("CSRF_TOKEN_SERVICE", (c) => {
|
|
@@ -4370,31 +4483,6 @@ var init_middleware_module = __esm({
|
|
|
4370
4483
|
});
|
|
4371
4484
|
middlewares.push(TOKENS4.CSRF_MIDDLEWARE);
|
|
4372
4485
|
}
|
|
4373
|
-
if (Guards42.isDefined(opts.rateLimite.maxRequests) || Guards42.isDefined(opts.rateLimite.windowSeconds)) {
|
|
4374
|
-
const maxRequests = opts.rateLimite.maxRequests ?? 30;
|
|
4375
|
-
Guards42.throwIfNegative(maxRequests, "MaxRequests must be positive");
|
|
4376
|
-
Guards42.throwIfNotInteger(maxRequests, "MaxRequests must be an integer");
|
|
4377
|
-
const windowSeconds = opts.rateLimite.windowSeconds ?? 30;
|
|
4378
|
-
Guards42.throwIfNegative(windowSeconds, "WindowSeconds must be positive");
|
|
4379
|
-
Guards42.throwIfNotInteger(windowSeconds, "WindowSeconds must be an integer");
|
|
4380
|
-
if (!opts.isCache) {
|
|
4381
|
-
const { CacheUtils: CacheUtils2 } = await Promise.resolve().then(() => (init_cache_utils(), cache_utils_exports));
|
|
4382
|
-
await CacheUtils2.addCache(container, { inMemory: true, redis: void 0 });
|
|
4383
|
-
}
|
|
4384
|
-
const { RateLimitMiddleware: RateLimitMiddleware2 } = await Promise.resolve().then(() => (init_presentation(), presentation_exports));
|
|
4385
|
-
container.addSingleton(TOKENS4.RATE_LIMITER_MIDDLEWARE, (c) => {
|
|
4386
|
-
return new RateLimitMiddleware2(
|
|
4387
|
-
c.resolve(TOKENS4.CONTEXT_ACCESSOR),
|
|
4388
|
-
c.resolve(TOKENS4.CACHE),
|
|
4389
|
-
c.resolve(TOKENS4.LOGGER),
|
|
4390
|
-
{
|
|
4391
|
-
maxRequests,
|
|
4392
|
-
windowSeconds
|
|
4393
|
-
}
|
|
4394
|
-
);
|
|
4395
|
-
});
|
|
4396
|
-
middlewares.push(TOKENS4.RATE_LIMITER_MIDDLEWARE);
|
|
4397
|
-
}
|
|
4398
4486
|
const { CompositeMiddleware: CompositeMiddleware2 } = await Promise.resolve().then(() => (init_presentation(), presentation_exports));
|
|
4399
4487
|
container.addSingleton(TOKENS4.MIDDLEWARE, (c) => {
|
|
4400
4488
|
const resolvedMiddleware = middlewares.map(
|
|
@@ -4464,7 +4552,7 @@ __export(index_exports, {
|
|
|
4464
4552
|
init_application();
|
|
4465
4553
|
|
|
4466
4554
|
// src/infrastructure/builder/app.builder.ts
|
|
4467
|
-
import { Guards as
|
|
4555
|
+
import { Guards as Guards44, LOG_LEVEL as LOG_LEVEL6, TOKENS as TOKENS3 } from "@xeno-js/shared";
|
|
4468
4556
|
|
|
4469
4557
|
// src/infrastructure/configuration/configuration.ts
|
|
4470
4558
|
import { Guards as Guards13 } from "@xeno-js/shared";
|
|
@@ -4776,6 +4864,7 @@ var AppBuilder = class {
|
|
|
4776
4864
|
trustedIpHeader: void 0,
|
|
4777
4865
|
trustedProxies: [],
|
|
4778
4866
|
allowOrigins: [],
|
|
4867
|
+
allowHeaders: [],
|
|
4779
4868
|
cors: true
|
|
4780
4869
|
};
|
|
4781
4870
|
_httpConfig = {
|
|
@@ -4858,7 +4947,7 @@ var AppBuilder = class {
|
|
|
4858
4947
|
pino: { config: void 0 },
|
|
4859
4948
|
customLoggers: void 0
|
|
4860
4949
|
};
|
|
4861
|
-
if (
|
|
4950
|
+
if (Guards44.isDefined(setupAction) && Guards44.isDefined(config))
|
|
4862
4951
|
setupAction(config, this._configuration);
|
|
4863
4952
|
this._modules.push({
|
|
4864
4953
|
priority: 3,
|
|
@@ -4884,7 +4973,7 @@ var AppBuilder = class {
|
|
|
4884
4973
|
addCache(setupAction) {
|
|
4885
4974
|
if (this._isCacheModuleQueued) return this;
|
|
4886
4975
|
this._isCacheModuleQueued = true;
|
|
4887
|
-
if (
|
|
4976
|
+
if (Guards44.isDefined(setupAction)) setupAction(this._config, this._configuration);
|
|
4888
4977
|
this._modules.push({
|
|
4889
4978
|
priority: 3,
|
|
4890
4979
|
name: "CacheModule",
|
|
@@ -4993,7 +5082,7 @@ var AppBuilder = class {
|
|
|
4993
5082
|
* @link https://github.com/xeno-js/xeno-js
|
|
4994
5083
|
*/
|
|
4995
5084
|
addPipeline(setupAction) {
|
|
4996
|
-
if (
|
|
5085
|
+
if (Guards44.isDefined(setupAction)) {
|
|
4997
5086
|
setupAction(this._pipelineConfig, this._configuration);
|
|
4998
5087
|
}
|
|
4999
5088
|
this._queuePipelineModule();
|
|
@@ -5127,7 +5216,7 @@ var AppBuilder = class {
|
|
|
5127
5216
|
console.error(`\u{1F449} Module: **${queued.name}**`);
|
|
5128
5217
|
console.error(`\u{1F4DD} Reason: ${errorMessage}
|
|
5129
5218
|
`);
|
|
5130
|
-
if (error instanceof Error &&
|
|
5219
|
+
if (error instanceof Error && Guards44.isDefined(error.stack)) {
|
|
5131
5220
|
console.error(error.stack);
|
|
5132
5221
|
}
|
|
5133
5222
|
throw new Error(`Bootstrap failed at [${queued.name}]: ${errorMessage}`, { cause: error });
|
|
@@ -5219,8 +5308,8 @@ var AppBuilder = class {
|
|
|
5219
5308
|
}
|
|
5220
5309
|
};
|
|
5221
5310
|
|
|
5222
|
-
// src/infrastructure/
|
|
5223
|
-
|
|
5311
|
+
// src/infrastructure/index.ts
|
|
5312
|
+
init_cache();
|
|
5224
5313
|
|
|
5225
5314
|
// src/infrastructure/context/index.ts
|
|
5226
5315
|
init_request_context();
|
|
@@ -5257,7 +5346,7 @@ init_validation_utils();
|
|
|
5257
5346
|
|
|
5258
5347
|
// src/infrastructure/repositories/read-dao.ts
|
|
5259
5348
|
import { AppError as AppError16, Result as Result17 } from "@xeno-js/shared";
|
|
5260
|
-
import { Guards as
|
|
5349
|
+
import { Guards as Guards45 } from "@xeno-js/shared";
|
|
5261
5350
|
var ReadDao = class {
|
|
5262
5351
|
/**
|
|
5263
5352
|
* Constructs a new ReadDao instance.
|
|
@@ -5279,7 +5368,7 @@ var ReadDao = class {
|
|
|
5279
5368
|
async findById(id, ctx, signal) {
|
|
5280
5369
|
AppError16.throwIfAborted(signal, "ReadDao.findById");
|
|
5281
5370
|
const result = await this._dataSource.findById(id, ctx, signal);
|
|
5282
|
-
if (
|
|
5371
|
+
if (Guards45.isNullOrEmpty(result)) return Result17.ok();
|
|
5283
5372
|
const entity = this._mapper.toEntity(result);
|
|
5284
5373
|
return Result17.ok(entity);
|
|
5285
5374
|
}
|
|
@@ -5293,7 +5382,7 @@ var ReadDao = class {
|
|
|
5293
5382
|
|
|
5294
5383
|
// src/infrastructure/repositories/repository.ts
|
|
5295
5384
|
import { AppError as AppError17, Result as Result18 } from "@xeno-js/shared";
|
|
5296
|
-
import { Guards as
|
|
5385
|
+
import { Guards as Guards46 } from "@xeno-js/shared";
|
|
5297
5386
|
var Repository = class {
|
|
5298
5387
|
/**
|
|
5299
5388
|
* Constructs a new Repository instance.
|
|
@@ -5315,7 +5404,7 @@ var Repository = class {
|
|
|
5315
5404
|
async findById(id, ctx, signal) {
|
|
5316
5405
|
AppError17.throwIfAborted(signal, "Repository.findById");
|
|
5317
5406
|
const result = await this._dataSource.findById(id, ctx, signal);
|
|
5318
|
-
if (
|
|
5407
|
+
if (Guards46.isNullOrEmpty(result)) return Result18.ok();
|
|
5319
5408
|
const entity = this._mapper.toEntity(result);
|
|
5320
5409
|
return Result18.ok(entity);
|
|
5321
5410
|
}
|
|
@@ -5382,4 +5471,14 @@ export {
|
|
|
5382
5471
|
* @link https://github.com/xeno-js/xeno-js
|
|
5383
5472
|
* @license MIT
|
|
5384
5473
|
*/
|
|
5474
|
+
/**
|
|
5475
|
+
* @description The RateLimitKeyBuilder class implements the IRateLimitKeyBuilder interface, providing a method to build rate limit keys based on the user's identity. This class utilizes an instance of IIdentityAccessor to retrieve the current user's identity, allowing for the creation of tenant-specific rate limit keys in multi-tenant applications. If a tenant ID is present in the identity, the rate limit key is prefixed with the tenant ID; otherwise, it defaults to a public rate limit key. This approach ensures that rate limit data is appropriately scoped to the user's context, preventing data leakage between tenants.
|
|
5476
|
+
*
|
|
5477
|
+
* @author Xeno
|
|
5478
|
+
* @version 1.0.0
|
|
5479
|
+
* @since 2025-09-30
|
|
5480
|
+
* @link https://github.com/xeno-js/xeno-vue
|
|
5481
|
+
* @copyright Xeno
|
|
5482
|
+
* @license MIT
|
|
5483
|
+
*/
|
|
5385
5484
|
//# sourceMappingURL=index.js.map
|