@travetto/web 7.0.0-rc.2 → 7.0.0-rc.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/README.md +8 -8
- package/package.json +10 -10
- package/src/decorator/common.ts +4 -4
- package/src/decorator/endpoint.ts +5 -5
- package/src/decorator/param.ts +3 -3
- package/src/interceptor/accept.ts +5 -5
- package/src/interceptor/body.ts +2 -2
- package/src/interceptor/compress.ts +2 -2
- package/src/interceptor/cookie.ts +1 -1
- package/src/interceptor/cors.ts +4 -4
- package/src/interceptor/logging.ts +4 -4
- package/src/interceptor/respond.ts +5 -5
- package/src/registry/registry-adapter.ts +26 -26
- package/src/registry/registry-index.ts +13 -27
- package/src/registry/types.ts +9 -15
- package/src/registry/visitor.ts +5 -6
- package/src/router/base.ts +10 -27
- package/src/router/standard.ts +5 -11
- package/src/types/core.ts +2 -2
- package/src/types/dispatch.ts +1 -1
- package/src/types/headers.ts +16 -16
- package/src/types/message.ts +4 -4
- package/src/types/response.ts +4 -4
- package/src/util/body.ts +20 -20
- package/src/util/common.ts +20 -20
- package/src/util/cookie.ts +9 -9
- package/src/util/endpoint.ts +52 -58
- package/src/util/header.ts +40 -37
- package/src/util/keygrip.ts +1 -1
- package/src/util/net.ts +15 -15
- package/support/test/dispatch-util.ts +2 -2
- package/support/test/suite/base.ts +2 -2
- package/support/test/suite/standard.ts +2 -8
package/src/router/base.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Class, toConcrete } from '@travetto/runtime';
|
|
2
2
|
import { DependencyRegistryIndex, Injectable } from '@travetto/di';
|
|
3
3
|
import { ControllerRegistryIndex } from '@travetto/web';
|
|
4
|
-
import { Registry } from '@travetto/registry';
|
|
5
4
|
|
|
6
5
|
import { ControllerConfig, EndpointConfig } from '../registry/types.ts';
|
|
7
6
|
import type { WebRouter } from '../types/dispatch.ts';
|
|
@@ -17,21 +16,19 @@ import { EndpointUtil } from '../util/endpoint.ts';
|
|
|
17
16
|
@Injectable()
|
|
18
17
|
export abstract class BaseWebRouter implements WebRouter {
|
|
19
18
|
|
|
20
|
-
#cleanup = new Map<string, Function>();
|
|
21
19
|
#interceptors: WebInterceptor[];
|
|
22
20
|
|
|
23
|
-
async #register(
|
|
24
|
-
const config = ControllerRegistryIndex.getConfig(
|
|
21
|
+
async #register(cls: Class): Promise<void> {
|
|
22
|
+
const config = ControllerRegistryIndex.getConfig(cls);
|
|
25
23
|
|
|
26
|
-
let endpoints = await EndpointUtil.getBoundEndpoints(
|
|
24
|
+
let endpoints = await EndpointUtil.getBoundEndpoints(cls);
|
|
27
25
|
endpoints = EndpointUtil.orderEndpoints(endpoints);
|
|
28
26
|
|
|
29
|
-
for (const
|
|
30
|
-
|
|
27
|
+
for (const endpoint of endpoints) {
|
|
28
|
+
endpoint.filter = EndpointUtil.createEndpointHandler(this.#interceptors, endpoint, config);
|
|
31
29
|
}
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
this.#cleanup.set(c.Ⲑid, fn);
|
|
31
|
+
await this.register(endpoints, config);
|
|
35
32
|
};
|
|
36
33
|
|
|
37
34
|
/**
|
|
@@ -41,29 +38,15 @@ export abstract class BaseWebRouter implements WebRouter {
|
|
|
41
38
|
|
|
42
39
|
this.#interceptors = await DependencyRegistryIndex.getInstances(toConcrete<WebInterceptor>());
|
|
43
40
|
this.#interceptors = EndpointUtil.orderInterceptors(this.#interceptors);
|
|
44
|
-
const names = this.#interceptors.map(
|
|
41
|
+
const names = this.#interceptors.map(interceptor => interceptor.constructor.name);
|
|
45
42
|
console.debug('Sorting interceptors', { count: names.length, names });
|
|
46
43
|
|
|
47
44
|
// Register all active
|
|
48
|
-
for (const
|
|
49
|
-
await this.#register(
|
|
45
|
+
for (const cls of ControllerRegistryIndex.getClasses()) {
|
|
46
|
+
await this.#register(cls);
|
|
50
47
|
}
|
|
51
|
-
|
|
52
|
-
// Listen for updates
|
|
53
|
-
Registry.onClassChange(async e => {
|
|
54
|
-
const targetCls = 'curr' in e ? e.curr : e.prev;
|
|
55
|
-
console.debug('Registry event', { type: e.type, target: targetCls.Ⲑid });
|
|
56
|
-
|
|
57
|
-
if ('prev' in e) {
|
|
58
|
-
this.#cleanup.get(e.prev.Ⲑid)?.();
|
|
59
|
-
this.#cleanup.delete(e.prev.Ⲑid);
|
|
60
|
-
}
|
|
61
|
-
if ('curr' in e) {
|
|
62
|
-
await this.#register(e.curr);
|
|
63
|
-
}
|
|
64
|
-
}, ControllerRegistryIndex);
|
|
65
48
|
}
|
|
66
49
|
|
|
67
|
-
abstract register(endpoints: EndpointConfig[], controller: ControllerConfig): Promise<
|
|
50
|
+
abstract register(endpoints: EndpointConfig[], controller: ControllerConfig): Promise<void>;
|
|
68
51
|
abstract dispatch(ctx: WebFilterContext): Promise<WebResponse>;
|
|
69
52
|
}
|
package/src/router/standard.ts
CHANGED
|
@@ -26,19 +26,13 @@ export class StandardWebRouter extends BaseWebRouter {
|
|
|
26
26
|
#cache = new Map<Function, EndpointConfig>();
|
|
27
27
|
raw = router();
|
|
28
28
|
|
|
29
|
-
async register(endpoints: EndpointConfig[]): Promise<
|
|
30
|
-
for (const
|
|
31
|
-
const fullPath =
|
|
29
|
+
async register(endpoints: EndpointConfig[]): Promise<void> {
|
|
30
|
+
for (const endpoint of endpoints) {
|
|
31
|
+
const fullPath = endpoint.fullPath.replace(/[*][^*]+/g, '*'); // Flatten wildcards
|
|
32
32
|
const handler = (): void => { };
|
|
33
|
-
this.#cache.set(handler,
|
|
34
|
-
this.raw[HTTP_METHODS[
|
|
33
|
+
this.#cache.set(handler, endpoint);
|
|
34
|
+
this.raw[HTTP_METHODS[endpoint.httpMethod ?? DEFAULT_HTTP_METHOD].lower](fullPath, handler);
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
return (): void => {
|
|
38
|
-
for (const ep of endpoints ?? []) {
|
|
39
|
-
this.raw.off(ep.httpMethod ?? DEFAULT_HTTP_METHOD, ep.fullPath);
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
36
|
}
|
|
43
37
|
|
|
44
38
|
/**
|
package/src/types/core.ts
CHANGED
|
@@ -3,8 +3,8 @@ function verb<
|
|
|
3
3
|
M extends string,
|
|
4
4
|
L extends string,
|
|
5
5
|
C extends Partial<MethodConfig>
|
|
6
|
-
>(method: M, lower: L,
|
|
7
|
-
return { body: false, cacheable: false, emptyStatusCode: 204, ...
|
|
6
|
+
>(method: M, lower: L, config: C): { method: M, lower: L } & C & MethodConfig {
|
|
7
|
+
return { body: false, cacheable: false, emptyStatusCode: 204, ...config, method, lower, };
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export const HTTP_METHODS = {
|
package/src/types/dispatch.ts
CHANGED
|
@@ -19,5 +19,5 @@ export interface WebRouter extends WebDispatcher {
|
|
|
19
19
|
/**
|
|
20
20
|
* Register a controller with the prepared endpoints
|
|
21
21
|
*/
|
|
22
|
-
register(endpoints: EndpointConfig[], controller: ControllerConfig): Promise<
|
|
22
|
+
register(endpoints: EndpointConfig[], controller: ControllerConfig): Promise<void>;
|
|
23
23
|
}
|
package/src/types/headers.ts
CHANGED
|
@@ -9,14 +9,14 @@ export type WebHeadersInit = Headers | Record<string, undefined | null | HeaderV
|
|
|
9
9
|
*/
|
|
10
10
|
export class WebHeaders extends Headers {
|
|
11
11
|
|
|
12
|
-
constructor(
|
|
13
|
-
const passed = (
|
|
14
|
-
super(passed ?
|
|
12
|
+
constructor(input?: WebHeadersInit) {
|
|
13
|
+
const passed = (input instanceof Headers);
|
|
14
|
+
super(passed ? input : undefined);
|
|
15
15
|
|
|
16
|
-
if (
|
|
17
|
-
for (const [
|
|
18
|
-
if (
|
|
19
|
-
this.append(
|
|
16
|
+
if (input && !passed) {
|
|
17
|
+
for (const [key, value] of (Array.isArray(input) ? input : Object.entries(input))) {
|
|
18
|
+
if (value !== undefined && value !== null && !key.startsWith(':')) {
|
|
19
|
+
this.append(key, castTo(value));
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -33,21 +33,21 @@ export class WebHeaders extends Headers {
|
|
|
33
33
|
* Get a header value as a list, breaking on commas except for cookies
|
|
34
34
|
*/
|
|
35
35
|
getList(key: string): string[] | undefined {
|
|
36
|
-
const
|
|
37
|
-
if (!
|
|
36
|
+
const value = this.get(key);
|
|
37
|
+
if (!value) {
|
|
38
38
|
return;
|
|
39
|
-
} else if (
|
|
39
|
+
} else if (value.toLowerCase() === 'set-cookie') {
|
|
40
40
|
return this.getSetCookie();
|
|
41
41
|
}
|
|
42
|
-
return
|
|
42
|
+
return value.split(key === 'cookie' ? /\s{0,3};\s{0,3}/ : /\s{0,3},\s{0,3}/);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// @ts-expect-error
|
|
46
|
-
forEach(set: (
|
|
47
|
-
forEach(set: (
|
|
48
|
-
forEach(set: (
|
|
49
|
-
for (const [
|
|
50
|
-
set(
|
|
46
|
+
forEach(set: (value: string | string[], key: string, headers: WebHeaders) => void): void;
|
|
47
|
+
forEach(set: (value: Any, key: string, headers: WebHeaders) => void): void;
|
|
48
|
+
forEach(set: (value: string | string[], key: string, headers: WebHeaders) => void): void {
|
|
49
|
+
for (const [key, value] of this.entries()) {
|
|
50
|
+
set(key === 'set-cookie' ? this.getSetCookie() : value, key, this);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
package/src/types/message.ts
CHANGED
|
@@ -25,9 +25,9 @@ export class BaseWebMessage<B = unknown, C = unknown> implements WebMessage<B, C
|
|
|
25
25
|
readonly headers: WebHeaders;
|
|
26
26
|
body?: B;
|
|
27
27
|
|
|
28
|
-
constructor(
|
|
29
|
-
this.context =
|
|
30
|
-
this.headers = new WebHeaders(
|
|
31
|
-
this.body =
|
|
28
|
+
constructor(input: WebMessageInit<B, C> = {}) {
|
|
29
|
+
this.context = input.context ?? castTo<C>({});
|
|
30
|
+
this.headers = new WebHeaders(input.headers);
|
|
31
|
+
this.body = input.body;
|
|
32
32
|
}
|
|
33
33
|
}
|
package/src/types/response.ts
CHANGED
|
@@ -12,10 +12,10 @@ export interface WebResponseContext {
|
|
|
12
12
|
export class WebResponse<B = unknown> extends BaseWebMessage<B, WebResponseContext> {
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
* Build the redirect
|
|
16
|
+
* @param location Location to redirect to
|
|
17
|
+
* @param statusCode Status code
|
|
18
|
+
*/
|
|
19
19
|
static redirect(location: string, statusCode = 302): WebResponse<undefined> {
|
|
20
20
|
return new WebResponse({ context: { httpStatusCode: statusCode }, headers: { Location: location } });
|
|
21
21
|
}
|
package/src/util/body.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TextDecoder } from 'node:util';
|
|
2
2
|
import { Readable } from 'node:stream';
|
|
3
3
|
|
|
4
|
-
import { Any, BinaryUtil, castTo, hasToJSON, Util } from '@travetto/runtime';
|
|
4
|
+
import { Any, BinaryUtil, castTo, hasToJSON, JSONUtil, Util } from '@travetto/runtime';
|
|
5
5
|
|
|
6
6
|
import { WebBinaryBody, WebMessage } from '../types/message.ts';
|
|
7
7
|
import { WebHeaders } from '../types/headers.ts';
|
|
@@ -19,13 +19,13 @@ export class WebBodyUtil {
|
|
|
19
19
|
*/
|
|
20
20
|
static async * buildMultiPartBody(form: FormData, boundary: string): AsyncIterable<string | Buffer> {
|
|
21
21
|
const nl = '\r\n';
|
|
22
|
-
for (const [
|
|
23
|
-
const data =
|
|
22
|
+
for (const [key, value] of form.entries()) {
|
|
23
|
+
const data = value.slice();
|
|
24
24
|
const filename = data instanceof File ? data.name : undefined;
|
|
25
25
|
const size = data instanceof Blob ? data.size : data.length;
|
|
26
26
|
const type = data instanceof Blob ? data.type : undefined;
|
|
27
27
|
yield `--${boundary}${nl}`;
|
|
28
|
-
yield `Content-Disposition: form-data; name="${
|
|
28
|
+
yield `Content-Disposition: form-data; name="${key}"; filename="${filename ?? key}"${nl}`;
|
|
29
29
|
yield `Content-Length: ${size}${nl}`;
|
|
30
30
|
if (type) {
|
|
31
31
|
yield `Content-Type: ${type}${nl}`;
|
|
@@ -66,7 +66,7 @@ export class WebBodyUtil {
|
|
|
66
66
|
toAdd.push(['Content-disposition', `attachment; filename="${value.name}"`]);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
return toAdd.filter((
|
|
69
|
+
return toAdd.filter((pair): pair is [string, string] => !!pair[1]);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
|
@@ -97,8 +97,8 @@ export class WebBodyUtil {
|
|
|
97
97
|
|
|
98
98
|
const out: Omit<WebMessage<WebBinaryBody>, 'context'> = { headers: new WebHeaders(message.headers), body: null! };
|
|
99
99
|
if (body instanceof Blob) {
|
|
100
|
-
for (const [
|
|
101
|
-
out.headers.set(
|
|
100
|
+
for (const [key, value] of this.getBlobHeaders(body)) {
|
|
101
|
+
out.headers.set(key, value);
|
|
102
102
|
}
|
|
103
103
|
out.body = Readable.fromWeb(body.stream());
|
|
104
104
|
} else if (body instanceof FormData) {
|
|
@@ -139,29 +139,29 @@ export class WebBodyUtil {
|
|
|
139
139
|
/**
|
|
140
140
|
* Set body and mark as unprocessed
|
|
141
141
|
*/
|
|
142
|
-
static markRaw(
|
|
143
|
-
if (
|
|
144
|
-
Object.defineProperty(
|
|
142
|
+
static markRaw(body: WebBinaryBody | undefined): typeof body {
|
|
143
|
+
if (body) {
|
|
144
|
+
Object.defineProperty(body, WebRawStreamSymbol, { value: body });
|
|
145
145
|
}
|
|
146
|
-
return
|
|
146
|
+
return body;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
/**
|
|
150
150
|
* Is the input raw
|
|
151
151
|
*/
|
|
152
|
-
static isRaw(
|
|
152
|
+
static isRaw(body: unknown): body is WebBinaryBody {
|
|
153
153
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
154
|
-
return !!
|
|
154
|
+
return !!body && ((Buffer.isBuffer(body) || BinaryUtil.isReadable(body)) && (body as Any)[WebRawStreamSymbol] === body);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
/**
|
|
158
158
|
* Simple parse support
|
|
159
159
|
*/
|
|
160
|
-
static parseBody(type: string,
|
|
160
|
+
static parseBody(type: string, body: string): unknown {
|
|
161
161
|
switch (type) {
|
|
162
|
-
case 'text': return
|
|
163
|
-
case 'json': return
|
|
164
|
-
case 'form': return Object.fromEntries(new URLSearchParams(
|
|
162
|
+
case 'text': return body;
|
|
163
|
+
case 'json': return JSONUtil.parseSafe(body);
|
|
164
|
+
case 'form': return Object.fromEntries(new URLSearchParams(body));
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
|
|
@@ -199,11 +199,11 @@ export class WebBodyUtil {
|
|
|
199
199
|
}
|
|
200
200
|
all.push(decoder.decode(Buffer.alloc(0), { stream: false }));
|
|
201
201
|
return { text: all.join(''), read: received };
|
|
202
|
-
} catch (
|
|
203
|
-
if (
|
|
202
|
+
} catch (error) {
|
|
203
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
204
204
|
throw WebError.for('Request Aborted', 400, { received });
|
|
205
205
|
} else {
|
|
206
|
-
throw
|
|
206
|
+
throw error;
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
}
|
package/src/util/common.ts
CHANGED
|
@@ -38,18 +38,18 @@ export class WebCommonUtil {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
static #buildEdgeMap<T, U extends OrderedState<T>>(items: List<U>): Map<T, Set<T>> {
|
|
41
|
-
const edgeMap = new Map(items.map(
|
|
41
|
+
const edgeMap = new Map(items.map(item => [item.key, new Set(item.after ?? [])]));
|
|
42
42
|
|
|
43
43
|
// Build out edge map
|
|
44
44
|
for (const input of items) {
|
|
45
|
-
for (const
|
|
46
|
-
if (edgeMap.has(
|
|
47
|
-
edgeMap.get(
|
|
45
|
+
for (const item of input.before ?? []) {
|
|
46
|
+
if (edgeMap.has(item)) {
|
|
47
|
+
edgeMap.get(item)!.add(input.key);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
const afterSet = edgeMap.get(input.key)!;
|
|
51
|
-
for (const
|
|
52
|
-
afterSet.add(
|
|
51
|
+
for (const item of input.after ?? []) {
|
|
52
|
+
afterSet.add(item);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
return edgeMap;
|
|
@@ -64,7 +64,7 @@ export class WebCommonUtil {
|
|
|
64
64
|
rules,
|
|
65
65
|
this.#convert.bind(this),
|
|
66
66
|
(regex, mime) => regex.test(mime),
|
|
67
|
-
|
|
67
|
+
key => key
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -94,8 +94,8 @@ export class WebCommonUtil {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
const inputMap = new Map(items.map(
|
|
98
|
-
return keys.map(
|
|
97
|
+
const inputMap = new Map(items.map(item => [item.key, item]));
|
|
98
|
+
return keys.map(key => inputMap.get(key)!);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
/**
|
|
@@ -110,18 +110,18 @@ export class WebCommonUtil {
|
|
|
110
110
|
/**
|
|
111
111
|
* From catch value
|
|
112
112
|
*/
|
|
113
|
-
static catchResponse(
|
|
114
|
-
if (
|
|
115
|
-
return
|
|
113
|
+
static catchResponse(error: unknown): WebResponse<Error> {
|
|
114
|
+
if (error instanceof WebResponse) {
|
|
115
|
+
return error;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
const body =
|
|
119
|
-
(!!
|
|
120
|
-
new AppError(
|
|
121
|
-
new AppError(`${
|
|
118
|
+
const body = error instanceof Error ? error :
|
|
119
|
+
(!!error && typeof error === 'object' && ('message' in error && typeof error.message === 'string')) ?
|
|
120
|
+
new AppError(error.message, { details: error }) :
|
|
121
|
+
new AppError(`${error}`);
|
|
122
122
|
|
|
123
|
-
const
|
|
124
|
-
const statusCode =
|
|
123
|
+
const webError: Error & Partial<WebError> = body;
|
|
124
|
+
const statusCode = webError.details?.statusCode ?? ERROR_CATEGORY_STATUS[webError.category!] ?? 500;
|
|
125
125
|
|
|
126
126
|
return new WebResponse({ body, context: { httpStatusCode: statusCode } });
|
|
127
127
|
}
|
|
@@ -147,7 +147,7 @@ export class WebCommonUtil {
|
|
|
147
147
|
if (typeof input === 'number') {
|
|
148
148
|
return input;
|
|
149
149
|
}
|
|
150
|
-
const [,
|
|
151
|
-
return parseInt(
|
|
150
|
+
const [, value, unit] = input.toLowerCase().split(/(\d+)/);
|
|
151
|
+
return parseInt(value, 10) * (UNIT_MAPPING[unit] ?? 1);
|
|
152
152
|
}
|
|
153
153
|
}
|
package/src/util/cookie.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { Cookie, CookieGetOptions, CookieSetOptions } from '../types/cookie.ts';
|
|
|
4
4
|
import { KeyGrip } from './keygrip.ts';
|
|
5
5
|
import { WebHeaderUtil } from './header.ts';
|
|
6
6
|
|
|
7
|
-
const pairText = (
|
|
8
|
-
const pair = (
|
|
7
|
+
const pairText = (cookie: Cookie): string => `${cookie.name}=${cookie.value}`;
|
|
8
|
+
const pair = (key: string, value: unknown): string => `${key}=${value}`;
|
|
9
9
|
|
|
10
10
|
type CookieJarOptions = { keys?: string[] } & CookieSetOptions;
|
|
11
11
|
|
|
@@ -66,13 +66,13 @@ export class CookieJar {
|
|
|
66
66
|
return this;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
has(name: string,
|
|
70
|
-
const needSigned =
|
|
69
|
+
has(name: string, options: CookieGetOptions = {}): boolean {
|
|
70
|
+
const needSigned = options.signed ?? this.#setOptions.signed;
|
|
71
71
|
return name in this.#cookies && this.#cookies[name].signed === needSigned;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
get(name: string,
|
|
75
|
-
if (this.has(name,
|
|
74
|
+
get(name: string, options: CookieGetOptions = {}): string | undefined {
|
|
75
|
+
if (this.has(name, options)) {
|
|
76
76
|
return this.#cookies[name]?.value;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -111,12 +111,12 @@ export class CookieJar {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
exportCookieHeader(): string {
|
|
114
|
-
return this.getAll().flatMap(
|
|
114
|
+
return this.getAll().flatMap(cookie => this.#exportCookie(cookie)).join('; ');
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
exportSetCookieHeader(): string[] {
|
|
118
118
|
return this.getAll()
|
|
119
|
-
.filter(
|
|
120
|
-
.flatMap(
|
|
119
|
+
.filter(cookie => cookie.response)
|
|
120
|
+
.flatMap(cookie => this.#exportCookie(cookie, true));
|
|
121
121
|
}
|
|
122
122
|
}
|