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