@equinor/fusion-framework-module-http 6.2.1 → 6.2.2
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/CHANGELOG.md +336 -310
- package/dist/esm/configurator.js.map +1 -1
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/lib/client/client-msal.js.map +1 -1
- package/dist/esm/lib/client/client.js.map +1 -1
- package/dist/esm/lib/operators/capitalize-request-method.operator.js +3 -1
- package/dist/esm/lib/operators/capitalize-request-method.operator.js.map +1 -1
- package/dist/esm/lib/operators/fetch-request.schema.js.map +1 -1
- package/dist/esm/lib/operators/http-request-handler.js.map +1 -1
- package/dist/esm/lib/operators/process-operators.js.map +1 -1
- package/dist/esm/lib/operators/request-operator-header.js.map +1 -1
- package/dist/esm/lib/operators/request-validation.operator.js.map +1 -1
- package/dist/esm/lib/selectors/blob-selector.js.map +1 -1
- package/dist/esm/lib/selectors/json-selector.js.map +1 -1
- package/dist/esm/module.js +1 -1
- package/dist/esm/module.js.map +1 -1
- package/dist/esm/provider.js +8 -3
- package/dist/esm/provider.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/lib/operators/process-operators.d.ts +1 -1
- package/dist/types/module.d.ts +3 -3
- package/dist/types/provider.d.ts +10 -3
- package/dist/types/version.d.ts +1 -1
- package/package.json +3 -3
- package/src/configurator.ts +115 -116
- package/src/errors.ts +24 -24
- package/src/lib/client/client-msal.ts +34 -34
- package/src/lib/client/client.ts +298 -298
- package/src/lib/client/types.ts +147 -145
- package/src/lib/operators/capitalize-request-method.operator.ts +11 -9
- package/src/lib/operators/fetch-request.schema.ts +70 -73
- package/src/lib/operators/http-request-handler.ts +11 -11
- package/src/lib/operators/process-operators.ts +88 -88
- package/src/lib/operators/request-operator-header.ts +6 -6
- package/src/lib/operators/request-validation.operator.ts +32 -32
- package/src/lib/operators/types.ts +44 -44
- package/src/lib/selectors/blob-selector.ts +24 -24
- package/src/lib/selectors/json-selector.ts +25 -25
- package/src/module.ts +73 -69
- package/src/provider.ts +141 -139
- package/src/version.ts +1 -1
- package/tests/HttpClient.test.ts +37 -37
- package/tests/operators.test.ts +67 -67
- package/vitest.config.ts +6 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
2
|
import type { Observable } from 'rxjs';
|
|
3
3
|
import { last, mergeScan } from 'rxjs/operators';
|
|
4
|
-
import { IProcessOperators, ProcessOperator } from './types';
|
|
4
|
+
import type { IProcessOperators, ProcessOperator } from './types';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* ProcessOperators class manages a collection of process operators
|
|
@@ -11,100 +11,100 @@ import { IProcessOperators, ProcessOperator } from './types';
|
|
|
11
11
|
* @template T The type of data that the process operators work with
|
|
12
12
|
*/
|
|
13
13
|
export class ProcessOperators<T> implements IProcessOperators<T> {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
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
|
+
if (operators && 'operators' in operators) {
|
|
36
|
+
this._operators = { ...operators.operators };
|
|
37
|
+
} else {
|
|
38
|
+
this._operators = operators ?? {};
|
|
40
39
|
}
|
|
40
|
+
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Adds a new operator to the collection.
|
|
44
|
+
* @param key The key under which the operator is stored.
|
|
45
|
+
* @param operator The operator to be added.
|
|
46
|
+
* @returns The instance of ProcessOperators for chaining.
|
|
47
|
+
* @throws Error if an operator with the same key already exists.
|
|
48
|
+
*/
|
|
49
|
+
add(key: string, operator: ProcessOperator<T>): ProcessOperators<T> {
|
|
50
|
+
if (Object.keys(this._operators).includes(key))
|
|
51
|
+
throw Error(`Operator [${key}] already defined`);
|
|
52
|
+
return this.set(key, operator);
|
|
53
|
+
}
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Sets or updates an operator in the collection.
|
|
57
|
+
* @param key The key under which the operator is stored.
|
|
58
|
+
* @param operator The operator to be set.
|
|
59
|
+
* @returns The instance of ProcessOperators for chaining.
|
|
60
|
+
*/
|
|
61
|
+
set(key: string, operator: ProcessOperator<T>): ProcessOperators<T> {
|
|
62
|
+
this._operators[key] = operator;
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Removes an operator from the collection by its key.
|
|
68
|
+
*
|
|
69
|
+
* @param key - The key of the operator to remove.
|
|
70
|
+
* @returns The current instance of `ProcessOperators` for method chaining.
|
|
71
|
+
*/
|
|
72
|
+
remove(key: string): ProcessOperators<T> {
|
|
73
|
+
delete this._operators[key];
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Retrieves an operator from the collection by its key.
|
|
79
|
+
* @param key The key of the operator to retrieve.
|
|
80
|
+
* @returns The retrieved operator.
|
|
81
|
+
*/
|
|
82
|
+
get(key: string): ProcessOperator<T> {
|
|
83
|
+
return this._operators[key];
|
|
84
|
+
}
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
return from(Object.values(this._operators)).pipe(
|
|
98
|
-
mergeScan(
|
|
99
|
-
// resolve current operator and return result or previous if void
|
|
100
|
-
(value, operator) => Promise.resolve(operator(value)).then((x) => x ?? value),
|
|
101
|
-
// initial value
|
|
102
|
-
request,
|
|
103
|
-
// only allow concurrency of one operator
|
|
104
|
-
1,
|
|
105
|
-
),
|
|
106
|
-
// output result of last operator
|
|
107
|
-
last(),
|
|
108
|
-
);
|
|
86
|
+
/**
|
|
87
|
+
* Processes an input request through the chain of operators.
|
|
88
|
+
* @param request The request to be processed.
|
|
89
|
+
* @returns An Observable of the processed request.
|
|
90
|
+
*/
|
|
91
|
+
process(request: T): Observable<T> {
|
|
92
|
+
const operators = Object.values(this._operators);
|
|
93
|
+
/** if no operators registered, just return the observable value */
|
|
94
|
+
if (!operators.length) {
|
|
95
|
+
return of(request);
|
|
109
96
|
}
|
|
97
|
+
return from(Object.values(this._operators)).pipe(
|
|
98
|
+
mergeScan(
|
|
99
|
+
// resolve current operator and return result or previous if void
|
|
100
|
+
(value, operator) => Promise.resolve(operator(value)).then((x) => x ?? value),
|
|
101
|
+
// initial value
|
|
102
|
+
request,
|
|
103
|
+
// only allow concurrency of one operator
|
|
104
|
+
1,
|
|
105
|
+
),
|
|
106
|
+
// output result of last operator
|
|
107
|
+
last(),
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
110
|
}
|
|
@@ -9,11 +9,11 @@ import type { ProcessOperator } from './types';
|
|
|
9
9
|
* @returns A process operator that adds the specified header to the request.
|
|
10
10
|
*/
|
|
11
11
|
export const requestOperatorHeader =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
18
|
|
|
19
19
|
export default requestOperatorHeader;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
1
|
+
import type { z } from 'zod';
|
|
2
2
|
import type { ProcessOperator } from './types';
|
|
3
3
|
import type { FetchRequest } from '../client/types';
|
|
4
4
|
import { fetchRequestSchema } from './fetch-request.schema';
|
|
@@ -17,34 +17,34 @@ import { fetchRequestSchema } from './fetch-request.schema';
|
|
|
17
17
|
* @throws Will log an error message if the request validation fails.
|
|
18
18
|
*/
|
|
19
19
|
export const requestValidationOperator =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
+
* @note 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
|
+
if (parse) {
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
console.error('Invalid request options', (error as z.ZodError).message);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
@@ -18,48 +18,48 @@ export type ProcessOperator<T, R = T> = (request: T) => R | void | Promise<R | v
|
|
|
18
18
|
* @template T The type of the request being processed.
|
|
19
19
|
*/
|
|
20
20
|
export interface IProcessOperators<T> {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Gets the operators registered in the collection.
|
|
23
|
+
*/
|
|
24
|
+
get operators(): Record<string, ProcessOperator<T>>;
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Adds a new operator to the collection.
|
|
28
|
+
* @param key The key to identify the operator.
|
|
29
|
+
* @param operator The process operator to add.
|
|
30
|
+
* @returns The updated collection of process operators.
|
|
31
|
+
* @throws An error if the operator is already defined.
|
|
32
|
+
*/
|
|
33
|
+
add(key: string, operator: ProcessOperator<T>): IProcessOperators<T>;
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Adds or sets a process operator in the collection.
|
|
37
|
+
* @param key The key to identify the operator.
|
|
38
|
+
* @param operator The process operator to add or set.
|
|
39
|
+
* @returns The updated collection of process operators.
|
|
40
|
+
*/
|
|
41
|
+
set(key: string, operator: ProcessOperator<T>): IProcessOperators<T>;
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Removes a process operator from the collection.
|
|
45
|
+
* @param key The key of the operator to remove.
|
|
46
|
+
* @returns The updated collection of process operators.
|
|
47
|
+
*/
|
|
48
|
+
remove(key: string): IProcessOperators<T>;
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Gets a process operator from the collection.
|
|
52
|
+
* @param key The key of the operator to retrieve.
|
|
53
|
+
* @returns The process operator associated with the key, or undefined if the key is invalid.
|
|
54
|
+
*/
|
|
55
|
+
get(key: string): ProcessOperator<T>;
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Processes the registered process operators.
|
|
59
|
+
* @param request The request to process.
|
|
60
|
+
* @returns An observable that emits the processed request.
|
|
61
|
+
*/
|
|
62
|
+
process(request: T): Observable<T>;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
/**
|
|
@@ -69,13 +69,13 @@ export interface IProcessOperators<T> {
|
|
|
69
69
|
* @template T - The type of the request being processed. Defaults to `FetchRequest`.
|
|
70
70
|
*/
|
|
71
71
|
export interface IHttpRequestHandler<T extends FetchRequest = FetchRequest>
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
72
|
+
extends IProcessOperators<T> {
|
|
73
|
+
/**
|
|
74
|
+
* Set header that will apply on all requests done by consumer @see {HttpClient}
|
|
75
|
+
* @param key - name of header
|
|
76
|
+
* @param value - header value
|
|
77
|
+
*/
|
|
78
|
+
setHeader(key: string, value: string): IHttpRequestHandler<T>;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
/**
|
|
@@ -8,34 +8,34 @@ import type { ResponseSelector, BlobResult } from '../client/types';
|
|
|
8
8
|
* @throws {Error} If the response is not successful or if there is an error parsing the response.
|
|
9
9
|
*/
|
|
10
10
|
export const blobSelector: ResponseSelector = async <TResponse extends Response = Response>(
|
|
11
|
-
|
|
11
|
+
response: TResponse,
|
|
12
12
|
): Promise<BlobResult> => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
if (!response.ok) {
|
|
14
|
+
// Throw an error if the network response is not successful
|
|
15
|
+
throw new Error('network response was not OK');
|
|
16
|
+
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
// Status code 204 indicates no content, so throw an error
|
|
19
|
+
if (response.status === 204) {
|
|
20
|
+
throw new Error('no content');
|
|
21
|
+
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
// Extract the filename from the 'content-disposition' header
|
|
24
|
+
const filename = response.headers
|
|
25
|
+
.get('content-disposition')
|
|
26
|
+
?.split(';')
|
|
27
|
+
.find((n) => n.includes('filename='))
|
|
28
|
+
?.replace('filename=', '')
|
|
29
|
+
?.trim();
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
try {
|
|
32
|
+
// Convert the response to a Blob and return the filename and Blob
|
|
33
|
+
const blob = await response.blob();
|
|
34
|
+
return { filename, blob };
|
|
35
|
+
} catch (err) {
|
|
36
|
+
// Throw an error if there's a problem parsing the response
|
|
37
|
+
throw Error('failed to parse response');
|
|
38
|
+
}
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
export default blobSelector;
|
|
@@ -16,37 +16,37 @@ import { HttpJsonResponseError } from '../../errors';
|
|
|
16
16
|
* @returns A promise that resolves with the parsed JSON data, or rejects with an `HttpJsonResponseError`.
|
|
17
17
|
*/
|
|
18
18
|
export const jsonSelector: ResponseSelector = async <
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
TType = unknown,
|
|
20
|
+
TResponse extends Response = Response,
|
|
21
21
|
>(
|
|
22
|
-
|
|
22
|
+
response: TResponse,
|
|
23
23
|
): Promise<TType> => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
// Parse the response JSON data
|
|
31
|
-
const data = await response.json();
|
|
24
|
+
/** Status code 204 indicates no content in the response */
|
|
25
|
+
if (response.status === 204) {
|
|
26
|
+
return Promise.resolve() as Promise<TType>;
|
|
27
|
+
}
|
|
32
28
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
throw new HttpJsonResponseError('network response was not OK', response, { data });
|
|
37
|
-
}
|
|
29
|
+
try {
|
|
30
|
+
// Parse the response JSON data
|
|
31
|
+
const data = await response.json();
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
throw cause;
|
|
45
|
-
}
|
|
33
|
+
// Check if the response was successful
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
// Throw an error with the response details
|
|
36
|
+
throw new HttpJsonResponseError('network response was not OK', response, { data });
|
|
37
|
+
}
|
|
46
38
|
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
// Return the parsed data
|
|
40
|
+
return data;
|
|
41
|
+
} catch (cause) {
|
|
42
|
+
// If the cause is an HttpJsonResponseError, rethrow it
|
|
43
|
+
if (cause instanceof HttpJsonResponseError) {
|
|
44
|
+
throw cause;
|
|
49
45
|
}
|
|
46
|
+
|
|
47
|
+
// Otherwise, throw a new HttpJsonResponseError with the parsing error
|
|
48
|
+
throw new HttpJsonResponseError('failed to parse response', response, { cause });
|
|
49
|
+
}
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
export default jsonSelector;
|