@vertesia/api-fetch-client 1.1.1-dev.20260505.163000Z → 1.3.0-dev.20260620.061059Z
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 +51 -0
- package/lib/base.d.ts +169 -0
- package/lib/base.d.ts.map +1 -0
- package/lib/base.js +481 -0
- package/lib/base.js.map +1 -0
- package/lib/{types/client.d.ts → client.d.ts} +8 -8
- package/lib/client.d.ts.map +1 -0
- package/lib/{esm/client.js → client.js} +27 -11
- package/lib/client.js.map +1 -0
- package/lib/{types/errors.d.ts → errors.d.ts} +5 -5
- package/lib/errors.d.ts.map +1 -0
- package/lib/{esm/errors.js → errors.js} +22 -9
- package/lib/errors.js.map +1 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +5 -0
- package/lib/index.js.map +1 -0
- package/lib/{types/sse → sse}/EventSourceParserStream.d.ts +4 -1
- package/lib/sse/EventSourceParserStream.d.ts.map +1 -0
- package/lib/{esm/sse → sse}/EventSourceParserStream.js +5 -4
- package/lib/sse/EventSourceParserStream.js.map +1 -0
- package/lib/sse/TextDecoderStream.d.ts.map +1 -0
- package/lib/{esm/sse → sse}/TextDecoderStream.js +2 -2
- package/lib/sse/TextDecoderStream.js.map +1 -0
- package/lib/{types/sse → sse}/index.d.ts +7 -2
- package/lib/sse/index.d.ts.map +1 -0
- package/lib/{esm/sse → sse}/index.js +3 -3
- package/lib/sse/index.js.map +1 -0
- package/lib/{types/utils.d.ts → utils.d.ts} +1 -1
- package/lib/utils.d.ts.map +1 -0
- package/lib/{esm/utils.js → utils.js} +3 -3
- package/lib/utils.js.map +1 -0
- package/package.json +22 -25
- package/src/base.ts +432 -79
- package/src/client.ts +50 -24
- package/src/errors.ts +28 -15
- package/src/index.ts +4 -4
- package/src/sse/EventSourceParserStream.ts +13 -10
- package/src/sse/TextDecoderStream.ts +16 -11
- package/src/sse/index.ts +14 -8
- package/src/utils.ts +5 -6
- package/lib/cjs/base.js +0 -240
- package/lib/cjs/base.js.map +0 -1
- package/lib/cjs/client.js +0 -115
- package/lib/cjs/client.js.map +0 -1
- package/lib/cjs/errors.js +0 -63
- package/lib/cjs/errors.js.map +0 -1
- package/lib/cjs/index.js +0 -21
- package/lib/cjs/index.js.map +0 -1
- package/lib/cjs/package.json +0 -3
- package/lib/cjs/sse/EventSourceParserStream.js +0 -41
- package/lib/cjs/sse/EventSourceParserStream.js.map +0 -1
- package/lib/cjs/sse/TextDecoderStream.js +0 -53
- package/lib/cjs/sse/TextDecoderStream.js.map +0 -1
- package/lib/cjs/sse/index.js +0 -27
- package/lib/cjs/sse/index.js.map +0 -1
- package/lib/cjs/utils.js +0 -38
- package/lib/cjs/utils.js.map +0 -1
- package/lib/esm/base.js +0 -235
- package/lib/esm/base.js.map +0 -1
- package/lib/esm/client.js.map +0 -1
- package/lib/esm/errors.js.map +0 -1
- package/lib/esm/index.js +0 -5
- package/lib/esm/index.js.map +0 -1
- package/lib/esm/sse/EventSourceParserStream.js.map +0 -1
- package/lib/esm/sse/TextDecoderStream.js.map +0 -1
- package/lib/esm/sse/index.js.map +0 -1
- package/lib/esm/utils.js.map +0 -1
- package/lib/tsconfig.tsbuildinfo +0 -1
- package/lib/types/base.d.ts +0 -83
- package/lib/types/base.d.ts.map +0 -1
- package/lib/types/client.d.ts.map +0 -1
- package/lib/types/errors.d.ts.map +0 -1
- package/lib/types/index.d.ts +0 -5
- package/lib/types/index.d.ts.map +0 -1
- package/lib/types/sse/EventSourceParserStream.d.ts.map +0 -1
- package/lib/types/sse/TextDecoderStream.d.ts.map +0 -1
- package/lib/types/sse/index.d.ts.map +0 -1
- package/lib/types/utils.d.ts.map +0 -1
- /package/lib/{types/sse → sse}/TextDecoderStream.d.ts +0 -0
package/src/client.ts
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
|
-
import { ClientBase, FETCH_FN, IRequestParamsWithPayload } from
|
|
2
|
-
import { RequestError } from
|
|
1
|
+
import { ClientBase, type FETCH_FN, type IRequestParamsWithPayload } from './base.js';
|
|
2
|
+
import type { RequestError } from './errors.js';
|
|
3
3
|
|
|
4
4
|
function isAuthorizationHeaderSet(headers: HeadersInit | undefined): boolean {
|
|
5
5
|
if (!headers) return false;
|
|
6
|
-
return
|
|
6
|
+
return 'authorization' in headers;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
function isServerFetchRuntime(): boolean {
|
|
10
|
+
const runtime = globalThis as typeof globalThis & {
|
|
11
|
+
Bun?: unknown;
|
|
12
|
+
process?: { versions?: { bun?: string; node?: string } };
|
|
13
|
+
window?: unknown;
|
|
14
|
+
};
|
|
15
|
+
return (
|
|
16
|
+
typeof runtime.window === 'undefined' &&
|
|
17
|
+
(typeof runtime.process?.versions?.node === 'string' ||
|
|
18
|
+
typeof runtime.process?.versions?.bun === 'string' ||
|
|
19
|
+
typeof runtime.Bun !== 'undefined')
|
|
20
|
+
);
|
|
21
|
+
}
|
|
10
22
|
|
|
23
|
+
export class AbstractFetchClient<T extends AbstractFetchClient<T>> extends ClientBase {
|
|
11
24
|
headers: Record<string, string>;
|
|
12
25
|
_auth?: () => Promise<string>;
|
|
13
26
|
// callbacks useful to log requests and responses
|
|
@@ -23,7 +36,11 @@ export class AbstractFetchClient<T extends AbstractFetchClient<T>> extends Clien
|
|
|
23
36
|
}
|
|
24
37
|
|
|
25
38
|
get initialHeaders() {
|
|
26
|
-
|
|
39
|
+
const headers: Record<string, string> = { accept: 'application/json' };
|
|
40
|
+
if (isServerFetchRuntime()) {
|
|
41
|
+
headers['accept-encoding'] = 'br, gzip, deflate';
|
|
42
|
+
}
|
|
43
|
+
return headers;
|
|
27
44
|
}
|
|
28
45
|
|
|
29
46
|
/**
|
|
@@ -75,38 +92,32 @@ export class AbstractFetchClient<T extends AbstractFetchClient<T>> extends Clien
|
|
|
75
92
|
init.headers = headers;
|
|
76
93
|
const auth = await this._auth();
|
|
77
94
|
if (auth) {
|
|
78
|
-
init.headers
|
|
95
|
+
init.headers.authorization = auth;
|
|
79
96
|
}
|
|
80
97
|
}
|
|
81
98
|
this.response = undefined;
|
|
82
99
|
const request = await super.createRequest(url, init);
|
|
83
|
-
this.onRequest
|
|
100
|
+
this.onRequest?.(request);
|
|
84
101
|
return request;
|
|
85
102
|
}
|
|
86
103
|
|
|
87
|
-
|
|
104
|
+
handleFetchResponse(req: Request, res: Response): void {
|
|
88
105
|
this.response = res; // store last response
|
|
89
|
-
this.onResponse
|
|
90
|
-
return super.handleResponse(req, res, params);
|
|
106
|
+
this.onResponse?.(res, req);
|
|
91
107
|
}
|
|
92
|
-
|
|
93
108
|
}
|
|
94
109
|
|
|
95
|
-
export class FetchClient extends AbstractFetchClient<FetchClient> {
|
|
96
|
-
|
|
97
|
-
constructor(baseUrl: string, fetchImpl?: FETCH_FN | Promise<FETCH_FN>) {
|
|
98
|
-
super(baseUrl, fetchImpl);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
}
|
|
110
|
+
export class FetchClient extends AbstractFetchClient<FetchClient> {}
|
|
102
111
|
|
|
103
112
|
export abstract class ApiTopic extends ClientBase {
|
|
104
|
-
|
|
105
|
-
|
|
113
|
+
constructor(
|
|
114
|
+
public client: ClientBase,
|
|
115
|
+
basePath: string,
|
|
116
|
+
) {
|
|
106
117
|
//TODO we should refactor the way ClientBase and ApiTopic is created
|
|
107
118
|
// to avoid cloning all customizations
|
|
108
119
|
super(client.getUrl(basePath), client._fetch);
|
|
109
|
-
this.createServerError = client.createServerError
|
|
120
|
+
this.createServerError = client.createServerError;
|
|
110
121
|
this.errorFactory = client.errorFactory;
|
|
111
122
|
this.verboseErrors = client.verboseErrors;
|
|
112
123
|
}
|
|
@@ -115,12 +126,27 @@ export abstract class ApiTopic extends ClientBase {
|
|
|
115
126
|
return this.client.createRequest(url, init);
|
|
116
127
|
}
|
|
117
128
|
|
|
118
|
-
handleResponse
|
|
119
|
-
|
|
129
|
+
handleResponse<T = unknown>(
|
|
130
|
+
req: Request,
|
|
131
|
+
res: Response,
|
|
132
|
+
params: IRequestParamsWithPayload | undefined,
|
|
133
|
+
): T | Promise<T> {
|
|
134
|
+
return this.client.handleResponse<T>(req, res, params);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
handleFetchResponse(req: Request, res: Response): void {
|
|
138
|
+
this.client.handleFetchResponse(req, res);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
getRetryPolicy() {
|
|
142
|
+
return this.client.getRetryPolicy();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
getTimeout() {
|
|
146
|
+
return this.client.getTimeout();
|
|
120
147
|
}
|
|
121
148
|
|
|
122
149
|
get headers() {
|
|
123
150
|
return this.client.headers;
|
|
124
151
|
}
|
|
125
|
-
|
|
126
152
|
}
|
package/src/errors.ts
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
2
|
+
return value !== null && typeof value === 'object';
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function getDetails(payload: unknown): unknown {
|
|
6
|
+
if (!isRecord(payload)) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
if (payload.details) {
|
|
10
|
+
return payload.details;
|
|
11
|
+
}
|
|
12
|
+
return isRecord(payload.error) ? payload.error.details : undefined;
|
|
13
|
+
}
|
|
1
14
|
|
|
2
|
-
function createMessage(message: string, request: Request, status: number, payload:
|
|
15
|
+
function createMessage(message: string, request: Request, status: number, payload: unknown, displayDetails: boolean) {
|
|
3
16
|
let msg = message;
|
|
4
17
|
if (displayDetails) {
|
|
5
|
-
msg +=
|
|
6
|
-
const details = payload
|
|
18
|
+
msg += `\nRequest: ${request.method} ${request.url} => ${status}`;
|
|
19
|
+
const details = getDetails(payload);
|
|
7
20
|
if (details) {
|
|
8
21
|
const detailsType = typeof details;
|
|
9
22
|
if (detailsType === 'string') {
|
|
10
|
-
msg +=
|
|
11
|
-
} else if (detailsType ===
|
|
12
|
-
msg +=
|
|
23
|
+
msg += `\nDetails: ${details}`;
|
|
24
|
+
} else if (detailsType === 'object') {
|
|
25
|
+
msg += `\nDetails: ${JSON.stringify(details, undefined, 2)}`;
|
|
13
26
|
}
|
|
14
27
|
}
|
|
15
28
|
msg += '\nStack Trace: ';
|
|
@@ -19,35 +32,35 @@ function createMessage(message: string, request: Request, status: number, payloa
|
|
|
19
32
|
|
|
20
33
|
export class RequestError extends Error {
|
|
21
34
|
status: number;
|
|
22
|
-
payload:
|
|
35
|
+
payload: unknown;
|
|
23
36
|
request: Request;
|
|
24
37
|
request_info: string;
|
|
25
38
|
displayDetails: boolean;
|
|
26
39
|
original_message: string;
|
|
27
|
-
constructor(message: string, request: Request, status: number, payload:
|
|
40
|
+
constructor(message: string, request: Request, status: number, payload: unknown, displayDetails = true) {
|
|
28
41
|
super(createMessage(message, request, status, payload, displayDetails));
|
|
29
42
|
this.original_message = message;
|
|
30
43
|
this.request = request;
|
|
31
44
|
this.status = status;
|
|
32
45
|
this.payload = payload;
|
|
33
|
-
this.request_info = request.method
|
|
46
|
+
this.request_info = `${request.method} ${request.url} => ${status}`;
|
|
34
47
|
this.displayDetails = displayDetails;
|
|
35
48
|
}
|
|
36
49
|
|
|
37
50
|
get details() {
|
|
38
|
-
return this.payload
|
|
51
|
+
return getDetails(this.payload);
|
|
39
52
|
}
|
|
40
|
-
|
|
41
53
|
}
|
|
42
54
|
|
|
43
55
|
export class ServerError extends RequestError {
|
|
44
|
-
constructor(message: string, req: Request, status: number, payload:
|
|
56
|
+
constructor(message: string, req: Request, status: number, payload: unknown, displayDetails = true) {
|
|
45
57
|
super(message, req, status, payload, displayDetails);
|
|
46
58
|
}
|
|
47
59
|
|
|
48
|
-
updateDetails(details:
|
|
60
|
+
updateDetails(details: unknown) {
|
|
49
61
|
if (details !== this.details) {
|
|
50
|
-
|
|
62
|
+
const payload = isRecord(this.payload) ? { ...this.payload, details } : { details };
|
|
63
|
+
return new ServerError(this.original_message, this.request, this.status, payload, this.displayDetails);
|
|
51
64
|
} else {
|
|
52
65
|
return this;
|
|
53
66
|
}
|
|
@@ -56,6 +69,6 @@ export class ServerError extends RequestError {
|
|
|
56
69
|
|
|
57
70
|
export class ConnectionError extends RequestError {
|
|
58
71
|
constructor(req: Request, err: Error) {
|
|
59
|
-
super(
|
|
72
|
+
super(`Failed to connect to server: ${err.message}`, req, 0, err);
|
|
60
73
|
}
|
|
61
74
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
1
|
+
export * from './base.js';
|
|
2
|
+
export * from './client.js';
|
|
3
|
+
export * from './errors.js';
|
|
4
|
+
export * from './sse/index.js';
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { createParser,
|
|
1
|
+
import { createParser, type EventSourceMessage, type EventSourceParser } from 'eventsource-parser';
|
|
2
|
+
|
|
3
|
+
export type ParsedEvent = EventSourceMessage & { type: 'event' };
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* We copied this file from the eventsource-parser/stream package and made it a part of our project.
|
|
5
7
|
* because importing the eventsource-parser/stream breaks tsc build when building the commonjs version
|
|
6
|
-
* see for a similar error:
|
|
8
|
+
* see for a similar error:
|
|
7
9
|
* https://stackoverflow.com/questions/77280140/why-typescript-dont-see-exports-of-package-with-module-commonjs-and-moduleres
|
|
8
10
|
*/
|
|
9
11
|
|
|
@@ -21,19 +23,20 @@ import { createParser, ReconnectInterval, type EventSourceParser, type ParsedEve
|
|
|
21
23
|
*/
|
|
22
24
|
export class EventSourceParserStream extends TransformStream<string, ParsedEvent> {
|
|
23
25
|
constructor() {
|
|
24
|
-
let parser!: EventSourceParser
|
|
26
|
+
let parser!: EventSourceParser;
|
|
25
27
|
|
|
26
28
|
super({
|
|
27
29
|
start(controller) {
|
|
28
|
-
parser = createParser(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
parser = createParser({
|
|
31
|
+
onEvent(event) {
|
|
32
|
+
const parsedEvent: ParsedEvent = { type: 'event', ...event };
|
|
33
|
+
controller.enqueue(parsedEvent);
|
|
34
|
+
},
|
|
35
|
+
});
|
|
33
36
|
},
|
|
34
37
|
transform(chunk) {
|
|
35
|
-
parser.feed(chunk)
|
|
38
|
+
parser.feed(chunk);
|
|
36
39
|
},
|
|
37
|
-
})
|
|
40
|
+
});
|
|
38
41
|
}
|
|
39
42
|
}
|
|
@@ -9,14 +9,20 @@ if (globalThis.TextDecoderStream && typeof globalThis.TextDecoderStream === 'fun
|
|
|
9
9
|
} else {
|
|
10
10
|
class MyTextDecoderStream extends TransformStream<ArrayBuffer | Uint8Array, string> {
|
|
11
11
|
private _options: {
|
|
12
|
-
encoding: string
|
|
13
|
-
fatal?: boolean
|
|
14
|
-
ignoreBOM?: boolean
|
|
15
|
-
}
|
|
16
|
-
constructor(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
encoding: string;
|
|
13
|
+
fatal?: boolean;
|
|
14
|
+
ignoreBOM?: boolean;
|
|
15
|
+
};
|
|
16
|
+
constructor(
|
|
17
|
+
encoding = 'utf-8',
|
|
18
|
+
{
|
|
19
|
+
fatal = false,
|
|
20
|
+
ignoreBOM = false,
|
|
21
|
+
}: {
|
|
22
|
+
fatal?: boolean;
|
|
23
|
+
ignoreBOM?: boolean;
|
|
24
|
+
} = {},
|
|
25
|
+
) {
|
|
20
26
|
super(new TextDecodeTransformer(new TextDecoder(encoding, { fatal, ignoreBOM })));
|
|
21
27
|
this._options = { fatal, ignoreBOM, encoding };
|
|
22
28
|
}
|
|
@@ -40,7 +46,7 @@ if (globalThis.TextDecoderStream && typeof globalThis.TextDecoderStream === 'fun
|
|
|
40
46
|
|
|
41
47
|
transform(chunk: ArrayBuffer | Uint8Array, controller: TransformStreamDefaultController<string>) {
|
|
42
48
|
if (!(chunk instanceof ArrayBuffer || ArrayBuffer.isView(chunk))) {
|
|
43
|
-
throw new TypeError(
|
|
49
|
+
throw new TypeError('Input must be a compatible with: ArrayBuffer | Uint8Array');
|
|
44
50
|
}
|
|
45
51
|
const text = this.decoder.decode(chunk, { stream: true });
|
|
46
52
|
if (text.length !== 0) {
|
|
@@ -55,8 +61,7 @@ if (globalThis.TextDecoderStream && typeof globalThis.TextDecoderStream === 'fun
|
|
|
55
61
|
}
|
|
56
62
|
}
|
|
57
63
|
}
|
|
58
|
-
_TextDecoderStream = MyTextDecoderStream as
|
|
64
|
+
_TextDecoderStream = MyTextDecoderStream as typeof TextDecoderStream;
|
|
59
65
|
}
|
|
60
66
|
|
|
61
67
|
export { _TextDecoderStream as TextDecoderStream };
|
|
62
|
-
|
package/src/sse/index.ts
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { EventSourceParserStream, type ParsedEvent } from './EventSourceParserStream.js';
|
|
2
|
+
import { TextDecoderStream } from './TextDecoderStream.js';
|
|
3
|
+
|
|
4
|
+
export type { ParsedEvent };
|
|
5
|
+
|
|
6
|
+
export interface ReconnectInterval {
|
|
7
|
+
type: 'reconnect-interval';
|
|
8
|
+
value: number;
|
|
9
|
+
}
|
|
4
10
|
|
|
5
11
|
export type ServerSentEvent = ParsedEvent | ReconnectInterval;
|
|
6
12
|
/**
|
|
7
13
|
* A SSE response reader.
|
|
8
14
|
* Usage client.get('/path', {reader: sse}) or client.post('/path', {reader: sse})
|
|
9
15
|
* where sse is this function
|
|
10
|
-
* @param response
|
|
11
|
-
* @returns
|
|
16
|
+
* @param response
|
|
17
|
+
* @returns
|
|
12
18
|
*/
|
|
13
19
|
export async function sse(response: Response): Promise<ReadableStream<ServerSentEvent>> {
|
|
14
20
|
if (!response.ok) {
|
|
15
21
|
const text = await response.text();
|
|
16
|
-
const error = new Error(
|
|
17
|
-
|
|
22
|
+
const error = new Error(`SSE error: ${response.status}. Content:\n${text}`) as Error & { status?: number };
|
|
23
|
+
error.status = response.status;
|
|
18
24
|
throw error;
|
|
19
25
|
}
|
|
20
26
|
if (!response.body) {
|
|
@@ -24,4 +30,4 @@ export async function sse(response: Response): Promise<ReadableStream<ServerSent
|
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
// re-export TextDecoderStream (in case it was polyfilled)
|
|
27
|
-
export { TextDecoderStream }
|
|
33
|
+
export { TextDecoderStream };
|
package/src/utils.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
export function buildQueryString(query: any) {
|
|
1
|
+
export function buildQueryString(query: Record<string, unknown>) {
|
|
3
2
|
const parts = [];
|
|
4
3
|
for (const key of Object.keys(query)) {
|
|
5
4
|
const val = query[key];
|
|
6
5
|
if (val != null) {
|
|
7
|
-
parts.push(encodeURIComponent(key)
|
|
6
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(val))}`);
|
|
8
7
|
}
|
|
9
8
|
}
|
|
10
|
-
return parts.join(
|
|
9
|
+
return parts.join('&');
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
export function join(left: string, right: string) {
|
|
@@ -20,7 +19,7 @@ export function join(left: string, right: string) {
|
|
|
20
19
|
} else if (right.startsWith('/')) {
|
|
21
20
|
return left + right;
|
|
22
21
|
} else {
|
|
23
|
-
return left
|
|
22
|
+
return `${left}/${right}`;
|
|
24
23
|
}
|
|
25
24
|
}
|
|
26
25
|
export function removeTrailingSlash(path: string) {
|
|
@@ -28,4 +27,4 @@ export function removeTrailingSlash(path: string) {
|
|
|
28
27
|
return path.slice(0, -1);
|
|
29
28
|
}
|
|
30
29
|
return path;
|
|
31
|
-
}
|
|
30
|
+
}
|
package/lib/cjs/base.js
DELETED
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ClientBase = void 0;
|
|
4
|
-
exports.fetchPromise = fetchPromise;
|
|
5
|
-
const errors_js_1 = require("./errors.js");
|
|
6
|
-
const index_js_1 = require("./sse/index.js");
|
|
7
|
-
const utils_js_1 = require("./utils.js");
|
|
8
|
-
function fetchPromise(fetchImpl) {
|
|
9
|
-
if (fetchImpl) {
|
|
10
|
-
return Promise.resolve(fetchImpl);
|
|
11
|
-
}
|
|
12
|
-
else if (typeof globalThis.fetch === 'function') {
|
|
13
|
-
return Promise.resolve(globalThis.fetch);
|
|
14
|
-
}
|
|
15
|
-
else {
|
|
16
|
-
// install an error impl
|
|
17
|
-
return Promise.resolve(() => {
|
|
18
|
-
throw new Error('No Fetch implementation found');
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
function isInvalidJsonPayload(payload) {
|
|
23
|
-
return payload?.error === "Not a valid JSON payload" && typeof payload.text === "string";
|
|
24
|
-
}
|
|
25
|
-
class ClientBase {
|
|
26
|
-
_fetch;
|
|
27
|
-
baseUrl;
|
|
28
|
-
errorFactory = (err) => err;
|
|
29
|
-
verboseErrors = true;
|
|
30
|
-
constructor(baseUrl, fetchImpl) {
|
|
31
|
-
this.baseUrl = (0, utils_js_1.removeTrailingSlash)(baseUrl);
|
|
32
|
-
this._fetch = fetchPromise(fetchImpl);
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Can be subclassed to map to custom errors
|
|
36
|
-
* @param err
|
|
37
|
-
*/
|
|
38
|
-
throwError(err) {
|
|
39
|
-
throw this.errorFactory(err);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Resolve a path to a full URL. If the path is already an absolute URL
|
|
43
|
-
* (starts with http:// or https://), it is returned as-is.
|
|
44
|
-
*/
|
|
45
|
-
getUrl(path) {
|
|
46
|
-
if (path.startsWith('http://') || path.startsWith('https://')) {
|
|
47
|
-
return (0, utils_js_1.removeTrailingSlash)(path);
|
|
48
|
-
}
|
|
49
|
-
return (0, utils_js_1.removeTrailingSlash)((0, utils_js_1.join)(this.baseUrl, path));
|
|
50
|
-
}
|
|
51
|
-
get(path, params) {
|
|
52
|
-
return this.request('GET', path, params);
|
|
53
|
-
}
|
|
54
|
-
del(path, params) {
|
|
55
|
-
return this.request('DELETE', path, params);
|
|
56
|
-
}
|
|
57
|
-
delete(path, params) {
|
|
58
|
-
return this.request('DELETE', path, params);
|
|
59
|
-
}
|
|
60
|
-
post(path, params) {
|
|
61
|
-
return this.request('POST', path, params);
|
|
62
|
-
}
|
|
63
|
-
put(path, params) {
|
|
64
|
-
return this.request('PUT', path, params);
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* You can customize the json parser by overriding this method
|
|
68
|
-
* @param text
|
|
69
|
-
* @returns
|
|
70
|
-
*/
|
|
71
|
-
jsonParse(text) {
|
|
72
|
-
return JSON.parse(text);
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Can be overridden to create the request
|
|
76
|
-
* @param fetch
|
|
77
|
-
* @param url
|
|
78
|
-
* @param init
|
|
79
|
-
* @returns
|
|
80
|
-
*/
|
|
81
|
-
createRequest(url, init) {
|
|
82
|
-
return Promise.resolve(new Request(url, init));
|
|
83
|
-
}
|
|
84
|
-
createServerError(req, res, payload) {
|
|
85
|
-
const status = res.status;
|
|
86
|
-
let message = 'Server Error: ' + status;
|
|
87
|
-
if (payload) {
|
|
88
|
-
if (isInvalidJsonPayload(payload)) {
|
|
89
|
-
message += res.statusText ? ' ' + res.statusText : '';
|
|
90
|
-
message += ': non-JSON response';
|
|
91
|
-
}
|
|
92
|
-
else if (payload.message) {
|
|
93
|
-
message = String(payload.message);
|
|
94
|
-
}
|
|
95
|
-
else if (payload.error) {
|
|
96
|
-
if (typeof payload.error === 'string') {
|
|
97
|
-
message = String(payload.error);
|
|
98
|
-
}
|
|
99
|
-
else if (typeof payload.error.message === 'string') {
|
|
100
|
-
message = String(payload.error.message);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return new errors_js_1.ServerError(message, req, res.status, payload, this.verboseErrors);
|
|
105
|
-
}
|
|
106
|
-
async readJSONPayload(res) {
|
|
107
|
-
return res.text().then(text => {
|
|
108
|
-
if (!text) {
|
|
109
|
-
return undefined;
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
try {
|
|
113
|
-
return this.jsonParse(text);
|
|
114
|
-
}
|
|
115
|
-
catch (err) {
|
|
116
|
-
return {
|
|
117
|
-
status: res.status,
|
|
118
|
-
error: "Not a valid JSON payload",
|
|
119
|
-
message: err.message,
|
|
120
|
-
text: text,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}).catch((err) => {
|
|
125
|
-
return {
|
|
126
|
-
status: res.status,
|
|
127
|
-
error: "Unable to load response content",
|
|
128
|
-
message: err.message,
|
|
129
|
-
};
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Subclasses You can override this to do something with the response
|
|
134
|
-
* @param res
|
|
135
|
-
*/
|
|
136
|
-
handleResponse(req, res, params) {
|
|
137
|
-
if (params && params.reader) {
|
|
138
|
-
if (params.reader === 'sse') {
|
|
139
|
-
return (0, index_js_1.sse)(res);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
return params.reader.call(this, res);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
return this.readJSONPayload(res).then((payload) => {
|
|
147
|
-
if (res.ok) {
|
|
148
|
-
return payload;
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
this.throwError(this.createServerError(req, res, payload));
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
async request(method, path, params) {
|
|
157
|
-
let url = this.getUrl(path);
|
|
158
|
-
if (params?.query) {
|
|
159
|
-
url += '?' + (0, utils_js_1.buildQueryString)(params.query);
|
|
160
|
-
}
|
|
161
|
-
const headers = this.headers ? Object.assign({}, this.headers) : {};
|
|
162
|
-
const paramsHeaders = params?.headers;
|
|
163
|
-
if (paramsHeaders) {
|
|
164
|
-
for (const key in paramsHeaders) {
|
|
165
|
-
headers[key.toLowerCase()] = paramsHeaders[key];
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
let body;
|
|
169
|
-
const payload = params?.payload;
|
|
170
|
-
if (payload) {
|
|
171
|
-
if (params && params.jsonPayload === false) {
|
|
172
|
-
body = payload;
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
body = (typeof payload !== 'string') ? JSON.stringify(payload) : payload;
|
|
176
|
-
if (!('content-type' in headers)) {
|
|
177
|
-
headers['content-type'] = 'application/json';
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
// When using SSE reader, ensure the Accept header requests event-stream
|
|
182
|
-
if (params?.reader === 'sse' && !('accept' in headers)) {
|
|
183
|
-
headers['accept'] = 'text/event-stream';
|
|
184
|
-
}
|
|
185
|
-
const init = {
|
|
186
|
-
method: method,
|
|
187
|
-
headers: headers,
|
|
188
|
-
body: body,
|
|
189
|
-
};
|
|
190
|
-
const req = await this.createRequest(url, init);
|
|
191
|
-
return this._fetch.then(fetch => fetch(req).catch(err => {
|
|
192
|
-
console.error(`Failed to connect to ${url}`, err);
|
|
193
|
-
this.throwError(new errors_js_1.ConnectionError(req, err));
|
|
194
|
-
}).then(res => {
|
|
195
|
-
return this.handleResponse(req, res, params);
|
|
196
|
-
}));
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Perform a request and consume the response as an SSE stream.
|
|
200
|
-
* Calls `onEvent` for each parsed SSE event, then returns the last event.
|
|
201
|
-
*
|
|
202
|
-
* @param method HTTP method
|
|
203
|
-
* @param path URL path (relative to baseUrl) or absolute URL (http:// or https://)
|
|
204
|
-
* @param params Request parameters (payload, headers, query)
|
|
205
|
-
* @param onEvent Callback for each SSE event
|
|
206
|
-
* @returns The last SSE event received, or undefined if the stream was empty
|
|
207
|
-
*/
|
|
208
|
-
async sseRequest(method, path, params, onEvent) {
|
|
209
|
-
const stream = await this.request(method, path, {
|
|
210
|
-
...params,
|
|
211
|
-
reader: 'sse',
|
|
212
|
-
});
|
|
213
|
-
const reader = stream.getReader();
|
|
214
|
-
let lastEvent;
|
|
215
|
-
try {
|
|
216
|
-
while (true) {
|
|
217
|
-
const { done, value } = await reader.read();
|
|
218
|
-
if (done)
|
|
219
|
-
break;
|
|
220
|
-
lastEvent = value;
|
|
221
|
-
onEvent(value);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
finally {
|
|
225
|
-
reader.releaseLock();
|
|
226
|
-
}
|
|
227
|
-
return lastEvent;
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Expose the fetch method
|
|
231
|
-
* @param input
|
|
232
|
-
* @param init
|
|
233
|
-
* @returns
|
|
234
|
-
*/
|
|
235
|
-
fetch(input, init) {
|
|
236
|
-
return this._fetch.then(fetch => fetch(input, init));
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
exports.ClientBase = ClientBase;
|
|
240
|
-
//# sourceMappingURL=base.js.map
|
package/lib/cjs/base.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/base.ts"],"names":[],"mappings":"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"}
|