@planqk/planqk-service-sdk 2.1.1 → 2.2.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/.gitlab-ci.yml +8 -39
- package/README-node.md +16 -12
- package/README.md +30 -41
- package/dist/sdk/Client.d.ts +10 -4
- package/dist/sdk/Client.js +46 -4
- package/dist/sdk/api/index.d.ts +2 -3
- package/dist/sdk/api/index.js +2 -3
- package/dist/sdk/api/resources/index.d.ts +2 -2
- package/dist/sdk/api/resources/index.js +2 -2
- package/dist/sdk/api/resources/serviceApi/client/Client.d.ts +41 -55
- package/dist/sdk/api/resources/serviceApi/client/Client.js +131 -227
- package/dist/sdk/api/resources/serviceApi/index.d.ts +2 -2
- package/dist/sdk/api/resources/serviceApi/index.js +2 -2
- package/dist/sdk/api/resources/serviceApi/types/GetResultResponse.d.ts +13 -3
- package/dist/sdk/api/resources/serviceApi/types/index.d.ts +1 -4
- package/dist/sdk/api/resources/serviceApi/types/index.js +1 -4
- package/dist/sdk/api/types/ServiceExecution.d.ts +12 -2
- package/dist/sdk/api/types/ServiceExecution.js +12 -0
- package/dist/sdk/api/types/index.d.ts +2 -6
- package/dist/sdk/api/types/index.js +2 -6
- package/dist/sdk/core/auth/BasicAuth.js +3 -3
- package/dist/sdk/core/auth/index.d.ts +2 -2
- package/dist/sdk/core/auth/index.js +4 -4
- package/dist/sdk/core/base64.d.ts +2 -0
- package/dist/sdk/core/base64.js +26 -0
- package/dist/sdk/core/fetcher/APIResponse.d.ts +10 -0
- package/dist/sdk/core/fetcher/BinaryResponse.d.ts +20 -0
- package/dist/sdk/core/fetcher/BinaryResponse.js +17 -0
- package/dist/sdk/core/fetcher/Fetcher.d.ts +5 -4
- package/dist/sdk/core/fetcher/Fetcher.js +41 -22
- package/dist/sdk/core/fetcher/Headers.d.ts +2 -0
- package/dist/sdk/core/fetcher/Headers.js +85 -0
- package/dist/sdk/core/fetcher/HttpResponsePromise.d.ts +58 -0
- package/dist/sdk/core/fetcher/HttpResponsePromise.js +94 -0
- package/dist/sdk/core/fetcher/RawResponse.d.ts +29 -0
- package/dist/sdk/core/fetcher/RawResponse.js +44 -0
- package/dist/sdk/core/fetcher/ResponseWithBody.d.ts +4 -0
- package/dist/sdk/core/fetcher/ResponseWithBody.js +6 -0
- package/dist/sdk/core/fetcher/createRequestUrl.d.ts +1 -1
- package/dist/sdk/core/fetcher/createRequestUrl.js +3 -7
- package/dist/sdk/core/fetcher/getErrorResponseBody.d.ts +1 -0
- package/dist/sdk/core/fetcher/getErrorResponseBody.js +32 -0
- package/dist/sdk/core/fetcher/getFetchFn.d.ts +1 -4
- package/dist/sdk/core/fetcher/getFetchFn.js +1 -52
- package/dist/sdk/core/fetcher/getRequestBody.js +2 -1
- package/dist/sdk/core/fetcher/getResponseBody.js +34 -30
- package/dist/sdk/core/fetcher/index.d.ts +9 -5
- package/dist/sdk/core/fetcher/index.js +13 -7
- package/dist/sdk/core/fetcher/makeRequest.js +3 -3
- package/dist/sdk/core/fetcher/requestWithRetries.js +14 -5
- package/dist/sdk/core/headers.d.ts +3 -0
- package/dist/sdk/core/headers.js +29 -0
- package/dist/sdk/core/index.d.ts +5 -3
- package/dist/sdk/core/index.js +28 -3
- package/dist/sdk/core/json.d.ts +15 -0
- package/dist/sdk/core/json.js +24 -0
- package/dist/sdk/core/runtime/index.d.ts +1 -1
- package/dist/sdk/core/runtime/index.js +2 -2
- package/dist/sdk/core/runtime/runtime.d.ts +1 -1
- package/dist/sdk/core/runtime/runtime.js +49 -40
- package/dist/sdk/core/url/index.d.ts +2 -0
- package/dist/sdk/core/url/index.js +7 -0
- package/dist/sdk/core/url/join.d.ts +1 -0
- package/dist/sdk/core/url/join.js +49 -0
- package/dist/sdk/core/url/qs.d.ts +6 -0
- package/dist/sdk/core/url/qs.js +67 -0
- package/dist/sdk/errors/PlanqkServiceApiError.d.ts +4 -1
- package/dist/sdk/errors/PlanqkServiceApiError.js +7 -8
- package/dist/sdk/errors/PlanqkServiceApiTimeoutError.d.ts +1 -1
- package/dist/sdk/errors/PlanqkServiceApiTimeoutError.js +2 -2
- package/dist/sdk/errors/index.d.ts +2 -2
- package/dist/sdk/errors/index.js +4 -4
- package/dist/sdk/index.d.ts +4 -4
- package/dist/sdk/index.js +9 -9
- package/fern/fern.config.json +1 -1
- package/fern/generators.yml +2 -2
- package/fern/openapi/openapi.yml +41 -131
- package/notebooks/python-sdk.ipynb +1 -1
- package/package.json +2 -3
- package/planqk/service/_version.py +1 -1
- package/pyproject.toml +1 -1
- package/src/index.test.ts +29 -16
- package/src/sdk/Client.ts +27 -7
- package/src/sdk/api/index.ts +2 -3
- package/src/sdk/api/resources/index.ts +2 -2
- package/src/sdk/api/resources/serviceApi/client/Client.ts +223 -250
- package/src/sdk/api/resources/serviceApi/index.ts +2 -2
- package/src/sdk/api/resources/serviceApi/types/GetResultResponse.ts +15 -3
- package/src/sdk/api/resources/serviceApi/types/index.ts +1 -4
- package/src/sdk/api/types/ServiceExecution.ts +13 -3
- package/src/sdk/api/types/index.ts +2 -6
- package/src/sdk/core/auth/BasicAuth.ts +3 -3
- package/src/sdk/core/auth/index.ts +2 -2
- package/src/sdk/core/base64.ts +27 -0
- package/src/sdk/core/fetcher/APIResponse.ts +11 -0
- package/src/sdk/core/fetcher/BinaryResponse.ts +36 -0
- package/src/sdk/core/fetcher/Fetcher.ts +46 -26
- package/src/sdk/core/fetcher/Headers.ts +93 -0
- package/src/sdk/core/fetcher/HttpResponsePromise.ts +116 -0
- package/src/sdk/core/fetcher/RawResponse.ts +61 -0
- package/src/sdk/core/fetcher/ResponseWithBody.ts +7 -0
- package/src/sdk/core/fetcher/createRequestUrl.ts +4 -8
- package/src/sdk/core/fetcher/getErrorResponseBody.ts +32 -0
- package/src/sdk/core/fetcher/getFetchFn.ts +2 -24
- package/src/sdk/core/fetcher/getRequestBody.ts +3 -1
- package/src/sdk/core/fetcher/getResponseBody.ts +38 -27
- package/src/sdk/core/fetcher/index.ts +9 -5
- package/src/sdk/core/fetcher/makeRequest.ts +2 -2
- package/src/sdk/core/fetcher/requestWithRetries.ts +18 -6
- package/src/sdk/core/fetcher/signals.ts +1 -1
- package/src/sdk/core/headers.ts +35 -0
- package/src/sdk/core/index.ts +5 -3
- package/src/sdk/core/json.ts +27 -0
- package/src/sdk/core/runtime/index.ts +1 -1
- package/src/sdk/core/runtime/runtime.ts +60 -53
- package/src/sdk/core/url/index.ts +2 -0
- package/src/sdk/core/url/join.ts +55 -0
- package/src/sdk/core/url/qs.ts +74 -0
- package/src/sdk/errors/PlanqkServiceApiError.ts +21 -11
- package/src/sdk/errors/PlanqkServiceApiTimeoutError.ts +2 -2
- package/src/sdk/errors/index.ts +2 -2
- package/src/sdk/index.ts +4 -4
- package/dist/sdk/api/errors/BadRequestError.d.ts +0 -7
- package/dist/sdk/api/errors/BadRequestError.js +0 -51
- package/dist/sdk/api/errors/ForbiddenError.d.ts +0 -7
- package/dist/sdk/api/errors/ForbiddenError.js +0 -51
- package/dist/sdk/api/errors/InternalServerError.d.ts +0 -7
- package/dist/sdk/api/errors/InternalServerError.js +0 -51
- package/dist/sdk/api/errors/NotFoundError.d.ts +0 -7
- package/dist/sdk/api/errors/NotFoundError.js +0 -51
- package/dist/sdk/api/errors/UnauthorizedError.d.ts +0 -7
- package/dist/sdk/api/errors/UnauthorizedError.js +0 -51
- package/dist/sdk/api/errors/index.d.ts +0 -5
- package/dist/sdk/api/errors/index.js +0 -21
- package/dist/sdk/api/resources/serviceApi/types/GetResultResponseEmbedded.d.ts +0 -7
- package/dist/sdk/api/resources/serviceApi/types/GetResultResponseEmbedded.js +0 -5
- package/dist/sdk/api/resources/serviceApi/types/GetResultResponseLinks.d.ts +0 -7
- package/dist/sdk/api/resources/serviceApi/types/GetResultResponseLinks.js +0 -5
- package/dist/sdk/api/resources/serviceApi/types/HealthCheckResponse.d.ts +0 -7
- package/dist/sdk/api/resources/serviceApi/types/HealthCheckResponse.js +0 -5
- package/dist/sdk/api/types/InputData.d.ts +0 -4
- package/dist/sdk/api/types/InputData.js +0 -5
- package/dist/sdk/api/types/InputDataRef.d.ts +0 -8
- package/dist/sdk/api/types/InputDataRef.js +0 -5
- package/dist/sdk/api/types/InputParams.d.ts +0 -4
- package/dist/sdk/api/types/InputParams.js +0 -5
- package/dist/sdk/api/types/ServiceExecutionStatus.d.ts +0 -12
- package/dist/sdk/api/types/ServiceExecutionStatus.js +0 -14
- package/dist/sdk/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.d.ts +0 -30
- package/dist/sdk/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.js +0 -232
- package/dist/sdk/core/fetcher/stream-wrappers/NodePre18StreamWrapper.d.ts +0 -21
- package/dist/sdk/core/fetcher/stream-wrappers/NodePre18StreamWrapper.js +0 -91
- package/dist/sdk/core/fetcher/stream-wrappers/UndiciStreamWrapper.d.ts +0 -31
- package/dist/sdk/core/fetcher/stream-wrappers/UndiciStreamWrapper.js +0 -214
- package/dist/sdk/core/fetcher/stream-wrappers/chooseStreamWrapper.d.ts +0 -18
- package/dist/sdk/core/fetcher/stream-wrappers/chooseStreamWrapper.js +0 -48
- package/src/sdk/api/errors/BadRequestError.ts +0 -16
- package/src/sdk/api/errors/ForbiddenError.ts +0 -16
- package/src/sdk/api/errors/InternalServerError.ts +0 -16
- package/src/sdk/api/errors/NotFoundError.ts +0 -16
- package/src/sdk/api/errors/UnauthorizedError.ts +0 -16
- package/src/sdk/api/errors/index.ts +0 -5
- package/src/sdk/api/resources/serviceApi/types/GetResultResponseEmbedded.ts +0 -9
- package/src/sdk/api/resources/serviceApi/types/GetResultResponseLinks.ts +0 -9
- package/src/sdk/api/resources/serviceApi/types/HealthCheckResponse.ts +0 -8
- package/src/sdk/api/types/InputData.ts +0 -5
- package/src/sdk/api/types/InputDataRef.ts +0 -9
- package/src/sdk/api/types/InputParams.ts +0 -5
- package/src/sdk/api/types/ServiceExecutionStatus.ts +0 -14
- package/src/sdk/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.ts +0 -252
- package/src/sdk/core/fetcher/stream-wrappers/NodePre18StreamWrapper.ts +0 -106
- package/src/sdk/core/fetcher/stream-wrappers/UndiciStreamWrapper.ts +0 -239
- package/src/sdk/core/fetcher/stream-wrappers/chooseStreamWrapper.ts +0 -33
|
@@ -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
|
+
}
|
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
|
|
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;
|
|
1
|
+
export async function getFetchFn(): Promise<typeof fetch> {
|
|
2
|
+
return fetch;
|
|
25
3
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { toJson } from "../json.js";
|
|
2
|
+
|
|
1
3
|
export declare namespace GetRequestBody {
|
|
2
4
|
interface Args {
|
|
3
5
|
body: unknown;
|
|
@@ -7,7 +9,7 @@ export declare namespace GetRequestBody {
|
|
|
7
9
|
|
|
8
10
|
export async function getRequestBody({ body, type }: GetRequestBody.Args): Promise<BodyInit | undefined> {
|
|
9
11
|
if (type.includes("json")) {
|
|
10
|
-
return
|
|
12
|
+
return toJson(body);
|
|
11
13
|
} else {
|
|
12
14
|
return body as BodyInit;
|
|
13
15
|
}
|
|
@@ -1,32 +1,43 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getBinaryResponse } from "./BinaryResponse.js";
|
|
2
|
+
import { isResponseWithBody } from "./ResponseWithBody.js";
|
|
3
|
+
import { fromJson } from "../json.js";
|
|
2
4
|
|
|
3
5
|
export async function getResponseBody(response: Response, responseType?: string): Promise<unknown> {
|
|
4
|
-
if (response
|
|
5
|
-
return
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
6
|
+
if (!isResponseWithBody(response)) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
switch (responseType) {
|
|
10
|
+
case "binary-response":
|
|
11
|
+
return getBinaryResponse(response);
|
|
12
|
+
case "blob":
|
|
13
|
+
return await response.blob();
|
|
14
|
+
case "arrayBuffer":
|
|
15
|
+
return await response.arrayBuffer();
|
|
16
|
+
case "sse":
|
|
17
|
+
return response.body;
|
|
18
|
+
case "streaming":
|
|
19
|
+
return response.body;
|
|
20
|
+
|
|
21
|
+
case "text":
|
|
22
|
+
return await response.text();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// if responseType is "json" or not specified, try to parse as JSON
|
|
26
|
+
const text = await response.text();
|
|
27
|
+
if (text.length > 0) {
|
|
28
|
+
try {
|
|
29
|
+
let responseBody = fromJson(text);
|
|
30
|
+
return responseBody;
|
|
31
|
+
} catch (err) {
|
|
32
|
+
return {
|
|
33
|
+
ok: false,
|
|
34
|
+
error: {
|
|
35
|
+
reason: "non-json",
|
|
36
|
+
statusCode: response.status,
|
|
37
|
+
rawBody: text,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
30
40
|
}
|
|
31
41
|
}
|
|
42
|
+
return undefined;
|
|
32
43
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
export type { APIResponse } from "./APIResponse";
|
|
2
|
-
export { fetcher } from "./Fetcher";
|
|
3
|
-
export type { Fetcher, FetchFunction } from "./Fetcher";
|
|
4
|
-
export { getHeader } from "./getHeader";
|
|
5
|
-
export { Supplier } from "./Supplier";
|
|
1
|
+
export type { APIResponse } from "./APIResponse.js";
|
|
2
|
+
export { fetcher } from "./Fetcher.js";
|
|
3
|
+
export type { Fetcher, FetchFunction } from "./Fetcher.js";
|
|
4
|
+
export { getHeader } from "./getHeader.js";
|
|
5
|
+
export { Supplier } from "./Supplier.js";
|
|
6
|
+
export { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js";
|
|
7
|
+
export type { RawResponse, WithRawResponse } from "./RawResponse.js";
|
|
8
|
+
export { HttpResponsePromise } from "./HttpResponsePromise.js";
|
|
9
|
+
export { BinaryResponse } from "./BinaryResponse.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { anySignal, getTimeoutSignal } from "./signals";
|
|
1
|
+
import { anySignal, getTimeoutSignal } from "./signals.js";
|
|
2
2
|
|
|
3
3
|
export const makeRequest = async (
|
|
4
4
|
fetchFn: (url: string, init: RequestInit) => Promise<Response>,
|
|
@@ -9,7 +9,7 @@ export const makeRequest = async (
|
|
|
9
9
|
timeoutMs?: number,
|
|
10
10
|
abortSignal?: AbortSignal,
|
|
11
11
|
withCredentials?: boolean,
|
|
12
|
-
duplex?: "half"
|
|
12
|
+
duplex?: "half",
|
|
13
13
|
): Promise<Response> => {
|
|
14
14
|
const signals: AbortSignal[] = [];
|
|
15
15
|
|
|
@@ -1,17 +1,29 @@
|
|
|
1
|
-
const INITIAL_RETRY_DELAY =
|
|
2
|
-
const MAX_RETRY_DELAY =
|
|
1
|
+
const INITIAL_RETRY_DELAY = 1000; // in milliseconds
|
|
2
|
+
const MAX_RETRY_DELAY = 60000; // in milliseconds
|
|
3
3
|
const DEFAULT_MAX_RETRIES = 2;
|
|
4
|
+
const JITTER_FACTOR = 0.2; // 20% random jitter
|
|
5
|
+
|
|
6
|
+
function addJitter(delay: number): number {
|
|
7
|
+
// Generate a random value between -JITTER_FACTOR and +JITTER_FACTOR
|
|
8
|
+
const jitterMultiplier = 1 + (Math.random() * 2 - 1) * JITTER_FACTOR;
|
|
9
|
+
return delay * jitterMultiplier;
|
|
10
|
+
}
|
|
4
11
|
|
|
5
12
|
export async function requestWithRetries(
|
|
6
13
|
requestFn: () => Promise<Response>,
|
|
7
|
-
maxRetries: number = DEFAULT_MAX_RETRIES
|
|
14
|
+
maxRetries: number = DEFAULT_MAX_RETRIES,
|
|
8
15
|
): Promise<Response> {
|
|
9
16
|
let response: Response = await requestFn();
|
|
10
17
|
|
|
11
18
|
for (let i = 0; i < maxRetries; ++i) {
|
|
12
|
-
if ([408,
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
if ([408, 429].includes(response.status) || response.status >= 500) {
|
|
20
|
+
// Calculate base delay using exponential backoff (in milliseconds)
|
|
21
|
+
const baseDelay = Math.min(INITIAL_RETRY_DELAY * Math.pow(2, i), MAX_RETRY_DELAY);
|
|
22
|
+
|
|
23
|
+
// Add jitter to the delay
|
|
24
|
+
const delayWithJitter = addJitter(baseDelay);
|
|
25
|
+
|
|
26
|
+
await new Promise((resolve) => setTimeout(resolve, delayWithJitter));
|
|
15
27
|
response = await requestFn();
|
|
16
28
|
} else {
|
|
17
29
|
break;
|
|
@@ -15,7 +15,7 @@ export function getTimeoutSignal(timeoutMs: number): { signal: AbortSignal; abor
|
|
|
15
15
|
export function anySignal(...args: AbortSignal[] | [AbortSignal[]]): AbortSignal {
|
|
16
16
|
// Allowing signals to be passed either as array
|
|
17
17
|
// of signals or as multiple arguments.
|
|
18
|
-
const signals =
|
|
18
|
+
const signals = (args.length === 1 && Array.isArray(args[0]) ? args[0] : args) as AbortSignal[];
|
|
19
19
|
|
|
20
20
|
const controller = new AbortController();
|
|
21
21
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as core from "./index.js";
|
|
2
|
+
|
|
3
|
+
export function mergeHeaders(
|
|
4
|
+
...headersArray: (Record<string, string | core.Supplier<string | undefined> | undefined> | undefined)[]
|
|
5
|
+
): Record<string, string | core.Supplier<string | undefined>> {
|
|
6
|
+
const result: Record<string, string | core.Supplier<string | undefined>> = {};
|
|
7
|
+
|
|
8
|
+
for (const [key, value] of headersArray
|
|
9
|
+
.filter((headers) => headers != null)
|
|
10
|
+
.flatMap((headers) => Object.entries(headers))) {
|
|
11
|
+
if (value != null) {
|
|
12
|
+
result[key] = value;
|
|
13
|
+
} else if (key in result) {
|
|
14
|
+
delete result[key];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function mergeOnlyDefinedHeaders(
|
|
22
|
+
...headersArray: (Record<string, string | core.Supplier<string | undefined> | undefined> | undefined)[]
|
|
23
|
+
): Record<string, string | core.Supplier<string | undefined>> {
|
|
24
|
+
const result: Record<string, string | core.Supplier<string | undefined>> = {};
|
|
25
|
+
|
|
26
|
+
for (const [key, value] of headersArray
|
|
27
|
+
.filter((headers) => headers != null)
|
|
28
|
+
.flatMap((headers) => Object.entries(headers))) {
|
|
29
|
+
if (value != null) {
|
|
30
|
+
result[key] = value;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return result;
|
|
35
|
+
}
|
package/src/sdk/core/index.ts
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize a value to JSON
|
|
3
|
+
* @param value A JavaScript value, usually an object or array, to be converted.
|
|
4
|
+
* @param replacer A function that transforms the results.
|
|
5
|
+
* @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
|
|
6
|
+
* @returns JSON string
|
|
7
|
+
*/
|
|
8
|
+
export const toJson = (
|
|
9
|
+
value: unknown,
|
|
10
|
+
replacer?: (this: unknown, key: string, value: unknown) => unknown,
|
|
11
|
+
space?: string | number,
|
|
12
|
+
): string => {
|
|
13
|
+
return JSON.stringify(value, replacer, space);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Parse JSON string to object, array, or other type
|
|
18
|
+
* @param text A valid JSON string.
|
|
19
|
+
* @param reviver A function that transforms the results. This function is called for each member of the object. If a member contains nested objects, the nested objects are transformed before the parent object is.
|
|
20
|
+
* @returns Parsed object, array, or other type
|
|
21
|
+
*/
|
|
22
|
+
export function fromJson<T = unknown>(
|
|
23
|
+
text: string,
|
|
24
|
+
reviver?: (this: unknown, key: string, value: unknown) => unknown,
|
|
25
|
+
): T {
|
|
26
|
+
return JSON.parse(text, reviver);
|
|
27
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { RUNTIME } from "./runtime";
|
|
1
|
+
export { RUNTIME } from "./runtime.js";
|
|
@@ -8,58 +8,12 @@ interface BunGlobal {
|
|
|
8
8
|
version: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
declare const Deno: DenoGlobal;
|
|
12
|
-
declare const Bun: BunGlobal;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* A constant that indicates whether the environment the code is running is a Web Worker.
|
|
21
|
-
*/
|
|
22
|
-
const isWebWorker =
|
|
23
|
-
typeof self === "object" &&
|
|
24
|
-
// @ts-ignore
|
|
25
|
-
typeof self?.importScripts === "function" &&
|
|
26
|
-
(self.constructor?.name === "DedicatedWorkerGlobalScope" ||
|
|
27
|
-
self.constructor?.name === "ServiceWorkerGlobalScope" ||
|
|
28
|
-
self.constructor?.name === "SharedWorkerGlobalScope");
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* A constant that indicates whether the environment the code is running is Deno.
|
|
32
|
-
*/
|
|
33
|
-
const isDeno =
|
|
34
|
-
typeof Deno !== "undefined" && typeof Deno.version !== "undefined" && typeof Deno.version.deno !== "undefined";
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* A constant that indicates whether the environment the code is running is Bun.sh.
|
|
38
|
-
*/
|
|
39
|
-
const isBun = typeof Bun !== "undefined" && typeof Bun.version !== "undefined";
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* A constant that indicates whether the environment the code is running is Node.JS.
|
|
43
|
-
*/
|
|
44
|
-
const isNode =
|
|
45
|
-
typeof process !== "undefined" &&
|
|
46
|
-
Boolean(process.version) &&
|
|
47
|
-
Boolean(process.versions?.node) &&
|
|
48
|
-
// Deno spoofs process.versions.node, see https://deno.land/std@0.177.0/node/process.ts?s=versions
|
|
49
|
-
!isDeno &&
|
|
50
|
-
!isBun;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* A constant that indicates whether the environment the code is running is in React-Native.
|
|
54
|
-
* https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Core/setUpNavigator.js
|
|
55
|
-
*/
|
|
56
|
-
const isReactNative = typeof navigator !== "undefined" && navigator?.product === "ReactNative";
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* A constant that indicates whether the environment the code is running is Cloudflare.
|
|
60
|
-
* https://developers.cloudflare.com/workers/runtime-apis/web-standards/#navigatoruseragent
|
|
61
|
-
*/
|
|
62
|
-
const isCloudflare = typeof globalThis !== "undefined" && globalThis?.navigator?.userAgent === "Cloudflare-Workers";
|
|
11
|
+
declare const Deno: DenoGlobal | undefined;
|
|
12
|
+
declare const Bun: BunGlobal | undefined;
|
|
13
|
+
declare const EdgeRuntime: string | undefined;
|
|
14
|
+
declare const self: typeof globalThis.self & {
|
|
15
|
+
importScripts?: unknown;
|
|
16
|
+
};
|
|
63
17
|
|
|
64
18
|
/**
|
|
65
19
|
* A constant that indicates which environment and version the SDK is running in.
|
|
@@ -67,12 +21,16 @@ const isCloudflare = typeof globalThis !== "undefined" && globalThis?.navigator?
|
|
|
67
21
|
export const RUNTIME: Runtime = evaluateRuntime();
|
|
68
22
|
|
|
69
23
|
export interface Runtime {
|
|
70
|
-
type: "browser" | "web-worker" | "deno" | "bun" | "node" | "react-native" | "unknown" | "workerd";
|
|
24
|
+
type: "browser" | "web-worker" | "deno" | "bun" | "node" | "react-native" | "unknown" | "workerd" | "edge-runtime";
|
|
71
25
|
version?: string;
|
|
72
26
|
parsedVersion?: number;
|
|
73
27
|
}
|
|
74
28
|
|
|
75
29
|
function evaluateRuntime(): Runtime {
|
|
30
|
+
/**
|
|
31
|
+
* A constant that indicates whether the environment the code is running is a Web Browser.
|
|
32
|
+
*/
|
|
33
|
+
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
76
34
|
if (isBrowser) {
|
|
77
35
|
return {
|
|
78
36
|
type: "browser",
|
|
@@ -80,18 +38,49 @@ function evaluateRuntime(): Runtime {
|
|
|
80
38
|
};
|
|
81
39
|
}
|
|
82
40
|
|
|
41
|
+
/**
|
|
42
|
+
* A constant that indicates whether the environment the code is running is Cloudflare.
|
|
43
|
+
* https://developers.cloudflare.com/workers/runtime-apis/web-standards/#navigatoruseragent
|
|
44
|
+
*/
|
|
45
|
+
const isCloudflare = typeof globalThis !== "undefined" && globalThis?.navigator?.userAgent === "Cloudflare-Workers";
|
|
83
46
|
if (isCloudflare) {
|
|
84
47
|
return {
|
|
85
48
|
type: "workerd",
|
|
86
49
|
};
|
|
87
50
|
}
|
|
88
51
|
|
|
52
|
+
/**
|
|
53
|
+
* A constant that indicates whether the environment the code is running is Edge Runtime.
|
|
54
|
+
* https://vercel.com/docs/functions/runtimes/edge-runtime#check-if-you're-running-on-the-edge-runtime
|
|
55
|
+
*/
|
|
56
|
+
const isEdgeRuntime = typeof EdgeRuntime === "string";
|
|
57
|
+
if (isEdgeRuntime) {
|
|
58
|
+
return {
|
|
59
|
+
type: "edge-runtime",
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A constant that indicates whether the environment the code is running is a Web Worker.
|
|
65
|
+
*/
|
|
66
|
+
const isWebWorker =
|
|
67
|
+
typeof self === "object" &&
|
|
68
|
+
typeof self?.importScripts === "function" &&
|
|
69
|
+
(self.constructor?.name === "DedicatedWorkerGlobalScope" ||
|
|
70
|
+
self.constructor?.name === "ServiceWorkerGlobalScope" ||
|
|
71
|
+
self.constructor?.name === "SharedWorkerGlobalScope");
|
|
89
72
|
if (isWebWorker) {
|
|
90
73
|
return {
|
|
91
74
|
type: "web-worker",
|
|
92
75
|
};
|
|
93
76
|
}
|
|
94
77
|
|
|
78
|
+
/**
|
|
79
|
+
* A constant that indicates whether the environment the code is running is Deno.
|
|
80
|
+
* FYI Deno spoofs process.versions.node, see https://deno.land/std@0.177.0/node/process.ts?s=versions
|
|
81
|
+
*/
|
|
82
|
+
const isDeno =
|
|
83
|
+
typeof Deno !== "undefined" && typeof Deno.version !== "undefined" && typeof Deno.version.deno !== "undefined";
|
|
95
84
|
if (isDeno) {
|
|
96
85
|
return {
|
|
97
86
|
type: "deno",
|
|
@@ -99,6 +88,10 @@ function evaluateRuntime(): Runtime {
|
|
|
99
88
|
};
|
|
100
89
|
}
|
|
101
90
|
|
|
91
|
+
/**
|
|
92
|
+
* A constant that indicates whether the environment the code is running is Bun.sh.
|
|
93
|
+
*/
|
|
94
|
+
const isBun = typeof Bun !== "undefined" && typeof Bun.version !== "undefined";
|
|
102
95
|
if (isBun) {
|
|
103
96
|
return {
|
|
104
97
|
type: "bun",
|
|
@@ -106,6 +99,15 @@ function evaluateRuntime(): Runtime {
|
|
|
106
99
|
};
|
|
107
100
|
}
|
|
108
101
|
|
|
102
|
+
/**
|
|
103
|
+
* A constant that indicates whether the environment the code is running is Node.JS.
|
|
104
|
+
*/
|
|
105
|
+
const isNode =
|
|
106
|
+
typeof process !== "undefined" &&
|
|
107
|
+
"version" in process &&
|
|
108
|
+
!!process.version &&
|
|
109
|
+
"versions" in process &&
|
|
110
|
+
!!process.versions?.node;
|
|
109
111
|
if (isNode) {
|
|
110
112
|
return {
|
|
111
113
|
type: "node",
|
|
@@ -114,6 +116,11 @@ function evaluateRuntime(): Runtime {
|
|
|
114
116
|
};
|
|
115
117
|
}
|
|
116
118
|
|
|
119
|
+
/**
|
|
120
|
+
* A constant that indicates whether the environment the code is running is in React-Native.
|
|
121
|
+
* https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Core/setUpNavigator.js
|
|
122
|
+
*/
|
|
123
|
+
const isReactNative = typeof navigator !== "undefined" && navigator?.product === "ReactNative";
|
|
117
124
|
if (isReactNative) {
|
|
118
125
|
return {
|
|
119
126
|
type: "react-native",
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export function join(base: string, ...segments: string[]): string {
|
|
2
|
+
if (!base) {
|
|
3
|
+
return "";
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
if (base.includes("://")) {
|
|
7
|
+
let url: URL;
|
|
8
|
+
try {
|
|
9
|
+
url = new URL(base);
|
|
10
|
+
} catch {
|
|
11
|
+
// Fallback to path joining if URL is malformed
|
|
12
|
+
return joinPath(base, ...segments);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
for (const segment of segments) {
|
|
16
|
+
const cleanSegment = trimSlashes(segment);
|
|
17
|
+
if (cleanSegment) {
|
|
18
|
+
url.pathname = joinPathSegments(url.pathname, cleanSegment);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return url.toString();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return joinPath(base, ...segments);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function joinPath(base: string, ...segments: string[]): string {
|
|
29
|
+
let result = base;
|
|
30
|
+
|
|
31
|
+
for (const segment of segments) {
|
|
32
|
+
const cleanSegment = trimSlashes(segment);
|
|
33
|
+
if (cleanSegment) {
|
|
34
|
+
result = joinPathSegments(result, cleanSegment);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function joinPathSegments(left: string, right: string): string {
|
|
42
|
+
if (left.endsWith("/")) {
|
|
43
|
+
return left + right;
|
|
44
|
+
}
|
|
45
|
+
return left + "/" + right;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function trimSlashes(str: string): string {
|
|
49
|
+
if (!str) return str;
|
|
50
|
+
|
|
51
|
+
let start = str.startsWith("/") ? 1 : 0;
|
|
52
|
+
let end = str.endsWith("/") ? str.length - 1 : str.length;
|
|
53
|
+
|
|
54
|
+
return str.slice(start, end);
|
|
55
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
interface QueryStringOptions {
|
|
2
|
+
arrayFormat?: "indices" | "repeat";
|
|
3
|
+
encode?: boolean;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const defaultQsOptions: Required<QueryStringOptions> = {
|
|
7
|
+
arrayFormat: "indices",
|
|
8
|
+
encode: true,
|
|
9
|
+
} as const;
|
|
10
|
+
|
|
11
|
+
function encodeValue(value: unknown, shouldEncode: boolean): string {
|
|
12
|
+
if (value === undefined) {
|
|
13
|
+
return "";
|
|
14
|
+
}
|
|
15
|
+
if (value === null) {
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
const stringValue = String(value);
|
|
19
|
+
return shouldEncode ? encodeURIComponent(stringValue) : stringValue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function stringifyObject(obj: Record<string, unknown>, prefix = "", options: Required<QueryStringOptions>): string[] {
|
|
23
|
+
const parts: string[] = [];
|
|
24
|
+
|
|
25
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
26
|
+
const fullKey = prefix ? `${prefix}[${key}]` : key;
|
|
27
|
+
|
|
28
|
+
if (value === undefined) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (Array.isArray(value)) {
|
|
33
|
+
if (value.length === 0) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
for (let i = 0; i < value.length; i++) {
|
|
37
|
+
const item = value[i];
|
|
38
|
+
if (item === undefined) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (typeof item === "object" && !Array.isArray(item) && item !== null) {
|
|
42
|
+
const arrayKey = options.arrayFormat === "indices" ? `${fullKey}[${i}]` : fullKey;
|
|
43
|
+
parts.push(...stringifyObject(item as Record<string, unknown>, arrayKey, options));
|
|
44
|
+
} else {
|
|
45
|
+
const arrayKey = options.arrayFormat === "indices" ? `${fullKey}[${i}]` : fullKey;
|
|
46
|
+
const encodedKey = options.encode ? encodeURIComponent(arrayKey) : arrayKey;
|
|
47
|
+
parts.push(`${encodedKey}=${encodeValue(item, options.encode)}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} else if (typeof value === "object" && value !== null) {
|
|
51
|
+
if (Object.keys(value as Record<string, unknown>).length === 0) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
parts.push(...stringifyObject(value as Record<string, unknown>, fullKey, options));
|
|
55
|
+
} else {
|
|
56
|
+
const encodedKey = options.encode ? encodeURIComponent(fullKey) : fullKey;
|
|
57
|
+
parts.push(`${encodedKey}=${encodeValue(value, options.encode)}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return parts;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function toQueryString(obj: unknown, options?: QueryStringOptions): string {
|
|
65
|
+
if (obj == null || typeof obj !== "object") {
|
|
66
|
+
return "";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const parts = stringifyObject(obj as Record<string, unknown>, "", {
|
|
70
|
+
...defaultQsOptions,
|
|
71
|
+
...options,
|
|
72
|
+
});
|
|
73
|
+
return parts.join("&");
|
|
74
|
+
}
|
|
@@ -2,20 +2,30 @@
|
|
|
2
2
|
* This file was auto-generated by Fern from our API Definition.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import * as core from "../core/index.js";
|
|
6
|
+
import { toJson } from "../core/json.js";
|
|
7
|
+
|
|
5
8
|
export class PlanqkServiceApiError extends Error {
|
|
6
|
-
readonly statusCode?: number;
|
|
7
|
-
readonly body?: unknown;
|
|
9
|
+
public readonly statusCode?: number;
|
|
10
|
+
public readonly body?: unknown;
|
|
11
|
+
public readonly rawResponse?: core.RawResponse;
|
|
8
12
|
|
|
9
|
-
constructor({
|
|
13
|
+
constructor({
|
|
14
|
+
message,
|
|
15
|
+
statusCode,
|
|
16
|
+
body,
|
|
17
|
+
rawResponse,
|
|
18
|
+
}: {
|
|
19
|
+
message?: string;
|
|
20
|
+
statusCode?: number;
|
|
21
|
+
body?: unknown;
|
|
22
|
+
rawResponse?: core.RawResponse;
|
|
23
|
+
}) {
|
|
10
24
|
super(buildMessage({ message, statusCode, body }));
|
|
11
25
|
Object.setPrototypeOf(this, PlanqkServiceApiError.prototype);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (body !== undefined) {
|
|
17
|
-
this.body = body;
|
|
18
|
-
}
|
|
26
|
+
this.statusCode = statusCode;
|
|
27
|
+
this.body = body;
|
|
28
|
+
this.rawResponse = rawResponse;
|
|
19
29
|
}
|
|
20
30
|
}
|
|
21
31
|
|
|
@@ -38,7 +48,7 @@ function buildMessage({
|
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
if (body != null) {
|
|
41
|
-
lines.push(`Body: ${
|
|
51
|
+
lines.push(`Body: ${toJson(body, undefined, 2)}`);
|
|
42
52
|
}
|
|
43
53
|
|
|
44
54
|
return lines.join("\n");
|