@planqk/planqk-api-sdk 1.0.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/.devcontainer/devcontainer.json +32 -0
- package/.devcontainer/post-create.sh +7 -0
- package/.env.template +2 -0
- package/.gitlab-ci.yml +71 -0
- package/.python-version +1 -0
- package/.releaserc.json +45 -0
- package/LICENSE +201 -0
- package/README-node.md +18 -0
- package/README-python.md +21 -0
- package/README.md +56 -0
- package/dist/Client.d.ts +32 -0
- package/dist/Client.js +60 -0
- package/dist/api/errors/BadRequestError.d.ts +8 -0
- package/dist/api/errors/BadRequestError.js +52 -0
- package/dist/api/errors/ForbiddenError.d.ts +8 -0
- package/dist/api/errors/ForbiddenError.js +52 -0
- package/dist/api/errors/InternalServerError.d.ts +8 -0
- package/dist/api/errors/InternalServerError.js +52 -0
- package/dist/api/errors/NotFoundError.d.ts +8 -0
- package/dist/api/errors/NotFoundError.js +52 -0
- package/dist/api/errors/UnauthorizedError.d.ts +8 -0
- package/dist/api/errors/UnauthorizedError.js +52 -0
- package/dist/api/errors/index.d.ts +5 -0
- package/dist/api/errors/index.js +21 -0
- package/dist/api/index.d.ts +3 -0
- package/dist/api/index.js +19 -0
- package/dist/api/resources/dataPools/client/Client.d.ts +177 -0
- package/dist/api/resources/dataPools/client/Client.js +676 -0
- package/dist/api/resources/dataPools/client/index.d.ts +2 -0
- package/dist/api/resources/dataPools/client/index.js +17 -0
- package/dist/api/resources/dataPools/client/requests/AddDataPoolFileRequest.d.ts +14 -0
- package/dist/api/resources/dataPools/client/requests/AddDataPoolFileRequest.js +5 -0
- package/dist/api/resources/dataPools/client/requests/CreateDataPoolRequest.d.ts +10 -0
- package/dist/api/resources/dataPools/client/requests/CreateDataPoolRequest.js +5 -0
- package/dist/api/resources/dataPools/client/requests/UpdateDataPoolRequest.d.ts +12 -0
- package/dist/api/resources/dataPools/client/requests/UpdateDataPoolRequest.js +5 -0
- package/dist/api/resources/dataPools/client/requests/index.d.ts +3 -0
- package/dist/api/resources/dataPools/client/requests/index.js +2 -0
- package/dist/api/resources/dataPools/index.d.ts +1 -0
- package/dist/api/resources/dataPools/index.js +17 -0
- package/dist/api/resources/index.d.ts +2 -0
- package/dist/api/resources/index.js +41 -0
- package/dist/api/types/DataPoolDto.d.ts +23 -0
- package/dist/api/types/DataPoolDto.js +14 -0
- package/dist/api/types/DataPoolFileDto.d.ts +12 -0
- package/dist/api/types/DataPoolFileDto.js +5 -0
- package/dist/api/types/OauthScope.d.ts +9 -0
- package/dist/api/types/OauthScope.js +9 -0
- package/dist/api/types/index.d.ts +3 -0
- package/dist/api/types/index.js +19 -0
- package/dist/core/fetcher/APIResponse.d.ts +20 -0
- package/dist/core/fetcher/APIResponse.js +2 -0
- package/dist/core/fetcher/BinaryResponse.d.ts +20 -0
- package/dist/core/fetcher/BinaryResponse.js +17 -0
- package/dist/core/fetcher/Fetcher.d.ts +40 -0
- package/dist/core/fetcher/Fetcher.js +105 -0
- package/dist/core/fetcher/Headers.d.ts +2 -0
- package/dist/core/fetcher/Headers.js +85 -0
- package/dist/core/fetcher/HttpResponsePromise.d.ts +58 -0
- package/dist/core/fetcher/HttpResponsePromise.js +94 -0
- package/dist/core/fetcher/RawResponse.d.ts +29 -0
- package/dist/core/fetcher/RawResponse.js +44 -0
- package/dist/core/fetcher/ResponseWithBody.d.ts +4 -0
- package/dist/core/fetcher/ResponseWithBody.js +6 -0
- package/dist/core/fetcher/Supplier.d.ts +4 -0
- package/dist/core/fetcher/Supplier.js +13 -0
- package/dist/core/fetcher/createRequestUrl.d.ts +1 -0
- package/dist/core/fetcher/createRequestUrl.js +8 -0
- package/dist/core/fetcher/getErrorResponseBody.d.ts +1 -0
- package/dist/core/fetcher/getErrorResponseBody.js +32 -0
- package/dist/core/fetcher/getFetchFn.d.ts +1 -0
- package/dist/core/fetcher/getFetchFn.js +6 -0
- package/dist/core/fetcher/getHeader.d.ts +1 -0
- package/dist/core/fetcher/getHeader.js +11 -0
- package/dist/core/fetcher/getRequestBody.d.ts +7 -0
- package/dist/core/fetcher/getRequestBody.js +12 -0
- package/dist/core/fetcher/getResponseBody.d.ts +1 -0
- package/dist/core/fetcher/getResponseBody.js +44 -0
- package/dist/core/fetcher/index.d.ts +9 -0
- package/dist/core/fetcher/index.js +15 -0
- package/dist/core/fetcher/makeRequest.d.ts +1 -0
- package/dist/core/fetcher/makeRequest.js +33 -0
- package/dist/core/fetcher/requestWithRetries.d.ts +1 -0
- package/dist/core/fetcher/requestWithRetries.js +29 -0
- package/dist/core/fetcher/signals.d.ts +11 -0
- package/dist/core/fetcher/signals.js +36 -0
- package/dist/core/file.d.ts +1 -0
- package/dist/core/file.js +2 -0
- package/dist/core/form-data-utils/FormDataWrapper.d.ts +16 -0
- package/dist/core/form-data-utils/FormDataWrapper.js +166 -0
- package/dist/core/form-data-utils/encodeAsFormParameter.d.ts +1 -0
- package/dist/core/form-data-utils/encodeAsFormParameter.js +12 -0
- package/dist/core/form-data-utils/index.d.ts +2 -0
- package/dist/core/form-data-utils/index.js +20 -0
- package/dist/core/headers.d.ts +3 -0
- package/dist/core/headers.js +29 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +44 -0
- package/dist/core/json.d.ts +15 -0
- package/dist/core/json.js +24 -0
- package/dist/core/runtime/index.d.ts +1 -0
- package/dist/core/runtime/index.js +5 -0
- package/dist/core/runtime/runtime.d.ts +9 -0
- package/dist/core/runtime/runtime.js +101 -0
- package/dist/core/url/index.d.ts +2 -0
- package/dist/core/url/index.js +7 -0
- package/dist/core/url/join.d.ts +1 -0
- package/dist/core/url/join.js +49 -0
- package/dist/core/url/qs.d.ts +6 -0
- package/dist/core/url/qs.js +67 -0
- package/dist/environments.d.ts +7 -0
- package/dist/environments.js +9 -0
- package/dist/errors/PlanqkApiError.d.ts +15 -0
- package/dist/errors/PlanqkApiError.js +33 -0
- package/dist/errors/PlanqkApiTimeoutError.d.ts +6 -0
- package/dist/errors/PlanqkApiTimeoutError.js +13 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.js +7 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +44 -0
- package/eslint.config.mjs +11 -0
- package/fern/fern.config.json +4 -0
- package/fern/generators.yml +25 -0
- package/fern/openapi/openapi.json +610 -0
- package/notebooks/python-sdk.ipynb +218 -0
- package/package.json +48 -0
- package/planqk/__init__.py +0 -0
- package/planqk/api/__init__.py +1 -0
- package/planqk/api/_version.py +1 -0
- package/planqk/api/client.py +19 -0
- package/planqk/api/credentials.py +103 -0
- package/planqk/api/sdk/__init__.py +25 -0
- package/planqk/api/sdk/client.py +153 -0
- package/planqk/api/sdk/core/__init__.py +52 -0
- package/planqk/api/sdk/core/api_error.py +23 -0
- package/planqk/api/sdk/core/client_wrapper.py +76 -0
- package/planqk/api/sdk/core/datetime_utils.py +28 -0
- package/planqk/api/sdk/core/file.py +67 -0
- package/planqk/api/sdk/core/force_multipart.py +16 -0
- package/planqk/api/sdk/core/http_client.py +543 -0
- package/planqk/api/sdk/core/http_response.py +55 -0
- package/planqk/api/sdk/core/jsonable_encoder.py +100 -0
- package/planqk/api/sdk/core/pydantic_utilities.py +255 -0
- package/planqk/api/sdk/core/query_encoder.py +58 -0
- package/planqk/api/sdk/core/remove_none_from_dict.py +11 -0
- package/planqk/api/sdk/core/request_options.py +35 -0
- package/planqk/api/sdk/core/serialization.py +276 -0
- package/planqk/api/sdk/data_pools/__init__.py +4 -0
- package/planqk/api/sdk/data_pools/client.py +700 -0
- package/planqk/api/sdk/data_pools/raw_client.py +1650 -0
- package/planqk/api/sdk/environment.py +7 -0
- package/planqk/api/sdk/errors/__init__.py +11 -0
- package/planqk/api/sdk/errors/bad_request_error.py +10 -0
- package/planqk/api/sdk/errors/forbidden_error.py +10 -0
- package/planqk/api/sdk/errors/internal_server_error.py +10 -0
- package/planqk/api/sdk/errors/not_found_error.py +10 -0
- package/planqk/api/sdk/errors/unauthorized_error.py +10 -0
- package/planqk/api/sdk/types/__init__.py +10 -0
- package/planqk/api/sdk/types/data_pool_dto.py +33 -0
- package/planqk/api/sdk/types/data_pool_dto_current_user_permission.py +5 -0
- package/planqk/api/sdk/types/data_pool_file_dto.py +27 -0
- package/planqk/api/sdk/types/oauth_scope.py +5 -0
- package/pyproject.toml +51 -0
- package/scripts/update-version.sh +6 -0
- package/src/Client.ts +53 -0
- package/src/api/errors/BadRequestError.ts +18 -0
- package/src/api/errors/ForbiddenError.ts +18 -0
- package/src/api/errors/InternalServerError.ts +18 -0
- package/src/api/errors/NotFoundError.ts +18 -0
- package/src/api/errors/UnauthorizedError.ts +18 -0
- package/src/api/errors/index.ts +5 -0
- package/src/api/index.ts +3 -0
- package/src/api/resources/dataPools/client/Client.ts +825 -0
- package/src/api/resources/dataPools/client/index.ts +2 -0
- package/src/api/resources/dataPools/client/requests/AddDataPoolFileRequest.ts +17 -0
- package/src/api/resources/dataPools/client/requests/CreateDataPoolRequest.ts +11 -0
- package/src/api/resources/dataPools/client/requests/UpdateDataPoolRequest.ts +13 -0
- package/src/api/resources/dataPools/client/requests/index.ts +3 -0
- package/src/api/resources/dataPools/index.ts +1 -0
- package/src/api/resources/index.ts +2 -0
- package/src/api/types/DataPoolDto.ts +25 -0
- package/src/api/types/DataPoolFileDto.ts +13 -0
- package/src/api/types/OauthScope.ts +10 -0
- package/src/api/types/index.ts +3 -0
- package/src/core/fetcher/APIResponse.ts +23 -0
- package/src/core/fetcher/BinaryResponse.ts +36 -0
- package/src/core/fetcher/Fetcher.ts +163 -0
- package/src/core/fetcher/Headers.ts +93 -0
- package/src/core/fetcher/HttpResponsePromise.ts +116 -0
- package/src/core/fetcher/RawResponse.ts +61 -0
- package/src/core/fetcher/ResponseWithBody.ts +7 -0
- package/src/core/fetcher/Supplier.ts +11 -0
- package/src/core/fetcher/createRequestUrl.ts +6 -0
- package/src/core/fetcher/getErrorResponseBody.ts +32 -0
- package/src/core/fetcher/getFetchFn.ts +3 -0
- package/src/core/fetcher/getHeader.ts +8 -0
- package/src/core/fetcher/getRequestBody.ts +16 -0
- package/src/core/fetcher/getResponseBody.ts +43 -0
- package/src/core/fetcher/index.ts +9 -0
- package/src/core/fetcher/makeRequest.ts +44 -0
- package/src/core/fetcher/requestWithRetries.ts +33 -0
- package/src/core/fetcher/signals.ts +38 -0
- package/src/core/file.ts +11 -0
- package/src/core/form-data-utils/FormDataWrapper.ts +176 -0
- package/src/core/form-data-utils/encodeAsFormParameter.ts +12 -0
- package/src/core/form-data-utils/index.ts +2 -0
- package/src/core/headers.ts +35 -0
- package/src/core/index.ts +5 -0
- package/src/core/json.ts +27 -0
- package/src/core/runtime/index.ts +1 -0
- package/src/core/runtime/runtime.ts +133 -0
- package/src/core/url/index.ts +2 -0
- package/src/core/url/join.ts +55 -0
- package/src/core/url/qs.ts +74 -0
- package/src/environments.ts +9 -0
- package/src/errors/PlanqkApiError.ts +55 -0
- package/src/errors/PlanqkApiTimeoutError.ts +10 -0
- package/src/errors/index.ts +2 -0
- package/src/index.test.ts +17 -0
- package/src/index.ts +4 -0
- package/tsconfig.json +18 -0
- package/uv.lock +1102 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was auto-generated by Fern from our API Definition.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as fs from "fs";
|
|
6
|
+
import * as core from "../../../../../core/index.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @example
|
|
10
|
+
* {
|
|
11
|
+
* file: fs.createReadStream("/path/to/your/file")
|
|
12
|
+
* }
|
|
13
|
+
*/
|
|
14
|
+
export interface AddDataPoolFileRequest {
|
|
15
|
+
filename?: string;
|
|
16
|
+
file: core.FileLike;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./client/index.js";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was auto-generated by Fern from our API Definition.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface DataPoolDto {
|
|
6
|
+
/** The access permission role for this entity of the current user */
|
|
7
|
+
currentUserPermission?: DataPoolDto.CurrentUserPermission;
|
|
8
|
+
id?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
shortDescription?: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
createdAt?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export namespace DataPoolDto {
|
|
16
|
+
/**
|
|
17
|
+
* The access permission role for this entity of the current user
|
|
18
|
+
*/
|
|
19
|
+
export type CurrentUserPermission = "VIEWER" | "MAINTAINER" | "OWNER";
|
|
20
|
+
export const CurrentUserPermission = {
|
|
21
|
+
Viewer: "VIEWER",
|
|
22
|
+
Maintainer: "MAINTAINER",
|
|
23
|
+
Owner: "OWNER",
|
|
24
|
+
} as const;
|
|
25
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was auto-generated by Fern from our API Definition.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface DataPoolFileDto {
|
|
6
|
+
id?: string;
|
|
7
|
+
dataPoolId?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
fullPath?: string;
|
|
10
|
+
contentType?: string;
|
|
11
|
+
contentLength?: number;
|
|
12
|
+
createdAt?: string;
|
|
13
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { RawResponse } from "./RawResponse.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The response of an API call.
|
|
5
|
+
* It is a successful response or a failed response.
|
|
6
|
+
*/
|
|
7
|
+
export type APIResponse<Success, Failure> = SuccessfulResponse<Success> | FailedResponse<Failure>;
|
|
8
|
+
|
|
9
|
+
export interface SuccessfulResponse<T> {
|
|
10
|
+
ok: true;
|
|
11
|
+
body: T;
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated Use `rawResponse` instead
|
|
14
|
+
*/
|
|
15
|
+
headers?: Record<string, any>;
|
|
16
|
+
rawResponse: RawResponse;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface FailedResponse<T> {
|
|
20
|
+
ok: false;
|
|
21
|
+
error: T;
|
|
22
|
+
rawResponse: RawResponse;
|
|
23
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ResponseWithBody } from "./ResponseWithBody.js";
|
|
2
|
+
|
|
3
|
+
export type BinaryResponse = {
|
|
4
|
+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bodyUsed) */
|
|
5
|
+
bodyUsed: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Returns a ReadableStream of the response body.
|
|
8
|
+
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/body)
|
|
9
|
+
*/
|
|
10
|
+
stream: () => ReadableStream<Uint8Array>;
|
|
11
|
+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/arrayBuffer) */
|
|
12
|
+
arrayBuffer: () => Promise<ArrayBuffer>;
|
|
13
|
+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/blob) */
|
|
14
|
+
blob: () => Promise<Blob>;
|
|
15
|
+
/**
|
|
16
|
+
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bytes)
|
|
17
|
+
* Some versions of the Fetch API may not support this method.
|
|
18
|
+
*/
|
|
19
|
+
bytes?(): Promise<Uint8Array>;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function getBinaryResponse(response: ResponseWithBody): BinaryResponse {
|
|
23
|
+
const binaryResponse: BinaryResponse = {
|
|
24
|
+
get bodyUsed() {
|
|
25
|
+
return response.bodyUsed;
|
|
26
|
+
},
|
|
27
|
+
stream: () => response.body,
|
|
28
|
+
arrayBuffer: response.arrayBuffer.bind(response),
|
|
29
|
+
blob: response.blob.bind(response),
|
|
30
|
+
};
|
|
31
|
+
if ("bytes" in response && typeof response.bytes === "function") {
|
|
32
|
+
binaryResponse.bytes = response.bytes.bind(response);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return binaryResponse;
|
|
36
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { toJson } from "../json.js";
|
|
2
|
+
import { APIResponse } from "./APIResponse.js";
|
|
3
|
+
import { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js";
|
|
4
|
+
import { Supplier } from "./Supplier.js";
|
|
5
|
+
import { createRequestUrl } from "./createRequestUrl.js";
|
|
6
|
+
import { getErrorResponseBody } from "./getErrorResponseBody.js";
|
|
7
|
+
import { getFetchFn } from "./getFetchFn.js";
|
|
8
|
+
import { getRequestBody } from "./getRequestBody.js";
|
|
9
|
+
import { getResponseBody } from "./getResponseBody.js";
|
|
10
|
+
import { makeRequest } from "./makeRequest.js";
|
|
11
|
+
import { requestWithRetries } from "./requestWithRetries.js";
|
|
12
|
+
|
|
13
|
+
export type FetchFunction = <R = unknown>(args: Fetcher.Args) => Promise<APIResponse<R, Fetcher.Error>>;
|
|
14
|
+
|
|
15
|
+
export declare namespace Fetcher {
|
|
16
|
+
export interface Args {
|
|
17
|
+
url: string;
|
|
18
|
+
method: string;
|
|
19
|
+
contentType?: string;
|
|
20
|
+
headers?: Record<string, string | Supplier<string | undefined> | undefined>;
|
|
21
|
+
queryParameters?: Record<string, string | string[] | object | object[] | null>;
|
|
22
|
+
body?: unknown;
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
maxRetries?: number;
|
|
25
|
+
withCredentials?: boolean;
|
|
26
|
+
abortSignal?: AbortSignal;
|
|
27
|
+
requestType?: "json" | "file" | "bytes";
|
|
28
|
+
responseType?: "json" | "blob" | "sse" | "streaming" | "text" | "arrayBuffer" | "binary-response";
|
|
29
|
+
duplex?: "half";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type Error = FailedStatusCodeError | NonJsonError | TimeoutError | UnknownError;
|
|
33
|
+
|
|
34
|
+
export interface FailedStatusCodeError {
|
|
35
|
+
reason: "status-code";
|
|
36
|
+
statusCode: number;
|
|
37
|
+
body: unknown;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface NonJsonError {
|
|
41
|
+
reason: "non-json";
|
|
42
|
+
statusCode: number;
|
|
43
|
+
rawBody: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface TimeoutError {
|
|
47
|
+
reason: "timeout";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface UnknownError {
|
|
51
|
+
reason: "unknown";
|
|
52
|
+
errorMessage: string;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function getHeaders(args: Fetcher.Args): Promise<Record<string, string>> {
|
|
57
|
+
const newHeaders: Record<string, string> = {};
|
|
58
|
+
if (args.body !== undefined && args.contentType != null) {
|
|
59
|
+
newHeaders["Content-Type"] = args.contentType;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (args.headers == null) {
|
|
63
|
+
return newHeaders;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const [key, value] of Object.entries(args.headers)) {
|
|
67
|
+
const result = await Supplier.get(value);
|
|
68
|
+
if (typeof result === "string") {
|
|
69
|
+
newHeaders[key] = result;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (result == null) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
newHeaders[key] = `${result}`;
|
|
76
|
+
}
|
|
77
|
+
return newHeaders;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse<R, Fetcher.Error>> {
|
|
81
|
+
const url = createRequestUrl(args.url, args.queryParameters);
|
|
82
|
+
const requestBody: BodyInit | undefined = await getRequestBody({
|
|
83
|
+
body: args.body,
|
|
84
|
+
type: args.requestType === "json" ? "json" : "other",
|
|
85
|
+
});
|
|
86
|
+
const fetchFn = await getFetchFn();
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const response = await requestWithRetries(
|
|
90
|
+
async () =>
|
|
91
|
+
makeRequest(
|
|
92
|
+
fetchFn,
|
|
93
|
+
url,
|
|
94
|
+
args.method,
|
|
95
|
+
await getHeaders(args),
|
|
96
|
+
requestBody,
|
|
97
|
+
args.timeoutMs,
|
|
98
|
+
args.abortSignal,
|
|
99
|
+
args.withCredentials,
|
|
100
|
+
args.duplex,
|
|
101
|
+
),
|
|
102
|
+
args.maxRetries,
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
if (response.status >= 200 && response.status < 400) {
|
|
106
|
+
return {
|
|
107
|
+
ok: true,
|
|
108
|
+
body: (await getResponseBody(response, args.responseType)) as R,
|
|
109
|
+
headers: response.headers,
|
|
110
|
+
rawResponse: toRawResponse(response),
|
|
111
|
+
};
|
|
112
|
+
} else {
|
|
113
|
+
return {
|
|
114
|
+
ok: false,
|
|
115
|
+
error: {
|
|
116
|
+
reason: "status-code",
|
|
117
|
+
statusCode: response.status,
|
|
118
|
+
body: await getErrorResponseBody(response),
|
|
119
|
+
},
|
|
120
|
+
rawResponse: toRawResponse(response),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
} catch (error) {
|
|
124
|
+
if (args.abortSignal != null && args.abortSignal.aborted) {
|
|
125
|
+
return {
|
|
126
|
+
ok: false,
|
|
127
|
+
error: {
|
|
128
|
+
reason: "unknown",
|
|
129
|
+
errorMessage: "The user aborted a request",
|
|
130
|
+
},
|
|
131
|
+
rawResponse: abortRawResponse,
|
|
132
|
+
};
|
|
133
|
+
} else if (error instanceof Error && error.name === "AbortError") {
|
|
134
|
+
return {
|
|
135
|
+
ok: false,
|
|
136
|
+
error: {
|
|
137
|
+
reason: "timeout",
|
|
138
|
+
},
|
|
139
|
+
rawResponse: abortRawResponse,
|
|
140
|
+
};
|
|
141
|
+
} else if (error instanceof Error) {
|
|
142
|
+
return {
|
|
143
|
+
ok: false,
|
|
144
|
+
error: {
|
|
145
|
+
reason: "unknown",
|
|
146
|
+
errorMessage: error.message,
|
|
147
|
+
},
|
|
148
|
+
rawResponse: unknownRawResponse,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
ok: false,
|
|
154
|
+
error: {
|
|
155
|
+
reason: "unknown",
|
|
156
|
+
errorMessage: toJson(error),
|
|
157
|
+
},
|
|
158
|
+
rawResponse: unknownRawResponse,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export const fetcher: FetchFunction = fetcherImpl;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
let Headers: typeof globalThis.Headers;
|
|
2
|
+
|
|
3
|
+
if (typeof globalThis.Headers !== "undefined") {
|
|
4
|
+
Headers = globalThis.Headers;
|
|
5
|
+
} else {
|
|
6
|
+
Headers = class Headers implements Headers {
|
|
7
|
+
private headers: Map<string, string[]>;
|
|
8
|
+
|
|
9
|
+
constructor(init?: HeadersInit) {
|
|
10
|
+
this.headers = new Map();
|
|
11
|
+
|
|
12
|
+
if (init) {
|
|
13
|
+
if (init instanceof Headers) {
|
|
14
|
+
init.forEach((value, key) => this.append(key, value));
|
|
15
|
+
} else if (Array.isArray(init)) {
|
|
16
|
+
for (const [key, value] of init) {
|
|
17
|
+
if (typeof key === "string" && typeof value === "string") {
|
|
18
|
+
this.append(key, value);
|
|
19
|
+
} else {
|
|
20
|
+
throw new TypeError("Each header entry must be a [string, string] tuple");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
} else {
|
|
24
|
+
for (const [key, value] of Object.entries(init)) {
|
|
25
|
+
if (typeof value === "string") {
|
|
26
|
+
this.append(key, value);
|
|
27
|
+
} else {
|
|
28
|
+
throw new TypeError("Header values must be strings");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
append(name: string, value: string): void {
|
|
36
|
+
const key = name.toLowerCase();
|
|
37
|
+
const existing = this.headers.get(key) || [];
|
|
38
|
+
this.headers.set(key, [...existing, value]);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
delete(name: string): void {
|
|
42
|
+
const key = name.toLowerCase();
|
|
43
|
+
this.headers.delete(key);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get(name: string): string | null {
|
|
47
|
+
const key = name.toLowerCase();
|
|
48
|
+
const values = this.headers.get(key);
|
|
49
|
+
return values ? values.join(", ") : null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
has(name: string): boolean {
|
|
53
|
+
const key = name.toLowerCase();
|
|
54
|
+
return this.headers.has(key);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
set(name: string, value: string): void {
|
|
58
|
+
const key = name.toLowerCase();
|
|
59
|
+
this.headers.set(key, [value]);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: unknown): void {
|
|
63
|
+
const boundCallback = thisArg ? callbackfn.bind(thisArg) : callbackfn;
|
|
64
|
+
this.headers.forEach((values, key) => boundCallback(values.join(", "), key, this));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getSetCookie(): string[] {
|
|
68
|
+
return this.headers.get("set-cookie") || [];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
*entries(): HeadersIterator<[string, string]> {
|
|
72
|
+
for (const [key, values] of this.headers.entries()) {
|
|
73
|
+
yield [key, values.join(", ")];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
*keys(): HeadersIterator<string> {
|
|
78
|
+
yield* this.headers.keys();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
*values(): HeadersIterator<string> {
|
|
82
|
+
for (const values of this.headers.values()) {
|
|
83
|
+
yield values.join(", ");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[Symbol.iterator](): HeadersIterator<[string, string]> {
|
|
88
|
+
return this.entries();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { Headers };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { WithRawResponse } from "./RawResponse.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A promise that returns the parsed response and lets you retrieve the raw response too.
|
|
5
|
+
*/
|
|
6
|
+
export class HttpResponsePromise<T> extends Promise<T> {
|
|
7
|
+
private innerPromise: Promise<WithRawResponse<T>>;
|
|
8
|
+
private unwrappedPromise: Promise<T> | undefined;
|
|
9
|
+
|
|
10
|
+
private constructor(promise: Promise<WithRawResponse<T>>) {
|
|
11
|
+
// Initialize with a no-op to avoid premature parsing
|
|
12
|
+
super((resolve) => {
|
|
13
|
+
resolve(undefined as unknown as T);
|
|
14
|
+
});
|
|
15
|
+
this.innerPromise = promise;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates an `HttpResponsePromise` from a function that returns a promise.
|
|
20
|
+
*
|
|
21
|
+
* @param fn - A function that returns a promise resolving to a `WithRawResponse` object.
|
|
22
|
+
* @param args - Arguments to pass to the function.
|
|
23
|
+
* @returns An `HttpResponsePromise` instance.
|
|
24
|
+
*/
|
|
25
|
+
public static fromFunction<F extends (...args: never[]) => Promise<WithRawResponse<T>>, T>(
|
|
26
|
+
fn: F,
|
|
27
|
+
...args: Parameters<F>
|
|
28
|
+
): HttpResponsePromise<T> {
|
|
29
|
+
return new HttpResponsePromise<T>(fn(...args));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Creates a function that returns an `HttpResponsePromise` from a function that returns a promise.
|
|
34
|
+
*
|
|
35
|
+
* @param fn - A function that returns a promise resolving to a `WithRawResponse` object.
|
|
36
|
+
* @returns A function that returns an `HttpResponsePromise` instance.
|
|
37
|
+
*/
|
|
38
|
+
public static interceptFunction<
|
|
39
|
+
F extends (...args: never[]) => Promise<WithRawResponse<T>>,
|
|
40
|
+
T = Awaited<ReturnType<F>>["data"],
|
|
41
|
+
>(fn: F): (...args: Parameters<F>) => HttpResponsePromise<T> {
|
|
42
|
+
return (...args: Parameters<F>): HttpResponsePromise<T> => {
|
|
43
|
+
return HttpResponsePromise.fromPromise<T>(fn(...args));
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Creates an `HttpResponsePromise` from an existing promise.
|
|
49
|
+
*
|
|
50
|
+
* @param promise - A promise resolving to a `WithRawResponse` object.
|
|
51
|
+
* @returns An `HttpResponsePromise` instance.
|
|
52
|
+
*/
|
|
53
|
+
public static fromPromise<T>(promise: Promise<WithRawResponse<T>>): HttpResponsePromise<T> {
|
|
54
|
+
return new HttpResponsePromise<T>(promise);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Creates an `HttpResponsePromise` from an executor function.
|
|
59
|
+
*
|
|
60
|
+
* @param executor - A function that takes resolve and reject callbacks to create a promise.
|
|
61
|
+
* @returns An `HttpResponsePromise` instance.
|
|
62
|
+
*/
|
|
63
|
+
public static fromExecutor<T>(
|
|
64
|
+
executor: (resolve: (value: WithRawResponse<T>) => void, reject: (reason?: unknown) => void) => void,
|
|
65
|
+
): HttpResponsePromise<T> {
|
|
66
|
+
const promise = new Promise<WithRawResponse<T>>(executor);
|
|
67
|
+
return new HttpResponsePromise<T>(promise);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Creates an `HttpResponsePromise` from a resolved result.
|
|
72
|
+
*
|
|
73
|
+
* @param result - A `WithRawResponse` object to resolve immediately.
|
|
74
|
+
* @returns An `HttpResponsePromise` instance.
|
|
75
|
+
*/
|
|
76
|
+
public static fromResult<T>(result: WithRawResponse<T>): HttpResponsePromise<T> {
|
|
77
|
+
const promise = Promise.resolve(result);
|
|
78
|
+
return new HttpResponsePromise<T>(promise);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private unwrap(): Promise<T> {
|
|
82
|
+
if (!this.unwrappedPromise) {
|
|
83
|
+
this.unwrappedPromise = this.innerPromise.then(({ data }) => data);
|
|
84
|
+
}
|
|
85
|
+
return this.unwrappedPromise;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** @inheritdoc */
|
|
89
|
+
public override then<TResult1 = T, TResult2 = never>(
|
|
90
|
+
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
|
|
91
|
+
onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,
|
|
92
|
+
): Promise<TResult1 | TResult2> {
|
|
93
|
+
return this.unwrap().then(onfulfilled, onrejected);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** @inheritdoc */
|
|
97
|
+
public override catch<TResult = never>(
|
|
98
|
+
onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null,
|
|
99
|
+
): Promise<T | TResult> {
|
|
100
|
+
return this.unwrap().catch(onrejected);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** @inheritdoc */
|
|
104
|
+
public override finally(onfinally?: (() => void) | null): Promise<T> {
|
|
105
|
+
return this.unwrap().finally(onfinally);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Retrieves the data and raw response.
|
|
110
|
+
*
|
|
111
|
+
* @returns A promise resolving to a `WithRawResponse` object.
|
|
112
|
+
*/
|
|
113
|
+
public async withRawResponse(): Promise<WithRawResponse<T>> {
|
|
114
|
+
return await this.innerPromise;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Headers } from "./Headers.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The raw response from the fetch call excluding the body.
|
|
5
|
+
*/
|
|
6
|
+
export type RawResponse = Omit<
|
|
7
|
+
{
|
|
8
|
+
[K in keyof Response as Response[K] extends Function ? never : K]: Response[K]; // strips out functions
|
|
9
|
+
},
|
|
10
|
+
"ok" | "body" | "bodyUsed"
|
|
11
|
+
>; // strips out body and bodyUsed
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A raw response indicating that the request was aborted.
|
|
15
|
+
*/
|
|
16
|
+
export const abortRawResponse: RawResponse = {
|
|
17
|
+
headers: new Headers(),
|
|
18
|
+
redirected: false,
|
|
19
|
+
status: 499,
|
|
20
|
+
statusText: "Client Closed Request",
|
|
21
|
+
type: "error",
|
|
22
|
+
url: "",
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A raw response indicating an unknown error.
|
|
27
|
+
*/
|
|
28
|
+
export const unknownRawResponse: RawResponse = {
|
|
29
|
+
headers: new Headers(),
|
|
30
|
+
redirected: false,
|
|
31
|
+
status: 0,
|
|
32
|
+
statusText: "Unknown Error",
|
|
33
|
+
type: "error",
|
|
34
|
+
url: "",
|
|
35
|
+
} as const;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Converts a `RawResponse` object into a `RawResponse` by extracting its properties,
|
|
39
|
+
* excluding the `body` and `bodyUsed` fields.
|
|
40
|
+
*
|
|
41
|
+
* @param response - The `RawResponse` object to convert.
|
|
42
|
+
* @returns A `RawResponse` object containing the extracted properties of the input response.
|
|
43
|
+
*/
|
|
44
|
+
export function toRawResponse(response: Response): RawResponse {
|
|
45
|
+
return {
|
|
46
|
+
headers: response.headers,
|
|
47
|
+
redirected: response.redirected,
|
|
48
|
+
status: response.status,
|
|
49
|
+
statusText: response.statusText,
|
|
50
|
+
type: response.type,
|
|
51
|
+
url: response.url,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Creates a `RawResponse` from a standard `Response` object.
|
|
57
|
+
*/
|
|
58
|
+
export interface WithRawResponse<T> {
|
|
59
|
+
readonly data: T;
|
|
60
|
+
readonly rawResponse: RawResponse;
|
|
61
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type Supplier<T> = T | Promise<T> | (() => T | Promise<T>);
|
|
2
|
+
|
|
3
|
+
export const Supplier = {
|
|
4
|
+
get: async <T>(supplier: Supplier<T>): Promise<T> => {
|
|
5
|
+
if (typeof supplier === "function") {
|
|
6
|
+
return (supplier as () => T)();
|
|
7
|
+
} else {
|
|
8
|
+
return supplier;
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { toQueryString } from "../url/qs.js";
|
|
2
|
+
|
|
3
|
+
export function createRequestUrl(baseUrl: string, queryParameters?: Record<string, unknown>): string {
|
|
4
|
+
const queryString = toQueryString(queryParameters, { arrayFormat: "repeat" });
|
|
5
|
+
return queryString ? `${baseUrl}?${queryString}` : baseUrl;
|
|
6
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { fromJson } from "../json.js";
|
|
2
|
+
import { getResponseBody } from "./getResponseBody.js";
|
|
3
|
+
|
|
4
|
+
export async function getErrorResponseBody(response: Response): Promise<unknown> {
|
|
5
|
+
let contentType = response.headers.get("Content-Type")?.toLowerCase();
|
|
6
|
+
if (contentType == null || contentType.length === 0) {
|
|
7
|
+
return getResponseBody(response);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (contentType.indexOf(";") !== -1) {
|
|
11
|
+
contentType = contentType.split(";")[0]?.trim() ?? "";
|
|
12
|
+
}
|
|
13
|
+
switch (contentType) {
|
|
14
|
+
case "application/hal+json":
|
|
15
|
+
case "application/json":
|
|
16
|
+
case "application/ld+json":
|
|
17
|
+
case "application/problem+json":
|
|
18
|
+
case "application/vnd.api+json":
|
|
19
|
+
case "text/json":
|
|
20
|
+
const text = await response.text();
|
|
21
|
+
return text.length > 0 ? fromJson(text) : undefined;
|
|
22
|
+
default:
|
|
23
|
+
if (contentType.startsWith("application/vnd.") && contentType.endsWith("+json")) {
|
|
24
|
+
const text = await response.text();
|
|
25
|
+
return text.length > 0 ? fromJson(text) : undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Fallback to plain text if content type is not recognized
|
|
29
|
+
// Even if no body is present, the response will be an empty string
|
|
30
|
+
return await response.text();
|
|
31
|
+
}
|
|
32
|
+
}
|