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