@niledatabase/server 5.0.0-alpha.1 → 5.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -25,9 +25,16 @@ var LoginUserResponseTokenTypeEnum = {
25
25
  IdToken: "ID_TOKEN"
26
26
  };
27
27
 
28
+ // src/utils/constants.ts
29
+ var TENANT_COOKIE = "nile.tenant-id";
30
+ var USER_COOKIE = "nile.user-id";
31
+ var HEADER_ORIGIN = "nile-origin";
32
+ var HEADER_SECURE_COOKIES = "nile-secure-cookies";
33
+
28
34
  // src/api/utils/routes/index.ts
29
35
  var NILEDB_API_URL = process.env.NILEDB_API_URL;
30
- var appRoutes = (prefix = "/api") => ({
36
+ var DEFAULT_PREFIX = "/api";
37
+ var appRoutes = (prefix = DEFAULT_PREFIX) => ({
31
38
  SIGNIN: `${prefix}${"/auth/signin" /* SIGNIN */}`,
32
39
  PROVIDERS: `${prefix}${"/auth/providers" /* PROVIDERS */}`,
33
40
  SESSION: `${prefix}${"/auth/session" /* SESSION */}`,
@@ -36,7 +43,8 @@ var appRoutes = (prefix = "/api") => ({
36
43
  SIGNOUT: `${prefix}${"/auth/signout" /* SIGNOUT */}`,
37
44
  ERROR: `${prefix}/auth/error`,
38
45
  VERIFY_REQUEST: `${prefix}/auth/verify-request`,
39
- PASSWORD_RESET: `${prefix}/auth/reset-password`,
46
+ VERIFY_EMAIL: `${prefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`,
47
+ PASSWORD_RESET: `${prefix}${"/auth/reset-password" /* PASSWORD_RESET */}`,
40
48
  ME: `${prefix}${"/me" /* ME */}`,
41
49
  USERS: `${prefix}${"/users" /* USERS */}`,
42
50
  USER_TENANTS: `${prefix}${"/users/{userId}/tenants" /* USER_TENANTS */}`,
@@ -45,6 +53,8 @@ var appRoutes = (prefix = "/api") => ({
45
53
  TENANT_USER: `${prefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */}`,
46
54
  TENANT_USERS: `${prefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */}`,
47
55
  SIGNUP: `${prefix}${"/signup" /* SIGNUP */}`,
56
+ INVITES: `${prefix}${"/tenants/{tenantId}/invites" /* INVITES */}`,
57
+ INVITE: `${prefix}${"/tenants/{tenantId}/invite" /* INVITE */}`,
48
58
  LOG: `${prefix}/_log`
49
59
  });
50
60
  var apiRoutes = (config) => ({
@@ -55,6 +65,8 @@ var apiRoutes = (config) => ({
55
65
  TENANT: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}`),
56
66
  SIGNUP: makeRestUrl(config, "/signup"),
57
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`),
58
70
  TENANT_USER: makeRestUrl(
59
71
  config,
60
72
  `/tenants/${config.tenantId}/users/${config.userId}`
@@ -70,7 +82,8 @@ var proxyRoutes = (config) => ({
70
82
  SIGNOUT: makeRestUrl(config, "/auth/signout" /* SIGNOUT */),
71
83
  ERROR: makeRestUrl(config, "/auth/error"),
72
84
  VERIFY_REQUEST: makeRestUrl(config, "/auth/verify-request"),
73
- PASSWORD_RESET: makeRestUrl(config, "/auth/reset-password")
85
+ PASSWORD_RESET: makeRestUrl(config, "/auth/reset-password" /* PASSWORD_RESET */),
86
+ VERIFY_EMAIL: makeRestUrl(config, "/auth/verify-email" /* VERIFY_EMAIL */)
74
87
  });
75
88
  function filterNullUndefined(obj) {
76
89
  if (!obj) {
@@ -95,9 +108,9 @@ function makeRestUrl(config, path, qp) {
95
108
  const strParams = params.toString();
96
109
  return `${[url, path.substring(1, path.length)].join("/")}${strParams ? `?${strParams}` : ""}`;
97
110
  }
98
- function urlMatches(requestUrl, route16) {
111
+ function urlMatches(requestUrl, route20) {
99
112
  const url = new URL(requestUrl);
100
- return url.pathname.startsWith(route16);
113
+ return url.pathname.startsWith(route20);
101
114
  }
102
115
  function isUUID(value) {
103
116
  if (!value) {
@@ -107,109 +120,61 @@ function isUUID(value) {
107
120
  return regex.test(value);
108
121
  }
109
122
 
110
- // src/utils/Logger.ts
111
- var red = "\x1B[31m";
112
- var yellow = "\x1B[38;2;255;255;0m";
113
- var purple = "\x1B[38;2;200;160;255m";
114
- var orange = "\x1B[38;2;255;165;0m";
115
- var reset = "\x1B[0m";
116
- var baseLogger = (config, ...params) => ({
117
- info(message, meta) {
118
- if (config?.debug) {
119
- console.info(
120
- `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
121
- ""
122
- )}${reset} ${message}`,
123
- meta ? `${JSON.stringify(meta)}` : ""
124
- );
125
- }
126
- },
127
- debug(message, meta) {
128
- if (config?.debug) {
129
- console.debug(
130
- `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
131
- ""
132
- )}${reset} ${message}`,
133
- meta ? `${JSON.stringify(meta)}` : ""
134
- );
135
- }
136
- },
137
- warn(message, meta) {
138
- if (config?.debug) {
139
- console.warn(
140
- `${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
141
- ""
142
- )}${reset} ${message}`,
143
- meta ? JSON.stringify(meta) : ""
144
- );
145
- }
146
- },
147
- error(message, meta) {
148
- console.error(
149
- `${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
150
- ""
151
- )}${red} ${message}`,
152
- meta ? meta : "",
153
- `${reset}`
154
- );
155
- }
156
- });
157
- function Logger(config, ...params) {
158
- const base = baseLogger(config, params);
159
- const info = config?.logger?.info ?? base.info;
160
- const debug = config?.logger?.debug ?? base.debug;
161
- const warn = config?.logger?.warn ?? base.warn;
162
- const error = config?.logger?.error ?? base.error;
163
- return { info, warn, error, debug };
164
- }
165
- function matchesLog(configRoutes, request2) {
166
- return urlMatches(request2.url, configRoutes.LOG);
167
- }
168
-
169
- // src/utils/constants.ts
170
- var X_NILE_TENANT = "nile.tenant_id";
171
- var X_NILE_ORIGIN = "nile.origin";
172
- var X_NILE_SECURECOOKIES = "nile.secure_cookies";
173
-
174
123
  // src/api/utils/request.ts
175
124
  async function request(url, _init, config) {
176
- const { debug, info, error } = Logger(config, "[REQUEST]");
125
+ const { debug, info, error } = config.logger("[REQUEST]");
177
126
  const { request: request2, ...init } = _init;
178
127
  const requestUrl = new URL(request2.url);
179
128
  const updatedHeaders = new Headers({});
180
129
  if (request2.headers.get("cookie")) {
181
130
  updatedHeaders.set("cookie", String(request2.headers.get("cookie")));
182
131
  }
183
- if (request2.headers.get(X_NILE_TENANT)) {
132
+ if (request2.headers.get(TENANT_COOKIE)) {
184
133
  updatedHeaders.set(
185
- X_NILE_TENANT,
186
- String(request2.headers.get(X_NILE_TENANT))
134
+ TENANT_COOKIE,
135
+ String(request2.headers.get(TENANT_COOKIE))
187
136
  );
188
137
  }
189
138
  if (config.secureCookies != null) {
190
- updatedHeaders.set(X_NILE_SECURECOOKIES, String(config.secureCookies));
139
+ updatedHeaders.set(HEADER_SECURE_COOKIES, String(config.secureCookies));
140
+ } else {
141
+ updatedHeaders.set(
142
+ HEADER_SECURE_COOKIES,
143
+ process.env.NODE_ENV === "production" ? "true" : "false"
144
+ );
191
145
  }
192
146
  updatedHeaders.set("host", requestUrl.host);
193
147
  if (config.callbackUrl) {
194
148
  const cbUrl = new URL(config.callbackUrl);
195
149
  debug(`Obtained origin from config.callbackUrl ${config.callbackUrl}`);
196
- updatedHeaders.set(X_NILE_ORIGIN, cbUrl.origin);
150
+ updatedHeaders.set(HEADER_ORIGIN, cbUrl.origin);
151
+ } else if (config.origin) {
152
+ debug(`Obtained origin from config.origin ${config.origin}`);
153
+ updatedHeaders.set(HEADER_ORIGIN, config.origin);
197
154
  } else {
198
- updatedHeaders.set(X_NILE_ORIGIN, requestUrl.origin);
199
- debug(`Obtained origin from request ${requestUrl.origin}`);
155
+ const passedOrigin = request2.headers.get(HEADER_ORIGIN);
156
+ if (passedOrigin) {
157
+ updatedHeaders.set(HEADER_ORIGIN, passedOrigin);
158
+ } else {
159
+ const reqOrigin = config.routePrefix !== DEFAULT_PREFIX ? `${requestUrl.origin}${config.routePrefix}` : requestUrl.origin;
160
+ updatedHeaders.set(HEADER_ORIGIN, reqOrigin);
161
+ debug(`Obtained origin from request ${reqOrigin}`);
162
+ }
200
163
  }
201
164
  const params = { ...init };
202
165
  if (params.method?.toLowerCase() === "post" || params.method?.toLowerCase() === "put") {
203
166
  try {
204
167
  updatedHeaders.set("content-type", "application/json");
205
- const initBody = await new Response(_init.request.clone().body).json();
206
- const requestBody = await new Response(request2.clone().body).json();
207
- params.body = JSON.stringify(initBody ?? requestBody);
168
+ const bodyStream = _init.body ?? _init.request?.body ?? request2.body;
169
+ const bodyText = await new Response(bodyStream).text();
170
+ try {
171
+ params.body = JSON.stringify(JSON.parse(bodyText));
172
+ } catch {
173
+ updatedHeaders.set("content-type", "application/x-www-form-urlencoded");
174
+ params.body = bodyText;
175
+ }
208
176
  } catch (e) {
209
- updatedHeaders.set("content-type", "application/x-www-form-urlencoded");
210
- const initBody = await new Response(_init.request.clone().body).text();
211
- const requestBody = await new Response(request2.clone().body).text();
212
- params.body = initBody ?? requestBody;
177
+ error("Failed to parse request body");
213
178
  }
214
179
  }
215
180
  params.headers = updatedHeaders;
@@ -218,6 +183,7 @@ async function request(url, _init, config) {
218
183
  params.headers.set("request-id", crypto.randomUUID());
219
184
  params.cache = "no-store";
220
185
  }
186
+ await config.extensionCtx?.handleOnRequest(config, _init, params);
221
187
  try {
222
188
  const res = await fetch(fullUrl, {
223
189
  ...params
@@ -254,7 +220,7 @@ async function request(url, _init, config) {
254
220
 
255
221
  // src/api/utils/auth.ts
256
222
  async function auth(req, config) {
257
- const { info, error } = Logger(config, "[nileauth]");
223
+ const { info, error } = config.logger("[nileauth]");
258
224
  info("checking auth");
259
225
  const sessionUrl = `${config.apiUrl}/auth/session`;
260
226
  info(`using session ${sessionUrl}`);
@@ -300,7 +266,7 @@ function matches(configRoutes, request2) {
300
266
  return urlMatches(request2.url, configRoutes[key]);
301
267
  }
302
268
  async function fetchMe(config, method, body) {
303
- const clientUrl = `${config.origin}${config.routePrefix}${"/me" /* ME */}`;
269
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/me" /* ME */}`;
304
270
  const init = {
305
271
  headers: config.headers,
306
272
  method: method ?? "GET"
@@ -330,47 +296,6 @@ async function GET(url, init, config) {
330
296
  return res;
331
297
  }
332
298
 
333
- // src/utils/Event/index.ts
334
- var Eventer = class {
335
- events = {};
336
- publish(eventName, value) {
337
- const callbacks = this.events[eventName];
338
- if (callbacks) {
339
- for (const callback of callbacks) {
340
- callback(value);
341
- }
342
- }
343
- }
344
- subscribe(eventName, callback) {
345
- if (!this.events[eventName]) {
346
- this.events[eventName] = [];
347
- }
348
- this.events[eventName].push(callback);
349
- }
350
- unsubscribe(eventName, callback) {
351
- const callbacks = this.events[eventName];
352
- if (!callbacks) return;
353
- const index = callbacks.indexOf(callback);
354
- if (index !== -1) {
355
- callbacks.splice(index, 1);
356
- }
357
- if (callbacks.length === 0) {
358
- delete this.events[eventName];
359
- }
360
- }
361
- };
362
- var eventer = new Eventer();
363
- var watchTenantId = (cb) => eventer.subscribe("tenantId" /* Tenant */, cb);
364
- var watchUserId = (cb) => eventer.subscribe("userId" /* User */, cb);
365
- var evictPool = (val) => {
366
- eventer.publish("EvictPool" /* EvictPool */, val);
367
- };
368
- var watchEvictPool = (cb) => eventer.subscribe("EvictPool" /* EvictPool */, cb);
369
- var updateHeaders = (val) => {
370
- eventer.publish("headers" /* Headers */, val);
371
- };
372
- var watchHeaders = (cb) => eventer.subscribe("headers" /* Headers */, cb);
373
-
374
299
  // src/utils/fetch.ts
375
300
  function getTokenFromCookie(headers, cookieKey) {
376
301
  const cookie = headers.get("cookie")?.split("; ");
@@ -396,8 +321,8 @@ function getTokenFromCookie(headers, cookieKey) {
396
321
  }
397
322
  }
398
323
  function getTenantFromHttp(headers, config) {
399
- const cookieTenant = getTokenFromCookie(headers, X_NILE_TENANT);
400
- return cookieTenant ?? headers?.get(X_NILE_TENANT) ?? config?.tenantId;
324
+ const cookieTenant = getTokenFromCookie(headers, TENANT_COOKIE);
325
+ return cookieTenant ? cookieTenant : config?.tenantId;
401
326
  }
402
327
 
403
328
  // src/api/routes/users/POST.ts
@@ -407,7 +332,7 @@ async function POST(config, init) {
407
332
  const yurl = new URL(init.request.url);
408
333
  const tenantId = yurl.searchParams.get("tenantId");
409
334
  const newTenantName = yurl.searchParams.get("newTenantName");
410
- const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
335
+ const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
411
336
  const url = apiRoutes(config).USERS({ tenantId: tenant, newTenantName });
412
337
  return await request(url, init, config);
413
338
  }
@@ -416,21 +341,18 @@ async function POST(config, init) {
416
341
  async function GET2(config, init, log) {
417
342
  const yurl = new URL(init.request.url);
418
343
  const tenantId = yurl.searchParams.get("tenantId");
419
- const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
344
+ const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
420
345
  if (!tenant) {
421
346
  log("[GET] No tenant id provided.");
422
347
  return new Response(null, { status: 404 });
423
348
  }
424
- const url = apiRoutes(config).TENANT_USERS(tenant);
425
349
  init.method = "GET";
350
+ const url = apiRoutes(config).TENANT_USERS(tenant);
426
351
  return await request(url, init, config);
427
352
  }
428
353
 
429
354
  // src/api/routes/users/[userId]/PUT.ts
430
- async function PUT2(config, session, init) {
431
- if (!session) {
432
- return new Response(null, { status: 401 });
433
- }
355
+ async function PUT2(config, init) {
434
356
  init.body = init.request.body;
435
357
  init.method = "PUT";
436
358
  const [userId] = new URL(init.request.url).pathname.split("/").reverse();
@@ -441,18 +363,14 @@ async function PUT2(config, session, init) {
441
363
  // src/api/routes/users/index.ts
442
364
  var key2 = "USERS";
443
365
  async function route2(request2, config) {
444
- const { info } = Logger(
445
- { ...config, debug: config.debug },
446
- `[ROUTES][${key2}]`
447
- );
448
- const session = await auth(request2, config);
366
+ const { info } = config.logger(`[ROUTES][${key2}]`);
449
367
  switch (request2.method) {
450
368
  case "GET":
451
369
  return await GET2(config, { request: request2 }, info);
452
370
  case "POST":
453
371
  return await POST(config, { request: request2 });
454
372
  case "PUT":
455
- return await PUT2(config, session, { request: request2 });
373
+ return await PUT2(config, { request: request2 });
456
374
  default:
457
375
  return new Response("method not allowed", { status: 405 });
458
376
  }
@@ -470,7 +388,11 @@ async function GET3(config, init) {
470
388
  }
471
389
 
472
390
  // src/api/routes/tenants/[tenantId]/users/POST.ts
473
- async function POST2(config, session, init) {
391
+ async function POST2(config, init) {
392
+ const session = await auth(init.request, config);
393
+ if (!session) {
394
+ return new Response(null, { status: 401 });
395
+ }
474
396
  const yurl = new URL(init.request.url);
475
397
  const [, tenantId] = yurl.pathname.split("/").reverse();
476
398
  init.body = JSON.stringify({ email: session.email });
@@ -482,15 +404,7 @@ async function POST2(config, session, init) {
482
404
  // src/api/routes/tenants/[tenantId]/users/index.ts
483
405
  var key3 = "TENANT_USERS";
484
406
  async function route3(request2, config) {
485
- const { info } = Logger(
486
- { ...config, debug: config.debug },
487
- `[ROUTES][${key3}]`
488
- );
489
- const session = await auth(request2, config);
490
- if (!session) {
491
- info("401");
492
- return new Response(null, { status: 401 });
493
- }
407
+ const { info } = config.logger(`[ROUTES][${key3}]`);
494
408
  const yurl = new URL(request2.url);
495
409
  const [, tenantId] = yurl.pathname.split("/").reverse();
496
410
  if (!tenantId) {
@@ -501,7 +415,7 @@ async function route3(request2, config) {
501
415
  case "GET":
502
416
  return await GET3(config, { request: request2 });
503
417
  case "POST":
504
- return await POST2(config, session, { request: request2 });
418
+ return await POST2(config, { request: request2 });
505
419
  default:
506
420
  return new Response("method not allowed", { status: 405 });
507
421
  }
@@ -509,21 +423,21 @@ async function route3(request2, config) {
509
423
  function matches3(configRoutes, request2) {
510
424
  const url = new URL(request2.url);
511
425
  const [userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
512
- let route16 = configRoutes[key3].replace("{tenantId}", tenantId).replace("{userId}", userId);
426
+ let route20 = configRoutes[key3].replace("{tenantId}", tenantId).replace("{userId}", userId);
513
427
  if (userId === "users") {
514
- route16 = configRoutes[key3].replace("{tenantId}", possibleTenantId);
428
+ route20 = configRoutes[key3].replace("{tenantId}", possibleTenantId);
515
429
  }
516
- return urlMatches(request2.url, route16);
430
+ return urlMatches(request2.url, route20);
517
431
  }
518
432
  async function fetchTenantUsers(config, method, payload) {
519
433
  const { body, params } = {};
520
434
  if (!config.tenantId) {
521
435
  throw new Error(
522
- 'Unable to fetch tenant, the tenantId context is missing. Call nile.setContext({ tenantId }), set nile.tenantId = "tenantId", or add it to the function call'
436
+ "Unable to fetch the user's tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
523
437
  );
524
438
  }
525
- if (!isUUID(config.tenantId) && config.logger?.warn) {
526
- config.logger?.warn(
439
+ if (!isUUID(config.tenantId)) {
440
+ config.logger("fetchTenantUsers").warn(
527
441
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
528
442
  );
529
443
  }
@@ -534,7 +448,7 @@ async function fetchTenantUsers(config, method, payload) {
534
448
  if (params?.tenantId) {
535
449
  q.set("tenantId", params.tenantId);
536
450
  }
537
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
451
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
538
452
  "{tenantId}",
539
453
  config.tenantId
540
454
  )}`;
@@ -547,8 +461,139 @@ async function fetchTenantUsers(config, method, payload) {
547
461
  return await config.handlers[m](req);
548
462
  }
549
463
 
464
+ // src/api/routes/tenants/[tenantId]/invite/PUT.ts
465
+ async function PUT3(config, init) {
466
+ const yurl = new URL(init.request.url);
467
+ const [, tenantId] = yurl.pathname.split("/").reverse();
468
+ if (!tenantId) {
469
+ return new Response(null, { status: 404 });
470
+ }
471
+ if (yurl.searchParams.size > 0) {
472
+ init.body = new URLSearchParams(yurl.searchParams).toString();
473
+ }
474
+ init.method = "PUT";
475
+ const url = `${apiRoutes(config).INVITE(tenantId)}`;
476
+ const res = await request(url, init, config);
477
+ const location = res?.headers.get("location");
478
+ if (location) {
479
+ return new Response(res?.body, {
480
+ status: 302,
481
+ headers: res?.headers
482
+ });
483
+ }
484
+ return new Response(res?.body, {
485
+ status: res?.status,
486
+ headers: res?.headers
487
+ });
488
+ }
489
+
490
+ // src/api/routes/tenants/[tenantId]/invite/POST.ts
491
+ async function POST3(config, init) {
492
+ const yurl = new URL(init.request.url);
493
+ const [, tenantId] = yurl.pathname.split("/").reverse();
494
+ if (!tenantId) {
495
+ return new Response(null, { status: 404 });
496
+ }
497
+ init.method = "POST";
498
+ init.body = init.request.body;
499
+ const url = `${apiRoutes(config).INVITE(tenantId)}`;
500
+ return await request(url, init, config);
501
+ }
502
+
503
+ // src/api/routes/tenants/[tenantId]/invite/index.ts
504
+ var key4 = "INVITE";
505
+ async function route4(request2, config) {
506
+ switch (request2.method) {
507
+ // the browser is a GET, but we need to PUT it into nile-auth
508
+ // server side, this is a put
509
+ case "GET":
510
+ case "PUT":
511
+ return await PUT3(config, { request: request2 });
512
+ case "POST":
513
+ return await POST3(config, { request: request2 });
514
+ default:
515
+ return new Response("method not allowed", { status: 405 });
516
+ }
517
+ }
518
+ function matches4(configRoutes, request2) {
519
+ const url = new URL(request2.url);
520
+ const [, tenantId] = url.pathname.split("/").reverse();
521
+ const route20 = configRoutes[key4].replace("{tenantId}", tenantId);
522
+ return urlMatches(request2.url, route20);
523
+ }
524
+ async function fetchInvite(config, method, body) {
525
+ if (!config.tenantId) {
526
+ throw new Error(
527
+ "Unable to fetch the invite for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
528
+ );
529
+ }
530
+ if (!isUUID(config.tenantId)) {
531
+ config.logger("fetchInvite").warn(
532
+ "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
533
+ );
534
+ }
535
+ let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", config.tenantId)}`;
536
+ const m = method ?? "GET";
537
+ const init = {
538
+ method: m,
539
+ headers: config.headers
540
+ };
541
+ if (method === "POST" || method === "PUT") {
542
+ init.body = body;
543
+ }
544
+ if (method === "DELETE") {
545
+ clientUrl = `${clientUrl}/${body}`;
546
+ }
547
+ const req = new Request(clientUrl, init);
548
+ return await config.handlers[m](req);
549
+ }
550
+
551
+ // src/api/routes/tenants/[tenantId]/invites/GET.ts
552
+ async function GET4(config, init) {
553
+ const yurl = new URL(init.request.url);
554
+ const [, tenantId] = yurl.pathname.split("/").reverse();
555
+ if (!tenantId) {
556
+ return new Response(null, { status: 404 });
557
+ }
558
+ init.method = "GET";
559
+ const url = `${apiRoutes(config).INVITES(tenantId)}`;
560
+ return await request(url, init, config);
561
+ }
562
+
563
+ // src/api/routes/tenants/[tenantId]/invites/index.ts
564
+ var key5 = "INVITES";
565
+ async function route5(request2, config) {
566
+ switch (request2.method) {
567
+ case "GET":
568
+ return await GET4(config, { request: request2 });
569
+ default:
570
+ return new Response("method not allowed", { status: 405 });
571
+ }
572
+ }
573
+ function matches5(configRoutes, request2) {
574
+ const url = new URL(request2.url);
575
+ const [, tenantId] = url.pathname.split("/").reverse();
576
+ const route20 = configRoutes[key5].replace("{tenantId}", tenantId);
577
+ return url.pathname.endsWith(route20);
578
+ }
579
+ async function fetchInvites(config) {
580
+ if (!config.tenantId) {
581
+ throw new Error(
582
+ "Unable to fetch invites for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
583
+ );
584
+ }
585
+ if (!isUUID(config.tenantId)) {
586
+ config.logger("fetchInvites").warn(
587
+ "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
588
+ );
589
+ }
590
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}", config.tenantId)}`;
591
+ const req = new Request(clientUrl, { headers: config.headers });
592
+ return await config.handlers.GET(req);
593
+ }
594
+
550
595
  // src/api/routes/tenants/GET.ts
551
- async function GET4(config, session, init) {
596
+ async function GET5(config, session, init) {
552
597
  let url = `${apiRoutes(config).USER_TENANTS(session.id)}`;
553
598
  if (typeof session === "object" && "user" in session && session.user) {
554
599
  url = `${apiRoutes(config).USER_TENANTS(session.user.id)}`;
@@ -558,7 +603,7 @@ async function GET4(config, session, init) {
558
603
  }
559
604
 
560
605
  // src/api/routes/tenants/[tenantId]/GET.ts
561
- async function GET5(config, init, log) {
606
+ async function GET6(config, init, log) {
562
607
  const yurl = new URL(init.request.url);
563
608
  const [tenantId] = yurl.pathname.split("/").reverse();
564
609
  if (!tenantId) {
@@ -583,7 +628,7 @@ async function DELETE2(config, init) {
583
628
  }
584
629
 
585
630
  // src/api/routes/tenants/[tenantId]/PUT.ts
586
- async function PUT3(config, init) {
631
+ async function PUT4(config, init) {
587
632
  const yurl = new URL(init.request.url);
588
633
  const [tenantId] = yurl.pathname.split("/").reverse();
589
634
  if (!tenantId) {
@@ -596,7 +641,7 @@ async function PUT3(config, init) {
596
641
  }
597
642
 
598
643
  // src/api/routes/tenants/POST.ts
599
- async function POST3(config, init) {
644
+ async function POST4(config, init) {
600
645
  init.body = init.request.body;
601
646
  init.method = "POST";
602
647
  const url = `${apiRoutes(config).TENANTS}`;
@@ -604,12 +649,9 @@ async function POST3(config, init) {
604
649
  }
605
650
 
606
651
  // src/api/routes/tenants/index.ts
607
- var key4 = "TENANTS";
608
- async function route4(request2, config) {
609
- const { info } = Logger(
610
- { ...config, debug: config.debug },
611
- `[ROUTES][${key4}]`
612
- );
652
+ var key6 = "TENANTS";
653
+ async function route6(request2, config) {
654
+ const { info } = config.logger(`[ROUTES][${key6}]`);
613
655
  const session = await auth(request2, config);
614
656
  if (!session) {
615
657
  info("401");
@@ -619,24 +661,24 @@ async function route4(request2, config) {
619
661
  switch (request2.method) {
620
662
  case "GET":
621
663
  if (isUUID(possibleTenantId)) {
622
- return await GET5(config, { request: request2 }, info);
664
+ return await GET6(config, { request: request2 }, info);
623
665
  }
624
- return await GET4(config, session, { request: request2 });
666
+ return await GET5(config, session, { request: request2 });
625
667
  case "POST":
626
- return await POST3(config, { request: request2 });
668
+ return await POST4(config, { request: request2 });
627
669
  case "DELETE":
628
670
  return await DELETE2(config, { request: request2 });
629
671
  case "PUT":
630
- return await PUT3(config, { request: request2 });
672
+ return await PUT4(config, { request: request2 });
631
673
  default:
632
674
  return new Response("method not allowed", { status: 405 });
633
675
  }
634
676
  }
635
- function matches4(configRoutes, request2) {
636
- return urlMatches(request2.url, configRoutes[key4]);
677
+ function matches6(configRoutes, request2) {
678
+ return urlMatches(request2.url, configRoutes[key6]);
637
679
  }
638
680
  async function fetchTenants(config, method, body) {
639
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
681
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
640
682
  const init = {
641
683
  method,
642
684
  headers: config.headers
@@ -650,15 +692,15 @@ async function fetchTenants(config, method, body) {
650
692
  async function fetchTenant(config, method, body) {
651
693
  if (!config.tenantId) {
652
694
  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'
695
+ "Unable to fetch tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
654
696
  );
655
697
  }
656
- if (!isUUID(config.tenantId) && config.logger?.warn) {
657
- config.logger?.warn(
698
+ if (!isUUID(config.tenantId)) {
699
+ config.logger("fetch tenant").warn(
658
700
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
659
701
  );
660
702
  }
661
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", config.tenantId)}`;
703
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", config.tenantId)}`;
662
704
  const m = method ?? "GET";
663
705
  const init = {
664
706
  method: m,
@@ -671,36 +713,32 @@ async function fetchTenant(config, method, body) {
671
713
  return await config.handlers[m](req);
672
714
  }
673
715
  async function fetchTenantsByUser(config) {
674
- if (config.logger?.warn) {
675
- if (!config.userId) {
676
- config.logger?.warn(
677
- "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."
678
- );
679
- } else if (!isUUID(config.userId)) {
680
- config.logger?.warn(
681
- "nile.userId is not a valid UUID. This may lead to unexpected behavior in your application."
682
- );
683
- }
716
+ const { warn } = config.logger("fetchTenantsByUser");
717
+ if (!config.userId) {
718
+ warn(
719
+ "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."
720
+ );
721
+ } else if (!isUUID(config.userId)) {
722
+ warn(
723
+ "nile.userId is not a valid UUID. This may lead to unexpected behavior in your application."
724
+ );
684
725
  }
685
- const clientUrl = `${config.origin}${config.routePrefix}${"/users/{userId}/tenants" /* USER_TENANTS */.replace(
686
- "{userId}",
687
- config.userId ?? "WARN_NOT_SET"
688
- )}`;
726
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
689
727
  const req = new Request(clientUrl, { headers: config.headers });
690
728
  return await config.handlers.GET(req);
691
729
  }
692
730
 
693
731
  // src/api/routes/auth/signin.ts
694
- var key5 = "SIGNIN";
695
- async function route5(req, config) {
696
- let url = proxyRoutes(config)[key5];
732
+ var key7 = "SIGNIN";
733
+ async function route7(req, config) {
734
+ let url = proxyRoutes(config)[key7];
697
735
  const init = {
698
736
  method: req.method,
699
737
  headers: req.headers
700
738
  };
701
739
  if (req.method === "POST") {
702
740
  const [provider] = new URL(req.url).pathname.split("/").reverse();
703
- url = `${proxyRoutes(config)[key5]}/${provider}`;
741
+ url = `${proxyRoutes(config)[key7]}/${provider}`;
704
742
  }
705
743
  const passThroughUrl = new URL(req.url);
706
744
  const params = new URLSearchParams(passThroughUrl.search);
@@ -708,11 +746,11 @@ async function route5(req, config) {
708
746
  const res = await request(url, { ...init, request: req }, config);
709
747
  return res;
710
748
  }
711
- function matches5(configRoutes, request2) {
712
- return urlMatches(request2.url, configRoutes[key5]);
749
+ function matches7(configRoutes, request2) {
750
+ return urlMatches(request2.url, configRoutes[key7]);
713
751
  }
714
752
  async function fetchSignIn(config, provider, body) {
715
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
753
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
716
754
  const req = new Request(clientUrl, {
717
755
  method: "POST",
718
756
  headers: config.headers,
@@ -722,7 +760,7 @@ async function fetchSignIn(config, provider, body) {
722
760
  }
723
761
 
724
762
  // src/api/routes/auth/session.ts
725
- async function route6(req, config) {
763
+ async function route8(req, config) {
726
764
  return request(
727
765
  proxyRoutes(config).SESSION,
728
766
  {
@@ -732,11 +770,11 @@ async function route6(req, config) {
732
770
  config
733
771
  );
734
772
  }
735
- function matches6(configRoutes, request2) {
773
+ function matches8(configRoutes, request2) {
736
774
  return urlMatches(request2.url, configRoutes.SESSION);
737
775
  }
738
776
  async function fetchSession(config) {
739
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
777
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
740
778
  const req = new Request(clientUrl, {
741
779
  method: "GET",
742
780
  headers: config.headers
@@ -745,7 +783,7 @@ async function fetchSession(config) {
745
783
  }
746
784
 
747
785
  // src/api/routes/auth/providers.ts
748
- async function route7(req, config) {
786
+ async function route9(req, config) {
749
787
  return request(
750
788
  proxyRoutes(config).PROVIDERS,
751
789
  {
@@ -755,11 +793,11 @@ async function route7(req, config) {
755
793
  config
756
794
  );
757
795
  }
758
- function matches7(configRoutes, request2) {
796
+ function matches9(configRoutes, request2) {
759
797
  return urlMatches(request2.url, configRoutes.PROVIDERS);
760
798
  }
761
799
  async function fetchProviders(config) {
762
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
800
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
763
801
  const req = new Request(clientUrl, {
764
802
  method: "GET",
765
803
  headers: config.headers
@@ -768,7 +806,7 @@ async function fetchProviders(config) {
768
806
  }
769
807
 
770
808
  // src/api/routes/auth/csrf.ts
771
- async function route8(req, config) {
809
+ async function route10(req, config) {
772
810
  return request(
773
811
  proxyRoutes(config).CSRF,
774
812
  {
@@ -778,11 +816,11 @@ async function route8(req, config) {
778
816
  config
779
817
  );
780
818
  }
781
- function matches8(configRoutes, request2) {
819
+ function matches10(configRoutes, request2) {
782
820
  return urlMatches(request2.url, configRoutes.CSRF);
783
821
  }
784
822
  async function fetchCsrf(config) {
785
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
823
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
786
824
  const req = new Request(clientUrl, {
787
825
  method: "GET",
788
826
  headers: config.headers
@@ -791,17 +829,14 @@ async function fetchCsrf(config) {
791
829
  }
792
830
 
793
831
  // src/api/routes/auth/callback.ts
794
- var key6 = "CALLBACK";
795
- async function route9(req, config) {
796
- const { error } = Logger(
797
- { ...config, debug: config.debug },
798
- `[ROUTES][${key6}]`
799
- );
832
+ var key8 = "CALLBACK";
833
+ async function route11(req, config) {
834
+ const { error } = config.logger(`[ROUTES][${key8}]`);
800
835
  const [provider] = new URL(req.url).pathname.split("/").reverse();
801
836
  try {
802
837
  const passThroughUrl = new URL(req.url);
803
838
  const params = new URLSearchParams(passThroughUrl.search);
804
- const url = `${proxyRoutes(config)[key6]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
839
+ const url = `${proxyRoutes(config)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
805
840
  const res = await request(
806
841
  url,
807
842
  {
@@ -828,13 +863,13 @@ async function route9(req, config) {
828
863
  }
829
864
  return new Response("An unexpected error has occurred.", { status: 400 });
830
865
  }
831
- function matches9(configRoutes, request2) {
866
+ function matches11(configRoutes, request2) {
832
867
  return urlMatches(request2.url, configRoutes.CALLBACK);
833
868
  }
834
- async function fetchCallback(config, provider, body) {
835
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}`;
869
+ async function fetchCallback(config, provider, body, request2, method = "POST") {
870
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}${request2 ? `?${new URL(request2.url).searchParams}` : ""}`;
836
871
  const req = new Request(clientUrl, {
837
- method: "POST",
872
+ method,
838
873
  headers: config.headers,
839
874
  body
840
875
  });
@@ -842,25 +877,25 @@ async function fetchCallback(config, provider, body) {
842
877
  }
843
878
 
844
879
  // src/api/routes/auth/signout.ts
845
- var key7 = "SIGNOUT";
846
- async function route10(request2, config) {
847
- let url = proxyRoutes(config)[key7];
880
+ var key9 = "SIGNOUT";
881
+ async function route12(request2, config) {
882
+ let url = proxyRoutes(config)[key9];
848
883
  const init = {
849
884
  method: request2.method
850
885
  };
851
886
  if (request2.method === "POST") {
852
887
  init.body = request2.body;
853
888
  const [provider] = new URL(request2.url).pathname.split("/").reverse();
854
- url = `${proxyRoutes(config)[key7]}${provider !== "signout" ? `/${provider}` : ""}`;
889
+ url = `${proxyRoutes(config)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
855
890
  }
856
891
  const res = await request(url, { ...init, request: request2 }, config);
857
892
  return res;
858
893
  }
859
- function matches10(configRoutes, request2) {
860
- return urlMatches(request2.url, configRoutes[key7]);
894
+ function matches12(configRoutes, request2) {
895
+ return urlMatches(request2.url, configRoutes[key9]);
861
896
  }
862
897
  async function fetchSignOut(config, body) {
863
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
898
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
864
899
  const req = new Request(clientUrl, {
865
900
  method: "POST",
866
901
  body,
@@ -870,10 +905,10 @@ async function fetchSignOut(config, body) {
870
905
  }
871
906
 
872
907
  // src/api/routes/auth/error.ts
873
- var key8 = "ERROR";
874
- async function route11(req, config) {
908
+ var key10 = "ERROR";
909
+ async function route13(req, config) {
875
910
  return request(
876
- proxyRoutes(config)[key8],
911
+ proxyRoutes(config)[key10],
877
912
  {
878
913
  method: req.method,
879
914
  request: req
@@ -881,15 +916,15 @@ async function route11(req, config) {
881
916
  config
882
917
  );
883
918
  }
884
- function matches11(configRoutes, request2) {
885
- return urlMatches(request2.url, configRoutes[key8]);
919
+ function matches13(configRoutes, request2) {
920
+ return urlMatches(request2.url, configRoutes[key10]);
886
921
  }
887
922
 
888
923
  // src/api/routes/auth/verify-request.ts
889
- var key9 = "VERIFY_REQUEST";
890
- async function route12(req, config) {
924
+ var key11 = "VERIFY_REQUEST";
925
+ async function route14(req, config) {
891
926
  return request(
892
- proxyRoutes(config)[key9],
927
+ proxyRoutes(config)[key11],
893
928
  {
894
929
  method: req.method,
895
930
  request: req
@@ -897,14 +932,14 @@ async function route12(req, config) {
897
932
  config
898
933
  );
899
934
  }
900
- function matches12(configRoutes, request2) {
901
- return urlMatches(request2.url, configRoutes[key9]);
935
+ function matches14(configRoutes, request2) {
936
+ return urlMatches(request2.url, configRoutes[key11]);
902
937
  }
903
938
 
904
939
  // src/api/routes/auth/password-reset.ts
905
- var key10 = "PASSWORD_RESET";
906
- async function route13(req, config) {
907
- const url = proxyRoutes(config)[key10];
940
+ var key12 = "PASSWORD_RESET";
941
+ async function route15(req, config) {
942
+ const url = proxyRoutes(config)[key12];
908
943
  const res = await request(
909
944
  url,
910
945
  {
@@ -925,73 +960,203 @@ async function route13(req, config) {
925
960
  headers: res?.headers
926
961
  });
927
962
  }
928
- function matches13(configRoutes, request2) {
963
+ function matches15(configRoutes, request2) {
929
964
  return urlMatches(request2.url, configRoutes.PASSWORD_RESET);
930
965
  }
966
+ async function fetchResetPassword(config, method, body, params, useJson = true) {
967
+ const authParams = new URLSearchParams(params ?? {});
968
+ if (useJson) {
969
+ authParams?.set("json", "true");
970
+ }
971
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}?${authParams?.toString()}`;
972
+ const init = {
973
+ method,
974
+ headers: config.headers
975
+ };
976
+ if (body && method !== "GET") {
977
+ init.body = body;
978
+ }
979
+ const req = new Request(clientUrl, init);
980
+ return await config.handlers[method](req);
981
+ }
982
+
983
+ // src/api/routes/auth/verify-email.ts
984
+ var key13 = "VERIFY_EMAIL";
985
+ async function route16(req, config) {
986
+ const url = proxyRoutes(config)[key13];
987
+ const res = await request(
988
+ url,
989
+ {
990
+ method: req.method,
991
+ request: req
992
+ },
993
+ config
994
+ );
995
+ const location = res?.headers.get("location");
996
+ if (location) {
997
+ return new Response(res?.body, {
998
+ status: 302,
999
+ headers: res?.headers
1000
+ });
1001
+ }
1002
+ return new Response(res?.body, {
1003
+ status: res?.status,
1004
+ headers: res?.headers
1005
+ });
1006
+ }
1007
+ function matches16(configRoutes, request2) {
1008
+ return urlMatches(request2.url, configRoutes[key13]);
1009
+ }
1010
+ async function fetchVerifyEmail(config, method, body) {
1011
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`;
1012
+ const init = {
1013
+ method,
1014
+ headers: config.headers
1015
+ };
1016
+ if (body) {
1017
+ init.body = body;
1018
+ }
1019
+ const req = new Request(clientUrl, init);
1020
+ return await config.handlers[method](req);
1021
+ }
931
1022
 
932
1023
  // src/api/handlers/GET.ts
933
1024
  function GETTER(configRoutes, config) {
934
- const { info, warn } = Logger(config, "[GET MATCHER]");
935
- return async function GET6(req) {
1025
+ const { info, warn } = config.logger("[GET MATCHER]");
1026
+ return async function GET7(req) {
936
1027
  if (matches(configRoutes, req)) {
937
1028
  info("matches me");
938
1029
  return route(req, config);
939
1030
  }
1031
+ if (matches5(configRoutes, req)) {
1032
+ info("matches tenant invites");
1033
+ return route5(req, config);
1034
+ }
1035
+ if (matches4(configRoutes, req)) {
1036
+ info("matches invite");
1037
+ return route4(req, config);
1038
+ }
940
1039
  if (matches3(configRoutes, req)) {
941
1040
  info("matches tenant users");
942
1041
  return route3(req, config);
943
1042
  }
1043
+ if (matches6(configRoutes, req)) {
1044
+ info("matches tenants");
1045
+ return route6(req, config);
1046
+ }
944
1047
  if (matches2(configRoutes, req)) {
945
1048
  info("matches users");
946
1049
  return route2(req, config);
947
1050
  }
948
- if (matches4(configRoutes, req)) {
949
- info("matches tenants");
950
- return route4(req, config);
951
- }
952
- if (matches6(configRoutes, req)) {
1051
+ if (matches8(configRoutes, req)) {
953
1052
  info("matches session");
954
- return route6(req, config);
1053
+ return route8(req, config);
955
1054
  }
956
- if (matches5(configRoutes, req)) {
1055
+ if (matches7(configRoutes, req)) {
957
1056
  info("matches signin");
958
- return route5(req, config);
1057
+ return route7(req, config);
959
1058
  }
960
- if (matches7(configRoutes, req)) {
1059
+ if (matches9(configRoutes, req)) {
961
1060
  info("matches providers");
962
- return route7(req, config);
1061
+ return route9(req, config);
963
1062
  }
964
- if (matches8(configRoutes, req)) {
1063
+ if (matches10(configRoutes, req)) {
965
1064
  info("matches csrf");
966
- return route8(req, config);
1065
+ return route10(req, config);
967
1066
  }
968
- if (matches13(configRoutes, req)) {
1067
+ if (matches15(configRoutes, req)) {
969
1068
  info("matches password reset");
970
- return route13(req, config);
1069
+ return route15(req, config);
971
1070
  }
972
- if (matches9(configRoutes, req)) {
1071
+ if (matches11(configRoutes, req)) {
973
1072
  info("matches callback");
974
- return route9(req, config);
1073
+ return route11(req, config);
975
1074
  }
976
- if (matches10(configRoutes, req)) {
1075
+ if (matches12(configRoutes, req)) {
977
1076
  info("matches signout");
978
- return route10(req, config);
1077
+ return route12(req, config);
979
1078
  }
980
- if (matches12(configRoutes, req)) {
1079
+ if (matches14(configRoutes, req)) {
981
1080
  info("matches verify-request");
982
- return route12(req, config);
1081
+ return route14(req, config);
983
1082
  }
984
- if (matches11(configRoutes, req)) {
1083
+ if (matches16(configRoutes, req)) {
1084
+ info("matches verify-email");
1085
+ return route16(req, config);
1086
+ }
1087
+ if (matches13(configRoutes, req)) {
985
1088
  info("matches error");
986
- return route11(req, config);
1089
+ return route13(req, config);
987
1090
  }
988
1091
  warn(`No GET routes matched ${req.url}`);
989
1092
  return new Response(null, { status: 404 });
990
1093
  };
991
1094
  }
992
1095
 
1096
+ // src/utils/Logger.ts
1097
+ var red = "\x1B[31m";
1098
+ var yellow = "\x1B[38;2;255;255;0m";
1099
+ var purple = "\x1B[38;2;200;160;255m";
1100
+ var orange = "\x1B[38;2;255;165;0m";
1101
+ var reset = "\x1B[0m";
1102
+ var baseLogger = (config, ...params) => ({
1103
+ info(message, meta) {
1104
+ if (config?.debug) {
1105
+ console.info(
1106
+ `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
1107
+ ""
1108
+ )}${reset} ${message}`,
1109
+ meta ? `${JSON.stringify(meta)}` : ""
1110
+ );
1111
+ }
1112
+ },
1113
+ debug(message, meta) {
1114
+ if (config?.debug) {
1115
+ console.debug(
1116
+ `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
1117
+ ""
1118
+ )}${reset} ${message}`,
1119
+ meta ? `${JSON.stringify(meta)}` : ""
1120
+ );
1121
+ }
1122
+ },
1123
+ warn(message, meta) {
1124
+ if (config?.debug) {
1125
+ console.warn(
1126
+ `${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
1127
+ ""
1128
+ )}${reset} ${message}`,
1129
+ meta ? JSON.stringify(meta) : ""
1130
+ );
1131
+ }
1132
+ },
1133
+ error(message, meta) {
1134
+ console.error(
1135
+ `${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
1136
+ ""
1137
+ )}${red} ${message}`,
1138
+ meta ? meta : "",
1139
+ `${reset}`
1140
+ );
1141
+ }
1142
+ });
1143
+ function Logger(config) {
1144
+ return (prefixes) => {
1145
+ const { info, debug, warn, error } = config && typeof config?.logger === "function" ? config.logger(prefixes) : baseLogger(config, prefixes);
1146
+ return {
1147
+ info,
1148
+ debug,
1149
+ warn,
1150
+ error
1151
+ };
1152
+ };
1153
+ }
1154
+ function matchesLog(configRoutes, request2) {
1155
+ return urlMatches(request2.url, configRoutes.LOG);
1156
+ }
1157
+
993
1158
  // src/api/routes/signup/POST.ts
994
- async function POST4(config, init) {
1159
+ async function POST5(config, init) {
995
1160
  init.body = init.request.body;
996
1161
  init.method = "POST";
997
1162
  const url = `${apiRoutes(config).SIGNUP}`;
@@ -999,17 +1164,17 @@ async function POST4(config, init) {
999
1164
  }
1000
1165
 
1001
1166
  // src/api/routes/signup/index.tsx
1002
- var key11 = "SIGNUP";
1003
- async function route14(request2, config) {
1167
+ var key14 = "SIGNUP";
1168
+ async function route17(request2, config) {
1004
1169
  switch (request2.method) {
1005
1170
  case "POST":
1006
- return await POST4(config, { request: request2 });
1171
+ return await POST5(config, { request: request2 });
1007
1172
  default:
1008
1173
  return new Response("method not allowed", { status: 405 });
1009
1174
  }
1010
1175
  }
1011
- function matches14(configRoutes, request2) {
1012
- return urlMatches(request2.url, configRoutes[key11]);
1176
+ function matches17(configRoutes, request2) {
1177
+ return urlMatches(request2.url, configRoutes[key14]);
1013
1178
  }
1014
1179
  async function fetchSignUp(config, payload) {
1015
1180
  const { body, params } = payload ?? {};
@@ -1020,7 +1185,7 @@ async function fetchSignUp(config, payload) {
1020
1185
  if (params?.tenantId) {
1021
1186
  q.set("tenantId", params.tenantId);
1022
1187
  }
1023
- const clientUrl = `${config.origin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
1188
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
1024
1189
  const req = new Request(clientUrl, {
1025
1190
  method: "POST",
1026
1191
  headers: config.headers,
@@ -1031,63 +1196,68 @@ async function fetchSignUp(config, payload) {
1031
1196
 
1032
1197
  // src/api/handlers/POST.ts
1033
1198
  function POSTER(configRoutes, config) {
1034
- const { info, warn, error } = Logger(config, "[POST MATCHER]");
1035
- return async function POST5(req) {
1199
+ const { info, warn, error } = config.logger("[POST MATCHER]");
1200
+ return async function POST6(req) {
1036
1201
  if (matchesLog(configRoutes, req)) {
1037
- if (req.body) {
1038
- try {
1039
- const text = await req.text();
1040
- error(text);
1041
- return new Response(null, {
1042
- status: 200
1043
- });
1044
- } catch (e) {
1045
- }
1202
+ try {
1203
+ const json = await req.clone().json();
1204
+ error(req.body && json);
1205
+ } catch {
1206
+ error(await req.text());
1046
1207
  }
1208
+ return new Response(null, { status: 200 });
1047
1209
  }
1048
1210
  if (matches3(configRoutes, req)) {
1049
1211
  info("matches tenant users");
1050
1212
  return route3(req, config);
1051
1213
  }
1052
- if (matches14(configRoutes, req)) {
1214
+ if (matches4(configRoutes, req)) {
1215
+ info("matches tenant invite");
1216
+ return route4(req, config);
1217
+ }
1218
+ if (matches17(configRoutes, req)) {
1053
1219
  info("matches signup");
1054
- return route14(req, config);
1220
+ return route17(req, config);
1055
1221
  }
1056
1222
  if (matches2(configRoutes, req)) {
1057
1223
  info("matches users");
1058
1224
  return route2(req, config);
1059
1225
  }
1060
- if (matches4(configRoutes, req)) {
1226
+ if (matches6(configRoutes, req)) {
1061
1227
  info("matches tenants");
1062
- return route4(req, config);
1228
+ return route6(req, config);
1063
1229
  }
1064
- if (matches6(configRoutes, req)) {
1230
+ if (matches8(configRoutes, req)) {
1065
1231
  info("matches session");
1066
- return route6(req, config);
1232
+ return route8(req, config);
1067
1233
  }
1068
- if (matches5(configRoutes, req)) {
1234
+ if (matches7(configRoutes, req)) {
1069
1235
  info("matches signin");
1070
- return route5(req, config);
1236
+ return route7(req, config);
1071
1237
  }
1072
- if (matches13(configRoutes, req)) {
1238
+ if (matches15(configRoutes, req)) {
1073
1239
  info("matches password reset");
1074
- return route13(req, config);
1240
+ return route15(req, config);
1075
1241
  }
1076
- if (matches7(configRoutes, req)) {
1242
+ if (matches9(configRoutes, req)) {
1077
1243
  info("matches providers");
1078
- return route7(req, config);
1244
+ return route9(req, config);
1079
1245
  }
1080
- if (matches8(configRoutes, req)) {
1246
+ if (matches10(configRoutes, req)) {
1081
1247
  info("matches csrf");
1082
- return route8(req, config);
1248
+ return route10(req, config);
1083
1249
  }
1084
- if (matches9(configRoutes, req)) {
1250
+ if (matches11(configRoutes, req)) {
1085
1251
  info("matches callback");
1086
- return route9(req, config);
1252
+ return route11(req, config);
1087
1253
  }
1088
- if (matches10(configRoutes, req)) {
1254
+ if (matches12(configRoutes, req)) {
1089
1255
  info("matches signout");
1090
- return route10(req, config);
1256
+ return route12(req, config);
1257
+ }
1258
+ if (matches16(configRoutes, req)) {
1259
+ info("matches verify-email");
1260
+ return route16(req, config);
1091
1261
  }
1092
1262
  warn(`No POST routes matched ${req.url}`);
1093
1263
  return new Response(null, { status: 404 });
@@ -1106,7 +1276,7 @@ async function DELETE3(config, init) {
1106
1276
  }
1107
1277
 
1108
1278
  // src/api/routes/tenants/[tenantId]/users/[userId]/PUT.ts
1109
- async function PUT4(config, init) {
1279
+ async function PUT5(config, init) {
1110
1280
  const yurl = new URL(init.request.url);
1111
1281
  const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
1112
1282
  config.tenantId = tenantId;
@@ -1117,12 +1287,9 @@ async function PUT4(config, init) {
1117
1287
  }
1118
1288
 
1119
1289
  // src/api/routes/tenants/[tenantId]/users/[userId]/index.ts
1120
- var key12 = "TENANT_USER";
1121
- async function route15(request2, config) {
1122
- const { info } = Logger(
1123
- { ...config, debug: config.debug },
1124
- `[ROUTES][${key12}]`
1125
- );
1290
+ var key15 = "TENANT_USER";
1291
+ async function route18(request2, config) {
1292
+ const { info } = config.logger(`[ROUTES][${key15}]`);
1126
1293
  const session = await auth(request2, config);
1127
1294
  if (!session) {
1128
1295
  info("401");
@@ -1136,21 +1303,21 @@ async function route15(request2, config) {
1136
1303
  }
1137
1304
  switch (request2.method) {
1138
1305
  case "PUT":
1139
- return await PUT4(config, { request: request2 });
1306
+ return await PUT5(config, { request: request2 });
1140
1307
  case "DELETE":
1141
1308
  return await DELETE3(config, { request: request2 });
1142
1309
  default:
1143
1310
  return new Response("method not allowed", { status: 405 });
1144
1311
  }
1145
1312
  }
1146
- function matches15(configRoutes, request2) {
1313
+ function matches18(configRoutes, request2) {
1147
1314
  const url = new URL(request2.url);
1148
1315
  const [, userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
1149
- let route16 = configRoutes[key12].replace("{tenantId}", tenantId).replace("{userId}", userId);
1316
+ let route20 = configRoutes[key15].replace("{tenantId}", tenantId).replace("{userId}", userId);
1150
1317
  if (userId === "users") {
1151
- route16 = configRoutes[key12].replace("{tenantId}", possibleTenantId);
1318
+ route20 = configRoutes[key15].replace("{tenantId}", possibleTenantId);
1152
1319
  }
1153
- return urlMatches(request2.url, route16);
1320
+ return urlMatches(request2.url, route20);
1154
1321
  }
1155
1322
  async function fetchTenantUser(config, method) {
1156
1323
  if (!config.tenantId) {
@@ -1163,7 +1330,7 @@ async function fetchTenantUser(config, method) {
1163
1330
  "the userId context is missing. Call nile.setContext({ userId })"
1164
1331
  );
1165
1332
  }
1166
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
1333
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
1167
1334
  "{tenantId}",
1168
1335
  config.tenantId
1169
1336
  ).replace("{userId}", config.userId)}/link`;
@@ -1174,21 +1341,54 @@ async function fetchTenantUser(config, method) {
1174
1341
  return await config.handlers[method](req);
1175
1342
  }
1176
1343
 
1344
+ // src/api/routes/tenants/[tenantId]/invite/[inviteId]/DELETE.ts
1345
+ async function DELETE4(config, init) {
1346
+ const yurl = new URL(init.request.url);
1347
+ const [inviteId, , tenantId] = yurl.pathname.split("/").reverse();
1348
+ if (!tenantId) {
1349
+ return new Response(null, { status: 404 });
1350
+ }
1351
+ init.method = "DELETE";
1352
+ const url = `${apiRoutes(config).INVITE(tenantId)}/${inviteId}`;
1353
+ return await request(url, init, config);
1354
+ }
1355
+
1356
+ // src/api/routes/tenants/[tenantId]/invite/[inviteId]/index.ts
1357
+ var key16 = "INVITE";
1358
+ async function route19(request2, config) {
1359
+ switch (request2.method) {
1360
+ case "DELETE":
1361
+ return await DELETE4(config, { request: request2 });
1362
+ default:
1363
+ return new Response("method not allowed", { status: 405 });
1364
+ }
1365
+ }
1366
+ function matches19(configRoutes, request2) {
1367
+ const url = new URL(request2.url);
1368
+ const [inviteId, , tenantId] = url.pathname.split("/").reverse();
1369
+ const route20 = configRoutes[key16].replace("{tenantId}", tenantId).replace("{inviteId}", inviteId);
1370
+ return urlMatches(request2.url, route20);
1371
+ }
1372
+
1177
1373
  // src/api/handlers/DELETE.ts
1178
1374
  function DELETER(configRoutes, config) {
1179
- const { info, warn } = Logger(config, "[DELETE MATCHER]");
1180
- return async function DELETE4(req) {
1181
- if (matches15(configRoutes, req)) {
1375
+ const { info, warn } = config.logger("[DELETE MATCHER]");
1376
+ return async function DELETE5(req) {
1377
+ if (matches19(configRoutes, req)) {
1378
+ info("matches tenant invite id");
1379
+ return route19(req, config);
1380
+ }
1381
+ if (matches18(configRoutes, req)) {
1182
1382
  info("matches tenant user");
1183
- return route15(req, config);
1383
+ return route18(req, config);
1184
1384
  }
1185
1385
  if (matches3(configRoutes, req)) {
1186
1386
  info("matches tenant users");
1187
1387
  return route3(req, config);
1188
1388
  }
1189
- if (matches4(configRoutes, req)) {
1389
+ if (matches6(configRoutes, req)) {
1190
1390
  info("matches tenants");
1191
- return route4(req, config);
1391
+ return route6(req, config);
1192
1392
  }
1193
1393
  if (matches(configRoutes, req)) {
1194
1394
  info("matches me");
@@ -1201,11 +1401,15 @@ function DELETER(configRoutes, config) {
1201
1401
 
1202
1402
  // src/api/handlers/PUT.ts
1203
1403
  function PUTER(configRoutes, config) {
1204
- const { info, warn } = Logger(config, "[PUT MATCHER]");
1205
- return async function PUT5(req) {
1206
- if (matches15(configRoutes, req)) {
1404
+ const { info, warn } = config.logger("[PUT MATCHER]");
1405
+ return async function PUT6(req) {
1406
+ if (matches4(configRoutes, req)) {
1407
+ info("matches tenant invite");
1408
+ return route4(req, config);
1409
+ }
1410
+ if (matches18(configRoutes, req)) {
1207
1411
  info("matches tenant user");
1208
- return route15(req, config);
1412
+ return route18(req, config);
1209
1413
  }
1210
1414
  if (matches3(configRoutes, req)) {
1211
1415
  info("matches tenant users");
@@ -1219,13 +1423,13 @@ function PUTER(configRoutes, config) {
1219
1423
  info("matches me");
1220
1424
  return route(req, config);
1221
1425
  }
1222
- if (matches4(configRoutes, req)) {
1426
+ if (matches6(configRoutes, req)) {
1223
1427
  info("matches tenants");
1224
- return route4(req, config);
1428
+ return route6(req, config);
1225
1429
  }
1226
- if (matches13(configRoutes, req)) {
1430
+ if (matches15(configRoutes, req)) {
1227
1431
  info("matches reset password");
1228
- return route13(req, config);
1432
+ return route15(req, config);
1229
1433
  }
1230
1434
  warn("No PUT routes matched");
1231
1435
  return new Response(null, { status: 404 });
@@ -1234,15 +1438,15 @@ function PUTER(configRoutes, config) {
1234
1438
 
1235
1439
  // src/api/handlers/index.ts
1236
1440
  function Handlers(configRoutes, config) {
1237
- const GET6 = GETTER(configRoutes, config);
1238
- const POST5 = POSTER(configRoutes, config);
1239
- const DELETE4 = DELETER(configRoutes, config);
1240
- const PUT5 = PUTER(configRoutes, config);
1441
+ const GET7 = GETTER(configRoutes, config);
1442
+ const POST6 = POSTER(configRoutes, config);
1443
+ const DELETE5 = DELETER(configRoutes, config);
1444
+ const PUT6 = PUTER(configRoutes, config);
1241
1445
  return {
1242
- GET: GET6,
1243
- POST: POST5,
1244
- DELETE: DELETE4,
1245
- PUT: PUT5
1446
+ GET: GET7,
1447
+ POST: POST6,
1448
+ DELETE: DELETE5,
1449
+ PUT: PUT6
1246
1450
  };
1247
1451
  }
1248
1452
  var getApiUrl = (cfg) => {
@@ -1275,15 +1479,16 @@ var getSecureCookies = (cfg) => {
1275
1479
  return void 0;
1276
1480
  };
1277
1481
  var getUsername = (cfg) => {
1278
- const { config, logger } = cfg;
1279
- const { info } = Logger(config, "[username]");
1482
+ const { config } = cfg;
1483
+ const logger = config.logger;
1484
+ const { info } = logger();
1280
1485
  if (config?.user) {
1281
- logger && info(`${logger}[config] ${config.user}`);
1486
+ info(`[config] ${config.user}`);
1282
1487
  return String(config?.user);
1283
1488
  }
1284
1489
  const user = stringCheck(process.env.NILEDB_USER);
1285
1490
  if (user) {
1286
- logger && info(`${logger}[NILEDB_USER] ${user}`);
1491
+ info(`[NILEDB_USER] ${user}`);
1287
1492
  return user;
1288
1493
  }
1289
1494
  const pg2 = stringCheck(process.env.NILEDB_POSTGRES_URL);
@@ -1301,16 +1506,16 @@ var getUsername = (cfg) => {
1301
1506
  );
1302
1507
  };
1303
1508
  var getPassword = (cfg) => {
1304
- const { config, logger } = cfg;
1509
+ const { config } = cfg;
1510
+ const logger = config.logger;
1305
1511
  const log = logProtector(logger);
1306
- const { info } = Logger(config, "[password]");
1307
1512
  if (stringCheck(config?.password)) {
1308
- log && info(`${logger}[config] ***`);
1513
+ log && log("[config]").info("***");
1309
1514
  return String(config?.password);
1310
1515
  }
1311
1516
  const pass = stringCheck(process.env.NILEDB_PASSWORD);
1312
1517
  if (pass) {
1313
- logger && info(`${logger}[NILEDB_PASSWORD] ***`);
1518
+ logger("[NILEDB_PASSWORD]").info("***");
1314
1519
  return pass;
1315
1520
  }
1316
1521
  const pg2 = stringCheck(process.env.NILEDB_POSTGRES_URL);
@@ -1328,15 +1533,15 @@ var getPassword = (cfg) => {
1328
1533
  );
1329
1534
  };
1330
1535
  var getDatabaseName = (cfg) => {
1331
- const { config, logger } = cfg;
1332
- const { info } = Logger(config, "[databaseName]");
1536
+ const { config } = cfg;
1537
+ const { info } = config.logger("[databaseName]");
1333
1538
  if (stringCheck(config?.databaseName)) {
1334
- logger && info(`${logger}[config] ${config?.databaseName}`);
1539
+ info(`[config] ${config?.databaseName}`);
1335
1540
  return String(config?.databaseName);
1336
1541
  }
1337
1542
  const name = stringCheck(process.env.NILEDB_NAME);
1338
1543
  if (name) {
1339
- logger && info(`${logger}[NILEDB_NAME] ${name}`);
1544
+ info(`[NILEDB_NAME] ${name}`);
1340
1545
  return name;
1341
1546
  }
1342
1547
  if (process.env.NILEDB_POSTGRES_URL) {
@@ -1351,50 +1556,52 @@ var getDatabaseName = (cfg) => {
1351
1556
  );
1352
1557
  };
1353
1558
  var getTenantId = (cfg) => {
1354
- const { config, logger } = cfg;
1355
- const { info } = Logger(config, "[tenantId]");
1559
+ const { config } = cfg;
1560
+ const { info } = config.logger("[tenantId]");
1356
1561
  if (stringCheck(config?.tenantId)) {
1357
- logger && info(`${logger}[config] ${config?.tenantId}`);
1562
+ info(`[config] ${config?.tenantId}`);
1358
1563
  return String(config?.tenantId);
1359
1564
  }
1360
1565
  if (stringCheck(process.env.NILEDB_TENANT)) {
1361
- logger && info(`${logger}[NILEDB_TENANT] ${process.env.NILEDB_TENANT}`);
1566
+ info(`[NILEDB_TENANT] ${process.env.NILEDB_TENANT}`);
1362
1567
  return String(process.env.NILEDB_TENANT);
1363
1568
  }
1364
1569
  return null;
1365
1570
  };
1366
1571
  function getDbHost(cfg) {
1367
- const { config, logger } = cfg;
1368
- const { info } = Logger(config, "[db.host]");
1572
+ const { config } = cfg;
1573
+ const logger = config.logger;
1574
+ const { info } = logger("[db.host]");
1369
1575
  if (stringCheck(config?.db && config.db.host)) {
1370
- logger && info(`${logger}[config] ${config?.db?.host}`);
1576
+ info(`[config] ${config?.db?.host}`);
1371
1577
  return String(config?.db?.host);
1372
1578
  }
1373
1579
  if (stringCheck(process.env.NILEDB_HOST)) {
1374
- logger && info(`${logger}[NILEDB_HOST] ${process.env.NILEDB_HOST}`);
1580
+ info(`[NILEDB_HOST] ${process.env.NILEDB_HOST}`);
1375
1581
  return process.env.NILEDB_HOST;
1376
1582
  }
1377
1583
  const pg2 = stringCheck(process.env.NILEDB_POSTGRES_URL);
1378
1584
  if (pg2) {
1379
1585
  try {
1380
1586
  const pgUrl = new URL(pg2);
1381
- logger && info(`${logger}[NILEDB_POSTGRES_URL] ${pgUrl.hostname}`);
1587
+ info(`[NILEDB_POSTGRES_URL] ${pgUrl.hostname}`);
1382
1588
  return pgUrl.hostname;
1383
1589
  } catch (e) {
1384
1590
  }
1385
1591
  }
1386
- logger && info(`${logger}[default] db.thenile.dev`);
1592
+ info("[default] db.thenile.dev");
1387
1593
  return "db.thenile.dev";
1388
1594
  }
1389
1595
  function getDbPort(cfg) {
1390
- const { config, logger } = cfg;
1391
- const { info } = Logger(config, "[db.port]");
1596
+ const { config } = cfg;
1597
+ const logger = config.logger;
1598
+ const { info } = logger("[db.port]");
1392
1599
  if (config?.db?.port && config.db.port != null) {
1393
- logger && info(`${logger}[config] ${config?.db.port}`);
1600
+ info(`[config] ${config?.db.port}`);
1394
1601
  return Number(config.db?.port);
1395
1602
  }
1396
1603
  if (stringCheck(process.env.NILEDB_PORT)) {
1397
- logger && info(`${logger}[NILEDB_PORT] ${process.env.NILEDB_PORT}`);
1604
+ info(`[NILEDB_PORT] ${process.env.NILEDB_PORT}`);
1398
1605
  return Number(process.env.NILEDB_PORT);
1399
1606
  }
1400
1607
  const pg2 = stringCheck(process.env.NILEDB_POSTGRES_URL);
@@ -1407,7 +1614,7 @@ function getDbPort(cfg) {
1407
1614
  } catch (e) {
1408
1615
  }
1409
1616
  }
1410
- logger && info(`${logger}[default] 5432`);
1617
+ info("[default] 5432");
1411
1618
  return 5432;
1412
1619
  }
1413
1620
  var logProtector = (logger) => {
@@ -1423,9 +1630,10 @@ var stringCheck = (str) => {
1423
1630
  // src/utils/Config/index.ts
1424
1631
  var Config = class {
1425
1632
  routes;
1426
- // handlersWithContext;
1427
1633
  handlers;
1428
1634
  paths;
1635
+ extensionCtx;
1636
+ extensions;
1429
1637
  logger;
1430
1638
  /**
1431
1639
  * Stores the set tenant id from Server for use in sub classes
@@ -1444,6 +1652,10 @@ var Config = class {
1444
1652
  */
1445
1653
  apiUrl;
1446
1654
  origin;
1655
+ /**
1656
+ * important for separating the `origin` config value from a default in order to make requests
1657
+ */
1658
+ serverOrigin;
1447
1659
  debug;
1448
1660
  /**
1449
1661
  * To use secure cookies or not in the fetch
@@ -1455,14 +1667,19 @@ var Config = class {
1455
1667
  */
1456
1668
  routePrefix;
1457
1669
  db;
1458
- // api: ApiConfig;
1459
- constructor(config, logger) {
1460
- const envVarConfig = { config, logger };
1670
+ constructor(config) {
1461
1671
  this.routePrefix = config?.routePrefix ?? "/api";
1672
+ this.debug = config?.debug;
1673
+ this.origin = config?.origin;
1674
+ this.extensions = config?.extensions;
1675
+ this.extensionCtx = config?.extensionCtx;
1676
+ this.serverOrigin = config?.origin ?? "http://localhost:3000";
1677
+ this.logger = Logger(config);
1678
+ const envVarConfig = {
1679
+ config: { ...config, logger: this.logger }
1680
+ };
1462
1681
  this.secureCookies = getSecureCookies(envVarConfig);
1463
1682
  this.callbackUrl = getCallbackUrl(envVarConfig);
1464
- this.debug = config?.debug;
1465
- this.origin = config?.origin ?? "http://localhost:3000";
1466
1683
  this.apiUrl = getApiUrl(envVarConfig);
1467
1684
  const user = getUsername(envVarConfig);
1468
1685
  const password = getPassword(envVarConfig);
@@ -1529,13 +1746,56 @@ var Config = class {
1529
1746
  };
1530
1747
  this.tenantId = config?.tenantId;
1531
1748
  this.userId = config?.userId;
1532
- this.logger = config?.logger;
1533
1749
  }
1534
1750
  };
1535
1751
 
1752
+ // src/utils/Event/index.ts
1753
+ var Eventer = class {
1754
+ events = {};
1755
+ publish(eventName, value) {
1756
+ const callbacks = this.events[eventName];
1757
+ if (callbacks) {
1758
+ for (const callback of callbacks) {
1759
+ callback(value);
1760
+ }
1761
+ }
1762
+ }
1763
+ subscribe(eventName, callback) {
1764
+ if (!this.events[eventName]) {
1765
+ this.events[eventName] = [];
1766
+ }
1767
+ this.events[eventName].push(callback);
1768
+ }
1769
+ unsubscribe(eventName, callback) {
1770
+ const callbacks = this.events[eventName];
1771
+ if (!callbacks) return;
1772
+ const index = callbacks.indexOf(callback);
1773
+ if (index !== -1) {
1774
+ callbacks.splice(index, 1);
1775
+ }
1776
+ if (callbacks.length === 0) {
1777
+ delete this.events[eventName];
1778
+ }
1779
+ }
1780
+ };
1781
+ var eventer = new Eventer();
1782
+ var updateTenantId = (tenantId) => {
1783
+ eventer.publish("tenantId" /* Tenant */, tenantId);
1784
+ };
1785
+ var watchTenantId = (cb) => eventer.subscribe("tenantId" /* Tenant */, cb);
1786
+ var watchUserId = (cb) => eventer.subscribe("userId" /* User */, cb);
1787
+ var evictPool = (val) => {
1788
+ eventer.publish("EvictPool" /* EvictPool */, val);
1789
+ };
1790
+ var watchEvictPool = (cb) => eventer.subscribe("EvictPool" /* EvictPool */, cb);
1791
+ var updateHeaders = (val) => {
1792
+ eventer.publish("headers" /* Headers */, val);
1793
+ };
1794
+ var watchHeaders = (cb) => eventer.subscribe("headers" /* Headers */, cb);
1795
+
1536
1796
  // src/db/PoolProxy.ts
1537
1797
  function createProxyForPool(pool, config) {
1538
- const { info, error } = Logger(config, "[pool]");
1798
+ const { info, error } = config.logger("[pool]");
1539
1799
  return new Proxy(pool, {
1540
1800
  get(target, property) {
1541
1801
  if (property === "query") {
@@ -1571,7 +1831,7 @@ var NileDatabase = class {
1571
1831
  config;
1572
1832
  timer;
1573
1833
  constructor(config, id) {
1574
- const { warn, info, debug } = Logger(config, "[NileInstance]");
1834
+ const { warn, info, debug } = config.logger("[NileInstance]");
1575
1835
  this.id = id;
1576
1836
  const poolConfig = {
1577
1837
  min: 0,
@@ -1600,7 +1860,7 @@ var NileDatabase = class {
1600
1860
  `${this.id}-${this.timer}`
1601
1861
  );
1602
1862
  afterCreate2(client, (err) => {
1603
- const { error } = Logger(config, "[after create callback]");
1863
+ const { error } = config.logger("[after create callback]");
1604
1864
  if (err) {
1605
1865
  clearTimeout(this.timer);
1606
1866
  error("after create failed", {
@@ -1628,7 +1888,7 @@ var NileDatabase = class {
1628
1888
  });
1629
1889
  }
1630
1890
  startTimeout() {
1631
- const { debug } = Logger(this.config, "[NileInstance]");
1891
+ const { debug } = this.config.logger("[NileInstance]");
1632
1892
  if (this.timer) {
1633
1893
  clearTimeout(this.timer);
1634
1894
  }
@@ -1643,7 +1903,7 @@ var NileDatabase = class {
1643
1903
  }, Number(this.config.db.idleTimeoutMillis) ?? 3e4);
1644
1904
  }
1645
1905
  shutdown() {
1646
- const { debug } = Logger(this.config, "[NileInstance]");
1906
+ const { debug } = this.config.logger("[NileInstance]");
1647
1907
  debug(`attempting to shut down ${this.id}`);
1648
1908
  clearTimeout(this.timer);
1649
1909
  this.pool.end(() => {
@@ -1653,7 +1913,7 @@ var NileDatabase = class {
1653
1913
  };
1654
1914
  var NileInstance_default = NileDatabase;
1655
1915
  function makeAfterCreate(config, id) {
1656
- const { error, warn, debug } = Logger(config, "[afterCreate]");
1916
+ const { error, warn, debug } = config.logger("[afterCreate]");
1657
1917
  return (conn, done) => {
1658
1918
  conn.on("error", function errorHandler(e) {
1659
1919
  error(`Connection ${id} was terminated by server`, {
@@ -1717,7 +1977,7 @@ var DBManager = class {
1717
1977
  watchEvictPool(this.poolWatcherFn);
1718
1978
  }
1719
1979
  poolWatcher = (config) => (id) => {
1720
- const { info, warn } = Logger(config, "[DBManager]");
1980
+ const { info, warn } = Logger(config)("[DBManager]");
1721
1981
  if (id && this.connections.has(id)) {
1722
1982
  info(`Removing ${id} from db connection pool.`);
1723
1983
  const connection = this.connections.get(id);
@@ -1728,7 +1988,7 @@ var DBManager = class {
1728
1988
  }
1729
1989
  };
1730
1990
  getConnection = (config) => {
1731
- const { info } = Logger(config, "[DBManager]");
1991
+ const { info } = Logger(config)("[DBManager]");
1732
1992
  const id = this.makeId(config.tenantId, config.userId);
1733
1993
  const existing = this.connections.get(id);
1734
1994
  info(`# of instances: ${this.connections.size}`);
@@ -1747,7 +2007,7 @@ var DBManager = class {
1747
2007
  return newOne.pool;
1748
2008
  };
1749
2009
  clear = (config) => {
1750
- const { info } = Logger(config, "[DBManager]");
2010
+ const { info } = Logger(config)("[DBManager]");
1751
2011
  info(`Clearing all connections ${this.connections.size}`);
1752
2012
  this.cleared = true;
1753
2013
  this.connections.forEach((connection) => {
@@ -1757,195 +2017,13 @@ var DBManager = class {
1757
2017
  };
1758
2018
  };
1759
2019
 
1760
- // src/users/index.ts
1761
- var Users = class {
1762
- #config;
1763
- constructor(config) {
1764
- this.#config = config;
1765
- }
1766
- async updateSelf(req, rawResponse) {
1767
- const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
1768
- if (rawResponse) {
1769
- return res;
1770
- }
1771
- try {
1772
- return await res?.clone().json();
1773
- } catch {
1774
- return res;
1775
- }
1776
- }
1777
- async removeSelf() {
1778
- const me = await this.getSelf();
1779
- if ("id" in me) {
1780
- this.#config.userId = me.id;
1781
- }
1782
- const res = await fetchMe(this.#config, "DELETE");
1783
- updateHeaders(new Headers());
1784
- return res;
1785
- }
1786
- async getSelf(rawResponse) {
1787
- const res = await fetchMe(this.#config);
1788
- if (rawResponse) {
1789
- return res;
1790
- }
1791
- try {
1792
- return await res?.clone().json();
1793
- } catch {
1794
- return res;
1795
- }
1796
- }
1797
- };
1798
-
1799
- // src/tenants/index.ts
1800
- var Tenants = class {
1801
- #logger;
1802
- #config;
1803
- constructor(config) {
1804
- this.#logger = Logger(config, "[tenants]");
1805
- this.#config = config;
1806
- }
1807
- async create(req, rawResponse) {
1808
- let res;
1809
- if (typeof req === "string") {
1810
- res = await fetchTenants(
1811
- this.#config,
1812
- "POST",
1813
- JSON.stringify({ name: req })
1814
- );
1815
- } else if (typeof req === "object" && ("name" in req || "id" in req)) {
1816
- res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
1817
- }
1818
- if (rawResponse) {
1819
- return res;
1820
- }
1821
- try {
1822
- return await res?.clone().json();
1823
- } catch {
1824
- return res;
1825
- }
1826
- }
1827
- async delete(req) {
1828
- if (typeof req === "string") {
1829
- this.#config.tenantId = req;
1830
- }
1831
- if (typeof req === "object" && "id" in req) {
1832
- this.#config.tenantId = req.id;
1833
- }
1834
- const res = await fetchTenant(this.#config, "DELETE");
1835
- return res;
1836
- }
1837
- async get(req, rawResponse) {
1838
- if (typeof req === "string") {
1839
- this.#config.tenantId = req;
1840
- } else if (typeof req === "object" && "id" in req) {
1841
- this.#config.tenantId = req.id;
1842
- }
1843
- const res = await fetchTenant(this.#config, "GET");
1844
- if (rawResponse === true || req === true) {
1845
- return res;
1846
- }
1847
- try {
1848
- return await res?.clone().json();
1849
- } catch {
1850
- return res;
1851
- }
1852
- }
1853
- async update(req, rawResponse) {
1854
- let res;
1855
- if (typeof req === "object" && ("name" in req || "id" in req)) {
1856
- const { id, ...remaining } = req;
1857
- if (id) {
1858
- this.#config.tenantId = id;
1859
- }
1860
- res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
1861
- }
1862
- if (rawResponse) {
1863
- return res;
1864
- }
1865
- try {
1866
- return await res?.clone().json();
1867
- } catch {
1868
- return res;
1869
- }
1870
- }
1871
- async list(req) {
1872
- const res = await fetchTenantsByUser(this.#config);
1873
- if (req === true) {
1874
- return res;
1875
- }
1876
- try {
1877
- return await res?.clone().json();
1878
- } catch {
1879
- return res;
1880
- }
1881
- }
1882
- async leaveTenant(req) {
1883
- const me = await fetchMe(this.#config);
1884
- try {
1885
- const json = await me.json();
1886
- if ("id" in json) {
1887
- this.#config.userId = json.id;
1888
- }
1889
- } catch {
1890
- }
1891
- if (typeof req === "string") {
1892
- this.#config.tenantId = req;
1893
- } else {
1894
- this.#handleContext(req);
1895
- }
1896
- return await fetchTenantUser(this.#config, "DELETE");
1897
- }
1898
- async addMember(req, rawResponse) {
1899
- if (typeof req === "string") {
1900
- this.#config.userId = req;
1901
- } else {
1902
- this.#handleContext(req);
1903
- }
1904
- const res = await fetchTenantUser(this.#config, "PUT");
1905
- return responseHandler(res, rawResponse);
1906
- }
1907
- async removeMember(req, rawResponse) {
1908
- this.#handleContext(req);
1909
- const res = await fetchTenantUser(this.#config, "DELETE");
1910
- return responseHandler(res, rawResponse);
1911
- }
1912
- async users(req, rawResponse) {
1913
- this.#handleContext(req);
1914
- const res = await fetchTenantUsers(this.#config, "GET");
1915
- return responseHandler(
1916
- res,
1917
- rawResponse || typeof req === "boolean" && req
1918
- );
1919
- }
1920
- #handleContext(req) {
1921
- if (typeof req === "object") {
1922
- if ("tenantId" in req) {
1923
- this.#config.tenantId = req.tenantId;
1924
- }
1925
- if ("userId" in req) {
1926
- this.#config.tenantId = req.tenantId;
1927
- }
1928
- }
1929
- }
1930
- };
1931
- async function responseHandler(res, rawResponse) {
1932
- if (rawResponse) {
1933
- return res;
1934
- }
1935
- try {
1936
- return await res?.clone().json();
1937
- } catch {
1938
- return res;
1939
- }
1940
- }
1941
-
1942
2020
  // src/auth/index.ts
1943
2021
  var Auth = class {
1944
2022
  #logger;
1945
2023
  #config;
1946
2024
  constructor(config) {
1947
2025
  this.#config = config;
1948
- this.#logger = Logger(config, "[auth]");
2026
+ this.#logger = config.logger("[auth]");
1949
2027
  }
1950
2028
  async getSession(rawResponse = false) {
1951
2029
  const res = await fetchSession(this.#config);
@@ -1963,46 +2041,7 @@ var Auth = class {
1963
2041
  }
1964
2042
  }
1965
2043
  async getCsrf(rawResponse = false) {
1966
- const res = await fetchCsrf(this.#config);
1967
- const csrfCook = parseCSRF(res.headers);
1968
- if (csrfCook) {
1969
- const [, value] = csrfCook.split("=");
1970
- const [token] = decodeURIComponent(value).split("|");
1971
- const setCookie = res.headers.get("set-cookie");
1972
- if (setCookie) {
1973
- const cookie = [
1974
- csrfCook,
1975
- parseCallback(res.headers),
1976
- parseToken(res.headers)
1977
- ].filter(Boolean).join("; ");
1978
- this.#config.headers.set("cookie", cookie);
1979
- updateHeaders(new Headers({ cookie }));
1980
- }
1981
- if (!rawResponse) {
1982
- return { csrfToken: token };
1983
- }
1984
- } else {
1985
- const existingCookie = this.#config.headers.get("cookie");
1986
- const cookieParts = [];
1987
- if (existingCookie) {
1988
- cookieParts.push(
1989
- parseToken(this.#config.headers),
1990
- parseCallback(this.#config.headers)
1991
- );
1992
- }
1993
- cookieParts.push(csrfCook);
1994
- const cookie = cookieParts.filter(Boolean).join("; ");
1995
- this.#config.headers.set("cookie", cookie);
1996
- updateHeaders(new Headers({ cookie }));
1997
- }
1998
- if (rawResponse) {
1999
- return res;
2000
- }
2001
- try {
2002
- return await res.clone().json();
2003
- } catch {
2004
- return res;
2005
- }
2044
+ return await obtainCsrf(this.#config, rawResponse);
2006
2045
  }
2007
2046
  async listProviders(rawResponse = false) {
2008
2047
  const res = await fetchProviders(this.#config);
@@ -2072,21 +2111,178 @@ var Auth = class {
2072
2111
  return res;
2073
2112
  }
2074
2113
  try {
2075
- return await res.clone().json();
2114
+ const json = await res.clone().json();
2115
+ if (json && typeof json === "object" && "tenants" in json) {
2116
+ const tenantId = json.tenants[0];
2117
+ if (tenantId) {
2118
+ updateTenantId(tenantId);
2119
+ }
2120
+ }
2121
+ return json;
2076
2122
  } catch {
2077
2123
  return res;
2078
2124
  }
2079
2125
  }
2080
- async signIn(provider, payload, rawResponse) {
2081
- this.#config.headers = new Headers();
2082
- const { info, error } = this.#logger;
2083
- const { email, password } = payload ?? {};
2084
- if (provider === "email" && (!email || !password)) {
2126
+ async forgotPassword(req) {
2127
+ let email = "";
2128
+ const defaults = defaultCallbackUrl({
2129
+ config: this.#config
2130
+ });
2131
+ let callbackUrl = defaults.callbackUrl;
2132
+ let redirectUrl = defaults.redirectUrl;
2133
+ if ("email" in req) {
2134
+ email = req.email;
2135
+ }
2136
+ if ("callbackUrl" in req) {
2137
+ callbackUrl = req.callbackUrl ? req.callbackUrl : null;
2138
+ }
2139
+ if ("redirectUrl" in req) {
2140
+ redirectUrl = req.redirectUrl ? req.redirectUrl : null;
2141
+ }
2142
+ const body = JSON.stringify({
2143
+ email,
2144
+ redirectUrl,
2145
+ callbackUrl
2146
+ });
2147
+ const data = await fetchResetPassword(
2148
+ this.#config,
2149
+ "POST",
2150
+ body,
2151
+ new URLSearchParams(),
2152
+ false
2153
+ );
2154
+ return data;
2155
+ }
2156
+ async resetPassword(req) {
2157
+ let email = "";
2158
+ let password = "";
2159
+ const defaults = defaultCallbackUrl({ config: this.#config });
2160
+ let callbackUrl = defaults.callbackUrl;
2161
+ let redirectUrl = defaults.redirectUrl;
2162
+ if (req instanceof Request) {
2163
+ const body2 = await req.json();
2164
+ email = body2.email;
2165
+ password = body2.password;
2166
+ const cbFromHeaders = parseCallback(req.headers);
2167
+ if (cbFromHeaders) {
2168
+ callbackUrl = cbFromHeaders;
2169
+ }
2170
+ if (body2.callbackUrl) {
2171
+ callbackUrl = body2.callbackUrl;
2172
+ }
2173
+ if (body2.redirectUrl) {
2174
+ redirectUrl = body2.redirectUrl;
2175
+ }
2176
+ } else {
2177
+ if ("email" in req) {
2178
+ email = req.email;
2179
+ }
2180
+ if ("password" in req) {
2181
+ password = req.password;
2182
+ }
2183
+ if ("callbackUrl" in req) {
2184
+ callbackUrl = req.callbackUrl ? req.callbackUrl : null;
2185
+ }
2186
+ if ("redirectUrl" in req) {
2187
+ redirectUrl = req.redirectUrl ? req.redirectUrl : null;
2188
+ }
2189
+ }
2190
+ await this.getCsrf();
2191
+ const body = JSON.stringify({
2192
+ email,
2193
+ password,
2194
+ redirectUrl,
2195
+ callbackUrl
2196
+ });
2197
+ let urlWithParams;
2198
+ try {
2199
+ const data = await fetchResetPassword(this.#config, "POST", body);
2200
+ const cloned = data.clone();
2201
+ if (data.status === 400) {
2202
+ const text = await cloned.text();
2203
+ this.#logger.error(text);
2204
+ return data;
2205
+ }
2206
+ const { url } = await data.json();
2207
+ urlWithParams = url;
2208
+ } catch {
2209
+ }
2210
+ let token;
2211
+ try {
2212
+ const worthyParams = new URL(urlWithParams).searchParams;
2213
+ const answer = await fetchResetPassword(
2214
+ this.#config,
2215
+ "GET",
2216
+ null,
2217
+ worthyParams
2218
+ );
2219
+ token = parseResetToken(answer.headers);
2220
+ } catch {
2221
+ this.#logger.warn(
2222
+ "Unable to parse reset password url. Password not reset."
2223
+ );
2224
+ }
2225
+ const cookie = this.#config.headers.get("cookie")?.split("; ");
2226
+ if (token) {
2227
+ cookie?.push(token);
2228
+ } else {
2085
2229
  throw new Error(
2086
- "Server side sign in requires a user email and password."
2230
+ "Unable to reset password, reset token is missing from response"
2087
2231
  );
2088
2232
  }
2089
- info(`Obtaining providers for ${email}`);
2233
+ this.#config.headers = new Headers({
2234
+ ...this.#config.headers,
2235
+ cookie: cookie?.join("; ")
2236
+ });
2237
+ const res = await fetchResetPassword(this.#config, "PUT", body);
2238
+ cookie?.pop();
2239
+ const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
2240
+ cleaned.push(String(parseToken(res.headers)));
2241
+ const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
2242
+ updateHeaders(updatedHeaders);
2243
+ return res;
2244
+ }
2245
+ async callback(provider, body) {
2246
+ if (body instanceof Request) {
2247
+ this.#config.headers = body.headers;
2248
+ return await fetchCallback(
2249
+ this.#config,
2250
+ provider,
2251
+ void 0,
2252
+ body,
2253
+ "GET"
2254
+ );
2255
+ }
2256
+ return await fetchCallback(this.#config, provider, body);
2257
+ }
2258
+ async signIn(provider, payload, rawResponse) {
2259
+ if (payload instanceof Request) {
2260
+ const body2 = new URLSearchParams(await payload.text());
2261
+ const origin = new URL(payload.url).origin;
2262
+ const payloadUrl = body2?.get("callbackUrl");
2263
+ const csrfToken2 = body2?.get("csrfToken");
2264
+ const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
2265
+ if (!csrfToken2) {
2266
+ throw new Error(
2267
+ "CSRF token in missing from request. Request it by the client before calling sign in"
2268
+ );
2269
+ }
2270
+ this.#config.headers = new Headers(payload.headers);
2271
+ this.#config.headers.set(
2272
+ "Content-Type",
2273
+ "application/x-www-form-urlencoded"
2274
+ );
2275
+ const params = new URLSearchParams({
2276
+ csrfToken: csrfToken2,
2277
+ json: String(true)
2278
+ });
2279
+ if (payloadUrl) {
2280
+ params.set("callbackUrl", callbackUrl);
2281
+ }
2282
+ return await fetchSignIn(this.#config, provider, params);
2283
+ }
2284
+ this.#config.headers = new Headers();
2285
+ const { info, error } = this.#logger;
2090
2286
  const providers = await this.listProviders();
2091
2287
  info("Obtaining csrf");
2092
2288
  const csrf = await this.getCsrf();
@@ -2102,13 +2298,13 @@ var Auth = class {
2102
2298
  "Unable to obtain credential provider. Aborting server side sign in."
2103
2299
  );
2104
2300
  }
2105
- if (provider !== "credentials") {
2106
- return await fetchSignIn(
2107
- this.#config,
2108
- provider,
2109
- JSON.stringify({ csrfToken })
2301
+ const { email, password } = payload ?? {};
2302
+ if (provider === "email" && (!email || !password)) {
2303
+ throw new Error(
2304
+ "Server side sign in requires a user email and password."
2110
2305
  );
2111
2306
  }
2307
+ info(`Obtaining providers for ${email}`);
2112
2308
  info(`Attempting sign in with email ${email}`);
2113
2309
  const body = JSON.stringify({
2114
2310
  email,
@@ -2116,7 +2312,7 @@ var Auth = class {
2116
2312
  csrfToken,
2117
2313
  callbackUrl: credentials.callbackUrl
2118
2314
  });
2119
- const signInRes = await fetchCallback(this.#config, provider, body);
2315
+ const signInRes = await this.callback(provider, body);
2120
2316
  const authCookie = signInRes?.headers.get("set-cookie");
2121
2317
  if (!authCookie) {
2122
2318
  throw new Error("authentication failed");
@@ -2131,7 +2327,7 @@ var Auth = class {
2131
2327
  }
2132
2328
  if (urlError) {
2133
2329
  error("Unable to log user in", { error: urlError });
2134
- return void 0;
2330
+ return new Response(urlError, { status: signInRes.status });
2135
2331
  }
2136
2332
  }
2137
2333
  if (!token) {
@@ -2198,31 +2394,421 @@ function parseToken(headers) {
2198
2394
  const [, token] = /((__Secure-)?nile\.session-token=[^;]+)/.exec(authCookie) ?? [];
2199
2395
  return token;
2200
2396
  }
2397
+ function parseResetToken(headers) {
2398
+ let authCookie = headers?.get("set-cookie");
2399
+ if (!authCookie) {
2400
+ authCookie = headers?.get("cookie");
2401
+ }
2402
+ if (!authCookie) {
2403
+ return void 0;
2404
+ }
2405
+ const [, token] = /((__Secure-)?nile\.reset=[^;]+)/.exec(authCookie) ?? [];
2406
+ return token;
2407
+ }
2408
+ function defaultCallbackUrl({ config }) {
2409
+ let cb = null;
2410
+ let redirect = null;
2411
+ const fallbackCb = parseCallback(config.headers);
2412
+ if (fallbackCb) {
2413
+ const [, value] = fallbackCb.split("=");
2414
+ cb = decodeURIComponent(value);
2415
+ if (value) {
2416
+ redirect = `${new URL(cb).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
2417
+ }
2418
+ }
2419
+ return { callbackUrl: cb, redirectUrl: redirect };
2420
+ }
2421
+
2422
+ // src/auth/obtainCsrf.ts
2423
+ async function obtainCsrf(config, rawResponse = false) {
2424
+ const res = await fetchCsrf(config);
2425
+ const csrfCook = parseCSRF(res.headers);
2426
+ if (csrfCook) {
2427
+ const [, value] = csrfCook.split("=");
2428
+ const [token] = decodeURIComponent(value).split("|");
2429
+ const setCookie = res.headers.get("set-cookie");
2430
+ if (setCookie) {
2431
+ const cookie = [
2432
+ csrfCook,
2433
+ parseCallback(res.headers),
2434
+ parseToken(res.headers)
2435
+ ].filter(Boolean).join("; ");
2436
+ config.headers.set("cookie", cookie);
2437
+ updateHeaders(new Headers({ cookie }));
2438
+ }
2439
+ if (!rawResponse) {
2440
+ return { csrfToken: token };
2441
+ }
2442
+ } else {
2443
+ const existingCookie = config.headers.get("cookie");
2444
+ const cookieParts = [];
2445
+ if (existingCookie) {
2446
+ cookieParts.push(
2447
+ parseToken(config.headers),
2448
+ parseCallback(config.headers)
2449
+ );
2450
+ }
2451
+ if (csrfCook) {
2452
+ cookieParts.push(csrfCook);
2453
+ } else {
2454
+ cookieParts.push(parseCSRF(config.headers));
2455
+ }
2456
+ const cookie = cookieParts.filter(Boolean).join("; ");
2457
+ config.headers.set("cookie", cookie);
2458
+ updateHeaders(new Headers({ cookie }));
2459
+ }
2460
+ if (rawResponse) {
2461
+ return res;
2462
+ }
2463
+ try {
2464
+ return await res.clone().json();
2465
+ } catch {
2466
+ return res;
2467
+ }
2468
+ }
2469
+
2470
+ // src/users/index.ts
2471
+ var Users = class {
2472
+ #config;
2473
+ #logger;
2474
+ constructor(config) {
2475
+ this.#config = config;
2476
+ this.#logger = config.logger("[me]");
2477
+ }
2478
+ async updateSelf(req, rawResponse) {
2479
+ const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
2480
+ if (rawResponse) {
2481
+ return res;
2482
+ }
2483
+ try {
2484
+ return await res?.clone().json();
2485
+ } catch {
2486
+ return res;
2487
+ }
2488
+ }
2489
+ async removeSelf() {
2490
+ const me = await this.getSelf();
2491
+ if ("id" in me) {
2492
+ this.#config.userId = me.id;
2493
+ }
2494
+ const res = await fetchMe(this.#config, "DELETE");
2495
+ updateHeaders(new Headers());
2496
+ return res;
2497
+ }
2498
+ async getSelf(rawResponse) {
2499
+ const res = await fetchMe(this.#config);
2500
+ if (rawResponse) {
2501
+ return res;
2502
+ }
2503
+ try {
2504
+ return await res?.clone().json();
2505
+ } catch {
2506
+ return res;
2507
+ }
2508
+ }
2509
+ async verifySelf(options, rawResponse = false) {
2510
+ const bypassEmail = typeof options === "object" ? options.bypassEmail ?? process.env.NODE_ENV !== "production" : process.env.NODE_ENV !== "production";
2511
+ const callbackUrl = typeof options === "object" ? options.callbackUrl : defaultCallbackUrl2(this.#config).callbackUrl;
2512
+ let res;
2513
+ try {
2514
+ const me = await this.getSelf();
2515
+ if (me instanceof Response) {
2516
+ return me;
2517
+ }
2518
+ res = await verifyEmailAddress(this.#config, me, String(callbackUrl));
2519
+ return res;
2520
+ } catch {
2521
+ const message = "Unable to verify email.";
2522
+ this.#logger?.warn(message);
2523
+ res = new Response(message, { status: 400 });
2524
+ }
2525
+ if (bypassEmail) {
2526
+ res = this.updateSelf({ emailVerified: true }, rawResponse);
2527
+ }
2528
+ this.#logger.error(
2529
+ "Unable to verify email address. Configure your SMTP server in the console."
2530
+ );
2531
+ return res;
2532
+ }
2533
+ };
2534
+ async function verifyEmailAddress(config, user, callback) {
2535
+ config.headers.set("content-type", "application/x-www-form-urlencoded");
2536
+ const { csrfToken } = await obtainCsrf(config);
2537
+ const defaults = defaultCallbackUrl2(config);
2538
+ const callbackUrl = callback ?? String(defaults.callbackUrl);
2539
+ const res = await fetchVerifyEmail(
2540
+ config,
2541
+ "POST",
2542
+ new URLSearchParams({
2543
+ csrfToken,
2544
+ email: user.email,
2545
+ callbackUrl
2546
+ }).toString()
2547
+ );
2548
+ if (res.status > 299) {
2549
+ throw new Error(await res.text());
2550
+ }
2551
+ return res;
2552
+ }
2553
+ function defaultCallbackUrl2(config) {
2554
+ let cb = null;
2555
+ const fallbackCb = parseCallback(config.headers);
2556
+ if (fallbackCb) {
2557
+ const [, value] = fallbackCb.split("=");
2558
+ cb = decodeURIComponent(value);
2559
+ }
2560
+ return { callbackUrl: cb };
2561
+ }
2562
+
2563
+ // src/tenants/index.ts
2564
+ var Tenants = class {
2565
+ #config;
2566
+ constructor(config) {
2567
+ this.#config = config;
2568
+ }
2569
+ async create(req, rawResponse) {
2570
+ let res;
2571
+ if (typeof req === "string") {
2572
+ res = await fetchTenants(
2573
+ this.#config,
2574
+ "POST",
2575
+ JSON.stringify({ name: req })
2576
+ );
2577
+ } else if (typeof req === "object" && ("name" in req || "id" in req)) {
2578
+ res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
2579
+ }
2580
+ if (rawResponse) {
2581
+ return res;
2582
+ }
2583
+ try {
2584
+ return await res?.clone().json();
2585
+ } catch {
2586
+ return res;
2587
+ }
2588
+ }
2589
+ async delete(req) {
2590
+ if (typeof req === "string") {
2591
+ this.#config.tenantId = req;
2592
+ }
2593
+ if (typeof req === "object" && "id" in req) {
2594
+ this.#config.tenantId = req.id;
2595
+ }
2596
+ const res = await fetchTenant(this.#config, "DELETE");
2597
+ return res;
2598
+ }
2599
+ async get(req, rawResponse) {
2600
+ if (typeof req === "string") {
2601
+ this.#config.tenantId = req;
2602
+ } else if (typeof req === "object" && "id" in req) {
2603
+ this.#config.tenantId = req.id;
2604
+ }
2605
+ const res = await fetchTenant(this.#config, "GET");
2606
+ if (rawResponse === true || req === true) {
2607
+ return res;
2608
+ }
2609
+ try {
2610
+ return await res?.clone().json();
2611
+ } catch {
2612
+ return res;
2613
+ }
2614
+ }
2615
+ async update(req, rawResponse) {
2616
+ let res;
2617
+ if (typeof req === "object" && ("name" in req || "id" in req)) {
2618
+ const { id, ...remaining } = req;
2619
+ if (id) {
2620
+ this.#config.tenantId = id;
2621
+ }
2622
+ res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
2623
+ }
2624
+ if (rawResponse) {
2625
+ return res;
2626
+ }
2627
+ try {
2628
+ return await res?.clone().json();
2629
+ } catch {
2630
+ return res;
2631
+ }
2632
+ }
2633
+ async list(req) {
2634
+ const res = await fetchTenantsByUser(this.#config);
2635
+ if (req === true) {
2636
+ return res;
2637
+ }
2638
+ try {
2639
+ return await res?.clone().json();
2640
+ } catch {
2641
+ return res;
2642
+ }
2643
+ }
2644
+ async leaveTenant(req) {
2645
+ const me = await fetchMe(this.#config);
2646
+ try {
2647
+ const json = await me.json();
2648
+ if ("id" in json) {
2649
+ this.#config.userId = json.id;
2650
+ }
2651
+ } catch {
2652
+ }
2653
+ if (typeof req === "string") {
2654
+ this.#config.tenantId = req;
2655
+ } else {
2656
+ this.#handleContext(req);
2657
+ }
2658
+ return await fetchTenantUser(this.#config, "DELETE");
2659
+ }
2660
+ async addMember(req, rawResponse) {
2661
+ if (typeof req === "string") {
2662
+ this.#config.userId = req;
2663
+ } else {
2664
+ this.#handleContext(req);
2665
+ }
2666
+ const res = await fetchTenantUser(this.#config, "PUT");
2667
+ return responseHandler(res, rawResponse);
2668
+ }
2669
+ async removeMember(req, rawResponse) {
2670
+ this.#handleContext(req);
2671
+ const res = await fetchTenantUser(this.#config, "DELETE");
2672
+ return responseHandler(res, rawResponse);
2673
+ }
2674
+ async users(req, rawResponse) {
2675
+ this.#handleContext(req);
2676
+ const res = await fetchTenantUsers(this.#config, "GET");
2677
+ return responseHandler(
2678
+ res,
2679
+ rawResponse || typeof req === "boolean" && req
2680
+ );
2681
+ }
2682
+ async invites() {
2683
+ const res = await fetchInvites(this.#config);
2684
+ return responseHandler(res);
2685
+ }
2686
+ async invite(req, rawResponse) {
2687
+ const { csrfToken } = await obtainCsrf(this.#config);
2688
+ const defaults = defaultCallbackUrl3(this.#config);
2689
+ let identifier = req;
2690
+ let callbackUrl = defaults.callbackUrl;
2691
+ let redirectUrl = defaults.redirectUrl;
2692
+ if (typeof req === "object") {
2693
+ if ("email" in req) {
2694
+ identifier = req.email;
2695
+ }
2696
+ if ("callbackUrl" in req) {
2697
+ callbackUrl = req.callbackUrl ? req.callbackUrl : "";
2698
+ }
2699
+ if ("redirectUrl" in req) {
2700
+ redirectUrl = req.redirectUrl ? req.redirectUrl : "";
2701
+ }
2702
+ }
2703
+ this.#config.headers.set(
2704
+ "Content-Type",
2705
+ "application/x-www-form-urlencoded"
2706
+ );
2707
+ const res = await fetchInvite(
2708
+ this.#config,
2709
+ "POST",
2710
+ new URLSearchParams({
2711
+ identifier,
2712
+ csrfToken,
2713
+ callbackUrl,
2714
+ redirectUrl
2715
+ }).toString()
2716
+ );
2717
+ return responseHandler(res, rawResponse);
2718
+ }
2719
+ async acceptInvite(req, rawResponse) {
2720
+ if (!req) {
2721
+ throw new Error("The identifier and token are required.");
2722
+ }
2723
+ const { identifier, token } = req;
2724
+ const defaults = defaultCallbackUrl3(this.#config);
2725
+ const callbackUrl = String(defaults.callbackUrl);
2726
+ const res = await fetchInvite(
2727
+ this.#config,
2728
+ "PUT",
2729
+ new URLSearchParams({
2730
+ identifier,
2731
+ token,
2732
+ callbackUrl
2733
+ }).toString()
2734
+ );
2735
+ return responseHandler(res, rawResponse);
2736
+ }
2737
+ async deleteInvite(req) {
2738
+ let id = "";
2739
+ if (typeof req === "object") {
2740
+ id = req.id;
2741
+ } else {
2742
+ id = req;
2743
+ }
2744
+ if (!id) {
2745
+ throw new Error("An invite id is required.");
2746
+ }
2747
+ const res = await fetchInvite(this.#config, "DELETE", id);
2748
+ return responseHandler(res, true);
2749
+ }
2750
+ #handleContext(req) {
2751
+ if (typeof req === "object") {
2752
+ if ("tenantId" in req) {
2753
+ this.#config.tenantId = req.tenantId;
2754
+ }
2755
+ if ("userId" in req) {
2756
+ this.#config.tenantId = req.tenantId;
2757
+ }
2758
+ }
2759
+ }
2760
+ };
2761
+ async function responseHandler(res, rawResponse) {
2762
+ if (rawResponse) {
2763
+ return res;
2764
+ }
2765
+ try {
2766
+ return await res?.clone().json();
2767
+ } catch {
2768
+ return res;
2769
+ }
2770
+ }
2771
+ function defaultCallbackUrl3(config) {
2772
+ let cb = null;
2773
+ let redirect = null;
2774
+ const fallbackCb = parseCallback(config.headers);
2775
+ if (fallbackCb) {
2776
+ const [, value] = fallbackCb.split("=");
2777
+ cb = decodeURIComponent(value);
2778
+ if (value) {
2779
+ redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace(
2780
+ "{tenantId}",
2781
+ String(config.tenantId)
2782
+ )}`;
2783
+ }
2784
+ }
2785
+ return { callbackUrl: cb, redirectUrl: redirect };
2786
+ }
2201
2787
 
2202
2788
  // src/api/handlers/withContext/index.ts
2203
2789
  function handlersWithContext(config) {
2204
- const GET6 = GETTER(config.routes, config);
2205
- const POST5 = POSTER(config.routes, config);
2206
- const DELETE4 = DELETER(config.routes, config);
2207
- const PUT5 = PUTER(config.routes, config);
2790
+ const GET7 = GETTER(config.routes, config);
2791
+ const POST6 = POSTER(config.routes, config);
2792
+ const DELETE5 = DELETER(config.routes, config);
2793
+ const PUT6 = PUTER(config.routes, config);
2208
2794
  return {
2209
2795
  GET: async (req) => {
2210
- const response = await GET6(req);
2796
+ const response = await GET7(req);
2211
2797
  const updatedConfig = updateConfig(response, config);
2212
2798
  return { response, nile: new Server(updatedConfig) };
2213
2799
  },
2214
2800
  POST: async (req) => {
2215
- const response = await POST5(req);
2801
+ const response = await POST6(req);
2216
2802
  const updatedConfig = updateConfig(response, config);
2217
2803
  return { response, nile: new Server(updatedConfig) };
2218
2804
  },
2219
2805
  DELETE: async (req) => {
2220
- const response = await DELETE4(req);
2806
+ const response = await DELETE5(req);
2221
2807
  const updatedConfig = updateConfig(response, config);
2222
2808
  return { response, nile: new Server(updatedConfig) };
2223
2809
  },
2224
2810
  PUT: async (req) => {
2225
- const response = await PUT5(req);
2811
+ const response = await PUT6(req);
2226
2812
  const updatedConfig = updateConfig(response, config);
2227
2813
  return { response, nile: new Server(updatedConfig) };
2228
2814
  }
@@ -2234,14 +2820,14 @@ function updateConfig(response, config) {
2234
2820
  if (response?.status === 302) {
2235
2821
  const location = response.headers.get("location");
2236
2822
  if (location) {
2237
- const normalized = location.endsWith("/") ? location.slice(0, -1) : location;
2238
- origin = normalized;
2823
+ const urlLocation = new URL(location);
2824
+ origin = urlLocation.origin;
2239
2825
  }
2240
2826
  }
2241
2827
  const setCookies = [];
2242
2828
  if (response?.headers) {
2243
- for (const [key13, value] of response.headers) {
2244
- if (key13.toLowerCase() === "set-cookie") {
2829
+ for (const [key17, value] of response.headers) {
2830
+ if (key17.toLowerCase() === "set-cookie") {
2245
2831
  setCookies.push(value);
2246
2832
  }
2247
2833
  }
@@ -2253,9 +2839,68 @@ function updateConfig(response, config) {
2253
2839
  return {
2254
2840
  ...config,
2255
2841
  origin,
2256
- headers: headers ?? void 0
2842
+ headers: headers ?? void 0,
2843
+ preserveHeaders: true
2844
+ };
2845
+ }
2846
+
2847
+ // src/api/utils/extensions.ts
2848
+ function bindHandleOnRequest(instance) {
2849
+ return async function handleOnRequest(config, _init, params) {
2850
+ const { debug } = config.logger("[EXTENSIONS]");
2851
+ if (config.extensions) {
2852
+ for (const create2 of config.extensions) {
2853
+ if (typeof create2 !== "function") {
2854
+ return void 0;
2855
+ }
2856
+ const ext = await create2(instance);
2857
+ if (ext.onRequest) {
2858
+ const previousContext = instance.getContext();
2859
+ if (previousContext.preserveHeaders) {
2860
+ instance.setContext({ preserveHeaders: false });
2861
+ }
2862
+ await ext.onRequest(_init.request);
2863
+ const updatedContext = instance.getContext();
2864
+ if (updatedContext?.headers) {
2865
+ const cookie = updatedContext.headers.get("cookie");
2866
+ if (cookie) {
2867
+ params.headers.set(
2868
+ "cookie",
2869
+ mergeCookies(
2870
+ previousContext.preserveHeaders ? previousContext.headers?.get("cookie") : null,
2871
+ updatedContext.headers.get("cookie")
2872
+ )
2873
+ );
2874
+ }
2875
+ if (updatedContext.tenantId) {
2876
+ params.headers.set(
2877
+ TENANT_COOKIE,
2878
+ String(updatedContext.headers.get(TENANT_COOKIE))
2879
+ );
2880
+ }
2881
+ }
2882
+ debug(`${ext.id ?? create2.name} ran onRequest`);
2883
+ }
2884
+ }
2885
+ }
2257
2886
  };
2258
2887
  }
2888
+ function buildExtensionConfig(instance) {
2889
+ return {
2890
+ handleOnRequest: bindHandleOnRequest(instance)
2891
+ };
2892
+ }
2893
+ function mergeCookies(...cookieStrings) {
2894
+ const cookieMap = /* @__PURE__ */ new Map();
2895
+ for (const str of cookieStrings) {
2896
+ if (!str) continue;
2897
+ for (const part of str.split(";")) {
2898
+ const [key17, value] = part.split("=").map((s) => s.trim());
2899
+ if (key17 && value) cookieMap.set(key17, value);
2900
+ }
2901
+ }
2902
+ return [...cookieMap.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
2903
+ }
2259
2904
 
2260
2905
  // src/Server.ts
2261
2906
  var Server = class {
@@ -2267,8 +2912,12 @@ var Server = class {
2267
2912
  #paths;
2268
2913
  #manager;
2269
2914
  #headers;
2915
+ #preserveHeaders;
2270
2916
  constructor(config) {
2271
- this.#config = new Config(config, "[initial config]");
2917
+ this.#config = new Config({
2918
+ ...config,
2919
+ extensionCtx: buildExtensionConfig(this)
2920
+ });
2272
2921
  watchTenantId((tenantId) => {
2273
2922
  if (tenantId !== this.#config.tenantId) {
2274
2923
  this.#config.tenantId = tenantId;
@@ -2289,6 +2938,7 @@ var Server = class {
2289
2938
  ...this.#config.handlers,
2290
2939
  withContext: handlersWithContext(this.#config)
2291
2940
  };
2941
+ this.#preserveHeaders = config?.preserveHeaders ?? false;
2292
2942
  this.#paths = this.#config.paths;
2293
2943
  this.#config.tenantId = getTenantId({ config: this.#config });
2294
2944
  this.#manager = new DBManager(this.#config);
@@ -2355,6 +3005,10 @@ var Server = class {
2355
3005
  ok = true;
2356
3006
  this.#config.userId = req.userId;
2357
3007
  }
3008
+ if (req && typeof req === "object" && "preserveHeaders" in req) {
3009
+ ok = true;
3010
+ this.#preserveHeaders = Boolean(req.preserveHeaders);
3011
+ }
2358
3012
  if (ok) {
2359
3013
  return;
2360
3014
  }
@@ -2366,7 +3020,7 @@ var Server = class {
2366
3020
  return;
2367
3021
  }
2368
3022
  }
2369
- const { warn } = Logger(this.#config, "[API]");
3023
+ const { warn } = Logger(this.#config)("[API]");
2370
3024
  if (warn) {
2371
3025
  warn(
2372
3026
  "Set context expects a Request, Header instance or an object of Record<string, string>"
@@ -2377,7 +3031,8 @@ var Server = class {
2377
3031
  return {
2378
3032
  headers: this.#headers,
2379
3033
  userId: this.#config.userId,
2380
- tenantId: this.#config.tenantId
3034
+ tenantId: this.#config.tenantId,
3035
+ preserveHeaders: this.#preserveHeaders
2381
3036
  };
2382
3037
  }
2383
3038
  /**
@@ -2393,33 +3048,35 @@ var Server = class {
2393
3048
  } else if (config?.headers) {
2394
3049
  headers = config?.headers;
2395
3050
  if (config && config.origin) {
2396
- this.#headers.set(X_NILE_ORIGIN, config.origin);
3051
+ this.#headers.set(HEADER_ORIGIN, config.origin);
2397
3052
  }
2398
3053
  if (config && config.secureCookies != null) {
2399
- this.#headers.set(X_NILE_SECURECOOKIES, String(config.secureCookies));
3054
+ this.#headers.set(HEADER_SECURE_COOKIES, String(config.secureCookies));
2400
3055
  }
2401
3056
  }
2402
3057
  if (headers instanceof Headers) {
2403
- headers.forEach((value, key13) => {
2404
- updates.push([key13.toLowerCase(), value]);
3058
+ headers.forEach((value, key17) => {
3059
+ updates.push([key17.toLowerCase(), value]);
2405
3060
  });
2406
3061
  } else {
2407
- for (const [key13, value] of Object.entries(headers ?? {})) {
2408
- updates.push([key13.toLowerCase(), value]);
3062
+ for (const [key17, value] of Object.entries(headers ?? {})) {
3063
+ updates.push([key17.toLowerCase(), value]);
2409
3064
  }
2410
3065
  }
2411
3066
  const merged = {};
2412
- this.#headers?.forEach((value, key13) => {
2413
- if (key13.toLowerCase() !== "cookie") {
2414
- merged[key13.toLowerCase()] = value;
3067
+ this.#config.tenantId = getTenantFromHttp(this.#headers, this.#config);
3068
+ this.#headers?.forEach((value, key17) => {
3069
+ if (key17.toLowerCase() !== "cookie") {
3070
+ merged[key17.toLowerCase()] = value;
2415
3071
  }
2416
3072
  });
2417
- for (const [key13, value] of updates) {
2418
- merged[key13] = value;
3073
+ for (const [key17, value] of updates) {
3074
+ merged[key17] = value;
2419
3075
  }
2420
- for (const [key13, value] of Object.entries(merged)) {
2421
- this.#headers.set(key13, value);
3076
+ for (const [key17, value] of Object.entries(merged)) {
3077
+ this.#headers.set(key17, value);
2422
3078
  }
3079
+ this.#config.logger("[handleHeaders]").debug(JSON.stringify(merged));
2423
3080
  this.#config.headers = this.#headers;
2424
3081
  }
2425
3082
  /**
@@ -2440,6 +3097,6 @@ function create(config) {
2440
3097
  return server;
2441
3098
  }
2442
3099
 
2443
- export { APIErrorErrorCodeEnum, LoginUserResponseTokenTypeEnum, create as Nile, Server, parseCSRF, parseCallback, parseToken };
3100
+ export { APIErrorErrorCodeEnum, HEADER_ORIGIN, HEADER_SECURE_COOKIES, LoginUserResponseTokenTypeEnum, create as Nile, Server, TENANT_COOKIE, USER_COOKIE, parseCSRF, parseCallback, parseToken };
2444
3101
  //# sourceMappingURL=index.mjs.map
2445
3102
  //# sourceMappingURL=index.mjs.map