@niledatabase/server 5.0.0-alpha.25 → 5.0.0-alpha.27

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.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { AsyncLocalStorage } from 'async_hooks';
1
2
  import 'dotenv/config';
2
3
  import pg from 'pg';
3
4
 
@@ -6,6 +7,7 @@ var ExtensionState = /* @__PURE__ */ ((ExtensionState2) => {
6
7
  ExtensionState2["onHandleRequest"] = "onHandleRequest";
7
8
  ExtensionState2["onRequest"] = "onRequest";
8
9
  ExtensionState2["onResponse"] = "onResponse";
10
+ ExtensionState2["withContext"] = "withContext";
9
11
  return ExtensionState2;
10
12
  })(ExtensionState || {});
11
13
  var APIErrorErrorCodeEnum = {
@@ -63,21 +65,18 @@ var appRoutes = (prefix = DEFAULT_PREFIX) => ({
63
65
  INVITE: `${prefix}${"/tenants/{tenantId}/invite" /* INVITE */}`,
64
66
  LOG: `${prefix}/_log`
65
67
  });
66
- var apiRoutes = (config) => ({
67
- ME: makeRestUrl(config, "/me"),
68
- USERS: (qp) => makeRestUrl(config, "/users", qp),
69
- USER: (userId) => makeRestUrl(config, `/users/${userId}`),
70
- TENANTS: makeRestUrl(config, "/tenants"),
71
- TENANT: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}`),
72
- SIGNUP: makeRestUrl(config, "/signup"),
73
- TENANT_USERS: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}/users`),
74
- INVITES: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}/invites`),
75
- INVITE: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}/invite`),
76
- TENANT_USER: makeRestUrl(
77
- config,
78
- `/tenants/${config.tenantId}/users/${config.userId}`
79
- ),
80
- USER_TENANTS: (userId) => makeRestUrl(config, `/users/${userId}/tenants`)
68
+ var apiRoutes = (apiUrl) => ({
69
+ ME: makeRestUrl(apiUrl, "/me"),
70
+ USERS: (qp) => makeRestUrl(apiUrl, "/users", qp),
71
+ USER: (userId) => makeRestUrl(apiUrl, `/users/${userId}`),
72
+ TENANTS: makeRestUrl(apiUrl, "/tenants"),
73
+ TENANT: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}`),
74
+ SIGNUP: makeRestUrl(apiUrl, "/signup"),
75
+ TENANT_USERS: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/users`),
76
+ INVITES: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/invites`),
77
+ INVITE: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/invite`),
78
+ TENANT_USER: (tenantId, userId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/users/${userId}`),
79
+ USER_TENANTS: (userId) => makeRestUrl(apiUrl, `/users/${userId}/tenants`)
81
80
  });
82
81
  var proxyRoutes = (config) => ({
83
82
  SIGNIN: makeRestUrl(config, "/auth/signin" /* SIGNIN */),
@@ -101,8 +100,8 @@ function filterNullUndefined(obj) {
101
100
  )
102
101
  );
103
102
  }
104
- function makeRestUrl(config, path, qp) {
105
- const url = config.apiUrl || NILEDB_API_URL;
103
+ function makeRestUrl(apiUrl, path, qp) {
104
+ const url = apiUrl || NILEDB_API_URL;
106
105
  if (!url) {
107
106
  throw new Error(
108
107
  "An API url is required. Set it via NILEDB_API_URL. Was auto configuration run?"
@@ -259,10 +258,290 @@ async function auth(req, config) {
259
258
  }
260
259
  }
261
260
 
261
+ // src/utils/Logger.ts
262
+ var red = "\x1B[31m";
263
+ var yellow = "\x1B[38;2;255;255;0m";
264
+ var purple = "\x1B[38;2;200;160;255m";
265
+ var orange = "\x1B[38;2;255;165;0m";
266
+ var reset = "\x1B[0m";
267
+ var baseLogger = (config, ...params) => ({
268
+ silly(message, meta) {
269
+ if (config?.debug && process.env.LOG_LEVEL === "silly") {
270
+ console.log(
271
+ `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
272
+ ""
273
+ )}${reset} ${message}`,
274
+ meta ? `${JSON.stringify(meta)}` : ""
275
+ );
276
+ }
277
+ },
278
+ info(message, meta) {
279
+ if (config?.debug) {
280
+ console.info(
281
+ `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
282
+ ""
283
+ )}${reset} ${message}`,
284
+ meta ? `${JSON.stringify(meta)}` : ""
285
+ );
286
+ }
287
+ },
288
+ debug(message, meta) {
289
+ if (config?.debug) {
290
+ console.log(
291
+ `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
292
+ ""
293
+ )}${reset} ${message}`,
294
+ meta ? `${JSON.stringify(meta)}` : ""
295
+ );
296
+ }
297
+ },
298
+ warn(message, meta) {
299
+ if (config?.debug) {
300
+ console.warn(
301
+ `${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
302
+ ""
303
+ )}${reset} ${message}`,
304
+ meta ? JSON.stringify(meta) : ""
305
+ );
306
+ }
307
+ },
308
+ error(message, meta) {
309
+ console.error(
310
+ `${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
311
+ ""
312
+ )}${red} ${message}`,
313
+ meta ? meta : "",
314
+ `${reset}`
315
+ );
316
+ }
317
+ });
318
+ function Logger(config) {
319
+ return (prefixes) => {
320
+ const { info, debug, warn: warn2, error, silly: silly2 } = config && typeof config?.logger === "function" ? config.logger(prefixes) : baseLogger(config, prefixes);
321
+ return {
322
+ info,
323
+ debug,
324
+ warn: warn2,
325
+ error,
326
+ silly: silly2
327
+ };
328
+ };
329
+ }
330
+ function matchesLog(configRoutes, request2) {
331
+ return urlMatches(request2.url, configRoutes.LOG);
332
+ }
333
+
334
+ // src/api/utils/extensions.ts
335
+ function getRequestConfig(params) {
336
+ if (typeof params[1] === "object") {
337
+ return params[1];
338
+ }
339
+ return {};
340
+ }
341
+ function bindRunExtensions(instance) {
342
+ return async function runExtensions(toRun, config, params, _init) {
343
+ const { debug } = config.logger("[EXTENSIONS]");
344
+ const extensionConfig = getRequestConfig(
345
+ Array.isArray(params) ? params : [null, params]
346
+ );
347
+ if (config.extensions) {
348
+ for (const create2 of config.extensions) {
349
+ if (typeof create2 !== "function") {
350
+ continue;
351
+ }
352
+ const ext = create2(instance);
353
+ if (extensionConfig.disableExtensions?.includes(ext.id)) {
354
+ continue;
355
+ }
356
+ if (ext.withContext && toRun === "withContext" /* withContext */) {
357
+ await ext.withContext(ctx);
358
+ }
359
+ if (ext.onHandleRequest && toRun === "onHandleRequest" /* onHandleRequest */) {
360
+ const result = await ext.onHandleRequest(
361
+ Array.isArray(params) ? params : [params]
362
+ );
363
+ debug(`${ext.id ?? create2.name} ran onHandleRequest`);
364
+ if (result != null) {
365
+ return result;
366
+ }
367
+ }
368
+ const [param] = Array.isArray(params) ? params : [params];
369
+ if (ext.onRequest && toRun === "onRequest" /* onRequest */) {
370
+ const { ...previousContext } = ctx.get();
371
+ const preserveHeaders = previousContext.preserveHeaders;
372
+ if (preserveHeaders) {
373
+ ctx.set({ preserveHeaders: false });
374
+ }
375
+ if (!_init) {
376
+ continue;
377
+ }
378
+ const previousHeaders = new Headers(previousContext.headers);
379
+ await ext.onRequest(_init.request, ctx);
380
+ const updatedContext = ctx.get();
381
+ if (updatedContext?.headers) {
382
+ const cookie = updatedContext.headers.get("cookie");
383
+ if (cookie && param.headers) {
384
+ const updatedCookies = mergeCookies(
385
+ preserveHeaders ? previousHeaders?.get("cookie") : null,
386
+ updatedContext.headers.get("cookie")
387
+ );
388
+ param.headers.set("cookie", updatedCookies);
389
+ }
390
+ if (updatedContext.tenantId && param.headers) {
391
+ param.headers.set(
392
+ TENANT_COOKIE,
393
+ String(updatedContext.headers.get(TENANT_COOKIE))
394
+ );
395
+ }
396
+ ctx.set({ headers: param.headers });
397
+ }
398
+ debug(`${ext.id ?? create2.name} ran onRequest`);
399
+ }
400
+ if (ext.onResponse && toRun === "onResponse" /* onResponse */) {
401
+ const result = await ext.onResponse(param, ctx);
402
+ debug(`${ext.id ?? create2.name} ran onResponse`);
403
+ if (result != null) {
404
+ return result;
405
+ }
406
+ }
407
+ }
408
+ }
409
+ return void 0;
410
+ };
411
+ }
412
+ function buildExtensionConfig(instance) {
413
+ return {
414
+ runExtensions: bindRunExtensions(instance)
415
+ };
416
+ }
417
+ function mergeCookies(...cookieStrings) {
418
+ const cookieMap = /* @__PURE__ */ new Map();
419
+ for (const str of cookieStrings) {
420
+ if (!str) continue;
421
+ for (const part of str.split(";")) {
422
+ const [key17, value] = part.split("=").map((s) => s.trim());
423
+ if (key17 && value) cookieMap.set(key17, value);
424
+ }
425
+ }
426
+ return [...cookieMap.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
427
+ }
428
+ async function runExtensionContext(config) {
429
+ await config?.extensionCtx?.runExtensions("withContext" /* withContext */, config);
430
+ }
431
+
432
+ // src/api/utils/request-context.ts
433
+ var { warn, silly } = Logger({ debug: true })("[REQUEST CONTEXT]");
434
+ var storage = new AsyncLocalStorage();
435
+ var defaultContext = {
436
+ headers: new Headers(),
437
+ tenantId: void 0,
438
+ userId: void 0,
439
+ preserveHeaders: false
440
+ };
441
+ var lastUsedContext = defaultContext;
442
+ var ctx = {
443
+ run(ctx2, fn) {
444
+ const merged = {
445
+ ...defaultContext,
446
+ ...ctx2,
447
+ headers: ctx2.headers instanceof Headers ? ctx2.headers : new Headers(ctx2.headers)
448
+ };
449
+ lastUsedContext = merged;
450
+ return storage.run(merged, fn);
451
+ },
452
+ get: () => {
453
+ const ctx2 = storage.getStore();
454
+ if (!ctx2) {
455
+ return { ...defaultContext };
456
+ }
457
+ silly(`[GET] ${serializeContext(ctx2)}`);
458
+ return ctx2;
459
+ },
460
+ /**
461
+ * This is a mirror of Server.getContext, but only for requests. We keep only the request
462
+ * information around, everything else is :above_my_pay_grade:
463
+ * @param partial A partial context to override
464
+ */
465
+ set: (partial) => {
466
+ const store = storage.getStore();
467
+ if (!store) {
468
+ warn("ctx.set() called outside of ctx.run(). This will not persist.");
469
+ return;
470
+ }
471
+ if (partial.headers === null) {
472
+ store.headers = new Headers();
473
+ } else if (partial.headers && store.headers instanceof Headers) {
474
+ for (const [k, v] of new Headers(partial.headers).entries()) {
475
+ store.headers.set(k, v);
476
+ }
477
+ }
478
+ if ("tenantId" in partial)
479
+ store.tenantId = partial.tenantId ?? store.tenantId;
480
+ if ("userId" in partial) store.userId = partial.userId ?? store.userId;
481
+ if ("preserveHeaders" in partial)
482
+ store.preserveHeaders = Boolean(partial.preserveHeaders);
483
+ silly(`[SET] ${serializeContext(store)}`);
484
+ lastUsedContext = { ...store };
485
+ },
486
+ // for convenience only
487
+ getLastUsed: () => lastUsedContext
488
+ };
489
+ function withNileContext(config, fn, name = "unknown") {
490
+ const initialContext = config.context;
491
+ const existing = ctx.get();
492
+ const mergedHeaders = new Headers(existing.headers);
493
+ if (initialContext instanceof Request) {
494
+ initialContext.headers.forEach((value, key17) => {
495
+ mergedHeaders.set(key17, value);
496
+ });
497
+ const context2 = {
498
+ headers: mergedHeaders,
499
+ tenantId: existing.tenantId,
500
+ userId: existing.userId,
501
+ preserveHeaders: existing.preserveHeaders ?? false
502
+ };
503
+ silly(`${name} [INITIAL - Request] ${serializeContext(context2)}`);
504
+ return ctx.run(context2, fn);
505
+ }
506
+ if (initialContext.headers) {
507
+ const incoming = initialContext.headers instanceof Headers ? initialContext.headers : new Headers(initialContext.headers);
508
+ incoming.forEach((value, key17) => {
509
+ mergedHeaders.set(key17, value);
510
+ });
511
+ }
512
+ const tenantId = "tenantId" in initialContext && initialContext.tenantId;
513
+ const userId = "userId" in initialContext && initialContext.userId;
514
+ const preserveHeaders = "preserveHeaders" in initialContext && initialContext.preserveHeaders;
515
+ const context = {
516
+ headers: mergedHeaders,
517
+ tenantId: tenantId ? tenantId : existing.tenantId,
518
+ userId: userId ? userId : existing.userId,
519
+ preserveHeaders: preserveHeaders ? preserveHeaders : existing.preserveHeaders ?? false
520
+ };
521
+ silly(`${name} [INITIAL - Partial<Context>] ${serializeContext(context)}`);
522
+ return ctx.run(context, async () => {
523
+ await runExtensionContext(config);
524
+ return fn();
525
+ });
526
+ }
527
+ function serializeContext(context) {
528
+ const headers = {};
529
+ const rawHeaders = new Headers(context.headers);
530
+ rawHeaders.forEach((value, key17) => {
531
+ headers[key17] = value;
532
+ });
533
+ return JSON.stringify({
534
+ headers,
535
+ tenantId: context.tenantId,
536
+ userId: context.userId,
537
+ preserveHeaders: context.preserveHeaders
538
+ });
539
+ }
540
+
262
541
  // src/api/routes/me/index.ts
263
542
  var key = "ME";
264
543
  async function route(request2, config) {
265
- const url = apiRoutes(config)[key];
544
+ const url = apiRoutes(config.apiUrl)[key];
266
545
  if (request2.method === "GET") {
267
546
  return await GET(url, { request: request2 }, config);
268
547
  }
@@ -283,8 +562,9 @@ function matches(configRoutes, request2) {
283
562
  }
284
563
  async function fetchMe(config, method, body) {
285
564
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/me" /* ME */}`;
565
+ const { headers } = ctx.get();
286
566
  const init = {
287
- headers: config.headers,
567
+ headers,
288
568
  method: method ?? "GET"
289
569
  };
290
570
  if (method === "PUT") {
@@ -336,9 +616,9 @@ function getTokenFromCookie(headers, cookieKey) {
336
616
  return _cookies[cookieKey];
337
617
  }
338
618
  }
339
- function getTenantFromHttp(headers, config) {
619
+ function getTenantFromHttp(headers, context) {
340
620
  const cookieTenant = getTokenFromCookie(headers, TENANT_COOKIE);
341
- return cookieTenant ? cookieTenant : config?.tenantId;
621
+ return cookieTenant ? cookieTenant : context?.tenantId;
342
622
  }
343
623
 
344
624
  // src/api/routes/users/POST.ts
@@ -348,8 +628,11 @@ async function POST(config, init) {
348
628
  const yurl = new URL(init.request.url);
349
629
  const tenantId = yurl.searchParams.get("tenantId");
350
630
  const newTenantName = yurl.searchParams.get("newTenantName");
351
- const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
352
- const url = apiRoutes(config).USERS({ tenantId: tenant, newTenantName });
631
+ const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
632
+ const url = apiRoutes(config.apiUrl).USERS({
633
+ tenantId: tenant,
634
+ newTenantName
635
+ });
353
636
  return await request(url, init, config);
354
637
  }
355
638
 
@@ -357,13 +640,13 @@ async function POST(config, init) {
357
640
  async function GET2(config, init, log) {
358
641
  const yurl = new URL(init.request.url);
359
642
  const tenantId = yurl.searchParams.get("tenantId");
360
- const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
643
+ const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config.context);
361
644
  if (!tenant) {
362
645
  log("[GET] No tenant id provided.");
363
646
  return new Response(null, { status: 404 });
364
647
  }
365
648
  init.method = "GET";
366
- const url = apiRoutes(config).TENANT_USERS(tenant);
649
+ const url = apiRoutes(config.apiUrl).TENANT_USERS(tenant);
367
650
  return await request(url, init, config);
368
651
  }
369
652
 
@@ -372,7 +655,7 @@ async function PUT2(config, init) {
372
655
  init.body = init.request.body;
373
656
  init.method = "PUT";
374
657
  const [userId] = new URL(init.request.url).pathname.split("/").reverse();
375
- const url = apiRoutes(config).USER(userId);
658
+ const url = apiRoutes(config.apiUrl).USER(userId);
376
659
  return await request(url, init, config);
377
660
  }
378
661
 
@@ -399,7 +682,7 @@ function matches2(configRoutes, request2) {
399
682
  async function GET3(config, init) {
400
683
  const yurl = new URL(init.request.url);
401
684
  const [, tenantId] = yurl.pathname.split("/").reverse();
402
- const url = `${apiRoutes(config).TENANT_USERS(tenantId)}`;
685
+ const url = `${apiRoutes(config.apiUrl).TENANT_USERS(tenantId)}`;
403
686
  return await request(url, init, config);
404
687
  }
405
688
 
@@ -413,7 +696,7 @@ async function POST2(config, init) {
413
696
  const [, tenantId] = yurl.pathname.split("/").reverse();
414
697
  init.body = JSON.stringify({ email: session.email });
415
698
  init.method = "POST";
416
- const url = apiRoutes(config).TENANT_USERS(tenantId);
699
+ const url = apiRoutes(config.apiUrl).TENANT_USERS(tenantId);
417
700
  return await request(url, init, config);
418
701
  }
419
702
 
@@ -447,12 +730,13 @@ function matches3(configRoutes, request2) {
447
730
  }
448
731
  async function fetchTenantUsers(config, method, payload) {
449
732
  const { body, params } = {};
450
- if (!config.tenantId) {
733
+ const { tenantId, headers } = ctx.get();
734
+ if (!tenantId) {
451
735
  throw new Error(
452
736
  "Unable to fetch the user's tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
453
737
  );
454
738
  }
455
- if (!isUUID(config.tenantId)) {
739
+ if (!isUUID(tenantId)) {
456
740
  config.logger("fetchTenantUsers").warn(
457
741
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
458
742
  );
@@ -464,14 +748,11 @@ async function fetchTenantUsers(config, method, payload) {
464
748
  if (params?.tenantId) {
465
749
  q.set("tenantId", params.tenantId);
466
750
  }
467
- const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
468
- "{tenantId}",
469
- config.tenantId
470
- )}`;
751
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace("{tenantId}", tenantId)}`;
471
752
  const m = method;
472
753
  const init = {
473
754
  method: m,
474
- headers: config.headers
755
+ headers
475
756
  };
476
757
  const req = new Request(clientUrl, init);
477
758
  return await config.handlers[m](req);
@@ -488,7 +769,7 @@ async function PUT3(config, init) {
488
769
  init.body = new URLSearchParams(yurl.searchParams).toString();
489
770
  }
490
771
  init.method = "PUT";
491
- const url = `${apiRoutes(config).INVITE(tenantId)}`;
772
+ const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
492
773
  const res = await request(url, init, config);
493
774
  const location = res?.headers?.get("location");
494
775
  if (location) {
@@ -512,7 +793,7 @@ async function POST3(config, init) {
512
793
  }
513
794
  init.method = "POST";
514
795
  init.body = init.request.body;
515
- const url = `${apiRoutes(config).INVITE(tenantId)}`;
796
+ const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
516
797
  return await request(url, init, config);
517
798
  }
518
799
 
@@ -538,21 +819,22 @@ function matches4(configRoutes, request2) {
538
819
  return urlMatches(request2.url, route20);
539
820
  }
540
821
  async function fetchInvite(config, method, body) {
541
- if (!config.tenantId) {
822
+ const { headers, tenantId } = ctx.get();
823
+ if (!tenantId) {
542
824
  throw new Error(
543
825
  "Unable to fetch the invite for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
544
826
  );
545
827
  }
546
- if (!isUUID(config.tenantId)) {
828
+ if (!isUUID(tenantId)) {
547
829
  config.logger("fetchInvite").warn(
548
830
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
549
831
  );
550
832
  }
551
- let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", config.tenantId)}`;
833
+ let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", tenantId)}`;
552
834
  const m = method ?? "GET";
553
835
  const init = {
554
836
  method: m,
555
- headers: config.headers
837
+ headers
556
838
  };
557
839
  if (method === "POST" || method === "PUT") {
558
840
  init.body = body;
@@ -572,7 +854,7 @@ async function GET4(config, init) {
572
854
  return new Response(null, { status: 404 });
573
855
  }
574
856
  init.method = "GET";
575
- const url = `${apiRoutes(config).INVITES(tenantId)}`;
857
+ const url = `${apiRoutes(config.apiUrl).INVITES(tenantId)}`;
576
858
  return await request(url, init, config);
577
859
  }
578
860
 
@@ -593,29 +875,29 @@ function matches5(configRoutes, request2) {
593
875
  return url.pathname.endsWith(route20);
594
876
  }
595
877
  async function fetchInvites(config) {
596
- if (!config.tenantId) {
878
+ const { tenantId, headers } = ctx.get();
879
+ if (!tenantId) {
597
880
  throw new Error(
598
881
  "Unable to fetch invites for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
599
882
  );
600
883
  }
601
- if (!isUUID(config.tenantId)) {
884
+ if (!isUUID(tenantId)) {
602
885
  config.logger("fetchInvites").warn(
603
886
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
604
887
  );
605
888
  }
606
- const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}", config.tenantId)}`;
607
- const req = new Request(clientUrl, { headers: config.headers });
889
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}", tenantId)}`;
890
+ const req = new Request(clientUrl, { headers });
608
891
  return await config.handlers.GET(req);
609
892
  }
610
893
 
611
894
  // src/api/routes/tenants/GET.ts
612
895
  async function GET5(config, session, init) {
613
- let url = `${apiRoutes(config).USER_TENANTS(session.id)}`;
896
+ let url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.id)}`;
614
897
  if (typeof session === "object" && "user" in session && session.user) {
615
- url = `${apiRoutes(config).USER_TENANTS(session.user.id)}`;
898
+ url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.user.id)}`;
616
899
  }
617
- const res = await request(url, init, config);
618
- return res;
900
+ return await request(url, init, config);
619
901
  }
620
902
 
621
903
  // src/api/routes/tenants/[tenantId]/GET.ts
@@ -627,7 +909,7 @@ async function GET6(config, init, log) {
627
909
  return new Response(null, { status: 404 });
628
910
  }
629
911
  init.method = "GET";
630
- const url = `${apiRoutes(config).TENANT(tenantId)}`;
912
+ const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
631
913
  return await request(url, init, config);
632
914
  }
633
915
 
@@ -639,7 +921,7 @@ async function DELETE2(config, init) {
639
921
  return new Response(null, { status: 404 });
640
922
  }
641
923
  init.method = "DELETE";
642
- const url = `${apiRoutes(config).TENANT(tenantId)}`;
924
+ const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
643
925
  return await request(url, init, config);
644
926
  }
645
927
 
@@ -652,7 +934,7 @@ async function PUT4(config, init) {
652
934
  }
653
935
  init.body = init.request.body;
654
936
  init.method = "PUT";
655
- const url = `${apiRoutes(config).TENANT(tenantId)}`;
937
+ const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
656
938
  return await request(url, init, config);
657
939
  }
658
940
 
@@ -660,7 +942,7 @@ async function PUT4(config, init) {
660
942
  async function POST4(config, init) {
661
943
  init.body = init.request.body;
662
944
  init.method = "POST";
663
- const url = `${apiRoutes(config).TENANTS}`;
945
+ const url = `${apiRoutes(config.apiUrl).TENANTS}`;
664
946
  return await request(url, init, config);
665
947
  }
666
948
 
@@ -694,10 +976,11 @@ function matches6(configRoutes, request2) {
694
976
  return urlMatches(request2.url, configRoutes[key6]);
695
977
  }
696
978
  async function fetchTenants(config, method, body) {
979
+ const { headers } = ctx.get();
697
980
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
698
981
  const init = {
699
982
  method,
700
- headers: config.headers
983
+ headers
701
984
  };
702
985
  {
703
986
  init.body = body;
@@ -706,21 +989,22 @@ async function fetchTenants(config, method, body) {
706
989
  return await config.handlers.POST(req);
707
990
  }
708
991
  async function fetchTenant(config, method, body) {
709
- if (!config.tenantId) {
992
+ const { headers, tenantId } = ctx.get();
993
+ if (!tenantId) {
710
994
  throw new Error(
711
995
  "Unable to fetch tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
712
996
  );
713
997
  }
714
- if (!isUUID(config.tenantId)) {
998
+ if (!isUUID(tenantId)) {
715
999
  config.logger("fetch tenant").warn(
716
1000
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
717
1001
  );
718
1002
  }
719
- const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", config.tenantId)}`;
1003
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", tenantId)}`;
720
1004
  const m = method ?? "GET";
721
1005
  const init = {
722
1006
  method: m,
723
- headers: config.headers
1007
+ headers
724
1008
  };
725
1009
  if (m === "PUT") {
726
1010
  init.body = body;
@@ -729,32 +1013,33 @@ async function fetchTenant(config, method, body) {
729
1013
  return await config.handlers[m](req);
730
1014
  }
731
1015
  async function fetchTenantsByUser(config) {
732
- const { warn } = config.logger("fetchTenantsByUser");
733
- if (!config.userId) {
734
- warn(
1016
+ const { warn: warn2 } = config.logger(" fetchTenantsByUser ");
1017
+ const { userId, headers } = ctx.get();
1018
+ if (!userId) {
1019
+ warn2(
735
1020
  "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."
736
1021
  );
737
- } else if (!isUUID(config.userId)) {
738
- warn(
1022
+ } else if (!isUUID(userId)) {
1023
+ warn2(
739
1024
  "nile.userId is not a valid UUID. This may lead to unexpected behavior in your application."
740
1025
  );
741
1026
  }
742
1027
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
743
- const req = new Request(clientUrl, { headers: config.headers });
1028
+ const req = new Request(clientUrl, { headers });
744
1029
  return await config.handlers.GET(req);
745
1030
  }
746
1031
 
747
1032
  // src/api/routes/auth/signin.ts
748
1033
  var key7 = "SIGNIN";
749
1034
  async function route7(req, config) {
750
- let url = proxyRoutes(config)[key7];
1035
+ let url = proxyRoutes(config.apiUrl)[key7];
751
1036
  const init = {
752
1037
  method: req.method,
753
1038
  headers: req.headers
754
1039
  };
755
1040
  if (req.method === "POST") {
756
1041
  const [provider] = new URL(req.url).pathname.split("/").reverse();
757
- url = `${proxyRoutes(config)[key7]}/${provider}`;
1042
+ url = `${proxyRoutes(config.apiUrl)[key7]}/${provider}`;
758
1043
  }
759
1044
  const passThroughUrl = new URL(req.url);
760
1045
  const params = new URLSearchParams(passThroughUrl.search);
@@ -767,10 +1052,11 @@ function matches7(configRoutes, request2) {
767
1052
  }
768
1053
  async function fetchSignIn(config, provider, body) {
769
1054
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
1055
+ const { headers } = ctx.get();
770
1056
  const req = new Request(clientUrl, {
771
1057
  method: "POST",
772
- headers: config.headers,
773
- body
1058
+ body,
1059
+ headers
774
1060
  });
775
1061
  return await config.handlers.POST(req);
776
1062
  }
@@ -778,7 +1064,7 @@ async function fetchSignIn(config, provider, body) {
778
1064
  // src/api/routes/auth/session.ts
779
1065
  async function route8(req, config) {
780
1066
  return request(
781
- proxyRoutes(config).SESSION,
1067
+ proxyRoutes(config.apiUrl).SESSION,
782
1068
  {
783
1069
  method: req.method,
784
1070
  request: req
@@ -791,9 +1077,10 @@ function matches8(configRoutes, request2) {
791
1077
  }
792
1078
  async function fetchSession(config) {
793
1079
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
1080
+ const { headers } = ctx.get();
794
1081
  const req = new Request(clientUrl, {
795
1082
  method: "GET",
796
- headers: config.headers
1083
+ headers
797
1084
  });
798
1085
  return await config.handlers.GET(req);
799
1086
  }
@@ -801,7 +1088,7 @@ async function fetchSession(config) {
801
1088
  // src/api/routes/auth/providers.ts
802
1089
  async function route9(req, config) {
803
1090
  return request(
804
- proxyRoutes(config).PROVIDERS,
1091
+ proxyRoutes(config.apiUrl).PROVIDERS,
805
1092
  {
806
1093
  method: req.method,
807
1094
  request: req
@@ -814,9 +1101,10 @@ function matches9(configRoutes, request2) {
814
1101
  }
815
1102
  async function fetchProviders(config) {
816
1103
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
1104
+ const { headers } = ctx.get();
817
1105
  const req = new Request(clientUrl, {
818
1106
  method: "GET",
819
- headers: config.headers
1107
+ headers
820
1108
  });
821
1109
  return await config.handlers.GET(req);
822
1110
  }
@@ -824,7 +1112,7 @@ async function fetchProviders(config) {
824
1112
  // src/api/routes/auth/csrf.ts
825
1113
  async function route10(req, config) {
826
1114
  return request(
827
- proxyRoutes(config).CSRF,
1115
+ proxyRoutes(config.apiUrl).CSRF,
828
1116
  {
829
1117
  method: req.method,
830
1118
  request: req
@@ -837,9 +1125,10 @@ function matches10(configRoutes, request2) {
837
1125
  }
838
1126
  async function fetchCsrf(config) {
839
1127
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
1128
+ const { headers } = ctx.get();
840
1129
  const req = new Request(clientUrl, {
841
1130
  method: "GET",
842
- headers: config.headers
1131
+ headers
843
1132
  });
844
1133
  return await config.handlers.GET(req);
845
1134
  }
@@ -852,7 +1141,7 @@ async function route11(req, config) {
852
1141
  try {
853
1142
  const passThroughUrl = new URL(req.url);
854
1143
  const params = new URLSearchParams(passThroughUrl.search);
855
- const url = `${proxyRoutes(config)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
1144
+ const url = `${proxyRoutes(config.apiUrl)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
856
1145
  const res = await request(
857
1146
  url,
858
1147
  {
@@ -883,10 +1172,11 @@ function matches11(configRoutes, request2) {
883
1172
  return urlMatches(request2.url, configRoutes.CALLBACK);
884
1173
  }
885
1174
  async function fetchCallback(config, provider, body, request2, method = "POST") {
1175
+ const { headers } = ctx.get();
886
1176
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}${request2 ? `?${new URL(request2.url).searchParams}` : ""}`;
887
1177
  const req = new Request(clientUrl, {
888
1178
  method,
889
- headers: config.headers,
1179
+ headers,
890
1180
  body
891
1181
  });
892
1182
  return await config.handlers.POST(req);
@@ -895,14 +1185,14 @@ async function fetchCallback(config, provider, body, request2, method = "POST")
895
1185
  // src/api/routes/auth/signout.ts
896
1186
  var key9 = "SIGNOUT";
897
1187
  async function route12(request2, config) {
898
- let url = proxyRoutes(config)[key9];
1188
+ let url = proxyRoutes(config.apiUrl)[key9];
899
1189
  const init = {
900
1190
  method: request2.method
901
1191
  };
902
1192
  if (request2.method === "POST") {
903
1193
  init.body = request2.body;
904
1194
  const [provider] = new URL(request2.url).pathname.split("/").reverse();
905
- url = `${proxyRoutes(config)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
1195
+ url = `${proxyRoutes(config.apiUrl)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
906
1196
  }
907
1197
  const res = await request(url, { ...init, request: request2 }, config);
908
1198
  return res;
@@ -912,10 +1202,11 @@ function matches12(configRoutes, request2) {
912
1202
  }
913
1203
  async function fetchSignOut(config, body) {
914
1204
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
1205
+ const { headers } = ctx.get();
915
1206
  const req = new Request(clientUrl, {
916
1207
  method: "POST",
917
1208
  body,
918
- headers: config.headers
1209
+ headers
919
1210
  });
920
1211
  return await config.handlers.POST(req);
921
1212
  }
@@ -924,7 +1215,7 @@ async function fetchSignOut(config, body) {
924
1215
  var key10 = "ERROR";
925
1216
  async function route13(req, config) {
926
1217
  return request(
927
- proxyRoutes(config)[key10],
1218
+ proxyRoutes(config.apiUrl)[key10],
928
1219
  {
929
1220
  method: req.method,
930
1221
  request: req
@@ -940,7 +1231,7 @@ function matches13(configRoutes, request2) {
940
1231
  var key11 = "VERIFY_REQUEST";
941
1232
  async function route14(req, config) {
942
1233
  return request(
943
- proxyRoutes(config)[key11],
1234
+ proxyRoutes(config.apiUrl)[key11],
944
1235
  {
945
1236
  method: req.method,
946
1237
  request: req
@@ -955,7 +1246,7 @@ function matches14(configRoutes, request2) {
955
1246
  // src/api/routes/auth/password-reset.ts
956
1247
  var key12 = "PASSWORD_RESET";
957
1248
  async function route15(req, config) {
958
- const url = proxyRoutes(config)[key12];
1249
+ const url = proxyRoutes(config.apiUrl)[key12];
959
1250
  const res = await request(
960
1251
  url,
961
1252
  {
@@ -984,10 +1275,11 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
984
1275
  if (useJson) {
985
1276
  authParams?.set("json", "true");
986
1277
  }
1278
+ const { headers } = ctx.get();
987
1279
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}?${authParams?.toString()}`;
988
1280
  const init = {
989
1281
  method,
990
- headers: config.headers
1282
+ headers
991
1283
  };
992
1284
  if (body && method !== "GET") {
993
1285
  init.body = body;
@@ -999,7 +1291,7 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
999
1291
  // src/api/routes/auth/verify-email.ts
1000
1292
  var key13 = "VERIFY_EMAIL";
1001
1293
  async function route16(req, config) {
1002
- const url = proxyRoutes(config)[key13];
1294
+ const url = proxyRoutes(config.apiUrl)[key13];
1003
1295
  const res = await request(
1004
1296
  url,
1005
1297
  {
@@ -1025,9 +1317,10 @@ function matches16(configRoutes, request2) {
1025
1317
  }
1026
1318
  async function fetchVerifyEmail(config, method, body) {
1027
1319
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`;
1320
+ const { headers } = ctx.get();
1028
1321
  const init = {
1029
1322
  method,
1030
- headers: config.headers
1323
+ headers
1031
1324
  };
1032
1325
  if (body) {
1033
1326
  init.body = body;
@@ -1038,7 +1331,7 @@ async function fetchVerifyEmail(config, method, body) {
1038
1331
 
1039
1332
  // src/api/handlers/GET.ts
1040
1333
  function GETTER(configRoutes, config) {
1041
- const { error, info, warn } = config.logger("[GET MATCHER]");
1334
+ const { error, info, warn: warn2 } = config.logger("[GET MATCHER]");
1042
1335
  return async function GET7(...params) {
1043
1336
  const handledRequest = await config.extensionCtx?.runExtensions(
1044
1337
  "onHandleRequest" /* onHandleRequest */,
@@ -1117,78 +1410,16 @@ function GETTER(configRoutes, config) {
1117
1410
  info("matches error");
1118
1411
  return route13(req, config);
1119
1412
  }
1120
- warn(`No GET routes matched ${req.url}`);
1413
+ warn2(`No GET routes matched ${req.url}`);
1121
1414
  return new Response(null, { status: 404 });
1122
1415
  };
1123
1416
  }
1124
1417
 
1125
- // src/utils/Logger.ts
1126
- var red = "\x1B[31m";
1127
- var yellow = "\x1B[38;2;255;255;0m";
1128
- var purple = "\x1B[38;2;200;160;255m";
1129
- var orange = "\x1B[38;2;255;165;0m";
1130
- var reset = "\x1B[0m";
1131
- var baseLogger = (config, ...params) => ({
1132
- info(message, meta) {
1133
- if (config?.debug) {
1134
- console.info(
1135
- `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
1136
- ""
1137
- )}${reset} ${message}`,
1138
- meta ? `${JSON.stringify(meta)}` : ""
1139
- );
1140
- }
1141
- },
1142
- debug(message, meta) {
1143
- if (config?.debug) {
1144
- console.info(
1145
- `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
1146
- ""
1147
- )}${reset} ${message}`,
1148
- meta ? `${JSON.stringify(meta)}` : ""
1149
- );
1150
- }
1151
- },
1152
- warn(message, meta) {
1153
- if (config?.debug) {
1154
- console.warn(
1155
- `${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
1156
- ""
1157
- )}${reset} ${message}`,
1158
- meta ? JSON.stringify(meta) : ""
1159
- );
1160
- }
1161
- },
1162
- error(message, meta) {
1163
- console.error(
1164
- `${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
1165
- ""
1166
- )}${red} ${message}`,
1167
- meta ? meta : "",
1168
- `${reset}`
1169
- );
1170
- }
1171
- });
1172
- function Logger(config) {
1173
- return (prefixes) => {
1174
- const { info, debug, warn, error } = config && typeof config?.logger === "function" ? config.logger(prefixes) : baseLogger(config, prefixes);
1175
- return {
1176
- info,
1177
- debug,
1178
- warn,
1179
- error
1180
- };
1181
- };
1182
- }
1183
- function matchesLog(configRoutes, request2) {
1184
- return urlMatches(request2.url, configRoutes.LOG);
1185
- }
1186
-
1187
1418
  // src/api/routes/signup/POST.ts
1188
1419
  async function POST5(config, init) {
1189
1420
  init.body = init.request.body;
1190
1421
  init.method = "POST";
1191
- const url = `${apiRoutes(config).SIGNUP}`;
1422
+ const url = `${apiRoutes(config.apiUrl).SIGNUP}`;
1192
1423
  return await request(url, init, config);
1193
1424
  }
1194
1425
 
@@ -1215,9 +1446,10 @@ async function fetchSignUp(config, payload) {
1215
1446
  q.set("tenantId", params.tenantId);
1216
1447
  }
1217
1448
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
1449
+ const { headers } = ctx.get();
1218
1450
  const req = new Request(clientUrl, {
1219
1451
  method: "POST",
1220
- headers: config.headers,
1452
+ headers,
1221
1453
  body
1222
1454
  });
1223
1455
  return await config.handlers.POST(req);
@@ -1225,7 +1457,7 @@ async function fetchSignUp(config, payload) {
1225
1457
 
1226
1458
  // src/api/handlers/POST.ts
1227
1459
  function POSTER(configRoutes, config) {
1228
- const { info, warn, error } = config.logger("[POST MATCHER]");
1460
+ const { info, warn: warn2, error } = config.logger("[POST MATCHER]");
1229
1461
  return async function POST6(...params) {
1230
1462
  const handledRequest = await config.extensionCtx?.runExtensions(
1231
1463
  "onHandleRequest" /* onHandleRequest */,
@@ -1261,10 +1493,6 @@ function POSTER(configRoutes, config) {
1261
1493
  info("matches signup");
1262
1494
  return route17(req, config);
1263
1495
  }
1264
- if (matches2(configRoutes, req)) {
1265
- info("matches users");
1266
- return route2(req, config);
1267
- }
1268
1496
  if (matches6(configRoutes, req)) {
1269
1497
  info("matches tenants");
1270
1498
  return route6(req, config);
@@ -1301,7 +1529,7 @@ function POSTER(configRoutes, config) {
1301
1529
  info("matches verify-email");
1302
1530
  return route16(req, config);
1303
1531
  }
1304
- warn(`No POST routes matched ${req.url}`);
1532
+ warn2(`No POST routes matched ${req.url}`);
1305
1533
  return new Response(null, { status: 404 });
1306
1534
  };
1307
1535
  }
@@ -1310,10 +1538,8 @@ function POSTER(configRoutes, config) {
1310
1538
  async function DELETE3(config, init) {
1311
1539
  const yurl = new URL(init.request.url);
1312
1540
  const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
1313
- config.tenantId = tenantId;
1314
- config.userId = userId;
1315
1541
  init.method = "DELETE";
1316
- const url = `${apiRoutes(config).TENANT_USER}/link`;
1542
+ const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
1317
1543
  return await request(url, init, config);
1318
1544
  }
1319
1545
 
@@ -1321,10 +1547,8 @@ async function DELETE3(config, init) {
1321
1547
  async function PUT5(config, init) {
1322
1548
  const yurl = new URL(init.request.url);
1323
1549
  const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
1324
- config.tenantId = tenantId;
1325
- config.userId = userId;
1326
1550
  init.method = "PUT";
1327
- const url = `${apiRoutes(config).TENANT_USER}/link`;
1551
+ const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
1328
1552
  return await request(url, init, config);
1329
1553
  }
1330
1554
 
@@ -1362,22 +1586,24 @@ function matches18(configRoutes, request2) {
1362
1586
  return urlMatches(request2.url, route20);
1363
1587
  }
1364
1588
  async function fetchTenantUser(config, method) {
1365
- if (!config.tenantId) {
1589
+ const { headers, tenantId, userId } = ctx.get();
1590
+ const action = method === "PUT" ? "add" : "delete";
1591
+ if (!tenantId) {
1366
1592
  throw new Error(
1367
- "The tenantId context is missing. Call nile.setContext({ tenantId })"
1593
+ `Unable to ${action} user to the tenant, the tenantId context is missing. Use nile.withContext({ tenantId })`
1368
1594
  );
1369
1595
  }
1370
- if (!config.userId) {
1596
+ if (!userId) {
1371
1597
  throw new Error(
1372
- "the userId context is missing. Call nile.setContext({ userId })"
1598
+ `Unable to ${action} user to tenant. The userId context is missing. Use nile.withContext({ userId })`
1373
1599
  );
1374
1600
  }
1375
- const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
1376
- "{tenantId}",
1377
- config.tenantId
1378
- ).replace("{userId}", config.userId)}/link`;
1601
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace("{tenantId}", tenantId).replace(
1602
+ "{userId}",
1603
+ userId
1604
+ )}/link`;
1379
1605
  const req = new Request(clientUrl, {
1380
- headers: config.headers,
1606
+ headers,
1381
1607
  method
1382
1608
  });
1383
1609
  return await config.handlers[method](req);
@@ -1391,7 +1617,7 @@ async function DELETE4(config, init) {
1391
1617
  return new Response(null, { status: 404 });
1392
1618
  }
1393
1619
  init.method = "DELETE";
1394
- const url = `${apiRoutes(config).INVITE(tenantId)}/${inviteId}`;
1620
+ const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}/${inviteId}`;
1395
1621
  return await request(url, init, config);
1396
1622
  }
1397
1623
 
@@ -1414,7 +1640,7 @@ function matches19(configRoutes, request2) {
1414
1640
 
1415
1641
  // src/api/handlers/DELETE.ts
1416
1642
  function DELETER(configRoutes, config) {
1417
- const { error, info, warn } = config.logger("[DELETE MATCHER]");
1643
+ const { error, info, warn: warn2 } = config.logger("[DELETE MATCHER]");
1418
1644
  return async function DELETE5(...params) {
1419
1645
  const handledRequest = await config.extensionCtx?.runExtensions(
1420
1646
  "onHandleRequest" /* onHandleRequest */,
@@ -1445,14 +1671,14 @@ function DELETER(configRoutes, config) {
1445
1671
  info("matches me");
1446
1672
  return route(req, config);
1447
1673
  }
1448
- warn("No DELETE routes matched");
1674
+ warn2("No DELETE routes matched");
1449
1675
  return new Response(null, { status: 404 });
1450
1676
  };
1451
1677
  }
1452
1678
 
1453
1679
  // src/api/handlers/PUT.ts
1454
1680
  function PUTER(configRoutes, config) {
1455
- const { error, info, warn } = config.logger("[PUT MATCHER]");
1681
+ const { error, info, warn: warn2 } = config.logger("[PUT MATCHER]");
1456
1682
  return async function PUT6(...params) {
1457
1683
  const handledRequest = await config.extensionCtx?.runExtensions(
1458
1684
  "onHandleRequest" /* onHandleRequest */,
@@ -1479,10 +1705,6 @@ function PUTER(configRoutes, config) {
1479
1705
  info("matches tenant users");
1480
1706
  return route3(req, config);
1481
1707
  }
1482
- if (matches2(configRoutes, req)) {
1483
- info("matches users");
1484
- return route2(req, config);
1485
- }
1486
1708
  if (matches(configRoutes, req)) {
1487
1709
  info("matches me");
1488
1710
  return route(req, config);
@@ -1495,7 +1717,7 @@ function PUTER(configRoutes, config) {
1495
1717
  info("matches reset password");
1496
1718
  return route15(req, config);
1497
1719
  }
1498
- warn("No PUT routes matched");
1720
+ warn2("No PUT routes matched");
1499
1721
  return new Response(null, { status: 404 });
1500
1722
  };
1501
1723
  }
@@ -1699,25 +1921,14 @@ var Config = class {
1699
1921
  extensionCtx;
1700
1922
  extensions;
1701
1923
  logger;
1924
+ context;
1702
1925
  /**
1703
- * Stores the set tenant id from Server for use in sub classes
1926
+ * The nile-auth url
1704
1927
  */
1705
- tenantId;
1928
+ apiUrl;
1929
+ origin;
1706
1930
  /**
1707
- * Stores the set user id from Server for use in sub classes
1708
- */
1709
- userId;
1710
- /**
1711
- * Stores the headers to be used in `fetch` calls
1712
- */
1713
- headers;
1714
- /**
1715
- * The nile-auth url
1716
- */
1717
- apiUrl;
1718
- origin;
1719
- /**
1720
- * important for separating the `origin` config value from a default in order to make requests
1931
+ * important for separating the `origin` config value from a default in order to make requests
1721
1932
  */
1722
1933
  serverOrigin;
1723
1934
  debug;
@@ -1761,11 +1972,12 @@ var Config = class {
1761
1972
  if (databaseName) {
1762
1973
  this.db.database = databaseName;
1763
1974
  }
1764
- if (config?.headers) {
1765
- this.headers = config?.headers;
1766
- } else {
1767
- this.headers = new Headers();
1768
- }
1975
+ this.context = {
1976
+ tenantId: config?.tenantId,
1977
+ userId: config?.userId,
1978
+ headers: config?.headers ? new Headers(config.headers) : new Headers(),
1979
+ preserveHeaders: false
1980
+ };
1769
1981
  this.routes = {
1770
1982
  ...appRoutes(config?.routePrefix),
1771
1983
  ...config?.routes
@@ -1808,8 +2020,6 @@ var Config = class {
1808
2020
  ],
1809
2021
  delete: [this.routes.TENANT_USER, this.routes.TENANT]
1810
2022
  };
1811
- this.tenantId = config?.tenantId;
1812
- this.userId = config?.userId;
1813
2023
  }
1814
2024
  };
1815
2025
 
@@ -1876,7 +2086,15 @@ function createProxyForPool(pool, config) {
1876
2086
  }
1877
2087
  const caller = target[property];
1878
2088
  return function query(...args) {
1879
- info("query", ...args);
2089
+ let log = "[QUERY]";
2090
+ const { userId, tenantId } = config.context;
2091
+ if (tenantId) {
2092
+ log = `${log}[TENANT:${tenantId}]`;
2093
+ }
2094
+ if (userId) {
2095
+ log = `${log}[USER:${userId}]`;
2096
+ }
2097
+ info(log, ...args);
1880
2098
  const called = caller.apply(this, args);
1881
2099
  return called;
1882
2100
  };
@@ -1895,7 +2113,7 @@ var NileDatabase = class {
1895
2113
  config;
1896
2114
  timer;
1897
2115
  constructor(config, id) {
1898
- const { warn, info, debug } = config.logger("[NileInstance]");
2116
+ const { warn: warn2, info, debug } = config.logger("[NileInstance]");
1899
2117
  this.id = id;
1900
2118
  const poolConfig = {
1901
2119
  min: 0,
@@ -1911,7 +2129,7 @@ var NileDatabase = class {
1911
2129
  debug(`Connection pool config ${JSON.stringify(cloned)}`);
1912
2130
  this.pool = createProxyForPool(new pg.Pool(remaining), this.config);
1913
2131
  if (typeof afterCreate === "function") {
1914
- warn(
2132
+ warn2(
1915
2133
  "Providing an pool configuration will stop automatic tenant context setting."
1916
2134
  );
1917
2135
  }
@@ -1977,7 +2195,7 @@ var NileDatabase = class {
1977
2195
  };
1978
2196
  var NileInstance_default = NileDatabase;
1979
2197
  function makeAfterCreate(config, id) {
1980
- const { error, warn, debug } = config.logger("[afterCreate]");
2198
+ const { error, warn: warn2, debug } = config.logger("[afterCreate]");
1981
2199
  return (conn, done) => {
1982
2200
  conn.on("error", function errorHandler(e) {
1983
2201
  error(`Connection ${id} was terminated by server`, {
@@ -1986,13 +2204,15 @@ function makeAfterCreate(config, id) {
1986
2204
  });
1987
2205
  done(e, conn);
1988
2206
  });
1989
- if (config.tenantId) {
1990
- const query = [`SET nile.tenant_id = '${config.tenantId}'`];
1991
- if (config.userId) {
1992
- if (!config.tenantId) {
1993
- warn("A user id cannot be set in context without a tenant id");
2207
+ const tenantId = config.context.tenantId;
2208
+ const userId = config.context.userId;
2209
+ if (tenantId) {
2210
+ const query = [`SET nile.tenant_id = '${tenantId}'`];
2211
+ if (userId) {
2212
+ if (!tenantId) {
2213
+ warn2("A user id cannot be set in context without a tenant id");
1994
2214
  }
1995
- query.push(`SET nile.user_id = '${config.userId}'`);
2215
+ query.push(`SET nile.user_id = '${userId}'`);
1996
2216
  }
1997
2217
  conn.query(query.join(";"), function(err) {
1998
2218
  if (err) {
@@ -2005,11 +2225,11 @@ function makeAfterCreate(config, id) {
2005
2225
  });
2006
2226
  } else {
2007
2227
  if (query.length === 1) {
2008
- debug(`connection context set: tenantId=${config.tenantId}`);
2228
+ debug(`connection context set: tenantId=${tenantId}`);
2009
2229
  }
2010
2230
  if (query.length === 2) {
2011
2231
  debug(
2012
- `connection context set: tenantId=${config.tenantId} userId=${config.userId}`
2232
+ `connection context set: tenantId=${tenantId} userId=${userId}`
2013
2233
  );
2014
2234
  }
2015
2235
  }
@@ -2041,19 +2261,19 @@ var DBManager = class {
2041
2261
  watchEvictPool(this.poolWatcherFn);
2042
2262
  }
2043
2263
  poolWatcher = (config) => (id) => {
2044
- const { info, warn } = Logger(config)("[DBManager]");
2264
+ const { info, warn: warn2 } = Logger(config)("[DBManager]");
2045
2265
  if (id && this.connections.has(id)) {
2046
2266
  info(`Removing ${id} from db connection pool.`);
2047
2267
  const connection = this.connections.get(id);
2048
2268
  connection?.shutdown();
2049
2269
  this.connections.delete(id);
2050
2270
  } else {
2051
- warn(`missed eviction of ${id}`);
2271
+ warn2(`missed eviction of ${id}`);
2052
2272
  }
2053
2273
  };
2054
2274
  getConnection = (config) => {
2055
2275
  const { info } = Logger(config)("[DBManager]");
2056
- const id = this.makeId(config.tenantId, config.userId);
2276
+ const id = this.makeId(config.context.tenantId, config.context.userId);
2057
2277
  const existing = this.connections.get(id);
2058
2278
  info(`# of instances: ${this.connections.size}`);
2059
2279
  if (existing) {
@@ -2061,7 +2281,7 @@ var DBManager = class {
2061
2281
  existing.startTimeout();
2062
2282
  return existing.pool;
2063
2283
  }
2064
- const newOne = new NileInstance_default(new Config(config), id);
2284
+ const newOne = new NileInstance_default(config, id);
2065
2285
  this.connections.set(id, newOne);
2066
2286
  info(`created new ${id}`);
2067
2287
  info(`# of instances: ${this.connections.size}`);
@@ -2096,33 +2316,39 @@ var Auth = class {
2096
2316
  this.#logger = config.logger("[auth]");
2097
2317
  }
2098
2318
  async getSession(rawResponse = false) {
2099
- const res = await fetchSession(this.#config);
2100
- if (rawResponse) {
2101
- return res;
2102
- }
2103
- try {
2104
- const session = await res.clone().json();
2105
- if (Object.keys(session).length === 0) {
2106
- return void 0;
2319
+ return withNileContext(this.#config, async () => {
2320
+ const res = await fetchSession(this.#config);
2321
+ if (rawResponse) {
2322
+ return res;
2107
2323
  }
2108
- return session;
2109
- } catch {
2110
- return res;
2111
- }
2324
+ try {
2325
+ const session = await res.clone().json();
2326
+ if (Object.keys(session).length === 0) {
2327
+ return void 0;
2328
+ }
2329
+ return session;
2330
+ } catch {
2331
+ return res;
2332
+ }
2333
+ });
2112
2334
  }
2113
2335
  async getCsrf(rawResponse = false) {
2114
- return await obtainCsrf(this.#config, rawResponse);
2336
+ return withNileContext(this.#config, async () => {
2337
+ return await obtainCsrf(this.#config, rawResponse);
2338
+ });
2115
2339
  }
2116
2340
  async listProviders(rawResponse = false) {
2117
- const res = await fetchProviders(this.#config);
2118
- if (rawResponse) {
2119
- return res;
2120
- }
2121
- try {
2122
- return await res.clone().json();
2123
- } catch {
2124
- return res;
2125
- }
2341
+ return withNileContext(this.#config, async () => {
2342
+ const res = await fetchProviders(this.#config);
2343
+ if (rawResponse) {
2344
+ return res;
2345
+ }
2346
+ try {
2347
+ return await res.clone().json();
2348
+ } catch {
2349
+ return res;
2350
+ }
2351
+ });
2126
2352
  }
2127
2353
  /**
2128
2354
  * Sign the current user out by calling `/api/auth/signout`.
@@ -2131,73 +2357,79 @@ var Auth = class {
2131
2357
  * from the internal configuration once the request completes.
2132
2358
  */
2133
2359
  async signOut() {
2134
- const csrfRes = await this.getCsrf();
2135
- if (!("csrfToken" in csrfRes)) {
2136
- throw new Error("Unable to obtain CSRF token. Sign out failed.");
2137
- }
2138
- const body = JSON.stringify({
2139
- csrfToken: csrfRes.csrfToken,
2140
- json: true
2360
+ return withNileContext(this.#config, async () => {
2361
+ const csrfRes = await this.getCsrf();
2362
+ if (!("csrfToken" in csrfRes)) {
2363
+ throw new Error("Unable to obtain CSRF token. Sign out failed.");
2364
+ }
2365
+ const body = JSON.stringify({
2366
+ csrfToken: csrfRes.csrfToken,
2367
+ json: true
2368
+ });
2369
+ const res = await fetchSignOut(this.#config, body);
2370
+ updateHeaders(new Headers({}));
2371
+ ctx.set({ headers: null });
2372
+ return res;
2141
2373
  });
2142
- const res = await fetchSignOut(this.#config, body);
2143
- updateHeaders(new Headers({}));
2144
- this.#config.headers = new Headers();
2145
- return res;
2146
2374
  }
2147
2375
  async signUp(payload, rawResponse) {
2148
- this.#config.headers = new Headers();
2149
- const { email, password, ...params } = payload;
2150
- if (!email || !password) {
2151
- throw new Error(
2152
- "Server side sign up requires a user email and password."
2153
- );
2154
- }
2155
- const providers = await this.listProviders();
2156
- const { credentials } = providers ?? {};
2157
- if (!credentials) {
2158
- throw new Error(
2159
- "Unable to obtain credential provider. Aborting server side sign up."
2160
- );
2161
- }
2162
- const csrf = await this.getCsrf();
2163
- let csrfToken;
2164
- if ("csrfToken" in csrf) {
2165
- csrfToken = csrf.csrfToken;
2166
- } else {
2167
- throw new Error("Unable to obtain parse CSRF. Request blocked.");
2168
- }
2169
- const body = JSON.stringify({
2170
- email,
2171
- password,
2172
- csrfToken,
2173
- callbackUrl: credentials.callbackUrl
2174
- });
2175
- const res = await fetchSignUp(this.#config, { body, params });
2176
- if (res.status > 299) {
2177
- this.#logger.error(await res.clone().text());
2178
- return void 0;
2179
- }
2180
- const token = parseToken(res.headers);
2181
- if (!token) {
2182
- throw new Error("Server side sign up failed. Session token not found");
2183
- }
2184
- this.#config.headers?.append("cookie", token);
2185
- updateHeaders(this.#config.headers);
2186
- if (rawResponse) {
2187
- return res;
2188
- }
2189
- try {
2190
- const json = await res.clone().json();
2191
- if (json && typeof json === "object" && "tenants" in json) {
2192
- const tenantId = json.tenants[0];
2193
- if (tenantId) {
2194
- updateTenantId(tenantId);
2376
+ return withNileContext(this.#config, async () => {
2377
+ ctx.set({ headers: null });
2378
+ const { email, password, ...params } = payload;
2379
+ if (!email || !password) {
2380
+ throw new Error(
2381
+ "Server side sign up requires a user email and password."
2382
+ );
2383
+ }
2384
+ const providers = await this.listProviders();
2385
+ const { credentials } = providers ?? {};
2386
+ if (!credentials) {
2387
+ throw new Error(
2388
+ "Unable to obtain credential provider. Aborting server side sign up."
2389
+ );
2390
+ }
2391
+ const csrf = await obtainCsrf(this.#config);
2392
+ let csrfToken;
2393
+ if ("csrfToken" in csrf) {
2394
+ csrfToken = csrf.csrfToken;
2395
+ } else {
2396
+ throw new Error("Unable to obtain parse CSRF. Request blocked.");
2397
+ }
2398
+ const body = JSON.stringify({
2399
+ email,
2400
+ password,
2401
+ csrfToken,
2402
+ callbackUrl: credentials.callbackUrl
2403
+ });
2404
+ const res = await fetchSignUp(this.#config, { body, params });
2405
+ if (res.status > 299) {
2406
+ this.#logger.error(await res.clone().text());
2407
+ return void 0;
2408
+ }
2409
+ const token = parseToken(res.headers);
2410
+ if (!token) {
2411
+ throw new Error("Server side sign up failed. Session token not found");
2412
+ }
2413
+ const { headers } = ctx.get();
2414
+ headers?.append("cookie", token);
2415
+ ctx.set({ headers });
2416
+ updateHeaders(headers);
2417
+ if (rawResponse) {
2418
+ return res;
2419
+ }
2420
+ try {
2421
+ const json = await res.clone().json();
2422
+ if (json && typeof json === "object" && "tenants" in json) {
2423
+ const tenantId = json.tenants[0];
2424
+ if (tenantId) {
2425
+ updateTenantId(tenantId);
2426
+ }
2195
2427
  }
2428
+ return json;
2429
+ } catch {
2430
+ return res;
2196
2431
  }
2197
- return json;
2198
- } catch {
2199
- return res;
2200
- }
2432
+ });
2201
2433
  }
2202
2434
  /**
2203
2435
  * Request a password reset email.
@@ -2207,34 +2439,34 @@ var Auth = class {
2207
2439
  * which is returned as a {@link Response} object.
2208
2440
  */
2209
2441
  async forgotPassword(req) {
2210
- let email = "";
2211
- const defaults = defaultCallbackUrl({
2212
- config: this.#config
2213
- });
2214
- let callbackUrl = defaults.callbackUrl;
2215
- let redirectUrl = defaults.redirectUrl;
2216
- if ("email" in req) {
2217
- email = req.email;
2218
- }
2219
- if ("callbackUrl" in req) {
2220
- callbackUrl = req.callbackUrl ? req.callbackUrl : null;
2221
- }
2222
- if ("redirectUrl" in req) {
2223
- redirectUrl = req.redirectUrl ? req.redirectUrl : null;
2224
- }
2225
- const body = JSON.stringify({
2226
- email,
2227
- redirectUrl,
2228
- callbackUrl
2442
+ return withNileContext(this.#config, async () => {
2443
+ let email = "";
2444
+ const defaults = defaultCallbackUrl(this.#config);
2445
+ let callbackUrl = defaults.callbackUrl;
2446
+ let redirectUrl = defaults.redirectUrl;
2447
+ if ("email" in req) {
2448
+ email = req.email;
2449
+ }
2450
+ if ("callbackUrl" in req) {
2451
+ callbackUrl = fQUrl(req.callbackUrl ?? "", this.#config);
2452
+ }
2453
+ if ("redirectUrl" in req) {
2454
+ redirectUrl = fQUrl(req.redirectUrl ?? "", this.#config);
2455
+ }
2456
+ const body = JSON.stringify({
2457
+ email,
2458
+ redirectUrl,
2459
+ callbackUrl
2460
+ });
2461
+ const data = await fetchResetPassword(
2462
+ this.#config,
2463
+ "POST",
2464
+ body,
2465
+ new URLSearchParams(),
2466
+ false
2467
+ );
2468
+ return data;
2229
2469
  });
2230
- const data = await fetchResetPassword(
2231
- this.#config,
2232
- "POST",
2233
- body,
2234
- new URLSearchParams(),
2235
- false
2236
- );
2237
- return data;
2238
2470
  }
2239
2471
  /**
2240
2472
  * Complete a password reset.
@@ -2247,93 +2479,98 @@ var Auth = class {
2247
2479
  * containing the necessary fields.
2248
2480
  */
2249
2481
  async resetPassword(req) {
2250
- let email = "";
2251
- let password = "";
2252
- const defaults = defaultCallbackUrl({ config: this.#config });
2253
- let callbackUrl = defaults.callbackUrl;
2254
- let redirectUrl = defaults.redirectUrl;
2255
- if (req instanceof Request) {
2256
- const body2 = await req.json();
2257
- email = body2.email;
2258
- password = body2.password;
2259
- const cbFromHeaders = parseCallback(req.headers);
2260
- if (cbFromHeaders) {
2261
- callbackUrl = cbFromHeaders;
2262
- }
2263
- if (body2.callbackUrl) {
2264
- callbackUrl = body2.callbackUrl;
2265
- }
2266
- if (body2.redirectUrl) {
2267
- redirectUrl = body2.redirectUrl;
2482
+ return withNileContext(this.#config, async () => {
2483
+ let email = "";
2484
+ let password = "";
2485
+ const defaults = defaultCallbackUrl(this.#config);
2486
+ let callbackUrl = defaults.callbackUrl;
2487
+ let redirectUrl = defaults.redirectUrl;
2488
+ if (req instanceof Request) {
2489
+ const body2 = await req.json();
2490
+ email = body2.email;
2491
+ password = body2.password;
2492
+ const cbFromHeaders = parseCallback(req.headers);
2493
+ if (cbFromHeaders) {
2494
+ callbackUrl = cbFromHeaders;
2495
+ }
2496
+ if (body2.callbackUrl) {
2497
+ callbackUrl = body2.callbackUrl;
2498
+ }
2499
+ if (body2.redirectUrl) {
2500
+ redirectUrl = body2.redirectUrl;
2501
+ }
2502
+ } else {
2503
+ if ("email" in req) {
2504
+ email = req.email;
2505
+ }
2506
+ if ("password" in req) {
2507
+ password = req.password;
2508
+ }
2509
+ if ("callbackUrl" in req) {
2510
+ callbackUrl = req.callbackUrl ? req.callbackUrl : null;
2511
+ }
2512
+ if ("redirectUrl" in req) {
2513
+ redirectUrl = req.redirectUrl ? req.redirectUrl : null;
2514
+ }
2268
2515
  }
2269
- } else {
2270
- if ("email" in req) {
2271
- email = req.email;
2516
+ await this.getCsrf();
2517
+ const body = JSON.stringify({
2518
+ email,
2519
+ password,
2520
+ redirectUrl,
2521
+ callbackUrl
2522
+ });
2523
+ let urlWithParams;
2524
+ try {
2525
+ const data = await fetchResetPassword(this.#config, "POST", body);
2526
+ const cloned = data.clone();
2527
+ if (data.status === 400) {
2528
+ const text = await cloned.text();
2529
+ this.#logger.error(text);
2530
+ return data;
2531
+ }
2532
+ const { url } = await data.json();
2533
+ urlWithParams = url;
2534
+ } catch {
2272
2535
  }
2273
- if ("password" in req) {
2274
- password = req.password;
2536
+ let token;
2537
+ try {
2538
+ const worthyParams = new URL(urlWithParams).searchParams;
2539
+ const answer = await fetchResetPassword(
2540
+ this.#config,
2541
+ "GET",
2542
+ null,
2543
+ worthyParams
2544
+ );
2545
+ token = parseResetToken(answer.headers);
2546
+ } catch {
2547
+ this.#logger.warn(
2548
+ "Unable to parse reset password url. Password not reset."
2549
+ );
2275
2550
  }
2276
- if ("callbackUrl" in req) {
2277
- callbackUrl = req.callbackUrl ? req.callbackUrl : null;
2551
+ const { headers } = ctx.get();
2552
+ const cookie = headers?.get("cookie")?.split("; ");
2553
+ if (token) {
2554
+ cookie?.push(token);
2555
+ } else {
2556
+ throw new Error(
2557
+ "Unable to reset password, reset token is missing from response"
2558
+ );
2278
2559
  }
2279
- if ("redirectUrl" in req) {
2280
- redirectUrl = req.redirectUrl ? req.redirectUrl : null;
2560
+ if (cookie) {
2561
+ headers?.set("cookie", cookie?.join("; "));
2562
+ ctx.set({
2563
+ headers
2564
+ });
2281
2565
  }
2282
- }
2283
- await this.getCsrf();
2284
- const body = JSON.stringify({
2285
- email,
2286
- password,
2287
- redirectUrl,
2288
- callbackUrl
2289
- });
2290
- let urlWithParams;
2291
- try {
2292
- const data = await fetchResetPassword(this.#config, "POST", body);
2293
- const cloned = data.clone();
2294
- if (data.status === 400) {
2295
- const text = await cloned.text();
2296
- this.#logger.error(text);
2297
- return data;
2298
- }
2299
- const { url } = await data.json();
2300
- urlWithParams = url;
2301
- } catch {
2302
- }
2303
- let token;
2304
- try {
2305
- const worthyParams = new URL(urlWithParams).searchParams;
2306
- const answer = await fetchResetPassword(
2307
- this.#config,
2308
- "GET",
2309
- null,
2310
- worthyParams
2311
- );
2312
- token = parseResetToken(answer.headers);
2313
- } catch {
2314
- this.#logger.warn(
2315
- "Unable to parse reset password url. Password not reset."
2316
- );
2317
- }
2318
- const cookie = this.#config.headers.get("cookie")?.split("; ");
2319
- if (token) {
2320
- cookie?.push(token);
2321
- } else {
2322
- throw new Error(
2323
- "Unable to reset password, reset token is missing from response"
2324
- );
2325
- }
2326
- this.#config.headers = new Headers({
2327
- ...this.#config.headers,
2328
- cookie: cookie?.join("; ")
2566
+ const res = await fetchResetPassword(this.#config, "PUT", body);
2567
+ cookie?.pop();
2568
+ const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
2569
+ cleaned.push(String(parseToken(res.headers)));
2570
+ const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
2571
+ updateHeaders(updatedHeaders);
2572
+ return res;
2329
2573
  });
2330
- const res = await fetchResetPassword(this.#config, "PUT", body);
2331
- cookie?.pop();
2332
- const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
2333
- cleaned.push(String(parseToken(res.headers)));
2334
- const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
2335
- updateHeaders(updatedHeaders);
2336
- return res;
2337
2574
  }
2338
2575
  /**
2339
2576
  * Low level helper used by {@link signIn} to complete provider flows.
@@ -2343,7 +2580,9 @@ var Auth = class {
2343
2580
  */
2344
2581
  async callback(provider, body) {
2345
2582
  if (body instanceof Request) {
2346
- this.#config.headers = body.headers;
2583
+ ctx.set({
2584
+ headers: body.headers
2585
+ });
2347
2586
  return await fetchCallback(
2348
2587
  this.#config,
2349
2588
  provider,
@@ -2355,112 +2594,115 @@ var Auth = class {
2355
2594
  return await fetchCallback(this.#config, provider, body);
2356
2595
  }
2357
2596
  async signIn(provider, payload, rawResponse) {
2358
- if (payload instanceof Request) {
2359
- const body2 = new URLSearchParams(await payload.text());
2360
- const origin = new URL(payload.url).origin;
2361
- const payloadUrl = body2?.get("callbackUrl");
2362
- const csrfToken2 = body2?.get("csrfToken");
2363
- const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
2364
- if (!csrfToken2) {
2597
+ return withNileContext(this.#config, async () => {
2598
+ if (payload instanceof Request) {
2599
+ const body2 = new URLSearchParams(await payload.text());
2600
+ const origin = new URL(payload.url).origin;
2601
+ const payloadUrl = body2?.get("callbackUrl");
2602
+ const csrfToken2 = body2?.get("csrfToken");
2603
+ const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
2604
+ if (!csrfToken2) {
2605
+ throw new Error(
2606
+ "CSRF token in missing from request. Request it by the client before calling sign in"
2607
+ );
2608
+ }
2609
+ const updatedHeaders = new Headers(payload.headers);
2610
+ updatedHeaders.set("Content-Type", "application/x-www-form-urlencoded");
2611
+ ctx.set({ headers: updatedHeaders });
2612
+ const params = new URLSearchParams({
2613
+ csrfToken: csrfToken2,
2614
+ json: String(true)
2615
+ });
2616
+ if (payloadUrl) {
2617
+ params.set("callbackUrl", callbackUrl);
2618
+ }
2619
+ return await fetchSignIn(this.#config, provider, params);
2620
+ }
2621
+ ctx.set({ headers: null });
2622
+ const { info, error } = this.#logger;
2623
+ const providers = await this.listProviders();
2624
+ info("Obtaining csrf");
2625
+ const csrf = await obtainCsrf(this.#config);
2626
+ let csrfToken;
2627
+ if ("csrfToken" in csrf) {
2628
+ csrfToken = csrf.csrfToken;
2629
+ } else {
2630
+ throw new Error("Unable to obtain parse CSRF. Request blocked.");
2631
+ }
2632
+ const { credentials } = providers ?? {};
2633
+ if (!credentials) {
2365
2634
  throw new Error(
2366
- "CSRF token in missing from request. Request it by the client before calling sign in"
2635
+ "Unable to obtain credential provider. Aborting server side sign in."
2367
2636
  );
2368
2637
  }
2369
- this.#config.headers = new Headers(payload.headers);
2370
- this.#config.headers.set(
2371
- "Content-Type",
2372
- "application/x-www-form-urlencoded"
2373
- );
2374
- const params = new URLSearchParams({
2375
- csrfToken: csrfToken2,
2376
- json: String(true)
2638
+ const { email, password } = payload ?? {};
2639
+ if (provider === "email" && (!email || !password)) {
2640
+ throw new Error(
2641
+ "Server side sign in requires a user email and password."
2642
+ );
2643
+ }
2644
+ info(`Obtaining providers for ${email}`);
2645
+ info(`Attempting sign in with email ${email}`);
2646
+ if (!email) {
2647
+ throw new Error("Email missing from payload, unable to sign in");
2648
+ }
2649
+ const body = JSON.stringify({
2650
+ email,
2651
+ password,
2652
+ csrfToken,
2653
+ callbackUrl: credentials.callbackUrl
2377
2654
  });
2378
- if (payloadUrl) {
2379
- params.set("callbackUrl", callbackUrl);
2380
- }
2381
- return await fetchSignIn(this.#config, provider, params);
2382
- }
2383
- this.#config.headers = new Headers();
2384
- const { info, error } = this.#logger;
2385
- const providers = await this.listProviders();
2386
- info("Obtaining csrf");
2387
- const csrf = await this.getCsrf();
2388
- let csrfToken;
2389
- if ("csrfToken" in csrf) {
2390
- csrfToken = csrf.csrfToken;
2391
- } else {
2392
- throw new Error("Unable to obtain parse CSRF. Request blocked.");
2393
- }
2394
- const { credentials } = providers ?? {};
2395
- if (!credentials) {
2396
- throw new Error(
2397
- "Unable to obtain credential provider. Aborting server side sign in."
2398
- );
2399
- }
2400
- const { email, password } = payload ?? {};
2401
- if (provider === "email" && (!email || !password)) {
2402
- throw new Error(
2403
- "Server side sign in requires a user email and password."
2404
- );
2405
- }
2406
- info(`Obtaining providers for ${email}`);
2407
- info(`Attempting sign in with email ${email}`);
2408
- if (!email) {
2409
- throw new Error("Email missing from payload, unable to sign in");
2410
- }
2411
- const body = JSON.stringify({
2412
- email,
2413
- password,
2414
- csrfToken,
2415
- callbackUrl: credentials.callbackUrl
2416
- });
2417
- const signInRes = await this.callback(provider, body);
2418
- const authCookie = signInRes?.headers.get("set-cookie");
2419
- if (!authCookie) {
2420
- throw new Error("authentication failed");
2421
- }
2422
- const token = parseToken(signInRes?.headers);
2423
- const possibleError = signInRes?.headers.get("location");
2424
- if (possibleError) {
2425
- let urlError;
2655
+ const signInRes = await this.callback(provider, body);
2656
+ const authCookie = signInRes?.headers.get("set-cookie");
2657
+ if (!authCookie) {
2658
+ throw new Error("authentication failed");
2659
+ }
2660
+ const token = parseToken(signInRes?.headers);
2661
+ const possibleError = signInRes?.headers.get("location");
2662
+ if (possibleError) {
2663
+ let urlError;
2664
+ try {
2665
+ urlError = new URL(possibleError).searchParams.get("error");
2666
+ } catch {
2667
+ }
2668
+ if (urlError) {
2669
+ error("Unable to log user in", { error: urlError });
2670
+ return new Response(urlError, { status: signInRes.status });
2671
+ }
2672
+ }
2673
+ if (!token) {
2674
+ error("Unable to obtain auth token", {
2675
+ authCookie,
2676
+ signInRes
2677
+ });
2678
+ throw new Error("Server login failed");
2679
+ }
2680
+ info("Server sign in successful", { authCookie });
2681
+ const setCookie = signInRes.headers.get("set-cookie");
2682
+ const { headers } = ctx.get();
2683
+ if (setCookie) {
2684
+ const cookie = [
2685
+ parseCSRF(headers),
2686
+ parseCallback(signInRes.headers),
2687
+ parseToken(signInRes.headers)
2688
+ ].filter(Boolean).join("; ");
2689
+ const uHeaders = new Headers({ cookie });
2690
+ updateHeaders(uHeaders);
2691
+ ctx.set({ headers: uHeaders });
2692
+ } else {
2693
+ error("Unable to set context after sign in", {
2694
+ headers: signInRes.headers
2695
+ });
2696
+ }
2697
+ if (rawResponse) {
2698
+ return signInRes;
2699
+ }
2426
2700
  try {
2427
- urlError = new URL(possibleError).searchParams.get("error");
2701
+ return await signInRes.clone().json();
2428
2702
  } catch {
2703
+ return signInRes;
2429
2704
  }
2430
- if (urlError) {
2431
- error("Unable to log user in", { error: urlError });
2432
- return new Response(urlError, { status: signInRes.status });
2433
- }
2434
- }
2435
- if (!token) {
2436
- error("Unable to obtain auth token", {
2437
- authCookie,
2438
- signInRes
2439
- });
2440
- throw new Error("Server login failed");
2441
- }
2442
- info("Server sign in successful", { authCookie });
2443
- const setCookie = signInRes.headers.get("set-cookie");
2444
- if (setCookie) {
2445
- const cookie = [
2446
- parseCSRF(this.#config.headers),
2447
- parseCallback(signInRes.headers),
2448
- parseToken(signInRes.headers)
2449
- ].filter(Boolean).join("; ");
2450
- updateHeaders(new Headers({ cookie }));
2451
- } else {
2452
- error("Unable to set context after sign in", {
2453
- headers: signInRes.headers
2454
- });
2455
- }
2456
- if (rawResponse) {
2457
- return signInRes;
2458
- }
2459
- try {
2460
- return await signInRes.clone().json();
2461
- } catch {
2462
- return signInRes;
2463
- }
2705
+ });
2464
2706
  }
2465
2707
  };
2466
2708
  function parseCSRF(headers) {
@@ -2507,25 +2749,56 @@ function parseResetToken(headers) {
2507
2749
  const [, token] = /((__Secure-)?nile\.reset=[^;]+)/.exec(authCookie) ?? [];
2508
2750
  return token;
2509
2751
  }
2510
- function defaultCallbackUrl({ config }) {
2752
+ function parseTenantId(headers) {
2753
+ let authCookie = headers?.get("set-cookie");
2754
+ if (!authCookie) {
2755
+ authCookie = headers?.get("cookie");
2756
+ }
2757
+ if (!authCookie) {
2758
+ return void 0;
2759
+ }
2760
+ const [, token] = /((__Secure-)?nile\.tenant-id=[^;]+)/.exec(authCookie) ?? [];
2761
+ if (token) {
2762
+ const [, tenantId] = token.split("=");
2763
+ return tenantId;
2764
+ }
2765
+ return null;
2766
+ }
2767
+ function defaultCallbackUrl(config) {
2511
2768
  let cb = null;
2512
2769
  let redirect = null;
2513
- const fallbackCb = parseCallback(config.headers);
2770
+ const { headers } = ctx.get();
2771
+ const fallbackCb = parseCallback(headers);
2514
2772
  if (fallbackCb) {
2515
2773
  const [, value] = fallbackCb.split("=");
2516
2774
  cb = decodeURIComponent(value);
2517
2775
  if (value) {
2518
- redirect = `${new URL(cb).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
2776
+ redirect = `${new URL(cb).origin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}`;
2519
2777
  }
2520
2778
  }
2521
2779
  return { callbackUrl: cb, redirectUrl: redirect };
2522
2780
  }
2781
+ function fQUrl(path, config) {
2782
+ if (path.startsWith("/")) {
2783
+ const { callbackUrl } = defaultCallbackUrl(config);
2784
+ if (callbackUrl) {
2785
+ const { origin } = new URL(callbackUrl);
2786
+ return `${origin}${path}`;
2787
+ }
2788
+ }
2789
+ try {
2790
+ new URL(path);
2791
+ } catch {
2792
+ throw new Error("An invalid URL has been passed.");
2793
+ }
2794
+ return path;
2795
+ }
2523
2796
 
2524
2797
  // src/auth/obtainCsrf.ts
2525
2798
  async function obtainCsrf(config, rawResponse = false) {
2799
+ const { headers } = ctx.get();
2526
2800
  const res = await fetchCsrf(config);
2527
2801
  const csrfCook = parseCSRF(res.headers);
2528
- const h = new Headers();
2529
2802
  if (csrfCook) {
2530
2803
  const [, value] = csrfCook.split("=");
2531
2804
  const [token] = decodeURIComponent(value).split("|");
@@ -2536,29 +2809,27 @@ async function obtainCsrf(config, rawResponse = false) {
2536
2809
  parseCallback(res.headers),
2537
2810
  parseToken(res.headers)
2538
2811
  ].filter(Boolean).join("; ");
2539
- config.headers.set("cookie", cookie);
2540
- h.set("cookie", cookie);
2541
- updateHeaders(h);
2812
+ headers.set("cookie", cookie);
2813
+ ctx.set({ headers, preserveHeaders: true });
2814
+ updateHeaders(headers);
2542
2815
  }
2543
2816
  if (!rawResponse) {
2544
2817
  return { csrfToken: token };
2545
2818
  }
2546
2819
  } else {
2547
- const existingCookie = config.headers.get("cookie");
2820
+ const existingCookie = headers.get("cookie");
2548
2821
  const cookieParts = [];
2549
2822
  if (existingCookie) {
2550
- cookieParts.push(
2551
- parseToken(config.headers),
2552
- parseCallback(config.headers)
2553
- );
2823
+ cookieParts.push(parseToken(headers), parseCallback(headers));
2554
2824
  }
2555
2825
  if (csrfCook) {
2556
2826
  cookieParts.push(csrfCook);
2557
2827
  } else {
2558
- cookieParts.push(parseCSRF(config.headers));
2828
+ cookieParts.push(parseCSRF(headers));
2559
2829
  }
2560
2830
  const cookie = cookieParts.filter(Boolean).join("; ");
2561
- config.headers.set("cookie", cookie);
2831
+ headers.set("cookie", cookie);
2832
+ ctx.set({ headers, preserveHeaders: true });
2562
2833
  updateHeaders(new Headers({ cookie }));
2563
2834
  }
2564
2835
  if (rawResponse) {
@@ -2593,15 +2864,17 @@ var Users = class {
2593
2864
  * @param [rawResponse] - When `true`, return the raw {@link Response}.
2594
2865
  */
2595
2866
  async updateSelf(req, rawResponse) {
2596
- const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
2597
- if (rawResponse) {
2598
- return res;
2599
- }
2600
- try {
2601
- return await res?.clone().json();
2602
- } catch {
2603
- return res;
2604
- }
2867
+ return withNileContext(this.#config, async () => {
2868
+ const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
2869
+ if (rawResponse) {
2870
+ return res;
2871
+ }
2872
+ try {
2873
+ return await res?.clone().json();
2874
+ } catch {
2875
+ return res;
2876
+ }
2877
+ });
2605
2878
  }
2606
2879
  /**
2607
2880
  * Remove the current user using `DELETE /api/me`.
@@ -2611,59 +2884,70 @@ var Users = class {
2611
2884
  * `packages/server/src/api/routes/me/index.ts` under `removeSelf`.
2612
2885
  */
2613
2886
  async removeSelf() {
2614
- const me = await this.getSelf();
2615
- if ("id" in me) {
2616
- this.#config.userId = me.id;
2617
- }
2618
- const res = await fetchMe(this.#config, "DELETE");
2619
- updateHeaders(new Headers());
2620
- return res;
2887
+ return withNileContext(this.#config, async () => {
2888
+ const me = await this.getSelf();
2889
+ if ("id" in me) {
2890
+ const userId = me.id;
2891
+ ctx.set({ userId });
2892
+ }
2893
+ const res = await fetchMe(this.#config, "DELETE");
2894
+ updateHeaders(new Headers());
2895
+ return res;
2896
+ });
2621
2897
  }
2622
2898
  async getSelf(rawResponse) {
2623
- const res = await fetchMe(this.#config);
2624
- if (rawResponse) {
2625
- return res;
2626
- }
2627
- try {
2628
- return await res?.clone().json();
2629
- } catch {
2630
- return res;
2631
- }
2899
+ return withNileContext(this.#config, async () => {
2900
+ const res = await fetchMe(this.#config);
2901
+ if (rawResponse) {
2902
+ return res;
2903
+ }
2904
+ try {
2905
+ return await res?.clone().json();
2906
+ } catch {
2907
+ return res;
2908
+ }
2909
+ });
2632
2910
  }
2633
2911
  async verifySelf(options, rawResponse = false) {
2634
- const bypassEmail = typeof options === "object" && options?.bypassEmail === true;
2635
- const callbackUrl = typeof options === "object" ? options.callbackUrl : defaultCallbackUrl2(this.#config).callbackUrl;
2636
- let res;
2637
- try {
2638
- const me = await this.getSelf();
2639
- if (me instanceof Response) {
2640
- return me;
2641
- }
2642
- res = await verifyEmailAddress(this.#config, me, String(callbackUrl));
2643
- return res;
2644
- } catch (e) {
2645
- if (!bypassEmail) {
2646
- let message = "Unable to verify email.";
2647
- if (e instanceof Error) {
2648
- message = e.message;
2912
+ return withNileContext(this.#config, async () => {
2913
+ const bypassEmail = typeof options === "object" && options?.bypassEmail === true;
2914
+ const callbackUrl = typeof options === "object" ? options.callbackUrl : defaultCallbackUrl2().callbackUrl;
2915
+ let res;
2916
+ try {
2917
+ const me = await this.getSelf();
2918
+ if (me instanceof Response) {
2919
+ return me;
2920
+ }
2921
+ res = await verifyEmailAddress(this.#config, me, String(callbackUrl));
2922
+ return res;
2923
+ } catch (e) {
2924
+ if (!bypassEmail) {
2925
+ let message = "Unable to verify email.";
2926
+ if (e instanceof Error) {
2927
+ message = e.message;
2928
+ }
2929
+ this.#logger?.error(
2930
+ `${message} you can bypass this message by setting bypassEmail: true when calling 'verifySelf'`
2931
+ );
2932
+ res = new Response(message, { status: 400 });
2649
2933
  }
2650
- this.#logger?.error(
2651
- `${message} you can bypass this message by setting bypassEmail: true when calling 'verifySelf'`
2934
+ }
2935
+ if (bypassEmail) {
2936
+ this.#logger?.info(
2937
+ "bypassing email requirements for email verification"
2652
2938
  );
2653
- res = new Response(message, { status: 400 });
2939
+ res = this.updateSelf({ emailVerified: true }, rawResponse);
2654
2940
  }
2655
- }
2656
- if (bypassEmail) {
2657
- this.#logger?.info("bypassing email requirements for email verification");
2658
- res = this.updateSelf({ emailVerified: true }, rawResponse);
2659
- }
2660
- return res;
2941
+ return res;
2942
+ });
2661
2943
  }
2662
2944
  };
2663
2945
  async function verifyEmailAddress(config, user, callback) {
2664
- config.headers.set("content-type", "application/x-www-form-urlencoded");
2946
+ const { headers } = ctx.get();
2947
+ headers?.set("content-type", "application/x-www-form-urlencoded");
2948
+ ctx.set({ headers });
2665
2949
  const { csrfToken } = await obtainCsrf(config);
2666
- const defaults = defaultCallbackUrl2(config);
2950
+ const defaults = defaultCallbackUrl2();
2667
2951
  const callbackUrl = callback ?? String(defaults.callbackUrl);
2668
2952
  const res = await fetchVerifyEmail(
2669
2953
  config,
@@ -2679,9 +2963,10 @@ async function verifyEmailAddress(config, user, callback) {
2679
2963
  }
2680
2964
  return res;
2681
2965
  }
2682
- function defaultCallbackUrl2(config) {
2966
+ function defaultCallbackUrl2() {
2683
2967
  let cb = null;
2684
- const fallbackCb = parseCallback(config.headers);
2968
+ const { headers } = ctx.get();
2969
+ const fallbackCb = parseCallback(headers);
2685
2970
  if (fallbackCb) {
2686
2971
  const [, value] = fallbackCb.split("=");
2687
2972
  cb = decodeURIComponent(value);
@@ -2701,24 +2986,26 @@ var Tenants = class {
2701
2986
  * `createTenant` operation definition.
2702
2987
  */
2703
2988
  async create(req, rawResponse) {
2704
- let res;
2705
- if (typeof req === "string") {
2706
- res = await fetchTenants(
2707
- this.#config,
2708
- "POST",
2709
- JSON.stringify({ name: req })
2710
- );
2711
- } else if (typeof req === "object" && ("name" in req || "id" in req)) {
2712
- res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
2713
- }
2714
- if (rawResponse) {
2715
- return res;
2716
- }
2717
- try {
2718
- return await res?.clone().json();
2719
- } catch {
2720
- return res;
2721
- }
2989
+ return withNileContext(this.#config, async () => {
2990
+ let res;
2991
+ if (typeof req === "string") {
2992
+ res = await fetchTenants(
2993
+ this.#config,
2994
+ "POST",
2995
+ JSON.stringify({ name: req })
2996
+ );
2997
+ } else if (typeof req === "object" && ("name" in req || "id" in req)) {
2998
+ res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
2999
+ }
3000
+ if (rawResponse) {
3001
+ return res;
3002
+ }
3003
+ try {
3004
+ return await res?.clone().json();
3005
+ } catch {
3006
+ return res;
3007
+ }
3008
+ });
2722
3009
  }
2723
3010
  /**
2724
3011
  * Remove a tenant via `DELETE /api/tenants/{tenantId}`.
@@ -2726,14 +3013,16 @@ var Tenants = class {
2726
3013
  * @param req - The tenant to remove or context containing the id.
2727
3014
  */
2728
3015
  async delete(req) {
2729
- if (typeof req === "string") {
2730
- this.#config.tenantId = req;
2731
- }
2732
- if (typeof req === "object" && "id" in req) {
2733
- this.#config.tenantId = req.id;
2734
- }
2735
- const res = await fetchTenant(this.#config, "DELETE");
2736
- return res;
3016
+ return withNileContext(this.#config, async () => {
3017
+ if (typeof req === "string") {
3018
+ ctx.set({ tenantId: req });
3019
+ }
3020
+ if (typeof req === "object" && "id" in req) {
3021
+ ctx.set({ tenantId: req.id });
3022
+ }
3023
+ const res = await fetchTenant(this.#config, "DELETE");
3024
+ return res;
3025
+ });
2737
3026
  }
2738
3027
  /**
2739
3028
  * Fetch details for a tenant using `GET /api/tenants/{tenantId}`.
@@ -2742,53 +3031,63 @@ var Tenants = class {
2742
3031
  * @param [rawResponse] - When true, return the raw {@link Response}.
2743
3032
  */
2744
3033
  async get(req, rawResponse) {
2745
- if (typeof req === "string") {
2746
- this.#config.tenantId = req;
2747
- } else if (typeof req === "object" && "id" in req) {
2748
- this.#config.tenantId = req.id;
2749
- }
2750
- const res = await fetchTenant(this.#config, "GET");
2751
- if (rawResponse === true || req === true) {
2752
- return res;
2753
- }
2754
- try {
2755
- return await res?.clone().json();
2756
- } catch {
2757
- return res;
2758
- }
3034
+ return withNileContext(this.#config, async () => {
3035
+ if (typeof req === "string") {
3036
+ ctx.set({ tenantId: req });
3037
+ } else if (typeof req === "object" && "id" in req) {
3038
+ ctx.set({ tenantId: req.id });
3039
+ }
3040
+ const res = await fetchTenant(this.#config, "GET");
3041
+ if (rawResponse === true || req === true) {
3042
+ return res;
3043
+ }
3044
+ try {
3045
+ return await res?.clone().json();
3046
+ } catch {
3047
+ return res;
3048
+ }
3049
+ });
2759
3050
  }
2760
3051
  async update(req, rawResponse) {
2761
- let res;
2762
- if (typeof req === "object" && ("name" in req || "id" in req)) {
2763
- const { id, ...remaining } = req;
2764
- if (id) {
2765
- this.#config.tenantId = id;
3052
+ return withNileContext(this.#config, async () => {
3053
+ let res;
3054
+ if (typeof req === "object" && ("name" in req || "id" in req)) {
3055
+ const { id, ...remaining } = req;
3056
+ if (id) {
3057
+ ctx.set({ tenantId: id });
3058
+ }
3059
+ res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
2766
3060
  }
2767
- res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
2768
- }
2769
- if (rawResponse) {
2770
- return res;
2771
- }
2772
- try {
2773
- return await res?.clone().json();
2774
- } catch {
2775
- return res;
2776
- }
3061
+ if (rawResponse) {
3062
+ return res;
3063
+ }
3064
+ try {
3065
+ return await res?.clone().json();
3066
+ } catch {
3067
+ return res;
3068
+ }
3069
+ });
2777
3070
  }
2778
3071
  /**
2779
3072
  * List tenants for the current user via `GET /api/tenants`.
2780
3073
  * See `packages/server/src/api/routes/tenants/GET.ts` for details.
2781
3074
  */
2782
3075
  async list(req) {
2783
- const res = await fetchTenantsByUser(this.#config);
2784
- if (req === true) {
2785
- return res;
2786
- }
2787
- try {
2788
- return await res?.clone().json();
2789
- } catch {
2790
- return res;
2791
- }
3076
+ return withNileContext(
3077
+ this.#config,
3078
+ async () => {
3079
+ const res = await fetchTenantsByUser(this.#config);
3080
+ if (req === true) {
3081
+ return res;
3082
+ }
3083
+ try {
3084
+ return await res?.clone().json();
3085
+ } catch {
3086
+ return res;
3087
+ }
3088
+ },
3089
+ "listTenants"
3090
+ );
2792
3091
  }
2793
3092
  /**
2794
3093
  * Leave the current tenant using `DELETE /api/tenants/{tenantId}/users/{userId}`.
@@ -2796,29 +3095,33 @@ var Tenants = class {
2796
3095
  * @param [req] - Optionally specify the tenant id to leave.
2797
3096
  */
2798
3097
  async leaveTenant(req) {
2799
- const me = await fetchMe(this.#config);
2800
- try {
2801
- const json = await me.json();
2802
- if ("id" in json) {
2803
- this.#config.userId = json.id;
3098
+ return withNileContext(this.#config, async () => {
3099
+ const me = await fetchMe(this.#config);
3100
+ try {
3101
+ const json = await me.json();
3102
+ if ("id" in json) {
3103
+ ctx.set({ userId: json.id, preserveHeaders: true });
3104
+ }
3105
+ } catch {
2804
3106
  }
2805
- } catch {
2806
- }
2807
- if (typeof req === "string") {
2808
- this.#config.tenantId = req;
2809
- } else {
2810
- this.#handleContext(req);
2811
- }
2812
- return await fetchTenantUser(this.#config, "DELETE");
3107
+ if (typeof req === "string") {
3108
+ ctx.set({ tenantId: req, preserveHeaders: true });
3109
+ } else {
3110
+ this.#handleContext(req);
3111
+ }
3112
+ return await fetchTenantUser(this.#config, "DELETE");
3113
+ });
2813
3114
  }
2814
3115
  async addMember(req, rawResponse) {
2815
- if (typeof req === "string") {
2816
- this.#config.userId = req;
2817
- } else {
2818
- this.#handleContext(req);
2819
- }
2820
- const res = await fetchTenantUser(this.#config, "PUT");
2821
- return responseHandler(res, rawResponse);
3116
+ return withNileContext(this.#config, async () => {
3117
+ if (typeof req === "string") {
3118
+ ctx.set({ userId: req, preserveHeaders: true });
3119
+ } else {
3120
+ this.#handleContext(req);
3121
+ }
3122
+ const res = await fetchTenantUser(this.#config, "PUT");
3123
+ return responseHandler(res, rawResponse);
3124
+ });
2822
3125
  }
2823
3126
  /**
2824
3127
  * Remove a user from a tenant with `DELETE /api/tenants/{tenantId}/users/{userId}`.
@@ -2827,57 +3130,82 @@ var Tenants = class {
2827
3130
  * @param [rawResponse] - When true, return the raw {@link Response}.
2828
3131
  */
2829
3132
  async removeMember(req, rawResponse) {
2830
- this.#handleContext(req);
2831
- const res = await fetchTenantUser(this.#config, "DELETE");
2832
- return responseHandler(res, rawResponse);
3133
+ return withNileContext(this.#config, async () => {
3134
+ this.#handleContext(req);
3135
+ if (typeof req === "string") {
3136
+ ctx.set({ userId: req, preserveHeaders: true });
3137
+ }
3138
+ const res = await fetchTenantUser(this.#config, "DELETE");
3139
+ return responseHandler(res, rawResponse);
3140
+ });
2833
3141
  }
2834
3142
  async users(req, rawResponse) {
2835
- this.#handleContext(req);
2836
- const res = await fetchTenantUsers(this.#config, "GET");
2837
- return responseHandler(
2838
- res,
2839
- rawResponse || typeof req === "boolean" && req
3143
+ return withNileContext(
3144
+ this.#config,
3145
+ async () => {
3146
+ this.#handleContext(req);
3147
+ const res = await fetchTenantUsers(this.#config, "GET");
3148
+ return responseHandler(
3149
+ res,
3150
+ rawResponse || typeof req === "boolean" && req
3151
+ );
3152
+ },
3153
+ "users"
2840
3154
  );
2841
3155
  }
2842
3156
  /**
2843
3157
  * List invites for the current tenant via `GET /api/tenants/{tenantId}/invites`.
2844
3158
  */
2845
3159
  async invites() {
2846
- const res = await fetchInvites(this.#config);
2847
- return responseHandler(res);
3160
+ return withNileContext(
3161
+ this.#config,
3162
+ async () => {
3163
+ const res = await fetchInvites(this.#config);
3164
+ return responseHandler(res);
3165
+ },
3166
+ "invites"
3167
+ );
2848
3168
  }
2849
3169
  async invite(req, rawResponse) {
2850
- const { csrfToken } = await obtainCsrf(this.#config);
2851
- const defaults = defaultCallbackUrl3(this.#config);
2852
- let identifier = req;
2853
- let callbackUrl = defaults.callbackUrl;
2854
- let redirectUrl = defaults.redirectUrl;
2855
- if (typeof req === "object") {
2856
- if ("email" in req) {
2857
- identifier = req.email;
2858
- }
2859
- if ("callbackUrl" in req) {
2860
- callbackUrl = req.callbackUrl ? req.callbackUrl : "";
2861
- }
2862
- if ("redirectUrl" in req) {
2863
- redirectUrl = req.redirectUrl ? req.redirectUrl : "";
2864
- }
2865
- }
2866
- this.#config.headers.set(
2867
- "Content-Type",
2868
- "application/x-www-form-urlencoded"
2869
- );
2870
- const res = await fetchInvite(
3170
+ return withNileContext(
2871
3171
  this.#config,
2872
- "POST",
2873
- new URLSearchParams({
2874
- identifier,
2875
- csrfToken,
2876
- callbackUrl,
2877
- redirectUrl
2878
- }).toString()
3172
+ async () => {
3173
+ await runExtensionContext(this.#config);
3174
+ const { csrfToken } = await obtainCsrf(
3175
+ this.#config
3176
+ );
3177
+ const defaults = defaultCallbackUrl3(this.#config);
3178
+ let identifier = req;
3179
+ let callbackUrl = defaults.callbackUrl;
3180
+ let redirectUrl = defaults.redirectUrl;
3181
+ if (typeof req === "object") {
3182
+ if ("email" in req) {
3183
+ identifier = req.email;
3184
+ }
3185
+ if ("callbackUrl" in req) {
3186
+ callbackUrl = fQUrl2(req.callbackUrl ?? "", this.#config);
3187
+ }
3188
+ if ("redirectUrl" in req) {
3189
+ redirectUrl = fQUrl2(req.redirectUrl ?? "", this.#config);
3190
+ }
3191
+ }
3192
+ const { headers } = ctx.get();
3193
+ headers?.set("Content-Type", "application/x-www-form-urlencoded");
3194
+ ctx.set({ headers });
3195
+ const res = await fetchInvite(
3196
+ this.#config,
3197
+ "POST",
3198
+ new URLSearchParams({
3199
+ identifier,
3200
+ csrfToken,
3201
+ callbackUrl,
3202
+ redirectUrl
3203
+ }).toString()
3204
+ );
3205
+ return responseHandler(res, rawResponse);
3206
+ },
3207
+ "invites"
2879
3208
  );
2880
- return responseHandler(res, rawResponse);
2881
3209
  }
2882
3210
  /**
2883
3211
  * Accept an invite using `PUT /api/tenants/{tenantId}/invite`.
@@ -2886,22 +3214,24 @@ var Tenants = class {
2886
3214
  * @param [rawResponse] - When true, return the raw {@link Response}.
2887
3215
  */
2888
3216
  async acceptInvite(req, rawResponse) {
2889
- if (!req) {
2890
- throw new Error("The identifier and token are required.");
2891
- }
2892
- const { identifier, token } = req;
2893
- const defaults = defaultCallbackUrl3(this.#config);
2894
- const callbackUrl = String(defaults.callbackUrl);
2895
- const res = await fetchInvite(
2896
- this.#config,
2897
- "PUT",
2898
- new URLSearchParams({
2899
- identifier,
2900
- token,
2901
- callbackUrl
2902
- }).toString()
2903
- );
2904
- return responseHandler(res, rawResponse);
3217
+ return withNileContext(this.#config, async () => {
3218
+ if (!req) {
3219
+ throw new Error("The identifier and token are required.");
3220
+ }
3221
+ const { identifier, token } = req;
3222
+ const defaults = defaultCallbackUrl3(this.#config);
3223
+ const callbackUrl = String(defaults.callbackUrl);
3224
+ const res = await fetchInvite(
3225
+ this.#config,
3226
+ "PUT",
3227
+ new URLSearchParams({
3228
+ identifier,
3229
+ token,
3230
+ callbackUrl
3231
+ }).toString()
3232
+ );
3233
+ return responseHandler(res, rawResponse);
3234
+ });
2905
3235
  }
2906
3236
  /**
2907
3237
  * Delete a pending invite using `DELETE /api/tenants/{tenantId}/invite/{inviteId}`.
@@ -2909,25 +3239,27 @@ var Tenants = class {
2909
3239
  * @param req - Identifier of the invite to remove.
2910
3240
  */
2911
3241
  async deleteInvite(req) {
2912
- let id = "";
2913
- if (typeof req === "object") {
2914
- id = req.id;
2915
- } else {
2916
- id = req;
2917
- }
2918
- if (!id) {
2919
- throw new Error("An invite id is required.");
2920
- }
2921
- const res = await fetchInvite(this.#config, "DELETE", id);
2922
- return responseHandler(res, true);
3242
+ return withNileContext(this.#config, async () => {
3243
+ let id = "";
3244
+ if (typeof req === "object") {
3245
+ id = req.id;
3246
+ } else {
3247
+ id = req;
3248
+ }
3249
+ if (!id) {
3250
+ throw new Error("An invite id is required.");
3251
+ }
3252
+ const res = await fetchInvite(this.#config, "DELETE", id);
3253
+ return responseHandler(res, true);
3254
+ });
2923
3255
  }
2924
3256
  #handleContext(req) {
2925
3257
  if (typeof req === "object") {
2926
3258
  if ("tenantId" in req) {
2927
- this.#config.tenantId = req.tenantId;
3259
+ ctx.set({ tenantId: req.tenantId, preserveHeaders: true });
2928
3260
  }
2929
3261
  if ("userId" in req) {
2930
- this.#config.tenantId = req.tenantId;
3262
+ ctx.set({ userId: req.userId, preserveHeaders: true });
2931
3263
  }
2932
3264
  }
2933
3265
  }
@@ -2945,19 +3277,32 @@ async function responseHandler(res, rawResponse) {
2945
3277
  function defaultCallbackUrl3(config) {
2946
3278
  let cb = null;
2947
3279
  let redirect = null;
2948
- const fallbackCb = parseCallback(config.headers);
3280
+ const { headers, tenantId } = ctx.get();
3281
+ const fallbackCb = parseCallback(headers);
2949
3282
  if (fallbackCb) {
2950
3283
  const [, value] = fallbackCb.split("=");
2951
3284
  cb = decodeURIComponent(value);
2952
3285
  if (value) {
2953
- redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace(
2954
- "{tenantId}",
2955
- String(config.tenantId)
2956
- )}`;
3286
+ redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", String(tenantId))}`;
2957
3287
  }
2958
3288
  }
2959
3289
  return { callbackUrl: cb, redirectUrl: redirect };
2960
3290
  }
3291
+ function fQUrl2(path, config) {
3292
+ if (path.startsWith("/")) {
3293
+ const { callbackUrl } = defaultCallbackUrl3(config);
3294
+ if (callbackUrl) {
3295
+ const { origin } = new URL(callbackUrl);
3296
+ return `${origin}${path}`;
3297
+ }
3298
+ }
3299
+ try {
3300
+ new URL(path);
3301
+ } catch {
3302
+ throw new Error("An invalid URL has been passed.");
3303
+ }
3304
+ return path;
3305
+ }
2961
3306
 
2962
3307
  // src/api/handlers/withContext/index.ts
2963
3308
  function handlersWithContext(config) {
@@ -3020,97 +3365,6 @@ function updateConfig(response, config) {
3020
3365
  };
3021
3366
  }
3022
3367
 
3023
- // src/api/utils/extensions.ts
3024
- function getRequestConfig(params) {
3025
- if (typeof params[1] === "object") {
3026
- return params[1];
3027
- }
3028
- return {};
3029
- }
3030
- function bindRunExtensions(instance) {
3031
- return async function runExtensions(toRun, config, params, _init) {
3032
- const { debug } = config.logger("[EXTENSIONS]");
3033
- const extensionConfig = getRequestConfig(
3034
- Array.isArray(params) ? params : [null, params]
3035
- );
3036
- if (config.extensions) {
3037
- for (const create2 of config.extensions) {
3038
- if (typeof create2 !== "function") {
3039
- continue;
3040
- }
3041
- const ext = create2(instance);
3042
- if (extensionConfig.disableExtensions?.includes(ext.id)) {
3043
- continue;
3044
- }
3045
- if (ext.onHandleRequest && toRun === "onHandleRequest" /* onHandleRequest */) {
3046
- const result = await ext.onHandleRequest(
3047
- ...Array.isArray(params) ? params : [params]
3048
- );
3049
- debug(`${ext.id ?? create2.name} ran onHandleRequest`);
3050
- if (result != null) {
3051
- return result;
3052
- }
3053
- }
3054
- const [param] = Array.isArray(params) ? params : [params];
3055
- if (ext.onRequest && toRun === "onRequest" /* onRequest */) {
3056
- const previousContext = instance.getContext();
3057
- if (previousContext.preserveHeaders) {
3058
- instance.setContext({ preserveHeaders: false });
3059
- }
3060
- if (!_init) {
3061
- continue;
3062
- }
3063
- await ext.onRequest(_init.request);
3064
- const updatedContext = instance.getContext();
3065
- if (updatedContext?.headers) {
3066
- const cookie = updatedContext.headers.get("cookie");
3067
- if (cookie && param.headers) {
3068
- param.headers.set(
3069
- "cookie",
3070
- mergeCookies(
3071
- previousContext.preserveHeaders ? previousContext.headers?.get("cookie") : null,
3072
- updatedContext.headers.get("cookie")
3073
- )
3074
- );
3075
- }
3076
- if (updatedContext.tenantId && param.headers) {
3077
- param.headers.set(
3078
- TENANT_COOKIE,
3079
- String(updatedContext.headers.get(TENANT_COOKIE))
3080
- );
3081
- }
3082
- }
3083
- debug(`${ext.id ?? create2.name} ran onRequest`);
3084
- }
3085
- if (ext.onResponse && toRun === "onResponse" /* onResponse */) {
3086
- const result = await ext.onResponse(param);
3087
- debug(`${ext.id ?? create2.name} ran onResponse`);
3088
- if (result != null) {
3089
- return result;
3090
- }
3091
- }
3092
- }
3093
- }
3094
- return void 0;
3095
- };
3096
- }
3097
- function buildExtensionConfig(instance) {
3098
- return {
3099
- runExtensions: bindRunExtensions(instance)
3100
- };
3101
- }
3102
- function mergeCookies(...cookieStrings) {
3103
- const cookieMap = /* @__PURE__ */ new Map();
3104
- for (const str of cookieStrings) {
3105
- if (!str) continue;
3106
- for (const part of str.split(";")) {
3107
- const [key17, value] = part.split("=").map((s) => s.trim());
3108
- if (key17 && value) cookieMap.set(key17, value);
3109
- }
3110
- }
3111
- return [...cookieMap.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
3112
- }
3113
-
3114
3368
  // src/Server.ts
3115
3369
  var Server = class {
3116
3370
  users;
@@ -3119,35 +3373,37 @@ var Server = class {
3119
3373
  #config;
3120
3374
  #handlers;
3121
3375
  #manager;
3122
- #headers;
3123
- #preserveHeaders;
3376
+ // #headers: undefined | Headers;
3377
+ // #preserveHeaders: boolean;
3124
3378
  constructor(config) {
3125
3379
  this.#config = new Config({
3126
3380
  ...config,
3127
3381
  extensionCtx: buildExtensionConfig(this)
3128
3382
  });
3129
3383
  watchTenantId((tenantId) => {
3130
- if (tenantId !== this.#config.tenantId) {
3131
- this.#config.tenantId = tenantId;
3384
+ if (tenantId !== this.#config.context.tenantId) {
3385
+ this.#config.context.tenantId = String(tenantId);
3132
3386
  this.#reset();
3133
3387
  }
3134
3388
  });
3135
3389
  watchUserId((userId) => {
3136
- if (userId !== this.#config.userId) {
3137
- this.#config.userId = userId;
3390
+ if (userId !== this.#config.context.userId) {
3391
+ this.#config.context.userId = String(userId);
3138
3392
  this.#reset();
3139
3393
  }
3140
3394
  });
3141
3395
  watchHeaders((headers) => {
3142
- this.setContext(headers);
3143
- this.#reset();
3396
+ if (headers) {
3397
+ this.#config.context.headers = new Headers(headers);
3398
+ this.#reset();
3399
+ }
3144
3400
  });
3145
3401
  this.#handlers = {
3146
3402
  ...this.#config.handlers,
3147
3403
  withContext: handlersWithContext(this.#config)
3148
3404
  };
3149
- this.#preserveHeaders = config?.preserveHeaders ?? false;
3150
- this.#config.tenantId = getTenantId({ config: this.#config });
3405
+ this.#config.context.preserveHeaders = config?.preserveHeaders ?? false;
3406
+ this.#config.context.tenantId = getTenantId({ config: this.#config });
3151
3407
  this.#manager = new DBManager(this.#config);
3152
3408
  this.#handleHeaders(config);
3153
3409
  this.users = new Users(this.#config);
@@ -3202,21 +3458,6 @@ var Server = class {
3202
3458
  }
3203
3459
  };
3204
3460
  }
3205
- /**
3206
- * A convenience function that applies a config and ensures whatever was passed is set properly
3207
- */
3208
- getInstance(config, req) {
3209
- const _config = { ...this.#config, ...config };
3210
- const updatedConfig = new Config(_config);
3211
- this.#config = new Config(updatedConfig);
3212
- this.#config.tenantId = config.tenantId;
3213
- this.#config.userId = config.userId;
3214
- if (req) {
3215
- this.setContext(req);
3216
- }
3217
- this.#reset();
3218
- return this;
3219
- }
3220
3461
  get handlers() {
3221
3462
  return this.#handlers;
3222
3463
  }
@@ -3226,98 +3467,30 @@ var Server = class {
3226
3467
  set paths(paths) {
3227
3468
  this.#config.paths = paths;
3228
3469
  }
3229
- /**
3230
- * Allow the setting of headers from a req or header object.
3231
- * Makes it possible to handle REST requests easily
3232
- * Also makes it easy to set user + tenant in some way
3233
- * @param req
3234
- * @returns undefined
3235
- */
3236
- setContext = (req, ...remaining) => {
3237
- let ok = false;
3238
- if (req && typeof req === "object" && "tenantId" in req) {
3239
- ok = true;
3240
- this.#config.tenantId = req.tenantId;
3241
- }
3242
- if (req && typeof req === "object" && "userId" in req) {
3243
- ok = true;
3244
- this.#config.userId = req.userId;
3245
- }
3246
- if (req && typeof req === "object" && "preserveHeaders" in req) {
3247
- ok = true;
3248
- this.#preserveHeaders = Boolean(req.preserveHeaders);
3249
- }
3250
- let atLeastOne = false;
3251
- if (this.#config?.extensions) {
3252
- for (const create2 of this.#config.extensions) {
3253
- if (typeof create2 !== "function") {
3254
- continue;
3255
- }
3256
- const ext = create2(this);
3257
- if (typeof ext.onSetContext === "function") {
3258
- if (req) {
3259
- ext.onSetContext(req, ...remaining);
3260
- atLeastOne = true;
3261
- } else {
3262
- this.#config.logger("extension").warn("attempted to call onSetContext without a value");
3263
- }
3264
- }
3265
- }
3266
- }
3267
- if (atLeastOne) {
3268
- return;
3269
- }
3270
- try {
3271
- if (req instanceof Headers) {
3272
- this.#handleHeaders(req);
3273
- this.#reset();
3274
- return;
3275
- } else if (req instanceof Request) {
3276
- this.#handleHeaders(new Headers(req.headers));
3277
- this.#reset();
3278
- return;
3279
- }
3280
- } catch {
3470
+ async withContext(context, fn) {
3471
+ const { ddl, ...ctx2 } = context ?? defaultContext;
3472
+ this.#config.context = { ...ctx2 };
3473
+ const preserve = (context && "preserveHeaders" in context && context.preserveHeaders) ?? true;
3474
+ if (preserve) {
3475
+ this.#config.context = { ...this.getContext(), ...context };
3281
3476
  }
3282
- if (ok) {
3283
- return;
3477
+ if (ddl) {
3478
+ delete this.#config.context.tenantId;
3479
+ delete this.#config.context.userId;
3284
3480
  }
3285
- if (typeof req === "object") {
3286
- try {
3287
- const headers = new Headers(req);
3288
- if (headers) {
3289
- this.#handleHeaders(headers);
3290
- this.#reset();
3291
- return;
3292
- }
3293
- } catch {
3481
+ return withNileContext(this.#config, async () => {
3482
+ if (fn) {
3483
+ return fn(this);
3294
3484
  }
3295
- }
3296
- const { warn } = Logger(this.#config)("[API]");
3297
- if (warn) {
3298
- warn(
3299
- "Set context expects a Request, Header instance or an object of Record<string, string>"
3300
- );
3301
- }
3302
- };
3485
+ return this;
3486
+ });
3487
+ }
3488
+ /**
3489
+ *
3490
+ * @returns the last used (basically global) context object, useful for debugging or making your own context
3491
+ */
3303
3492
  getContext() {
3304
- if (this.#config?.extensions) {
3305
- for (const create2 of this.#config.extensions) {
3306
- if (typeof create2 !== "function") {
3307
- continue;
3308
- }
3309
- const ext = create2(this);
3310
- if (typeof ext.onGetContext === "function") {
3311
- return ext.onGetContext();
3312
- }
3313
- }
3314
- }
3315
- return {
3316
- headers: this.#headers,
3317
- userId: this.#config?.userId,
3318
- tenantId: this.#config?.tenantId,
3319
- preserveHeaders: this.#preserveHeaders
3320
- };
3493
+ return ctx.getLastUsed();
3321
3494
  }
3322
3495
  /**
3323
3496
  * Merge headers together
@@ -3326,16 +3499,19 @@ var Server = class {
3326
3499
  #handleHeaders(config) {
3327
3500
  const updates = [];
3328
3501
  let headers;
3329
- this.#headers = new Headers();
3502
+ this.#config.context.headers = new Headers();
3330
3503
  if (config instanceof Headers) {
3331
3504
  headers = config;
3332
3505
  } else if (config?.headers) {
3333
3506
  headers = config?.headers;
3334
3507
  if (config && config.origin) {
3335
- this.#headers.set(HEADER_ORIGIN, config.origin);
3508
+ this.#config.context.headers.set(HEADER_ORIGIN, config.origin);
3336
3509
  }
3337
3510
  if (config && config.secureCookies != null) {
3338
- this.#headers.set(HEADER_SECURE_COOKIES, String(config.secureCookies));
3511
+ this.#config.context.headers.set(
3512
+ HEADER_SECURE_COOKIES,
3513
+ String(config.secureCookies)
3514
+ );
3339
3515
  }
3340
3516
  }
3341
3517
  if (headers instanceof Headers) {
@@ -3348,8 +3524,7 @@ var Server = class {
3348
3524
  }
3349
3525
  }
3350
3526
  const merged = {};
3351
- this.#config.tenantId = getTenantFromHttp(this.#headers, this.#config);
3352
- this.#headers?.forEach((value, key17) => {
3527
+ this.#config.context.headers?.forEach((value, key17) => {
3353
3528
  if (key17.toLowerCase() !== "cookie") {
3354
3529
  merged[key17.toLowerCase()] = value;
3355
3530
  }
@@ -3358,16 +3533,14 @@ var Server = class {
3358
3533
  merged[key17] = value;
3359
3534
  }
3360
3535
  for (const [key17, value] of Object.entries(merged)) {
3361
- this.#headers.set(key17, value);
3536
+ this.#config.context.headers.set(key17, value);
3362
3537
  }
3363
3538
  this.#config.logger("[handleHeaders]").debug(JSON.stringify(merged));
3364
- this.#config.headers = this.#headers;
3365
3539
  }
3366
3540
  /**
3367
3541
  * Allow some internal mutations to reset our config + headers
3368
3542
  */
3369
3543
  #reset = () => {
3370
- this.#config.headers = this.#headers ?? new Headers();
3371
3544
  this.#config.extensionCtx = buildExtensionConfig(this);
3372
3545
  this.users = new Users(this.#config);
3373
3546
  this.tenants = new Tenants(this.#config);
@@ -3382,6 +3555,6 @@ function create(config) {
3382
3555
  return server;
3383
3556
  }
3384
3557
 
3385
- export { APIErrorErrorCodeEnum, ExtensionState, HEADER_ORIGIN, HEADER_SECURE_COOKIES, LoginUserResponseTokenTypeEnum, create as Nile, Server, TENANT_COOKIE, USER_COOKIE, parseCSRF, parseCallback, parseResetToken, parseToken };
3558
+ export { APIErrorErrorCodeEnum, ExtensionState, HEADER_ORIGIN, HEADER_SECURE_COOKIES, LoginUserResponseTokenTypeEnum, create as Nile, Server, TENANT_COOKIE, USER_COOKIE, parseCSRF, parseCallback, parseResetToken, parseTenantId, parseToken };
3386
3559
  //# sourceMappingURL=index.mjs.map
3387
3560
  //# sourceMappingURL=index.mjs.map