@predictorsdk/client 0.1.0
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/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/BaseClient.d.ts +39 -0
- package/dist/BaseClient.js +28 -0
- package/dist/Client.d.ts +41 -0
- package/dist/Client.js +101 -0
- package/dist/api/client/index.d.ts +1 -0
- package/dist/api/client/index.js +1 -0
- package/dist/api/client/requests/GetSportsMatchingMarketsRequest.d.ts +14 -0
- package/dist/api/client/requests/GetSportsMatchingMarketsRequest.js +2 -0
- package/dist/api/client/requests/index.d.ts +1 -0
- package/dist/api/client/requests/index.js +1 -0
- package/dist/api/errors/BadRequestError.d.ts +6 -0
- package/dist/api/errors/BadRequestError.js +17 -0
- package/dist/api/errors/ForbiddenError.d.ts +6 -0
- package/dist/api/errors/ForbiddenError.js +17 -0
- package/dist/api/errors/ServiceUnavailableError.d.ts +6 -0
- package/dist/api/errors/ServiceUnavailableError.js +17 -0
- package/dist/api/errors/TooManyRequestsError.d.ts +6 -0
- package/dist/api/errors/TooManyRequestsError.js +17 -0
- package/dist/api/errors/UnauthorizedError.d.ts +6 -0
- package/dist/api/errors/UnauthorizedError.js +17 -0
- package/dist/api/errors/index.d.ts +5 -0
- package/dist/api/errors/index.js +5 -0
- package/dist/api/index.d.ts +3 -0
- package/dist/api/index.js +3 -0
- package/dist/api/types/ErrorResponse.d.ts +4 -0
- package/dist/api/types/ErrorResponse.js +2 -0
- package/dist/api/types/PlatformMarket.d.ts +24 -0
- package/dist/api/types/PlatformMarket.js +10 -0
- package/dist/api/types/SportsMatchingResponse.d.ts +5 -0
- package/dist/api/types/SportsMatchingResponse.js +2 -0
- package/dist/api/types/index.d.ts +3 -0
- package/dist/api/types/index.js +3 -0
- package/dist/auth/BearerAuthProvider.d.ts +20 -0
- package/dist/auth/BearerAuthProvider.js +32 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.js +1 -0
- package/dist/core/auth/AuthProvider.d.ts +7 -0
- package/dist/core/auth/AuthProvider.js +1 -0
- package/dist/core/auth/AuthRequest.d.ts +9 -0
- package/dist/core/auth/AuthRequest.js +1 -0
- package/dist/core/auth/BasicAuth.d.ts +8 -0
- package/dist/core/auth/BasicAuth.js +24 -0
- package/dist/core/auth/BearerToken.d.ts +7 -0
- package/dist/core/auth/BearerToken.js +13 -0
- package/dist/core/auth/NoOpAuthProvider.d.ts +5 -0
- package/dist/core/auth/NoOpAuthProvider.js +5 -0
- package/dist/core/auth/index.d.ts +5 -0
- package/dist/core/auth/index.js +3 -0
- package/dist/core/base64.d.ts +2 -0
- package/dist/core/base64.js +22 -0
- package/dist/core/exports.d.ts +1 -0
- package/dist/core/exports.js +1 -0
- package/dist/core/fetcher/APIResponse.d.ts +20 -0
- package/dist/core/fetcher/APIResponse.js +1 -0
- package/dist/core/fetcher/BinaryResponse.d.ts +19 -0
- package/dist/core/fetcher/BinaryResponse.js +14 -0
- package/dist/core/fetcher/EndpointMetadata.d.ts +13 -0
- package/dist/core/fetcher/EndpointMetadata.js +1 -0
- package/dist/core/fetcher/EndpointSupplier.d.ts +12 -0
- package/dist/core/fetcher/EndpointSupplier.js +10 -0
- package/dist/core/fetcher/Fetcher.d.ts +50 -0
- package/dist/core/fetcher/Fetcher.js +305 -0
- package/dist/core/fetcher/Headers.d.ts +2 -0
- package/dist/core/fetcher/Headers.js +83 -0
- package/dist/core/fetcher/HttpResponsePromise.d.ts +58 -0
- package/dist/core/fetcher/HttpResponsePromise.js +90 -0
- package/dist/core/fetcher/RawResponse.d.ts +29 -0
- package/dist/core/fetcher/RawResponse.js +40 -0
- package/dist/core/fetcher/Supplier.d.ts +4 -0
- package/dist/core/fetcher/Supplier.js +10 -0
- package/dist/core/fetcher/createRequestUrl.d.ts +1 -0
- package/dist/core/fetcher/createRequestUrl.js +5 -0
- package/dist/core/fetcher/getErrorResponseBody.d.ts +1 -0
- package/dist/core/fetcher/getErrorResponseBody.js +30 -0
- package/dist/core/fetcher/getFetchFn.d.ts +1 -0
- package/dist/core/fetcher/getFetchFn.js +3 -0
- package/dist/core/fetcher/getHeader.d.ts +1 -0
- package/dist/core/fetcher/getHeader.js +8 -0
- package/dist/core/fetcher/getRequestBody.d.ts +7 -0
- package/dist/core/fetcher/getRequestBody.js +13 -0
- package/dist/core/fetcher/getResponseBody.d.ts +1 -0
- package/dist/core/fetcher/getResponseBody.js +55 -0
- package/dist/core/fetcher/index.d.ts +13 -0
- package/dist/core/fetcher/index.js +7 -0
- package/dist/core/fetcher/makePassthroughRequest.d.ts +49 -0
- package/dist/core/fetcher/makePassthroughRequest.js +119 -0
- package/dist/core/fetcher/makeRequest.d.ts +6 -0
- package/dist/core/fetcher/makeRequest.js +53 -0
- package/dist/core/fetcher/requestWithRetries.d.ts +1 -0
- package/dist/core/fetcher/requestWithRetries.js +53 -0
- package/dist/core/fetcher/signals.d.ts +5 -0
- package/dist/core/fetcher/signals.js +20 -0
- package/dist/core/headers.d.ts +2 -0
- package/dist/core/headers.js +27 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.js +6 -0
- package/dist/core/json.d.ts +15 -0
- package/dist/core/json.js +19 -0
- package/dist/core/logging/exports.d.ts +18 -0
- package/dist/core/logging/exports.js +9 -0
- package/dist/core/logging/index.d.ts +1 -0
- package/dist/core/logging/index.js +1 -0
- package/dist/core/logging/logger.d.ts +126 -0
- package/dist/core/logging/logger.js +140 -0
- package/dist/core/runtime/index.d.ts +1 -0
- package/dist/core/runtime/index.js +1 -0
- package/dist/core/runtime/runtime.d.ts +9 -0
- package/dist/core/runtime/runtime.js +100 -0
- package/dist/core/url/encodePathParam.d.ts +1 -0
- package/dist/core/url/encodePathParam.js +18 -0
- package/dist/core/url/index.d.ts +3 -0
- package/dist/core/url/index.js +3 -0
- package/dist/core/url/join.d.ts +1 -0
- package/dist/core/url/join.js +65 -0
- package/dist/core/url/qs.d.ts +6 -0
- package/dist/core/url/qs.js +64 -0
- package/dist/environments.d.ts +4 -0
- package/dist/environments.js +4 -0
- package/dist/errors/PredictorSDKError.d.ts +14 -0
- package/dist/errors/PredictorSDKError.js +35 -0
- package/dist/errors/PredictorSDKTimeoutError.d.ts +6 -0
- package/dist/errors/PredictorSDKTimeoutError.js +15 -0
- package/dist/errors/handleNonStatusCodeError.d.ts +2 -0
- package/dist/errors/handleNonStatusCodeError.js +32 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.js +2 -0
- package/dist/exports.d.ts +1 -0
- package/dist/exports.js +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/package.json +42 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { WithRawResponse } from "./RawResponse.js";
|
|
2
|
+
/**
|
|
3
|
+
* A promise that returns the parsed response and lets you retrieve the raw response too.
|
|
4
|
+
*/
|
|
5
|
+
export declare class HttpResponsePromise<T> extends Promise<T> {
|
|
6
|
+
private innerPromise;
|
|
7
|
+
private unwrappedPromise;
|
|
8
|
+
private constructor();
|
|
9
|
+
/**
|
|
10
|
+
* Creates an `HttpResponsePromise` from a function that returns a promise.
|
|
11
|
+
*
|
|
12
|
+
* @param fn - A function that returns a promise resolving to a `WithRawResponse` object.
|
|
13
|
+
* @param args - Arguments to pass to the function.
|
|
14
|
+
* @returns An `HttpResponsePromise` instance.
|
|
15
|
+
*/
|
|
16
|
+
static fromFunction<F extends (...args: never[]) => Promise<WithRawResponse<T>>, T>(fn: F, ...args: Parameters<F>): HttpResponsePromise<T>;
|
|
17
|
+
/**
|
|
18
|
+
* Creates a function that returns an `HttpResponsePromise` from a function that returns a promise.
|
|
19
|
+
*
|
|
20
|
+
* @param fn - A function that returns a promise resolving to a `WithRawResponse` object.
|
|
21
|
+
* @returns A function that returns an `HttpResponsePromise` instance.
|
|
22
|
+
*/
|
|
23
|
+
static interceptFunction<F extends (...args: never[]) => Promise<WithRawResponse<T>>, T = Awaited<ReturnType<F>>["data"]>(fn: F): (...args: Parameters<F>) => HttpResponsePromise<T>;
|
|
24
|
+
/**
|
|
25
|
+
* Creates an `HttpResponsePromise` from an existing promise.
|
|
26
|
+
*
|
|
27
|
+
* @param promise - A promise resolving to a `WithRawResponse` object.
|
|
28
|
+
* @returns An `HttpResponsePromise` instance.
|
|
29
|
+
*/
|
|
30
|
+
static fromPromise<T>(promise: Promise<WithRawResponse<T>>): HttpResponsePromise<T>;
|
|
31
|
+
/**
|
|
32
|
+
* Creates an `HttpResponsePromise` from an executor function.
|
|
33
|
+
*
|
|
34
|
+
* @param executor - A function that takes resolve and reject callbacks to create a promise.
|
|
35
|
+
* @returns An `HttpResponsePromise` instance.
|
|
36
|
+
*/
|
|
37
|
+
static fromExecutor<T>(executor: (resolve: (value: WithRawResponse<T>) => void, reject: (reason?: unknown) => void) => void): HttpResponsePromise<T>;
|
|
38
|
+
/**
|
|
39
|
+
* Creates an `HttpResponsePromise` from a resolved result.
|
|
40
|
+
*
|
|
41
|
+
* @param result - A `WithRawResponse` object to resolve immediately.
|
|
42
|
+
* @returns An `HttpResponsePromise` instance.
|
|
43
|
+
*/
|
|
44
|
+
static fromResult<T>(result: WithRawResponse<T>): HttpResponsePromise<T>;
|
|
45
|
+
private unwrap;
|
|
46
|
+
/** @inheritdoc */
|
|
47
|
+
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
48
|
+
/** @inheritdoc */
|
|
49
|
+
catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<T | TResult>;
|
|
50
|
+
/** @inheritdoc */
|
|
51
|
+
finally(onfinally?: (() => void) | null): Promise<T>;
|
|
52
|
+
/**
|
|
53
|
+
* Retrieves the data and raw response.
|
|
54
|
+
*
|
|
55
|
+
* @returns A promise resolving to a `WithRawResponse` object.
|
|
56
|
+
*/
|
|
57
|
+
withRawResponse(): Promise<WithRawResponse<T>>;
|
|
58
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A promise that returns the parsed response and lets you retrieve the raw response too.
|
|
3
|
+
*/
|
|
4
|
+
export class HttpResponsePromise extends Promise {
|
|
5
|
+
innerPromise;
|
|
6
|
+
unwrappedPromise;
|
|
7
|
+
constructor(promise) {
|
|
8
|
+
// Initialize with a no-op to avoid premature parsing
|
|
9
|
+
super((resolve) => {
|
|
10
|
+
resolve(undefined);
|
|
11
|
+
});
|
|
12
|
+
this.innerPromise = promise;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates an `HttpResponsePromise` from a function that returns a promise.
|
|
16
|
+
*
|
|
17
|
+
* @param fn - A function that returns a promise resolving to a `WithRawResponse` object.
|
|
18
|
+
* @param args - Arguments to pass to the function.
|
|
19
|
+
* @returns An `HttpResponsePromise` instance.
|
|
20
|
+
*/
|
|
21
|
+
static fromFunction(fn, ...args) {
|
|
22
|
+
return new HttpResponsePromise(fn(...args));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates a function that returns an `HttpResponsePromise` from a function that returns a promise.
|
|
26
|
+
*
|
|
27
|
+
* @param fn - A function that returns a promise resolving to a `WithRawResponse` object.
|
|
28
|
+
* @returns A function that returns an `HttpResponsePromise` instance.
|
|
29
|
+
*/
|
|
30
|
+
static interceptFunction(fn) {
|
|
31
|
+
return (...args) => {
|
|
32
|
+
return HttpResponsePromise.fromPromise(fn(...args));
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Creates an `HttpResponsePromise` from an existing promise.
|
|
37
|
+
*
|
|
38
|
+
* @param promise - A promise resolving to a `WithRawResponse` object.
|
|
39
|
+
* @returns An `HttpResponsePromise` instance.
|
|
40
|
+
*/
|
|
41
|
+
static fromPromise(promise) {
|
|
42
|
+
return new HttpResponsePromise(promise);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates an `HttpResponsePromise` from an executor function.
|
|
46
|
+
*
|
|
47
|
+
* @param executor - A function that takes resolve and reject callbacks to create a promise.
|
|
48
|
+
* @returns An `HttpResponsePromise` instance.
|
|
49
|
+
*/
|
|
50
|
+
static fromExecutor(executor) {
|
|
51
|
+
const promise = new Promise(executor);
|
|
52
|
+
return new HttpResponsePromise(promise);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Creates an `HttpResponsePromise` from a resolved result.
|
|
56
|
+
*
|
|
57
|
+
* @param result - A `WithRawResponse` object to resolve immediately.
|
|
58
|
+
* @returns An `HttpResponsePromise` instance.
|
|
59
|
+
*/
|
|
60
|
+
static fromResult(result) {
|
|
61
|
+
const promise = Promise.resolve(result);
|
|
62
|
+
return new HttpResponsePromise(promise);
|
|
63
|
+
}
|
|
64
|
+
unwrap() {
|
|
65
|
+
if (!this.unwrappedPromise) {
|
|
66
|
+
this.unwrappedPromise = this.innerPromise.then(({ data }) => data);
|
|
67
|
+
}
|
|
68
|
+
return this.unwrappedPromise;
|
|
69
|
+
}
|
|
70
|
+
/** @inheritdoc */
|
|
71
|
+
then(onfulfilled, onrejected) {
|
|
72
|
+
return this.unwrap().then(onfulfilled, onrejected);
|
|
73
|
+
}
|
|
74
|
+
/** @inheritdoc */
|
|
75
|
+
catch(onrejected) {
|
|
76
|
+
return this.unwrap().catch(onrejected);
|
|
77
|
+
}
|
|
78
|
+
/** @inheritdoc */
|
|
79
|
+
finally(onfinally) {
|
|
80
|
+
return this.unwrap().finally(onfinally);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Retrieves the data and raw response.
|
|
84
|
+
*
|
|
85
|
+
* @returns A promise resolving to a `WithRawResponse` object.
|
|
86
|
+
*/
|
|
87
|
+
async withRawResponse() {
|
|
88
|
+
return await this.innerPromise;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The raw response from the fetch call excluding the body.
|
|
3
|
+
*/
|
|
4
|
+
export type RawResponse = Omit<{
|
|
5
|
+
[K in keyof Response as Response[K] extends Function ? never : K]: Response[K];
|
|
6
|
+
}, "ok" | "body" | "bodyUsed">;
|
|
7
|
+
/**
|
|
8
|
+
* A raw response indicating that the request was aborted.
|
|
9
|
+
*/
|
|
10
|
+
export declare const abortRawResponse: RawResponse;
|
|
11
|
+
/**
|
|
12
|
+
* A raw response indicating an unknown error.
|
|
13
|
+
*/
|
|
14
|
+
export declare const unknownRawResponse: RawResponse;
|
|
15
|
+
/**
|
|
16
|
+
* Converts a `RawResponse` object into a `RawResponse` by extracting its properties,
|
|
17
|
+
* excluding the `body` and `bodyUsed` fields.
|
|
18
|
+
*
|
|
19
|
+
* @param response - The `RawResponse` object to convert.
|
|
20
|
+
* @returns A `RawResponse` object containing the extracted properties of the input response.
|
|
21
|
+
*/
|
|
22
|
+
export declare function toRawResponse(response: Response): RawResponse;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a `RawResponse` from a standard `Response` object.
|
|
25
|
+
*/
|
|
26
|
+
export interface WithRawResponse<T> {
|
|
27
|
+
readonly data: T;
|
|
28
|
+
readonly rawResponse: RawResponse;
|
|
29
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Headers } from "./Headers.js";
|
|
2
|
+
/**
|
|
3
|
+
* A raw response indicating that the request was aborted.
|
|
4
|
+
*/
|
|
5
|
+
export const abortRawResponse = {
|
|
6
|
+
headers: new Headers(),
|
|
7
|
+
redirected: false,
|
|
8
|
+
status: 499,
|
|
9
|
+
statusText: "Client Closed Request",
|
|
10
|
+
type: "error",
|
|
11
|
+
url: "",
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* A raw response indicating an unknown error.
|
|
15
|
+
*/
|
|
16
|
+
export const unknownRawResponse = {
|
|
17
|
+
headers: new Headers(),
|
|
18
|
+
redirected: false,
|
|
19
|
+
status: 0,
|
|
20
|
+
statusText: "Unknown Error",
|
|
21
|
+
type: "error",
|
|
22
|
+
url: "",
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Converts a `RawResponse` object into a `RawResponse` by extracting its properties,
|
|
26
|
+
* excluding the `body` and `bodyUsed` fields.
|
|
27
|
+
*
|
|
28
|
+
* @param response - The `RawResponse` object to convert.
|
|
29
|
+
* @returns A `RawResponse` object containing the extracted properties of the input response.
|
|
30
|
+
*/
|
|
31
|
+
export function toRawResponse(response) {
|
|
32
|
+
return {
|
|
33
|
+
headers: response.headers,
|
|
34
|
+
redirected: response.redirected,
|
|
35
|
+
status: response.status,
|
|
36
|
+
statusText: response.statusText,
|
|
37
|
+
type: response.type,
|
|
38
|
+
url: response.url,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createRequestUrl(baseUrl: string, queryParameters?: Record<string, unknown>): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getErrorResponseBody(response: Response): Promise<unknown>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { fromJson } from "../json.js";
|
|
2
|
+
import { getResponseBody } from "./getResponseBody.js";
|
|
3
|
+
export async function getErrorResponseBody(response) {
|
|
4
|
+
let contentType = response.headers.get("Content-Type")?.toLowerCase();
|
|
5
|
+
if (contentType == null || contentType.length === 0) {
|
|
6
|
+
return getResponseBody(response);
|
|
7
|
+
}
|
|
8
|
+
if (contentType.indexOf(";") !== -1) {
|
|
9
|
+
contentType = contentType.split(";")[0]?.trim() ?? "";
|
|
10
|
+
}
|
|
11
|
+
switch (contentType) {
|
|
12
|
+
case "application/hal+json":
|
|
13
|
+
case "application/json":
|
|
14
|
+
case "application/ld+json":
|
|
15
|
+
case "application/problem+json":
|
|
16
|
+
case "application/vnd.api+json":
|
|
17
|
+
case "text/json": {
|
|
18
|
+
const text = await response.text();
|
|
19
|
+
return text.length > 0 ? fromJson(text) : undefined;
|
|
20
|
+
}
|
|
21
|
+
default:
|
|
22
|
+
if (contentType.startsWith("application/vnd.") && contentType.endsWith("+json")) {
|
|
23
|
+
const text = await response.text();
|
|
24
|
+
return text.length > 0 ? fromJson(text) : undefined;
|
|
25
|
+
}
|
|
26
|
+
// Fallback to plain text if content type is not recognized
|
|
27
|
+
// Even if no body is present, the response will be an empty string
|
|
28
|
+
return await response.text();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getFetchFn(): Promise<typeof fetch>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getHeader(headers: Record<string, any>, header: string): string | undefined;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { toJson } from "../json.js";
|
|
2
|
+
import { toQueryString } from "../url/qs.js";
|
|
3
|
+
export async function getRequestBody({ body, type }) {
|
|
4
|
+
if (type === "form") {
|
|
5
|
+
return toQueryString(body, { arrayFormat: "repeat", encode: true });
|
|
6
|
+
}
|
|
7
|
+
if (type.includes("json")) {
|
|
8
|
+
return toJson(body);
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
return body;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getResponseBody(response: Response, responseType?: string): Promise<unknown>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { fromJson } from "../json.js";
|
|
2
|
+
import { getBinaryResponse } from "./BinaryResponse.js";
|
|
3
|
+
export async function getResponseBody(response, responseType) {
|
|
4
|
+
switch (responseType) {
|
|
5
|
+
case "binary-response":
|
|
6
|
+
return getBinaryResponse(response);
|
|
7
|
+
case "blob":
|
|
8
|
+
return await response.blob();
|
|
9
|
+
case "arrayBuffer":
|
|
10
|
+
return await response.arrayBuffer();
|
|
11
|
+
case "sse":
|
|
12
|
+
if (response.body == null) {
|
|
13
|
+
return {
|
|
14
|
+
ok: false,
|
|
15
|
+
error: {
|
|
16
|
+
reason: "body-is-null",
|
|
17
|
+
statusCode: response.status,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return response.body;
|
|
22
|
+
case "streaming":
|
|
23
|
+
if (response.body == null) {
|
|
24
|
+
return {
|
|
25
|
+
ok: false,
|
|
26
|
+
error: {
|
|
27
|
+
reason: "body-is-null",
|
|
28
|
+
statusCode: response.status,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return response.body;
|
|
33
|
+
case "text":
|
|
34
|
+
return await response.text();
|
|
35
|
+
}
|
|
36
|
+
// if responseType is "json" or not specified, try to parse as JSON
|
|
37
|
+
const text = await response.text();
|
|
38
|
+
if (text.length > 0) {
|
|
39
|
+
try {
|
|
40
|
+
const responseBody = fromJson(text);
|
|
41
|
+
return responseBody;
|
|
42
|
+
}
|
|
43
|
+
catch (_err) {
|
|
44
|
+
return {
|
|
45
|
+
ok: false,
|
|
46
|
+
error: {
|
|
47
|
+
reason: "non-json",
|
|
48
|
+
statusCode: response.status,
|
|
49
|
+
rawBody: text,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type { APIResponse } from "./APIResponse.js";
|
|
2
|
+
export type { BinaryResponse } from "./BinaryResponse.js";
|
|
3
|
+
export type { EndpointMetadata } from "./EndpointMetadata.js";
|
|
4
|
+
export { EndpointSupplier } from "./EndpointSupplier.js";
|
|
5
|
+
export type { Fetcher, FetchFunction } from "./Fetcher.js";
|
|
6
|
+
export { fetcher } from "./Fetcher.js";
|
|
7
|
+
export { getHeader } from "./getHeader.js";
|
|
8
|
+
export { HttpResponsePromise } from "./HttpResponsePromise.js";
|
|
9
|
+
export type { PassthroughRequest } from "./makePassthroughRequest.js";
|
|
10
|
+
export { makePassthroughRequest } from "./makePassthroughRequest.js";
|
|
11
|
+
export type { RawResponse, WithRawResponse } from "./RawResponse.js";
|
|
12
|
+
export { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js";
|
|
13
|
+
export { Supplier } from "./Supplier.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { EndpointSupplier } from "./EndpointSupplier.js";
|
|
2
|
+
export { fetcher } from "./Fetcher.js";
|
|
3
|
+
export { getHeader } from "./getHeader.js";
|
|
4
|
+
export { HttpResponsePromise } from "./HttpResponsePromise.js";
|
|
5
|
+
export { makePassthroughRequest } from "./makePassthroughRequest.js";
|
|
6
|
+
export { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js";
|
|
7
|
+
export { Supplier } from "./Supplier.js";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type LogConfig, type Logger } from "../logging/logger.js";
|
|
2
|
+
import { Supplier } from "./Supplier.js";
|
|
3
|
+
export declare namespace PassthroughRequest {
|
|
4
|
+
/**
|
|
5
|
+
* Per-request options that can override the SDK client defaults.
|
|
6
|
+
*/
|
|
7
|
+
interface RequestOptions {
|
|
8
|
+
/** Override the default timeout for this request (in seconds). */
|
|
9
|
+
timeoutInSeconds?: number;
|
|
10
|
+
/** Override the default number of retries for this request. */
|
|
11
|
+
maxRetries?: number;
|
|
12
|
+
/** Additional headers to include in this request. */
|
|
13
|
+
headers?: Record<string, string>;
|
|
14
|
+
/** Abort signal for this request. */
|
|
15
|
+
abortSignal?: AbortSignal;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* SDK client configuration used by the passthrough fetch method.
|
|
19
|
+
*/
|
|
20
|
+
interface ClientOptions {
|
|
21
|
+
/** The base URL or environment for the client. */
|
|
22
|
+
environment?: Supplier<string>;
|
|
23
|
+
/** Override the base URL. */
|
|
24
|
+
baseUrl?: Supplier<string>;
|
|
25
|
+
/** Default headers to include in requests. */
|
|
26
|
+
headers?: Record<string, unknown>;
|
|
27
|
+
/** Default maximum time to wait for a response in seconds. */
|
|
28
|
+
timeoutInSeconds?: number;
|
|
29
|
+
/** Default number of times to retry the request. Defaults to 2. */
|
|
30
|
+
maxRetries?: number;
|
|
31
|
+
/** A custom fetch function. */
|
|
32
|
+
fetch?: typeof fetch;
|
|
33
|
+
/** Logging configuration. */
|
|
34
|
+
logging?: LogConfig | Logger;
|
|
35
|
+
/** A function that returns auth headers. */
|
|
36
|
+
getAuthHeaders?: () => Promise<Record<string, string>>;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Makes a passthrough HTTP request using the SDK's configuration (auth, retry, logging, etc.)
|
|
41
|
+
* while mimicking the standard `fetch` API.
|
|
42
|
+
*
|
|
43
|
+
* @param input - The URL, path, or Request object. If a relative path, it will be resolved against the configured base URL.
|
|
44
|
+
* @param init - Standard RequestInit options (method, headers, body, signal, etc.)
|
|
45
|
+
* @param clientOptions - SDK client options (auth, default headers, logging, etc.)
|
|
46
|
+
* @param requestOptions - Per-request overrides (timeout, retries, extra headers, abort signal).
|
|
47
|
+
* @returns A standard Response object.
|
|
48
|
+
*/
|
|
49
|
+
export declare function makePassthroughRequest(input: Request | string | URL, init: RequestInit | undefined, clientOptions: PassthroughRequest.ClientOptions, requestOptions?: PassthroughRequest.RequestOptions): Promise<Response>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { createLogger } from "../logging/logger.js";
|
|
2
|
+
import { join } from "../url/join.js";
|
|
3
|
+
import { EndpointSupplier } from "./EndpointSupplier.js";
|
|
4
|
+
import { getFetchFn } from "./getFetchFn.js";
|
|
5
|
+
import { makeRequest } from "./makeRequest.js";
|
|
6
|
+
import { requestWithRetries } from "./requestWithRetries.js";
|
|
7
|
+
import { Supplier } from "./Supplier.js";
|
|
8
|
+
/**
|
|
9
|
+
* Makes a passthrough HTTP request using the SDK's configuration (auth, retry, logging, etc.)
|
|
10
|
+
* while mimicking the standard `fetch` API.
|
|
11
|
+
*
|
|
12
|
+
* @param input - The URL, path, or Request object. If a relative path, it will be resolved against the configured base URL.
|
|
13
|
+
* @param init - Standard RequestInit options (method, headers, body, signal, etc.)
|
|
14
|
+
* @param clientOptions - SDK client options (auth, default headers, logging, etc.)
|
|
15
|
+
* @param requestOptions - Per-request overrides (timeout, retries, extra headers, abort signal).
|
|
16
|
+
* @returns A standard Response object.
|
|
17
|
+
*/
|
|
18
|
+
export async function makePassthroughRequest(input, init, clientOptions, requestOptions) {
|
|
19
|
+
const logger = createLogger(clientOptions.logging);
|
|
20
|
+
// Extract URL and default init properties from Request object if provided
|
|
21
|
+
let url;
|
|
22
|
+
let effectiveInit = init;
|
|
23
|
+
if (input instanceof Request) {
|
|
24
|
+
url = input.url;
|
|
25
|
+
// If no explicit init provided, extract properties from the Request object
|
|
26
|
+
if (init == null) {
|
|
27
|
+
effectiveInit = {
|
|
28
|
+
method: input.method,
|
|
29
|
+
headers: Object.fromEntries(input.headers.entries()),
|
|
30
|
+
body: input.body,
|
|
31
|
+
signal: input.signal,
|
|
32
|
+
credentials: input.credentials,
|
|
33
|
+
cache: input.cache,
|
|
34
|
+
redirect: input.redirect,
|
|
35
|
+
referrer: input.referrer,
|
|
36
|
+
integrity: input.integrity,
|
|
37
|
+
mode: input.mode,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
url = input instanceof URL ? input.toString() : input;
|
|
43
|
+
}
|
|
44
|
+
// Resolve the base URL
|
|
45
|
+
const baseUrl = (clientOptions.baseUrl != null ? await Supplier.get(clientOptions.baseUrl) : undefined) ??
|
|
46
|
+
(clientOptions.environment != null ? await Supplier.get(clientOptions.environment) : undefined);
|
|
47
|
+
// Determine the full URL
|
|
48
|
+
let fullUrl;
|
|
49
|
+
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
50
|
+
fullUrl = url;
|
|
51
|
+
}
|
|
52
|
+
else if (baseUrl != null) {
|
|
53
|
+
fullUrl = join(baseUrl, url);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
fullUrl = url;
|
|
57
|
+
}
|
|
58
|
+
// Merge headers: SDK default headers -> auth headers -> user-provided headers
|
|
59
|
+
const mergedHeaders = {};
|
|
60
|
+
// Apply SDK default headers (resolve suppliers)
|
|
61
|
+
if (clientOptions.headers != null) {
|
|
62
|
+
for (const [key, value] of Object.entries(clientOptions.headers)) {
|
|
63
|
+
const resolved = await EndpointSupplier.get(value, { endpointMetadata: {} });
|
|
64
|
+
if (resolved != null) {
|
|
65
|
+
mergedHeaders[key.toLowerCase()] = `${resolved}`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Apply auth headers
|
|
70
|
+
if (clientOptions.getAuthHeaders != null) {
|
|
71
|
+
const authHeaders = await clientOptions.getAuthHeaders();
|
|
72
|
+
for (const [key, value] of Object.entries(authHeaders)) {
|
|
73
|
+
mergedHeaders[key.toLowerCase()] = value;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Apply user-provided headers from init
|
|
77
|
+
if (effectiveInit?.headers != null) {
|
|
78
|
+
const initHeaders = effectiveInit.headers instanceof Headers
|
|
79
|
+
? Object.fromEntries(effectiveInit.headers.entries())
|
|
80
|
+
: Array.isArray(effectiveInit.headers)
|
|
81
|
+
? Object.fromEntries(effectiveInit.headers)
|
|
82
|
+
: effectiveInit.headers;
|
|
83
|
+
for (const [key, value] of Object.entries(initHeaders)) {
|
|
84
|
+
if (value != null) {
|
|
85
|
+
mergedHeaders[key.toLowerCase()] = value;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Apply per-request option headers (highest priority)
|
|
90
|
+
if (requestOptions?.headers != null) {
|
|
91
|
+
for (const [key, value] of Object.entries(requestOptions.headers)) {
|
|
92
|
+
mergedHeaders[key.toLowerCase()] = value;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const method = effectiveInit?.method ?? "GET";
|
|
96
|
+
const body = effectiveInit?.body;
|
|
97
|
+
const timeoutInSeconds = requestOptions?.timeoutInSeconds ?? clientOptions.timeoutInSeconds;
|
|
98
|
+
const timeoutMs = timeoutInSeconds != null ? timeoutInSeconds * 1000 : undefined;
|
|
99
|
+
const maxRetries = requestOptions?.maxRetries ?? clientOptions.maxRetries;
|
|
100
|
+
const abortSignal = requestOptions?.abortSignal ?? effectiveInit?.signal ?? undefined;
|
|
101
|
+
const fetchFn = clientOptions.fetch ?? (await getFetchFn());
|
|
102
|
+
if (logger.isDebug()) {
|
|
103
|
+
logger.debug("Making passthrough HTTP request", {
|
|
104
|
+
method,
|
|
105
|
+
url: fullUrl,
|
|
106
|
+
hasBody: body != null,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
const response = await requestWithRetries(async () => makeRequest(fetchFn, fullUrl, method, mergedHeaders, body ?? undefined, timeoutMs, abortSignal, effectiveInit?.credentials === "include", undefined, // duplex
|
|
110
|
+
false), maxRetries);
|
|
111
|
+
if (logger.isDebug()) {
|
|
112
|
+
logger.debug("Passthrough HTTP request completed", {
|
|
113
|
+
method,
|
|
114
|
+
url: fullUrl,
|
|
115
|
+
statusCode: response.status,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return response;
|
|
119
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function isCacheNoStoreSupported(): boolean;
|
|
2
|
+
/**
|
|
3
|
+
* Reset the cached result of `isCacheNoStoreSupported`. Exposed for testing only.
|
|
4
|
+
*/
|
|
5
|
+
export declare function resetCacheNoStoreSupported(): void;
|
|
6
|
+
export declare const makeRequest: (fetchFn: (url: string, init: RequestInit) => Promise<Response>, url: string, method: string, headers: Headers | Record<string, string>, requestBody: BodyInit | undefined, timeoutMs?: number, abortSignal?: AbortSignal, withCredentials?: boolean, duplex?: "half", disableCache?: boolean) => Promise<Response>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { anySignal, getTimeoutSignal } from "./signals.js";
|
|
2
|
+
/**
|
|
3
|
+
* Cached result of checking whether the current runtime supports
|
|
4
|
+
* the `cache` option in `Request`. Some runtimes (e.g. Cloudflare Workers)
|
|
5
|
+
* throw a TypeError when this option is used.
|
|
6
|
+
*/
|
|
7
|
+
let _cacheNoStoreSupported;
|
|
8
|
+
export function isCacheNoStoreSupported() {
|
|
9
|
+
if (_cacheNoStoreSupported != null) {
|
|
10
|
+
return _cacheNoStoreSupported;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
new Request("http://localhost", { cache: "no-store" });
|
|
14
|
+
_cacheNoStoreSupported = true;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
_cacheNoStoreSupported = false;
|
|
18
|
+
}
|
|
19
|
+
return _cacheNoStoreSupported;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Reset the cached result of `isCacheNoStoreSupported`. Exposed for testing only.
|
|
23
|
+
*/
|
|
24
|
+
export function resetCacheNoStoreSupported() {
|
|
25
|
+
_cacheNoStoreSupported = undefined;
|
|
26
|
+
}
|
|
27
|
+
export const makeRequest = async (fetchFn, url, method, headers, requestBody, timeoutMs, abortSignal, withCredentials, duplex, disableCache) => {
|
|
28
|
+
const signals = [];
|
|
29
|
+
let timeoutAbortId;
|
|
30
|
+
if (timeoutMs != null) {
|
|
31
|
+
const { signal, abortId } = getTimeoutSignal(timeoutMs);
|
|
32
|
+
timeoutAbortId = abortId;
|
|
33
|
+
signals.push(signal);
|
|
34
|
+
}
|
|
35
|
+
if (abortSignal != null) {
|
|
36
|
+
signals.push(abortSignal);
|
|
37
|
+
}
|
|
38
|
+
const newSignals = anySignal(signals);
|
|
39
|
+
const response = await fetchFn(url, {
|
|
40
|
+
method: method,
|
|
41
|
+
headers,
|
|
42
|
+
body: requestBody,
|
|
43
|
+
signal: newSignals,
|
|
44
|
+
credentials: withCredentials ? "include" : undefined,
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
duplex,
|
|
47
|
+
...(disableCache && isCacheNoStoreSupported() ? { cache: "no-store" } : {}),
|
|
48
|
+
});
|
|
49
|
+
if (timeoutAbortId != null) {
|
|
50
|
+
clearTimeout(timeoutAbortId);
|
|
51
|
+
}
|
|
52
|
+
return response;
|
|
53
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function requestWithRetries(requestFn: () => Promise<Response>, maxRetries?: number): Promise<Response>;
|