@planqk/planqk-service-sdk 1.9.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devcontainer/devcontainer.json +32 -0
- package/.devcontainer/post-create.sh +7 -0
- package/.env.template +4 -0
- package/.gitlab-ci.yml +103 -0
- package/.python-version +1 -0
- package/.releaserc.json +45 -0
- package/LICENSE +201 -0
- package/README-node.md +41 -0
- package/README-python.md +52 -0
- package/README.md +42 -21
- package/dist/auth.js +12 -19
- package/dist/client.d.ts +2 -12
- package/dist/client.js +5 -76
- package/dist/sdk/Client.d.ts +4 -3
- package/dist/sdk/Client.js +4 -8
- package/dist/sdk/api/errors/BadRequestError.d.ts +1 -1
- package/dist/sdk/api/errors/BadRequestError.js +18 -8
- package/dist/sdk/api/errors/ForbiddenError.d.ts +1 -1
- package/dist/sdk/api/errors/ForbiddenError.js +18 -8
- package/dist/sdk/api/errors/InternalServerError.d.ts +1 -1
- package/dist/sdk/api/errors/InternalServerError.js +18 -8
- package/dist/sdk/api/errors/NotFoundError.d.ts +1 -1
- package/dist/sdk/api/errors/NotFoundError.js +18 -8
- package/dist/sdk/api/errors/UnauthorizedError.d.ts +1 -1
- package/dist/sdk/api/errors/UnauthorizedError.js +18 -8
- package/dist/sdk/api/resources/index.d.ts +0 -3
- package/dist/sdk/api/resources/index.js +18 -11
- package/dist/sdk/api/resources/serviceApi/client/Client.d.ts +65 -12
- package/dist/sdk/api/resources/serviceApi/client/Client.js +405 -261
- package/dist/sdk/api/resources/serviceApi/client/index.d.ts +1 -1
- package/dist/sdk/api/resources/serviceApi/client/index.js +0 -15
- package/dist/sdk/api/resources/serviceApi/types/GetResultResponse.d.ts +4 -1
- package/dist/sdk/api/resources/serviceApi/types/{GetInterimResultsResponse.d.ts → GetResultResponseEmbedded.d.ts} +3 -1
- package/dist/sdk/api/resources/serviceApi/types/GetResultResponseLinks.d.ts +7 -0
- package/dist/sdk/api/resources/{statusApi → serviceApi}/types/HealthCheckResponse.d.ts +1 -0
- package/dist/sdk/api/resources/serviceApi/types/index.d.ts +3 -1
- package/dist/sdk/api/resources/serviceApi/types/index.js +3 -1
- package/dist/sdk/api/types/HalLink.d.ts +21 -0
- package/dist/sdk/api/types/InputData.d.ts +1 -1
- package/dist/sdk/api/types/{InputRef.d.ts → InputDataRef.d.ts} +1 -1
- package/dist/sdk/api/types/InputParams.d.ts +1 -1
- package/dist/sdk/api/types/{Job.d.ts → ServiceExecution.d.ts} +2 -2
- package/dist/sdk/api/types/{JobStatus.d.ts → ServiceExecutionStatus.d.ts} +2 -2
- package/dist/sdk/api/types/{JobStatus.js → ServiceExecutionStatus.js} +2 -2
- package/dist/sdk/api/types/index.d.ts +4 -8
- package/dist/sdk/api/types/index.js +4 -8
- package/dist/sdk/core/fetcher/APIResponse.d.ts +1 -0
- package/dist/sdk/core/fetcher/Fetcher.d.ts +6 -5
- package/dist/sdk/core/fetcher/Fetcher.js +68 -112
- package/dist/sdk/core/fetcher/Supplier.js +2 -11
- package/dist/sdk/core/fetcher/createRequestUrl.d.ts +1 -0
- package/dist/sdk/core/fetcher/createRequestUrl.js +12 -0
- package/dist/sdk/core/fetcher/getFetchFn.d.ts +4 -0
- package/dist/sdk/core/fetcher/getFetchFn.js +57 -0
- package/dist/sdk/core/fetcher/getHeader.d.ts +1 -0
- package/dist/sdk/core/fetcher/getHeader.js +11 -0
- package/dist/sdk/core/fetcher/getRequestBody.d.ts +7 -0
- package/dist/sdk/core/fetcher/getRequestBody.js +11 -0
- package/dist/sdk/core/fetcher/getResponseBody.d.ts +1 -0
- package/dist/sdk/core/fetcher/getResponseBody.js +40 -0
- package/dist/sdk/core/fetcher/index.d.ts +1 -0
- package/dist/sdk/core/fetcher/index.js +3 -1
- package/dist/sdk/core/fetcher/makeRequest.d.ts +1 -0
- package/dist/sdk/core/fetcher/makeRequest.js +33 -0
- package/dist/sdk/core/fetcher/requestWithRetries.d.ts +1 -0
- package/dist/sdk/core/fetcher/requestWithRetries.js +20 -0
- package/dist/sdk/core/fetcher/signals.d.ts +11 -0
- package/dist/sdk/core/fetcher/signals.js +36 -0
- package/dist/sdk/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.d.ts +30 -0
- package/dist/sdk/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.js +232 -0
- package/dist/sdk/core/fetcher/stream-wrappers/NodePre18StreamWrapper.d.ts +21 -0
- package/dist/sdk/core/fetcher/stream-wrappers/NodePre18StreamWrapper.js +91 -0
- package/dist/sdk/core/fetcher/stream-wrappers/UndiciStreamWrapper.d.ts +31 -0
- package/dist/sdk/core/fetcher/stream-wrappers/UndiciStreamWrapper.js +214 -0
- package/dist/sdk/core/fetcher/stream-wrappers/chooseStreamWrapper.d.ts +18 -0
- package/dist/sdk/core/fetcher/stream-wrappers/chooseStreamWrapper.js +48 -0
- package/dist/sdk/core/index.d.ts +1 -0
- package/dist/sdk/core/index.js +1 -0
- package/dist/sdk/core/runtime/index.d.ts +1 -0
- package/dist/sdk/core/runtime/index.js +5 -0
- package/dist/sdk/core/runtime/runtime.d.ts +9 -0
- package/dist/sdk/core/runtime/runtime.js +92 -0
- package/dist/sdk/errors/PlanqkServiceApiError.js +2 -0
- package/dist/sdk/index.js +17 -7
- package/eslint.config.mjs +11 -0
- package/fern/fern.config.json +4 -0
- package/fern/generators.yml +25 -0
- package/fern/openapi/openapi.yml +342 -0
- package/notebooks/python-sdk.ipynb +280 -0
- package/package.json +27 -28
- package/planqk/__init__.py +0 -0
- package/planqk/service/__init__.py +1 -0
- package/planqk/service/_version.py +1 -0
- package/planqk/service/auth.py +30 -0
- package/planqk/service/client.py +151 -0
- package/planqk/service/sdk/__init__.py +48 -0
- package/planqk/service/sdk/client.py +152 -0
- package/planqk/service/sdk/core/__init__.py +47 -0
- package/planqk/service/sdk/core/api_error.py +17 -0
- package/planqk/service/sdk/core/client_wrapper.py +74 -0
- package/planqk/service/sdk/core/datetime_utils.py +30 -0
- package/planqk/service/sdk/core/file.py +70 -0
- package/planqk/service/sdk/core/http_client.py +575 -0
- package/planqk/service/sdk/core/jsonable_encoder.py +103 -0
- package/planqk/service/sdk/core/pydantic_utilities.py +323 -0
- package/planqk/service/sdk/core/query_encoder.py +60 -0
- package/planqk/service/sdk/core/remove_none_from_dict.py +11 -0
- package/planqk/service/sdk/core/request_options.py +35 -0
- package/planqk/service/sdk/core/serialization.py +276 -0
- package/planqk/service/sdk/environment.py +7 -0
- package/planqk/service/sdk/errors/__init__.py +15 -0
- package/planqk/service/sdk/errors/bad_request_error.py +9 -0
- package/planqk/service/sdk/errors/forbidden_error.py +9 -0
- package/planqk/service/sdk/errors/internal_server_error.py +9 -0
- package/planqk/service/sdk/errors/not_found_error.py +9 -0
- package/planqk/service/sdk/errors/unauthorized_error.py +9 -0
- package/planqk/service/sdk/service_api/__init__.py +15 -0
- package/planqk/service/sdk/service_api/client.py +1257 -0
- package/planqk/service/sdk/service_api/types/__init__.py +13 -0
- package/planqk/service/sdk/service_api/types/get_result_response.py +30 -0
- package/planqk/service/sdk/service_api/types/get_result_response_embedded.py +22 -0
- package/planqk/service/sdk/service_api/types/get_result_response_links.py +22 -0
- package/planqk/service/sdk/service_api/types/health_check_response.py +24 -0
- package/planqk/service/sdk/types/__init__.py +17 -0
- package/planqk/service/sdk/types/hal_link.py +59 -0
- package/planqk/service/sdk/types/input_data.py +5 -0
- package/planqk/service/sdk/types/input_data_ref.py +27 -0
- package/planqk/service/sdk/types/input_params.py +5 -0
- package/planqk/service/sdk/types/service_execution.py +34 -0
- package/planqk/service/sdk/types/service_execution_status.py +8 -0
- package/pyproject.toml +51 -0
- package/scripts/update-version.sh +6 -0
- package/src/client.ts +4 -78
- package/src/index.test.ts +43 -0
- package/src/sdk/Client.ts +4 -7
- package/src/sdk/api/errors/BadRequestError.ts +1 -1
- package/src/sdk/api/errors/ForbiddenError.ts +1 -1
- package/src/sdk/api/errors/InternalServerError.ts +1 -1
- package/src/sdk/api/errors/NotFoundError.ts +1 -1
- package/src/sdk/api/errors/UnauthorizedError.ts +1 -1
- package/src/sdk/api/resources/index.ts +0 -3
- package/src/sdk/api/resources/serviceApi/client/Client.ts +205 -32
- package/src/sdk/api/resources/serviceApi/client/index.ts +1 -1
- package/src/sdk/api/resources/serviceApi/types/GetResultResponse.ts +4 -5
- package/src/sdk/api/resources/serviceApi/types/GetResultResponseEmbedded.ts +9 -0
- package/src/sdk/api/resources/serviceApi/types/GetResultResponseLinks.ts +9 -0
- package/src/sdk/api/resources/{statusApi → serviceApi}/types/HealthCheckResponse.ts +1 -0
- package/src/sdk/api/resources/serviceApi/types/index.ts +3 -1
- package/src/sdk/api/types/HalLink.ts +22 -0
- package/src/sdk/api/types/InputData.ts +1 -1
- package/src/sdk/api/types/{InputRef.ts → InputDataRef.ts} +1 -1
- package/src/sdk/api/types/InputParams.ts +1 -1
- package/src/sdk/api/types/{Job.ts → ServiceExecution.ts} +2 -2
- package/src/sdk/api/types/{JobStatus.ts → ServiceExecutionStatus.ts} +2 -2
- package/src/sdk/api/types/index.ts +4 -8
- package/src/sdk/core/fetcher/APIResponse.ts +1 -0
- package/src/sdk/core/fetcher/Fetcher.ts +55 -72
- package/src/sdk/core/fetcher/createRequestUrl.ts +10 -0
- package/src/sdk/core/fetcher/getFetchFn.ts +25 -0
- package/src/sdk/core/fetcher/getHeader.ts +8 -0
- package/src/sdk/core/fetcher/getRequestBody.ts +14 -0
- package/src/sdk/core/fetcher/getResponseBody.ts +32 -0
- package/src/sdk/core/fetcher/index.ts +1 -0
- package/src/sdk/core/fetcher/makeRequest.ts +44 -0
- package/src/sdk/core/fetcher/requestWithRetries.ts +21 -0
- package/src/sdk/core/fetcher/signals.ts +38 -0
- package/src/sdk/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.ts +252 -0
- package/src/sdk/core/fetcher/stream-wrappers/NodePre18StreamWrapper.ts +106 -0
- package/src/sdk/core/fetcher/stream-wrappers/UndiciStreamWrapper.ts +239 -0
- package/src/sdk/core/fetcher/stream-wrappers/chooseStreamWrapper.ts +33 -0
- package/src/sdk/core/index.ts +1 -0
- package/src/sdk/core/runtime/index.ts +1 -0
- package/src/sdk/core/runtime/runtime.ts +126 -0
- package/tsconfig.json +15 -107
- package/uv.lock +1109 -0
- package/.eslintignore +0 -3
- package/.eslintrc +0 -7
- package/dist/sdk/api/resources/serviceApi/client/requests/GetInterimResultsRequest.d.ts +0 -9
- package/dist/sdk/api/resources/serviceApi/client/requests/StartExecutionRequest.d.ts +0 -13
- package/dist/sdk/api/resources/serviceApi/client/requests/index.d.ts +0 -2
- package/dist/sdk/api/resources/serviceApi/client/requests/index.js +0 -2
- package/dist/sdk/api/resources/statusApi/client/Client.d.ts +0 -28
- package/dist/sdk/api/resources/statusApi/client/Client.js +0 -97
- package/dist/sdk/api/resources/statusApi/client/index.d.ts +0 -1
- package/dist/sdk/api/resources/statusApi/client/index.js +0 -2
- package/dist/sdk/api/resources/statusApi/index.d.ts +0 -2
- package/dist/sdk/api/resources/statusApi/index.js +0 -18
- package/dist/sdk/api/resources/statusApi/types/index.d.ts +0 -1
- package/dist/sdk/api/resources/statusApi/types/index.js +0 -17
- package/dist/sdk/api/types/ArrayResponse.d.ts +0 -4
- package/dist/sdk/api/types/InterimResultResponse.d.ts +0 -4
- package/dist/sdk/api/types/InterimResultResponse.js +0 -5
- package/dist/sdk/api/types/Job.js +0 -5
- package/dist/sdk/api/types/NumberResponse.d.ts +0 -4
- package/dist/sdk/api/types/NumberResponse.js +0 -5
- package/dist/sdk/api/types/ObjectResponse.d.ts +0 -4
- package/dist/sdk/api/types/ObjectResponse.js +0 -5
- package/dist/sdk/api/types/StringResponse.d.ts +0 -4
- package/dist/sdk/api/types/StringResponse.js +0 -5
- package/jest.config.js +0 -12
- package/src/sdk/api/resources/serviceApi/client/requests/GetInterimResultsRequest.ts +0 -10
- package/src/sdk/api/resources/serviceApi/client/requests/StartExecutionRequest.ts +0 -15
- package/src/sdk/api/resources/serviceApi/client/requests/index.ts +0 -2
- package/src/sdk/api/resources/serviceApi/types/GetInterimResultsResponse.ts +0 -9
- package/src/sdk/api/resources/statusApi/client/Client.ts +0 -75
- package/src/sdk/api/resources/statusApi/client/index.ts +0 -1
- package/src/sdk/api/resources/statusApi/index.ts +0 -2
- package/src/sdk/api/resources/statusApi/types/index.ts +0 -1
- package/src/sdk/api/types/ArrayResponse.ts +0 -5
- package/src/sdk/api/types/InterimResultResponse.ts +0 -5
- package/src/sdk/api/types/NumberResponse.ts +0 -5
- package/src/sdk/api/types/ObjectResponse.ts +0 -5
- package/src/sdk/api/types/StringResponse.ts +0 -5
- package/tests/fixtures/complex-input.ts +0 -477
- package/tests/integration.test.ts +0 -92
- /package/dist/sdk/api/resources/serviceApi/{client/requests/GetInterimResultsRequest.js → types/GetResultResponseEmbedded.js} +0 -0
- /package/dist/sdk/api/resources/serviceApi/{client/requests/StartExecutionRequest.js → types/GetResultResponseLinks.js} +0 -0
- /package/dist/sdk/api/resources/{statusApi → serviceApi}/types/HealthCheckResponse.js +0 -0
- /package/dist/sdk/api/{resources/serviceApi/types/GetInterimResultsResponse.js → types/HalLink.js} +0 -0
- /package/dist/sdk/api/types/{ArrayResponse.js → InputDataRef.js} +0 -0
- /package/dist/sdk/api/types/{InputRef.js → ServiceExecution.js} +0 -0
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import axios, { AxiosAdapter, AxiosError, AxiosResponse } from "axios";
|
|
2
|
-
import qs from "qs";
|
|
3
1
|
import { APIResponse } from "./APIResponse";
|
|
2
|
+
import { createRequestUrl } from "./createRequestUrl";
|
|
3
|
+
import { getFetchFn } from "./getFetchFn";
|
|
4
|
+
import { getRequestBody } from "./getRequestBody";
|
|
5
|
+
import { getResponseBody } from "./getResponseBody";
|
|
6
|
+
import { makeRequest } from "./makeRequest";
|
|
7
|
+
import { requestWithRetries } from "./requestWithRetries";
|
|
4
8
|
|
|
5
9
|
export type FetchFunction = <R = unknown>(args: Fetcher.Args) => Promise<APIResponse<R, Fetcher.Error>>;
|
|
6
10
|
|
|
@@ -10,14 +14,15 @@ export declare namespace Fetcher {
|
|
|
10
14
|
method: string;
|
|
11
15
|
contentType?: string;
|
|
12
16
|
headers?: Record<string, string | undefined>;
|
|
13
|
-
queryParameters?: Record<string, string | string[]>;
|
|
17
|
+
queryParameters?: Record<string, string | string[] | object | object[]>;
|
|
14
18
|
body?: unknown;
|
|
15
19
|
timeoutMs?: number;
|
|
16
20
|
maxRetries?: number;
|
|
17
21
|
withCredentials?: boolean;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
abortSignal?: AbortSignal;
|
|
23
|
+
requestType?: "json" | "file" | "bytes";
|
|
24
|
+
responseType?: "json" | "blob" | "sse" | "streaming" | "text";
|
|
25
|
+
duplex?: "half";
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
export type Error = FailedStatusCodeError | NonJsonError | TimeoutError | UnknownError;
|
|
@@ -44,11 +49,7 @@ export declare namespace Fetcher {
|
|
|
44
49
|
}
|
|
45
50
|
}
|
|
46
51
|
|
|
47
|
-
|
|
48
|
-
const MAX_RETRY_DELAY = 60;
|
|
49
|
-
const DEFAULT_MAX_RETRIES = 2;
|
|
50
|
-
|
|
51
|
-
async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse<R, Fetcher.Error>> {
|
|
52
|
+
export async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse<R, Fetcher.Error>> {
|
|
52
53
|
const headers: Record<string, string> = {};
|
|
53
54
|
if (args.body !== undefined && args.contentType != null) {
|
|
54
55
|
headers["Content-Type"] = args.contentType;
|
|
@@ -62,70 +63,36 @@ async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse
|
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
},
|
|
72
|
-
method: args.method,
|
|
73
|
-
headers,
|
|
74
|
-
data: args.body,
|
|
75
|
-
validateStatus: () => true,
|
|
76
|
-
transformResponse: (response) => response,
|
|
77
|
-
timeout: args.timeoutMs,
|
|
78
|
-
transitional: {
|
|
79
|
-
clarifyTimeoutError: true,
|
|
80
|
-
},
|
|
81
|
-
withCredentials: args.withCredentials,
|
|
82
|
-
adapter: args.adapter,
|
|
83
|
-
onUploadProgress: args.onUploadProgress,
|
|
84
|
-
maxBodyLength: Infinity,
|
|
85
|
-
maxContentLength: Infinity,
|
|
86
|
-
responseType: args.responseType ?? "json",
|
|
87
|
-
});
|
|
66
|
+
const url = createRequestUrl(args.url, args.queryParameters);
|
|
67
|
+
let requestBody: BodyInit | undefined = await getRequestBody({
|
|
68
|
+
body: args.body,
|
|
69
|
+
type: args.requestType === "json" ? "json" : "other",
|
|
70
|
+
});
|
|
71
|
+
const fetchFn = await getFetchFn();
|
|
88
72
|
|
|
89
73
|
try {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
let body: unknown;
|
|
108
|
-
if (args.responseType === "blob") {
|
|
109
|
-
body = response.data;
|
|
110
|
-
} else if (response.data != null && response.data.length > 0) {
|
|
111
|
-
try {
|
|
112
|
-
body = JSON.parse(response.data) ?? undefined;
|
|
113
|
-
} catch {
|
|
114
|
-
return {
|
|
115
|
-
ok: false,
|
|
116
|
-
error: {
|
|
117
|
-
reason: "non-json",
|
|
118
|
-
statusCode: response.status,
|
|
119
|
-
rawBody: response.data,
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
}
|
|
74
|
+
const response = await requestWithRetries(
|
|
75
|
+
async () =>
|
|
76
|
+
makeRequest(
|
|
77
|
+
fetchFn,
|
|
78
|
+
url,
|
|
79
|
+
args.method,
|
|
80
|
+
headers,
|
|
81
|
+
requestBody,
|
|
82
|
+
args.timeoutMs,
|
|
83
|
+
args.abortSignal,
|
|
84
|
+
args.withCredentials,
|
|
85
|
+
args.duplex
|
|
86
|
+
),
|
|
87
|
+
args.maxRetries
|
|
88
|
+
);
|
|
89
|
+
let responseBody = await getResponseBody(response, args.responseType);
|
|
124
90
|
|
|
125
91
|
if (response.status >= 200 && response.status < 400) {
|
|
126
92
|
return {
|
|
127
93
|
ok: true,
|
|
128
|
-
body:
|
|
94
|
+
body: responseBody as R,
|
|
95
|
+
headers: response.headers,
|
|
129
96
|
};
|
|
130
97
|
} else {
|
|
131
98
|
return {
|
|
@@ -133,25 +100,41 @@ async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse
|
|
|
133
100
|
error: {
|
|
134
101
|
reason: "status-code",
|
|
135
102
|
statusCode: response.status,
|
|
136
|
-
body,
|
|
103
|
+
body: responseBody,
|
|
137
104
|
},
|
|
138
105
|
};
|
|
139
106
|
}
|
|
140
107
|
} catch (error) {
|
|
141
|
-
if (
|
|
108
|
+
if (args.abortSignal != null && args.abortSignal.aborted) {
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
error: {
|
|
112
|
+
reason: "unknown",
|
|
113
|
+
errorMessage: "The user aborted a request",
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
} else if (error instanceof Error && error.name === "AbortError") {
|
|
142
117
|
return {
|
|
143
118
|
ok: false,
|
|
144
119
|
error: {
|
|
145
120
|
reason: "timeout",
|
|
146
121
|
},
|
|
147
122
|
};
|
|
123
|
+
} else if (error instanceof Error) {
|
|
124
|
+
return {
|
|
125
|
+
ok: false,
|
|
126
|
+
error: {
|
|
127
|
+
reason: "unknown",
|
|
128
|
+
errorMessage: error.message,
|
|
129
|
+
},
|
|
130
|
+
};
|
|
148
131
|
}
|
|
149
132
|
|
|
150
133
|
return {
|
|
151
134
|
ok: false,
|
|
152
135
|
error: {
|
|
153
136
|
reason: "unknown",
|
|
154
|
-
errorMessage: (error
|
|
137
|
+
errorMessage: JSON.stringify(error),
|
|
155
138
|
},
|
|
156
139
|
};
|
|
157
140
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import qs from "qs";
|
|
2
|
+
|
|
3
|
+
export function createRequestUrl(
|
|
4
|
+
baseUrl: string,
|
|
5
|
+
queryParameters?: Record<string, string | string[] | object | object[]>
|
|
6
|
+
): string {
|
|
7
|
+
return Object.keys(queryParameters ?? {}).length > 0
|
|
8
|
+
? `${baseUrl}?${qs.stringify(queryParameters, { arrayFormat: "repeat" })}`
|
|
9
|
+
: baseUrl;
|
|
10
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { RUNTIME } from "../runtime";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns a fetch function based on the runtime
|
|
5
|
+
*/
|
|
6
|
+
export async function getFetchFn(): Promise<any> {
|
|
7
|
+
// In Node.js 18+ environments, use native fetch
|
|
8
|
+
if (RUNTIME.type === "node" && RUNTIME.parsedVersion != null && RUNTIME.parsedVersion >= 18) {
|
|
9
|
+
return fetch;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// In Node.js 18 or lower environments, the SDK always uses`node-fetch`.
|
|
13
|
+
if (RUNTIME.type === "node") {
|
|
14
|
+
return (await import("node-fetch")).default as any;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Otherwise the SDK uses global fetch if available,
|
|
18
|
+
// and falls back to node-fetch.
|
|
19
|
+
if (typeof fetch == "function") {
|
|
20
|
+
return fetch;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Defaults to node `node-fetch` if global fetch isn't available
|
|
24
|
+
return (await import("node-fetch")).default as any;
|
|
25
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function getHeader(headers: Record<string, any>, header: string): string | undefined {
|
|
2
|
+
for (const [headerKey, headerValue] of Object.entries(headers)) {
|
|
3
|
+
if (headerKey.toLowerCase() === header.toLowerCase()) {
|
|
4
|
+
return headerValue;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare namespace GetRequestBody {
|
|
2
|
+
interface Args {
|
|
3
|
+
body: unknown;
|
|
4
|
+
type: "json" | "file" | "bytes" | "other";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export async function getRequestBody({ body, type }: GetRequestBody.Args): Promise<BodyInit | undefined> {
|
|
9
|
+
if (type.includes("json")) {
|
|
10
|
+
return JSON.stringify(body);
|
|
11
|
+
} else {
|
|
12
|
+
return body as BodyInit;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { chooseStreamWrapper } from "./stream-wrappers/chooseStreamWrapper";
|
|
2
|
+
|
|
3
|
+
export async function getResponseBody(response: Response, responseType?: string): Promise<unknown> {
|
|
4
|
+
if (response.body != null && responseType === "blob") {
|
|
5
|
+
return await response.blob();
|
|
6
|
+
} else if (response.body != null && responseType === "sse") {
|
|
7
|
+
return response.body;
|
|
8
|
+
} else if (response.body != null && responseType === "streaming") {
|
|
9
|
+
return chooseStreamWrapper(response.body);
|
|
10
|
+
} else if (response.body != null && responseType === "text") {
|
|
11
|
+
return await response.text();
|
|
12
|
+
} else {
|
|
13
|
+
const text = await response.text();
|
|
14
|
+
if (text.length > 0) {
|
|
15
|
+
try {
|
|
16
|
+
let responseBody = JSON.parse(text);
|
|
17
|
+
return responseBody;
|
|
18
|
+
} catch (err) {
|
|
19
|
+
return {
|
|
20
|
+
ok: false,
|
|
21
|
+
error: {
|
|
22
|
+
reason: "non-json",
|
|
23
|
+
statusCode: response.status,
|
|
24
|
+
rawBody: text,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { anySignal, getTimeoutSignal } from "./signals";
|
|
2
|
+
|
|
3
|
+
export const makeRequest = async (
|
|
4
|
+
fetchFn: (url: string, init: RequestInit) => Promise<Response>,
|
|
5
|
+
url: string,
|
|
6
|
+
method: string,
|
|
7
|
+
headers: Record<string, string>,
|
|
8
|
+
requestBody: BodyInit | undefined,
|
|
9
|
+
timeoutMs?: number,
|
|
10
|
+
abortSignal?: AbortSignal,
|
|
11
|
+
withCredentials?: boolean,
|
|
12
|
+
duplex?: "half"
|
|
13
|
+
): Promise<Response> => {
|
|
14
|
+
const signals: AbortSignal[] = [];
|
|
15
|
+
|
|
16
|
+
// Add timeout signal
|
|
17
|
+
let timeoutAbortId: NodeJS.Timeout | undefined = undefined;
|
|
18
|
+
if (timeoutMs != null) {
|
|
19
|
+
const { signal, abortId } = getTimeoutSignal(timeoutMs);
|
|
20
|
+
timeoutAbortId = abortId;
|
|
21
|
+
signals.push(signal);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Add arbitrary signal
|
|
25
|
+
if (abortSignal != null) {
|
|
26
|
+
signals.push(abortSignal);
|
|
27
|
+
}
|
|
28
|
+
let newSignals = anySignal(signals);
|
|
29
|
+
const response = await fetchFn(url, {
|
|
30
|
+
method: method,
|
|
31
|
+
headers,
|
|
32
|
+
body: requestBody,
|
|
33
|
+
signal: newSignals,
|
|
34
|
+
credentials: withCredentials ? "include" : undefined,
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
duplex,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (timeoutAbortId != null) {
|
|
40
|
+
clearTimeout(timeoutAbortId);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return response;
|
|
44
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const INITIAL_RETRY_DELAY = 1;
|
|
2
|
+
const MAX_RETRY_DELAY = 60;
|
|
3
|
+
const DEFAULT_MAX_RETRIES = 2;
|
|
4
|
+
|
|
5
|
+
export async function requestWithRetries(
|
|
6
|
+
requestFn: () => Promise<Response>,
|
|
7
|
+
maxRetries: number = DEFAULT_MAX_RETRIES
|
|
8
|
+
): Promise<Response> {
|
|
9
|
+
let response: Response = await requestFn();
|
|
10
|
+
|
|
11
|
+
for (let i = 0; i < maxRetries; ++i) {
|
|
12
|
+
if ([408, 409, 429].includes(response.status) || response.status >= 500) {
|
|
13
|
+
const delay = Math.min(INITIAL_RETRY_DELAY * Math.pow(2, i), MAX_RETRY_DELAY);
|
|
14
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
15
|
+
response = await requestFn();
|
|
16
|
+
} else {
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return response!;
|
|
21
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const TIMEOUT = "timeout";
|
|
2
|
+
|
|
3
|
+
export function getTimeoutSignal(timeoutMs: number): { signal: AbortSignal; abortId: NodeJS.Timeout } {
|
|
4
|
+
const controller = new AbortController();
|
|
5
|
+
const abortId = setTimeout(() => controller.abort(TIMEOUT), timeoutMs);
|
|
6
|
+
return { signal: controller.signal, abortId };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Returns an abort signal that is getting aborted when
|
|
11
|
+
* at least one of the specified abort signals is aborted.
|
|
12
|
+
*
|
|
13
|
+
* Requires at least node.js 18.
|
|
14
|
+
*/
|
|
15
|
+
export function anySignal(...args: AbortSignal[] | [AbortSignal[]]): AbortSignal {
|
|
16
|
+
// Allowing signals to be passed either as array
|
|
17
|
+
// of signals or as multiple arguments.
|
|
18
|
+
const signals = <AbortSignal[]>(args.length === 1 && Array.isArray(args[0]) ? args[0] : args);
|
|
19
|
+
|
|
20
|
+
const controller = new AbortController();
|
|
21
|
+
|
|
22
|
+
for (const signal of signals) {
|
|
23
|
+
if (signal.aborted) {
|
|
24
|
+
// Exiting early if one of the signals
|
|
25
|
+
// is already aborted.
|
|
26
|
+
controller.abort((signal as any)?.reason);
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Listening for signals and removing the listeners
|
|
31
|
+
// when at least one symbol is aborted.
|
|
32
|
+
signal.addEventListener("abort", () => controller.abort((signal as any)?.reason), {
|
|
33
|
+
signal: controller.signal,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return controller.signal;
|
|
38
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import type { Writable } from "stream";
|
|
2
|
+
import { EventCallback, StreamWrapper } from "./chooseStreamWrapper";
|
|
3
|
+
|
|
4
|
+
export class Node18UniversalStreamWrapper<ReadFormat extends Uint8Array | Uint16Array | Uint32Array>
|
|
5
|
+
implements
|
|
6
|
+
StreamWrapper<Node18UniversalStreamWrapper<ReadFormat> | Writable | WritableStream<ReadFormat>, ReadFormat>
|
|
7
|
+
{
|
|
8
|
+
private readableStream: ReadableStream<ReadFormat>;
|
|
9
|
+
private reader: ReadableStreamDefaultReader<ReadFormat>;
|
|
10
|
+
private events: Record<string, EventCallback[] | undefined>;
|
|
11
|
+
private paused: boolean;
|
|
12
|
+
private resumeCallback: ((value?: unknown) => void) | null;
|
|
13
|
+
private encoding: string | null;
|
|
14
|
+
|
|
15
|
+
constructor(readableStream: ReadableStream<ReadFormat>) {
|
|
16
|
+
this.readableStream = readableStream;
|
|
17
|
+
this.reader = this.readableStream.getReader();
|
|
18
|
+
this.events = {
|
|
19
|
+
data: [],
|
|
20
|
+
end: [],
|
|
21
|
+
error: [],
|
|
22
|
+
readable: [],
|
|
23
|
+
close: [],
|
|
24
|
+
pause: [],
|
|
25
|
+
resume: [],
|
|
26
|
+
};
|
|
27
|
+
this.paused = false;
|
|
28
|
+
this.resumeCallback = null;
|
|
29
|
+
this.encoding = null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public on(event: string, callback: EventCallback): void {
|
|
33
|
+
this.events[event]?.push(callback);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public off(event: string, callback: EventCallback): void {
|
|
37
|
+
this.events[event] = this.events[event]?.filter((cb) => cb !== callback);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public pipe(
|
|
41
|
+
dest: Node18UniversalStreamWrapper<ReadFormat> | Writable | WritableStream<ReadFormat>
|
|
42
|
+
): Node18UniversalStreamWrapper<ReadFormat> | Writable | WritableStream<ReadFormat> {
|
|
43
|
+
this.on("data", async (chunk) => {
|
|
44
|
+
if (dest instanceof Node18UniversalStreamWrapper) {
|
|
45
|
+
dest._write(chunk);
|
|
46
|
+
} else if (dest instanceof WritableStream) {
|
|
47
|
+
const writer = dest.getWriter();
|
|
48
|
+
writer.write(chunk).then(() => writer.releaseLock());
|
|
49
|
+
} else {
|
|
50
|
+
dest.write(chunk);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
this.on("end", async () => {
|
|
55
|
+
if (dest instanceof Node18UniversalStreamWrapper) {
|
|
56
|
+
dest._end();
|
|
57
|
+
} else if (dest instanceof WritableStream) {
|
|
58
|
+
const writer = dest.getWriter();
|
|
59
|
+
writer.close();
|
|
60
|
+
} else {
|
|
61
|
+
dest.end();
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
this.on("error", async (error) => {
|
|
66
|
+
if (dest instanceof Node18UniversalStreamWrapper) {
|
|
67
|
+
dest._error(error);
|
|
68
|
+
} else if (dest instanceof WritableStream) {
|
|
69
|
+
const writer = dest.getWriter();
|
|
70
|
+
writer.abort(error);
|
|
71
|
+
} else {
|
|
72
|
+
dest.destroy(error);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
this._startReading();
|
|
77
|
+
|
|
78
|
+
return dest;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public pipeTo(
|
|
82
|
+
dest: Node18UniversalStreamWrapper<ReadFormat> | Writable | WritableStream<ReadFormat>
|
|
83
|
+
): Node18UniversalStreamWrapper<ReadFormat> | Writable | WritableStream<ReadFormat> {
|
|
84
|
+
return this.pipe(dest);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public unpipe(dest: Node18UniversalStreamWrapper<ReadFormat> | Writable | WritableStream<ReadFormat>): void {
|
|
88
|
+
this.off("data", async (chunk) => {
|
|
89
|
+
if (dest instanceof Node18UniversalStreamWrapper) {
|
|
90
|
+
dest._write(chunk);
|
|
91
|
+
} else if (dest instanceof WritableStream) {
|
|
92
|
+
const writer = dest.getWriter();
|
|
93
|
+
writer.write(chunk).then(() => writer.releaseLock());
|
|
94
|
+
} else {
|
|
95
|
+
dest.write(chunk);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
this.off("end", async () => {
|
|
100
|
+
if (dest instanceof Node18UniversalStreamWrapper) {
|
|
101
|
+
dest._end();
|
|
102
|
+
} else if (dest instanceof WritableStream) {
|
|
103
|
+
const writer = dest.getWriter();
|
|
104
|
+
writer.close();
|
|
105
|
+
} else {
|
|
106
|
+
dest.end();
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
this.off("error", async (error) => {
|
|
111
|
+
if (dest instanceof Node18UniversalStreamWrapper) {
|
|
112
|
+
dest._error(error);
|
|
113
|
+
} else if (dest instanceof WritableStream) {
|
|
114
|
+
const writer = dest.getWriter();
|
|
115
|
+
writer.abort(error);
|
|
116
|
+
} else {
|
|
117
|
+
dest.destroy(error);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public destroy(error?: Error): void {
|
|
123
|
+
this.reader
|
|
124
|
+
.cancel(error)
|
|
125
|
+
.then(() => {
|
|
126
|
+
this._emit("close");
|
|
127
|
+
})
|
|
128
|
+
.catch((err) => {
|
|
129
|
+
this._emit("error", err);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public pause(): void {
|
|
134
|
+
this.paused = true;
|
|
135
|
+
this._emit("pause");
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public resume(): void {
|
|
139
|
+
if (this.paused) {
|
|
140
|
+
this.paused = false;
|
|
141
|
+
this._emit("resume");
|
|
142
|
+
if (this.resumeCallback) {
|
|
143
|
+
this.resumeCallback();
|
|
144
|
+
this.resumeCallback = null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
public get isPaused(): boolean {
|
|
150
|
+
return this.paused;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
public async read(): Promise<ReadFormat | undefined> {
|
|
154
|
+
if (this.paused) {
|
|
155
|
+
await new Promise((resolve) => {
|
|
156
|
+
this.resumeCallback = resolve;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
const { done, value } = await this.reader.read();
|
|
160
|
+
|
|
161
|
+
if (done) {
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
return value;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
public setEncoding(encoding: string): void {
|
|
168
|
+
this.encoding = encoding;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public async text(): Promise<string> {
|
|
172
|
+
const chunks: ReadFormat[] = [];
|
|
173
|
+
|
|
174
|
+
while (true) {
|
|
175
|
+
const { done, value } = await this.reader.read();
|
|
176
|
+
if (done) break;
|
|
177
|
+
if (value) chunks.push(value);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const decoder = new TextDecoder(this.encoding || "utf-8");
|
|
181
|
+
return decoder.decode(await new Blob(chunks).arrayBuffer());
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public async json<T>(): Promise<T> {
|
|
185
|
+
const text = await this.text();
|
|
186
|
+
return JSON.parse(text);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private _write(chunk: ReadFormat): void {
|
|
190
|
+
this._emit("data", chunk);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
private _end(): void {
|
|
194
|
+
this._emit("end");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private _error(error: any): void {
|
|
198
|
+
this._emit("error", error);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
private _emit(event: string, data?: any): void {
|
|
202
|
+
if (this.events[event]) {
|
|
203
|
+
for (const callback of this.events[event] || []) {
|
|
204
|
+
callback(data);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private async _startReading(): Promise<void> {
|
|
210
|
+
try {
|
|
211
|
+
this._emit("readable");
|
|
212
|
+
while (true) {
|
|
213
|
+
if (this.paused) {
|
|
214
|
+
await new Promise((resolve) => {
|
|
215
|
+
this.resumeCallback = resolve;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
const { done, value } = await this.reader.read();
|
|
219
|
+
if (done) {
|
|
220
|
+
this._emit("end");
|
|
221
|
+
this._emit("close");
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
if (value) {
|
|
225
|
+
this._emit("data", value);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
} catch (error) {
|
|
229
|
+
this._emit("error", error);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<ReadFormat> {
|
|
234
|
+
return {
|
|
235
|
+
next: async () => {
|
|
236
|
+
if (this.paused) {
|
|
237
|
+
await new Promise((resolve) => {
|
|
238
|
+
this.resumeCallback = resolve;
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
const { done, value } = await this.reader.read();
|
|
242
|
+
if (done) {
|
|
243
|
+
return { done: true, value: undefined };
|
|
244
|
+
}
|
|
245
|
+
return { done: false, value };
|
|
246
|
+
},
|
|
247
|
+
[Symbol.asyncIterator]() {
|
|
248
|
+
return this;
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
}
|