@niledatabase/server 5.0.0-alpha.27 → 5.0.0-alpha.29
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.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +202 -157
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +202 -157
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -125,139 +125,6 @@ function isUUID(value) {
|
|
|
125
125
|
return regex.test(value);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
// src/api/utils/request.ts
|
|
129
|
-
async function request(url, _init, config) {
|
|
130
|
-
const { debug, info, error } = config.logger("[REQUEST]");
|
|
131
|
-
const { request: request2, ...init } = _init;
|
|
132
|
-
const requestUrl = new URL(request2.url);
|
|
133
|
-
const updatedHeaders = new Headers({});
|
|
134
|
-
if (request2.headers.get("cookie")) {
|
|
135
|
-
updatedHeaders.set("cookie", String(request2.headers.get("cookie")));
|
|
136
|
-
}
|
|
137
|
-
if (request2.headers.get(TENANT_COOKIE)) {
|
|
138
|
-
updatedHeaders.set(
|
|
139
|
-
TENANT_COOKIE,
|
|
140
|
-
String(request2.headers.get(TENANT_COOKIE))
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
if (config.secureCookies != null) {
|
|
144
|
-
updatedHeaders.set(HEADER_SECURE_COOKIES, String(config.secureCookies));
|
|
145
|
-
} else {
|
|
146
|
-
updatedHeaders.set(
|
|
147
|
-
HEADER_SECURE_COOKIES,
|
|
148
|
-
process.env.NODE_ENV === "production" ? "true" : "false"
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
updatedHeaders.set("host", requestUrl.host);
|
|
152
|
-
if (config.callbackUrl) {
|
|
153
|
-
const cbUrl = new URL(config.callbackUrl);
|
|
154
|
-
debug(`Obtained origin from config.callbackUrl ${config.callbackUrl}`);
|
|
155
|
-
updatedHeaders.set(HEADER_ORIGIN, cbUrl.origin);
|
|
156
|
-
} else if (config.origin) {
|
|
157
|
-
debug(`Obtained origin from config.origin ${config.origin}`);
|
|
158
|
-
updatedHeaders.set(HEADER_ORIGIN, config.origin);
|
|
159
|
-
} else {
|
|
160
|
-
const passedOrigin = request2.headers.get(HEADER_ORIGIN);
|
|
161
|
-
if (passedOrigin) {
|
|
162
|
-
updatedHeaders.set(HEADER_ORIGIN, passedOrigin);
|
|
163
|
-
} else {
|
|
164
|
-
const reqOrigin = config.routePrefix !== DEFAULT_PREFIX ? `${requestUrl.origin}${config.routePrefix}` : requestUrl.origin;
|
|
165
|
-
updatedHeaders.set(HEADER_ORIGIN, reqOrigin);
|
|
166
|
-
debug(`Obtained origin from request ${reqOrigin}`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
const params = { ...init };
|
|
170
|
-
if (params.method?.toLowerCase() === "post" || params.method?.toLowerCase() === "put") {
|
|
171
|
-
try {
|
|
172
|
-
updatedHeaders.set("content-type", "application/json");
|
|
173
|
-
const bodyStream = _init.body ?? _init.request?.body ?? request2.body;
|
|
174
|
-
const bodyText = await new Response(bodyStream).text();
|
|
175
|
-
try {
|
|
176
|
-
params.body = JSON.stringify(JSON.parse(bodyText));
|
|
177
|
-
} catch {
|
|
178
|
-
updatedHeaders.set("content-type", "application/x-www-form-urlencoded");
|
|
179
|
-
params.body = bodyText;
|
|
180
|
-
}
|
|
181
|
-
} catch (e) {
|
|
182
|
-
error("Failed to parse request body");
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
params.headers = updatedHeaders;
|
|
186
|
-
const fullUrl = `${url}${requestUrl.search}`;
|
|
187
|
-
if (config.debug) {
|
|
188
|
-
params.headers.set("request-id", crypto.randomUUID());
|
|
189
|
-
params.cache = "no-store";
|
|
190
|
-
}
|
|
191
|
-
await config.extensionCtx?.runExtensions(
|
|
192
|
-
"onRequest" /* onRequest */,
|
|
193
|
-
config,
|
|
194
|
-
params,
|
|
195
|
-
_init
|
|
196
|
-
);
|
|
197
|
-
try {
|
|
198
|
-
const res = await fetch(fullUrl, {
|
|
199
|
-
...params
|
|
200
|
-
}).catch((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
|
-
const loggingRes = typeof res?.clone === "function" ? res?.clone() : null;
|
|
211
|
-
info(`[${params.method ?? "GET"}] ${fullUrl}`, {
|
|
212
|
-
status: res?.status,
|
|
213
|
-
statusText: res?.statusText,
|
|
214
|
-
text: await loggingRes?.text()
|
|
215
|
-
});
|
|
216
|
-
const updatedRes = await config.extensionCtx?.runExtensions(
|
|
217
|
-
"onResponse" /* onResponse */,
|
|
218
|
-
config,
|
|
219
|
-
{ ...params, response: res }
|
|
220
|
-
);
|
|
221
|
-
if (updatedRes) {
|
|
222
|
-
return updatedRes;
|
|
223
|
-
}
|
|
224
|
-
return res;
|
|
225
|
-
} catch (e) {
|
|
226
|
-
if (e instanceof Error) {
|
|
227
|
-
error("An error has occurred in the fetch", {
|
|
228
|
-
message: e.message,
|
|
229
|
-
stack: e.stack
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
return new Response(
|
|
233
|
-
"An unexpected (most likely configuration) problem has occurred",
|
|
234
|
-
{ status: 500 }
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// src/api/utils/auth.ts
|
|
240
|
-
async function auth(req, config) {
|
|
241
|
-
const { info, error } = config.logger("[nileauth]");
|
|
242
|
-
info("checking auth");
|
|
243
|
-
const sessionUrl = `${config.apiUrl}/auth/session`;
|
|
244
|
-
info(`using session ${sessionUrl}`);
|
|
245
|
-
req.headers.delete("content-length");
|
|
246
|
-
const res = await request(sessionUrl, { request: req }, config);
|
|
247
|
-
try {
|
|
248
|
-
const session = await new Response(res.body).json();
|
|
249
|
-
if (Object.keys(session).length === 0) {
|
|
250
|
-
info("no session found");
|
|
251
|
-
return void 0;
|
|
252
|
-
}
|
|
253
|
-
info("session active");
|
|
254
|
-
return session;
|
|
255
|
-
} catch (e) {
|
|
256
|
-
error(e);
|
|
257
|
-
return void 0;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
128
|
// src/utils/Logger.ts
|
|
262
129
|
var red = "\x1B[31m";
|
|
263
130
|
var yellow = "\x1B[38;2;255;255;0m";
|
|
@@ -471,8 +338,17 @@ var ctx = {
|
|
|
471
338
|
if (partial.headers === null) {
|
|
472
339
|
store.headers = new Headers();
|
|
473
340
|
} else if (partial.headers && store.headers instanceof Headers) {
|
|
474
|
-
for (const [
|
|
475
|
-
|
|
341
|
+
for (const [key17, value] of new Headers(partial.headers).entries()) {
|
|
342
|
+
if (key17.toLowerCase() === "cookie") {
|
|
343
|
+
const existingCookies = parseCookieHeader(
|
|
344
|
+
store.headers.get("cookie") || ""
|
|
345
|
+
);
|
|
346
|
+
const newCookies = parseCookieHeader(value);
|
|
347
|
+
const mergedCookies = { ...existingCookies, ...newCookies };
|
|
348
|
+
store.headers.set("cookie", serializeCookies(mergedCookies));
|
|
349
|
+
} else {
|
|
350
|
+
store.headers.set(key17, value);
|
|
351
|
+
}
|
|
476
352
|
}
|
|
477
353
|
}
|
|
478
354
|
if ("tenantId" in partial)
|
|
@@ -537,6 +413,170 @@ function serializeContext(context) {
|
|
|
537
413
|
preserveHeaders: context.preserveHeaders
|
|
538
414
|
});
|
|
539
415
|
}
|
|
416
|
+
function parseCookieHeader(header) {
|
|
417
|
+
return header.split(";").map((c) => c.trim()).filter(Boolean).reduce((acc, curr) => {
|
|
418
|
+
const [key17, ...val] = curr.split("=");
|
|
419
|
+
if (key17) acc[key17] = val.join("=");
|
|
420
|
+
return acc;
|
|
421
|
+
}, {});
|
|
422
|
+
}
|
|
423
|
+
function serializeCookies(cookies) {
|
|
424
|
+
return Object.entries(cookies).map(([k, v]) => `${k}=${v}`).join("; ");
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// src/api/utils/request.ts
|
|
428
|
+
async function request(url, _init, config) {
|
|
429
|
+
const { debug, info, error, warn: warn2 } = config.logger("[REQUEST]");
|
|
430
|
+
const { request: request2, ...init } = _init;
|
|
431
|
+
const requestUrl = new URL(request2.url);
|
|
432
|
+
const updatedHeaders = new Headers({});
|
|
433
|
+
if (request2.headers.get("cookie")) {
|
|
434
|
+
updatedHeaders.set("cookie", String(request2.headers.get("cookie")));
|
|
435
|
+
}
|
|
436
|
+
if (request2.headers.get(TENANT_COOKIE)) {
|
|
437
|
+
updatedHeaders.set(
|
|
438
|
+
TENANT_COOKIE,
|
|
439
|
+
String(request2.headers.get(TENANT_COOKIE))
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
if (config.secureCookies != null) {
|
|
443
|
+
updatedHeaders.set(HEADER_SECURE_COOKIES, String(config.secureCookies));
|
|
444
|
+
} else {
|
|
445
|
+
updatedHeaders.set(
|
|
446
|
+
HEADER_SECURE_COOKIES,
|
|
447
|
+
process.env.NODE_ENV === "production" ? "true" : "false"
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
updatedHeaders.set("host", requestUrl.host);
|
|
451
|
+
if (config.callbackUrl) {
|
|
452
|
+
const cbUrl = new URL(config.callbackUrl);
|
|
453
|
+
debug(`Obtained origin from config.callbackUrl ${config.callbackUrl}`);
|
|
454
|
+
updatedHeaders.set(HEADER_ORIGIN, cbUrl.origin);
|
|
455
|
+
} else if (config.origin) {
|
|
456
|
+
debug(`Obtained origin from config.origin ${config.origin}`);
|
|
457
|
+
updatedHeaders.set(HEADER_ORIGIN, config.origin);
|
|
458
|
+
} else {
|
|
459
|
+
const passedOrigin = request2.headers.get(HEADER_ORIGIN);
|
|
460
|
+
if (passedOrigin) {
|
|
461
|
+
updatedHeaders.set(HEADER_ORIGIN, passedOrigin);
|
|
462
|
+
} else {
|
|
463
|
+
const { headers } = ctx.get();
|
|
464
|
+
const host = headers.get("host");
|
|
465
|
+
if (host) {
|
|
466
|
+
const serverSideOrigin = `${getProtocolFromHeaders(headers)}://${host}`;
|
|
467
|
+
updatedHeaders.set(HEADER_ORIGIN, serverSideOrigin);
|
|
468
|
+
debug(`Obtained origin from server side headers ${serverSideOrigin}`);
|
|
469
|
+
} else {
|
|
470
|
+
const reqOrigin = config.routePrefix !== DEFAULT_PREFIX ? `${requestUrl.origin}${config.routePrefix}` : requestUrl.origin;
|
|
471
|
+
updatedHeaders.set(HEADER_ORIGIN, reqOrigin);
|
|
472
|
+
debug(`Obtained origin from request ${reqOrigin}`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
const params = { ...init };
|
|
477
|
+
if (params.method?.toLowerCase() === "post" || params.method?.toLowerCase() === "put") {
|
|
478
|
+
try {
|
|
479
|
+
updatedHeaders.set("content-type", "application/json");
|
|
480
|
+
const bodyStream = _init.body ?? _init.request?.body ?? request2.body;
|
|
481
|
+
const bodyText = await new Response(bodyStream).text();
|
|
482
|
+
try {
|
|
483
|
+
params.body = JSON.stringify(JSON.parse(bodyText));
|
|
484
|
+
} catch {
|
|
485
|
+
updatedHeaders.set("content-type", "application/x-www-form-urlencoded");
|
|
486
|
+
params.body = bodyText;
|
|
487
|
+
}
|
|
488
|
+
} catch (e) {
|
|
489
|
+
error("Failed to parse request body");
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
params.headers = updatedHeaders;
|
|
493
|
+
const fullUrl = `${url}${requestUrl.search}`;
|
|
494
|
+
if (config.debug) {
|
|
495
|
+
params.headers.set("request-id", crypto.randomUUID());
|
|
496
|
+
params.cache = "no-store";
|
|
497
|
+
}
|
|
498
|
+
await config.extensionCtx?.runExtensions(
|
|
499
|
+
"onRequest" /* onRequest */,
|
|
500
|
+
config,
|
|
501
|
+
params,
|
|
502
|
+
_init
|
|
503
|
+
);
|
|
504
|
+
try {
|
|
505
|
+
const res = await fetch(fullUrl, {
|
|
506
|
+
...params
|
|
507
|
+
}).catch((e) => {
|
|
508
|
+
error("An error has occurred in the fetch", {
|
|
509
|
+
message: e.message,
|
|
510
|
+
stack: e.stack
|
|
511
|
+
});
|
|
512
|
+
return new Response(
|
|
513
|
+
"An unexpected (most likely configuration) problem has occurred",
|
|
514
|
+
{ status: 500 }
|
|
515
|
+
);
|
|
516
|
+
});
|
|
517
|
+
const loggingRes = typeof res?.clone === "function" ? res?.clone() : null;
|
|
518
|
+
info(`[${params.method ?? "GET"}] ${fullUrl}`, {
|
|
519
|
+
status: res?.status,
|
|
520
|
+
statusText: res?.statusText,
|
|
521
|
+
text: await loggingRes?.text()
|
|
522
|
+
});
|
|
523
|
+
const updatedRes = await config.extensionCtx?.runExtensions(
|
|
524
|
+
"onResponse" /* onResponse */,
|
|
525
|
+
config,
|
|
526
|
+
{ ...params, response: res }
|
|
527
|
+
);
|
|
528
|
+
if (updatedRes) {
|
|
529
|
+
return updatedRes;
|
|
530
|
+
}
|
|
531
|
+
return res;
|
|
532
|
+
} catch (e) {
|
|
533
|
+
if (e instanceof Error) {
|
|
534
|
+
error("An error has occurred in the fetch", {
|
|
535
|
+
message: e.message,
|
|
536
|
+
stack: e.stack
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
return new Response(
|
|
540
|
+
"An unexpected (most likely configuration) problem has occurred",
|
|
541
|
+
{ status: 500 }
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
function getProtocolFromHeaders(headers) {
|
|
546
|
+
const get = (key17) => headers instanceof Headers ? headers.get(key17) : headers[key17.toLowerCase()];
|
|
547
|
+
const xfp = get("x-forwarded-proto");
|
|
548
|
+
if (xfp) return xfp.toLowerCase();
|
|
549
|
+
const forwarded = get("forwarded");
|
|
550
|
+
if (forwarded) {
|
|
551
|
+
const match = forwarded.match(/proto=(https?)/i);
|
|
552
|
+
if (match) return match[1].toLowerCase();
|
|
553
|
+
}
|
|
554
|
+
const ref = get("referer") || get("origin");
|
|
555
|
+
if (ref && ref.startsWith("https")) return "https";
|
|
556
|
+
return "http";
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// src/api/utils/auth.ts
|
|
560
|
+
async function auth(req, config) {
|
|
561
|
+
const { info, error } = config.logger("[nileauth]");
|
|
562
|
+
info("checking auth");
|
|
563
|
+
const sessionUrl = `${config.apiUrl}/auth/session`;
|
|
564
|
+
info(`using session ${sessionUrl}`);
|
|
565
|
+
req.headers.delete("content-length");
|
|
566
|
+
const res = await request(sessionUrl, { request: req }, config);
|
|
567
|
+
try {
|
|
568
|
+
const session = await new Response(res.body).json();
|
|
569
|
+
if (Object.keys(session).length === 0) {
|
|
570
|
+
info("no session found");
|
|
571
|
+
return void 0;
|
|
572
|
+
}
|
|
573
|
+
info("session active");
|
|
574
|
+
return session;
|
|
575
|
+
} catch (e) {
|
|
576
|
+
error(e);
|
|
577
|
+
return void 0;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
540
580
|
|
|
541
581
|
// src/api/routes/me/index.ts
|
|
542
582
|
var key = "ME";
|
|
@@ -2688,7 +2728,7 @@ var Auth = class {
|
|
|
2688
2728
|
].filter(Boolean).join("; ");
|
|
2689
2729
|
const uHeaders = new Headers({ cookie });
|
|
2690
2730
|
updateHeaders(uHeaders);
|
|
2691
|
-
ctx.set({ headers: uHeaders });
|
|
2731
|
+
ctx.set({ headers: uHeaders, preserveHeaders: true });
|
|
2692
2732
|
} else {
|
|
2693
2733
|
error("Unable to set context after sign in", {
|
|
2694
2734
|
headers: signInRes.headers
|
|
@@ -2842,6 +2882,22 @@ async function obtainCsrf(config, rawResponse = false) {
|
|
|
2842
2882
|
}
|
|
2843
2883
|
}
|
|
2844
2884
|
|
|
2885
|
+
// src/utils/qualifyDomain.ts
|
|
2886
|
+
function fQUrl2(callbackUrl, path) {
|
|
2887
|
+
if (path.startsWith("/")) {
|
|
2888
|
+
if (callbackUrl) {
|
|
2889
|
+
const { origin } = new URL(callbackUrl);
|
|
2890
|
+
return `${origin}${path}`;
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
try {
|
|
2894
|
+
new URL(path);
|
|
2895
|
+
} catch {
|
|
2896
|
+
throw new Error("An invalid URL has been passed.");
|
|
2897
|
+
}
|
|
2898
|
+
return path;
|
|
2899
|
+
}
|
|
2900
|
+
|
|
2845
2901
|
// src/users/index.ts
|
|
2846
2902
|
var Users = class {
|
|
2847
2903
|
#config;
|
|
@@ -2911,7 +2967,10 @@ var Users = class {
|
|
|
2911
2967
|
async verifySelf(options, rawResponse = false) {
|
|
2912
2968
|
return withNileContext(this.#config, async () => {
|
|
2913
2969
|
const bypassEmail = typeof options === "object" && options?.bypassEmail === true;
|
|
2914
|
-
const callbackUrl =
|
|
2970
|
+
const callbackUrl = fQUrl2(
|
|
2971
|
+
defaultCallbackUrl2().callbackUrl,
|
|
2972
|
+
typeof options === "object" ? String(options.callbackUrl) : "/"
|
|
2973
|
+
);
|
|
2915
2974
|
let res;
|
|
2916
2975
|
try {
|
|
2917
2976
|
const me = await this.getSelf();
|
|
@@ -3170,7 +3229,6 @@ var Tenants = class {
|
|
|
3170
3229
|
return withNileContext(
|
|
3171
3230
|
this.#config,
|
|
3172
3231
|
async () => {
|
|
3173
|
-
await runExtensionContext(this.#config);
|
|
3174
3232
|
const { csrfToken } = await obtainCsrf(
|
|
3175
3233
|
this.#config
|
|
3176
3234
|
);
|
|
@@ -3182,11 +3240,12 @@ var Tenants = class {
|
|
|
3182
3240
|
if ("email" in req) {
|
|
3183
3241
|
identifier = req.email;
|
|
3184
3242
|
}
|
|
3243
|
+
const { callbackUrl: cbUrl } = defaultCallbackUrl3(this.#config);
|
|
3185
3244
|
if ("callbackUrl" in req) {
|
|
3186
|
-
callbackUrl = fQUrl2(req.callbackUrl ?? ""
|
|
3245
|
+
callbackUrl = fQUrl2(cbUrl, req.callbackUrl ?? "/");
|
|
3187
3246
|
}
|
|
3188
3247
|
if ("redirectUrl" in req) {
|
|
3189
|
-
redirectUrl = fQUrl2(req.redirectUrl ?? ""
|
|
3248
|
+
redirectUrl = fQUrl2(cbUrl, req.redirectUrl ?? "/");
|
|
3190
3249
|
}
|
|
3191
3250
|
}
|
|
3192
3251
|
const { headers } = ctx.get();
|
|
@@ -3219,8 +3278,8 @@ var Tenants = class {
|
|
|
3219
3278
|
throw new Error("The identifier and token are required.");
|
|
3220
3279
|
}
|
|
3221
3280
|
const { identifier, token } = req;
|
|
3222
|
-
const
|
|
3223
|
-
const callbackUrl =
|
|
3281
|
+
const { callbackUrl: cbUrl } = defaultCallbackUrl3(this.#config);
|
|
3282
|
+
const callbackUrl = fQUrl2(cbUrl, req?.callbackUrl ?? "/");
|
|
3224
3283
|
const res = await fetchInvite(
|
|
3225
3284
|
this.#config,
|
|
3226
3285
|
"PUT",
|
|
@@ -3288,21 +3347,6 @@ function defaultCallbackUrl3(config) {
|
|
|
3288
3347
|
}
|
|
3289
3348
|
return { callbackUrl: cb, redirectUrl: redirect };
|
|
3290
3349
|
}
|
|
3291
|
-
function fQUrl2(path, config) {
|
|
3292
|
-
if (path.startsWith("/")) {
|
|
3293
|
-
const { callbackUrl } = defaultCallbackUrl3(config);
|
|
3294
|
-
if (callbackUrl) {
|
|
3295
|
-
const { origin } = new URL(callbackUrl);
|
|
3296
|
-
return `${origin}${path}`;
|
|
3297
|
-
}
|
|
3298
|
-
}
|
|
3299
|
-
try {
|
|
3300
|
-
new URL(path);
|
|
3301
|
-
} catch {
|
|
3302
|
-
throw new Error("An invalid URL has been passed.");
|
|
3303
|
-
}
|
|
3304
|
-
return path;
|
|
3305
|
-
}
|
|
3306
3350
|
|
|
3307
3351
|
// src/api/handlers/withContext/index.ts
|
|
3308
3352
|
function handlersWithContext(config) {
|
|
@@ -3395,6 +3439,7 @@ var Server = class {
|
|
|
3395
3439
|
watchHeaders((headers) => {
|
|
3396
3440
|
if (headers) {
|
|
3397
3441
|
this.#config.context.headers = new Headers(headers);
|
|
3442
|
+
this.#config.context.preserveHeaders = true;
|
|
3398
3443
|
this.#reset();
|
|
3399
3444
|
}
|
|
3400
3445
|
});
|