@xeno-js/core 0.1.12 → 1.0.0

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  <div align="center">
2
- <img src="logo/logo.png" alt="Xeno Logo" width="140" />
2
+ <img src="logo/logo.png" alt="Xeno.JS Logo" width="140" />
3
3
 
4
4
  <h1>Xeno.JS</h1>
5
5
  <p><strong>The application architecture framework for TypeScript.</strong></p>
@@ -19,7 +19,7 @@
19
19
 
20
20
  ## What is Xeno?
21
21
 
22
- Xeno is a TypeScript application architecture framework for Node.js.
22
+ Xeno.JS is a TypeScript application architecture framework for Node.js.
23
23
 
24
24
  It provides explicit building blocks for applications organized around:
25
25
 
@@ -34,7 +34,7 @@ It provides explicit building blocks for applications organized around:
34
34
 
35
35
  The goal is simple: **make application architecture explicit in code.**
36
36
 
37
- Xeno is not tied to a specific HTTP server. Your application layer can remain
37
+ Xeno.JS is not tied to a specific HTTP server. Your application layer can remain
38
38
  independent from the transport that delivers a request.
39
39
 
40
40
  ---
@@ -45,7 +45,7 @@ independent from the transport that delivers a request.
45
45
 
46
46
  **Your dependency graph is code.**
47
47
 
48
- Xeno does not require decorators, runtime scanning, or implicit dependency
48
+ Xeno.JS does not require decorators, runtime scanning, or implicit dependency
49
49
  discovery. Services are registered explicitly, and their lifetimes are visible
50
50
  at the composition root.
51
51
 
@@ -65,7 +65,7 @@ reason about.
65
65
 
66
66
  Business logic should not belong to your HTTP framework.
67
67
 
68
- Xeno keeps application concerns separate from delivery mechanisms, allowing the
68
+ Xeno.JS keeps application concerns separate from delivery mechanisms, allowing the
69
69
  same application architecture to be hosted behind transports such as Fastify,
70
70
  Hono, Express, or other adapters.
71
71
 
@@ -104,7 +104,7 @@ This keeps cross-cutting concerns out of individual handlers.
104
104
 
105
105
  ### 04 — Explicit Lifetimes and Request Boundaries
106
106
 
107
- Xeno distinguishes service lifetimes such as singleton, scoped, and transient
107
+ Xeno.JS distinguishes service lifetimes such as singleton, scoped, and transient
108
108
  services.
109
109
 
110
110
  Request-scoped dependencies are resolved inside an explicit application scope,
@@ -127,7 +127,7 @@ infrastructure.
127
127
 
128
128
  ## Architecture
129
129
 
130
- A typical Xeno application can be organized like this:
130
+ A typical Xeno.JS application can be organized like this:
131
131
 
132
132
  ```text
133
133
  +------------------------------------------+
@@ -181,7 +181,7 @@ Infrastructure capabilities can be enabled only when they are needed.
181
181
  npm install @xeno-js/core
182
182
  ```
183
183
 
184
- Install only the integrations your application uses. Xeno exposes optional
184
+ Install only the integrations your application uses. Xeno.JS exposes optional
185
185
  infrastructure dependencies for capabilities such as databases, Redis, logging,
186
186
  resilience, and authentication.
187
187
 
@@ -198,9 +198,11 @@ npm install zod pino cockatiel drizzle-orm
198
198
  The composition root is explicit:
199
199
 
200
200
  ```typescript
201
+ // src/bootstrap.ts
201
202
  import { AppBuilder } from '@xeno-js/core'
202
203
 
203
- const app = new AppBuilder().addServices((services) => {
204
+ const app = new AppBuilder()
205
+ .addServices((services) => {
204
206
  services.addScoped('USER_REPOSITORY', (container) => {
205
207
  return new UserRepository(container.resolve('USER_DATA_SOURCE'))
206
208
  })
@@ -210,12 +212,14 @@ const app = new AppBuilder().addServices((services) => {
210
212
  })
211
213
 
212
214
  services.addTransient('FIND_USER_CONTROLLER', (c) => {
213
- return new FindUserHandler(
215
+ return new FindUserController(
214
216
  c.resolve(TOKENS.REQUEST_CONTEXT),
215
217
  c.resolve(TOKENS.MEDIATOR),
216
218
  )
217
219
  })
218
220
  })
221
+
222
+ await app.build()
219
223
  ```
220
224
 
221
225
  The transport remains outside the application composition:
@@ -228,17 +232,17 @@ The transport remains outside the application composition:
228
232
 
229
233
  ```typescript
230
234
  import Fastify from 'fastify'
231
- import { builder } from './bootstrap'
235
+ import { app } from './bootstrap'
232
236
 
233
- const app = Fastify({ logger: true })
237
+ const fastify = Fastify({ logger: true })
234
238
 
235
- app.get('/users/:id', async (req, reply) => {
239
+ fastify.get('/users/:id', async (req, reply) => {
236
240
  const endpoint = req.url
237
- const container = await builder.build()
241
+
238
242
  const action = async () => {
239
243
  const controller = ContainerUtils.resolveServiceScoped(
240
244
  'FIND_USER_CONTROLLER',
241
- container,
245
+ app,
242
246
  )
243
247
  return await controller.handle()
244
248
  }
@@ -248,7 +252,7 @@ app.get('/users/:id', async (req, reply) => {
248
252
  req.method,
249
253
  req.headers,
250
254
  { reply, req },
251
- container,
255
+ app,
252
256
  action,
253
257
  )
254
258
 
@@ -298,7 +302,7 @@ application.
298
302
 
299
303
  ## Infrastructure & Integrations
300
304
 
301
- Xeno Core can be composed with infrastructure such as:
305
+ Xeno.JS Core can be composed with infrastructure such as:
302
306
 
303
307
  - **Database:** Drizzle ORM, PostgreSQL, LibSQL
304
308
  - **Cache / distributed coordination:** Redis
@@ -315,7 +319,7 @@ architecture.
315
319
 
316
320
  ## CLI
317
321
 
318
- Use the official CLI to scaffold a Xeno application:
322
+ Use the official CLI to scaffold a Xeno.JS application:
319
323
 
320
324
  ```bash
321
325
  npm install @xeno-js/cli
@@ -347,7 +351,7 @@ Recommended starting points:
347
351
 
348
352
  ## Ecosystem
349
353
 
350
- Xeno is designed as an ecosystem rather than a single monolithic package:
354
+ Xeno.JS is designed as an ecosystem rather than a single monolithic package:
351
355
 
352
356
  | Package | Role |
353
357
  | ----------------- | ----------------------------------------- |
@@ -358,15 +362,15 @@ Xeno is designed as an ecosystem rather than a single monolithic package:
358
362
 
359
363
  ---
360
364
 
361
- ## What Xeno Is Not
365
+ ## What Xeno.JS Is Not
362
366
 
363
- Xeno is not primarily an HTTP framework.
367
+ Xeno.JS is not primarily an HTTP framework.
364
368
 
365
369
  If you are looking for a framework centered on routing, controllers, middleware,
366
370
  and server lifecycle, there are excellent options already available in the
367
371
  Node.js ecosystem.
368
372
 
369
- Xeno focuses on the layer above transport:
373
+ Xeno.JS focuses on the layer above transport:
370
374
 
371
375
  > **How should a TypeScript application be structured so that its business
372
376
  > logic, dependencies, and infrastructure boundaries remain explicit as the
@@ -376,7 +380,7 @@ Xeno focuses on the layer above transport:
376
380
 
377
381
  ## Production Considerations
378
382
 
379
- Xeno provides architectural primitives, but application correctness still
383
+ Xeno.JS provides architectural primitives, but application correctness still
380
384
  depends on how those primitives are composed.
381
385
 
382
386
  Before deploying an application, test the behaviors that matter to your
@@ -439,10 +443,10 @@ npm run check
439
443
 
440
444
  ## Support
441
445
 
442
- If Xeno is useful to you, you can support the project through the community and
446
+ If Xeno.JS is useful to you, you can support the project through the community and
443
447
  sponsorship channels documented on the website:
444
448
 
445
- **[Support Xeno](https://www.xeno-js.it/support-us)**
449
+ **[Support Xeno](https://www.xeno-js.it/docs/support-us)**
446
450
 
447
451
  ---
448
452
 
package/dist/index.cjs CHANGED
@@ -68,15 +68,11 @@ var init_container_utils = __esm({
68
68
  * @throws Error If the service is not found in the container.
69
69
  * @throws Error If the service is not a scoped service.
70
70
  */
71
- async runExecute(endpoint, method, headers, transport, container, action) {
71
+ async runExecute(res, req, container, action) {
72
72
  const middleware = container.resolve(import_shared.TOKENS.MIDDLEWARE);
73
- return await middleware.execute(
74
- { path: endpoint, method: method ?? "GET", transport },
75
- { ...headers },
76
- async () => {
77
- return await action();
78
- }
79
- );
73
+ return await middleware.execute(req, res, async () => {
74
+ return await action();
75
+ });
80
76
  }
81
77
  });
82
78
  }
@@ -1024,7 +1020,6 @@ var init_gate_keeper = __esm({
1024
1020
  }
1025
1021
  }
1026
1022
  return import_shared27.Result.ok(guest);
1027
- return import_shared27.Result.ok(guest);
1028
1023
  }
1029
1024
  };
1030
1025
  }
@@ -1955,17 +1950,19 @@ var init_extract_bearer_extractor = __esm({
1955
1950
  "use strict";
1956
1951
  import_shared45 = require("@xeno-js/shared");
1957
1952
  BearerTokenExtractor = class {
1953
+ constructor(_cookiePrefix) {
1954
+ this._cookiePrefix = _cookiePrefix;
1955
+ }
1956
+ _cookiePrefix;
1958
1957
  extract(headers) {
1959
- const authHeader = import_shared45.StringHelper.getSingleValue(headers["authorization"]);
1960
- if (!import_shared45.Guards.isDefined(authHeader)) {
1961
- return void 0;
1962
- }
1963
- if (authHeader.toLowerCase().startsWith("bearer ")) {
1958
+ const authHeader = headers.get("Authorization");
1959
+ if (import_shared45.Guards.isDefined(authHeader) && authHeader.toLowerCase().startsWith("bearer ")) {
1964
1960
  return authHeader.substring(7);
1965
1961
  }
1966
- const cookieHeader = import_shared45.StringHelper.getSingleValue(headers["cookie"]);
1962
+ const cookieHeader = headers.get("cookie");
1967
1963
  if (import_shared45.Guards.isDefined(cookieHeader)) {
1968
- const match = /sb-access-token=([^;]+)/.exec(cookieHeader);
1964
+ const regex = new RegExp(`${this._cookiePrefix}=([^;]+)`);
1965
+ const match = regex.exec(cookieHeader);
1969
1966
  if (!import_shared45.Guards.isNullOrEmpty(match) && import_shared45.Guards.isDefined(match[1])) {
1970
1967
  return match[1].trim();
1971
1968
  }
@@ -1984,11 +1981,11 @@ var init_extract_ssr_bearer_extractor = __esm({
1984
1981
  import_shared46 = require("@xeno-js/shared");
1985
1982
  SupabaseSsrTokenExtractor = class {
1986
1983
  extract(headers) {
1987
- const authHeader = import_shared46.StringHelper.getSingleValue(headers["authorization"]);
1984
+ const authHeader = headers.get("authorization");
1988
1985
  if (import_shared46.Guards.isDefined(authHeader) && authHeader.toLowerCase().startsWith("bearer ")) {
1989
1986
  return authHeader.substring(7);
1990
1987
  }
1991
- const cookieHeader = import_shared46.StringHelper.getSingleValue(headers["cookie"]);
1988
+ const cookieHeader = headers.get("cookie");
1992
1989
  if (import_shared46.Guards.isNullOrEmpty(cookieHeader)) return void 0;
1993
1990
  const cookies = cookieHeader.split(";").map((c) => c.trim());
1994
1991
  const tokenChunks = {};
@@ -2078,29 +2075,29 @@ var init_http_header_extractor = __esm({
2078
2075
  _trustedIp;
2079
2076
  _cookieName;
2080
2077
  extract(headers) {
2081
- const correlationId = import_shared48.GuidHelper.parse(import_shared48.StringHelper.getSingleValue(headers["x-correlation-id"]));
2082
- const requestId = import_shared48.GuidHelper.parse(import_shared48.StringHelper.getSingleValue(headers["x-request-id"]));
2078
+ const correlationId = import_shared48.GuidHelper.parse(headers.get("x-correlation-id") ?? void 0);
2079
+ const requestId = import_shared48.GuidHelper.parse(headers.get("x-request-id") ?? void 0);
2083
2080
  const token = this._bearerExtractor.extract(headers);
2084
- const clientIp = import_shared48.StringHelper.getSingleValue(headers[this._trustedIp?.toLowerCase() ?? "x-forwarded-for"]) ?? import_shared48.StringHelper.getSingleValue(headers["x-real-ip"]);
2085
- const spanId = import_shared48.GuidHelper.parse(import_shared48.StringHelper.getSingleValue(headers["x-span-id"]));
2086
- const parentSpanId = import_shared48.StringHelper.getSingleValue(headers["x-parent-span-id"]);
2087
- const acceptHeader = import_shared48.StringHelper.getSingleValue(headers["accept"]);
2088
- const contentTypeHeader = import_shared48.StringHelper.getSingleValue(headers["content-type"]);
2089
- const userAgent = import_shared48.StringHelper.getSingleValue(headers["user-agent"]);
2090
- const returnAddress = import_shared48.StringHelper.getSingleValue(headers["x-return-address"]);
2091
- const sequenceId = import_shared48.StringHelper.getSingleValue(headers["x-sequence-id"]);
2092
- const position = import_shared48.StringHelper.getSingleValue(headers["x-sequence-position"]);
2093
- const size = import_shared48.StringHelper.getSingleValue(headers["x-sequence-size"]);
2094
- const expiration = import_shared48.StringHelper.getSingleValue(headers["x-expiration"]);
2095
- const csrf = import_shared48.StringHelper.getSingleValue(headers["x-csrf-token"]);
2096
- const cookieHeader = import_shared48.StringHelper.getSingleValue(headers["cookie"]);
2081
+ const clientIp = headers.get(this._trustedIp?.toLowerCase() ?? "x-forwarded-for") ?? headers.get("x-real-ip") ?? void 0;
2082
+ const spanId = import_shared48.GuidHelper.parse(headers.get("x-span-id") ?? void 0);
2083
+ const parentSpanId = headers.get("x-parent-span-id") ?? void 0;
2084
+ const acceptHeader = headers.get("accept");
2085
+ const contentTypeHeader = headers.get("content-type");
2086
+ const userAgent = headers.get("user-agent") ?? void 0;
2087
+ const returnAddress = headers.get("x-return-address") ?? void 0;
2088
+ const sequenceId = headers.get("x-sequence-id") ?? void 0;
2089
+ const position = headers.get("x-sequence-position");
2090
+ const size = headers.get("x-sequence-size");
2091
+ const expiration = headers.get("x-expiration");
2092
+ const csrf = headers.get("x-csrf-token") ?? void 0;
2093
+ const cookieHeader = headers.get("cookie") ?? void 0;
2097
2094
  const csrfCookie = this._cookieExtractor.extract({
2098
2095
  header: cookieHeader,
2099
2096
  name: this._cookieName
2100
2097
  });
2101
- const origin = import_shared48.StringHelper.getSingleValue(headers["origin"]);
2098
+ const origin = headers.get("origin") ?? void 0;
2102
2099
  const cleanOrigin = import_shared48.HttpHelper.sanitizeOriginUrl(origin);
2103
- const referer = import_shared48.StringHelper.getSingleValue(headers["referer"]);
2100
+ const referer = headers.get("referer") ?? void 0;
2104
2101
  const cleanReferer = import_shared48.HttpHelper.sanitizeOriginUrl(referer);
2105
2102
  const accept = acceptHeader === "*/*" ? void 0 : acceptHeader;
2106
2103
  const formatIndicator = accept ?? contentTypeHeader ?? "application/json";
@@ -2289,7 +2286,7 @@ var init_axios_factory = __esm({
2289
2286
  import_node_https = __toESM(require("https"), 1);
2290
2287
  import_shared52 = require("@xeno-js/shared");
2291
2288
  import_axios = __toESM(require("axios"), 1);
2292
- NodeAxiosFactory = class extends import_shared52.AxiosFactory {
2289
+ NodeAxiosFactory = class {
2293
2290
  create(config) {
2294
2291
  const isKeepAlive = config.keepAlive ?? true;
2295
2292
  const maxSockets = config.maxSockets ?? 100;
@@ -2821,17 +2818,26 @@ var init_auth_utils = __esm({
2821
2818
  * @link https://github.com/xeno-js/xeno-js
2822
2819
  */
2823
2820
  async addAuthN(container, opts) {
2824
- const { TOKENS: TOKENS4 } = await import("@xeno-js/shared");
2825
- const _t = opts;
2826
- const { SupabaseServerAuthFactory: SupabaseServerAuthFactory2 } = await Promise.resolve().then(() => (init_factories(), factories_exports));
2827
- const factory = new SupabaseServerAuthFactory2();
2828
- const supabase = factory.create({ config: opts, container });
2829
- container.addScoped(TOKENS4.AUTH_SERVICE, () => {
2830
- return supabase;
2831
- });
2832
- container.addSingleton(TOKENS4.BASE_AUTH_SERVICE, () => {
2833
- return supabase;
2834
- });
2821
+ const { Guards: Guards46, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
2822
+ if (Guards46.isDefined(opts.customAuth)) {
2823
+ const authService = opts.customAuth.authExtendedService();
2824
+ container.addScoped(TOKENS4.AUTH_SERVICE, () => {
2825
+ return authService;
2826
+ });
2827
+ container.addSingleton(TOKENS4.BASE_AUTH_SERVICE, () => {
2828
+ return authService;
2829
+ });
2830
+ } else {
2831
+ const { SupabaseServerAuthFactory: SupabaseServerAuthFactory2 } = await Promise.resolve().then(() => (init_factories(), factories_exports));
2832
+ const factory = new SupabaseServerAuthFactory2();
2833
+ const supabase = factory.create({ config: opts, container });
2834
+ container.addScoped(TOKENS4.AUTH_SERVICE, () => {
2835
+ return supabase;
2836
+ });
2837
+ container.addSingleton(TOKENS4.BASE_AUTH_SERVICE, () => {
2838
+ return supabase;
2839
+ });
2840
+ }
2835
2841
  }
2836
2842
  });
2837
2843
  }
@@ -3426,6 +3432,7 @@ var init_base_controller = __esm({
3426
3432
  /**
3427
3433
  * Helper to send a query through the mediator and return the result.
3428
3434
  * @param request - The IQuery instance to be sent.
3435
+ * @param signal - The AbortSignal
3429
3436
  * @returns A promise resolving to the result of the query.
3430
3437
  *
3431
3438
  * @author Xeno
@@ -3433,13 +3440,13 @@ var init_base_controller = __esm({
3433
3440
  * @since 2025-09-30
3434
3441
  * @link https://github.com/xeno-js/xeno-js
3435
3442
  */
3436
- _query(request) {
3437
- const signal = new AbortController().signal;
3443
+ _query(request, signal) {
3438
3444
  return this._mediator.query(request, signal);
3439
3445
  }
3440
3446
  /**
3441
3447
  * Helper to send a command through the mediator and return the result.
3442
3448
  * @param request - The ICommand instance to be sent.
3449
+ * @param signal - The AbortSignal
3443
3450
  * @returns A promise resolving to the result of the command.
3444
3451
  *
3445
3452
  * @author Xeno
@@ -3447,8 +3454,7 @@ var init_base_controller = __esm({
3447
3454
  * @since 2025-09-30
3448
3455
  * @link https://github.com/xeno-js/xeno-js
3449
3456
  */
3450
- _send(request) {
3451
- const signal = new AbortController().signal;
3457
+ _send(request, signal) {
3452
3458
  return this._mediator.send(request, signal);
3453
3459
  }
3454
3460
  getContext() {
@@ -3479,7 +3485,7 @@ var init_allow_method_middleware = __esm({
3479
3485
  }
3480
3486
  _requestContext;
3481
3487
  _allowMethod;
3482
- async execute(req, _headers, next) {
3488
+ async execute(req, _res, next) {
3483
3489
  const isAllowed = this._allowMethod.check(req.path, req.method);
3484
3490
  if (!isAllowed) {
3485
3491
  const { network, tracing } = this._requestContext.getContext() ?? {};
@@ -3524,7 +3530,7 @@ var init_allow_origin_middleware = __esm({
3524
3530
  _allowOrigin;
3525
3531
  _requestContext;
3526
3532
  _logger;
3527
- async execute(req, _headers, next) {
3533
+ async execute(req, _res, next) {
3528
3534
  const { network, tracing } = this._requestContext.getContext() ?? {};
3529
3535
  const origin = network?.origin;
3530
3536
  if (!this._allowOrigin.isAllowed(origin)) {
@@ -3569,8 +3575,8 @@ var init_auth_middleware = __esm({
3569
3575
  _tokenExtractor;
3570
3576
  _gateKeeper;
3571
3577
  _logger;
3572
- async execute(req, headers, next) {
3573
- const token = this._tokenExtractor.extract(headers);
3578
+ async execute(req, _res, next) {
3579
+ const token = this._tokenExtractor.extract(req.headers);
3574
3580
  const authResult = await this._gateKeeper.authenticate(token);
3575
3581
  if (!authResult.isOk()) {
3576
3582
  const error = authResult.getErrorOrThrow();
@@ -3613,12 +3619,12 @@ var init_composite_middleware = __esm({
3613
3619
  this._middlewares = _middlewares;
3614
3620
  }
3615
3621
  _middlewares;
3616
- async execute(req, headers, next) {
3622
+ async execute(req, res, next) {
3617
3623
  let currentNext = next;
3618
3624
  for (let i = this._middlewares.length - 1; i >= 0; i--) {
3619
3625
  const currentBehavior = this._middlewares[i];
3620
3626
  const previousNext = currentNext;
3621
- currentNext = () => currentBehavior.execute(req, headers, previousNext);
3627
+ currentNext = () => currentBehavior.execute(req, res, previousNext);
3622
3628
  }
3623
3629
  return currentNext();
3624
3630
  }
@@ -3639,7 +3645,7 @@ var init_cors_middleware = __esm({
3639
3645
  }
3640
3646
  _requestContext;
3641
3647
  _withCredentials;
3642
- async execute(_req, _headers, next) {
3648
+ async execute(_req, _res, next) {
3643
3649
  const { network } = this._requestContext.getContext() ?? {};
3644
3650
  const origin = network?.origin;
3645
3651
  const response = await next();
@@ -3669,7 +3675,7 @@ var init_csrf_middleware = __esm({
3669
3675
  }
3670
3676
  _requestContext;
3671
3677
  _csrfTokenService;
3672
- async execute(req, _headers, next) {
3678
+ async execute(req, _res, next) {
3673
3679
  const method = req.method.toUpperCase();
3674
3680
  const isStateChanging = ["POST", "PUT", "DELETE", "PATCH"].includes(method);
3675
3681
  if (isStateChanging) {
@@ -3761,7 +3767,7 @@ var init_csrf_cookie_middleware = __esm({
3761
3767
  _requestContext;
3762
3768
  _csrfTokenService;
3763
3769
  _csrf;
3764
- async execute(_req, _headers, next) {
3770
+ async execute(_req, _res, next) {
3765
3771
  const response = await next();
3766
3772
  const context = this._requestContext.getContext();
3767
3773
  const identity = context?.identity;
@@ -3801,7 +3807,7 @@ var init_options_middleware = __esm({
3801
3807
  _alloewMethod;
3802
3808
  _allowHeaders;
3803
3809
  _withCredentials;
3804
- async execute(req, _headers, next) {
3810
+ async execute(req, _res, next) {
3805
3811
  if (req.method.toUpperCase() === "OPTIONS") {
3806
3812
  const network = this._requestContext.getNetworkContext();
3807
3813
  const origin = network?.origin;
@@ -3840,7 +3846,7 @@ var init_rate_limiter_middleware = __esm({
3840
3846
  _keyBuilder;
3841
3847
  _logger;
3842
3848
  _opts;
3843
- async execute(req, _headers, next) {
3849
+ async execute(req, _res, next) {
3844
3850
  const cacheKey = this._keyBuilder.buildRateLimitKey(req.path);
3845
3851
  const { network, tracing } = this._ctxAccessor.getContext() ?? {};
3846
3852
  if (!import_shared69.Guards.isDefined(cacheKey))
@@ -3873,7 +3879,7 @@ var init_rate_limiter_middleware = __esm({
3873
3879
  error: {
3874
3880
  code: import_shared69.ERROR_CODES.TOO_MANY_REQUESTS,
3875
3881
  message: import_shared69.ERROR_CODE_MESSAGES[import_shared69.ERROR_CODES.TOO_MANY_REQUESTS],
3876
- details: `Rate limit exceeded. Key ${cacheKey} throttled.`,
3882
+ details: `Rate limit exceeded.`,
3877
3883
  path: req.path
3878
3884
  },
3879
3885
  correlationId: tracing?.correlationId ?? import_shared69.GuidHelper.generate(),
@@ -3981,14 +3987,14 @@ var init_request_middleware = __esm({
3981
3987
  _extractor;
3982
3988
  _resolver;
3983
3989
  _logger;
3984
- async execute(req, headers, next) {
3990
+ async execute(req, res, next) {
3985
3991
  const correlationId = import_shared71.GuidHelper.generate();
3986
3992
  const requestId = import_shared71.GuidHelper.generate();
3987
3993
  const spanId = correlationId;
3988
3994
  const formatIndicator = "application/json";
3989
3995
  try {
3990
- const meta = this._extractor.extract(headers);
3991
- const clientIp = this._resolver.resolve(req.transport.req, meta.clientIp);
3996
+ const meta = this._extractor.extract(req.headers);
3997
+ const clientIp = this._resolver.resolve(req, meta.clientIp);
3992
3998
  const metadata = {
3993
3999
  ...meta,
3994
4000
  clientIp,
@@ -4001,7 +4007,7 @@ var init_request_middleware = __esm({
4001
4007
  metadata,
4002
4008
  identity: import_shared71.GUEST,
4003
4009
  path: req.path,
4004
- transport: req.transport
4010
+ transport: { req, res }
4005
4011
  });
4006
4012
  const result = await this._requestContext.runAsync(tmpContext, async () => {
4007
4013
  return next();
@@ -4132,7 +4138,11 @@ var init_middleware_module = __esm({
4132
4138
  const { Guards: Guards46, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
4133
4139
  const { HttpCookieExtractor: HttpCookieExtractor2 } = await Promise.resolve().then(() => (init_services(), services_exports));
4134
4140
  const { HttpHeaderExtractor: HttpHeaderExtractor2 } = await Promise.resolve().then(() => (init_services(), services_exports));
4135
- const tokenExtractor = await this._getTokenExtractor(opts.isSSR);
4141
+ const tokenExtractor = await this._getTokenExtractor(
4142
+ opts.isSSR,
4143
+ opts.authCookieName,
4144
+ opts.customTokenExtractor
4145
+ );
4136
4146
  container.addSingleton(
4137
4147
  TOKENS4.SERVICE_EXTRACTOR,
4138
4148
  () => new HttpHeaderExtractor2(
@@ -4251,13 +4261,15 @@ var init_middleware_module = __esm({
4251
4261
  return new CompositeMiddleware2(middlewares);
4252
4262
  });
4253
4263
  }
4254
- async _getTokenExtractor(isSSR) {
4264
+ async _getTokenExtractor(isSSR, cookieName, customTokenExtractor) {
4265
+ const { Guards: Guards46 } = await import("@xeno-js/shared");
4266
+ if (Guards46.isDefined(customTokenExtractor)) return customTokenExtractor();
4255
4267
  if (isSSR) {
4256
4268
  const { SupabaseSsrTokenExtractor: SupabaseSsrTokenExtractor2 } = await Promise.resolve().then(() => (init_services(), services_exports));
4257
4269
  return new SupabaseSsrTokenExtractor2();
4258
4270
  } else {
4259
4271
  const { BearerTokenExtractor: BearerTokenExtractor2 } = await Promise.resolve().then(() => (init_services(), services_exports));
4260
- return new BearerTokenExtractor2();
4272
+ return new BearerTokenExtractor2(cookieName ?? "sb-access-token");
4261
4273
  }
4262
4274
  }
4263
4275
  async _getAllowMethod(configure, opts) {
@@ -4642,7 +4654,17 @@ var AppBuilder = class {
4642
4654
  allowOrigins: [],
4643
4655
  allowHeaders: [],
4644
4656
  cors: true,
4645
- withCredentials: true
4657
+ withCredentials: true,
4658
+ authCookieName: "sb-access-token"
4659
+ };
4660
+ _authConfig = {
4661
+ url: "",
4662
+ key: "",
4663
+ opts: void 0,
4664
+ redirectTo: "",
4665
+ storageOpts: { type: "memory", cookieOpts: void 0, storage: void 0 },
4666
+ ssrOpts: void 0,
4667
+ customAuth: void 0
4646
4668
  };
4647
4669
  _httpConfig = {
4648
4670
  dataSourceToken: void 0,
@@ -4773,21 +4795,13 @@ var AppBuilder = class {
4773
4795
  addAuth(setupAction) {
4774
4796
  if (this._isAuthModuleQueued) return this;
4775
4797
  this._isAuthModuleQueued = true;
4776
- const config = {
4777
- url: "",
4778
- key: "",
4779
- opts: void 0,
4780
- redirectTo: "",
4781
- storageOpts: { type: "memory", cookieOpts: void 0, storage: void 0 },
4782
- ssrOpts: void 0
4783
- };
4784
- setupAction(config, this._configuration);
4798
+ setupAction(this._authConfig, this._configuration);
4785
4799
  this._modules.push({
4786
4800
  priority: 3,
4787
4801
  name: "AuthModule",
4788
4802
  action: async () => {
4789
4803
  const { AuthUtils: AuthUtils2 } = await Promise.resolve().then(() => (init_auth_utils(), auth_utils_exports));
4790
- await AuthUtils2.addAuthN(this._container, config);
4804
+ await AuthUtils2.addAuthN(this._container, this._authConfig);
4791
4805
  }
4792
4806
  });
4793
4807
  return this;
@@ -5039,7 +5053,8 @@ var AppBuilder = class {
5039
5053
  const middlewareModule = new MiddlewareModule2();
5040
5054
  await middlewareModule.configure(this._container, {
5041
5055
  ...this._middlewareConfig,
5042
- isAuth: this._isAuthModuleQueued
5056
+ isAuth: this._isAuthModuleQueued,
5057
+ customTokenExtractor: this._authConfig.customAuth?.authHeaderExtractor
5043
5058
  });
5044
5059
  }
5045
5060
  });