@niledatabase/server 4.0.1 → 4.0.2-alpha.11
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/express.d.mts +9 -1
- package/dist/express.d.ts +9 -1
- package/dist/express.js +22 -12
- package/dist/express.js.map +1 -1
- package/dist/express.mjs +22 -13
- package/dist/express.mjs.map +1 -1
- package/dist/index.d.mts +21 -7
- package/dist/index.d.ts +21 -7
- package/dist/index.js +174 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +174 -34
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -23,39 +23,48 @@ function urlMatches(requestUrl, route15) {
|
|
|
23
23
|
|
|
24
24
|
// src/utils/Logger.ts
|
|
25
25
|
var red = "\x1B[31m";
|
|
26
|
-
var yellow = "\x1B[
|
|
26
|
+
var yellow = "\x1B[38;2;255;255;0m";
|
|
27
|
+
var purple = "\x1B[38;2;200;160;255m";
|
|
28
|
+
var orange = "\x1B[38;2;255;165;0m";
|
|
27
29
|
var reset = "\x1B[0m";
|
|
28
30
|
var baseLogger = (config, ...params) => ({
|
|
29
31
|
info(message, meta) {
|
|
30
32
|
if (config?.debug) {
|
|
31
33
|
console.info(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
${
|
|
34
|
+
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
35
|
+
""
|
|
36
|
+
)}${reset} ${message}`,
|
|
37
|
+
meta ? `${JSON.stringify(meta)}` : ""
|
|
35
38
|
);
|
|
36
39
|
}
|
|
37
40
|
},
|
|
38
41
|
debug(message, meta) {
|
|
39
42
|
if (config?.debug) {
|
|
40
43
|
console.debug(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
${
|
|
44
|
+
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
45
|
+
""
|
|
46
|
+
)}${reset} ${message}`,
|
|
47
|
+
meta ? `${JSON.stringify(meta)}` : ""
|
|
44
48
|
);
|
|
45
49
|
}
|
|
46
50
|
},
|
|
47
51
|
warn(message, meta) {
|
|
48
52
|
if (config?.debug) {
|
|
49
53
|
console.warn(
|
|
50
|
-
`${
|
|
51
|
-
|
|
54
|
+
`${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
|
|
55
|
+
""
|
|
56
|
+
)}${reset} ${message}`,
|
|
57
|
+
meta ? JSON.stringify(meta) : ""
|
|
52
58
|
);
|
|
53
59
|
}
|
|
54
60
|
},
|
|
55
61
|
error(message, meta) {
|
|
56
62
|
console.error(
|
|
57
|
-
`${
|
|
58
|
-
|
|
63
|
+
`${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
|
|
64
|
+
""
|
|
65
|
+
)}${red} ${message}`,
|
|
66
|
+
meta ? meta : "",
|
|
67
|
+
`${reset}`
|
|
59
68
|
);
|
|
60
69
|
}
|
|
61
70
|
});
|
|
@@ -77,6 +86,73 @@ var X_NILE_USER_ID = "nile.user_id";
|
|
|
77
86
|
var X_NILE_ORIGIN = "nile.origin";
|
|
78
87
|
var X_NILE_SECURECOOKIES = "nile.secure_cookies";
|
|
79
88
|
|
|
89
|
+
// src/context/asyncStorage.ts
|
|
90
|
+
var globalContext = null;
|
|
91
|
+
function setContext(headers) {
|
|
92
|
+
const origin = headers.get(X_NILE_ORIGIN);
|
|
93
|
+
const host = headers.get("host");
|
|
94
|
+
const cookie = headers.get("cookie");
|
|
95
|
+
const tenantId = headers.get(X_NILE_TENANT);
|
|
96
|
+
const userId = headers.get(X_NILE_USER_ID);
|
|
97
|
+
const context = {};
|
|
98
|
+
if (origin) {
|
|
99
|
+
context.origin = origin;
|
|
100
|
+
} else if (host) {
|
|
101
|
+
context.origin = host;
|
|
102
|
+
}
|
|
103
|
+
if (cookie) {
|
|
104
|
+
context.cookie = cookie;
|
|
105
|
+
}
|
|
106
|
+
if (tenantId) {
|
|
107
|
+
context.tenantId = tenantId;
|
|
108
|
+
}
|
|
109
|
+
if (userId) {
|
|
110
|
+
context.userId = userId;
|
|
111
|
+
}
|
|
112
|
+
globalContext = context;
|
|
113
|
+
}
|
|
114
|
+
function getOrigin() {
|
|
115
|
+
return globalContext?.origin;
|
|
116
|
+
}
|
|
117
|
+
function getCookie() {
|
|
118
|
+
return globalContext?.cookie;
|
|
119
|
+
}
|
|
120
|
+
function setCookie(headers) {
|
|
121
|
+
const getSet = headers?.getSetCookie?.();
|
|
122
|
+
if (getSet?.length) {
|
|
123
|
+
const updatedCookie = [];
|
|
124
|
+
for (const cook of getSet) {
|
|
125
|
+
const [c] = cook.split("; ");
|
|
126
|
+
const [, val] = c.split("=");
|
|
127
|
+
if (val) {
|
|
128
|
+
updatedCookie.push(c);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const cookie = mergeCookies(updatedCookie);
|
|
132
|
+
globalContext = { ...globalContext, cookie };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function mergeCookies(overrideArray) {
|
|
136
|
+
const cookieString = getCookie();
|
|
137
|
+
const cookieMap = {};
|
|
138
|
+
if (!cookieString) {
|
|
139
|
+
return overrideArray.join("; ");
|
|
140
|
+
}
|
|
141
|
+
cookieString.split(";").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
|
+
overrideArray.forEach((cookie) => {
|
|
148
|
+
const [rawKey, ...rawVal] = cookie.trim().split("=");
|
|
149
|
+
const key12 = rawKey.trim();
|
|
150
|
+
const value = rawVal.join("=").trim();
|
|
151
|
+
if (key12) cookieMap[key12] = value;
|
|
152
|
+
});
|
|
153
|
+
return Object.entries(cookieMap).map(([k, v]) => `${k}=${v}`).join("; ");
|
|
154
|
+
}
|
|
155
|
+
|
|
80
156
|
// src/api/utils/request.ts
|
|
81
157
|
async function request(url, _init, config) {
|
|
82
158
|
const { debug, info, error } = Logger(config, "[REQUEST]");
|
|
@@ -110,7 +186,7 @@ async function request(url, _init, config) {
|
|
|
110
186
|
debug(`Obtained origin from request ${requestUrl.origin}`);
|
|
111
187
|
}
|
|
112
188
|
const params = { ...init, headers: updatedHeaders };
|
|
113
|
-
if (params.method === "
|
|
189
|
+
if (params.method?.toLowerCase() === "post" || params.method?.toLowerCase() === "put") {
|
|
114
190
|
try {
|
|
115
191
|
updatedHeaders.set("content-type", "application/json");
|
|
116
192
|
const initBody = await new Response(_init.request.clone().body).json();
|
|
@@ -125,22 +201,26 @@ async function request(url, _init, config) {
|
|
|
125
201
|
}
|
|
126
202
|
const fullUrl = `${url}${requestUrl.search}`;
|
|
127
203
|
try {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
204
|
+
setContext(updatedHeaders);
|
|
205
|
+
const res = await fetch(fullUrl, { ...params }).catch(
|
|
206
|
+
(e) => {
|
|
207
|
+
error("An error has occurred in the fetch", {
|
|
208
|
+
message: e.message,
|
|
209
|
+
stack: e.stack
|
|
210
|
+
});
|
|
211
|
+
return new Response(
|
|
212
|
+
"An unexpected (most likely configuration) problem has occurred",
|
|
213
|
+
{ status: 500 }
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
);
|
|
138
217
|
const loggingRes = typeof res?.clone === "function" ? res?.clone() : null;
|
|
139
218
|
info(`[${params.method ?? "GET"}] ${fullUrl}`, {
|
|
140
219
|
status: res?.status,
|
|
141
220
|
statusText: res?.statusText,
|
|
142
221
|
text: await loggingRes?.text()
|
|
143
222
|
});
|
|
223
|
+
setCookie(res?.headers);
|
|
144
224
|
return res;
|
|
145
225
|
} catch (e) {
|
|
146
226
|
if (e instanceof Error) {
|
|
@@ -440,11 +520,11 @@ var ApiConfig = class {
|
|
|
440
520
|
* If this is set, any `callbackUrl` from the client will be ignored.
|
|
441
521
|
*/
|
|
442
522
|
callbackUrl;
|
|
443
|
-
|
|
523
|
+
#token;
|
|
444
524
|
constructor(config, logger) {
|
|
445
525
|
const envVarConfig = { config, logger };
|
|
446
526
|
this.cookieKey = getCookieKey(envVarConfig);
|
|
447
|
-
this
|
|
527
|
+
this.#token = getToken(envVarConfig);
|
|
448
528
|
this.callbackUrl = getCallbackUrl(envVarConfig);
|
|
449
529
|
this.secureCookies = getSecureCookies(envVarConfig);
|
|
450
530
|
this.basePath = getBasePath(envVarConfig);
|
|
@@ -453,10 +533,10 @@ var ApiConfig = class {
|
|
|
453
533
|
this.origin = config?.api?.origin;
|
|
454
534
|
}
|
|
455
535
|
get token() {
|
|
456
|
-
return this
|
|
536
|
+
return this.#token;
|
|
457
537
|
}
|
|
458
538
|
set token(value) {
|
|
459
|
-
this
|
|
539
|
+
this.#token = value;
|
|
460
540
|
}
|
|
461
541
|
};
|
|
462
542
|
var Config = class {
|
|
@@ -968,7 +1048,7 @@ var ResponseError = class {
|
|
|
968
1048
|
|
|
969
1049
|
// src/utils/fetch.ts
|
|
970
1050
|
function getTokenFromCookie(headers, cookieKey) {
|
|
971
|
-
const cookie = headers.get("cookie")?.split("; ");
|
|
1051
|
+
const cookie = headers.get("cookie")?.split("; ") ?? getCookie()?.split("; ");
|
|
972
1052
|
const _cookies = {};
|
|
973
1053
|
if (cookie) {
|
|
974
1054
|
for (const parts of cookie) {
|
|
@@ -1003,7 +1083,8 @@ function getUserFromHttp(headers, config) {
|
|
|
1003
1083
|
}
|
|
1004
1084
|
return headers?.get(X_NILE_USER_ID) ?? config.userId;
|
|
1005
1085
|
}
|
|
1006
|
-
function makeBasicHeaders(config, opts) {
|
|
1086
|
+
function makeBasicHeaders(config, url, opts) {
|
|
1087
|
+
const { warn, error } = Logger(config, "[headers]");
|
|
1007
1088
|
const headers = new Headers(opts?.headers);
|
|
1008
1089
|
headers.set("content-type", "application/json; charset=utf-8");
|
|
1009
1090
|
const cookieKey = config.api?.cookieKey;
|
|
@@ -1016,11 +1097,31 @@ function makeBasicHeaders(config, opts) {
|
|
|
1016
1097
|
headers.set("Authorization", `Bearer ${getToken({ config })}`);
|
|
1017
1098
|
}
|
|
1018
1099
|
}
|
|
1100
|
+
const cookie = headers.get("cookie");
|
|
1101
|
+
if (!cookie) {
|
|
1102
|
+
const contextCookie = getCookie();
|
|
1103
|
+
if (contextCookie) {
|
|
1104
|
+
headers.set("cookie", contextCookie);
|
|
1105
|
+
} else {
|
|
1106
|
+
if (!url.endsWith("/users")) {
|
|
1107
|
+
error(
|
|
1108
|
+
"Missing cookie header from request. Call nile.api.setContext(request) before making additional calls."
|
|
1109
|
+
);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1019
1113
|
if (config && config.api.secureCookies != null) {
|
|
1020
1114
|
headers.set(X_NILE_SECURECOOKIES, String(config.api.secureCookies));
|
|
1021
1115
|
}
|
|
1116
|
+
const savedOrigin = getOrigin();
|
|
1022
1117
|
if (config && config.api.origin) {
|
|
1023
1118
|
headers.set(X_NILE_ORIGIN, config.api.origin);
|
|
1119
|
+
} else if (savedOrigin) {
|
|
1120
|
+
headers.set(X_NILE_ORIGIN, savedOrigin);
|
|
1121
|
+
} else {
|
|
1122
|
+
warn(
|
|
1123
|
+
"nile.origin missing from header, which defaults to secure cookies only."
|
|
1124
|
+
);
|
|
1024
1125
|
}
|
|
1025
1126
|
return headers;
|
|
1026
1127
|
}
|
|
@@ -1029,7 +1130,7 @@ async function _fetch(config, path, opts) {
|
|
|
1029
1130
|
const url = `${config.api?.basePath}${path}`;
|
|
1030
1131
|
const headers = new Headers(opts?.headers);
|
|
1031
1132
|
const tenantId = getTenantFromHttp(headers, config);
|
|
1032
|
-
const basicHeaders = makeBasicHeaders(config, opts);
|
|
1133
|
+
const basicHeaders = makeBasicHeaders(config, url, opts);
|
|
1033
1134
|
updateTenantId(tenantId);
|
|
1034
1135
|
const userId = getUserFromHttp(headers, config);
|
|
1035
1136
|
updateUserId(userId);
|
|
@@ -1988,7 +2089,7 @@ function serverLogin(config, handlers) {
|
|
|
1988
2089
|
if (!authCookie) {
|
|
1989
2090
|
throw new Error("authentication failed");
|
|
1990
2091
|
}
|
|
1991
|
-
const
|
|
2092
|
+
const token = parseToken(loginRes?.headers);
|
|
1992
2093
|
if (!token) {
|
|
1993
2094
|
error("Unable to obtain auth token", { authCookie });
|
|
1994
2095
|
throw new Error("Server login failed");
|
|
@@ -2001,6 +2102,17 @@ function serverLogin(config, handlers) {
|
|
|
2001
2102
|
return [headers, loginRes];
|
|
2002
2103
|
};
|
|
2003
2104
|
}
|
|
2105
|
+
function parseToken(headers) {
|
|
2106
|
+
let authCookie = headers?.get("set-cookie");
|
|
2107
|
+
if (!authCookie) {
|
|
2108
|
+
authCookie = headers?.get("cookie");
|
|
2109
|
+
}
|
|
2110
|
+
if (!authCookie) {
|
|
2111
|
+
return void 0;
|
|
2112
|
+
}
|
|
2113
|
+
const [, token] = /((__Secure-)?nile\.session-token=[^;]+)/.exec(authCookie) ?? [];
|
|
2114
|
+
return token;
|
|
2115
|
+
}
|
|
2004
2116
|
var Auth = class extends Config {
|
|
2005
2117
|
headers;
|
|
2006
2118
|
resetHeaders;
|
|
@@ -2247,8 +2359,15 @@ var Users = class extends Config {
|
|
|
2247
2359
|
super(config);
|
|
2248
2360
|
this.headers = headers;
|
|
2249
2361
|
}
|
|
2250
|
-
|
|
2251
|
-
|
|
2362
|
+
usersUrl(user) {
|
|
2363
|
+
const params = new URLSearchParams();
|
|
2364
|
+
if (user.newTenantName) {
|
|
2365
|
+
params.set("newTenantName", user.newTenantName);
|
|
2366
|
+
}
|
|
2367
|
+
if (user.tenantId) {
|
|
2368
|
+
params.set("tenantId", user.tenantId);
|
|
2369
|
+
}
|
|
2370
|
+
return `/users?${params.size > 0 ? params : ""}`;
|
|
2252
2371
|
}
|
|
2253
2372
|
get tenantUsersUrl() {
|
|
2254
2373
|
return `/tenants/${this.tenantId ?? "{tenantId}"}/users`;
|
|
@@ -2273,10 +2392,10 @@ var Users = class extends Config {
|
|
|
2273
2392
|
}
|
|
2274
2393
|
return void 0;
|
|
2275
2394
|
}
|
|
2276
|
-
createUser = async (
|
|
2395
|
+
createUser = async (user, init) => {
|
|
2277
2396
|
const _requester = new Requester(this);
|
|
2278
2397
|
const _init = this.handleHeaders(init);
|
|
2279
|
-
return await _requester.post(
|
|
2398
|
+
return await _requester.post(user, this.usersUrl(user), _init);
|
|
2280
2399
|
};
|
|
2281
2400
|
createTenantUser = async (req, init) => {
|
|
2282
2401
|
const _requester = new Requester(this);
|
|
@@ -2421,6 +2540,7 @@ var Api = class {
|
|
|
2421
2540
|
};
|
|
2422
2541
|
resetHeaders = (headers) => {
|
|
2423
2542
|
this.#headers = new Headers(headers ?? {});
|
|
2543
|
+
setContext(new Headers());
|
|
2424
2544
|
this.reset();
|
|
2425
2545
|
};
|
|
2426
2546
|
set headers(headers) {
|
|
@@ -2450,12 +2570,21 @@ var Api = class {
|
|
|
2450
2570
|
get headers() {
|
|
2451
2571
|
return this.#headers;
|
|
2452
2572
|
}
|
|
2573
|
+
getCookie(req) {
|
|
2574
|
+
if (req instanceof Headers) {
|
|
2575
|
+
return parseToken(req);
|
|
2576
|
+
} else if (req instanceof Request) {
|
|
2577
|
+
return parseToken(req.headers);
|
|
2578
|
+
}
|
|
2579
|
+
return null;
|
|
2580
|
+
}
|
|
2453
2581
|
login = async (payload, config) => {
|
|
2454
2582
|
const [headers, loginRes] = await serverLogin(
|
|
2455
2583
|
this.config,
|
|
2456
2584
|
this.handlers
|
|
2457
2585
|
)(payload);
|
|
2458
2586
|
this.headers = headers;
|
|
2587
|
+
this.setContext(headers);
|
|
2459
2588
|
if (config?.returnResponse) {
|
|
2460
2589
|
return loginRes;
|
|
2461
2590
|
}
|
|
@@ -2469,6 +2598,17 @@ var Api = class {
|
|
|
2469
2598
|
}
|
|
2470
2599
|
return this.auth.getSession(this.#headers);
|
|
2471
2600
|
};
|
|
2601
|
+
setContext = (req) => {
|
|
2602
|
+
if (req instanceof Headers) {
|
|
2603
|
+
setContext(req);
|
|
2604
|
+
} else if (req instanceof Request) {
|
|
2605
|
+
setContext(req.headers);
|
|
2606
|
+
}
|
|
2607
|
+
const { warn } = Logger(this.config, "[API]");
|
|
2608
|
+
if (warn) {
|
|
2609
|
+
warn("Set context expects a Request or Header object");
|
|
2610
|
+
}
|
|
2611
|
+
};
|
|
2472
2612
|
};
|
|
2473
2613
|
|
|
2474
2614
|
// src/Server.ts
|