@niledatabase/server 5.0.0-alpha.2 → 5.0.0-alpha.4

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
@@ -53,6 +53,8 @@ var appRoutes = (prefix = DEFAULT_PREFIX) => ({
53
53
  TENANT_USER: `${prefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */}`,
54
54
  TENANT_USERS: `${prefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */}`,
55
55
  SIGNUP: `${prefix}${"/signup" /* SIGNUP */}`,
56
+ INVITES: `${prefix}${"/tenants/{tenantId}/invites" /* INVITES */}`,
57
+ INVITE: `${prefix}${"/tenants/{tenantId}/invite" /* INVITE */}`,
56
58
  LOG: `${prefix}/_log`
57
59
  });
58
60
  var apiRoutes = (config) => ({
@@ -63,6 +65,8 @@ var apiRoutes = (config) => ({
63
65
  TENANT: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}`),
64
66
  SIGNUP: makeRestUrl(config, "/signup"),
65
67
  TENANT_USERS: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}/users`),
68
+ INVITES: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}/invites`),
69
+ INVITE: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}/invite`),
66
70
  TENANT_USER: makeRestUrl(
67
71
  config,
68
72
  `/tenants/${config.tenantId}/users/${config.userId}`
@@ -104,9 +108,9 @@ function makeRestUrl(config, path, qp) {
104
108
  const strParams = params.toString();
105
109
  return `${[url, path.substring(1, path.length)].join("/")}${strParams ? `?${strParams}` : ""}`;
106
110
  }
107
- function urlMatches(requestUrl, route17) {
111
+ function urlMatches(requestUrl, route20) {
108
112
  const url = new URL(requestUrl);
109
- return url.pathname.startsWith(route17);
113
+ return url.pathname.startsWith(route20);
110
114
  }
111
115
  function isUUID(value) {
112
116
  if (!value) {
@@ -176,9 +180,10 @@ function matchesLog(configRoutes, request2) {
176
180
  }
177
181
 
178
182
  // src/utils/constants.ts
179
- var X_NILE_TENANT = "nile-tenant-id";
180
- var X_NILE_ORIGIN = "nile-origin";
181
- var X_NILE_SECURECOOKIES = "nile-secure-cookies";
183
+ var TENANT_COOKIE = "nile.tenant-id";
184
+ var USER_COOKIE = "nile.user-id";
185
+ var HEADER_ORIGIN = "nile-origin";
186
+ var HEADER_SECURE_COOKIES = "nile-secure-cookies";
182
187
 
183
188
  // src/api/utils/request.ts
184
189
  async function request(url, _init, config) {
@@ -189,17 +194,17 @@ async function request(url, _init, config) {
189
194
  if (request2.headers.get("cookie")) {
190
195
  updatedHeaders.set("cookie", String(request2.headers.get("cookie")));
191
196
  }
192
- if (request2.headers.get(X_NILE_TENANT)) {
197
+ if (request2.headers.get(TENANT_COOKIE)) {
193
198
  updatedHeaders.set(
194
- X_NILE_TENANT,
195
- String(request2.headers.get(X_NILE_TENANT))
199
+ TENANT_COOKIE,
200
+ String(request2.headers.get(TENANT_COOKIE))
196
201
  );
197
202
  }
198
203
  if (config.secureCookies != null) {
199
- updatedHeaders.set(X_NILE_SECURECOOKIES, String(config.secureCookies));
204
+ updatedHeaders.set(HEADER_SECURE_COOKIES, String(config.secureCookies));
200
205
  } else {
201
206
  updatedHeaders.set(
202
- X_NILE_SECURECOOKIES,
207
+ HEADER_SECURE_COOKIES,
203
208
  process.env.NODE_ENV === "production" ? "true" : "false"
204
209
  );
205
210
  }
@@ -207,17 +212,17 @@ async function request(url, _init, config) {
207
212
  if (config.callbackUrl) {
208
213
  const cbUrl = new URL(config.callbackUrl);
209
214
  debug(`Obtained origin from config.callbackUrl ${config.callbackUrl}`);
210
- updatedHeaders.set(X_NILE_ORIGIN, cbUrl.origin);
215
+ updatedHeaders.set(HEADER_ORIGIN, cbUrl.origin);
211
216
  } else if (config.origin) {
212
217
  debug(`Obtained origin from config.origin ${config.origin}`);
213
- updatedHeaders.set(X_NILE_ORIGIN, config.origin);
218
+ updatedHeaders.set(HEADER_ORIGIN, config.origin);
214
219
  } else {
215
- const passedOrigin = request2.headers.get(X_NILE_ORIGIN);
220
+ const passedOrigin = request2.headers.get(HEADER_ORIGIN);
216
221
  if (passedOrigin) {
217
- updatedHeaders.set(X_NILE_ORIGIN, passedOrigin);
222
+ updatedHeaders.set(HEADER_ORIGIN, passedOrigin);
218
223
  } else {
219
224
  const reqOrigin = config.routePrefix !== DEFAULT_PREFIX ? `${requestUrl.origin}${config.routePrefix}` : requestUrl.origin;
220
- updatedHeaders.set(X_NILE_ORIGIN, reqOrigin);
225
+ updatedHeaders.set(HEADER_ORIGIN, reqOrigin);
221
226
  debug(`Obtained origin from request ${reqOrigin}`);
222
227
  }
223
228
  }
@@ -225,14 +230,16 @@ async function request(url, _init, config) {
225
230
  if (params.method?.toLowerCase() === "post" || params.method?.toLowerCase() === "put") {
226
231
  try {
227
232
  updatedHeaders.set("content-type", "application/json");
228
- const initBody = await new Response(_init.request.clone().body).json();
229
- const requestBody = await new Response(request2.clone().body).json();
230
- params.body = JSON.stringify(initBody ?? requestBody);
233
+ const bodyStream = _init.body ?? _init.request?.body ?? request2.body;
234
+ const bodyText = await new Response(bodyStream).text();
235
+ try {
236
+ params.body = JSON.stringify(JSON.parse(bodyText));
237
+ } catch {
238
+ updatedHeaders.set("content-type", "application/x-www-form-urlencoded");
239
+ params.body = bodyText;
240
+ }
231
241
  } catch (e) {
232
- updatedHeaders.set("content-type", "application/x-www-form-urlencoded");
233
- const initBody = await new Response(_init.request.clone().body).text();
234
- const requestBody = await new Response(request2.clone().body).text();
235
- params.body = initBody ?? requestBody;
242
+ error("Failed to parse request body");
236
243
  }
237
244
  }
238
245
  params.headers = updatedHeaders;
@@ -241,6 +248,7 @@ async function request(url, _init, config) {
241
248
  params.headers.set("request-id", crypto.randomUUID());
242
249
  params.cache = "no-store";
243
250
  }
251
+ await config.extensionCtx?.handleOnRequest(config, _init, params);
244
252
  try {
245
253
  const res = await fetch(fullUrl, {
246
254
  ...params
@@ -378,8 +386,8 @@ function getTokenFromCookie(headers, cookieKey) {
378
386
  }
379
387
  }
380
388
  function getTenantFromHttp(headers, config) {
381
- const cookieTenant = getTokenFromCookie(headers, X_NILE_TENANT);
382
- return cookieTenant ?? headers?.get(X_NILE_TENANT) ?? config?.tenantId;
389
+ const cookieTenant = getTokenFromCookie(headers, TENANT_COOKIE);
390
+ return cookieTenant ? cookieTenant : config?.tenantId;
383
391
  }
384
392
 
385
393
  // src/api/routes/users/POST.ts
@@ -389,7 +397,7 @@ async function POST(config, init) {
389
397
  const yurl = new URL(init.request.url);
390
398
  const tenantId = yurl.searchParams.get("tenantId");
391
399
  const newTenantName = yurl.searchParams.get("newTenantName");
392
- const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
400
+ const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
393
401
  const url = apiRoutes(config).USERS({ tenantId: tenant, newTenantName });
394
402
  return await request(url, init, config);
395
403
  }
@@ -398,21 +406,18 @@ async function POST(config, init) {
398
406
  async function GET2(config, init, log) {
399
407
  const yurl = new URL(init.request.url);
400
408
  const tenantId = yurl.searchParams.get("tenantId");
401
- const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
409
+ const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
402
410
  if (!tenant) {
403
411
  log("[GET] No tenant id provided.");
404
412
  return new Response(null, { status: 404 });
405
413
  }
406
- const url = apiRoutes(config).TENANT_USERS(tenant);
407
414
  init.method = "GET";
415
+ const url = apiRoutes(config).TENANT_USERS(tenant);
408
416
  return await request(url, init, config);
409
417
  }
410
418
 
411
419
  // src/api/routes/users/[userId]/PUT.ts
412
- async function PUT2(config, session, init) {
413
- if (!session) {
414
- return new Response(null, { status: 401 });
415
- }
420
+ async function PUT2(config, init) {
416
421
  init.body = init.request.body;
417
422
  init.method = "PUT";
418
423
  const [userId] = new URL(init.request.url).pathname.split("/").reverse();
@@ -427,14 +432,13 @@ async function route2(request2, config) {
427
432
  { ...config, debug: config.debug },
428
433
  `[ROUTES][${key2}]`
429
434
  );
430
- const session = await auth(request2, config);
431
435
  switch (request2.method) {
432
436
  case "GET":
433
437
  return await GET2(config, { request: request2 }, info);
434
438
  case "POST":
435
439
  return await POST(config, { request: request2 });
436
440
  case "PUT":
437
- return await PUT2(config, session, { request: request2 });
441
+ return await PUT2(config, { request: request2 });
438
442
  default:
439
443
  return new Response("method not allowed", { status: 405 });
440
444
  }
@@ -452,7 +456,11 @@ async function GET3(config, init) {
452
456
  }
453
457
 
454
458
  // src/api/routes/tenants/[tenantId]/users/POST.ts
455
- async function POST2(config, session, init) {
459
+ async function POST2(config, init) {
460
+ const session = await auth(init.request, config);
461
+ if (!session) {
462
+ return new Response(null, { status: 401 });
463
+ }
456
464
  const yurl = new URL(init.request.url);
457
465
  const [, tenantId] = yurl.pathname.split("/").reverse();
458
466
  init.body = JSON.stringify({ email: session.email });
@@ -468,11 +476,6 @@ async function route3(request2, config) {
468
476
  { ...config, debug: config.debug },
469
477
  `[ROUTES][${key3}]`
470
478
  );
471
- const session = await auth(request2, config);
472
- if (!session) {
473
- info("401");
474
- return new Response(null, { status: 401 });
475
- }
476
479
  const yurl = new URL(request2.url);
477
480
  const [, tenantId] = yurl.pathname.split("/").reverse();
478
481
  if (!tenantId) {
@@ -483,7 +486,7 @@ async function route3(request2, config) {
483
486
  case "GET":
484
487
  return await GET3(config, { request: request2 });
485
488
  case "POST":
486
- return await POST2(config, session, { request: request2 });
489
+ return await POST2(config, { request: request2 });
487
490
  default:
488
491
  return new Response("method not allowed", { status: 405 });
489
492
  }
@@ -491,11 +494,11 @@ async function route3(request2, config) {
491
494
  function matches3(configRoutes, request2) {
492
495
  const url = new URL(request2.url);
493
496
  const [userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
494
- let route17 = configRoutes[key3].replace("{tenantId}", tenantId).replace("{userId}", userId);
497
+ let route20 = configRoutes[key3].replace("{tenantId}", tenantId).replace("{userId}", userId);
495
498
  if (userId === "users") {
496
- route17 = configRoutes[key3].replace("{tenantId}", possibleTenantId);
499
+ route20 = configRoutes[key3].replace("{tenantId}", possibleTenantId);
497
500
  }
498
- return urlMatches(request2.url, route17);
501
+ return urlMatches(request2.url, route20);
499
502
  }
500
503
  async function fetchTenantUsers(config, method, payload) {
501
504
  const { body, params } = {};
@@ -529,8 +532,139 @@ async function fetchTenantUsers(config, method, payload) {
529
532
  return await config.handlers[m](req);
530
533
  }
531
534
 
535
+ // src/api/routes/tenants/[tenantId]/invite/PUT.ts
536
+ async function PUT3(config, init) {
537
+ const yurl = new URL(init.request.url);
538
+ const [, tenantId] = yurl.pathname.split("/").reverse();
539
+ if (!tenantId) {
540
+ return new Response(null, { status: 404 });
541
+ }
542
+ if (yurl.searchParams.size > 0) {
543
+ init.body = new URLSearchParams(yurl.searchParams).toString();
544
+ }
545
+ init.method = "PUT";
546
+ const url = `${apiRoutes(config).INVITE(tenantId)}`;
547
+ const res = await request(url, init, config);
548
+ const location = res?.headers.get("location");
549
+ if (location) {
550
+ return new Response(res?.body, {
551
+ status: 302,
552
+ headers: res?.headers
553
+ });
554
+ }
555
+ return new Response(res?.body, {
556
+ status: res?.status,
557
+ headers: res?.headers
558
+ });
559
+ }
560
+
561
+ // src/api/routes/tenants/[tenantId]/invite/POST.ts
562
+ async function POST3(config, init) {
563
+ const yurl = new URL(init.request.url);
564
+ const [, tenantId] = yurl.pathname.split("/").reverse();
565
+ if (!tenantId) {
566
+ return new Response(null, { status: 404 });
567
+ }
568
+ init.method = "POST";
569
+ init.body = init.request.body;
570
+ const url = `${apiRoutes(config).INVITE(tenantId)}`;
571
+ return await request(url, init, config);
572
+ }
573
+
574
+ // src/api/routes/tenants/[tenantId]/invite/index.ts
575
+ var key4 = "INVITE";
576
+ async function route4(request2, config) {
577
+ switch (request2.method) {
578
+ // the browser is a GET, but we need to PUT it into nile-auth
579
+ // server side, this is a put
580
+ case "GET":
581
+ case "PUT":
582
+ return await PUT3(config, { request: request2 });
583
+ case "POST":
584
+ return await POST3(config, { request: request2 });
585
+ default:
586
+ return new Response("method not allowed", { status: 405 });
587
+ }
588
+ }
589
+ function matches4(configRoutes, request2) {
590
+ const url = new URL(request2.url);
591
+ const [, tenantId] = url.pathname.split("/").reverse();
592
+ const route20 = configRoutes[key4].replace("{tenantId}", tenantId);
593
+ return urlMatches(request2.url, route20);
594
+ }
595
+ async function fetchInvite(config, method, body) {
596
+ if (!config.tenantId) {
597
+ throw new Error(
598
+ 'Unable to fetch tenant, the tenantId context is missing. Call nile.setContext({ tenantId }), set nile.tenantId = "tenantId", or add it to the function call'
599
+ );
600
+ }
601
+ if (!isUUID(config.tenantId) && config.logger?.warn) {
602
+ config.logger?.warn(
603
+ "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
604
+ );
605
+ }
606
+ let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", config.tenantId)}`;
607
+ const m = method ?? "GET";
608
+ const init = {
609
+ method: m,
610
+ headers: config.headers
611
+ };
612
+ if (method === "POST" || method === "PUT") {
613
+ init.body = body;
614
+ }
615
+ if (method === "DELETE") {
616
+ clientUrl = `${clientUrl}/${body}`;
617
+ }
618
+ const req = new Request(clientUrl, init);
619
+ return await config.handlers[m](req);
620
+ }
621
+
622
+ // src/api/routes/tenants/[tenantId]/invites/GET.ts
623
+ async function GET4(config, init) {
624
+ const yurl = new URL(init.request.url);
625
+ const [, tenantId] = yurl.pathname.split("/").reverse();
626
+ if (!tenantId) {
627
+ return new Response(null, { status: 404 });
628
+ }
629
+ init.method = "GET";
630
+ const url = `${apiRoutes(config).INVITES(tenantId)}`;
631
+ return await request(url, init, config);
632
+ }
633
+
634
+ // src/api/routes/tenants/[tenantId]/invites/index.ts
635
+ var key5 = "INVITES";
636
+ async function route5(request2, config) {
637
+ switch (request2.method) {
638
+ case "GET":
639
+ return await GET4(config, { request: request2 });
640
+ default:
641
+ return new Response("method not allowed", { status: 405 });
642
+ }
643
+ }
644
+ function matches5(configRoutes, request2) {
645
+ const url = new URL(request2.url);
646
+ const [, tenantId] = url.pathname.split("/").reverse();
647
+ const route20 = configRoutes[key5].replace("{tenantId}", tenantId);
648
+ return url.pathname.endsWith(route20);
649
+ }
650
+ async function fetchInvites(config) {
651
+ if (!config.tenantId) {
652
+ throw new Error(
653
+ 'Unable to fetch tenant, the tenantId context is missing. Call nile.setContext({ tenantId }), set nile.tenantId = "tenantId", or add it to the function call'
654
+ );
655
+ }
656
+ if (!isUUID(config.tenantId) && config.logger?.warn) {
657
+ config.logger?.warn(
658
+ "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
659
+ );
660
+ }
661
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}", config.tenantId)}`;
662
+ const req = new Request(clientUrl, { headers: config.headers });
663
+ return await config.handlers.GET(req);
664
+ }
665
+
532
666
  // src/api/routes/tenants/GET.ts
533
- async function GET4(config, session, init) {
667
+ async function GET5(config, session, init) {
534
668
  let url = `${apiRoutes(config).USER_TENANTS(session.id)}`;
535
669
  if (typeof session === "object" && "user" in session && session.user) {
536
670
  url = `${apiRoutes(config).USER_TENANTS(session.user.id)}`;
@@ -540,7 +674,7 @@ async function GET4(config, session, init) {
540
674
  }
541
675
 
542
676
  // src/api/routes/tenants/[tenantId]/GET.ts
543
- async function GET5(config, init, log) {
677
+ async function GET6(config, init, log) {
544
678
  const yurl = new URL(init.request.url);
545
679
  const [tenantId] = yurl.pathname.split("/").reverse();
546
680
  if (!tenantId) {
@@ -565,7 +699,7 @@ async function DELETE2(config, init) {
565
699
  }
566
700
 
567
701
  // src/api/routes/tenants/[tenantId]/PUT.ts
568
- async function PUT3(config, init) {
702
+ async function PUT4(config, init) {
569
703
  const yurl = new URL(init.request.url);
570
704
  const [tenantId] = yurl.pathname.split("/").reverse();
571
705
  if (!tenantId) {
@@ -578,7 +712,7 @@ async function PUT3(config, init) {
578
712
  }
579
713
 
580
714
  // src/api/routes/tenants/POST.ts
581
- async function POST3(config, init) {
715
+ async function POST4(config, init) {
582
716
  init.body = init.request.body;
583
717
  init.method = "POST";
584
718
  const url = `${apiRoutes(config).TENANTS}`;
@@ -586,11 +720,11 @@ async function POST3(config, init) {
586
720
  }
587
721
 
588
722
  // src/api/routes/tenants/index.ts
589
- var key4 = "TENANTS";
590
- async function route4(request2, config) {
723
+ var key6 = "TENANTS";
724
+ async function route6(request2, config) {
591
725
  const { info } = Logger(
592
726
  { ...config, debug: config.debug },
593
- `[ROUTES][${key4}]`
727
+ `[ROUTES][${key6}]`
594
728
  );
595
729
  const session = await auth(request2, config);
596
730
  if (!session) {
@@ -601,21 +735,21 @@ async function route4(request2, config) {
601
735
  switch (request2.method) {
602
736
  case "GET":
603
737
  if (isUUID(possibleTenantId)) {
604
- return await GET5(config, { request: request2 }, info);
738
+ return await GET6(config, { request: request2 }, info);
605
739
  }
606
- return await GET4(config, session, { request: request2 });
740
+ return await GET5(config, session, { request: request2 });
607
741
  case "POST":
608
- return await POST3(config, { request: request2 });
742
+ return await POST4(config, { request: request2 });
609
743
  case "DELETE":
610
744
  return await DELETE2(config, { request: request2 });
611
745
  case "PUT":
612
- return await PUT3(config, { request: request2 });
746
+ return await PUT4(config, { request: request2 });
613
747
  default:
614
748
  return new Response("method not allowed", { status: 405 });
615
749
  }
616
750
  }
617
- function matches4(configRoutes, request2) {
618
- return urlMatches(request2.url, configRoutes[key4]);
751
+ function matches6(configRoutes, request2) {
752
+ return urlMatches(request2.url, configRoutes[key6]);
619
753
  }
620
754
  async function fetchTenants(config, method, body) {
621
755
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
@@ -673,16 +807,16 @@ async function fetchTenantsByUser(config) {
673
807
  }
674
808
 
675
809
  // src/api/routes/auth/signin.ts
676
- var key5 = "SIGNIN";
677
- async function route5(req, config) {
678
- let url = proxyRoutes(config)[key5];
810
+ var key7 = "SIGNIN";
811
+ async function route7(req, config) {
812
+ let url = proxyRoutes(config)[key7];
679
813
  const init = {
680
814
  method: req.method,
681
815
  headers: req.headers
682
816
  };
683
817
  if (req.method === "POST") {
684
818
  const [provider] = new URL(req.url).pathname.split("/").reverse();
685
- url = `${proxyRoutes(config)[key5]}/${provider}`;
819
+ url = `${proxyRoutes(config)[key7]}/${provider}`;
686
820
  }
687
821
  const passThroughUrl = new URL(req.url);
688
822
  const params = new URLSearchParams(passThroughUrl.search);
@@ -690,8 +824,8 @@ async function route5(req, config) {
690
824
  const res = await request(url, { ...init, request: req }, config);
691
825
  return res;
692
826
  }
693
- function matches5(configRoutes, request2) {
694
- return urlMatches(request2.url, configRoutes[key5]);
827
+ function matches7(configRoutes, request2) {
828
+ return urlMatches(request2.url, configRoutes[key7]);
695
829
  }
696
830
  async function fetchSignIn(config, provider, body) {
697
831
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
@@ -704,7 +838,7 @@ async function fetchSignIn(config, provider, body) {
704
838
  }
705
839
 
706
840
  // src/api/routes/auth/session.ts
707
- async function route6(req, config) {
841
+ async function route8(req, config) {
708
842
  return request(
709
843
  proxyRoutes(config).SESSION,
710
844
  {
@@ -714,7 +848,7 @@ async function route6(req, config) {
714
848
  config
715
849
  );
716
850
  }
717
- function matches6(configRoutes, request2) {
851
+ function matches8(configRoutes, request2) {
718
852
  return urlMatches(request2.url, configRoutes.SESSION);
719
853
  }
720
854
  async function fetchSession(config) {
@@ -727,7 +861,7 @@ async function fetchSession(config) {
727
861
  }
728
862
 
729
863
  // src/api/routes/auth/providers.ts
730
- async function route7(req, config) {
864
+ async function route9(req, config) {
731
865
  return request(
732
866
  proxyRoutes(config).PROVIDERS,
733
867
  {
@@ -737,7 +871,7 @@ async function route7(req, config) {
737
871
  config
738
872
  );
739
873
  }
740
- function matches7(configRoutes, request2) {
874
+ function matches9(configRoutes, request2) {
741
875
  return urlMatches(request2.url, configRoutes.PROVIDERS);
742
876
  }
743
877
  async function fetchProviders(config) {
@@ -750,7 +884,7 @@ async function fetchProviders(config) {
750
884
  }
751
885
 
752
886
  // src/api/routes/auth/csrf.ts
753
- async function route8(req, config) {
887
+ async function route10(req, config) {
754
888
  return request(
755
889
  proxyRoutes(config).CSRF,
756
890
  {
@@ -760,7 +894,7 @@ async function route8(req, config) {
760
894
  config
761
895
  );
762
896
  }
763
- function matches8(configRoutes, request2) {
897
+ function matches10(configRoutes, request2) {
764
898
  return urlMatches(request2.url, configRoutes.CSRF);
765
899
  }
766
900
  async function fetchCsrf(config) {
@@ -773,17 +907,17 @@ async function fetchCsrf(config) {
773
907
  }
774
908
 
775
909
  // src/api/routes/auth/callback.ts
776
- var key6 = "CALLBACK";
777
- async function route9(req, config) {
910
+ var key8 = "CALLBACK";
911
+ async function route11(req, config) {
778
912
  const { error } = Logger(
779
913
  { ...config, debug: config.debug },
780
- `[ROUTES][${key6}]`
914
+ `[ROUTES][${key8}]`
781
915
  );
782
916
  const [provider] = new URL(req.url).pathname.split("/").reverse();
783
917
  try {
784
918
  const passThroughUrl = new URL(req.url);
785
919
  const params = new URLSearchParams(passThroughUrl.search);
786
- const url = `${proxyRoutes(config)[key6]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
920
+ const url = `${proxyRoutes(config)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
787
921
  const res = await request(
788
922
  url,
789
923
  {
@@ -810,7 +944,7 @@ async function route9(req, config) {
810
944
  }
811
945
  return new Response("An unexpected error has occurred.", { status: 400 });
812
946
  }
813
- function matches9(configRoutes, request2) {
947
+ function matches11(configRoutes, request2) {
814
948
  return urlMatches(request2.url, configRoutes.CALLBACK);
815
949
  }
816
950
  async function fetchCallback(config, provider, body, request2, method = "POST") {
@@ -824,22 +958,22 @@ async function fetchCallback(config, provider, body, request2, method = "POST")
824
958
  }
825
959
 
826
960
  // src/api/routes/auth/signout.ts
827
- var key7 = "SIGNOUT";
828
- async function route10(request2, config) {
829
- let url = proxyRoutes(config)[key7];
961
+ var key9 = "SIGNOUT";
962
+ async function route12(request2, config) {
963
+ let url = proxyRoutes(config)[key9];
830
964
  const init = {
831
965
  method: request2.method
832
966
  };
833
967
  if (request2.method === "POST") {
834
968
  init.body = request2.body;
835
969
  const [provider] = new URL(request2.url).pathname.split("/").reverse();
836
- url = `${proxyRoutes(config)[key7]}${provider !== "signout" ? `/${provider}` : ""}`;
970
+ url = `${proxyRoutes(config)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
837
971
  }
838
972
  const res = await request(url, { ...init, request: request2 }, config);
839
973
  return res;
840
974
  }
841
- function matches10(configRoutes, request2) {
842
- return urlMatches(request2.url, configRoutes[key7]);
975
+ function matches12(configRoutes, request2) {
976
+ return urlMatches(request2.url, configRoutes[key9]);
843
977
  }
844
978
  async function fetchSignOut(config, body) {
845
979
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
@@ -852,10 +986,10 @@ async function fetchSignOut(config, body) {
852
986
  }
853
987
 
854
988
  // src/api/routes/auth/error.ts
855
- var key8 = "ERROR";
856
- async function route11(req, config) {
989
+ var key10 = "ERROR";
990
+ async function route13(req, config) {
857
991
  return request(
858
- proxyRoutes(config)[key8],
992
+ proxyRoutes(config)[key10],
859
993
  {
860
994
  method: req.method,
861
995
  request: req
@@ -863,15 +997,15 @@ async function route11(req, config) {
863
997
  config
864
998
  );
865
999
  }
866
- function matches11(configRoutes, request2) {
867
- return urlMatches(request2.url, configRoutes[key8]);
1000
+ function matches13(configRoutes, request2) {
1001
+ return urlMatches(request2.url, configRoutes[key10]);
868
1002
  }
869
1003
 
870
1004
  // src/api/routes/auth/verify-request.ts
871
- var key9 = "VERIFY_REQUEST";
872
- async function route12(req, config) {
1005
+ var key11 = "VERIFY_REQUEST";
1006
+ async function route14(req, config) {
873
1007
  return request(
874
- proxyRoutes(config)[key9],
1008
+ proxyRoutes(config)[key11],
875
1009
  {
876
1010
  method: req.method,
877
1011
  request: req
@@ -879,14 +1013,14 @@ async function route12(req, config) {
879
1013
  config
880
1014
  );
881
1015
  }
882
- function matches12(configRoutes, request2) {
883
- return urlMatches(request2.url, configRoutes[key9]);
1016
+ function matches14(configRoutes, request2) {
1017
+ return urlMatches(request2.url, configRoutes[key11]);
884
1018
  }
885
1019
 
886
1020
  // src/api/routes/auth/password-reset.ts
887
- var key10 = "PASSWORD_RESET";
888
- async function route13(req, config) {
889
- const url = proxyRoutes(config)[key10];
1021
+ var key12 = "PASSWORD_RESET";
1022
+ async function route15(req, config) {
1023
+ const url = proxyRoutes(config)[key12];
890
1024
  const res = await request(
891
1025
  url,
892
1026
  {
@@ -907,12 +1041,14 @@ async function route13(req, config) {
907
1041
  headers: res?.headers
908
1042
  });
909
1043
  }
910
- function matches13(configRoutes, request2) {
1044
+ function matches15(configRoutes, request2) {
911
1045
  return urlMatches(request2.url, configRoutes.PASSWORD_RESET);
912
1046
  }
913
- async function fetchResetPassword(config, method, body, params) {
1047
+ async function fetchResetPassword(config, method, body, params, useJson = true) {
914
1048
  const authParams = new URLSearchParams(params ?? {});
915
- authParams?.set("json", "true");
1049
+ if (useJson) {
1050
+ authParams?.set("json", "true");
1051
+ }
916
1052
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}?${authParams?.toString()}`;
917
1053
  const init = {
918
1054
  method,
@@ -926,9 +1062,9 @@ async function fetchResetPassword(config, method, body, params) {
926
1062
  }
927
1063
 
928
1064
  // src/api/routes/auth/verify-email.ts
929
- var key11 = "VERIFY_EMAIL";
930
- async function route14(req, config) {
931
- const url = proxyRoutes(config)[key11];
1065
+ var key13 = "VERIFY_EMAIL";
1066
+ async function route16(req, config) {
1067
+ const url = proxyRoutes(config)[key13];
932
1068
  const res = await request(
933
1069
  url,
934
1070
  {
@@ -949,8 +1085,8 @@ async function route14(req, config) {
949
1085
  headers: res?.headers
950
1086
  });
951
1087
  }
952
- function matches14(configRoutes, request2) {
953
- return urlMatches(request2.url, configRoutes[key11]);
1088
+ function matches16(configRoutes, request2) {
1089
+ return urlMatches(request2.url, configRoutes[key13]);
954
1090
  }
955
1091
  async function fetchVerifyEmail(config, method, body) {
956
1092
  const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`;
@@ -968,62 +1104,70 @@ async function fetchVerifyEmail(config, method, body) {
968
1104
  // src/api/handlers/GET.ts
969
1105
  function GETTER(configRoutes, config) {
970
1106
  const { info, warn } = Logger(config, "[GET MATCHER]");
971
- return async function GET6(req) {
1107
+ return async function GET7(req) {
972
1108
  if (matches(configRoutes, req)) {
973
1109
  info("matches me");
974
1110
  return route(req, config);
975
1111
  }
1112
+ if (matches5(configRoutes, req)) {
1113
+ info("matches tenant invites");
1114
+ return route5(req, config);
1115
+ }
1116
+ if (matches4(configRoutes, req)) {
1117
+ info("matches invite");
1118
+ return route4(req, config);
1119
+ }
976
1120
  if (matches3(configRoutes, req)) {
977
1121
  info("matches tenant users");
978
1122
  return route3(req, config);
979
1123
  }
1124
+ if (matches6(configRoutes, req)) {
1125
+ info("matches tenants");
1126
+ return route6(req, config);
1127
+ }
980
1128
  if (matches2(configRoutes, req)) {
981
1129
  info("matches users");
982
1130
  return route2(req, config);
983
1131
  }
984
- if (matches4(configRoutes, req)) {
985
- info("matches tenants");
986
- return route4(req, config);
987
- }
988
- if (matches6(configRoutes, req)) {
1132
+ if (matches8(configRoutes, req)) {
989
1133
  info("matches session");
990
- return route6(req, config);
1134
+ return route8(req, config);
991
1135
  }
992
- if (matches5(configRoutes, req)) {
1136
+ if (matches7(configRoutes, req)) {
993
1137
  info("matches signin");
994
- return route5(req, config);
1138
+ return route7(req, config);
995
1139
  }
996
- if (matches7(configRoutes, req)) {
1140
+ if (matches9(configRoutes, req)) {
997
1141
  info("matches providers");
998
- return route7(req, config);
1142
+ return route9(req, config);
999
1143
  }
1000
- if (matches8(configRoutes, req)) {
1144
+ if (matches10(configRoutes, req)) {
1001
1145
  info("matches csrf");
1002
- return route8(req, config);
1146
+ return route10(req, config);
1003
1147
  }
1004
- if (matches13(configRoutes, req)) {
1148
+ if (matches15(configRoutes, req)) {
1005
1149
  info("matches password reset");
1006
- return route13(req, config);
1150
+ return route15(req, config);
1007
1151
  }
1008
- if (matches9(configRoutes, req)) {
1152
+ if (matches11(configRoutes, req)) {
1009
1153
  info("matches callback");
1010
- return route9(req, config);
1011
- }
1012
- if (matches10(configRoutes, req)) {
1013
- info("matches signout");
1014
- return route10(req, config);
1154
+ return route11(req, config);
1015
1155
  }
1016
1156
  if (matches12(configRoutes, req)) {
1017
- info("matches verify-request");
1157
+ info("matches signout");
1018
1158
  return route12(req, config);
1019
1159
  }
1020
1160
  if (matches14(configRoutes, req)) {
1021
- info("matches verify-email");
1161
+ info("matches verify-request");
1022
1162
  return route14(req, config);
1023
1163
  }
1024
- if (matches11(configRoutes, req)) {
1164
+ if (matches16(configRoutes, req)) {
1165
+ info("matches verify-email");
1166
+ return route16(req, config);
1167
+ }
1168
+ if (matches13(configRoutes, req)) {
1025
1169
  info("matches error");
1026
- return route11(req, config);
1170
+ return route13(req, config);
1027
1171
  }
1028
1172
  warn(`No GET routes matched ${req.url}`);
1029
1173
  return new Response(null, { status: 404 });
@@ -1031,7 +1175,7 @@ function GETTER(configRoutes, config) {
1031
1175
  }
1032
1176
 
1033
1177
  // src/api/routes/signup/POST.ts
1034
- async function POST4(config, init) {
1178
+ async function POST5(config, init) {
1035
1179
  init.body = init.request.body;
1036
1180
  init.method = "POST";
1037
1181
  const url = `${apiRoutes(config).SIGNUP}`;
@@ -1039,17 +1183,17 @@ async function POST4(config, init) {
1039
1183
  }
1040
1184
 
1041
1185
  // src/api/routes/signup/index.tsx
1042
- var key12 = "SIGNUP";
1043
- async function route15(request2, config) {
1186
+ var key14 = "SIGNUP";
1187
+ async function route17(request2, config) {
1044
1188
  switch (request2.method) {
1045
1189
  case "POST":
1046
- return await POST4(config, { request: request2 });
1190
+ return await POST5(config, { request: request2 });
1047
1191
  default:
1048
1192
  return new Response("method not allowed", { status: 405 });
1049
1193
  }
1050
1194
  }
1051
- function matches15(configRoutes, request2) {
1052
- return urlMatches(request2.url, configRoutes[key12]);
1195
+ function matches17(configRoutes, request2) {
1196
+ return urlMatches(request2.url, configRoutes[key14]);
1053
1197
  }
1054
1198
  async function fetchSignUp(config, payload) {
1055
1199
  const { body, params } = payload ?? {};
@@ -1072,7 +1216,7 @@ async function fetchSignUp(config, payload) {
1072
1216
  // src/api/handlers/POST.ts
1073
1217
  function POSTER(configRoutes, config) {
1074
1218
  const { info, warn, error } = Logger(config, "[POST MATCHER]");
1075
- return async function POST5(req) {
1219
+ return async function POST6(req) {
1076
1220
  if (matchesLog(configRoutes, req)) {
1077
1221
  try {
1078
1222
  const json = await req.clone().json();
@@ -1086,49 +1230,53 @@ function POSTER(configRoutes, config) {
1086
1230
  info("matches tenant users");
1087
1231
  return route3(req, config);
1088
1232
  }
1089
- if (matches15(configRoutes, req)) {
1233
+ if (matches4(configRoutes, req)) {
1234
+ info("matches tenant invite");
1235
+ return route4(req, config);
1236
+ }
1237
+ if (matches17(configRoutes, req)) {
1090
1238
  info("matches signup");
1091
- return route15(req, config);
1239
+ return route17(req, config);
1092
1240
  }
1093
1241
  if (matches2(configRoutes, req)) {
1094
1242
  info("matches users");
1095
1243
  return route2(req, config);
1096
1244
  }
1097
- if (matches4(configRoutes, req)) {
1245
+ if (matches6(configRoutes, req)) {
1098
1246
  info("matches tenants");
1099
- return route4(req, config);
1247
+ return route6(req, config);
1100
1248
  }
1101
- if (matches6(configRoutes, req)) {
1249
+ if (matches8(configRoutes, req)) {
1102
1250
  info("matches session");
1103
- return route6(req, config);
1251
+ return route8(req, config);
1104
1252
  }
1105
- if (matches5(configRoutes, req)) {
1253
+ if (matches7(configRoutes, req)) {
1106
1254
  info("matches signin");
1107
- return route5(req, config);
1255
+ return route7(req, config);
1108
1256
  }
1109
- if (matches13(configRoutes, req)) {
1257
+ if (matches15(configRoutes, req)) {
1110
1258
  info("matches password reset");
1111
- return route13(req, config);
1259
+ return route15(req, config);
1112
1260
  }
1113
- if (matches7(configRoutes, req)) {
1261
+ if (matches9(configRoutes, req)) {
1114
1262
  info("matches providers");
1115
- return route7(req, config);
1263
+ return route9(req, config);
1116
1264
  }
1117
- if (matches8(configRoutes, req)) {
1265
+ if (matches10(configRoutes, req)) {
1118
1266
  info("matches csrf");
1119
- return route8(req, config);
1267
+ return route10(req, config);
1120
1268
  }
1121
- if (matches9(configRoutes, req)) {
1269
+ if (matches11(configRoutes, req)) {
1122
1270
  info("matches callback");
1123
- return route9(req, config);
1271
+ return route11(req, config);
1124
1272
  }
1125
- if (matches10(configRoutes, req)) {
1273
+ if (matches12(configRoutes, req)) {
1126
1274
  info("matches signout");
1127
- return route10(req, config);
1275
+ return route12(req, config);
1128
1276
  }
1129
- if (matches14(configRoutes, req)) {
1277
+ if (matches16(configRoutes, req)) {
1130
1278
  info("matches verify-email");
1131
- return route14(req, config);
1279
+ return route16(req, config);
1132
1280
  }
1133
1281
  warn(`No POST routes matched ${req.url}`);
1134
1282
  return new Response(null, { status: 404 });
@@ -1147,7 +1295,7 @@ async function DELETE3(config, init) {
1147
1295
  }
1148
1296
 
1149
1297
  // src/api/routes/tenants/[tenantId]/users/[userId]/PUT.ts
1150
- async function PUT4(config, init) {
1298
+ async function PUT5(config, init) {
1151
1299
  const yurl = new URL(init.request.url);
1152
1300
  const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
1153
1301
  config.tenantId = tenantId;
@@ -1158,11 +1306,11 @@ async function PUT4(config, init) {
1158
1306
  }
1159
1307
 
1160
1308
  // src/api/routes/tenants/[tenantId]/users/[userId]/index.ts
1161
- var key13 = "TENANT_USER";
1162
- async function route16(request2, config) {
1309
+ var key15 = "TENANT_USER";
1310
+ async function route18(request2, config) {
1163
1311
  const { info } = Logger(
1164
1312
  { ...config, debug: config.debug },
1165
- `[ROUTES][${key13}]`
1313
+ `[ROUTES][${key15}]`
1166
1314
  );
1167
1315
  const session = await auth(request2, config);
1168
1316
  if (!session) {
@@ -1177,21 +1325,21 @@ async function route16(request2, config) {
1177
1325
  }
1178
1326
  switch (request2.method) {
1179
1327
  case "PUT":
1180
- return await PUT4(config, { request: request2 });
1328
+ return await PUT5(config, { request: request2 });
1181
1329
  case "DELETE":
1182
1330
  return await DELETE3(config, { request: request2 });
1183
1331
  default:
1184
1332
  return new Response("method not allowed", { status: 405 });
1185
1333
  }
1186
1334
  }
1187
- function matches16(configRoutes, request2) {
1335
+ function matches18(configRoutes, request2) {
1188
1336
  const url = new URL(request2.url);
1189
1337
  const [, userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
1190
- let route17 = configRoutes[key13].replace("{tenantId}", tenantId).replace("{userId}", userId);
1338
+ let route20 = configRoutes[key15].replace("{tenantId}", tenantId).replace("{userId}", userId);
1191
1339
  if (userId === "users") {
1192
- route17 = configRoutes[key13].replace("{tenantId}", possibleTenantId);
1340
+ route20 = configRoutes[key15].replace("{tenantId}", possibleTenantId);
1193
1341
  }
1194
- return urlMatches(request2.url, route17);
1342
+ return urlMatches(request2.url, route20);
1195
1343
  }
1196
1344
  async function fetchTenantUser(config, method) {
1197
1345
  if (!config.tenantId) {
@@ -1215,21 +1363,54 @@ async function fetchTenantUser(config, method) {
1215
1363
  return await config.handlers[method](req);
1216
1364
  }
1217
1365
 
1366
+ // src/api/routes/tenants/[tenantId]/invite/[inviteId]/DELETE.ts
1367
+ async function DELETE4(config, init) {
1368
+ const yurl = new URL(init.request.url);
1369
+ const [inviteId, , tenantId] = yurl.pathname.split("/").reverse();
1370
+ if (!tenantId) {
1371
+ return new Response(null, { status: 404 });
1372
+ }
1373
+ init.method = "DELETE";
1374
+ const url = `${apiRoutes(config).INVITE(tenantId)}/${inviteId}`;
1375
+ return await request(url, init, config);
1376
+ }
1377
+
1378
+ // src/api/routes/tenants/[tenantId]/invite/[inviteId]/index.ts
1379
+ var key16 = "INVITE";
1380
+ async function route19(request2, config) {
1381
+ switch (request2.method) {
1382
+ case "DELETE":
1383
+ return await DELETE4(config, { request: request2 });
1384
+ default:
1385
+ return new Response("method not allowed", { status: 405 });
1386
+ }
1387
+ }
1388
+ function matches19(configRoutes, request2) {
1389
+ const url = new URL(request2.url);
1390
+ const [inviteId, , tenantId] = url.pathname.split("/").reverse();
1391
+ const route20 = configRoutes[key16].replace("{tenantId}", tenantId).replace("{inviteId}", inviteId);
1392
+ return urlMatches(request2.url, route20);
1393
+ }
1394
+
1218
1395
  // src/api/handlers/DELETE.ts
1219
1396
  function DELETER(configRoutes, config) {
1220
1397
  const { info, warn } = Logger(config, "[DELETE MATCHER]");
1221
- return async function DELETE4(req) {
1222
- if (matches16(configRoutes, req)) {
1398
+ return async function DELETE5(req) {
1399
+ if (matches19(configRoutes, req)) {
1400
+ info("matches tenant invite id");
1401
+ return route19(req, config);
1402
+ }
1403
+ if (matches18(configRoutes, req)) {
1223
1404
  info("matches tenant user");
1224
- return route16(req, config);
1405
+ return route18(req, config);
1225
1406
  }
1226
1407
  if (matches3(configRoutes, req)) {
1227
1408
  info("matches tenant users");
1228
1409
  return route3(req, config);
1229
1410
  }
1230
- if (matches4(configRoutes, req)) {
1411
+ if (matches6(configRoutes, req)) {
1231
1412
  info("matches tenants");
1232
- return route4(req, config);
1413
+ return route6(req, config);
1233
1414
  }
1234
1415
  if (matches(configRoutes, req)) {
1235
1416
  info("matches me");
@@ -1243,10 +1424,14 @@ function DELETER(configRoutes, config) {
1243
1424
  // src/api/handlers/PUT.ts
1244
1425
  function PUTER(configRoutes, config) {
1245
1426
  const { info, warn } = Logger(config, "[PUT MATCHER]");
1246
- return async function PUT5(req) {
1247
- if (matches16(configRoutes, req)) {
1427
+ return async function PUT6(req) {
1428
+ if (matches4(configRoutes, req)) {
1429
+ info("matches tenant invite");
1430
+ return route4(req, config);
1431
+ }
1432
+ if (matches18(configRoutes, req)) {
1248
1433
  info("matches tenant user");
1249
- return route16(req, config);
1434
+ return route18(req, config);
1250
1435
  }
1251
1436
  if (matches3(configRoutes, req)) {
1252
1437
  info("matches tenant users");
@@ -1260,13 +1445,13 @@ function PUTER(configRoutes, config) {
1260
1445
  info("matches me");
1261
1446
  return route(req, config);
1262
1447
  }
1263
- if (matches4(configRoutes, req)) {
1448
+ if (matches6(configRoutes, req)) {
1264
1449
  info("matches tenants");
1265
- return route4(req, config);
1450
+ return route6(req, config);
1266
1451
  }
1267
- if (matches13(configRoutes, req)) {
1452
+ if (matches15(configRoutes, req)) {
1268
1453
  info("matches reset password");
1269
- return route13(req, config);
1454
+ return route15(req, config);
1270
1455
  }
1271
1456
  warn("No PUT routes matched");
1272
1457
  return new Response(null, { status: 404 });
@@ -1275,15 +1460,15 @@ function PUTER(configRoutes, config) {
1275
1460
 
1276
1461
  // src/api/handlers/index.ts
1277
1462
  function Handlers(configRoutes, config) {
1278
- const GET6 = GETTER(configRoutes, config);
1279
- const POST5 = POSTER(configRoutes, config);
1280
- const DELETE4 = DELETER(configRoutes, config);
1281
- const PUT5 = PUTER(configRoutes, config);
1463
+ const GET7 = GETTER(configRoutes, config);
1464
+ const POST6 = POSTER(configRoutes, config);
1465
+ const DELETE5 = DELETER(configRoutes, config);
1466
+ const PUT6 = PUTER(configRoutes, config);
1282
1467
  return {
1283
- GET: GET6,
1284
- POST: POST5,
1285
- DELETE: DELETE4,
1286
- PUT: PUT5
1468
+ GET: GET7,
1469
+ POST: POST6,
1470
+ DELETE: DELETE5,
1471
+ PUT: PUT6
1287
1472
  };
1288
1473
  }
1289
1474
  var getApiUrl = (cfg) => {
@@ -1316,7 +1501,8 @@ var getSecureCookies = (cfg) => {
1316
1501
  return void 0;
1317
1502
  };
1318
1503
  var getUsername = (cfg) => {
1319
- const { config, logger } = cfg;
1504
+ const { config } = cfg;
1505
+ const logger = config.logger;
1320
1506
  const { info } = Logger(config, "[username]");
1321
1507
  if (config?.user) {
1322
1508
  logger && info(`${logger}[config] ${config.user}`);
@@ -1342,7 +1528,8 @@ var getUsername = (cfg) => {
1342
1528
  );
1343
1529
  };
1344
1530
  var getPassword = (cfg) => {
1345
- const { config, logger } = cfg;
1531
+ const { config } = cfg;
1532
+ const logger = config.logger;
1346
1533
  const log = logProtector(logger);
1347
1534
  const { info } = Logger(config, "[password]");
1348
1535
  if (stringCheck(config?.password)) {
@@ -1369,7 +1556,8 @@ var getPassword = (cfg) => {
1369
1556
  );
1370
1557
  };
1371
1558
  var getDatabaseName = (cfg) => {
1372
- const { config, logger } = cfg;
1559
+ const { config } = cfg;
1560
+ const logger = config.logger;
1373
1561
  const { info } = Logger(config, "[databaseName]");
1374
1562
  if (stringCheck(config?.databaseName)) {
1375
1563
  logger && info(`${logger}[config] ${config?.databaseName}`);
@@ -1392,7 +1580,8 @@ var getDatabaseName = (cfg) => {
1392
1580
  );
1393
1581
  };
1394
1582
  var getTenantId = (cfg) => {
1395
- const { config, logger } = cfg;
1583
+ const { config } = cfg;
1584
+ const logger = config.logger;
1396
1585
  const { info } = Logger(config, "[tenantId]");
1397
1586
  if (stringCheck(config?.tenantId)) {
1398
1587
  logger && info(`${logger}[config] ${config?.tenantId}`);
@@ -1405,7 +1594,8 @@ var getTenantId = (cfg) => {
1405
1594
  return null;
1406
1595
  };
1407
1596
  function getDbHost(cfg) {
1408
- const { config, logger } = cfg;
1597
+ const { config } = cfg;
1598
+ const logger = config.logger;
1409
1599
  const { info } = Logger(config, "[db.host]");
1410
1600
  if (stringCheck(config?.db && config.db.host)) {
1411
1601
  logger && info(`${logger}[config] ${config?.db?.host}`);
@@ -1428,7 +1618,8 @@ function getDbHost(cfg) {
1428
1618
  return "db.thenile.dev";
1429
1619
  }
1430
1620
  function getDbPort(cfg) {
1431
- const { config, logger } = cfg;
1621
+ const { config } = cfg;
1622
+ const logger = config.logger;
1432
1623
  const { info } = Logger(config, "[db.port]");
1433
1624
  if (config?.db?.port && config.db.port != null) {
1434
1625
  logger && info(`${logger}[config] ${config?.db.port}`);
@@ -1466,6 +1657,8 @@ var Config = class {
1466
1657
  routes;
1467
1658
  handlers;
1468
1659
  paths;
1660
+ extensionCtx;
1661
+ extensions;
1469
1662
  logger;
1470
1663
  /**
1471
1664
  * Stores the set tenant id from Server for use in sub classes
@@ -1500,14 +1693,19 @@ var Config = class {
1500
1693
  routePrefix;
1501
1694
  db;
1502
1695
  // api: ApiConfig;
1503
- constructor(config, logger) {
1504
- const envVarConfig = { config, logger };
1696
+ constructor(config) {
1505
1697
  this.routePrefix = config?.routePrefix ?? "/api";
1506
- this.secureCookies = getSecureCookies(envVarConfig);
1507
- this.callbackUrl = getCallbackUrl(envVarConfig);
1508
1698
  this.debug = config?.debug;
1509
1699
  this.origin = config?.origin;
1700
+ this.extensions = config?.extensions;
1701
+ this.extensionCtx = config?.extensionCtx;
1510
1702
  this.serverOrigin = config?.origin ?? "http://localhost:3000";
1703
+ this.logger = config?.logger ?? Logger(this);
1704
+ const envVarConfig = {
1705
+ config: { ...config, logger: this.logger }
1706
+ };
1707
+ this.secureCookies = getSecureCookies(envVarConfig);
1708
+ this.callbackUrl = getCallbackUrl(envVarConfig);
1511
1709
  this.apiUrl = getApiUrl(envVarConfig);
1512
1710
  const user = getUsername(envVarConfig);
1513
1711
  const password = getPassword(envVarConfig);
@@ -1574,7 +1772,6 @@ var Config = class {
1574
1772
  };
1575
1773
  this.tenantId = config?.tenantId;
1576
1774
  this.userId = config?.userId;
1577
- this.logger = config?.logger;
1578
1775
  }
1579
1776
  };
1580
1777
 
@@ -1608,6 +1805,9 @@ var Eventer = class {
1608
1805
  }
1609
1806
  };
1610
1807
  var eventer = new Eventer();
1808
+ var updateTenantId = (tenantId) => {
1809
+ eventer.publish("tenantId" /* Tenant */, tenantId);
1810
+ };
1611
1811
  var watchTenantId = (cb) => eventer.subscribe("tenantId" /* Tenant */, cb);
1612
1812
  var watchUserId = (cb) => eventer.subscribe("userId" /* User */, cb);
1613
1813
  var evictPool = (val) => {
@@ -1867,7 +2067,7 @@ var Auth = class {
1867
2067
  }
1868
2068
  }
1869
2069
  async getCsrf(rawResponse = false) {
1870
- return await getCsrf(this.#config, rawResponse);
2070
+ return await obtainCsrf(this.#config, rawResponse);
1871
2071
  }
1872
2072
  async listProviders(rawResponse = false) {
1873
2073
  const res = await fetchProviders(this.#config);
@@ -1937,16 +2137,54 @@ var Auth = class {
1937
2137
  return res;
1938
2138
  }
1939
2139
  try {
1940
- return await res.clone().json();
2140
+ const json = await res.clone().json();
2141
+ if (json && typeof json === "object" && "tenants" in json) {
2142
+ const tenantId = json.tenants[0];
2143
+ if (tenantId) {
2144
+ updateTenantId(tenantId);
2145
+ }
2146
+ }
2147
+ return json;
1941
2148
  } catch {
1942
2149
  return res;
1943
2150
  }
1944
2151
  }
2152
+ async forgotPassword(req) {
2153
+ let email = "";
2154
+ const defaults = defaultCallbackUrl({
2155
+ config: this.#config
2156
+ });
2157
+ let callbackUrl = defaults.callbackUrl;
2158
+ let redirectUrl = defaults.redirectUrl;
2159
+ if ("email" in req) {
2160
+ email = req.email;
2161
+ }
2162
+ if ("callbackUrl" in req) {
2163
+ callbackUrl = req.callbackUrl ? req.callbackUrl : null;
2164
+ }
2165
+ if ("redirectUrl" in req) {
2166
+ redirectUrl = req.redirectUrl ? req.redirectUrl : null;
2167
+ }
2168
+ const body = JSON.stringify({
2169
+ email,
2170
+ redirectUrl,
2171
+ callbackUrl
2172
+ });
2173
+ const data = await fetchResetPassword(
2174
+ this.#config,
2175
+ "POST",
2176
+ body,
2177
+ new URLSearchParams(),
2178
+ false
2179
+ );
2180
+ return data;
2181
+ }
1945
2182
  async resetPassword(req) {
1946
2183
  let email = "";
1947
2184
  let password = "";
1948
- let callbackUrl = null;
1949
- let redirectUrl = null;
2185
+ const defaults = defaultCallbackUrl({ config: this.#config });
2186
+ let callbackUrl = defaults.callbackUrl;
2187
+ let redirectUrl = defaults.redirectUrl;
1950
2188
  if (req instanceof Request) {
1951
2189
  const body2 = await req.json();
1952
2190
  email = body2.email;
@@ -1975,19 +2213,6 @@ var Auth = class {
1975
2213
  redirectUrl = req.redirectUrl ? req.redirectUrl : null;
1976
2214
  }
1977
2215
  }
1978
- const fallbackCb = parseCallback(this.#config.headers);
1979
- if (fallbackCb) {
1980
- const [, value] = fallbackCb.split("=");
1981
- if (value) {
1982
- const parsedUrl = decodeURIComponent(value);
1983
- if (!redirectUrl) {
1984
- redirectUrl = `${new URL(parsedUrl).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
1985
- }
1986
- }
1987
- if (!callbackUrl) {
1988
- callbackUrl = value;
1989
- }
1990
- }
1991
2216
  await this.getCsrf();
1992
2217
  const body = JSON.stringify({
1993
2218
  email,
@@ -2206,9 +2431,22 @@ function parseResetToken(headers) {
2206
2431
  const [, token] = /((__Secure-)?nile\.reset=[^;]+)/.exec(authCookie) ?? [];
2207
2432
  return token;
2208
2433
  }
2434
+ function defaultCallbackUrl({ config }) {
2435
+ let cb = null;
2436
+ let redirect = null;
2437
+ const fallbackCb = parseCallback(config.headers);
2438
+ if (fallbackCb) {
2439
+ const [, value] = fallbackCb.split("=");
2440
+ cb = decodeURIComponent(value);
2441
+ if (value) {
2442
+ redirect = `${new URL(cb).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
2443
+ }
2444
+ }
2445
+ return { callbackUrl: cb, redirectUrl: redirect };
2446
+ }
2209
2447
 
2210
- // src/auth/getCsrf.ts
2211
- async function getCsrf(config, rawResponse = false) {
2448
+ // src/auth/obtainCsrf.ts
2449
+ async function obtainCsrf(config, rawResponse = false) {
2212
2450
  const res = await fetchCsrf(config);
2213
2451
  const csrfCook = parseCSRF(res.headers);
2214
2452
  if (csrfCook) {
@@ -2294,21 +2532,27 @@ var Users = class {
2294
2532
  return res;
2295
2533
  }
2296
2534
  }
2297
- async verifySelf(bypassEmail = process.env.NODE_ENV !== "production", rawResponse = false) {
2535
+ async verifySelf(options, rawResponse = false) {
2536
+ const bypassEmail = typeof options === "object" ? options.bypassEmail ?? process.env.NODE_ENV !== "production" : process.env.NODE_ENV !== "production";
2537
+ const callbackUrl = typeof options === "object" ? options.callbackUrl : defaultCallbackUrl2(this.#config).callbackUrl;
2298
2538
  try {
2299
2539
  const me = await this.getSelf();
2300
2540
  if (me instanceof Response) {
2301
2541
  return me;
2302
2542
  }
2303
- const res = await verifyEmailAddress(this.#config, me);
2543
+ const res = await verifyEmailAddress(
2544
+ this.#config,
2545
+ me,
2546
+ String(callbackUrl)
2547
+ );
2304
2548
  return res;
2305
2549
  } catch {
2306
2550
  this.#logger?.warn(
2307
- "Unable to verify email. The current user's email will be set to verified any way. Be sure to configure emails for production."
2551
+ "Unable to verify email. The current user's email will be set to verified anyway. Be sure to configure emails for production."
2308
2552
  );
2309
2553
  }
2310
2554
  if (bypassEmail) {
2311
- return await this.updateSelf({ emailVerified: true }, rawResponse);
2555
+ return this.updateSelf({ emailVerified: true }, rawResponse);
2312
2556
  }
2313
2557
  this.#logger.error(
2314
2558
  "Unable to verify email address. Configure your SMTP server in the console."
@@ -2316,19 +2560,34 @@ var Users = class {
2316
2560
  return void 0;
2317
2561
  }
2318
2562
  };
2319
- async function verifyEmailAddress(config, user) {
2563
+ async function verifyEmailAddress(config, user, callback) {
2320
2564
  config.headers.set("content-type", "application/x-www-form-urlencoded");
2321
- const { csrfToken } = await getCsrf(config);
2565
+ const { csrfToken } = await obtainCsrf(config);
2566
+ const defaults = defaultCallbackUrl2(config);
2567
+ const callbackUrl = callback ?? String(defaults.callbackUrl);
2322
2568
  const res = await fetchVerifyEmail(
2323
2569
  config,
2324
2570
  "POST",
2325
- new URLSearchParams({ csrfToken, email: user.email }).toString()
2571
+ new URLSearchParams({
2572
+ csrfToken,
2573
+ email: user.email,
2574
+ callbackUrl
2575
+ }).toString()
2326
2576
  );
2327
2577
  if (res.status > 299) {
2328
2578
  throw new Error(await res.text());
2329
2579
  }
2330
2580
  return res;
2331
2581
  }
2582
+ function defaultCallbackUrl2(config) {
2583
+ let cb = null;
2584
+ const fallbackCb = parseCallback(config.headers);
2585
+ if (fallbackCb) {
2586
+ const [, value] = fallbackCb.split("=");
2587
+ cb = decodeURIComponent(value);
2588
+ }
2589
+ return { callbackUrl: cb };
2590
+ }
2332
2591
 
2333
2592
  // src/tenants/index.ts
2334
2593
  var Tenants = class {
@@ -2451,6 +2710,74 @@ var Tenants = class {
2451
2710
  rawResponse || typeof req === "boolean" && req
2452
2711
  );
2453
2712
  }
2713
+ async invites() {
2714
+ const res = await fetchInvites(this.#config);
2715
+ return responseHandler(res);
2716
+ }
2717
+ async invite(req, rawResponse) {
2718
+ const { csrfToken } = await obtainCsrf(this.#config);
2719
+ const defaults = defaultCallbackUrl3(this.#config);
2720
+ let identifier = req;
2721
+ let callbackUrl = defaults.callbackUrl;
2722
+ let redirectUrl = defaults.redirectUrl;
2723
+ if (typeof req === "object") {
2724
+ if ("email" in req) {
2725
+ identifier = req.email;
2726
+ }
2727
+ if ("callbackUrl" in req) {
2728
+ callbackUrl = req.callbackUrl ? req.callbackUrl : "";
2729
+ }
2730
+ if ("redirectUrl" in req) {
2731
+ redirectUrl = req.redirectUrl ? req.redirectUrl : "";
2732
+ }
2733
+ }
2734
+ this.#config.headers.set(
2735
+ "Content-Type",
2736
+ "application/x-www-form-urlencoded"
2737
+ );
2738
+ const res = await fetchInvite(
2739
+ this.#config,
2740
+ "POST",
2741
+ new URLSearchParams({
2742
+ identifier,
2743
+ csrfToken,
2744
+ callbackUrl,
2745
+ redirectUrl
2746
+ }).toString()
2747
+ );
2748
+ return responseHandler(res, rawResponse);
2749
+ }
2750
+ async acceptInvite(req, rawResponse) {
2751
+ if (!req) {
2752
+ throw new Error("The identifier and token are required.");
2753
+ }
2754
+ const { identifier, token } = req;
2755
+ const defaults = defaultCallbackUrl3(this.#config);
2756
+ const callbackUrl = String(defaults.callbackUrl);
2757
+ const res = await fetchInvite(
2758
+ this.#config,
2759
+ "PUT",
2760
+ new URLSearchParams({
2761
+ identifier,
2762
+ token,
2763
+ callbackUrl
2764
+ }).toString()
2765
+ );
2766
+ return responseHandler(res, rawResponse);
2767
+ }
2768
+ async deleteInvite(req) {
2769
+ let id = "";
2770
+ if (typeof req === "object") {
2771
+ id = req.id;
2772
+ } else {
2773
+ id = req;
2774
+ }
2775
+ if (!id) {
2776
+ throw new Error("An invite id is required.");
2777
+ }
2778
+ const res = await fetchInvite(this.#config, "DELETE", id);
2779
+ return responseHandler(res, true);
2780
+ }
2454
2781
  #handleContext(req) {
2455
2782
  if (typeof req === "object") {
2456
2783
  if ("tenantId" in req) {
@@ -2472,31 +2799,47 @@ async function responseHandler(res, rawResponse) {
2472
2799
  return res;
2473
2800
  }
2474
2801
  }
2802
+ function defaultCallbackUrl3(config) {
2803
+ let cb = null;
2804
+ let redirect = null;
2805
+ const fallbackCb = parseCallback(config.headers);
2806
+ if (fallbackCb) {
2807
+ const [, value] = fallbackCb.split("=");
2808
+ cb = decodeURIComponent(value);
2809
+ if (value) {
2810
+ redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace(
2811
+ "{tenantId}",
2812
+ String(config.tenantId)
2813
+ )}`;
2814
+ }
2815
+ }
2816
+ return { callbackUrl: cb, redirectUrl: redirect };
2817
+ }
2475
2818
 
2476
2819
  // src/api/handlers/withContext/index.ts
2477
2820
  function handlersWithContext(config) {
2478
- const GET6 = GETTER(config.routes, config);
2479
- const POST5 = POSTER(config.routes, config);
2480
- const DELETE4 = DELETER(config.routes, config);
2481
- const PUT5 = PUTER(config.routes, config);
2821
+ const GET7 = GETTER(config.routes, config);
2822
+ const POST6 = POSTER(config.routes, config);
2823
+ const DELETE5 = DELETER(config.routes, config);
2824
+ const PUT6 = PUTER(config.routes, config);
2482
2825
  return {
2483
2826
  GET: async (req) => {
2484
- const response = await GET6(req);
2827
+ const response = await GET7(req);
2485
2828
  const updatedConfig = updateConfig(response, config);
2486
2829
  return { response, nile: new Server(updatedConfig) };
2487
2830
  },
2488
2831
  POST: async (req) => {
2489
- const response = await POST5(req);
2832
+ const response = await POST6(req);
2490
2833
  const updatedConfig = updateConfig(response, config);
2491
2834
  return { response, nile: new Server(updatedConfig) };
2492
2835
  },
2493
2836
  DELETE: async (req) => {
2494
- const response = await DELETE4(req);
2837
+ const response = await DELETE5(req);
2495
2838
  const updatedConfig = updateConfig(response, config);
2496
2839
  return { response, nile: new Server(updatedConfig) };
2497
2840
  },
2498
2841
  PUT: async (req) => {
2499
- const response = await PUT5(req);
2842
+ const response = await PUT6(req);
2500
2843
  const updatedConfig = updateConfig(response, config);
2501
2844
  return { response, nile: new Server(updatedConfig) };
2502
2845
  }
@@ -2514,8 +2857,8 @@ function updateConfig(response, config) {
2514
2857
  }
2515
2858
  const setCookies = [];
2516
2859
  if (response?.headers) {
2517
- for (const [key14, value] of response.headers) {
2518
- if (key14.toLowerCase() === "set-cookie") {
2860
+ for (const [key17, value] of response.headers) {
2861
+ if (key17.toLowerCase() === "set-cookie") {
2519
2862
  setCookies.push(value);
2520
2863
  }
2521
2864
  }
@@ -2531,6 +2874,36 @@ function updateConfig(response, config) {
2531
2874
  };
2532
2875
  }
2533
2876
 
2877
+ // src/api/utils/extensions.ts
2878
+ function bindHandleOnRequest(instance) {
2879
+ return async function handleOnRequest(config, _init, params) {
2880
+ if (config.extensions) {
2881
+ for (const create2 of config.extensions) {
2882
+ const ext = await create2(instance);
2883
+ if (ext.onRequest) {
2884
+ const modified = await ext.onRequest(_init.request);
2885
+ if (modified?.headers) {
2886
+ const modHeaders = new Headers(modified.headers);
2887
+ const cookie = modHeaders.get("cookie");
2888
+ if (cookie) {
2889
+ params.headers.set("cookie", cookie);
2890
+ config.logger.debug(
2891
+ `extension ${ext.id ?? create2.name} modified cookie`
2892
+ );
2893
+ }
2894
+ }
2895
+ }
2896
+ config.logger.debug(`extension ${ext.id ?? create2.name} ran onRequest`);
2897
+ }
2898
+ }
2899
+ };
2900
+ }
2901
+ function buildExtensionConfig(instance) {
2902
+ return {
2903
+ handleOnRequest: bindHandleOnRequest(instance)
2904
+ };
2905
+ }
2906
+
2534
2907
  // src/Server.ts
2535
2908
  var Server = class {
2536
2909
  users;
@@ -2542,7 +2915,10 @@ var Server = class {
2542
2915
  #manager;
2543
2916
  #headers;
2544
2917
  constructor(config) {
2545
- this.#config = new Config(config, "[initial config]");
2918
+ this.#config = new Config({
2919
+ ...config,
2920
+ extensionCtx: buildExtensionConfig(this)
2921
+ });
2546
2922
  watchTenantId((tenantId) => {
2547
2923
  if (tenantId !== this.#config.tenantId) {
2548
2924
  this.#config.tenantId = tenantId;
@@ -2667,32 +3043,33 @@ var Server = class {
2667
3043
  } else if (config?.headers) {
2668
3044
  headers = config?.headers;
2669
3045
  if (config && config.origin) {
2670
- this.#headers.set(X_NILE_ORIGIN, config.origin);
3046
+ this.#headers.set(HEADER_ORIGIN, config.origin);
2671
3047
  }
2672
3048
  if (config && config.secureCookies != null) {
2673
- this.#headers.set(X_NILE_SECURECOOKIES, String(config.secureCookies));
3049
+ this.#headers.set(HEADER_SECURE_COOKIES, String(config.secureCookies));
2674
3050
  }
2675
3051
  }
2676
3052
  if (headers instanceof Headers) {
2677
- headers.forEach((value, key14) => {
2678
- updates.push([key14.toLowerCase(), value]);
3053
+ headers.forEach((value, key17) => {
3054
+ updates.push([key17.toLowerCase(), value]);
2679
3055
  });
2680
3056
  } else {
2681
- for (const [key14, value] of Object.entries(headers ?? {})) {
2682
- updates.push([key14.toLowerCase(), value]);
3057
+ for (const [key17, value] of Object.entries(headers ?? {})) {
3058
+ updates.push([key17.toLowerCase(), value]);
2683
3059
  }
2684
3060
  }
2685
3061
  const merged = {};
2686
- this.#headers?.forEach((value, key14) => {
2687
- if (key14.toLowerCase() !== "cookie") {
2688
- merged[key14.toLowerCase()] = value;
3062
+ this.#config.tenantId = getTenantFromHttp(this.#headers, this.#config);
3063
+ this.#headers?.forEach((value, key17) => {
3064
+ if (key17.toLowerCase() !== "cookie") {
3065
+ merged[key17.toLowerCase()] = value;
2689
3066
  }
2690
3067
  });
2691
- for (const [key14, value] of updates) {
2692
- merged[key14] = value;
3068
+ for (const [key17, value] of updates) {
3069
+ merged[key17] = value;
2693
3070
  }
2694
- for (const [key14, value] of Object.entries(merged)) {
2695
- this.#headers.set(key14, value);
3071
+ for (const [key17, value] of Object.entries(merged)) {
3072
+ this.#headers.set(key17, value);
2696
3073
  }
2697
3074
  this.#config.headers = this.#headers;
2698
3075
  }
@@ -2715,9 +3092,13 @@ function create(config) {
2715
3092
  }
2716
3093
 
2717
3094
  exports.APIErrorErrorCodeEnum = APIErrorErrorCodeEnum;
3095
+ exports.HEADER_ORIGIN = HEADER_ORIGIN;
3096
+ exports.HEADER_SECURE_COOKIES = HEADER_SECURE_COOKIES;
2718
3097
  exports.LoginUserResponseTokenTypeEnum = LoginUserResponseTokenTypeEnum;
2719
3098
  exports.Nile = create;
2720
3099
  exports.Server = Server;
3100
+ exports.TENANT_COOKIE = TENANT_COOKIE;
3101
+ exports.USER_COOKIE = USER_COOKIE;
2721
3102
  exports.parseCSRF = parseCSRF;
2722
3103
  exports.parseCallback = parseCallback;
2723
3104
  exports.parseToken = parseToken;