@niledatabase/server 5.0.0-alpha.26 → 5.0.0-alpha.28

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.js CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var async_hooks = require('async_hooks');
3
4
  require('dotenv/config');
4
5
  var pg = require('pg');
5
6
 
@@ -12,6 +13,7 @@ var ExtensionState = /* @__PURE__ */ ((ExtensionState2) => {
12
13
  ExtensionState2["onHandleRequest"] = "onHandleRequest";
13
14
  ExtensionState2["onRequest"] = "onRequest";
14
15
  ExtensionState2["onResponse"] = "onResponse";
16
+ ExtensionState2["withContext"] = "withContext";
15
17
  return ExtensionState2;
16
18
  })(ExtensionState || {});
17
19
  var APIErrorErrorCodeEnum = {
@@ -69,21 +71,18 @@ var appRoutes = (prefix = DEFAULT_PREFIX) => ({
69
71
  INVITE: `${prefix}${"/tenants/{tenantId}/invite" /* INVITE */}`,
70
72
  LOG: `${prefix}/_log`
71
73
  });
72
- var apiRoutes = (config) => ({
73
- ME: makeRestUrl(config, "/me"),
74
- USERS: (qp) => makeRestUrl(config, "/users", qp),
75
- USER: (userId) => makeRestUrl(config, `/users/${userId}`),
76
- TENANTS: makeRestUrl(config, "/tenants"),
77
- TENANT: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}`),
78
- SIGNUP: makeRestUrl(config, "/signup"),
79
- TENANT_USERS: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}/users`),
80
- INVITES: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}/invites`),
81
- INVITE: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}/invite`),
82
- TENANT_USER: makeRestUrl(
83
- config,
84
- `/tenants/${config.tenantId}/users/${config.userId}`
85
- ),
86
- USER_TENANTS: (userId) => makeRestUrl(config, `/users/${userId}/tenants`)
74
+ var apiRoutes = (apiUrl) => ({
75
+ ME: makeRestUrl(apiUrl, "/me"),
76
+ USERS: (qp) => makeRestUrl(apiUrl, "/users", qp),
77
+ USER: (userId) => makeRestUrl(apiUrl, `/users/${userId}`),
78
+ TENANTS: makeRestUrl(apiUrl, "/tenants"),
79
+ TENANT: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}`),
80
+ SIGNUP: makeRestUrl(apiUrl, "/signup"),
81
+ TENANT_USERS: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/users`),
82
+ INVITES: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/invites`),
83
+ INVITE: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/invite`),
84
+ TENANT_USER: (tenantId, userId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/users/${userId}`),
85
+ USER_TENANTS: (userId) => makeRestUrl(apiUrl, `/users/${userId}/tenants`)
87
86
  });
88
87
  var proxyRoutes = (config) => ({
89
88
  SIGNIN: makeRestUrl(config, "/auth/signin" /* SIGNIN */),
@@ -107,8 +106,8 @@ function filterNullUndefined(obj) {
107
106
  )
108
107
  );
109
108
  }
110
- function makeRestUrl(config, path, qp) {
111
- const url = config.apiUrl || NILEDB_API_URL;
109
+ function makeRestUrl(apiUrl, path, qp) {
110
+ const url = apiUrl || NILEDB_API_URL;
112
111
  if (!url) {
113
112
  throw new Error(
114
113
  "An API url is required. Set it via NILEDB_API_URL. Was auto configuration run?"
@@ -265,10 +264,309 @@ async function auth(req, config) {
265
264
  }
266
265
  }
267
266
 
267
+ // src/utils/Logger.ts
268
+ var red = "\x1B[31m";
269
+ var yellow = "\x1B[38;2;255;255;0m";
270
+ var purple = "\x1B[38;2;200;160;255m";
271
+ var orange = "\x1B[38;2;255;165;0m";
272
+ var reset = "\x1B[0m";
273
+ var baseLogger = (config, ...params) => ({
274
+ silly(message, meta) {
275
+ if (config?.debug && process.env.LOG_LEVEL === "silly") {
276
+ console.log(
277
+ `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
278
+ ""
279
+ )}${reset} ${message}`,
280
+ meta ? `${JSON.stringify(meta)}` : ""
281
+ );
282
+ }
283
+ },
284
+ info(message, meta) {
285
+ if (config?.debug) {
286
+ console.info(
287
+ `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
288
+ ""
289
+ )}${reset} ${message}`,
290
+ meta ? `${JSON.stringify(meta)}` : ""
291
+ );
292
+ }
293
+ },
294
+ debug(message, meta) {
295
+ if (config?.debug) {
296
+ console.log(
297
+ `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
298
+ ""
299
+ )}${reset} ${message}`,
300
+ meta ? `${JSON.stringify(meta)}` : ""
301
+ );
302
+ }
303
+ },
304
+ warn(message, meta) {
305
+ if (config?.debug) {
306
+ console.warn(
307
+ `${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
308
+ ""
309
+ )}${reset} ${message}`,
310
+ meta ? JSON.stringify(meta) : ""
311
+ );
312
+ }
313
+ },
314
+ error(message, meta) {
315
+ console.error(
316
+ `${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
317
+ ""
318
+ )}${red} ${message}`,
319
+ meta ? meta : "",
320
+ `${reset}`
321
+ );
322
+ }
323
+ });
324
+ function Logger(config) {
325
+ return (prefixes) => {
326
+ const { info, debug, warn: warn2, error, silly: silly2 } = config && typeof config?.logger === "function" ? config.logger(prefixes) : baseLogger(config, prefixes);
327
+ return {
328
+ info,
329
+ debug,
330
+ warn: warn2,
331
+ error,
332
+ silly: silly2
333
+ };
334
+ };
335
+ }
336
+ function matchesLog(configRoutes, request2) {
337
+ return urlMatches(request2.url, configRoutes.LOG);
338
+ }
339
+
340
+ // src/api/utils/extensions.ts
341
+ function getRequestConfig(params) {
342
+ if (typeof params[1] === "object") {
343
+ return params[1];
344
+ }
345
+ return {};
346
+ }
347
+ function bindRunExtensions(instance) {
348
+ return async function runExtensions(toRun, config, params, _init) {
349
+ const { debug } = config.logger("[EXTENSIONS]");
350
+ const extensionConfig = getRequestConfig(
351
+ Array.isArray(params) ? params : [null, params]
352
+ );
353
+ if (config.extensions) {
354
+ for (const create2 of config.extensions) {
355
+ if (typeof create2 !== "function") {
356
+ continue;
357
+ }
358
+ const ext = create2(instance);
359
+ if (extensionConfig.disableExtensions?.includes(ext.id)) {
360
+ continue;
361
+ }
362
+ if (ext.withContext && toRun === "withContext" /* withContext */) {
363
+ await ext.withContext(ctx);
364
+ }
365
+ if (ext.onHandleRequest && toRun === "onHandleRequest" /* onHandleRequest */) {
366
+ const result = await ext.onHandleRequest(
367
+ Array.isArray(params) ? params : [params]
368
+ );
369
+ debug(`${ext.id ?? create2.name} ran onHandleRequest`);
370
+ if (result != null) {
371
+ return result;
372
+ }
373
+ }
374
+ const [param] = Array.isArray(params) ? params : [params];
375
+ if (ext.onRequest && toRun === "onRequest" /* onRequest */) {
376
+ const { ...previousContext } = ctx.get();
377
+ const preserveHeaders = previousContext.preserveHeaders;
378
+ if (preserveHeaders) {
379
+ ctx.set({ preserveHeaders: false });
380
+ }
381
+ if (!_init) {
382
+ continue;
383
+ }
384
+ const previousHeaders = new Headers(previousContext.headers);
385
+ await ext.onRequest(_init.request, ctx);
386
+ const updatedContext = ctx.get();
387
+ if (updatedContext?.headers) {
388
+ const cookie = updatedContext.headers.get("cookie");
389
+ if (cookie && param.headers) {
390
+ const updatedCookies = mergeCookies(
391
+ preserveHeaders ? previousHeaders?.get("cookie") : null,
392
+ updatedContext.headers.get("cookie")
393
+ );
394
+ param.headers.set("cookie", updatedCookies);
395
+ }
396
+ if (updatedContext.tenantId && param.headers) {
397
+ param.headers.set(
398
+ TENANT_COOKIE,
399
+ String(updatedContext.headers.get(TENANT_COOKIE))
400
+ );
401
+ }
402
+ ctx.set({ headers: param.headers });
403
+ }
404
+ debug(`${ext.id ?? create2.name} ran onRequest`);
405
+ }
406
+ if (ext.onResponse && toRun === "onResponse" /* onResponse */) {
407
+ const result = await ext.onResponse(param, ctx);
408
+ debug(`${ext.id ?? create2.name} ran onResponse`);
409
+ if (result != null) {
410
+ return result;
411
+ }
412
+ }
413
+ }
414
+ }
415
+ return void 0;
416
+ };
417
+ }
418
+ function buildExtensionConfig(instance) {
419
+ return {
420
+ runExtensions: bindRunExtensions(instance)
421
+ };
422
+ }
423
+ function mergeCookies(...cookieStrings) {
424
+ const cookieMap = /* @__PURE__ */ new Map();
425
+ for (const str of cookieStrings) {
426
+ if (!str) continue;
427
+ for (const part of str.split(";")) {
428
+ const [key17, value] = part.split("=").map((s) => s.trim());
429
+ if (key17 && value) cookieMap.set(key17, value);
430
+ }
431
+ }
432
+ return [...cookieMap.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
433
+ }
434
+ async function runExtensionContext(config) {
435
+ await config?.extensionCtx?.runExtensions("withContext" /* withContext */, config);
436
+ }
437
+
438
+ // src/api/utils/request-context.ts
439
+ var { warn, silly } = Logger({ debug: true })("[REQUEST CONTEXT]");
440
+ var storage = new async_hooks.AsyncLocalStorage();
441
+ var defaultContext = {
442
+ headers: new Headers(),
443
+ tenantId: void 0,
444
+ userId: void 0,
445
+ preserveHeaders: false
446
+ };
447
+ var lastUsedContext = defaultContext;
448
+ var ctx = {
449
+ run(ctx2, fn) {
450
+ const merged = {
451
+ ...defaultContext,
452
+ ...ctx2,
453
+ headers: ctx2.headers instanceof Headers ? ctx2.headers : new Headers(ctx2.headers)
454
+ };
455
+ lastUsedContext = merged;
456
+ return storage.run(merged, fn);
457
+ },
458
+ get: () => {
459
+ const ctx2 = storage.getStore();
460
+ if (!ctx2) {
461
+ return { ...defaultContext };
462
+ }
463
+ silly(`[GET] ${serializeContext(ctx2)}`);
464
+ return ctx2;
465
+ },
466
+ /**
467
+ * This is a mirror of Server.getContext, but only for requests. We keep only the request
468
+ * information around, everything else is :above_my_pay_grade:
469
+ * @param partial A partial context to override
470
+ */
471
+ set: (partial) => {
472
+ const store = storage.getStore();
473
+ if (!store) {
474
+ warn("ctx.set() called outside of ctx.run(). This will not persist.");
475
+ return;
476
+ }
477
+ if (partial.headers === null) {
478
+ store.headers = new Headers();
479
+ } else if (partial.headers && store.headers instanceof Headers) {
480
+ for (const [key17, value] of new Headers(partial.headers).entries()) {
481
+ if (key17.toLowerCase() === "cookie") {
482
+ const existingCookies = parseCookieHeader(
483
+ store.headers.get("cookie") || ""
484
+ );
485
+ const newCookies = parseCookieHeader(value);
486
+ const mergedCookies = { ...existingCookies, ...newCookies };
487
+ store.headers.set("cookie", serializeCookies(mergedCookies));
488
+ } else {
489
+ store.headers.set(key17, value);
490
+ }
491
+ }
492
+ }
493
+ if ("tenantId" in partial)
494
+ store.tenantId = partial.tenantId ?? store.tenantId;
495
+ if ("userId" in partial) store.userId = partial.userId ?? store.userId;
496
+ if ("preserveHeaders" in partial)
497
+ store.preserveHeaders = Boolean(partial.preserveHeaders);
498
+ silly(`[SET] ${serializeContext(store)}`);
499
+ lastUsedContext = { ...store };
500
+ },
501
+ // for convenience only
502
+ getLastUsed: () => lastUsedContext
503
+ };
504
+ function withNileContext(config, fn, name = "unknown") {
505
+ const initialContext = config.context;
506
+ const existing = ctx.get();
507
+ const mergedHeaders = new Headers(existing.headers);
508
+ if (initialContext instanceof Request) {
509
+ initialContext.headers.forEach((value, key17) => {
510
+ mergedHeaders.set(key17, value);
511
+ });
512
+ const context2 = {
513
+ headers: mergedHeaders,
514
+ tenantId: existing.tenantId,
515
+ userId: existing.userId,
516
+ preserveHeaders: existing.preserveHeaders ?? false
517
+ };
518
+ silly(`${name} [INITIAL - Request] ${serializeContext(context2)}`);
519
+ return ctx.run(context2, fn);
520
+ }
521
+ if (initialContext.headers) {
522
+ const incoming = initialContext.headers instanceof Headers ? initialContext.headers : new Headers(initialContext.headers);
523
+ incoming.forEach((value, key17) => {
524
+ mergedHeaders.set(key17, value);
525
+ });
526
+ }
527
+ const tenantId = "tenantId" in initialContext && initialContext.tenantId;
528
+ const userId = "userId" in initialContext && initialContext.userId;
529
+ const preserveHeaders = "preserveHeaders" in initialContext && initialContext.preserveHeaders;
530
+ const context = {
531
+ headers: mergedHeaders,
532
+ tenantId: tenantId ? tenantId : existing.tenantId,
533
+ userId: userId ? userId : existing.userId,
534
+ preserveHeaders: preserveHeaders ? preserveHeaders : existing.preserveHeaders ?? false
535
+ };
536
+ silly(`${name} [INITIAL - Partial<Context>] ${serializeContext(context)}`);
537
+ return ctx.run(context, async () => {
538
+ await runExtensionContext(config);
539
+ return fn();
540
+ });
541
+ }
542
+ function serializeContext(context) {
543
+ const headers = {};
544
+ const rawHeaders = new Headers(context.headers);
545
+ rawHeaders.forEach((value, key17) => {
546
+ headers[key17] = value;
547
+ });
548
+ return JSON.stringify({
549
+ headers,
550
+ tenantId: context.tenantId,
551
+ userId: context.userId,
552
+ preserveHeaders: context.preserveHeaders
553
+ });
554
+ }
555
+ function parseCookieHeader(header) {
556
+ return header.split(";").map((c) => c.trim()).filter(Boolean).reduce((acc, curr) => {
557
+ const [key17, ...val] = curr.split("=");
558
+ if (key17) acc[key17] = val.join("=");
559
+ return acc;
560
+ }, {});
561
+ }
562
+ function serializeCookies(cookies) {
563
+ return Object.entries(cookies).map(([k, v]) => `${k}=${v}`).join("; ");
564
+ }
565
+
268
566
  // src/api/routes/me/index.ts
269
567
  var key = "ME";
270
568
  async function route(request2, config) {
271
- const url = apiRoutes(config)[key];
569
+ const url = apiRoutes(config.apiUrl)[key];
272
570
  if (request2.method === "GET") {
273
571
  return await GET(url, { request: request2 }, config);
274
572
  }
@@ -289,8 +587,9 @@ function matches(configRoutes, request2) {
289
587
  }
290
588
  async function fetchMe(config, method, body) {
291
589
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/me" /* ME */}`;
590
+ const { headers } = ctx.get();
292
591
  const init = {
293
- headers: config.headers,
592
+ headers,
294
593
  method: method ?? "GET"
295
594
  };
296
595
  if (method === "PUT") {
@@ -342,9 +641,9 @@ function getTokenFromCookie(headers, cookieKey) {
342
641
  return _cookies[cookieKey];
343
642
  }
344
643
  }
345
- function getTenantFromHttp(headers, config) {
644
+ function getTenantFromHttp(headers, context) {
346
645
  const cookieTenant = getTokenFromCookie(headers, TENANT_COOKIE);
347
- return cookieTenant ? cookieTenant : config?.tenantId;
646
+ return cookieTenant ? cookieTenant : context?.tenantId;
348
647
  }
349
648
 
350
649
  // src/api/routes/users/POST.ts
@@ -354,8 +653,11 @@ async function POST(config, init) {
354
653
  const yurl = new URL(init.request.url);
355
654
  const tenantId = yurl.searchParams.get("tenantId");
356
655
  const newTenantName = yurl.searchParams.get("newTenantName");
357
- const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
358
- const url = apiRoutes(config).USERS({ tenantId: tenant, newTenantName });
656
+ const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
657
+ const url = apiRoutes(config.apiUrl).USERS({
658
+ tenantId: tenant,
659
+ newTenantName
660
+ });
359
661
  return await request(url, init, config);
360
662
  }
361
663
 
@@ -363,13 +665,13 @@ async function POST(config, init) {
363
665
  async function GET2(config, init, log) {
364
666
  const yurl = new URL(init.request.url);
365
667
  const tenantId = yurl.searchParams.get("tenantId");
366
- const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
668
+ const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config.context);
367
669
  if (!tenant) {
368
670
  log("[GET] No tenant id provided.");
369
671
  return new Response(null, { status: 404 });
370
672
  }
371
673
  init.method = "GET";
372
- const url = apiRoutes(config).TENANT_USERS(tenant);
674
+ const url = apiRoutes(config.apiUrl).TENANT_USERS(tenant);
373
675
  return await request(url, init, config);
374
676
  }
375
677
 
@@ -378,7 +680,7 @@ async function PUT2(config, init) {
378
680
  init.body = init.request.body;
379
681
  init.method = "PUT";
380
682
  const [userId] = new URL(init.request.url).pathname.split("/").reverse();
381
- const url = apiRoutes(config).USER(userId);
683
+ const url = apiRoutes(config.apiUrl).USER(userId);
382
684
  return await request(url, init, config);
383
685
  }
384
686
 
@@ -405,7 +707,7 @@ function matches2(configRoutes, request2) {
405
707
  async function GET3(config, init) {
406
708
  const yurl = new URL(init.request.url);
407
709
  const [, tenantId] = yurl.pathname.split("/").reverse();
408
- const url = `${apiRoutes(config).TENANT_USERS(tenantId)}`;
710
+ const url = `${apiRoutes(config.apiUrl).TENANT_USERS(tenantId)}`;
409
711
  return await request(url, init, config);
410
712
  }
411
713
 
@@ -419,7 +721,7 @@ async function POST2(config, init) {
419
721
  const [, tenantId] = yurl.pathname.split("/").reverse();
420
722
  init.body = JSON.stringify({ email: session.email });
421
723
  init.method = "POST";
422
- const url = apiRoutes(config).TENANT_USERS(tenantId);
724
+ const url = apiRoutes(config.apiUrl).TENANT_USERS(tenantId);
423
725
  return await request(url, init, config);
424
726
  }
425
727
 
@@ -453,12 +755,13 @@ function matches3(configRoutes, request2) {
453
755
  }
454
756
  async function fetchTenantUsers(config, method, payload) {
455
757
  const { body, params } = {};
456
- if (!config.tenantId) {
758
+ const { tenantId, headers } = ctx.get();
759
+ if (!tenantId) {
457
760
  throw new Error(
458
761
  "Unable to fetch the user's tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
459
762
  );
460
763
  }
461
- if (!isUUID(config.tenantId)) {
764
+ if (!isUUID(tenantId)) {
462
765
  config.logger("fetchTenantUsers").warn(
463
766
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
464
767
  );
@@ -470,14 +773,11 @@ async function fetchTenantUsers(config, method, payload) {
470
773
  if (params?.tenantId) {
471
774
  q.set("tenantId", params.tenantId);
472
775
  }
473
- const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
474
- "{tenantId}",
475
- config.tenantId
476
- )}`;
776
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace("{tenantId}", tenantId)}`;
477
777
  const m = method;
478
778
  const init = {
479
779
  method: m,
480
- headers: config.headers
780
+ headers
481
781
  };
482
782
  const req = new Request(clientUrl, init);
483
783
  return await config.handlers[m](req);
@@ -494,7 +794,7 @@ async function PUT3(config, init) {
494
794
  init.body = new URLSearchParams(yurl.searchParams).toString();
495
795
  }
496
796
  init.method = "PUT";
497
- const url = `${apiRoutes(config).INVITE(tenantId)}`;
797
+ const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
498
798
  const res = await request(url, init, config);
499
799
  const location = res?.headers?.get("location");
500
800
  if (location) {
@@ -518,7 +818,7 @@ async function POST3(config, init) {
518
818
  }
519
819
  init.method = "POST";
520
820
  init.body = init.request.body;
521
- const url = `${apiRoutes(config).INVITE(tenantId)}`;
821
+ const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
522
822
  return await request(url, init, config);
523
823
  }
524
824
 
@@ -544,21 +844,22 @@ function matches4(configRoutes, request2) {
544
844
  return urlMatches(request2.url, route20);
545
845
  }
546
846
  async function fetchInvite(config, method, body) {
547
- if (!config.tenantId) {
847
+ const { headers, tenantId } = ctx.get();
848
+ if (!tenantId) {
548
849
  throw new Error(
549
850
  "Unable to fetch the invite for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
550
851
  );
551
852
  }
552
- if (!isUUID(config.tenantId)) {
853
+ if (!isUUID(tenantId)) {
553
854
  config.logger("fetchInvite").warn(
554
855
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
555
856
  );
556
857
  }
557
- let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", config.tenantId)}`;
858
+ let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", tenantId)}`;
558
859
  const m = method ?? "GET";
559
860
  const init = {
560
861
  method: m,
561
- headers: config.headers
862
+ headers
562
863
  };
563
864
  if (method === "POST" || method === "PUT") {
564
865
  init.body = body;
@@ -578,7 +879,7 @@ async function GET4(config, init) {
578
879
  return new Response(null, { status: 404 });
579
880
  }
580
881
  init.method = "GET";
581
- const url = `${apiRoutes(config).INVITES(tenantId)}`;
882
+ const url = `${apiRoutes(config.apiUrl).INVITES(tenantId)}`;
582
883
  return await request(url, init, config);
583
884
  }
584
885
 
@@ -599,29 +900,29 @@ function matches5(configRoutes, request2) {
599
900
  return url.pathname.endsWith(route20);
600
901
  }
601
902
  async function fetchInvites(config) {
602
- if (!config.tenantId) {
903
+ const { tenantId, headers } = ctx.get();
904
+ if (!tenantId) {
603
905
  throw new Error(
604
906
  "Unable to fetch invites for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
605
907
  );
606
908
  }
607
- if (!isUUID(config.tenantId)) {
909
+ if (!isUUID(tenantId)) {
608
910
  config.logger("fetchInvites").warn(
609
911
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
610
912
  );
611
913
  }
612
- const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}", config.tenantId)}`;
613
- const req = new Request(clientUrl, { headers: config.headers });
914
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}", tenantId)}`;
915
+ const req = new Request(clientUrl, { headers });
614
916
  return await config.handlers.GET(req);
615
917
  }
616
918
 
617
919
  // src/api/routes/tenants/GET.ts
618
920
  async function GET5(config, session, init) {
619
- let url = `${apiRoutes(config).USER_TENANTS(session.id)}`;
921
+ let url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.id)}`;
620
922
  if (typeof session === "object" && "user" in session && session.user) {
621
- url = `${apiRoutes(config).USER_TENANTS(session.user.id)}`;
923
+ url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.user.id)}`;
622
924
  }
623
- const res = await request(url, init, config);
624
- return res;
925
+ return await request(url, init, config);
625
926
  }
626
927
 
627
928
  // src/api/routes/tenants/[tenantId]/GET.ts
@@ -633,7 +934,7 @@ async function GET6(config, init, log) {
633
934
  return new Response(null, { status: 404 });
634
935
  }
635
936
  init.method = "GET";
636
- const url = `${apiRoutes(config).TENANT(tenantId)}`;
937
+ const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
637
938
  return await request(url, init, config);
638
939
  }
639
940
 
@@ -645,7 +946,7 @@ async function DELETE2(config, init) {
645
946
  return new Response(null, { status: 404 });
646
947
  }
647
948
  init.method = "DELETE";
648
- const url = `${apiRoutes(config).TENANT(tenantId)}`;
949
+ const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
649
950
  return await request(url, init, config);
650
951
  }
651
952
 
@@ -658,7 +959,7 @@ async function PUT4(config, init) {
658
959
  }
659
960
  init.body = init.request.body;
660
961
  init.method = "PUT";
661
- const url = `${apiRoutes(config).TENANT(tenantId)}`;
962
+ const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
662
963
  return await request(url, init, config);
663
964
  }
664
965
 
@@ -666,7 +967,7 @@ async function PUT4(config, init) {
666
967
  async function POST4(config, init) {
667
968
  init.body = init.request.body;
668
969
  init.method = "POST";
669
- const url = `${apiRoutes(config).TENANTS}`;
970
+ const url = `${apiRoutes(config.apiUrl).TENANTS}`;
670
971
  return await request(url, init, config);
671
972
  }
672
973
 
@@ -700,10 +1001,11 @@ function matches6(configRoutes, request2) {
700
1001
  return urlMatches(request2.url, configRoutes[key6]);
701
1002
  }
702
1003
  async function fetchTenants(config, method, body) {
1004
+ const { headers } = ctx.get();
703
1005
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
704
1006
  const init = {
705
1007
  method,
706
- headers: config.headers
1008
+ headers
707
1009
  };
708
1010
  {
709
1011
  init.body = body;
@@ -712,21 +1014,22 @@ async function fetchTenants(config, method, body) {
712
1014
  return await config.handlers.POST(req);
713
1015
  }
714
1016
  async function fetchTenant(config, method, body) {
715
- if (!config.tenantId) {
1017
+ const { headers, tenantId } = ctx.get();
1018
+ if (!tenantId) {
716
1019
  throw new Error(
717
1020
  "Unable to fetch tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
718
1021
  );
719
1022
  }
720
- if (!isUUID(config.tenantId)) {
1023
+ if (!isUUID(tenantId)) {
721
1024
  config.logger("fetch tenant").warn(
722
1025
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
723
1026
  );
724
1027
  }
725
- const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", config.tenantId)}`;
1028
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", tenantId)}`;
726
1029
  const m = method ?? "GET";
727
1030
  const init = {
728
1031
  method: m,
729
- headers: config.headers
1032
+ headers
730
1033
  };
731
1034
  if (m === "PUT") {
732
1035
  init.body = body;
@@ -735,32 +1038,33 @@ async function fetchTenant(config, method, body) {
735
1038
  return await config.handlers[m](req);
736
1039
  }
737
1040
  async function fetchTenantsByUser(config) {
738
- const { warn } = config.logger("fetchTenantsByUser");
739
- if (!config.userId) {
740
- warn(
1041
+ const { warn: warn2 } = config.logger(" fetchTenantsByUser ");
1042
+ const { userId, headers } = ctx.get();
1043
+ if (!userId) {
1044
+ warn2(
741
1045
  "nile.userId is not set. The call will still work for the API, but the database context is not set properly and may lead to unexpected behavior in your application."
742
1046
  );
743
- } else if (!isUUID(config.userId)) {
744
- warn(
1047
+ } else if (!isUUID(userId)) {
1048
+ warn2(
745
1049
  "nile.userId is not a valid UUID. This may lead to unexpected behavior in your application."
746
1050
  );
747
1051
  }
748
1052
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
749
- const req = new Request(clientUrl, { headers: config.headers });
1053
+ const req = new Request(clientUrl, { headers });
750
1054
  return await config.handlers.GET(req);
751
1055
  }
752
1056
 
753
1057
  // src/api/routes/auth/signin.ts
754
1058
  var key7 = "SIGNIN";
755
1059
  async function route7(req, config) {
756
- let url = proxyRoutes(config)[key7];
1060
+ let url = proxyRoutes(config.apiUrl)[key7];
757
1061
  const init = {
758
1062
  method: req.method,
759
1063
  headers: req.headers
760
1064
  };
761
1065
  if (req.method === "POST") {
762
1066
  const [provider] = new URL(req.url).pathname.split("/").reverse();
763
- url = `${proxyRoutes(config)[key7]}/${provider}`;
1067
+ url = `${proxyRoutes(config.apiUrl)[key7]}/${provider}`;
764
1068
  }
765
1069
  const passThroughUrl = new URL(req.url);
766
1070
  const params = new URLSearchParams(passThroughUrl.search);
@@ -773,10 +1077,11 @@ function matches7(configRoutes, request2) {
773
1077
  }
774
1078
  async function fetchSignIn(config, provider, body) {
775
1079
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
1080
+ const { headers } = ctx.get();
776
1081
  const req = new Request(clientUrl, {
777
1082
  method: "POST",
778
- headers: config.headers,
779
- body
1083
+ body,
1084
+ headers
780
1085
  });
781
1086
  return await config.handlers.POST(req);
782
1087
  }
@@ -784,7 +1089,7 @@ async function fetchSignIn(config, provider, body) {
784
1089
  // src/api/routes/auth/session.ts
785
1090
  async function route8(req, config) {
786
1091
  return request(
787
- proxyRoutes(config).SESSION,
1092
+ proxyRoutes(config.apiUrl).SESSION,
788
1093
  {
789
1094
  method: req.method,
790
1095
  request: req
@@ -797,9 +1102,10 @@ function matches8(configRoutes, request2) {
797
1102
  }
798
1103
  async function fetchSession(config) {
799
1104
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
1105
+ const { headers } = ctx.get();
800
1106
  const req = new Request(clientUrl, {
801
1107
  method: "GET",
802
- headers: config.headers
1108
+ headers
803
1109
  });
804
1110
  return await config.handlers.GET(req);
805
1111
  }
@@ -807,7 +1113,7 @@ async function fetchSession(config) {
807
1113
  // src/api/routes/auth/providers.ts
808
1114
  async function route9(req, config) {
809
1115
  return request(
810
- proxyRoutes(config).PROVIDERS,
1116
+ proxyRoutes(config.apiUrl).PROVIDERS,
811
1117
  {
812
1118
  method: req.method,
813
1119
  request: req
@@ -820,9 +1126,10 @@ function matches9(configRoutes, request2) {
820
1126
  }
821
1127
  async function fetchProviders(config) {
822
1128
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
1129
+ const { headers } = ctx.get();
823
1130
  const req = new Request(clientUrl, {
824
1131
  method: "GET",
825
- headers: config.headers
1132
+ headers
826
1133
  });
827
1134
  return await config.handlers.GET(req);
828
1135
  }
@@ -830,7 +1137,7 @@ async function fetchProviders(config) {
830
1137
  // src/api/routes/auth/csrf.ts
831
1138
  async function route10(req, config) {
832
1139
  return request(
833
- proxyRoutes(config).CSRF,
1140
+ proxyRoutes(config.apiUrl).CSRF,
834
1141
  {
835
1142
  method: req.method,
836
1143
  request: req
@@ -843,9 +1150,10 @@ function matches10(configRoutes, request2) {
843
1150
  }
844
1151
  async function fetchCsrf(config) {
845
1152
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
1153
+ const { headers } = ctx.get();
846
1154
  const req = new Request(clientUrl, {
847
1155
  method: "GET",
848
- headers: config.headers
1156
+ headers
849
1157
  });
850
1158
  return await config.handlers.GET(req);
851
1159
  }
@@ -858,7 +1166,7 @@ async function route11(req, config) {
858
1166
  try {
859
1167
  const passThroughUrl = new URL(req.url);
860
1168
  const params = new URLSearchParams(passThroughUrl.search);
861
- const url = `${proxyRoutes(config)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
1169
+ const url = `${proxyRoutes(config.apiUrl)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
862
1170
  const res = await request(
863
1171
  url,
864
1172
  {
@@ -889,10 +1197,11 @@ function matches11(configRoutes, request2) {
889
1197
  return urlMatches(request2.url, configRoutes.CALLBACK);
890
1198
  }
891
1199
  async function fetchCallback(config, provider, body, request2, method = "POST") {
1200
+ const { headers } = ctx.get();
892
1201
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}${request2 ? `?${new URL(request2.url).searchParams}` : ""}`;
893
1202
  const req = new Request(clientUrl, {
894
1203
  method,
895
- headers: config.headers,
1204
+ headers,
896
1205
  body
897
1206
  });
898
1207
  return await config.handlers.POST(req);
@@ -901,14 +1210,14 @@ async function fetchCallback(config, provider, body, request2, method = "POST")
901
1210
  // src/api/routes/auth/signout.ts
902
1211
  var key9 = "SIGNOUT";
903
1212
  async function route12(request2, config) {
904
- let url = proxyRoutes(config)[key9];
1213
+ let url = proxyRoutes(config.apiUrl)[key9];
905
1214
  const init = {
906
1215
  method: request2.method
907
1216
  };
908
1217
  if (request2.method === "POST") {
909
1218
  init.body = request2.body;
910
1219
  const [provider] = new URL(request2.url).pathname.split("/").reverse();
911
- url = `${proxyRoutes(config)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
1220
+ url = `${proxyRoutes(config.apiUrl)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
912
1221
  }
913
1222
  const res = await request(url, { ...init, request: request2 }, config);
914
1223
  return res;
@@ -918,10 +1227,11 @@ function matches12(configRoutes, request2) {
918
1227
  }
919
1228
  async function fetchSignOut(config, body) {
920
1229
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
1230
+ const { headers } = ctx.get();
921
1231
  const req = new Request(clientUrl, {
922
1232
  method: "POST",
923
1233
  body,
924
- headers: config.headers
1234
+ headers
925
1235
  });
926
1236
  return await config.handlers.POST(req);
927
1237
  }
@@ -930,7 +1240,7 @@ async function fetchSignOut(config, body) {
930
1240
  var key10 = "ERROR";
931
1241
  async function route13(req, config) {
932
1242
  return request(
933
- proxyRoutes(config)[key10],
1243
+ proxyRoutes(config.apiUrl)[key10],
934
1244
  {
935
1245
  method: req.method,
936
1246
  request: req
@@ -946,7 +1256,7 @@ function matches13(configRoutes, request2) {
946
1256
  var key11 = "VERIFY_REQUEST";
947
1257
  async function route14(req, config) {
948
1258
  return request(
949
- proxyRoutes(config)[key11],
1259
+ proxyRoutes(config.apiUrl)[key11],
950
1260
  {
951
1261
  method: req.method,
952
1262
  request: req
@@ -961,7 +1271,7 @@ function matches14(configRoutes, request2) {
961
1271
  // src/api/routes/auth/password-reset.ts
962
1272
  var key12 = "PASSWORD_RESET";
963
1273
  async function route15(req, config) {
964
- const url = proxyRoutes(config)[key12];
1274
+ const url = proxyRoutes(config.apiUrl)[key12];
965
1275
  const res = await request(
966
1276
  url,
967
1277
  {
@@ -990,10 +1300,11 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
990
1300
  if (useJson) {
991
1301
  authParams?.set("json", "true");
992
1302
  }
1303
+ const { headers } = ctx.get();
993
1304
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}?${authParams?.toString()}`;
994
1305
  const init = {
995
1306
  method,
996
- headers: config.headers
1307
+ headers
997
1308
  };
998
1309
  if (body && method !== "GET") {
999
1310
  init.body = body;
@@ -1005,7 +1316,7 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
1005
1316
  // src/api/routes/auth/verify-email.ts
1006
1317
  var key13 = "VERIFY_EMAIL";
1007
1318
  async function route16(req, config) {
1008
- const url = proxyRoutes(config)[key13];
1319
+ const url = proxyRoutes(config.apiUrl)[key13];
1009
1320
  const res = await request(
1010
1321
  url,
1011
1322
  {
@@ -1031,9 +1342,10 @@ function matches16(configRoutes, request2) {
1031
1342
  }
1032
1343
  async function fetchVerifyEmail(config, method, body) {
1033
1344
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`;
1345
+ const { headers } = ctx.get();
1034
1346
  const init = {
1035
1347
  method,
1036
- headers: config.headers
1348
+ headers
1037
1349
  };
1038
1350
  if (body) {
1039
1351
  init.body = body;
@@ -1044,7 +1356,7 @@ async function fetchVerifyEmail(config, method, body) {
1044
1356
 
1045
1357
  // src/api/handlers/GET.ts
1046
1358
  function GETTER(configRoutes, config) {
1047
- const { error, info, warn } = config.logger("[GET MATCHER]");
1359
+ const { error, info, warn: warn2 } = config.logger("[GET MATCHER]");
1048
1360
  return async function GET7(...params) {
1049
1361
  const handledRequest = await config.extensionCtx?.runExtensions(
1050
1362
  "onHandleRequest" /* onHandleRequest */,
@@ -1123,78 +1435,16 @@ function GETTER(configRoutes, config) {
1123
1435
  info("matches error");
1124
1436
  return route13(req, config);
1125
1437
  }
1126
- warn(`No GET routes matched ${req.url}`);
1438
+ warn2(`No GET routes matched ${req.url}`);
1127
1439
  return new Response(null, { status: 404 });
1128
1440
  };
1129
1441
  }
1130
1442
 
1131
- // src/utils/Logger.ts
1132
- var red = "\x1B[31m";
1133
- var yellow = "\x1B[38;2;255;255;0m";
1134
- var purple = "\x1B[38;2;200;160;255m";
1135
- var orange = "\x1B[38;2;255;165;0m";
1136
- var reset = "\x1B[0m";
1137
- var baseLogger = (config, ...params) => ({
1138
- info(message, meta) {
1139
- if (config?.debug) {
1140
- console.info(
1141
- `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
1142
- ""
1143
- )}${reset} ${message}`,
1144
- meta ? `${JSON.stringify(meta)}` : ""
1145
- );
1146
- }
1147
- },
1148
- debug(message, meta) {
1149
- if (config?.debug) {
1150
- console.info(
1151
- `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
1152
- ""
1153
- )}${reset} ${message}`,
1154
- meta ? `${JSON.stringify(meta)}` : ""
1155
- );
1156
- }
1157
- },
1158
- warn(message, meta) {
1159
- if (config?.debug) {
1160
- console.warn(
1161
- `${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
1162
- ""
1163
- )}${reset} ${message}`,
1164
- meta ? JSON.stringify(meta) : ""
1165
- );
1166
- }
1167
- },
1168
- error(message, meta) {
1169
- console.error(
1170
- `${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
1171
- ""
1172
- )}${red} ${message}`,
1173
- meta ? meta : "",
1174
- `${reset}`
1175
- );
1176
- }
1177
- });
1178
- function Logger(config) {
1179
- return (prefixes) => {
1180
- const { info, debug, warn, error } = config && typeof config?.logger === "function" ? config.logger(prefixes) : baseLogger(config, prefixes);
1181
- return {
1182
- info,
1183
- debug,
1184
- warn,
1185
- error
1186
- };
1187
- };
1188
- }
1189
- function matchesLog(configRoutes, request2) {
1190
- return urlMatches(request2.url, configRoutes.LOG);
1191
- }
1192
-
1193
1443
  // src/api/routes/signup/POST.ts
1194
1444
  async function POST5(config, init) {
1195
1445
  init.body = init.request.body;
1196
1446
  init.method = "POST";
1197
- const url = `${apiRoutes(config).SIGNUP}`;
1447
+ const url = `${apiRoutes(config.apiUrl).SIGNUP}`;
1198
1448
  return await request(url, init, config);
1199
1449
  }
1200
1450
 
@@ -1221,9 +1471,10 @@ async function fetchSignUp(config, payload) {
1221
1471
  q.set("tenantId", params.tenantId);
1222
1472
  }
1223
1473
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
1474
+ const { headers } = ctx.get();
1224
1475
  const req = new Request(clientUrl, {
1225
1476
  method: "POST",
1226
- headers: config.headers,
1477
+ headers,
1227
1478
  body
1228
1479
  });
1229
1480
  return await config.handlers.POST(req);
@@ -1231,7 +1482,7 @@ async function fetchSignUp(config, payload) {
1231
1482
 
1232
1483
  // src/api/handlers/POST.ts
1233
1484
  function POSTER(configRoutes, config) {
1234
- const { info, warn, error } = config.logger("[POST MATCHER]");
1485
+ const { info, warn: warn2, error } = config.logger("[POST MATCHER]");
1235
1486
  return async function POST6(...params) {
1236
1487
  const handledRequest = await config.extensionCtx?.runExtensions(
1237
1488
  "onHandleRequest" /* onHandleRequest */,
@@ -1267,10 +1518,6 @@ function POSTER(configRoutes, config) {
1267
1518
  info("matches signup");
1268
1519
  return route17(req, config);
1269
1520
  }
1270
- if (matches2(configRoutes, req)) {
1271
- info("matches users");
1272
- return route2(req, config);
1273
- }
1274
1521
  if (matches6(configRoutes, req)) {
1275
1522
  info("matches tenants");
1276
1523
  return route6(req, config);
@@ -1307,7 +1554,7 @@ function POSTER(configRoutes, config) {
1307
1554
  info("matches verify-email");
1308
1555
  return route16(req, config);
1309
1556
  }
1310
- warn(`No POST routes matched ${req.url}`);
1557
+ warn2(`No POST routes matched ${req.url}`);
1311
1558
  return new Response(null, { status: 404 });
1312
1559
  };
1313
1560
  }
@@ -1316,10 +1563,8 @@ function POSTER(configRoutes, config) {
1316
1563
  async function DELETE3(config, init) {
1317
1564
  const yurl = new URL(init.request.url);
1318
1565
  const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
1319
- config.tenantId = tenantId;
1320
- config.userId = userId;
1321
1566
  init.method = "DELETE";
1322
- const url = `${apiRoutes(config).TENANT_USER}/link`;
1567
+ const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
1323
1568
  return await request(url, init, config);
1324
1569
  }
1325
1570
 
@@ -1327,10 +1572,8 @@ async function DELETE3(config, init) {
1327
1572
  async function PUT5(config, init) {
1328
1573
  const yurl = new URL(init.request.url);
1329
1574
  const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
1330
- config.tenantId = tenantId;
1331
- config.userId = userId;
1332
1575
  init.method = "PUT";
1333
- const url = `${apiRoutes(config).TENANT_USER}/link`;
1576
+ const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
1334
1577
  return await request(url, init, config);
1335
1578
  }
1336
1579
 
@@ -1368,22 +1611,24 @@ function matches18(configRoutes, request2) {
1368
1611
  return urlMatches(request2.url, route20);
1369
1612
  }
1370
1613
  async function fetchTenantUser(config, method) {
1371
- if (!config.tenantId) {
1614
+ const { headers, tenantId, userId } = ctx.get();
1615
+ const action = method === "PUT" ? "add" : "delete";
1616
+ if (!tenantId) {
1372
1617
  throw new Error(
1373
- "The tenantId context is missing. Call nile.setContext({ tenantId })"
1618
+ `Unable to ${action} user to the tenant, the tenantId context is missing. Use nile.withContext({ tenantId })`
1374
1619
  );
1375
1620
  }
1376
- if (!config.userId) {
1621
+ if (!userId) {
1377
1622
  throw new Error(
1378
- "the userId context is missing. Call nile.setContext({ userId })"
1623
+ `Unable to ${action} user to tenant. The userId context is missing. Use nile.withContext({ userId })`
1379
1624
  );
1380
1625
  }
1381
- const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
1382
- "{tenantId}",
1383
- config.tenantId
1384
- ).replace("{userId}", config.userId)}/link`;
1626
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace("{tenantId}", tenantId).replace(
1627
+ "{userId}",
1628
+ userId
1629
+ )}/link`;
1385
1630
  const req = new Request(clientUrl, {
1386
- headers: config.headers,
1631
+ headers,
1387
1632
  method
1388
1633
  });
1389
1634
  return await config.handlers[method](req);
@@ -1397,7 +1642,7 @@ async function DELETE4(config, init) {
1397
1642
  return new Response(null, { status: 404 });
1398
1643
  }
1399
1644
  init.method = "DELETE";
1400
- const url = `${apiRoutes(config).INVITE(tenantId)}/${inviteId}`;
1645
+ const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}/${inviteId}`;
1401
1646
  return await request(url, init, config);
1402
1647
  }
1403
1648
 
@@ -1420,7 +1665,7 @@ function matches19(configRoutes, request2) {
1420
1665
 
1421
1666
  // src/api/handlers/DELETE.ts
1422
1667
  function DELETER(configRoutes, config) {
1423
- const { error, info, warn } = config.logger("[DELETE MATCHER]");
1668
+ const { error, info, warn: warn2 } = config.logger("[DELETE MATCHER]");
1424
1669
  return async function DELETE5(...params) {
1425
1670
  const handledRequest = await config.extensionCtx?.runExtensions(
1426
1671
  "onHandleRequest" /* onHandleRequest */,
@@ -1451,14 +1696,14 @@ function DELETER(configRoutes, config) {
1451
1696
  info("matches me");
1452
1697
  return route(req, config);
1453
1698
  }
1454
- warn("No DELETE routes matched");
1699
+ warn2("No DELETE routes matched");
1455
1700
  return new Response(null, { status: 404 });
1456
1701
  };
1457
1702
  }
1458
1703
 
1459
1704
  // src/api/handlers/PUT.ts
1460
1705
  function PUTER(configRoutes, config) {
1461
- const { error, info, warn } = config.logger("[PUT MATCHER]");
1706
+ const { error, info, warn: warn2 } = config.logger("[PUT MATCHER]");
1462
1707
  return async function PUT6(...params) {
1463
1708
  const handledRequest = await config.extensionCtx?.runExtensions(
1464
1709
  "onHandleRequest" /* onHandleRequest */,
@@ -1485,10 +1730,6 @@ function PUTER(configRoutes, config) {
1485
1730
  info("matches tenant users");
1486
1731
  return route3(req, config);
1487
1732
  }
1488
- if (matches2(configRoutes, req)) {
1489
- info("matches users");
1490
- return route2(req, config);
1491
- }
1492
1733
  if (matches(configRoutes, req)) {
1493
1734
  info("matches me");
1494
1735
  return route(req, config);
@@ -1501,7 +1742,7 @@ function PUTER(configRoutes, config) {
1501
1742
  info("matches reset password");
1502
1743
  return route15(req, config);
1503
1744
  }
1504
- warn("No PUT routes matched");
1745
+ warn2("No PUT routes matched");
1505
1746
  return new Response(null, { status: 404 });
1506
1747
  };
1507
1748
  }
@@ -1705,18 +1946,7 @@ var Config = class {
1705
1946
  extensionCtx;
1706
1947
  extensions;
1707
1948
  logger;
1708
- /**
1709
- * Stores the set tenant id from Server for use in sub classes
1710
- */
1711
- tenantId;
1712
- /**
1713
- * Stores the set user id from Server for use in sub classes
1714
- */
1715
- userId;
1716
- /**
1717
- * Stores the headers to be used in `fetch` calls
1718
- */
1719
- headers;
1949
+ context;
1720
1950
  /**
1721
1951
  * The nile-auth url
1722
1952
  */
@@ -1767,11 +1997,12 @@ var Config = class {
1767
1997
  if (databaseName) {
1768
1998
  this.db.database = databaseName;
1769
1999
  }
1770
- if (config?.headers) {
1771
- this.headers = config?.headers;
1772
- } else {
1773
- this.headers = new Headers();
1774
- }
2000
+ this.context = {
2001
+ tenantId: config?.tenantId,
2002
+ userId: config?.userId,
2003
+ headers: config?.headers ? new Headers(config.headers) : new Headers(),
2004
+ preserveHeaders: false
2005
+ };
1775
2006
  this.routes = {
1776
2007
  ...appRoutes(config?.routePrefix),
1777
2008
  ...config?.routes
@@ -1814,8 +2045,6 @@ var Config = class {
1814
2045
  ],
1815
2046
  delete: [this.routes.TENANT_USER, this.routes.TENANT]
1816
2047
  };
1817
- this.tenantId = config?.tenantId;
1818
- this.userId = config?.userId;
1819
2048
  }
1820
2049
  };
1821
2050
 
@@ -1882,7 +2111,15 @@ function createProxyForPool(pool, config) {
1882
2111
  }
1883
2112
  const caller = target[property];
1884
2113
  return function query(...args) {
1885
- info("query", ...args);
2114
+ let log = "[QUERY]";
2115
+ const { userId, tenantId } = config.context;
2116
+ if (tenantId) {
2117
+ log = `${log}[TENANT:${tenantId}]`;
2118
+ }
2119
+ if (userId) {
2120
+ log = `${log}[USER:${userId}]`;
2121
+ }
2122
+ info(log, ...args);
1886
2123
  const called = caller.apply(this, args);
1887
2124
  return called;
1888
2125
  };
@@ -1901,7 +2138,7 @@ var NileDatabase = class {
1901
2138
  config;
1902
2139
  timer;
1903
2140
  constructor(config, id) {
1904
- const { warn, info, debug } = config.logger("[NileInstance]");
2141
+ const { warn: warn2, info, debug } = config.logger("[NileInstance]");
1905
2142
  this.id = id;
1906
2143
  const poolConfig = {
1907
2144
  min: 0,
@@ -1917,7 +2154,7 @@ var NileDatabase = class {
1917
2154
  debug(`Connection pool config ${JSON.stringify(cloned)}`);
1918
2155
  this.pool = createProxyForPool(new pg__default.default.Pool(remaining), this.config);
1919
2156
  if (typeof afterCreate === "function") {
1920
- warn(
2157
+ warn2(
1921
2158
  "Providing an pool configuration will stop automatic tenant context setting."
1922
2159
  );
1923
2160
  }
@@ -1983,7 +2220,7 @@ var NileDatabase = class {
1983
2220
  };
1984
2221
  var NileInstance_default = NileDatabase;
1985
2222
  function makeAfterCreate(config, id) {
1986
- const { error, warn, debug } = config.logger("[afterCreate]");
2223
+ const { error, warn: warn2, debug } = config.logger("[afterCreate]");
1987
2224
  return (conn, done) => {
1988
2225
  conn.on("error", function errorHandler(e) {
1989
2226
  error(`Connection ${id} was terminated by server`, {
@@ -1992,13 +2229,15 @@ function makeAfterCreate(config, id) {
1992
2229
  });
1993
2230
  done(e, conn);
1994
2231
  });
1995
- if (config.tenantId) {
1996
- const query = [`SET nile.tenant_id = '${config.tenantId}'`];
1997
- if (config.userId) {
1998
- if (!config.tenantId) {
1999
- warn("A user id cannot be set in context without a tenant id");
2232
+ const tenantId = config.context.tenantId;
2233
+ const userId = config.context.userId;
2234
+ if (tenantId) {
2235
+ const query = [`SET nile.tenant_id = '${tenantId}'`];
2236
+ if (userId) {
2237
+ if (!tenantId) {
2238
+ warn2("A user id cannot be set in context without a tenant id");
2000
2239
  }
2001
- query.push(`SET nile.user_id = '${config.userId}'`);
2240
+ query.push(`SET nile.user_id = '${userId}'`);
2002
2241
  }
2003
2242
  conn.query(query.join(";"), function(err) {
2004
2243
  if (err) {
@@ -2011,11 +2250,11 @@ function makeAfterCreate(config, id) {
2011
2250
  });
2012
2251
  } else {
2013
2252
  if (query.length === 1) {
2014
- debug(`connection context set: tenantId=${config.tenantId}`);
2253
+ debug(`connection context set: tenantId=${tenantId}`);
2015
2254
  }
2016
2255
  if (query.length === 2) {
2017
2256
  debug(
2018
- `connection context set: tenantId=${config.tenantId} userId=${config.userId}`
2257
+ `connection context set: tenantId=${tenantId} userId=${userId}`
2019
2258
  );
2020
2259
  }
2021
2260
  }
@@ -2047,19 +2286,19 @@ var DBManager = class {
2047
2286
  watchEvictPool(this.poolWatcherFn);
2048
2287
  }
2049
2288
  poolWatcher = (config) => (id) => {
2050
- const { info, warn } = Logger(config)("[DBManager]");
2289
+ const { info, warn: warn2 } = Logger(config)("[DBManager]");
2051
2290
  if (id && this.connections.has(id)) {
2052
2291
  info(`Removing ${id} from db connection pool.`);
2053
2292
  const connection = this.connections.get(id);
2054
2293
  connection?.shutdown();
2055
2294
  this.connections.delete(id);
2056
2295
  } else {
2057
- warn(`missed eviction of ${id}`);
2296
+ warn2(`missed eviction of ${id}`);
2058
2297
  }
2059
2298
  };
2060
2299
  getConnection = (config) => {
2061
2300
  const { info } = Logger(config)("[DBManager]");
2062
- const id = this.makeId(config.tenantId, config.userId);
2301
+ const id = this.makeId(config.context.tenantId, config.context.userId);
2063
2302
  const existing = this.connections.get(id);
2064
2303
  info(`# of instances: ${this.connections.size}`);
2065
2304
  if (existing) {
@@ -2067,7 +2306,7 @@ var DBManager = class {
2067
2306
  existing.startTimeout();
2068
2307
  return existing.pool;
2069
2308
  }
2070
- const newOne = new NileInstance_default(new Config(config), id);
2309
+ const newOne = new NileInstance_default(config, id);
2071
2310
  this.connections.set(id, newOne);
2072
2311
  info(`created new ${id}`);
2073
2312
  info(`# of instances: ${this.connections.size}`);
@@ -2102,33 +2341,39 @@ var Auth = class {
2102
2341
  this.#logger = config.logger("[auth]");
2103
2342
  }
2104
2343
  async getSession(rawResponse = false) {
2105
- const res = await fetchSession(this.#config);
2106
- if (rawResponse) {
2107
- return res;
2108
- }
2109
- try {
2110
- const session = await res.clone().json();
2111
- if (Object.keys(session).length === 0) {
2112
- return void 0;
2344
+ return withNileContext(this.#config, async () => {
2345
+ const res = await fetchSession(this.#config);
2346
+ if (rawResponse) {
2347
+ return res;
2113
2348
  }
2114
- return session;
2115
- } catch {
2116
- return res;
2117
- }
2349
+ try {
2350
+ const session = await res.clone().json();
2351
+ if (Object.keys(session).length === 0) {
2352
+ return void 0;
2353
+ }
2354
+ return session;
2355
+ } catch {
2356
+ return res;
2357
+ }
2358
+ });
2118
2359
  }
2119
2360
  async getCsrf(rawResponse = false) {
2120
- return await obtainCsrf(this.#config, rawResponse);
2361
+ return withNileContext(this.#config, async () => {
2362
+ return await obtainCsrf(this.#config, rawResponse);
2363
+ });
2121
2364
  }
2122
2365
  async listProviders(rawResponse = false) {
2123
- const res = await fetchProviders(this.#config);
2124
- if (rawResponse) {
2125
- return res;
2126
- }
2127
- try {
2128
- return await res.clone().json();
2129
- } catch {
2130
- return res;
2131
- }
2366
+ return withNileContext(this.#config, async () => {
2367
+ const res = await fetchProviders(this.#config);
2368
+ if (rawResponse) {
2369
+ return res;
2370
+ }
2371
+ try {
2372
+ return await res.clone().json();
2373
+ } catch {
2374
+ return res;
2375
+ }
2376
+ });
2132
2377
  }
2133
2378
  /**
2134
2379
  * Sign the current user out by calling `/api/auth/signout`.
@@ -2137,73 +2382,79 @@ var Auth = class {
2137
2382
  * from the internal configuration once the request completes.
2138
2383
  */
2139
2384
  async signOut() {
2140
- const csrfRes = await this.getCsrf();
2141
- if (!("csrfToken" in csrfRes)) {
2142
- throw new Error("Unable to obtain CSRF token. Sign out failed.");
2143
- }
2144
- const body = JSON.stringify({
2145
- csrfToken: csrfRes.csrfToken,
2146
- json: true
2385
+ return withNileContext(this.#config, async () => {
2386
+ const csrfRes = await this.getCsrf();
2387
+ if (!("csrfToken" in csrfRes)) {
2388
+ throw new Error("Unable to obtain CSRF token. Sign out failed.");
2389
+ }
2390
+ const body = JSON.stringify({
2391
+ csrfToken: csrfRes.csrfToken,
2392
+ json: true
2393
+ });
2394
+ const res = await fetchSignOut(this.#config, body);
2395
+ updateHeaders(new Headers({}));
2396
+ ctx.set({ headers: null });
2397
+ return res;
2147
2398
  });
2148
- const res = await fetchSignOut(this.#config, body);
2149
- updateHeaders(new Headers({}));
2150
- this.#config.headers = new Headers();
2151
- return res;
2152
2399
  }
2153
2400
  async signUp(payload, rawResponse) {
2154
- this.#config.headers = new Headers();
2155
- const { email, password, ...params } = payload;
2156
- if (!email || !password) {
2157
- throw new Error(
2158
- "Server side sign up requires a user email and password."
2159
- );
2160
- }
2161
- const providers = await this.listProviders();
2162
- const { credentials } = providers ?? {};
2163
- if (!credentials) {
2164
- throw new Error(
2165
- "Unable to obtain credential provider. Aborting server side sign up."
2166
- );
2167
- }
2168
- const csrf = await this.getCsrf();
2169
- let csrfToken;
2170
- if ("csrfToken" in csrf) {
2171
- csrfToken = csrf.csrfToken;
2172
- } else {
2173
- throw new Error("Unable to obtain parse CSRF. Request blocked.");
2174
- }
2175
- const body = JSON.stringify({
2176
- email,
2177
- password,
2178
- csrfToken,
2179
- callbackUrl: credentials.callbackUrl
2180
- });
2181
- const res = await fetchSignUp(this.#config, { body, params });
2182
- if (res.status > 299) {
2183
- this.#logger.error(await res.clone().text());
2184
- return void 0;
2185
- }
2186
- const token = parseToken(res.headers);
2187
- if (!token) {
2188
- throw new Error("Server side sign up failed. Session token not found");
2189
- }
2190
- this.#config.headers?.append("cookie", token);
2191
- updateHeaders(this.#config.headers);
2192
- if (rawResponse) {
2193
- return res;
2194
- }
2195
- try {
2196
- const json = await res.clone().json();
2197
- if (json && typeof json === "object" && "tenants" in json) {
2198
- const tenantId = json.tenants[0];
2199
- if (tenantId) {
2200
- updateTenantId(tenantId);
2401
+ return withNileContext(this.#config, async () => {
2402
+ ctx.set({ headers: null });
2403
+ const { email, password, ...params } = payload;
2404
+ if (!email || !password) {
2405
+ throw new Error(
2406
+ "Server side sign up requires a user email and password."
2407
+ );
2408
+ }
2409
+ const providers = await this.listProviders();
2410
+ const { credentials } = providers ?? {};
2411
+ if (!credentials) {
2412
+ throw new Error(
2413
+ "Unable to obtain credential provider. Aborting server side sign up."
2414
+ );
2415
+ }
2416
+ const csrf = await obtainCsrf(this.#config);
2417
+ let csrfToken;
2418
+ if ("csrfToken" in csrf) {
2419
+ csrfToken = csrf.csrfToken;
2420
+ } else {
2421
+ throw new Error("Unable to obtain parse CSRF. Request blocked.");
2422
+ }
2423
+ const body = JSON.stringify({
2424
+ email,
2425
+ password,
2426
+ csrfToken,
2427
+ callbackUrl: credentials.callbackUrl
2428
+ });
2429
+ const res = await fetchSignUp(this.#config, { body, params });
2430
+ if (res.status > 299) {
2431
+ this.#logger.error(await res.clone().text());
2432
+ return void 0;
2433
+ }
2434
+ const token = parseToken(res.headers);
2435
+ if (!token) {
2436
+ throw new Error("Server side sign up failed. Session token not found");
2437
+ }
2438
+ const { headers } = ctx.get();
2439
+ headers?.append("cookie", token);
2440
+ ctx.set({ headers });
2441
+ updateHeaders(headers);
2442
+ if (rawResponse) {
2443
+ return res;
2444
+ }
2445
+ try {
2446
+ const json = await res.clone().json();
2447
+ if (json && typeof json === "object" && "tenants" in json) {
2448
+ const tenantId = json.tenants[0];
2449
+ if (tenantId) {
2450
+ updateTenantId(tenantId);
2451
+ }
2201
2452
  }
2453
+ return json;
2454
+ } catch {
2455
+ return res;
2202
2456
  }
2203
- return json;
2204
- } catch {
2205
- return res;
2206
- }
2457
+ });
2207
2458
  }
2208
2459
  /**
2209
2460
  * Request a password reset email.
@@ -2213,34 +2464,34 @@ var Auth = class {
2213
2464
  * which is returned as a {@link Response} object.
2214
2465
  */
2215
2466
  async forgotPassword(req) {
2216
- let email = "";
2217
- const defaults = defaultCallbackUrl({
2218
- config: this.#config
2219
- });
2220
- let callbackUrl = defaults.callbackUrl;
2221
- let redirectUrl = defaults.redirectUrl;
2222
- if ("email" in req) {
2223
- email = req.email;
2224
- }
2225
- if ("callbackUrl" in req) {
2226
- callbackUrl = req.callbackUrl ? req.callbackUrl : null;
2227
- }
2228
- if ("redirectUrl" in req) {
2229
- redirectUrl = req.redirectUrl ? req.redirectUrl : null;
2230
- }
2231
- const body = JSON.stringify({
2232
- email,
2233
- redirectUrl,
2234
- callbackUrl
2467
+ return withNileContext(this.#config, async () => {
2468
+ let email = "";
2469
+ const defaults = defaultCallbackUrl(this.#config);
2470
+ let callbackUrl = defaults.callbackUrl;
2471
+ let redirectUrl = defaults.redirectUrl;
2472
+ if ("email" in req) {
2473
+ email = req.email;
2474
+ }
2475
+ if ("callbackUrl" in req) {
2476
+ callbackUrl = fQUrl(req.callbackUrl ?? "", this.#config);
2477
+ }
2478
+ if ("redirectUrl" in req) {
2479
+ redirectUrl = fQUrl(req.redirectUrl ?? "", this.#config);
2480
+ }
2481
+ const body = JSON.stringify({
2482
+ email,
2483
+ redirectUrl,
2484
+ callbackUrl
2485
+ });
2486
+ const data = await fetchResetPassword(
2487
+ this.#config,
2488
+ "POST",
2489
+ body,
2490
+ new URLSearchParams(),
2491
+ false
2492
+ );
2493
+ return data;
2235
2494
  });
2236
- const data = await fetchResetPassword(
2237
- this.#config,
2238
- "POST",
2239
- body,
2240
- new URLSearchParams(),
2241
- false
2242
- );
2243
- return data;
2244
2495
  }
2245
2496
  /**
2246
2497
  * Complete a password reset.
@@ -2253,93 +2504,98 @@ var Auth = class {
2253
2504
  * containing the necessary fields.
2254
2505
  */
2255
2506
  async resetPassword(req) {
2256
- let email = "";
2257
- let password = "";
2258
- const defaults = defaultCallbackUrl({ config: this.#config });
2259
- let callbackUrl = defaults.callbackUrl;
2260
- let redirectUrl = defaults.redirectUrl;
2261
- if (req instanceof Request) {
2262
- const body2 = await req.json();
2263
- email = body2.email;
2264
- password = body2.password;
2265
- const cbFromHeaders = parseCallback(req.headers);
2266
- if (cbFromHeaders) {
2267
- callbackUrl = cbFromHeaders;
2268
- }
2269
- if (body2.callbackUrl) {
2270
- callbackUrl = body2.callbackUrl;
2271
- }
2272
- if (body2.redirectUrl) {
2273
- redirectUrl = body2.redirectUrl;
2507
+ return withNileContext(this.#config, async () => {
2508
+ let email = "";
2509
+ let password = "";
2510
+ const defaults = defaultCallbackUrl(this.#config);
2511
+ let callbackUrl = defaults.callbackUrl;
2512
+ let redirectUrl = defaults.redirectUrl;
2513
+ if (req instanceof Request) {
2514
+ const body2 = await req.json();
2515
+ email = body2.email;
2516
+ password = body2.password;
2517
+ const cbFromHeaders = parseCallback(req.headers);
2518
+ if (cbFromHeaders) {
2519
+ callbackUrl = cbFromHeaders;
2520
+ }
2521
+ if (body2.callbackUrl) {
2522
+ callbackUrl = body2.callbackUrl;
2523
+ }
2524
+ if (body2.redirectUrl) {
2525
+ redirectUrl = body2.redirectUrl;
2526
+ }
2527
+ } else {
2528
+ if ("email" in req) {
2529
+ email = req.email;
2530
+ }
2531
+ if ("password" in req) {
2532
+ password = req.password;
2533
+ }
2534
+ if ("callbackUrl" in req) {
2535
+ callbackUrl = req.callbackUrl ? req.callbackUrl : null;
2536
+ }
2537
+ if ("redirectUrl" in req) {
2538
+ redirectUrl = req.redirectUrl ? req.redirectUrl : null;
2539
+ }
2274
2540
  }
2275
- } else {
2276
- if ("email" in req) {
2277
- email = req.email;
2541
+ await this.getCsrf();
2542
+ const body = JSON.stringify({
2543
+ email,
2544
+ password,
2545
+ redirectUrl,
2546
+ callbackUrl
2547
+ });
2548
+ let urlWithParams;
2549
+ try {
2550
+ const data = await fetchResetPassword(this.#config, "POST", body);
2551
+ const cloned = data.clone();
2552
+ if (data.status === 400) {
2553
+ const text = await cloned.text();
2554
+ this.#logger.error(text);
2555
+ return data;
2556
+ }
2557
+ const { url } = await data.json();
2558
+ urlWithParams = url;
2559
+ } catch {
2278
2560
  }
2279
- if ("password" in req) {
2280
- password = req.password;
2561
+ let token;
2562
+ try {
2563
+ const worthyParams = new URL(urlWithParams).searchParams;
2564
+ const answer = await fetchResetPassword(
2565
+ this.#config,
2566
+ "GET",
2567
+ null,
2568
+ worthyParams
2569
+ );
2570
+ token = parseResetToken(answer.headers);
2571
+ } catch {
2572
+ this.#logger.warn(
2573
+ "Unable to parse reset password url. Password not reset."
2574
+ );
2281
2575
  }
2282
- if ("callbackUrl" in req) {
2283
- callbackUrl = req.callbackUrl ? req.callbackUrl : null;
2576
+ const { headers } = ctx.get();
2577
+ const cookie = headers?.get("cookie")?.split("; ");
2578
+ if (token) {
2579
+ cookie?.push(token);
2580
+ } else {
2581
+ throw new Error(
2582
+ "Unable to reset password, reset token is missing from response"
2583
+ );
2284
2584
  }
2285
- if ("redirectUrl" in req) {
2286
- redirectUrl = req.redirectUrl ? req.redirectUrl : null;
2585
+ if (cookie) {
2586
+ headers?.set("cookie", cookie?.join("; "));
2587
+ ctx.set({
2588
+ headers
2589
+ });
2287
2590
  }
2288
- }
2289
- await this.getCsrf();
2290
- const body = JSON.stringify({
2291
- email,
2292
- password,
2293
- redirectUrl,
2294
- callbackUrl
2295
- });
2296
- let urlWithParams;
2297
- try {
2298
- const data = await fetchResetPassword(this.#config, "POST", body);
2299
- const cloned = data.clone();
2300
- if (data.status === 400) {
2301
- const text = await cloned.text();
2302
- this.#logger.error(text);
2303
- return data;
2304
- }
2305
- const { url } = await data.json();
2306
- urlWithParams = url;
2307
- } catch {
2308
- }
2309
- let token;
2310
- try {
2311
- const worthyParams = new URL(urlWithParams).searchParams;
2312
- const answer = await fetchResetPassword(
2313
- this.#config,
2314
- "GET",
2315
- null,
2316
- worthyParams
2317
- );
2318
- token = parseResetToken(answer.headers);
2319
- } catch {
2320
- this.#logger.warn(
2321
- "Unable to parse reset password url. Password not reset."
2322
- );
2323
- }
2324
- const cookie = this.#config.headers.get("cookie")?.split("; ");
2325
- if (token) {
2326
- cookie?.push(token);
2327
- } else {
2328
- throw new Error(
2329
- "Unable to reset password, reset token is missing from response"
2330
- );
2331
- }
2332
- this.#config.headers = new Headers({
2333
- ...this.#config.headers,
2334
- cookie: cookie?.join("; ")
2591
+ const res = await fetchResetPassword(this.#config, "PUT", body);
2592
+ cookie?.pop();
2593
+ const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
2594
+ cleaned.push(String(parseToken(res.headers)));
2595
+ const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
2596
+ updateHeaders(updatedHeaders);
2597
+ return res;
2335
2598
  });
2336
- const res = await fetchResetPassword(this.#config, "PUT", body);
2337
- cookie?.pop();
2338
- const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
2339
- cleaned.push(String(parseToken(res.headers)));
2340
- const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
2341
- updateHeaders(updatedHeaders);
2342
- return res;
2343
2599
  }
2344
2600
  /**
2345
2601
  * Low level helper used by {@link signIn} to complete provider flows.
@@ -2349,7 +2605,9 @@ var Auth = class {
2349
2605
  */
2350
2606
  async callback(provider, body) {
2351
2607
  if (body instanceof Request) {
2352
- this.#config.headers = body.headers;
2608
+ ctx.set({
2609
+ headers: body.headers
2610
+ });
2353
2611
  return await fetchCallback(
2354
2612
  this.#config,
2355
2613
  provider,
@@ -2361,112 +2619,115 @@ var Auth = class {
2361
2619
  return await fetchCallback(this.#config, provider, body);
2362
2620
  }
2363
2621
  async signIn(provider, payload, rawResponse) {
2364
- if (payload instanceof Request) {
2365
- const body2 = new URLSearchParams(await payload.text());
2366
- const origin = new URL(payload.url).origin;
2367
- const payloadUrl = body2?.get("callbackUrl");
2368
- const csrfToken2 = body2?.get("csrfToken");
2369
- const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
2370
- if (!csrfToken2) {
2622
+ return withNileContext(this.#config, async () => {
2623
+ if (payload instanceof Request) {
2624
+ const body2 = new URLSearchParams(await payload.text());
2625
+ const origin = new URL(payload.url).origin;
2626
+ const payloadUrl = body2?.get("callbackUrl");
2627
+ const csrfToken2 = body2?.get("csrfToken");
2628
+ const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
2629
+ if (!csrfToken2) {
2630
+ throw new Error(
2631
+ "CSRF token in missing from request. Request it by the client before calling sign in"
2632
+ );
2633
+ }
2634
+ const updatedHeaders = new Headers(payload.headers);
2635
+ updatedHeaders.set("Content-Type", "application/x-www-form-urlencoded");
2636
+ ctx.set({ headers: updatedHeaders });
2637
+ const params = new URLSearchParams({
2638
+ csrfToken: csrfToken2,
2639
+ json: String(true)
2640
+ });
2641
+ if (payloadUrl) {
2642
+ params.set("callbackUrl", callbackUrl);
2643
+ }
2644
+ return await fetchSignIn(this.#config, provider, params);
2645
+ }
2646
+ ctx.set({ headers: null });
2647
+ const { info, error } = this.#logger;
2648
+ const providers = await this.listProviders();
2649
+ info("Obtaining csrf");
2650
+ const csrf = await obtainCsrf(this.#config);
2651
+ let csrfToken;
2652
+ if ("csrfToken" in csrf) {
2653
+ csrfToken = csrf.csrfToken;
2654
+ } else {
2655
+ throw new Error("Unable to obtain parse CSRF. Request blocked.");
2656
+ }
2657
+ const { credentials } = providers ?? {};
2658
+ if (!credentials) {
2371
2659
  throw new Error(
2372
- "CSRF token in missing from request. Request it by the client before calling sign in"
2660
+ "Unable to obtain credential provider. Aborting server side sign in."
2373
2661
  );
2374
2662
  }
2375
- this.#config.headers = new Headers(payload.headers);
2376
- this.#config.headers.set(
2377
- "Content-Type",
2378
- "application/x-www-form-urlencoded"
2379
- );
2380
- const params = new URLSearchParams({
2381
- csrfToken: csrfToken2,
2382
- json: String(true)
2663
+ const { email, password } = payload ?? {};
2664
+ if (provider === "email" && (!email || !password)) {
2665
+ throw new Error(
2666
+ "Server side sign in requires a user email and password."
2667
+ );
2668
+ }
2669
+ info(`Obtaining providers for ${email}`);
2670
+ info(`Attempting sign in with email ${email}`);
2671
+ if (!email) {
2672
+ throw new Error("Email missing from payload, unable to sign in");
2673
+ }
2674
+ const body = JSON.stringify({
2675
+ email,
2676
+ password,
2677
+ csrfToken,
2678
+ callbackUrl: credentials.callbackUrl
2383
2679
  });
2384
- if (payloadUrl) {
2385
- params.set("callbackUrl", callbackUrl);
2386
- }
2387
- return await fetchSignIn(this.#config, provider, params);
2388
- }
2389
- this.#config.headers = new Headers();
2390
- const { info, error } = this.#logger;
2391
- const providers = await this.listProviders();
2392
- info("Obtaining csrf");
2393
- const csrf = await this.getCsrf();
2394
- let csrfToken;
2395
- if ("csrfToken" in csrf) {
2396
- csrfToken = csrf.csrfToken;
2397
- } else {
2398
- throw new Error("Unable to obtain parse CSRF. Request blocked.");
2399
- }
2400
- const { credentials } = providers ?? {};
2401
- if (!credentials) {
2402
- throw new Error(
2403
- "Unable to obtain credential provider. Aborting server side sign in."
2404
- );
2405
- }
2406
- const { email, password } = payload ?? {};
2407
- if (provider === "email" && (!email || !password)) {
2408
- throw new Error(
2409
- "Server side sign in requires a user email and password."
2410
- );
2411
- }
2412
- info(`Obtaining providers for ${email}`);
2413
- info(`Attempting sign in with email ${email}`);
2414
- if (!email) {
2415
- throw new Error("Email missing from payload, unable to sign in");
2416
- }
2417
- const body = JSON.stringify({
2418
- email,
2419
- password,
2420
- csrfToken,
2421
- callbackUrl: credentials.callbackUrl
2422
- });
2423
- const signInRes = await this.callback(provider, body);
2424
- const authCookie = signInRes?.headers.get("set-cookie");
2425
- if (!authCookie) {
2426
- throw new Error("authentication failed");
2427
- }
2428
- const token = parseToken(signInRes?.headers);
2429
- const possibleError = signInRes?.headers.get("location");
2430
- if (possibleError) {
2431
- let urlError;
2680
+ const signInRes = await this.callback(provider, body);
2681
+ const authCookie = signInRes?.headers.get("set-cookie");
2682
+ if (!authCookie) {
2683
+ throw new Error("authentication failed");
2684
+ }
2685
+ const token = parseToken(signInRes?.headers);
2686
+ const possibleError = signInRes?.headers.get("location");
2687
+ if (possibleError) {
2688
+ let urlError;
2689
+ try {
2690
+ urlError = new URL(possibleError).searchParams.get("error");
2691
+ } catch {
2692
+ }
2693
+ if (urlError) {
2694
+ error("Unable to log user in", { error: urlError });
2695
+ return new Response(urlError, { status: signInRes.status });
2696
+ }
2697
+ }
2698
+ if (!token) {
2699
+ error("Unable to obtain auth token", {
2700
+ authCookie,
2701
+ signInRes
2702
+ });
2703
+ throw new Error("Server login failed");
2704
+ }
2705
+ info("Server sign in successful", { authCookie });
2706
+ const setCookie = signInRes.headers.get("set-cookie");
2707
+ const { headers } = ctx.get();
2708
+ if (setCookie) {
2709
+ const cookie = [
2710
+ parseCSRF(headers),
2711
+ parseCallback(signInRes.headers),
2712
+ parseToken(signInRes.headers)
2713
+ ].filter(Boolean).join("; ");
2714
+ const uHeaders = new Headers({ cookie });
2715
+ updateHeaders(uHeaders);
2716
+ ctx.set({ headers: uHeaders, preserveHeaders: true });
2717
+ } else {
2718
+ error("Unable to set context after sign in", {
2719
+ headers: signInRes.headers
2720
+ });
2721
+ }
2722
+ if (rawResponse) {
2723
+ return signInRes;
2724
+ }
2432
2725
  try {
2433
- urlError = new URL(possibleError).searchParams.get("error");
2726
+ return await signInRes.clone().json();
2434
2727
  } catch {
2728
+ return signInRes;
2435
2729
  }
2436
- if (urlError) {
2437
- error("Unable to log user in", { error: urlError });
2438
- return new Response(urlError, { status: signInRes.status });
2439
- }
2440
- }
2441
- if (!token) {
2442
- error("Unable to obtain auth token", {
2443
- authCookie,
2444
- signInRes
2445
- });
2446
- throw new Error("Server login failed");
2447
- }
2448
- info("Server sign in successful", { authCookie });
2449
- const setCookie = signInRes.headers.get("set-cookie");
2450
- if (setCookie) {
2451
- const cookie = [
2452
- parseCSRF(this.#config.headers),
2453
- parseCallback(signInRes.headers),
2454
- parseToken(signInRes.headers)
2455
- ].filter(Boolean).join("; ");
2456
- updateHeaders(new Headers({ cookie }));
2457
- } else {
2458
- error("Unable to set context after sign in", {
2459
- headers: signInRes.headers
2460
- });
2461
- }
2462
- if (rawResponse) {
2463
- return signInRes;
2464
- }
2465
- try {
2466
- return await signInRes.clone().json();
2467
- } catch {
2468
- return signInRes;
2469
- }
2730
+ });
2470
2731
  }
2471
2732
  };
2472
2733
  function parseCSRF(headers) {
@@ -2513,25 +2774,56 @@ function parseResetToken(headers) {
2513
2774
  const [, token] = /((__Secure-)?nile\.reset=[^;]+)/.exec(authCookie) ?? [];
2514
2775
  return token;
2515
2776
  }
2516
- function defaultCallbackUrl({ config }) {
2777
+ function parseTenantId(headers) {
2778
+ let authCookie = headers?.get("set-cookie");
2779
+ if (!authCookie) {
2780
+ authCookie = headers?.get("cookie");
2781
+ }
2782
+ if (!authCookie) {
2783
+ return void 0;
2784
+ }
2785
+ const [, token] = /((__Secure-)?nile\.tenant-id=[^;]+)/.exec(authCookie) ?? [];
2786
+ if (token) {
2787
+ const [, tenantId] = token.split("=");
2788
+ return tenantId;
2789
+ }
2790
+ return null;
2791
+ }
2792
+ function defaultCallbackUrl(config) {
2517
2793
  let cb = null;
2518
2794
  let redirect = null;
2519
- const fallbackCb = parseCallback(config.headers);
2795
+ const { headers } = ctx.get();
2796
+ const fallbackCb = parseCallback(headers);
2520
2797
  if (fallbackCb) {
2521
2798
  const [, value] = fallbackCb.split("=");
2522
2799
  cb = decodeURIComponent(value);
2523
2800
  if (value) {
2524
- redirect = `${new URL(cb).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
2801
+ redirect = `${new URL(cb).origin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}`;
2525
2802
  }
2526
2803
  }
2527
2804
  return { callbackUrl: cb, redirectUrl: redirect };
2528
2805
  }
2806
+ function fQUrl(path, config) {
2807
+ if (path.startsWith("/")) {
2808
+ const { callbackUrl } = defaultCallbackUrl(config);
2809
+ if (callbackUrl) {
2810
+ const { origin } = new URL(callbackUrl);
2811
+ return `${origin}${path}`;
2812
+ }
2813
+ }
2814
+ try {
2815
+ new URL(path);
2816
+ } catch {
2817
+ throw new Error("An invalid URL has been passed.");
2818
+ }
2819
+ return path;
2820
+ }
2529
2821
 
2530
2822
  // src/auth/obtainCsrf.ts
2531
2823
  async function obtainCsrf(config, rawResponse = false) {
2824
+ const { headers } = ctx.get();
2532
2825
  const res = await fetchCsrf(config);
2533
2826
  const csrfCook = parseCSRF(res.headers);
2534
- const h = new Headers();
2535
2827
  if (csrfCook) {
2536
2828
  const [, value] = csrfCook.split("=");
2537
2829
  const [token] = decodeURIComponent(value).split("|");
@@ -2542,29 +2834,27 @@ async function obtainCsrf(config, rawResponse = false) {
2542
2834
  parseCallback(res.headers),
2543
2835
  parseToken(res.headers)
2544
2836
  ].filter(Boolean).join("; ");
2545
- config.headers.set("cookie", cookie);
2546
- h.set("cookie", cookie);
2547
- updateHeaders(h);
2837
+ headers.set("cookie", cookie);
2838
+ ctx.set({ headers, preserveHeaders: true });
2839
+ updateHeaders(headers);
2548
2840
  }
2549
2841
  if (!rawResponse) {
2550
2842
  return { csrfToken: token };
2551
2843
  }
2552
2844
  } else {
2553
- const existingCookie = config.headers.get("cookie");
2845
+ const existingCookie = headers.get("cookie");
2554
2846
  const cookieParts = [];
2555
2847
  if (existingCookie) {
2556
- cookieParts.push(
2557
- parseToken(config.headers),
2558
- parseCallback(config.headers)
2559
- );
2848
+ cookieParts.push(parseToken(headers), parseCallback(headers));
2560
2849
  }
2561
2850
  if (csrfCook) {
2562
2851
  cookieParts.push(csrfCook);
2563
2852
  } else {
2564
- cookieParts.push(parseCSRF(config.headers));
2853
+ cookieParts.push(parseCSRF(headers));
2565
2854
  }
2566
2855
  const cookie = cookieParts.filter(Boolean).join("; ");
2567
- config.headers.set("cookie", cookie);
2856
+ headers.set("cookie", cookie);
2857
+ ctx.set({ headers, preserveHeaders: true });
2568
2858
  updateHeaders(new Headers({ cookie }));
2569
2859
  }
2570
2860
  if (rawResponse) {
@@ -2577,6 +2867,22 @@ async function obtainCsrf(config, rawResponse = false) {
2577
2867
  }
2578
2868
  }
2579
2869
 
2870
+ // src/utils/qualifyDomain.ts
2871
+ function fQUrl2(callbackUrl, path) {
2872
+ if (path.startsWith("/")) {
2873
+ if (callbackUrl) {
2874
+ const { origin } = new URL(callbackUrl);
2875
+ return `${origin}${path}`;
2876
+ }
2877
+ }
2878
+ try {
2879
+ new URL(path);
2880
+ } catch {
2881
+ throw new Error("An invalid URL has been passed.");
2882
+ }
2883
+ return path;
2884
+ }
2885
+
2580
2886
  // src/users/index.ts
2581
2887
  var Users = class {
2582
2888
  #config;
@@ -2599,15 +2905,17 @@ var Users = class {
2599
2905
  * @param [rawResponse] - When `true`, return the raw {@link Response}.
2600
2906
  */
2601
2907
  async updateSelf(req, rawResponse) {
2602
- const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
2603
- if (rawResponse) {
2604
- return res;
2605
- }
2606
- try {
2607
- return await res?.clone().json();
2608
- } catch {
2609
- return res;
2610
- }
2908
+ return withNileContext(this.#config, async () => {
2909
+ const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
2910
+ if (rawResponse) {
2911
+ return res;
2912
+ }
2913
+ try {
2914
+ return await res?.clone().json();
2915
+ } catch {
2916
+ return res;
2917
+ }
2918
+ });
2611
2919
  }
2612
2920
  /**
2613
2921
  * Remove the current user using `DELETE /api/me`.
@@ -2617,59 +2925,73 @@ var Users = class {
2617
2925
  * `packages/server/src/api/routes/me/index.ts` under `removeSelf`.
2618
2926
  */
2619
2927
  async removeSelf() {
2620
- const me = await this.getSelf();
2621
- if ("id" in me) {
2622
- this.#config.userId = me.id;
2623
- }
2624
- const res = await fetchMe(this.#config, "DELETE");
2625
- updateHeaders(new Headers());
2626
- return res;
2928
+ return withNileContext(this.#config, async () => {
2929
+ const me = await this.getSelf();
2930
+ if ("id" in me) {
2931
+ const userId = me.id;
2932
+ ctx.set({ userId });
2933
+ }
2934
+ const res = await fetchMe(this.#config, "DELETE");
2935
+ updateHeaders(new Headers());
2936
+ return res;
2937
+ });
2627
2938
  }
2628
2939
  async getSelf(rawResponse) {
2629
- const res = await fetchMe(this.#config);
2630
- if (rawResponse) {
2631
- return res;
2632
- }
2633
- try {
2634
- return await res?.clone().json();
2635
- } catch {
2636
- return res;
2637
- }
2940
+ return withNileContext(this.#config, async () => {
2941
+ const res = await fetchMe(this.#config);
2942
+ if (rawResponse) {
2943
+ return res;
2944
+ }
2945
+ try {
2946
+ return await res?.clone().json();
2947
+ } catch {
2948
+ return res;
2949
+ }
2950
+ });
2638
2951
  }
2639
2952
  async verifySelf(options, rawResponse = false) {
2640
- const bypassEmail = typeof options === "object" && options?.bypassEmail === true;
2641
- const callbackUrl = typeof options === "object" ? options.callbackUrl : defaultCallbackUrl2(this.#config).callbackUrl;
2642
- let res;
2643
- try {
2644
- const me = await this.getSelf();
2645
- if (me instanceof Response) {
2646
- return me;
2647
- }
2648
- res = await verifyEmailAddress(this.#config, me, String(callbackUrl));
2649
- return res;
2650
- } catch (e) {
2651
- if (!bypassEmail) {
2652
- let message = "Unable to verify email.";
2653
- if (e instanceof Error) {
2654
- message = e.message;
2953
+ return withNileContext(this.#config, async () => {
2954
+ const bypassEmail = typeof options === "object" && options?.bypassEmail === true;
2955
+ const callbackUrl = fQUrl2(
2956
+ defaultCallbackUrl2().callbackUrl,
2957
+ typeof options === "object" ? String(options.callbackUrl) : "/"
2958
+ );
2959
+ let res;
2960
+ try {
2961
+ const me = await this.getSelf();
2962
+ if (me instanceof Response) {
2963
+ return me;
2655
2964
  }
2656
- this.#logger?.error(
2657
- `${message} you can bypass this message by setting bypassEmail: true when calling 'verifySelf'`
2965
+ res = await verifyEmailAddress(this.#config, me, String(callbackUrl));
2966
+ return res;
2967
+ } catch (e) {
2968
+ if (!bypassEmail) {
2969
+ let message = "Unable to verify email.";
2970
+ if (e instanceof Error) {
2971
+ message = e.message;
2972
+ }
2973
+ this.#logger?.error(
2974
+ `${message} you can bypass this message by setting bypassEmail: true when calling 'verifySelf'`
2975
+ );
2976
+ res = new Response(message, { status: 400 });
2977
+ }
2978
+ }
2979
+ if (bypassEmail) {
2980
+ this.#logger?.info(
2981
+ "bypassing email requirements for email verification"
2658
2982
  );
2659
- res = new Response(message, { status: 400 });
2983
+ res = this.updateSelf({ emailVerified: true }, rawResponse);
2660
2984
  }
2661
- }
2662
- if (bypassEmail) {
2663
- this.#logger?.info("bypassing email requirements for email verification");
2664
- res = this.updateSelf({ emailVerified: true }, rawResponse);
2665
- }
2666
- return res;
2985
+ return res;
2986
+ });
2667
2987
  }
2668
2988
  };
2669
2989
  async function verifyEmailAddress(config, user, callback) {
2670
- config.headers.set("content-type", "application/x-www-form-urlencoded");
2990
+ const { headers } = ctx.get();
2991
+ headers?.set("content-type", "application/x-www-form-urlencoded");
2992
+ ctx.set({ headers });
2671
2993
  const { csrfToken } = await obtainCsrf(config);
2672
- const defaults = defaultCallbackUrl2(config);
2994
+ const defaults = defaultCallbackUrl2();
2673
2995
  const callbackUrl = callback ?? String(defaults.callbackUrl);
2674
2996
  const res = await fetchVerifyEmail(
2675
2997
  config,
@@ -2685,9 +3007,10 @@ async function verifyEmailAddress(config, user, callback) {
2685
3007
  }
2686
3008
  return res;
2687
3009
  }
2688
- function defaultCallbackUrl2(config) {
3010
+ function defaultCallbackUrl2() {
2689
3011
  let cb = null;
2690
- const fallbackCb = parseCallback(config.headers);
3012
+ const { headers } = ctx.get();
3013
+ const fallbackCb = parseCallback(headers);
2691
3014
  if (fallbackCb) {
2692
3015
  const [, value] = fallbackCb.split("=");
2693
3016
  cb = decodeURIComponent(value);
@@ -2707,24 +3030,26 @@ var Tenants = class {
2707
3030
  * `createTenant` operation definition.
2708
3031
  */
2709
3032
  async create(req, rawResponse) {
2710
- let res;
2711
- if (typeof req === "string") {
2712
- res = await fetchTenants(
2713
- this.#config,
2714
- "POST",
2715
- JSON.stringify({ name: req })
2716
- );
2717
- } else if (typeof req === "object" && ("name" in req || "id" in req)) {
2718
- res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
2719
- }
2720
- if (rawResponse) {
2721
- return res;
2722
- }
2723
- try {
2724
- return await res?.clone().json();
2725
- } catch {
2726
- return res;
2727
- }
3033
+ return withNileContext(this.#config, async () => {
3034
+ let res;
3035
+ if (typeof req === "string") {
3036
+ res = await fetchTenants(
3037
+ this.#config,
3038
+ "POST",
3039
+ JSON.stringify({ name: req })
3040
+ );
3041
+ } else if (typeof req === "object" && ("name" in req || "id" in req)) {
3042
+ res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
3043
+ }
3044
+ if (rawResponse) {
3045
+ return res;
3046
+ }
3047
+ try {
3048
+ return await res?.clone().json();
3049
+ } catch {
3050
+ return res;
3051
+ }
3052
+ });
2728
3053
  }
2729
3054
  /**
2730
3055
  * Remove a tenant via `DELETE /api/tenants/{tenantId}`.
@@ -2732,14 +3057,16 @@ var Tenants = class {
2732
3057
  * @param req - The tenant to remove or context containing the id.
2733
3058
  */
2734
3059
  async delete(req) {
2735
- if (typeof req === "string") {
2736
- this.#config.tenantId = req;
2737
- }
2738
- if (typeof req === "object" && "id" in req) {
2739
- this.#config.tenantId = req.id;
2740
- }
2741
- const res = await fetchTenant(this.#config, "DELETE");
2742
- return res;
3060
+ return withNileContext(this.#config, async () => {
3061
+ if (typeof req === "string") {
3062
+ ctx.set({ tenantId: req });
3063
+ }
3064
+ if (typeof req === "object" && "id" in req) {
3065
+ ctx.set({ tenantId: req.id });
3066
+ }
3067
+ const res = await fetchTenant(this.#config, "DELETE");
3068
+ return res;
3069
+ });
2743
3070
  }
2744
3071
  /**
2745
3072
  * Fetch details for a tenant using `GET /api/tenants/{tenantId}`.
@@ -2748,53 +3075,63 @@ var Tenants = class {
2748
3075
  * @param [rawResponse] - When true, return the raw {@link Response}.
2749
3076
  */
2750
3077
  async get(req, rawResponse) {
2751
- if (typeof req === "string") {
2752
- this.#config.tenantId = req;
2753
- } else if (typeof req === "object" && "id" in req) {
2754
- this.#config.tenantId = req.id;
2755
- }
2756
- const res = await fetchTenant(this.#config, "GET");
2757
- if (rawResponse === true || req === true) {
2758
- return res;
2759
- }
2760
- try {
2761
- return await res?.clone().json();
2762
- } catch {
2763
- return res;
2764
- }
3078
+ return withNileContext(this.#config, async () => {
3079
+ if (typeof req === "string") {
3080
+ ctx.set({ tenantId: req });
3081
+ } else if (typeof req === "object" && "id" in req) {
3082
+ ctx.set({ tenantId: req.id });
3083
+ }
3084
+ const res = await fetchTenant(this.#config, "GET");
3085
+ if (rawResponse === true || req === true) {
3086
+ return res;
3087
+ }
3088
+ try {
3089
+ return await res?.clone().json();
3090
+ } catch {
3091
+ return res;
3092
+ }
3093
+ });
2765
3094
  }
2766
3095
  async update(req, rawResponse) {
2767
- let res;
2768
- if (typeof req === "object" && ("name" in req || "id" in req)) {
2769
- const { id, ...remaining } = req;
2770
- if (id) {
2771
- this.#config.tenantId = id;
3096
+ return withNileContext(this.#config, async () => {
3097
+ let res;
3098
+ if (typeof req === "object" && ("name" in req || "id" in req)) {
3099
+ const { id, ...remaining } = req;
3100
+ if (id) {
3101
+ ctx.set({ tenantId: id });
3102
+ }
3103
+ res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
2772
3104
  }
2773
- res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
2774
- }
2775
- if (rawResponse) {
2776
- return res;
2777
- }
2778
- try {
2779
- return await res?.clone().json();
2780
- } catch {
2781
- return res;
2782
- }
3105
+ if (rawResponse) {
3106
+ return res;
3107
+ }
3108
+ try {
3109
+ return await res?.clone().json();
3110
+ } catch {
3111
+ return res;
3112
+ }
3113
+ });
2783
3114
  }
2784
3115
  /**
2785
3116
  * List tenants for the current user via `GET /api/tenants`.
2786
3117
  * See `packages/server/src/api/routes/tenants/GET.ts` for details.
2787
3118
  */
2788
3119
  async list(req) {
2789
- const res = await fetchTenantsByUser(this.#config);
2790
- if (req === true) {
2791
- return res;
2792
- }
2793
- try {
2794
- return await res?.clone().json();
2795
- } catch {
2796
- return res;
2797
- }
3120
+ return withNileContext(
3121
+ this.#config,
3122
+ async () => {
3123
+ const res = await fetchTenantsByUser(this.#config);
3124
+ if (req === true) {
3125
+ return res;
3126
+ }
3127
+ try {
3128
+ return await res?.clone().json();
3129
+ } catch {
3130
+ return res;
3131
+ }
3132
+ },
3133
+ "listTenants"
3134
+ );
2798
3135
  }
2799
3136
  /**
2800
3137
  * Leave the current tenant using `DELETE /api/tenants/{tenantId}/users/{userId}`.
@@ -2802,29 +3139,33 @@ var Tenants = class {
2802
3139
  * @param [req] - Optionally specify the tenant id to leave.
2803
3140
  */
2804
3141
  async leaveTenant(req) {
2805
- const me = await fetchMe(this.#config);
2806
- try {
2807
- const json = await me.json();
2808
- if ("id" in json) {
2809
- this.#config.userId = json.id;
3142
+ return withNileContext(this.#config, async () => {
3143
+ const me = await fetchMe(this.#config);
3144
+ try {
3145
+ const json = await me.json();
3146
+ if ("id" in json) {
3147
+ ctx.set({ userId: json.id, preserveHeaders: true });
3148
+ }
3149
+ } catch {
2810
3150
  }
2811
- } catch {
2812
- }
2813
- if (typeof req === "string") {
2814
- this.#config.tenantId = req;
2815
- } else {
2816
- this.#handleContext(req);
2817
- }
2818
- return await fetchTenantUser(this.#config, "DELETE");
3151
+ if (typeof req === "string") {
3152
+ ctx.set({ tenantId: req, preserveHeaders: true });
3153
+ } else {
3154
+ this.#handleContext(req);
3155
+ }
3156
+ return await fetchTenantUser(this.#config, "DELETE");
3157
+ });
2819
3158
  }
2820
3159
  async addMember(req, rawResponse) {
2821
- if (typeof req === "string") {
2822
- this.#config.userId = req;
2823
- } else {
2824
- this.#handleContext(req);
2825
- }
2826
- const res = await fetchTenantUser(this.#config, "PUT");
2827
- return responseHandler(res, rawResponse);
3160
+ return withNileContext(this.#config, async () => {
3161
+ if (typeof req === "string") {
3162
+ ctx.set({ userId: req, preserveHeaders: true });
3163
+ } else {
3164
+ this.#handleContext(req);
3165
+ }
3166
+ const res = await fetchTenantUser(this.#config, "PUT");
3167
+ return responseHandler(res, rawResponse);
3168
+ });
2828
3169
  }
2829
3170
  /**
2830
3171
  * Remove a user from a tenant with `DELETE /api/tenants/{tenantId}/users/{userId}`.
@@ -2833,57 +3174,83 @@ var Tenants = class {
2833
3174
  * @param [rawResponse] - When true, return the raw {@link Response}.
2834
3175
  */
2835
3176
  async removeMember(req, rawResponse) {
2836
- this.#handleContext(req);
2837
- const res = await fetchTenantUser(this.#config, "DELETE");
2838
- return responseHandler(res, rawResponse);
3177
+ return withNileContext(this.#config, async () => {
3178
+ this.#handleContext(req);
3179
+ if (typeof req === "string") {
3180
+ ctx.set({ userId: req, preserveHeaders: true });
3181
+ }
3182
+ const res = await fetchTenantUser(this.#config, "DELETE");
3183
+ return responseHandler(res, rawResponse);
3184
+ });
2839
3185
  }
2840
3186
  async users(req, rawResponse) {
2841
- this.#handleContext(req);
2842
- const res = await fetchTenantUsers(this.#config, "GET");
2843
- return responseHandler(
2844
- res,
2845
- rawResponse || typeof req === "boolean" && req
3187
+ return withNileContext(
3188
+ this.#config,
3189
+ async () => {
3190
+ this.#handleContext(req);
3191
+ const res = await fetchTenantUsers(this.#config, "GET");
3192
+ return responseHandler(
3193
+ res,
3194
+ rawResponse || typeof req === "boolean" && req
3195
+ );
3196
+ },
3197
+ "users"
2846
3198
  );
2847
3199
  }
2848
3200
  /**
2849
3201
  * List invites for the current tenant via `GET /api/tenants/{tenantId}/invites`.
2850
3202
  */
2851
3203
  async invites() {
2852
- const res = await fetchInvites(this.#config);
2853
- return responseHandler(res);
3204
+ return withNileContext(
3205
+ this.#config,
3206
+ async () => {
3207
+ const res = await fetchInvites(this.#config);
3208
+ return responseHandler(res);
3209
+ },
3210
+ "invites"
3211
+ );
2854
3212
  }
2855
3213
  async invite(req, rawResponse) {
2856
- const { csrfToken } = await obtainCsrf(this.#config);
2857
- const defaults = defaultCallbackUrl3(this.#config);
2858
- let identifier = req;
2859
- let callbackUrl = defaults.callbackUrl;
2860
- let redirectUrl = defaults.redirectUrl;
2861
- if (typeof req === "object") {
2862
- if ("email" in req) {
2863
- identifier = req.email;
2864
- }
2865
- if ("callbackUrl" in req) {
2866
- callbackUrl = req.callbackUrl ? req.callbackUrl : "";
2867
- }
2868
- if ("redirectUrl" in req) {
2869
- redirectUrl = req.redirectUrl ? req.redirectUrl : "";
2870
- }
2871
- }
2872
- this.#config.headers.set(
2873
- "Content-Type",
2874
- "application/x-www-form-urlencoded"
2875
- );
2876
- const res = await fetchInvite(
3214
+ return withNileContext(
2877
3215
  this.#config,
2878
- "POST",
2879
- new URLSearchParams({
2880
- identifier,
2881
- csrfToken,
2882
- callbackUrl,
2883
- redirectUrl
2884
- }).toString()
3216
+ async () => {
3217
+ await runExtensionContext(this.#config);
3218
+ const { csrfToken } = await obtainCsrf(
3219
+ this.#config
3220
+ );
3221
+ const defaults = defaultCallbackUrl3(this.#config);
3222
+ let identifier = req;
3223
+ let callbackUrl = defaults.callbackUrl;
3224
+ let redirectUrl = defaults.redirectUrl;
3225
+ if (typeof req === "object") {
3226
+ if ("email" in req) {
3227
+ identifier = req.email;
3228
+ }
3229
+ const { callbackUrl: cbUrl } = defaultCallbackUrl3(this.#config);
3230
+ if ("callbackUrl" in req) {
3231
+ callbackUrl = fQUrl2(cbUrl, req.callbackUrl ?? "/");
3232
+ }
3233
+ if ("redirectUrl" in req) {
3234
+ redirectUrl = fQUrl2(cbUrl, req.redirectUrl ?? "/");
3235
+ }
3236
+ }
3237
+ const { headers } = ctx.get();
3238
+ headers?.set("Content-Type", "application/x-www-form-urlencoded");
3239
+ ctx.set({ headers });
3240
+ const res = await fetchInvite(
3241
+ this.#config,
3242
+ "POST",
3243
+ new URLSearchParams({
3244
+ identifier,
3245
+ csrfToken,
3246
+ callbackUrl,
3247
+ redirectUrl
3248
+ }).toString()
3249
+ );
3250
+ return responseHandler(res, rawResponse);
3251
+ },
3252
+ "invites"
2885
3253
  );
2886
- return responseHandler(res, rawResponse);
2887
3254
  }
2888
3255
  /**
2889
3256
  * Accept an invite using `PUT /api/tenants/{tenantId}/invite`.
@@ -2892,22 +3259,24 @@ var Tenants = class {
2892
3259
  * @param [rawResponse] - When true, return the raw {@link Response}.
2893
3260
  */
2894
3261
  async acceptInvite(req, rawResponse) {
2895
- if (!req) {
2896
- throw new Error("The identifier and token are required.");
2897
- }
2898
- const { identifier, token } = req;
2899
- const defaults = defaultCallbackUrl3(this.#config);
2900
- const callbackUrl = String(defaults.callbackUrl);
2901
- const res = await fetchInvite(
2902
- this.#config,
2903
- "PUT",
2904
- new URLSearchParams({
2905
- identifier,
2906
- token,
2907
- callbackUrl
2908
- }).toString()
2909
- );
2910
- return responseHandler(res, rawResponse);
3262
+ return withNileContext(this.#config, async () => {
3263
+ if (!req) {
3264
+ throw new Error("The identifier and token are required.");
3265
+ }
3266
+ const { identifier, token } = req;
3267
+ const defaults = defaultCallbackUrl3(this.#config);
3268
+ const callbackUrl = String(defaults.callbackUrl);
3269
+ const res = await fetchInvite(
3270
+ this.#config,
3271
+ "PUT",
3272
+ new URLSearchParams({
3273
+ identifier,
3274
+ token,
3275
+ callbackUrl
3276
+ }).toString()
3277
+ );
3278
+ return responseHandler(res, rawResponse);
3279
+ });
2911
3280
  }
2912
3281
  /**
2913
3282
  * Delete a pending invite using `DELETE /api/tenants/{tenantId}/invite/{inviteId}`.
@@ -2915,25 +3284,27 @@ var Tenants = class {
2915
3284
  * @param req - Identifier of the invite to remove.
2916
3285
  */
2917
3286
  async deleteInvite(req) {
2918
- let id = "";
2919
- if (typeof req === "object") {
2920
- id = req.id;
2921
- } else {
2922
- id = req;
2923
- }
2924
- if (!id) {
2925
- throw new Error("An invite id is required.");
2926
- }
2927
- const res = await fetchInvite(this.#config, "DELETE", id);
2928
- return responseHandler(res, true);
3287
+ return withNileContext(this.#config, async () => {
3288
+ let id = "";
3289
+ if (typeof req === "object") {
3290
+ id = req.id;
3291
+ } else {
3292
+ id = req;
3293
+ }
3294
+ if (!id) {
3295
+ throw new Error("An invite id is required.");
3296
+ }
3297
+ const res = await fetchInvite(this.#config, "DELETE", id);
3298
+ return responseHandler(res, true);
3299
+ });
2929
3300
  }
2930
3301
  #handleContext(req) {
2931
3302
  if (typeof req === "object") {
2932
3303
  if ("tenantId" in req) {
2933
- this.#config.tenantId = req.tenantId;
3304
+ ctx.set({ tenantId: req.tenantId, preserveHeaders: true });
2934
3305
  }
2935
3306
  if ("userId" in req) {
2936
- this.#config.tenantId = req.tenantId;
3307
+ ctx.set({ userId: req.userId, preserveHeaders: true });
2937
3308
  }
2938
3309
  }
2939
3310
  }
@@ -2951,15 +3322,13 @@ async function responseHandler(res, rawResponse) {
2951
3322
  function defaultCallbackUrl3(config) {
2952
3323
  let cb = null;
2953
3324
  let redirect = null;
2954
- const fallbackCb = parseCallback(config.headers);
3325
+ const { headers, tenantId } = ctx.get();
3326
+ const fallbackCb = parseCallback(headers);
2955
3327
  if (fallbackCb) {
2956
3328
  const [, value] = fallbackCb.split("=");
2957
3329
  cb = decodeURIComponent(value);
2958
3330
  if (value) {
2959
- redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace(
2960
- "{tenantId}",
2961
- String(config.tenantId)
2962
- )}`;
3331
+ redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", String(tenantId))}`;
2963
3332
  }
2964
3333
  }
2965
3334
  return { callbackUrl: cb, redirectUrl: redirect };
@@ -3026,97 +3395,6 @@ function updateConfig(response, config) {
3026
3395
  };
3027
3396
  }
3028
3397
 
3029
- // src/api/utils/extensions.ts
3030
- function getRequestConfig(params) {
3031
- if (typeof params[1] === "object") {
3032
- return params[1];
3033
- }
3034
- return {};
3035
- }
3036
- function bindRunExtensions(instance) {
3037
- return async function runExtensions(toRun, config, params, _init) {
3038
- const { debug } = config.logger("[EXTENSIONS]");
3039
- const extensionConfig = getRequestConfig(
3040
- Array.isArray(params) ? params : [null, params]
3041
- );
3042
- if (config.extensions) {
3043
- for (const create2 of config.extensions) {
3044
- if (typeof create2 !== "function") {
3045
- continue;
3046
- }
3047
- const ext = create2(instance);
3048
- if (extensionConfig.disableExtensions?.includes(ext.id)) {
3049
- continue;
3050
- }
3051
- if (ext.onHandleRequest && toRun === "onHandleRequest" /* onHandleRequest */) {
3052
- const result = await ext.onHandleRequest(
3053
- ...Array.isArray(params) ? params : [params]
3054
- );
3055
- debug(`${ext.id ?? create2.name} ran onHandleRequest`);
3056
- if (result != null) {
3057
- return result;
3058
- }
3059
- }
3060
- const [param] = Array.isArray(params) ? params : [params];
3061
- if (ext.onRequest && toRun === "onRequest" /* onRequest */) {
3062
- const previousContext = instance.getContext();
3063
- if (previousContext.preserveHeaders) {
3064
- instance.setContext({ preserveHeaders: false });
3065
- }
3066
- if (!_init) {
3067
- continue;
3068
- }
3069
- await ext.onRequest(_init.request);
3070
- const updatedContext = instance.getContext();
3071
- if (updatedContext?.headers) {
3072
- const cookie = updatedContext.headers.get("cookie");
3073
- if (cookie && param.headers) {
3074
- param.headers.set(
3075
- "cookie",
3076
- mergeCookies(
3077
- previousContext.preserveHeaders ? previousContext.headers?.get("cookie") : null,
3078
- updatedContext.headers.get("cookie")
3079
- )
3080
- );
3081
- }
3082
- if (updatedContext.tenantId && param.headers) {
3083
- param.headers.set(
3084
- TENANT_COOKIE,
3085
- String(updatedContext.headers.get(TENANT_COOKIE))
3086
- );
3087
- }
3088
- }
3089
- debug(`${ext.id ?? create2.name} ran onRequest`);
3090
- }
3091
- if (ext.onResponse && toRun === "onResponse" /* onResponse */) {
3092
- const result = await ext.onResponse(param);
3093
- debug(`${ext.id ?? create2.name} ran onResponse`);
3094
- if (result != null) {
3095
- return result;
3096
- }
3097
- }
3098
- }
3099
- }
3100
- return void 0;
3101
- };
3102
- }
3103
- function buildExtensionConfig(instance) {
3104
- return {
3105
- runExtensions: bindRunExtensions(instance)
3106
- };
3107
- }
3108
- function mergeCookies(...cookieStrings) {
3109
- const cookieMap = /* @__PURE__ */ new Map();
3110
- for (const str of cookieStrings) {
3111
- if (!str) continue;
3112
- for (const part of str.split(";")) {
3113
- const [key17, value] = part.split("=").map((s) => s.trim());
3114
- if (key17 && value) cookieMap.set(key17, value);
3115
- }
3116
- }
3117
- return [...cookieMap.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
3118
- }
3119
-
3120
3398
  // src/Server.ts
3121
3399
  var Server = class {
3122
3400
  users;
@@ -3125,35 +3403,38 @@ var Server = class {
3125
3403
  #config;
3126
3404
  #handlers;
3127
3405
  #manager;
3128
- #headers;
3129
- #preserveHeaders;
3406
+ // #headers: undefined | Headers;
3407
+ // #preserveHeaders: boolean;
3130
3408
  constructor(config) {
3131
3409
  this.#config = new Config({
3132
3410
  ...config,
3133
3411
  extensionCtx: buildExtensionConfig(this)
3134
3412
  });
3135
3413
  watchTenantId((tenantId) => {
3136
- if (tenantId !== this.#config.tenantId) {
3137
- this.#config.tenantId = tenantId;
3414
+ if (tenantId !== this.#config.context.tenantId) {
3415
+ this.#config.context.tenantId = String(tenantId);
3138
3416
  this.#reset();
3139
3417
  }
3140
3418
  });
3141
3419
  watchUserId((userId) => {
3142
- if (userId !== this.#config.userId) {
3143
- this.#config.userId = userId;
3420
+ if (userId !== this.#config.context.userId) {
3421
+ this.#config.context.userId = String(userId);
3144
3422
  this.#reset();
3145
3423
  }
3146
3424
  });
3147
3425
  watchHeaders((headers) => {
3148
- this.setContext(headers);
3149
- this.#reset();
3426
+ if (headers) {
3427
+ this.#config.context.headers = new Headers(headers);
3428
+ this.#config.context.preserveHeaders = true;
3429
+ this.#reset();
3430
+ }
3150
3431
  });
3151
3432
  this.#handlers = {
3152
3433
  ...this.#config.handlers,
3153
3434
  withContext: handlersWithContext(this.#config)
3154
3435
  };
3155
- this.#preserveHeaders = config?.preserveHeaders ?? false;
3156
- this.#config.tenantId = getTenantId({ config: this.#config });
3436
+ this.#config.context.preserveHeaders = config?.preserveHeaders ?? false;
3437
+ this.#config.context.tenantId = getTenantId({ config: this.#config });
3157
3438
  this.#manager = new DBManager(this.#config);
3158
3439
  this.#handleHeaders(config);
3159
3440
  this.users = new Users(this.#config);
@@ -3208,21 +3489,6 @@ var Server = class {
3208
3489
  }
3209
3490
  };
3210
3491
  }
3211
- /**
3212
- * A convenience function that applies a config and ensures whatever was passed is set properly
3213
- */
3214
- getInstance(config, req) {
3215
- const _config = { ...this.#config, ...config };
3216
- const updatedConfig = new Config(_config);
3217
- this.#config = new Config(updatedConfig);
3218
- this.#config.tenantId = config.tenantId;
3219
- this.#config.userId = config.userId;
3220
- if (req) {
3221
- this.setContext(req);
3222
- }
3223
- this.#reset();
3224
- return this;
3225
- }
3226
3492
  get handlers() {
3227
3493
  return this.#handlers;
3228
3494
  }
@@ -3232,98 +3498,30 @@ var Server = class {
3232
3498
  set paths(paths) {
3233
3499
  this.#config.paths = paths;
3234
3500
  }
3235
- /**
3236
- * Allow the setting of headers from a req or header object.
3237
- * Makes it possible to handle REST requests easily
3238
- * Also makes it easy to set user + tenant in some way
3239
- * @param req
3240
- * @returns undefined
3241
- */
3242
- setContext = (req, ...remaining) => {
3243
- let ok = false;
3244
- if (req && typeof req === "object" && "tenantId" in req) {
3245
- ok = true;
3246
- this.#config.tenantId = req.tenantId;
3247
- }
3248
- if (req && typeof req === "object" && "userId" in req) {
3249
- ok = true;
3250
- this.#config.userId = req.userId;
3251
- }
3252
- if (req && typeof req === "object" && "preserveHeaders" in req) {
3253
- ok = true;
3254
- this.#preserveHeaders = Boolean(req.preserveHeaders);
3255
- }
3256
- let atLeastOne = false;
3257
- if (this.#config?.extensions) {
3258
- for (const create2 of this.#config.extensions) {
3259
- if (typeof create2 !== "function") {
3260
- continue;
3261
- }
3262
- const ext = create2(this);
3263
- if (typeof ext.onSetContext === "function") {
3264
- if (req) {
3265
- ext.onSetContext(req, ...remaining);
3266
- atLeastOne = true;
3267
- } else {
3268
- this.#config.logger("extension").warn("attempted to call onSetContext without a value");
3269
- }
3270
- }
3271
- }
3272
- }
3273
- if (atLeastOne) {
3274
- return;
3275
- }
3276
- try {
3277
- if (req instanceof Headers) {
3278
- this.#handleHeaders(req);
3279
- this.#reset();
3280
- return;
3281
- } else if (req instanceof Request) {
3282
- this.#handleHeaders(new Headers(req.headers));
3283
- this.#reset();
3284
- return;
3285
- }
3286
- } catch {
3501
+ async withContext(context, fn) {
3502
+ const { ddl, ...ctx2 } = context ?? defaultContext;
3503
+ this.#config.context = { ...ctx2 };
3504
+ const preserve = (context && "preserveHeaders" in context && context.preserveHeaders) ?? true;
3505
+ if (preserve) {
3506
+ this.#config.context = { ...this.getContext(), ...context };
3287
3507
  }
3288
- if (ok) {
3289
- return;
3508
+ if (ddl) {
3509
+ delete this.#config.context.tenantId;
3510
+ delete this.#config.context.userId;
3290
3511
  }
3291
- if (typeof req === "object") {
3292
- try {
3293
- const headers = new Headers(req);
3294
- if (headers) {
3295
- this.#handleHeaders(headers);
3296
- this.#reset();
3297
- return;
3298
- }
3299
- } catch {
3512
+ return withNileContext(this.#config, async () => {
3513
+ if (fn) {
3514
+ return fn(this);
3300
3515
  }
3301
- }
3302
- const { warn } = Logger(this.#config)("[API]");
3303
- if (warn) {
3304
- warn(
3305
- "Set context expects a Request, Header instance or an object of Record<string, string>"
3306
- );
3307
- }
3308
- };
3516
+ return this;
3517
+ });
3518
+ }
3519
+ /**
3520
+ *
3521
+ * @returns the last used (basically global) context object, useful for debugging or making your own context
3522
+ */
3309
3523
  getContext() {
3310
- if (this.#config?.extensions) {
3311
- for (const create2 of this.#config.extensions) {
3312
- if (typeof create2 !== "function") {
3313
- continue;
3314
- }
3315
- const ext = create2(this);
3316
- if (typeof ext.onGetContext === "function") {
3317
- return ext.onGetContext();
3318
- }
3319
- }
3320
- }
3321
- return {
3322
- headers: this.#headers,
3323
- userId: this.#config?.userId,
3324
- tenantId: this.#config?.tenantId,
3325
- preserveHeaders: this.#preserveHeaders
3326
- };
3524
+ return ctx.getLastUsed();
3327
3525
  }
3328
3526
  /**
3329
3527
  * Merge headers together
@@ -3332,16 +3530,19 @@ var Server = class {
3332
3530
  #handleHeaders(config) {
3333
3531
  const updates = [];
3334
3532
  let headers;
3335
- this.#headers = new Headers();
3533
+ this.#config.context.headers = new Headers();
3336
3534
  if (config instanceof Headers) {
3337
3535
  headers = config;
3338
3536
  } else if (config?.headers) {
3339
3537
  headers = config?.headers;
3340
3538
  if (config && config.origin) {
3341
- this.#headers.set(HEADER_ORIGIN, config.origin);
3539
+ this.#config.context.headers.set(HEADER_ORIGIN, config.origin);
3342
3540
  }
3343
3541
  if (config && config.secureCookies != null) {
3344
- this.#headers.set(HEADER_SECURE_COOKIES, String(config.secureCookies));
3542
+ this.#config.context.headers.set(
3543
+ HEADER_SECURE_COOKIES,
3544
+ String(config.secureCookies)
3545
+ );
3345
3546
  }
3346
3547
  }
3347
3548
  if (headers instanceof Headers) {
@@ -3354,8 +3555,7 @@ var Server = class {
3354
3555
  }
3355
3556
  }
3356
3557
  const merged = {};
3357
- this.#config.tenantId = getTenantFromHttp(this.#headers, this.#config);
3358
- this.#headers?.forEach((value, key17) => {
3558
+ this.#config.context.headers?.forEach((value, key17) => {
3359
3559
  if (key17.toLowerCase() !== "cookie") {
3360
3560
  merged[key17.toLowerCase()] = value;
3361
3561
  }
@@ -3364,16 +3564,14 @@ var Server = class {
3364
3564
  merged[key17] = value;
3365
3565
  }
3366
3566
  for (const [key17, value] of Object.entries(merged)) {
3367
- this.#headers.set(key17, value);
3567
+ this.#config.context.headers.set(key17, value);
3368
3568
  }
3369
3569
  this.#config.logger("[handleHeaders]").debug(JSON.stringify(merged));
3370
- this.#config.headers = this.#headers;
3371
3570
  }
3372
3571
  /**
3373
3572
  * Allow some internal mutations to reset our config + headers
3374
3573
  */
3375
3574
  #reset = () => {
3376
- this.#config.headers = this.#headers ?? new Headers();
3377
3575
  this.#config.extensionCtx = buildExtensionConfig(this);
3378
3576
  this.users = new Users(this.#config);
3379
3577
  this.tenants = new Tenants(this.#config);
@@ -3400,6 +3598,7 @@ exports.USER_COOKIE = USER_COOKIE;
3400
3598
  exports.parseCSRF = parseCSRF;
3401
3599
  exports.parseCallback = parseCallback;
3402
3600
  exports.parseResetToken = parseResetToken;
3601
+ exports.parseTenantId = parseTenantId;
3403
3602
  exports.parseToken = parseToken;
3404
3603
  //# sourceMappingURL=index.js.map
3405
3604
  //# sourceMappingURL=index.js.map