@niledatabase/server 4.0.2 → 4.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -17,39 +17,48 @@ function urlMatches(requestUrl, route15) {
17
17
 
18
18
  // src/utils/Logger.ts
19
19
  var red = "\x1B[31m";
20
- var yellow = "\x1B[33m";
20
+ var yellow = "\x1B[38;2;255;255;0m";
21
+ var purple = "\x1B[38;2;200;160;255m";
22
+ var orange = "\x1B[38;2;255;165;0m";
21
23
  var reset = "\x1B[0m";
22
24
  var baseLogger = (config, ...params) => ({
23
25
  info(message, meta) {
24
26
  if (config?.debug) {
25
27
  console.info(
26
- `[niledb][DEBUG]${params.join("")} ${message}`,
27
- meta ? `
28
- ${JSON.stringify(meta, null, 2)}` : ""
28
+ `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
29
+ ""
30
+ )}${reset} ${message}`,
31
+ meta ? `${JSON.stringify(meta)}` : ""
29
32
  );
30
33
  }
31
34
  },
32
35
  debug(message, meta) {
33
36
  if (config?.debug) {
34
37
  console.debug(
35
- `[niledb][DEBUG]${params.join("")} ${message}`,
36
- meta ? `
37
- ${JSON.stringify(meta, null, 2)}` : ""
38
+ `${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
39
+ ""
40
+ )}${reset} ${message}`,
41
+ meta ? `${JSON.stringify(meta)}` : ""
38
42
  );
39
43
  }
40
44
  },
41
45
  warn(message, meta) {
42
46
  if (config?.debug) {
43
47
  console.warn(
44
- `${yellow}[niledb][WARN]${reset}${params.join("")} ${message}`,
45
- JSON.stringify(meta, null, 2)
48
+ `${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
49
+ ""
50
+ )}${reset} ${message}`,
51
+ meta ? JSON.stringify(meta) : ""
46
52
  );
47
53
  }
48
54
  },
49
55
  error(message, meta) {
50
56
  console.error(
51
- `${red}[niledb][ERROR]${reset}${params.join("")} ${message}`,
52
- meta
57
+ `${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
58
+ ""
59
+ )}${red} ${message}`,
60
+ meta ? meta : "",
61
+ `${reset}`
53
62
  );
54
63
  }
55
64
  });
@@ -71,6 +80,73 @@ var X_NILE_USER_ID = "nile.user_id";
71
80
  var X_NILE_ORIGIN = "nile.origin";
72
81
  var X_NILE_SECURECOOKIES = "nile.secure_cookies";
73
82
 
83
+ // src/context/asyncStorage.ts
84
+ var globalContext = null;
85
+ function setContext(headers) {
86
+ const origin = headers.get(X_NILE_ORIGIN);
87
+ const host = headers.get("host");
88
+ const cookie = headers.get("cookie");
89
+ const tenantId = headers.get(X_NILE_TENANT);
90
+ const userId = headers.get(X_NILE_USER_ID);
91
+ const context = {};
92
+ if (origin) {
93
+ context.origin = origin;
94
+ } else if (host) {
95
+ context.origin = host;
96
+ }
97
+ if (cookie) {
98
+ context.cookie = cookie;
99
+ }
100
+ if (tenantId) {
101
+ context.tenantId = tenantId;
102
+ }
103
+ if (userId) {
104
+ context.userId = userId;
105
+ }
106
+ globalContext = context;
107
+ }
108
+ function getOrigin() {
109
+ return globalContext?.origin;
110
+ }
111
+ function getCookie() {
112
+ return globalContext?.cookie;
113
+ }
114
+ function setCookie(headers) {
115
+ const getSet = headers?.getSetCookie?.();
116
+ if (getSet?.length) {
117
+ const updatedCookie = [];
118
+ for (const cook of getSet) {
119
+ const [c] = cook.split("; ");
120
+ const [, val] = c.split("=");
121
+ if (val) {
122
+ updatedCookie.push(c);
123
+ }
124
+ }
125
+ const cookie = mergeCookies(updatedCookie);
126
+ globalContext = { ...globalContext, cookie };
127
+ }
128
+ }
129
+ function mergeCookies(overrideArray) {
130
+ const cookieString = getCookie();
131
+ const cookieMap = {};
132
+ if (!cookieString) {
133
+ return overrideArray.join("; ");
134
+ }
135
+ cookieString.split(";").forEach((cookie) => {
136
+ const [rawKey, ...rawVal] = cookie.trim().split("=");
137
+ const key12 = rawKey.trim();
138
+ const value = rawVal.join("=").trim();
139
+ if (key12) cookieMap[key12] = value;
140
+ });
141
+ overrideArray.forEach((cookie) => {
142
+ const [rawKey, ...rawVal] = cookie.trim().split("=");
143
+ const key12 = rawKey.trim();
144
+ const value = rawVal.join("=").trim();
145
+ if (key12) cookieMap[key12] = value;
146
+ });
147
+ return Object.entries(cookieMap).map(([k, v]) => `${k}=${v}`).join("; ");
148
+ }
149
+
74
150
  // src/api/utils/request.ts
75
151
  async function request(url, _init, config) {
76
152
  const { debug, info, error } = Logger(config, "[REQUEST]");
@@ -104,7 +180,7 @@ async function request(url, _init, config) {
104
180
  debug(`Obtained origin from request ${requestUrl.origin}`);
105
181
  }
106
182
  const params = { ...init, headers: updatedHeaders };
107
- if (params.method === "POST" || params.method === "PUT") {
183
+ if (params.method?.toLowerCase() === "post" || params.method?.toLowerCase() === "put") {
108
184
  try {
109
185
  updatedHeaders.set("content-type", "application/json");
110
186
  const initBody = await new Response(_init.request.clone().body).json();
@@ -119,22 +195,26 @@ async function request(url, _init, config) {
119
195
  }
120
196
  const fullUrl = `${url}${requestUrl.search}`;
121
197
  try {
122
- const res = await fetch(fullUrl, { ...params }).catch((e) => {
123
- error("An error has occurred in the fetch", {
124
- message: e.message,
125
- stack: e.stack
126
- });
127
- return new Response(
128
- "An unexpected (most likely configuration) problem has occurred",
129
- { status: 500 }
130
- );
131
- });
198
+ setContext(updatedHeaders);
199
+ const res = await fetch(fullUrl, { ...params }).catch(
200
+ (e) => {
201
+ error("An error has occurred in the fetch", {
202
+ message: e.message,
203
+ stack: e.stack
204
+ });
205
+ return new Response(
206
+ "An unexpected (most likely configuration) problem has occurred",
207
+ { status: 500 }
208
+ );
209
+ }
210
+ );
132
211
  const loggingRes = typeof res?.clone === "function" ? res?.clone() : null;
133
212
  info(`[${params.method ?? "GET"}] ${fullUrl}`, {
134
213
  status: res?.status,
135
214
  statusText: res?.statusText,
136
215
  text: await loggingRes?.text()
137
216
  });
217
+ setCookie(res?.headers);
138
218
  return res;
139
219
  } catch (e) {
140
220
  if (e instanceof Error) {
@@ -434,11 +514,11 @@ var ApiConfig = class {
434
514
  * If this is set, any `callbackUrl` from the client will be ignored.
435
515
  */
436
516
  callbackUrl;
437
- _token;
517
+ #token;
438
518
  constructor(config, logger) {
439
519
  const envVarConfig = { config, logger };
440
520
  this.cookieKey = getCookieKey(envVarConfig);
441
- this._token = getToken(envVarConfig);
521
+ this.#token = getToken(envVarConfig);
442
522
  this.callbackUrl = getCallbackUrl(envVarConfig);
443
523
  this.secureCookies = getSecureCookies(envVarConfig);
444
524
  this.basePath = getBasePath(envVarConfig);
@@ -447,10 +527,10 @@ var ApiConfig = class {
447
527
  this.origin = config?.api?.origin;
448
528
  }
449
529
  get token() {
450
- return this._token;
530
+ return this.#token;
451
531
  }
452
532
  set token(value) {
453
- this._token = value;
533
+ this.#token = value;
454
534
  }
455
535
  };
456
536
  var Config = class {
@@ -962,7 +1042,7 @@ var ResponseError = class {
962
1042
 
963
1043
  // src/utils/fetch.ts
964
1044
  function getTokenFromCookie(headers, cookieKey) {
965
- const cookie = headers.get("cookie")?.split("; ");
1045
+ const cookie = headers.get("cookie")?.split("; ") ?? getCookie()?.split("; ");
966
1046
  const _cookies = {};
967
1047
  if (cookie) {
968
1048
  for (const parts of cookie) {
@@ -997,7 +1077,8 @@ function getUserFromHttp(headers, config) {
997
1077
  }
998
1078
  return headers?.get(X_NILE_USER_ID) ?? config.userId;
999
1079
  }
1000
- function makeBasicHeaders(config, opts) {
1080
+ function makeBasicHeaders(config, url, opts) {
1081
+ const { warn, error } = Logger(config, "[headers]");
1001
1082
  const headers = new Headers(opts?.headers);
1002
1083
  headers.set("content-type", "application/json; charset=utf-8");
1003
1084
  const cookieKey = config.api?.cookieKey;
@@ -1010,11 +1091,31 @@ function makeBasicHeaders(config, opts) {
1010
1091
  headers.set("Authorization", `Bearer ${getToken({ config })}`);
1011
1092
  }
1012
1093
  }
1094
+ const cookie = headers.get("cookie");
1095
+ if (!cookie) {
1096
+ const contextCookie = getCookie();
1097
+ if (contextCookie) {
1098
+ headers.set("cookie", contextCookie);
1099
+ } else {
1100
+ if (!url.endsWith("/users")) {
1101
+ error(
1102
+ "Missing cookie header from request. Call nile.api.setContext(request) before making additional calls."
1103
+ );
1104
+ }
1105
+ }
1106
+ }
1013
1107
  if (config && config.api.secureCookies != null) {
1014
1108
  headers.set(X_NILE_SECURECOOKIES, String(config.api.secureCookies));
1015
1109
  }
1110
+ const savedOrigin = getOrigin();
1016
1111
  if (config && config.api.origin) {
1017
1112
  headers.set(X_NILE_ORIGIN, config.api.origin);
1113
+ } else if (savedOrigin) {
1114
+ headers.set(X_NILE_ORIGIN, savedOrigin);
1115
+ } else {
1116
+ warn(
1117
+ "nile.origin missing from header, which defaults to secure cookies only."
1118
+ );
1018
1119
  }
1019
1120
  return headers;
1020
1121
  }
@@ -1023,7 +1124,7 @@ async function _fetch(config, path, opts) {
1023
1124
  const url = `${config.api?.basePath}${path}`;
1024
1125
  const headers = new Headers(opts?.headers);
1025
1126
  const tenantId = getTenantFromHttp(headers, config);
1026
- const basicHeaders = makeBasicHeaders(config, opts);
1127
+ const basicHeaders = makeBasicHeaders(config, url, opts);
1027
1128
  updateTenantId(tenantId);
1028
1129
  const userId = getUserFromHttp(headers, config);
1029
1130
  updateUserId(userId);
@@ -2433,6 +2534,7 @@ var Api = class {
2433
2534
  };
2434
2535
  resetHeaders = (headers) => {
2435
2536
  this.#headers = new Headers(headers ?? {});
2537
+ setContext(new Headers());
2436
2538
  this.reset();
2437
2539
  };
2438
2540
  set headers(headers) {
@@ -2476,6 +2578,7 @@ var Api = class {
2476
2578
  this.handlers
2477
2579
  )(payload);
2478
2580
  this.headers = headers;
2581
+ this.setContext(headers);
2479
2582
  if (config?.returnResponse) {
2480
2583
  return loginRes;
2481
2584
  }
@@ -2489,6 +2592,17 @@ var Api = class {
2489
2592
  }
2490
2593
  return this.auth.getSession(this.#headers);
2491
2594
  };
2595
+ setContext = (req) => {
2596
+ if (req instanceof Headers) {
2597
+ setContext(req);
2598
+ } else if (req instanceof Request) {
2599
+ setContext(req.headers);
2600
+ }
2601
+ const { warn } = Logger(this.config, "[API]");
2602
+ if (warn) {
2603
+ warn("Set context expects a Request or Header object");
2604
+ }
2605
+ };
2492
2606
  };
2493
2607
 
2494
2608
  // src/Server.ts