@equinor/fusion-framework-module-http 8.1.0-next.0 → 8.1.1
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/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +6 -3
- package/CHANGELOG.md +0 -1321
- package/docs/client-configuration.md +0 -175
- package/docs/observable-patterns.md +0 -103
- package/docs/selectors-and-handlers.md +0 -112
- package/docs/server-sent-events.md +0 -125
- package/docs/testing.md +0 -78
- package/src/configurator.ts +0 -249
- package/src/errors/ClientNotFoundException.ts +0 -9
- package/src/errors/HttpJsonResponseError.ts +0 -32
- package/src/errors/HttpResponseError.ts +0 -21
- package/src/errors/ServerSentEventResponseError.ts +0 -30
- package/src/errors/index.ts +0 -4
- package/src/index.ts +0 -15
- package/src/lib/client/client-msal.ts +0 -80
- package/src/lib/client/client.ts +0 -496
- package/src/lib/client/index.ts +0 -4
- package/src/lib/client/types.ts +0 -244
- package/src/lib/index.ts +0 -3
- package/src/lib/operators/HttpMiddlewareHandler.ts +0 -58
- package/src/lib/operators/HttpRequestHandler.ts +0 -29
- package/src/lib/operators/HttpResponseHandler.ts +0 -11
- package/src/lib/operators/ProcessOperators.ts +0 -113
- package/src/lib/operators/capitalize-request-method-operator.ts +0 -26
- package/src/lib/operators/fetch-request.schemas.ts +0 -104
- package/src/lib/operators/index.ts +0 -9
- package/src/lib/operators/request-operator-header.ts +0 -19
- package/src/lib/operators/request-validation-operator.ts +0 -51
- package/src/lib/operators/sse-map.operator.ts +0 -45
- package/src/lib/operators/types.ts +0 -174
- package/src/lib/selectors/blob-selector.ts +0 -42
- package/src/lib/selectors/create-sse-selector.ts +0 -279
- package/src/lib/selectors/index.ts +0 -11
- package/src/lib/selectors/json-selector.ts +0 -52
- package/src/mock/create-open-api-mock-middleware.ts +0 -40
- package/src/mock/create-router-middleware.ts +0 -158
- package/src/mock/index.ts +0 -26
- package/src/mock/resolve-open-api-mock-response.ts +0 -36
- package/src/module.ts +0 -149
- package/src/provider.ts +0 -225
- package/src/version.ts +0 -2
- package/tests/HttpClient.test.ts +0 -173
- package/tests/HttpMiddlewareHandler.test.ts +0 -58
- package/tests/mock/adapters.test.ts +0 -62
- package/tests/mock/router-middleware.test.ts +0 -135
- package/tests/operators.test.ts +0 -137
- package/tests/sse.selector.test.ts +0 -162
- package/tsconfig.json +0 -18
- package/vitest.config.ts +0 -12
package/src/lib/client/types.ts
DELETED
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import type { ObservableInput, Observable } from 'rxjs';
|
|
2
|
-
import type { IHttpRequestHandler, IHttpResponseHandler } from '../operators/types';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Represents a stream of response data.
|
|
6
|
-
* @template T - The type of the response data.
|
|
7
|
-
*/
|
|
8
|
-
export type StreamResponse<T> = Observable<T>;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A function that takes a `Response` object and returns an `ObservableInput` of type `T`.
|
|
12
|
-
*
|
|
13
|
-
* @template TResult - The type of the data contained in the response.
|
|
14
|
-
* @template TResponse - The type of the response object.
|
|
15
|
-
* @param response - The `Response` object to be processed.
|
|
16
|
-
* @returns An `ObservableInput` of type `T`.
|
|
17
|
-
*/
|
|
18
|
-
export type ResponseSelector<TResult = unknown, TResponse = Response> = (
|
|
19
|
-
response: TResponse,
|
|
20
|
-
) => ObservableInput<TResult>;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Represents the parameters for a fetch request, including the URI and path.
|
|
24
|
-
* @property {string} uri - The URI of the request.
|
|
25
|
-
* @property {string} path - The path of the request.
|
|
26
|
-
*/
|
|
27
|
-
export type FetchRequest = RequestInit & {
|
|
28
|
-
uri: string;
|
|
29
|
-
path: string;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Represents a request with a JSON body.
|
|
34
|
-
* @template TRequest - The base request type, which extends `FetchRequest`.
|
|
35
|
-
* @property {object | string | null} [body] - The request body, which can be an object, a string, or null.
|
|
36
|
-
*/
|
|
37
|
-
export type JsonRequest<TRequest extends FetchRequest = FetchRequest> = Omit<TRequest, 'body'> & {
|
|
38
|
-
body?: object | string | null;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Represents the result of a blob operation, including the filename (if available) and the blob itself.
|
|
43
|
-
* @property {string} [filename] - The filename of the blob, if available.
|
|
44
|
-
* @property {Blob} blob - The blob data.
|
|
45
|
-
*/
|
|
46
|
-
export type BlobResult = { filename?: string; blob: Blob };
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Represents the response from a fetch request, including the response object and a JSON parsing method.
|
|
50
|
-
* @template T - The type of the response data.
|
|
51
|
-
* @property {Response} - The original Response object.
|
|
52
|
-
* @property {() => Promise<T>} json - A method to parse the response body as JSON and return the data as type T.
|
|
53
|
-
*/
|
|
54
|
-
export type FetchResponse<T = unknown> = Response & {
|
|
55
|
-
json(): Promise<T>;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Represents the parameters for a fetch request, including the URI and path, as well as a selector function to transform the response.
|
|
60
|
-
* @template TReturn - The type of the transformed response data.
|
|
61
|
-
* @template TRequest - The type of the fetch request.
|
|
62
|
-
* @template TResponse - The type of the fetch response.
|
|
63
|
-
*/
|
|
64
|
-
export type FetchRequestInit<
|
|
65
|
-
TReturn = unknown,
|
|
66
|
-
TRequest = FetchRequest,
|
|
67
|
-
TResponse = FetchResponse<TReturn>,
|
|
68
|
-
> = Omit<TRequest, 'uri' | 'path'> & {
|
|
69
|
-
/** response selector function */
|
|
70
|
-
selector?: ResponseSelector<TReturn, TResponse>;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Represents the parameters for a fetch request, including the URI and path, as well as a selector function to transform the response.
|
|
75
|
-
*
|
|
76
|
-
* @template TReturn - The type of the transformed response data.
|
|
77
|
-
* @template TRequest - The type of the fetch request.
|
|
78
|
-
* @template TResponse - The type of the fetch response.
|
|
79
|
-
*/
|
|
80
|
-
export type ClientRequestInit<T extends IHttpClient, TReturn = unknown> =
|
|
81
|
-
T extends IHttpClient<infer TRequest, infer TResponse>
|
|
82
|
-
? FetchRequestInit<TReturn, TRequest, TResponse>
|
|
83
|
-
: never;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Represents the available execution methods for an HTTP client.
|
|
87
|
-
*/
|
|
88
|
-
export type ExecutionMethod = 'fetch' | 'fetch$' | 'json' | 'json$';
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Represents the type of the parameters for the execution methods of an `IHttpClient` instance.
|
|
92
|
-
*
|
|
93
|
-
* @template TMethod - The execution method of the `IHttpClient` instance, e.g. 'fetch', 'json'.
|
|
94
|
-
* @template TClient - The type of the `IHttpClient` instance.
|
|
95
|
-
*/
|
|
96
|
-
export type ExecutionMethodParameters<
|
|
97
|
-
TMethod extends ExecutionMethod = 'fetch',
|
|
98
|
-
TClient extends IHttpClient = IHttpClient,
|
|
99
|
-
> = Parameters<TClient[TMethod]>;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Represents the type of the return value for the execution methods of an `IHttpClient` instance.
|
|
103
|
-
*
|
|
104
|
-
* @template TMethod - The execution method of the `IHttpClient` instance, e.g. 'fetch', 'json'.
|
|
105
|
-
* @template TClient - The type of the `IHttpClient` instance.
|
|
106
|
-
*/
|
|
107
|
-
export type ExecutionResponse<
|
|
108
|
-
TMethod extends ExecutionMethod = 'fetch',
|
|
109
|
-
TClient extends IHttpClient = IHttpClient,
|
|
110
|
-
> = ReturnType<TClient[TMethod]>;
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* @template TRequest request arguments @see {@link https://developer.mozilla.org/en-US/docs/Web/API/request|request}
|
|
114
|
-
* @template TResponse request arguments @see {@link https://developer.mozilla.org/en-US/docs/Web/API/response|response}
|
|
115
|
-
*/
|
|
116
|
-
export interface IHttpClient<TRequest extends FetchRequest = FetchRequest, TResponse = Response> {
|
|
117
|
-
uri: string;
|
|
118
|
-
/**
|
|
119
|
-
* A pre-processor for requests made by the `IHttpClient` interface.
|
|
120
|
-
* This handler can be used to modify the request before it is sent, such as adding headers, authentication, or other transformations.
|
|
121
|
-
*/
|
|
122
|
-
readonly requestHandler: IHttpRequestHandler<TRequest>;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* A post-processor for responses received by the `IHttpClient` interface.
|
|
126
|
-
* This handler can be used to transform the response data after it is received, such as parsing JSON, handling errors, or other transformations.
|
|
127
|
-
*/
|
|
128
|
-
readonly responseHandler: IHttpResponseHandler<TResponse>;
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Observable stream of requests made by the `IHttpClient` interface.
|
|
132
|
-
* This stream can be used to observe and potentially modify the requests before they are sent.
|
|
133
|
-
*/
|
|
134
|
-
readonly request$: Observable<TRequest>;
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Observable stream of responses received by the `IHttpClient` interface.
|
|
138
|
-
* This stream can be used to observe and potentially handle the responses after they are received.
|
|
139
|
-
*/
|
|
140
|
-
readonly response$: Observable<TResponse>;
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Fetch a resource as an observable stream.
|
|
144
|
-
* This method simplifies the execution of a request and returns an observable stream of the response.
|
|
145
|
-
* The request will not be executed until the observable is subscribed to.
|
|
146
|
-
*
|
|
147
|
-
* @template T - The expected response type.
|
|
148
|
-
* @param path - The path to fetch the resource from.
|
|
149
|
-
* @param init - Optional request initialization options.
|
|
150
|
-
* @returns An observable stream of the response.
|
|
151
|
-
*
|
|
152
|
-
* @see {@link https://rxjs.dev/api/fetch/fromFetch|RxJS fromFetch}
|
|
153
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch|fetch}
|
|
154
|
-
*/
|
|
155
|
-
fetch$<T = TResponse>(
|
|
156
|
-
path: string,
|
|
157
|
-
init?: FetchRequestInit<T, TRequest, TResponse>,
|
|
158
|
-
): StreamResponse<T>;
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Fetch a resource as a promise.
|
|
162
|
-
*
|
|
163
|
-
* @template T - The expected response type.
|
|
164
|
-
* @param path - The path to fetch the resource from.
|
|
165
|
-
* @param init - Optional request initialization options.
|
|
166
|
-
* @returns A promise that resolves to the fetched resource.
|
|
167
|
-
*
|
|
168
|
-
* @see {@link IHttpClient.fetch$}
|
|
169
|
-
*/
|
|
170
|
-
fetch<T = TResponse>(path: string, init?: FetchRequestInit<T, TRequest, TResponse>): Promise<T>;
|
|
171
|
-
|
|
172
|
-
/** @deprecated use {@link IHttpClient.fetch} */
|
|
173
|
-
fetchAsync<T = TResponse>(
|
|
174
|
-
path: string,
|
|
175
|
-
args?: FetchRequestInit<T, TRequest, TResponse>,
|
|
176
|
-
): Promise<T>;
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Fetches a resource as an observable stream.
|
|
180
|
-
* This method simplifies the execution of a request and returns an observable stream of the response.
|
|
181
|
-
* The request will not be executed until the observable is subscribed to.
|
|
182
|
-
*
|
|
183
|
-
* @template T - The expected response type.
|
|
184
|
-
* @param path - The path to fetch the resource from.
|
|
185
|
-
* @param init - Optional request initialization options, including the request body, headers, and response type.
|
|
186
|
-
* @returns An observable stream of the fetched resource.
|
|
187
|
-
*
|
|
188
|
-
* @see {@link IHttpClient.fetch$}
|
|
189
|
-
*/
|
|
190
|
-
json$<T = unknown>(
|
|
191
|
-
path: string,
|
|
192
|
-
init?: FetchRequestInit<T, JsonRequest<TRequest>, TResponse>,
|
|
193
|
-
): StreamResponse<T>;
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Fetches a resource as a promise and returns the response as a JSON object.
|
|
197
|
-
*
|
|
198
|
-
* @template T - The expected response type.
|
|
199
|
-
* @param path - The path to fetch the resource from.
|
|
200
|
-
* @param init - Optional request initialization options, including the request body, headers, and response type.
|
|
201
|
-
* @returns A promise that resolves to the fetched resource as a JSON object.
|
|
202
|
-
*
|
|
203
|
-
* @see {@link IHttpClient.fetch} for fetching resources as an observable stream.
|
|
204
|
-
*/
|
|
205
|
-
json<T = unknown>(
|
|
206
|
-
path: string,
|
|
207
|
-
init?: FetchRequestInit<T, JsonRequest<TRequest>, TResponse>,
|
|
208
|
-
): Promise<T>;
|
|
209
|
-
|
|
210
|
-
/** @deprecated */
|
|
211
|
-
jsonAsync<T = unknown>(
|
|
212
|
-
path: string,
|
|
213
|
-
args?: FetchRequestInit<T, JsonRequest<TRequest>, TResponse>,
|
|
214
|
-
): Promise<T>;
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Fetches a blob resource from the specified path and returns a Promise that resolves to the fetched blob data.
|
|
218
|
-
*
|
|
219
|
-
* @param path - The path to fetch the blob from.
|
|
220
|
-
* @param args - Optional arguments for the fetch request, including the request body, headers, and response type.
|
|
221
|
-
* @returns A Promise that resolves to the fetched blob data.
|
|
222
|
-
*/
|
|
223
|
-
blob<T = BlobResult>(
|
|
224
|
-
path: string,
|
|
225
|
-
args?: FetchRequestInit<T, JsonRequest<TRequest>, TResponse>,
|
|
226
|
-
): Promise<T>;
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Fetches a blob from the specified path and returns a stream response.
|
|
230
|
-
*
|
|
231
|
-
* @param path - The path to fetch the blob from.
|
|
232
|
-
* @param args - Optional arguments for the fetch request, including the request body, headers, and response type.
|
|
233
|
-
* @returns A stream response containing the fetched blob.
|
|
234
|
-
*/
|
|
235
|
-
blob$<T = BlobResult>(
|
|
236
|
-
path: string,
|
|
237
|
-
args?: FetchRequestInit<T, JsonRequest<TRequest>, TResponse>,
|
|
238
|
-
): StreamResponse<T>;
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Abort all ongoing requests for the current client.
|
|
242
|
-
*/
|
|
243
|
-
abort(): void;
|
|
244
|
-
}
|
package/src/lib/index.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { firstValueFrom, from, of } from 'rxjs';
|
|
2
|
-
import type { Observable, ObservableInput } from 'rxjs';
|
|
3
|
-
|
|
4
|
-
import type { HttpMiddleware, HttpMiddlewareNext, IHttpMiddlewareHandler } from './types';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Normalizes a step's result to a `Promise`, so a middleware calling `next(...)` never has to
|
|
8
|
-
* branch on whether the next step short-circuited with a plain `Response` or reached all the
|
|
9
|
-
* way to an Observable-returning network call.
|
|
10
|
-
*/
|
|
11
|
-
function toPromise(result: Response | ObservableInput<Response>): Promise<Response> {
|
|
12
|
-
return result instanceof Response ? Promise.resolve(result) : firstValueFrom(from(result));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Composes registered {@link HttpMiddleware} into a single execution pipeline wrapping the
|
|
17
|
-
* network call, so retries, caching, telemetry, or circuit-breaking can wrap `_performFetch`
|
|
18
|
-
* without touching request or response payload transforms.
|
|
19
|
-
*
|
|
20
|
-
* @see {@link HttpClient}
|
|
21
|
-
*/
|
|
22
|
-
export class HttpMiddlewareHandler implements IHttpMiddlewareHandler {
|
|
23
|
-
#middleware: HttpMiddleware[];
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Constructs a handler, optionally cloning another handler's registered middleware.
|
|
27
|
-
* @param source - An existing handler to clone the registered middleware from.
|
|
28
|
-
*/
|
|
29
|
-
constructor(source?: IHttpMiddlewareHandler) {
|
|
30
|
-
this.#middleware = source ? [...source.middleware] : [];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** @inheritdoc */
|
|
34
|
-
get middleware(): readonly HttpMiddleware[] {
|
|
35
|
-
return this.#middleware;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** @inheritdoc */
|
|
39
|
-
use(middleware: HttpMiddleware): HttpMiddlewareHandler {
|
|
40
|
-
this.#middleware.push(middleware);
|
|
41
|
-
return this;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** @inheritdoc */
|
|
45
|
-
process(uri: string, init: RequestInit, terminal: HttpMiddlewareNext): Observable<Response> {
|
|
46
|
-
// wrap outward-in so the first-registered middleware is outermost, matching a conventional middleware chain
|
|
47
|
-
const chain = this.#middleware.reduceRight<HttpMiddlewareNext>(
|
|
48
|
-
(next, middleware) => (nextUri, nextInit) =>
|
|
49
|
-
middleware(nextUri, nextInit, (u, i) => toPromise(next(u, i))),
|
|
50
|
-
terminal,
|
|
51
|
-
);
|
|
52
|
-
const result = chain(uri, init);
|
|
53
|
-
// a middleware may short-circuit with a plain Response (no ObservableInput wrapping needed)
|
|
54
|
-
return result instanceof Response ? of(result) : from(result);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export default HttpMiddlewareHandler;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { ProcessOperators } from './ProcessOperators';
|
|
2
|
-
import { requestOperatorHeader } from './request-operator-header';
|
|
3
|
-
|
|
4
|
-
import type { FetchRequest } from '../client';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Extends the `ProcessOperators` class to handle HTTP requests.
|
|
8
|
-
*
|
|
9
|
-
* This class provides a method to set a header that will apply to all requests made by the `HttpClient`.
|
|
10
|
-
*
|
|
11
|
-
* @see {@link ProcessOperators}
|
|
12
|
-
*
|
|
13
|
-
* @template T - The type of the fetch request, which extends `FetchRequest`.
|
|
14
|
-
*/
|
|
15
|
-
export class HttpRequestHandler<T extends FetchRequest = FetchRequest> extends ProcessOperators<T> {
|
|
16
|
-
/**
|
|
17
|
-
* Sets a header that will apply to all requests made by the `HttpClient`.
|
|
18
|
-
*
|
|
19
|
-
* @param key - The name of the header to set.
|
|
20
|
-
* @param value - The value of the header to set.
|
|
21
|
-
* @returns The current `HttpRequestHandler` instance, allowing for method chaining.
|
|
22
|
-
*/
|
|
23
|
-
setHeader(key: string, value: string): HttpRequestHandler<T> {
|
|
24
|
-
const operator = requestOperatorHeader<T>(key, value);
|
|
25
|
-
return this.set(`header-${key}`, operator) as HttpRequestHandler<T>;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export default HttpRequestHandler;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { ProcessOperators } from './ProcessOperators';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The `HttpResponseHandler` class extends the `ProcessOperators` class and is responsible for handling HTTP responses.
|
|
5
|
-
* It provides a common interface for processing HTTP responses, allowing for consistent error handling and response transformation.
|
|
6
|
-
*
|
|
7
|
-
* @template T - The type of the HTTP response. Defaults to `Response`.
|
|
8
|
-
*/
|
|
9
|
-
export class HttpResponseHandler<T = Response> extends ProcessOperators<T> {}
|
|
10
|
-
|
|
11
|
-
export default HttpResponseHandler;
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { from, of } from 'rxjs';
|
|
2
|
-
import type { Observable } from 'rxjs';
|
|
3
|
-
import { last, mergeScan } from 'rxjs/operators';
|
|
4
|
-
import type { IProcessOperators, ProcessOperator } from './types';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* ProcessOperators class manages a collection of process operators
|
|
8
|
-
* and provides methods to add, set, get, and process these operators.
|
|
9
|
-
* It implements the IProcessOperators interface for type T.
|
|
10
|
-
*
|
|
11
|
-
* @template T The type of data that the process operators work with
|
|
12
|
-
*/
|
|
13
|
-
export class ProcessOperators<T> implements IProcessOperators<T> {
|
|
14
|
-
/**
|
|
15
|
-
* A record of process operators keyed by a string.
|
|
16
|
-
* This property is used to store and manage the collection of process operators
|
|
17
|
-
* that are used by the `ProcessOperators` class.
|
|
18
|
-
*/
|
|
19
|
-
protected _operators: Record<string, ProcessOperator<T>>;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Accessor for the collection of process operators.
|
|
23
|
-
* @returns The record of process operators.
|
|
24
|
-
*/
|
|
25
|
-
get operators(): Record<string, ProcessOperator<T>> {
|
|
26
|
-
return this._operators;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Constructs a new instance of the ProcessOperators class.
|
|
31
|
-
* @param operators - An optional object containing process operators.
|
|
32
|
-
* It can be either an instance of IProcessOperators<T> or a record of string keys and ProcessOperator<T> values.
|
|
33
|
-
*/
|
|
34
|
-
constructor(operators?: IProcessOperators<T> | Record<string, ProcessOperator<T>>) {
|
|
35
|
-
// accept either a raw operators record or another IProcessOperators instance to clone from
|
|
36
|
-
if (operators && 'operators' in operators) {
|
|
37
|
-
this._operators = { ...operators.operators };
|
|
38
|
-
} else {
|
|
39
|
-
this._operators = operators ?? {};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Adds a new operator to the collection.
|
|
45
|
-
* @param key The key under which the operator is stored.
|
|
46
|
-
* @param operator The operator to be added.
|
|
47
|
-
* @returns The instance of ProcessOperators for chaining.
|
|
48
|
-
* @throws Error if an operator with the same key already exists.
|
|
49
|
-
*/
|
|
50
|
-
add(key: string, operator: ProcessOperator<T>): ProcessOperators<T> {
|
|
51
|
-
// guard against silently overwriting an existing operator under the same key
|
|
52
|
-
if (Object.keys(this._operators).includes(key))
|
|
53
|
-
throw Error(`Operator [${key}] already defined`);
|
|
54
|
-
return this.set(key, operator);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Sets or updates an operator in the collection.
|
|
59
|
-
* @param key The key under which the operator is stored.
|
|
60
|
-
* @param operator The operator to be set.
|
|
61
|
-
* @returns The instance of ProcessOperators for chaining.
|
|
62
|
-
*/
|
|
63
|
-
set(key: string, operator: ProcessOperator<T>): ProcessOperators<T> {
|
|
64
|
-
this._operators[key] = operator;
|
|
65
|
-
return this;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Removes an operator from the collection by its key.
|
|
70
|
-
*
|
|
71
|
-
* @param key - The key of the operator to remove.
|
|
72
|
-
* @returns The current instance of `ProcessOperators` for method chaining.
|
|
73
|
-
*/
|
|
74
|
-
remove(key: string): ProcessOperators<T> {
|
|
75
|
-
delete this._operators[key];
|
|
76
|
-
return this;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Retrieves an operator from the collection by its key.
|
|
81
|
-
* @param key The key of the operator to retrieve.
|
|
82
|
-
* @returns The retrieved operator.
|
|
83
|
-
*/
|
|
84
|
-
get(key: string): ProcessOperator<T> {
|
|
85
|
-
return this._operators[key];
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Processes an input request through the chain of operators.
|
|
90
|
-
* @param request The request to be processed.
|
|
91
|
-
* @returns An Observable of the processed request.
|
|
92
|
-
*/
|
|
93
|
-
process(request: T): Observable<T> {
|
|
94
|
-
const operators = Object.values(this._operators);
|
|
95
|
-
/** if no operators registered, just return the observable value */
|
|
96
|
-
if (!operators.length) {
|
|
97
|
-
return of(request);
|
|
98
|
-
}
|
|
99
|
-
// feed the request through each operator sequentially, keeping the previous value when one returns void
|
|
100
|
-
return from(Object.values(this._operators)).pipe(
|
|
101
|
-
mergeScan(
|
|
102
|
-
// resolve current operator and return result or previous if void
|
|
103
|
-
(value, operator) => Promise.resolve(operator(value)).then((x) => x ?? value),
|
|
104
|
-
// initial value
|
|
105
|
-
request,
|
|
106
|
-
// only allow concurrency of one operator
|
|
107
|
-
1,
|
|
108
|
-
),
|
|
109
|
-
// output result of last operator
|
|
110
|
-
last(),
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { requestMethodCasing } from './fetch-request.schemas';
|
|
2
|
-
import type { ProcessOperator } from './types';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Ensures that the HTTP method of the given request is in uppercase.
|
|
6
|
-
*
|
|
7
|
-
* @param request - The HTTP request object to process.
|
|
8
|
-
* @returns A new request object with the HTTP method in uppercase.
|
|
9
|
-
*/
|
|
10
|
-
export const capitalizeRequestMethodOperator =
|
|
11
|
-
<T extends RequestInit>(options?: { silent?: boolean }): ProcessOperator<T> =>
|
|
12
|
-
(request): T => {
|
|
13
|
-
const { error, success, data } = requestMethodCasing().safeParse(request.method);
|
|
14
|
-
|
|
15
|
-
request.method = success ? data : request.method?.toUpperCase();
|
|
16
|
-
|
|
17
|
-
// surface schema validation issues as warnings when not running silently
|
|
18
|
-
if (error && !options?.silent) {
|
|
19
|
-
// one warning per issue so callers can see exactly what failed to validate
|
|
20
|
-
for (const e of error.issues) {
|
|
21
|
-
console.warn(e.message);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return request;
|
|
26
|
-
};
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Validates that the provided HTTP method string is in uppercase.
|
|
5
|
-
*
|
|
6
|
-
* @link https://www.rfc-editor.org/rfc/rfc7231#section-4.1
|
|
7
|
-
*/
|
|
8
|
-
export const requestMethodCasing = (): z.ZodType<string | undefined> => {
|
|
9
|
-
return z
|
|
10
|
-
.string()
|
|
11
|
-
.optional()
|
|
12
|
-
.refine((value) => value === undefined || value === value?.toUpperCase(), {
|
|
13
|
-
message: [
|
|
14
|
-
'Provided HTTP method must be in uppercase.',
|
|
15
|
-
'See RFC 7231 Section 4.1 for more information',
|
|
16
|
-
'https://www.rfc-editor.org/rfc/rfc7231#section-4.1',
|
|
17
|
-
].join(' '),
|
|
18
|
-
});
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Creates a Zod enum schema for HTTP request methods.
|
|
23
|
-
*
|
|
24
|
-
* The schema validates that the value is one of the standard HTTP methods:
|
|
25
|
-
* 'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD', 'CONNECT', 'TRACE'.
|
|
26
|
-
*
|
|
27
|
-
* If the validation fails, a custom error message is returned, indicating the
|
|
28
|
-
* expected methods and the received value. The error message also references
|
|
29
|
-
* RFC 2616 for more information.
|
|
30
|
-
*
|
|
31
|
-
* @link https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
|
|
32
|
-
*/
|
|
33
|
-
export const requestMethodVerb = () => {
|
|
34
|
-
return z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD', 'CONNECT', 'TRACE'], {
|
|
35
|
-
message:
|
|
36
|
-
'Invalid request method. Expected one of: GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD, CONNECT, TRACE. See RFC 2615 Section 9 for more information: https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html',
|
|
37
|
-
});
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export const requestMethod = () => requestMethodVerb().optional();
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Schema for validating the initialization options of a request.
|
|
44
|
-
*
|
|
45
|
-
* @link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request
|
|
46
|
-
*
|
|
47
|
-
* This schema is used to ensure that the request options conform to the expected structure and types.
|
|
48
|
-
*/
|
|
49
|
-
export const requestInitSchema = z.object({
|
|
50
|
-
attributionReporting: z
|
|
51
|
-
.object({
|
|
52
|
-
eventSourceEligible: z.boolean().optional(),
|
|
53
|
-
triggerEligible: z.boolean().optional(),
|
|
54
|
-
})
|
|
55
|
-
.optional(),
|
|
56
|
-
body: z
|
|
57
|
-
.union([
|
|
58
|
-
z.string(),
|
|
59
|
-
z.instanceof(Blob),
|
|
60
|
-
z.instanceof(ArrayBuffer),
|
|
61
|
-
z.instanceof(FormData),
|
|
62
|
-
z.instanceof(URLSearchParams),
|
|
63
|
-
z.instanceof(ReadableStream),
|
|
64
|
-
])
|
|
65
|
-
.optional(),
|
|
66
|
-
browsingTopics: z.boolean().optional(),
|
|
67
|
-
cache: z
|
|
68
|
-
.enum(['default', 'no-store', 'reload', 'no-cache', 'force-cache', 'only-if-cached'])
|
|
69
|
-
.optional(),
|
|
70
|
-
credentials: z.enum(['omit', 'same-origin', 'include']).optional(),
|
|
71
|
-
headers: z.record(z.string(), z.string()).optional().or(z.instanceof(Headers)),
|
|
72
|
-
integrity: z.string().optional(),
|
|
73
|
-
keepalive: z.boolean().optional(),
|
|
74
|
-
method: requestMethod().optional(),
|
|
75
|
-
mode: z.enum(['same-origin', 'cors', 'no-cors', 'navigate', 'websocket']).optional(),
|
|
76
|
-
priority: z.enum(['low', 'high', 'auto']).optional(),
|
|
77
|
-
redirect: z.enum(['follow', 'error', 'manual']).optional(),
|
|
78
|
-
referrer: z.string().optional(),
|
|
79
|
-
referrerPolicy: z
|
|
80
|
-
.enum([
|
|
81
|
-
'no-referrer',
|
|
82
|
-
'no-referrer-when-downgrade',
|
|
83
|
-
'origin',
|
|
84
|
-
'origin-when-cross-origin',
|
|
85
|
-
'same-origin',
|
|
86
|
-
'strict-origin',
|
|
87
|
-
'strict-origin-when-cross-origin',
|
|
88
|
-
'unsafe-url',
|
|
89
|
-
])
|
|
90
|
-
.optional(),
|
|
91
|
-
signal: z.instanceof(AbortSignal).optional(),
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Schema for validating fetch request configurations.
|
|
96
|
-
*
|
|
97
|
-
* This schema extends the `requestInitSchema` and adds additional properties:
|
|
98
|
-
* - `uri`: A required string representing the URI of the request.
|
|
99
|
-
* - `path`: An optional string representing the path of the request.
|
|
100
|
-
*/
|
|
101
|
-
export const fetchRequestSchema = requestInitSchema.extend({
|
|
102
|
-
uri: z.string(),
|
|
103
|
-
path: z.string().optional(),
|
|
104
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export { HttpRequestHandler } from './HttpRequestHandler';
|
|
2
|
-
export { HttpResponseHandler } from './HttpResponseHandler';
|
|
3
|
-
export { HttpMiddlewareHandler } from './HttpMiddlewareHandler';
|
|
4
|
-
export { ProcessOperators } from './ProcessOperators';
|
|
5
|
-
export { capitalizeRequestMethodOperator } from './capitalize-request-method-operator';
|
|
6
|
-
export { requestValidationOperator } from './request-validation-operator';
|
|
7
|
-
export { sseMap } from './sse-map.operator';
|
|
8
|
-
|
|
9
|
-
export * from './types';
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { FetchRequest } from '../client';
|
|
2
|
-
import type { ProcessOperator } from './types';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Creates a process operator that adds a header to the request.
|
|
6
|
-
*
|
|
7
|
-
* @param key - The header key to add.
|
|
8
|
-
* @param value - The header value to add.
|
|
9
|
-
* @returns A process operator that adds the specified header to the request.
|
|
10
|
-
*/
|
|
11
|
-
export const requestOperatorHeader =
|
|
12
|
-
<T extends FetchRequest = FetchRequest>(key: string, value: string): ProcessOperator<T> =>
|
|
13
|
-
(request) => {
|
|
14
|
-
const headers = new Headers(request.headers);
|
|
15
|
-
headers.append(key, value);
|
|
16
|
-
return { ...request, headers };
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export default requestOperatorHeader;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import type { z } from 'zod';
|
|
2
|
-
import type { ProcessOperator } from './types';
|
|
3
|
-
import type { FetchRequest } from '../client/types';
|
|
4
|
-
import { fetchRequestSchema } from './fetch-request.schemas';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Validates the given request using the `requestInitSchema`.
|
|
8
|
-
*
|
|
9
|
-
* By default, the validation is not strict, meaning that additional properties
|
|
10
|
-
* not defined in the schema will be allowed and passed through without causing validation errors.
|
|
11
|
-
* Also the operator will not modify the request object, it will only log an error message if the validation fails.
|
|
12
|
-
*
|
|
13
|
-
* @link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request
|
|
14
|
-
*
|
|
15
|
-
* @param request - The request object to be validated.
|
|
16
|
-
* @returns The validated request object if validation is successful.
|
|
17
|
-
* @throws Will log an error message if the request validation fails.
|
|
18
|
-
*/
|
|
19
|
-
export const requestValidationOperator =
|
|
20
|
-
<T extends FetchRequest>(options?: {
|
|
21
|
-
/**
|
|
22
|
-
* When enabled, the function will return the parsed result.
|
|
23
|
-
* This means that if the request object passes validation,
|
|
24
|
-
* the parsed and potentially transformed request object will be returned.
|
|
25
|
-
* If this option is not enabled, the function will not return anything
|
|
26
|
-
* even if the request object is valid.
|
|
27
|
-
*/
|
|
28
|
-
parse?: boolean;
|
|
29
|
-
/**
|
|
30
|
-
* When set to true, the validation will be strict, meaning that any additional properties
|
|
31
|
-
* not defined in the schema will cause the validation to fail. If set to false or omitted,
|
|
32
|
-
* additional properties will be allowed and passed through without causing validation errors.
|
|
33
|
-
*
|
|
34
|
-
* @remarks this option is only applicable when the `parse` option is enabled.
|
|
35
|
-
*/
|
|
36
|
-
strict?: boolean;
|
|
37
|
-
}): ProcessOperator<T> =>
|
|
38
|
-
(request) => {
|
|
39
|
-
const { strict, parse } = options ?? {};
|
|
40
|
-
const schema = strict ? fetchRequestSchema : fetchRequestSchema.passthrough();
|
|
41
|
-
try {
|
|
42
|
-
const result = schema.parse(request) as T;
|
|
43
|
-
return parse ? result : void 0;
|
|
44
|
-
} catch (error) {
|
|
45
|
-
// re-throw so callers relying on `parse` can react to validation failures directly
|
|
46
|
-
if (parse) {
|
|
47
|
-
throw error;
|
|
48
|
-
}
|
|
49
|
-
console.error('Invalid request options', (error as z.ZodError).message);
|
|
50
|
-
}
|
|
51
|
-
};
|