@kontent-ai/core-sdk 12.0.0-preview.5 → 12.0.0-preview.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/dist/devkit_api.d.ts +1 -0
- package/dist/devkit_api.js +1 -1
- package/dist/devkit_api.js.map +1 -1
- package/dist/models/error.models.d.ts +9 -14
- package/dist/models/error.models.js.map +1 -1
- package/dist/public_api.d.ts +2 -1
- package/dist/public_api.js +2 -1
- package/dist/public_api.js.map +1 -1
- package/dist/sdk/sdk-models.d.ts +2 -2
- package/dist/sdk/sdk-queries.d.ts +6 -4
- package/dist/sdk/sdk-queries.js +12 -10
- package/dist/sdk/sdk-queries.js.map +1 -1
- package/dist/sdk-info.js +1 -1
- package/dist/testkit/testkit.utils.d.ts +19 -0
- package/dist/testkit/testkit.utils.js +88 -0
- package/dist/testkit/testkit.utils.js.map +1 -0
- package/dist/testkit_api.d.ts +2 -1
- package/dist/testkit_api.js +1 -2
- package/dist/testkit_api.js.map +1 -1
- package/dist/utils/core.utils.d.ts +1 -0
- package/dist/utils/core.utils.js +5 -0
- package/dist/utils/core.utils.js.map +1 -1
- package/dist/utils/retry.utils.js +2 -4
- package/dist/utils/retry.utils.js.map +1 -1
- package/lib/devkit_api.ts +1 -1
- package/lib/models/error.models.ts +16 -34
- package/lib/public_api.ts +2 -6
- package/lib/sdk/sdk-models.ts +2 -2
- package/lib/sdk/sdk-queries.ts +19 -13
- package/lib/testkit/testkit.utils.ts +151 -0
- package/lib/testkit_api.ts +7 -2
- package/lib/utils/core.utils.ts +6 -0
- package/lib/utils/retry.utils.ts +2 -5
- package/package.json +4 -5
- package/dist/testkit/test.utils.d.ts +0 -15
- package/dist/testkit/test.utils.js +0 -42
- package/dist/testkit/test.utils.js.map +0 -1
- package/lib/testkit/test.utils.ts +0 -79
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2026 Kontent s.r.o.
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
6
|
|
package/dist/devkit_api.d.ts
CHANGED
package/dist/devkit_api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
/** biome-ignore-all lint/performance/noBarrelFile: One barrel for exported API is fine */
|
|
2
2
|
export { deleteFolderRecursive } from "./devkit/script.utils.js";
|
|
3
3
|
export { replaceSdkVersionPlaceholder } from "./utils/sdk-version.utils.js";
|
|
4
4
|
//# sourceMappingURL=devkit_api.js.map
|
package/dist/devkit_api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devkit_api.js","sourceRoot":"","sources":["../lib/devkit_api.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"devkit_api.js","sourceRoot":"","sources":["../lib/devkit_api.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -4,22 +4,11 @@ import type { SuccessfulHttpResponse } from "../sdk/sdk-models.js";
|
|
|
4
4
|
import type { KontentErrorResponseData, RetryStrategyOptions } from "./core.models.js";
|
|
5
5
|
import type { JsonValue } from "./json.models.js";
|
|
6
6
|
export type ErrorReason = "invalidResponse" | "invalidUrl" | "unknown" | "invalidBody" | "notFound" | "validationFailed" | "noResponses";
|
|
7
|
-
export type ErrorReasonData =
|
|
8
|
-
readonly kontentErrorResponse: KontentErrorResponseData | undefined;
|
|
9
|
-
} & Pick<AdapterResponse<HttpServiceStatus>, "isValidResponse" | "responseHeaders" | "status" | "statusText">> | TReasonData<"notFound", {
|
|
10
|
-
readonly kontentErrorResponse: KontentErrorResponseData | undefined;
|
|
11
|
-
} & Pick<AdapterResponse<404>, "isValidResponse" | "responseHeaders" | "status" | "statusText">> | TReasonData<"invalidBody", {
|
|
12
|
-
readonly originalError: unknown;
|
|
13
|
-
}> | TReasonData<"invalidUrl", {
|
|
14
|
-
readonly originalError: unknown;
|
|
15
|
-
}> | TReasonData<"unknown", {
|
|
16
|
-
readonly originalError: unknown;
|
|
17
|
-
}> | TReasonData<"validationFailed", {
|
|
18
|
-
readonly reason: "validationFailed";
|
|
7
|
+
export type ErrorReasonData = ReasonData<"invalidResponse", ErrorWithKontentErrorResponse> | ReasonData<"notFound", ErrorWithKontentErrorResponse> | ReasonData<"invalidBody", ErrorWithOriginalError> | ReasonData<"invalidUrl", ErrorWithOriginalError> | ReasonData<"unknown", ErrorWithOriginalError> | ReasonData<"validationFailed", {
|
|
19
8
|
readonly zodError: ZodError;
|
|
20
9
|
readonly response: SuccessfulHttpResponse<JsonValue, JsonValue>;
|
|
21
10
|
readonly url: string;
|
|
22
|
-
}> |
|
|
11
|
+
}> | ReasonData<"noResponses", {
|
|
23
12
|
readonly url: string;
|
|
24
13
|
}>;
|
|
25
14
|
export type SdkErrorDetails = {
|
|
@@ -44,7 +33,13 @@ export declare class SdkError extends Error {
|
|
|
44
33
|
readonly details: SdkErrorDetails;
|
|
45
34
|
constructor(details: SdkErrorDetails);
|
|
46
35
|
}
|
|
47
|
-
type
|
|
36
|
+
type ErrorWithKontentErrorResponse = {
|
|
37
|
+
readonly kontentErrorResponse: KontentErrorResponseData | undefined;
|
|
38
|
+
} & Pick<AdapterResponse<HttpServiceStatus>, "isValidResponse" | "responseHeaders" | "status" | "statusText">;
|
|
39
|
+
type ErrorWithOriginalError = {
|
|
40
|
+
readonly originalError: unknown;
|
|
41
|
+
};
|
|
42
|
+
type ReasonData<TReason extends ErrorReason, TData> = {
|
|
48
43
|
readonly reason: TReason;
|
|
49
44
|
} & TData;
|
|
50
45
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.models.js","sourceRoot":"","sources":["../../lib/models/error.models.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"error.models.js","sourceRoot":"","sources":["../../lib/models/error.models.ts"],"names":[],"mappings":"AAmDA,MAAM,OAAO,QAAS,SAAQ,KAAK;IACzB,OAAO,CAAkB;IAElC,YAAY,OAAwB;QACnC,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QAEhC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;CACD;AAcD,SAAS,eAAe,CAAC,KAAsB;IAC9C,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,iBAAiB,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,CAAC,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;QACvG,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,oBAAoB,CAAC,OAAO,EAAE,CAAC;IACjE,CAAC;IACD,OAAO,KAAK,CAAC,OAAO,CAAC;AACtB,CAAC"}
|
package/dist/public_api.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
/** biome-ignore-all lint/performance/noBarrelFile: One barrel for exported API is fine */
|
|
1
2
|
export { getDefaultHttpAdapter } from "./http/http.adapter.js";
|
|
2
3
|
export type { AdapterRequestOptions, AdapterResponse, DefaultHttpServiceConfig, DownloadFileRequestOptions, ExecuteRequestOptions, HttpAdapter, HttpResponse, HttpService, HttpServiceStatus, UploadFileRequestOptions, } from "./http/http.models.js";
|
|
3
4
|
export { getDefaultHttpService } from "./http/http.service.js";
|
|
4
5
|
export type { CommonHeaderNames, ContinuationHeaderName, Header, HttpMethod, RetryStrategyOptions, SDKInfo, } from "./models/core.models.js";
|
|
5
|
-
export type
|
|
6
|
+
export { type ErrorReason, type ErrorReasonData, SdkError } from "./models/error.models.js";
|
|
6
7
|
export type { JsonArray, JsonObject, JsonValue } from "./models/json.models.js";
|
|
7
8
|
export type { EmptyObject, Override, Prettify } from "./models/utility.models.js";
|
|
8
9
|
export type { PagingQuery, PagingQueryResult, Query, QueryResult, ResultOfSuccessfulQuery, SdkConfig, SdkResponse, SdkResponseMeta, SuccessfulHttpResponse, } from "./sdk/sdk-models.js";
|
package/dist/public_api.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
/** biome-ignore-all lint/performance/noBarrelFile: One barrel for exported API is fine */
|
|
2
2
|
export { getDefaultHttpAdapter } from "./http/http.adapter.js";
|
|
3
3
|
export { getDefaultHttpService } from "./http/http.service.js";
|
|
4
|
+
export { SdkError } from "./models/error.models.js";
|
|
4
5
|
export { extractContinuationToken, getPagingQuery, getQuery } from "./sdk/sdk-queries.js";
|
|
5
6
|
export { isKontent404Error } from "./utils/error.utils.js";
|
|
6
7
|
export { getSdkIdHeader } from "./utils/header.utils.js";
|
package/dist/public_api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public_api.js","sourceRoot":"","sources":["../lib/public_api.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"public_api.js","sourceRoot":"","sources":["../lib/public_api.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAa/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAS/D,OAAO,EAA0C,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAc5F,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/sdk/sdk-models.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ export type Query<TPayload, TExtraData = unknown> = {
|
|
|
48
48
|
export type PagingQuery<TPayload, TExtraData = unknown> = Query<TPayload, TExtraData> & {
|
|
49
49
|
toAllPromise(): Promise<PagingQueryResult<SdkResponse<TPayload, TExtraData>>>;
|
|
50
50
|
};
|
|
51
|
-
export type SuccessfulHttpResponse<TPayload extends JsonValue, TBodyData extends JsonValue> = Prettify<Extract<HttpResponse<TPayload, TBodyData>, {
|
|
51
|
+
export type SuccessfulHttpResponse<TPayload extends JsonValue, TBodyData extends JsonValue | Blob> = Prettify<Extract<HttpResponse<TPayload, TBodyData>, {
|
|
52
52
|
readonly success: true;
|
|
53
53
|
}>["response"]>;
|
|
54
54
|
export type ResultOfSuccessfulQuery<TQuery extends Query<unknown>> = Extract<Awaited<ReturnType<TQuery["toPromise"]>>, {
|
|
@@ -66,7 +66,7 @@ export type QueryResult<TResponse> = (Success & {
|
|
|
66
66
|
});
|
|
67
67
|
export type PagingQueryResult<TResponse> = (Success & {
|
|
68
68
|
readonly responses: TResponse[];
|
|
69
|
-
readonly lastContinuationToken: string;
|
|
69
|
+
readonly lastContinuationToken: string | undefined;
|
|
70
70
|
}) | (Failure & {
|
|
71
71
|
readonly responses?: never;
|
|
72
72
|
readonly lastContinuationToken?: never;
|
|
@@ -9,20 +9,22 @@ import type { JsonValue } from "../models/json.models.js";
|
|
|
9
9
|
import type { EmptyObject } from "../models/utility.models.js";
|
|
10
10
|
import type { PagingQuery, Query, SdkConfig, SdkResponse, SuccessfulHttpResponse } from "./sdk-models.js";
|
|
11
11
|
type ResolveToPromiseQuery<TPayload extends JsonValue, TExtraMetadata = EmptyObject> = ReturnType<Pick<Query<TPayload, TExtraMetadata>, "toPromise">["toPromise"]>;
|
|
12
|
-
|
|
12
|
+
type MetadataContextData = {
|
|
13
|
+
readonly continuationToken?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function getQuery<TPayload extends JsonValue, TBodyData extends JsonValue, TExtraMetadata = EmptyObject>(data: Parameters<typeof resolveQueryAsync<TPayload, TBodyData, TExtraMetadata>>[0]): Pick<Query<TPayload, TExtraMetadata>, "toPromise">;
|
|
13
16
|
export declare function getPagingQuery<TPayload extends JsonValue, TBodyData extends JsonValue, TExtraMetadata = EmptyObject>(data: Parameters<typeof resolveQueryAsync<TPayload, TBodyData, TExtraMetadata>>[0] & {
|
|
14
17
|
readonly canFetchNextResponse: (response: SdkResponse<TPayload, TExtraMetadata>) => boolean;
|
|
15
18
|
readonly continuationToken: string;
|
|
16
19
|
}): Pick<PagingQuery<TPayload, TExtraMetadata>, "toPromise" | "toAllPromise">;
|
|
17
20
|
export declare function extractContinuationToken(responseHeaders: readonly Header[]): string | undefined;
|
|
18
|
-
declare function resolveQueryAsync<TPayload extends JsonValue, TBodyData extends JsonValue, TExtraMetadata>({ config, request,
|
|
21
|
+
declare function resolveQueryAsync<TPayload extends JsonValue, TBodyData extends JsonValue, TExtraMetadata>({ config, request, extraMetadata, zodSchema, continuationToken, sdkInfo, authorizationApiKey, }: {
|
|
19
22
|
readonly continuationToken: string | undefined;
|
|
20
23
|
readonly request: Parameters<HttpService["requestAsync"]>[number] & {
|
|
21
24
|
readonly body: TBodyData;
|
|
22
25
|
};
|
|
23
|
-
readonly extraMetadata: (response: SuccessfulHttpResponse<TPayload, TBodyData
|
|
26
|
+
readonly extraMetadata: (response: SuccessfulHttpResponse<TPayload, TBodyData>, data: MetadataContextData) => TExtraMetadata;
|
|
24
27
|
readonly config: SdkConfig;
|
|
25
|
-
readonly url: string;
|
|
26
28
|
readonly zodSchema: ZodType<TPayload>;
|
|
27
29
|
readonly sdkInfo: SDKInfo;
|
|
28
30
|
readonly authorizationApiKey: string | undefined;
|
package/dist/sdk/sdk-queries.js
CHANGED
|
@@ -30,7 +30,7 @@ function getHttpService(config) {
|
|
|
30
30
|
function getCombinedRequestHeaders({ requestHeaders, continuationToken, authorizationApiKey, sdkInfo, }) {
|
|
31
31
|
return [
|
|
32
32
|
getSdkIdHeader({
|
|
33
|
-
host:
|
|
33
|
+
host: sdkInfo.host,
|
|
34
34
|
name: sdkInfo.name,
|
|
35
35
|
version: sdkInfo.version,
|
|
36
36
|
}),
|
|
@@ -56,7 +56,7 @@ function getCombinedRequestHeaders({ requestHeaders, continuationToken, authoriz
|
|
|
56
56
|
async function resolvePagingQueryAsync(data) {
|
|
57
57
|
const responses = [];
|
|
58
58
|
let nextContinuationToken = data.continuationToken;
|
|
59
|
-
while (nextContinuationToken) {
|
|
59
|
+
while (nextContinuationToken?.length) {
|
|
60
60
|
const { success, response, error } = await getQuery({
|
|
61
61
|
...data,
|
|
62
62
|
continuationToken: nextContinuationToken,
|
|
@@ -77,12 +77,13 @@ async function resolvePagingQueryAsync(data) {
|
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
|
|
80
|
+
const lastResponse = responses.at(-1);
|
|
81
|
+
if (!lastResponse) {
|
|
81
82
|
return {
|
|
82
83
|
success: false,
|
|
83
84
|
error: createSdkError({
|
|
84
85
|
reason: "noResponses",
|
|
85
|
-
url: data.url,
|
|
86
|
+
url: data.request.url,
|
|
86
87
|
message: "No responses were processed. Expected at least one response to be fetched when using paging queries.",
|
|
87
88
|
}),
|
|
88
89
|
};
|
|
@@ -90,10 +91,10 @@ async function resolvePagingQueryAsync(data) {
|
|
|
90
91
|
return {
|
|
91
92
|
success: true,
|
|
92
93
|
responses: responses,
|
|
93
|
-
lastContinuationToken:
|
|
94
|
+
lastContinuationToken: lastResponse.meta.continuationToken,
|
|
94
95
|
};
|
|
95
96
|
}
|
|
96
|
-
async function resolveQueryAsync({ config, request,
|
|
97
|
+
async function resolveQueryAsync({ config, request, extraMetadata, zodSchema, continuationToken, sdkInfo, authorizationApiKey, }) {
|
|
97
98
|
const { success, response, error } = await getHttpService(config).requestAsync({
|
|
98
99
|
...request,
|
|
99
100
|
requestHeaders: getCombinedRequestHeaders({
|
|
@@ -115,15 +116,16 @@ async function resolveQueryAsync({ config, request, url, extraMetadata, zodSchem
|
|
|
115
116
|
return {
|
|
116
117
|
success: false,
|
|
117
118
|
error: createSdkError({
|
|
118
|
-
message: `Failed to validate response schema for url '${url}'`,
|
|
119
|
+
message: `Failed to validate response schema for url '${request.url}'`,
|
|
119
120
|
reason: "validationFailed",
|
|
120
121
|
zodError: validationError,
|
|
121
122
|
response,
|
|
122
|
-
url,
|
|
123
|
+
url: request.url,
|
|
123
124
|
}),
|
|
124
125
|
};
|
|
125
126
|
}
|
|
126
127
|
}
|
|
128
|
+
const continuationTokenFromResponse = extractContinuationToken(response.adapterResponse.responseHeaders);
|
|
127
129
|
const result = {
|
|
128
130
|
success: true,
|
|
129
131
|
response: {
|
|
@@ -131,8 +133,8 @@ async function resolveQueryAsync({ config, request, url, extraMetadata, zodSchem
|
|
|
131
133
|
meta: {
|
|
132
134
|
responseHeaders: response.adapterResponse.responseHeaders,
|
|
133
135
|
status: response.adapterResponse.status,
|
|
134
|
-
continuationToken:
|
|
135
|
-
...extraMetadata(response),
|
|
136
|
+
continuationToken: continuationTokenFromResponse,
|
|
137
|
+
...extraMetadata(response, { continuationToken: continuationTokenFromResponse }),
|
|
136
138
|
},
|
|
137
139
|
},
|
|
138
140
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-queries.js","sourceRoot":"","sources":["../../lib/sdk/sdk-queries.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAIhE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"sdk-queries.js","sourceRoot":"","sources":["../../lib/sdk/sdk-queries.ts"],"names":[],"mappings":"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"}
|
package/dist/sdk-info.js
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HttpService, HttpServiceStatus } from "../http/http.models.js";
|
|
2
|
+
import type { SDKInfo } from "../models/core.models.js";
|
|
3
|
+
import type { JsonValue } from "../models/json.models.js";
|
|
4
|
+
export declare function mockGlobalFetchJsonResponse({ jsonResponse, statusCode, continuationToken, }: {
|
|
5
|
+
readonly jsonResponse: JsonValue;
|
|
6
|
+
readonly statusCode: HttpServiceStatus;
|
|
7
|
+
readonly continuationToken?: string;
|
|
8
|
+
}): void;
|
|
9
|
+
export declare function mockGlobalFetchBlobResponse({ blobResponse, statusCode, }: {
|
|
10
|
+
readonly blobResponse: Blob;
|
|
11
|
+
readonly statusCode: HttpServiceStatus;
|
|
12
|
+
}): void;
|
|
13
|
+
export declare function getFakeBlob(): Blob;
|
|
14
|
+
export declare function getTestSdkInfo(): SDKInfo;
|
|
15
|
+
export declare function getTestHttpServiceWithJsonResponse({ jsonResponse, statusCode, continuationToken, }: {
|
|
16
|
+
readonly jsonResponse: JsonValue;
|
|
17
|
+
readonly statusCode: HttpServiceStatus;
|
|
18
|
+
readonly continuationToken?: string;
|
|
19
|
+
}): HttpService;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { vi } from "vitest";
|
|
2
|
+
import { getDefaultHttpService } from "../http/http.service.js";
|
|
3
|
+
import { isNotUndefined } from "../utils/core.utils.js";
|
|
4
|
+
import { toFetchHeaders } from "../utils/header.utils.js";
|
|
5
|
+
export function mockGlobalFetchJsonResponse({ jsonResponse, statusCode, continuationToken, }) {
|
|
6
|
+
global.fetch = getFetchJsonMock({
|
|
7
|
+
json: jsonResponse,
|
|
8
|
+
status: statusCode,
|
|
9
|
+
responseHeaders: continuationToken ? [{ name: "X-Continuation", value: continuationToken }] : [],
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export function mockGlobalFetchBlobResponse({ blobResponse, statusCode, }) {
|
|
13
|
+
global.fetch = getFetchBlobMock({
|
|
14
|
+
blob: blobResponse,
|
|
15
|
+
status: statusCode,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export function getFakeBlob() {
|
|
19
|
+
return new Blob(["x"], { type: "text/plain" });
|
|
20
|
+
}
|
|
21
|
+
export function getTestSdkInfo() {
|
|
22
|
+
return {
|
|
23
|
+
name: "test",
|
|
24
|
+
version: "0.0.0",
|
|
25
|
+
host: "sdk",
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function getTestHttpServiceWithJsonResponse({ jsonResponse, statusCode, continuationToken, }) {
|
|
29
|
+
return getDefaultHttpService({
|
|
30
|
+
adapter: {
|
|
31
|
+
requestAsync: async () => {
|
|
32
|
+
const adapterResponse = {
|
|
33
|
+
isValidResponse: true,
|
|
34
|
+
responseHeaders: [
|
|
35
|
+
...(continuationToken
|
|
36
|
+
? [{ name: "X-Continuation", value: continuationToken }]
|
|
37
|
+
: []),
|
|
38
|
+
],
|
|
39
|
+
status: statusCode,
|
|
40
|
+
statusText: "",
|
|
41
|
+
toJsonAsync: async () => {
|
|
42
|
+
return await Promise.resolve(jsonResponse);
|
|
43
|
+
},
|
|
44
|
+
toBlobAsync: () => {
|
|
45
|
+
throw new Error("n/a");
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
return await Promise.resolve(adapterResponse);
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function getFetchBlobMock({ blob, status, responseHeaders, }) {
|
|
54
|
+
return getFetchMock({
|
|
55
|
+
blob,
|
|
56
|
+
status,
|
|
57
|
+
responseHeaders: responseHeaders ?? [],
|
|
58
|
+
json: undefined,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function getFetchJsonMock({ json, status, responseHeaders, }) {
|
|
62
|
+
return getFetchMock({
|
|
63
|
+
status,
|
|
64
|
+
responseHeaders: responseHeaders ?? [],
|
|
65
|
+
blob: undefined,
|
|
66
|
+
json,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function getFetchMock({ json, blob, status, responseHeaders, }) {
|
|
70
|
+
return vi.fn(async () => {
|
|
71
|
+
const contentTypeHeader = responseHeaders.find((m) => m.name.toLowerCase() === "Content-Type".toLowerCase())
|
|
72
|
+
? undefined
|
|
73
|
+
: {
|
|
74
|
+
name: "Content-Type",
|
|
75
|
+
value: "application/json",
|
|
76
|
+
};
|
|
77
|
+
return await Promise.resolve({
|
|
78
|
+
// only implement the methods we need, ignore the rest
|
|
79
|
+
...{},
|
|
80
|
+
ok: status === 200,
|
|
81
|
+
headers: toFetchHeaders([...responseHeaders, contentTypeHeader].filter(isNotUndefined)),
|
|
82
|
+
status,
|
|
83
|
+
json: async () => await Promise.resolve(json),
|
|
84
|
+
...(blob ? { blob: async () => await Promise.resolve(blob) } : {}),
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=testkit.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testkit.utils.js","sourceRoot":"","sources":["../../lib/testkit/testkit.utils.ts"],"names":[],"mappings":"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"}
|
package/dist/testkit_api.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
/** biome-ignore-all lint/performance/noBarrelFile: One barrel for exported API is fine */
|
|
2
2
|
export type { FetchResponse } from "./testkit/testkit.models.js";
|
|
3
|
+
export { getFakeBlob, getTestHttpServiceWithJsonResponse, mockGlobalFetchBlobResponse, mockGlobalFetchJsonResponse, } from "./testkit/testkit.utils.js";
|
package/dist/testkit_api.js
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export { getFakeBlob, getFetchBlobMock, getFetchJsonMock } from "./testkit/test.utils.js";
|
|
1
|
+
export { getFakeBlob, getTestHttpServiceWithJsonResponse, mockGlobalFetchBlobResponse, mockGlobalFetchJsonResponse, } from "./testkit/testkit.utils.js";
|
|
3
2
|
//# sourceMappingURL=testkit_api.js.map
|
package/dist/testkit_api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testkit_api.js","sourceRoot":"","sources":["../lib/testkit_api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"testkit_api.js","sourceRoot":"","sources":["../lib/testkit_api.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,WAAW,EACX,kCAAkC,EAClC,2BAA2B,EAC3B,2BAA2B,GAC3B,MAAM,4BAA4B,CAAC"}
|
package/dist/utils/core.utils.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.utils.js","sourceRoot":"","sources":["../../lib/utils/core.utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAI,KAAQ;IACzC,OAAO,KAAK,KAAK,SAAS,CAAC;AAC5B,CAAC"}
|
|
1
|
+
{"version":3,"file":"core.utils.js","sourceRoot":"","sources":["../../lib/utils/core.utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAI,KAAQ;IACzC,OAAO,KAAK,KAAK,SAAS,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,EAAU;IAC1C,OAAO,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAC1C,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sleepAsync } from "./core.utils.js";
|
|
1
2
|
import { createSdkError } from "./error.utils.js";
|
|
2
3
|
import { getRetryAfterHeaderValue } from "./header.utils.js";
|
|
3
4
|
const defaultMaxRetries = 3;
|
|
@@ -42,7 +43,7 @@ export async function runWithRetryAsync(data) {
|
|
|
42
43
|
};
|
|
43
44
|
}
|
|
44
45
|
logRetryAttempt(data.retryStrategyOptions, newRetryAttempt, data.url);
|
|
45
|
-
await
|
|
46
|
+
await sleepAsync(retryResult.retryInMs);
|
|
46
47
|
return await runWithRetryAsync({
|
|
47
48
|
funcAsync: data.funcAsync,
|
|
48
49
|
retryStrategyOptions: data.retryStrategyOptions,
|
|
@@ -78,9 +79,6 @@ function logRetryAttempt(opts, retryAttempt, url) {
|
|
|
78
79
|
opts.logRetryAttempt(retryAttempt, url);
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
|
-
function waitAsync(ms) {
|
|
82
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
83
|
-
}
|
|
84
82
|
function getRetryResult({ retryAttempt, error, options, }) {
|
|
85
83
|
if (retryAttempt >= options.maxRetries) {
|
|
86
84
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.utils.js","sourceRoot":"","sources":["../../lib/utils/retry.utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAW7D,MAAM,iBAAiB,GAAoD,CAAC,CAAC;AAC7E,MAAM,+BAA+B,GAAkE,CAAC,KAAK,EAAE,EAAE;IAChH,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,UAAU,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;QACvF,OAAO,oBAAoB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,CAAC,CAAC;AACV,CAAC,CAAC;AACF,MAAM,oBAAoB,GAAuD,CAAC,KAAK,EAAE,EAAE;IAC1F,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;QAChD,IAAI,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;YACxC,0EAA0E;YAC1E,OAAO,KAAK,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,GAAG,CAAC;IACpE,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAyE,IAO/G;IACA,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;IAE5D,IAAI,OAAO,EAAE,CAAC;QACb,OAAO;YACN,OAAO,EAAE,IAAI;YACb,QAAQ;SACR,CAAC;IACH,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;IAE9C,MAAM,WAAW,GAAG,cAAc,CAAC;QAClC,KAAK;QACL,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,OAAO,EAAE,IAAI,CAAC,oBAAoB;KAClC,CAAC,CAAC;IAEH,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC3B,OAAO;YACN,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,cAAc,CAAC;gBACrB,GAAG,KAAK,CAAC,OAAO;gBAChB,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;aAC/C,CAAC;SACF,CAAC;IACH,CAAC;IAED,eAAe,CAAC,IAAI,CAAC,oBAAoB,EAAE,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IAEtE,MAAM,
|
|
1
|
+
{"version":3,"file":"retry.utils.js","sourceRoot":"","sources":["../../lib/utils/retry.utils.ts"],"names":[],"mappings":"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"}
|
package/lib/devkit_api.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
/** biome-ignore-all lint/performance/noBarrelFile: One barrel for exported API is fine */
|
|
2
2
|
export { deleteFolderRecursive } from "./devkit/script.utils.js";
|
|
3
3
|
export { replaceSdkVersionPlaceholder } from "./utils/sdk-version.utils.js";
|
|
@@ -7,46 +7,20 @@ import type { JsonValue } from "./json.models.js";
|
|
|
7
7
|
export type ErrorReason = "invalidResponse" | "invalidUrl" | "unknown" | "invalidBody" | "notFound" | "validationFailed" | "noResponses";
|
|
8
8
|
|
|
9
9
|
export type ErrorReasonData =
|
|
10
|
-
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
| TReasonData<
|
|
17
|
-
"notFound",
|
|
18
|
-
{
|
|
19
|
-
readonly kontentErrorResponse: KontentErrorResponseData | undefined;
|
|
20
|
-
} & Pick<AdapterResponse<404>, "isValidResponse" | "responseHeaders" | "status" | "statusText">
|
|
21
|
-
>
|
|
22
|
-
| TReasonData<
|
|
23
|
-
"invalidBody",
|
|
24
|
-
{
|
|
25
|
-
readonly originalError: unknown;
|
|
26
|
-
}
|
|
27
|
-
>
|
|
28
|
-
| TReasonData<
|
|
29
|
-
"invalidUrl",
|
|
30
|
-
{
|
|
31
|
-
readonly originalError: unknown;
|
|
32
|
-
}
|
|
33
|
-
>
|
|
34
|
-
| TReasonData<
|
|
35
|
-
"unknown",
|
|
36
|
-
{
|
|
37
|
-
readonly originalError: unknown;
|
|
38
|
-
}
|
|
39
|
-
>
|
|
40
|
-
| TReasonData<
|
|
10
|
+
| ReasonData<"invalidResponse", ErrorWithKontentErrorResponse>
|
|
11
|
+
| ReasonData<"notFound", ErrorWithKontentErrorResponse>
|
|
12
|
+
| ReasonData<"invalidBody", ErrorWithOriginalError>
|
|
13
|
+
| ReasonData<"invalidUrl", ErrorWithOriginalError>
|
|
14
|
+
| ReasonData<"unknown", ErrorWithOriginalError>
|
|
15
|
+
| ReasonData<
|
|
41
16
|
"validationFailed",
|
|
42
17
|
{
|
|
43
|
-
readonly reason: "validationFailed";
|
|
44
18
|
readonly zodError: ZodError;
|
|
45
19
|
readonly response: SuccessfulHttpResponse<JsonValue, JsonValue>;
|
|
46
20
|
readonly url: string;
|
|
47
21
|
}
|
|
48
22
|
>
|
|
49
|
-
|
|
|
23
|
+
| ReasonData<
|
|
50
24
|
"noResponses",
|
|
51
25
|
{
|
|
52
26
|
readonly url: string;
|
|
@@ -85,7 +59,15 @@ export class SdkError extends Error {
|
|
|
85
59
|
}
|
|
86
60
|
}
|
|
87
61
|
|
|
88
|
-
type
|
|
62
|
+
type ErrorWithKontentErrorResponse = {
|
|
63
|
+
readonly kontentErrorResponse: KontentErrorResponseData | undefined;
|
|
64
|
+
} & Pick<AdapterResponse<HttpServiceStatus>, "isValidResponse" | "responseHeaders" | "status" | "statusText">;
|
|
65
|
+
|
|
66
|
+
type ErrorWithOriginalError = {
|
|
67
|
+
readonly originalError: unknown;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
type ReasonData<TReason extends ErrorReason, TData> = {
|
|
89
71
|
readonly reason: TReason;
|
|
90
72
|
} & TData;
|
|
91
73
|
|
package/lib/public_api.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
/** biome-ignore-all lint/performance/noBarrelFile: One barrel for exported API is fine */
|
|
2
2
|
export { getDefaultHttpAdapter } from "./http/http.adapter.js";
|
|
3
3
|
export type {
|
|
4
4
|
AdapterRequestOptions,
|
|
@@ -21,11 +21,7 @@ export type {
|
|
|
21
21
|
RetryStrategyOptions,
|
|
22
22
|
SDKInfo,
|
|
23
23
|
} from "./models/core.models.js";
|
|
24
|
-
export type
|
|
25
|
-
ErrorReason,
|
|
26
|
-
ErrorReasonData,
|
|
27
|
-
SdkError,
|
|
28
|
-
} from "./models/error.models.js";
|
|
24
|
+
export { type ErrorReason, type ErrorReasonData, SdkError } from "./models/error.models.js";
|
|
29
25
|
export type { JsonArray, JsonObject, JsonValue } from "./models/json.models.js";
|
|
30
26
|
export type { EmptyObject, Override, Prettify } from "./models/utility.models.js";
|
|
31
27
|
export type {
|
package/lib/sdk/sdk-models.ts
CHANGED
|
@@ -57,7 +57,7 @@ export type PagingQuery<TPayload, TExtraData = unknown> = Query<TPayload, TExtra
|
|
|
57
57
|
toAllPromise(): Promise<PagingQueryResult<SdkResponse<TPayload, TExtraData>>>;
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
export type SuccessfulHttpResponse<TPayload extends JsonValue, TBodyData extends JsonValue> = Prettify<
|
|
60
|
+
export type SuccessfulHttpResponse<TPayload extends JsonValue, TBodyData extends JsonValue | Blob> = Prettify<
|
|
61
61
|
Extract<HttpResponse<TPayload, TBodyData>, { readonly success: true }>["response"]
|
|
62
62
|
>;
|
|
63
63
|
|
|
@@ -73,7 +73,7 @@ export type ResultOfSuccessfulQuery<TQuery extends Query<unknown>> = Extract<
|
|
|
73
73
|
*/
|
|
74
74
|
export type QueryResult<TResponse> = (Success & { readonly response: TResponse }) | (Failure & { readonly response?: never });
|
|
75
75
|
export type PagingQueryResult<TResponse> =
|
|
76
|
-
| (Success & { readonly responses: TResponse[]; readonly lastContinuationToken: string })
|
|
76
|
+
| (Success & { readonly responses: TResponse[]; readonly lastContinuationToken: string | undefined })
|
|
77
77
|
| (Failure & { readonly responses?: never; readonly lastContinuationToken?: never });
|
|
78
78
|
|
|
79
79
|
type Success = {
|
package/lib/sdk/sdk-queries.ts
CHANGED
|
@@ -21,7 +21,11 @@ type ResolveToAllPromiseQuery<TPayload extends JsonValue, TExtraMetadata = Empty
|
|
|
21
21
|
Pick<PagingQuery<TPayload, TExtraMetadata>, "toAllPromise">["toAllPromise"]
|
|
22
22
|
>;
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
type MetadataContextData = {
|
|
25
|
+
readonly continuationToken?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export function getQuery<TPayload extends JsonValue, TBodyData extends JsonValue, TExtraMetadata = EmptyObject>(
|
|
25
29
|
data: Parameters<typeof resolveQueryAsync<TPayload, TBodyData, TExtraMetadata>>[0],
|
|
26
30
|
): Pick<Query<TPayload, TExtraMetadata>, "toPromise"> {
|
|
27
31
|
return {
|
|
@@ -67,7 +71,7 @@ function getCombinedRequestHeaders({
|
|
|
67
71
|
}): readonly Header[] {
|
|
68
72
|
return [
|
|
69
73
|
getSdkIdHeader({
|
|
70
|
-
host:
|
|
74
|
+
host: sdkInfo.host,
|
|
71
75
|
name: sdkInfo.name,
|
|
72
76
|
version: sdkInfo.version,
|
|
73
77
|
}),
|
|
@@ -97,7 +101,7 @@ async function resolvePagingQueryAsync<TPayload extends JsonValue, TBodyData ext
|
|
|
97
101
|
const responses: SdkResponse<TPayload, TExtraMetadata>[] = [];
|
|
98
102
|
let nextContinuationToken: string | undefined = data.continuationToken;
|
|
99
103
|
|
|
100
|
-
while (nextContinuationToken) {
|
|
104
|
+
while (nextContinuationToken?.length) {
|
|
101
105
|
const { success, response, error } = await getQuery<TPayload, TBodyData, TExtraMetadata>({
|
|
102
106
|
...data,
|
|
103
107
|
continuationToken: nextContinuationToken,
|
|
@@ -119,12 +123,14 @@ async function resolvePagingQueryAsync<TPayload extends JsonValue, TBodyData ext
|
|
|
119
123
|
}
|
|
120
124
|
}
|
|
121
125
|
|
|
122
|
-
|
|
126
|
+
const lastResponse: SdkResponse<TPayload, TExtraMetadata> | undefined = responses.at(-1);
|
|
127
|
+
|
|
128
|
+
if (!lastResponse) {
|
|
123
129
|
return {
|
|
124
130
|
success: false,
|
|
125
131
|
error: createSdkError({
|
|
126
132
|
reason: "noResponses",
|
|
127
|
-
url: data.url,
|
|
133
|
+
url: data.request.url,
|
|
128
134
|
message: "No responses were processed. Expected at least one response to be fetched when using paging queries.",
|
|
129
135
|
}),
|
|
130
136
|
};
|
|
@@ -133,14 +139,13 @@ async function resolvePagingQueryAsync<TPayload extends JsonValue, TBodyData ext
|
|
|
133
139
|
return {
|
|
134
140
|
success: true,
|
|
135
141
|
responses: responses,
|
|
136
|
-
lastContinuationToken:
|
|
142
|
+
lastContinuationToken: lastResponse.meta.continuationToken,
|
|
137
143
|
};
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
async function resolveQueryAsync<TPayload extends JsonValue, TBodyData extends JsonValue, TExtraMetadata>({
|
|
141
147
|
config,
|
|
142
148
|
request,
|
|
143
|
-
url,
|
|
144
149
|
extraMetadata,
|
|
145
150
|
zodSchema,
|
|
146
151
|
continuationToken,
|
|
@@ -149,9 +154,8 @@ async function resolveQueryAsync<TPayload extends JsonValue, TBodyData extends J
|
|
|
149
154
|
}: {
|
|
150
155
|
readonly continuationToken: string | undefined;
|
|
151
156
|
readonly request: Parameters<HttpService["requestAsync"]>[number] & { readonly body: TBodyData };
|
|
152
|
-
readonly extraMetadata: (response: SuccessfulHttpResponse<TPayload, TBodyData
|
|
157
|
+
readonly extraMetadata: (response: SuccessfulHttpResponse<TPayload, TBodyData>, data: MetadataContextData) => TExtraMetadata;
|
|
153
158
|
readonly config: SdkConfig;
|
|
154
|
-
readonly url: string;
|
|
155
159
|
readonly zodSchema: ZodType<TPayload>;
|
|
156
160
|
readonly sdkInfo: SDKInfo;
|
|
157
161
|
readonly authorizationApiKey: string | undefined;
|
|
@@ -179,16 +183,18 @@ async function resolveQueryAsync<TPayload extends JsonValue, TBodyData extends J
|
|
|
179
183
|
return {
|
|
180
184
|
success: false,
|
|
181
185
|
error: createSdkError({
|
|
182
|
-
message: `Failed to validate response schema for url '${url}'`,
|
|
186
|
+
message: `Failed to validate response schema for url '${request.url}'`,
|
|
183
187
|
reason: "validationFailed",
|
|
184
188
|
zodError: validationError,
|
|
185
189
|
response,
|
|
186
|
-
url,
|
|
190
|
+
url: request.url,
|
|
187
191
|
}),
|
|
188
192
|
};
|
|
189
193
|
}
|
|
190
194
|
}
|
|
191
195
|
|
|
196
|
+
const continuationTokenFromResponse = extractContinuationToken(response.adapterResponse.responseHeaders);
|
|
197
|
+
|
|
192
198
|
const result: Awaited<ResolveToPromiseQuery<TPayload, TExtraMetadata>> = {
|
|
193
199
|
success: true,
|
|
194
200
|
response: {
|
|
@@ -196,8 +202,8 @@ async function resolveQueryAsync<TPayload extends JsonValue, TBodyData extends J
|
|
|
196
202
|
meta: {
|
|
197
203
|
responseHeaders: response.adapterResponse.responseHeaders,
|
|
198
204
|
status: response.adapterResponse.status,
|
|
199
|
-
continuationToken:
|
|
200
|
-
...extraMetadata(response),
|
|
205
|
+
continuationToken: continuationTokenFromResponse,
|
|
206
|
+
...extraMetadata(response, { continuationToken: continuationTokenFromResponse }),
|
|
201
207
|
},
|
|
202
208
|
},
|
|
203
209
|
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { type Mock, vi } from "vitest";
|
|
2
|
+
import type { AdapterResponse, HttpService, HttpServiceStatus } from "../http/http.models.js";
|
|
3
|
+
import { getDefaultHttpService } from "../http/http.service.js";
|
|
4
|
+
import type { CommonHeaderNames, ContinuationHeaderName, SDKInfo } from "../models/core.models.js";
|
|
5
|
+
import type { JsonValue } from "../models/json.models.js";
|
|
6
|
+
import type { Header } from "../public_api.js";
|
|
7
|
+
import { isNotUndefined } from "../utils/core.utils.js";
|
|
8
|
+
import { toFetchHeaders } from "../utils/header.utils.js";
|
|
9
|
+
|
|
10
|
+
export function mockGlobalFetchJsonResponse({
|
|
11
|
+
jsonResponse,
|
|
12
|
+
statusCode,
|
|
13
|
+
continuationToken,
|
|
14
|
+
}: {
|
|
15
|
+
readonly jsonResponse: JsonValue;
|
|
16
|
+
readonly statusCode: HttpServiceStatus;
|
|
17
|
+
readonly continuationToken?: string;
|
|
18
|
+
}): void {
|
|
19
|
+
global.fetch = getFetchJsonMock({
|
|
20
|
+
json: jsonResponse,
|
|
21
|
+
status: statusCode,
|
|
22
|
+
responseHeaders: continuationToken ? [{ name: "X-Continuation" satisfies ContinuationHeaderName, value: continuationToken }] : [],
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function mockGlobalFetchBlobResponse({
|
|
27
|
+
blobResponse,
|
|
28
|
+
statusCode,
|
|
29
|
+
}: {
|
|
30
|
+
readonly blobResponse: Blob;
|
|
31
|
+
readonly statusCode: HttpServiceStatus;
|
|
32
|
+
}): void {
|
|
33
|
+
global.fetch = getFetchBlobMock({
|
|
34
|
+
blob: blobResponse,
|
|
35
|
+
status: statusCode,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getFakeBlob(): Blob {
|
|
40
|
+
return new Blob(["x"], { type: "text/plain" });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function getTestSdkInfo(): SDKInfo {
|
|
44
|
+
return {
|
|
45
|
+
name: "test",
|
|
46
|
+
version: "0.0.0",
|
|
47
|
+
host: "sdk",
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function getTestHttpServiceWithJsonResponse({
|
|
52
|
+
jsonResponse,
|
|
53
|
+
statusCode,
|
|
54
|
+
continuationToken,
|
|
55
|
+
}: {
|
|
56
|
+
readonly jsonResponse: JsonValue;
|
|
57
|
+
readonly statusCode: HttpServiceStatus;
|
|
58
|
+
readonly continuationToken?: string;
|
|
59
|
+
}): HttpService {
|
|
60
|
+
return getDefaultHttpService({
|
|
61
|
+
adapter: {
|
|
62
|
+
requestAsync: async () => {
|
|
63
|
+
const adapterResponse: AdapterResponse = {
|
|
64
|
+
isValidResponse: true,
|
|
65
|
+
responseHeaders: [
|
|
66
|
+
...(continuationToken
|
|
67
|
+
? [{ name: "X-Continuation" satisfies ContinuationHeaderName, value: continuationToken }]
|
|
68
|
+
: []),
|
|
69
|
+
],
|
|
70
|
+
status: statusCode,
|
|
71
|
+
statusText: "",
|
|
72
|
+
toJsonAsync: async () => {
|
|
73
|
+
return await Promise.resolve(jsonResponse);
|
|
74
|
+
},
|
|
75
|
+
toBlobAsync: () => {
|
|
76
|
+
throw new Error("n/a");
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
return await Promise.resolve<AdapterResponse>(adapterResponse);
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function getFetchBlobMock({
|
|
87
|
+
blob,
|
|
88
|
+
status,
|
|
89
|
+
responseHeaders,
|
|
90
|
+
}: {
|
|
91
|
+
readonly blob: Blob;
|
|
92
|
+
readonly status: HttpServiceStatus;
|
|
93
|
+
readonly responseHeaders?: readonly Header[];
|
|
94
|
+
}): Mock<() => Promise<Response>> {
|
|
95
|
+
return getFetchMock<Blob>({
|
|
96
|
+
blob,
|
|
97
|
+
status,
|
|
98
|
+
responseHeaders: responseHeaders ?? [],
|
|
99
|
+
json: undefined,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function getFetchJsonMock<TResponseData extends JsonValue>({
|
|
104
|
+
json,
|
|
105
|
+
status,
|
|
106
|
+
responseHeaders,
|
|
107
|
+
}: {
|
|
108
|
+
readonly json: TResponseData;
|
|
109
|
+
readonly status: HttpServiceStatus;
|
|
110
|
+
readonly responseHeaders?: readonly Header[];
|
|
111
|
+
}): Mock<() => Promise<Response>> {
|
|
112
|
+
return getFetchMock<JsonValue>({
|
|
113
|
+
status,
|
|
114
|
+
responseHeaders: responseHeaders ?? [],
|
|
115
|
+
blob: undefined,
|
|
116
|
+
json,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function getFetchMock<TResponseData extends JsonValue | Blob>({
|
|
121
|
+
json,
|
|
122
|
+
blob,
|
|
123
|
+
status,
|
|
124
|
+
responseHeaders,
|
|
125
|
+
}: {
|
|
126
|
+
readonly json: TResponseData extends JsonValue ? JsonValue : undefined;
|
|
127
|
+
readonly blob: TResponseData extends Blob ? Blob : undefined;
|
|
128
|
+
readonly status: HttpServiceStatus;
|
|
129
|
+
readonly responseHeaders: readonly Header[];
|
|
130
|
+
}): Mock<() => Promise<Response>> {
|
|
131
|
+
return vi.fn(async () => {
|
|
132
|
+
const contentTypeHeader: Header | undefined = responseHeaders.find(
|
|
133
|
+
(m) => m.name.toLowerCase() === ("Content-Type" satisfies CommonHeaderNames).toLowerCase(),
|
|
134
|
+
)
|
|
135
|
+
? undefined
|
|
136
|
+
: {
|
|
137
|
+
name: "Content-Type" satisfies CommonHeaderNames,
|
|
138
|
+
value: "application/json",
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
return await Promise.resolve<Response>({
|
|
142
|
+
// only implement the methods we need, ignore the rest
|
|
143
|
+
...({} as Response),
|
|
144
|
+
ok: status === 200,
|
|
145
|
+
headers: toFetchHeaders([...responseHeaders, contentTypeHeader].filter(isNotUndefined)),
|
|
146
|
+
status,
|
|
147
|
+
json: async () => await Promise.resolve(json),
|
|
148
|
+
...(blob ? { blob: async () => await Promise.resolve(blob) } : {}),
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
}
|
package/lib/testkit_api.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
export { getFakeBlob, getFetchBlobMock, getFetchJsonMock } from "./testkit/test.utils.js";
|
|
1
|
+
/** biome-ignore-all lint/performance/noBarrelFile: One barrel for exported API is fine */
|
|
3
2
|
export type { FetchResponse } from "./testkit/testkit.models.js";
|
|
3
|
+
export {
|
|
4
|
+
getFakeBlob,
|
|
5
|
+
getTestHttpServiceWithJsonResponse,
|
|
6
|
+
mockGlobalFetchBlobResponse,
|
|
7
|
+
mockGlobalFetchJsonResponse,
|
|
8
|
+
} from "./testkit/testkit.utils.js";
|
package/lib/utils/core.utils.ts
CHANGED
package/lib/utils/retry.utils.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { HttpResponse } from "../http/http.models.js";
|
|
|
2
2
|
import type { Header, HttpMethod, RetryStrategyOptions } from "../models/core.models.js";
|
|
3
3
|
import type { SdkError } from "../models/error.models.js";
|
|
4
4
|
import type { JsonValue } from "../models/json.models.js";
|
|
5
|
+
import { sleepAsync } from "./core.utils.js";
|
|
5
6
|
import { createSdkError } from "./error.utils.js";
|
|
6
7
|
import { getRetryAfterHeaderValue } from "./header.utils.js";
|
|
7
8
|
|
|
@@ -73,7 +74,7 @@ export async function runWithRetryAsync<TResponse extends JsonValue | Blob, TBod
|
|
|
73
74
|
|
|
74
75
|
logRetryAttempt(data.retryStrategyOptions, newRetryAttempt, data.url);
|
|
75
76
|
|
|
76
|
-
await
|
|
77
|
+
await sleepAsync(retryResult.retryInMs);
|
|
77
78
|
|
|
78
79
|
return await runWithRetryAsync({
|
|
79
80
|
funcAsync: data.funcAsync,
|
|
@@ -115,10 +116,6 @@ function logRetryAttempt(opts: Pick<RetryStrategyOptions, "logRetryAttempt">, re
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
function waitAsync(ms: number): Promise<void> {
|
|
119
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
120
|
-
}
|
|
121
|
-
|
|
122
119
|
function getRetryResult({
|
|
123
120
|
retryAttempt,
|
|
124
121
|
error,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kontent-ai/core-sdk",
|
|
3
|
-
"version": "12.0.0-preview.
|
|
3
|
+
"version": "12.0.0-preview.7",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/kontent-ai/kontent-core-js"
|
|
@@ -50,16 +50,15 @@
|
|
|
50
50
|
"zod": "4.3.5"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@kontent-ai/biome-config": "0.
|
|
54
|
-
"@kontent-ai/eslint-config": "2.
|
|
55
|
-
"@typescript-eslint/eslint-plugin": "8.51.0",
|
|
53
|
+
"@kontent-ai/biome-config": "0.7.0",
|
|
54
|
+
"@kontent-ai/eslint-config": "2.3.0",
|
|
56
55
|
"eslint": "9.39.2",
|
|
57
56
|
"@biomejs/biome": "2.3.11",
|
|
58
57
|
"@types/node": "25.0.3",
|
|
59
58
|
"chalk": "5.6.2",
|
|
60
59
|
"typescript": "5.9.3",
|
|
61
60
|
"vitest": "4.0.16",
|
|
62
|
-
"dotenv
|
|
61
|
+
"dotenv": "17.2.3",
|
|
63
62
|
"tsx": "4.21.0"
|
|
64
63
|
}
|
|
65
64
|
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Mock } from "vitest";
|
|
2
|
-
import type { HttpServiceStatus } from "../http/http.models.js";
|
|
3
|
-
import type { JsonValue } from "../models/json.models.js";
|
|
4
|
-
import type { Header } from "../public_api.js";
|
|
5
|
-
export declare function getFetchJsonMock<TResponseData extends JsonValue>({ json, status, responseHeaders, }: {
|
|
6
|
-
readonly json: TResponseData;
|
|
7
|
-
readonly status: HttpServiceStatus;
|
|
8
|
-
readonly responseHeaders?: readonly Header[];
|
|
9
|
-
}): Mock<() => Promise<Response>>;
|
|
10
|
-
export declare function getFetchBlobMock({ blob, status, responseHeaders, }: {
|
|
11
|
-
readonly blob: Blob;
|
|
12
|
-
readonly status: HttpServiceStatus;
|
|
13
|
-
readonly responseHeaders?: readonly Header[];
|
|
14
|
-
}): Mock<() => Promise<Response>>;
|
|
15
|
-
export declare function getFakeBlob(): Blob;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { vi } from "vitest";
|
|
2
|
-
import { isNotUndefined } from "../utils/core.utils.js";
|
|
3
|
-
import { toFetchHeaders } from "../utils/header.utils.js";
|
|
4
|
-
export function getFetchJsonMock({ json, status, responseHeaders, }) {
|
|
5
|
-
return getFetchMock({
|
|
6
|
-
status,
|
|
7
|
-
responseHeaders: responseHeaders ?? [],
|
|
8
|
-
blob: undefined,
|
|
9
|
-
json,
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
export function getFetchBlobMock({ blob, status, responseHeaders, }) {
|
|
13
|
-
return getFetchMock({
|
|
14
|
-
blob,
|
|
15
|
-
status,
|
|
16
|
-
responseHeaders: responseHeaders ?? [],
|
|
17
|
-
json: undefined,
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
export function getFakeBlob() {
|
|
21
|
-
return new Blob(["x"], { type: "text/plain" });
|
|
22
|
-
}
|
|
23
|
-
function getFetchMock({ json, blob, status, responseHeaders, }) {
|
|
24
|
-
return vi.fn(() => {
|
|
25
|
-
const contentTypeHeader = responseHeaders.find((m) => m.name.toLowerCase() === "Content-Type".toLowerCase())
|
|
26
|
-
? undefined
|
|
27
|
-
: {
|
|
28
|
-
name: "Content-Type",
|
|
29
|
-
value: "application/json",
|
|
30
|
-
};
|
|
31
|
-
return Promise.resolve({
|
|
32
|
-
// only implement the methods we need, ignore the rest
|
|
33
|
-
...{},
|
|
34
|
-
ok: status === 200,
|
|
35
|
-
headers: toFetchHeaders([...responseHeaders, contentTypeHeader].filter(isNotUndefined)),
|
|
36
|
-
status,
|
|
37
|
-
json: async () => await Promise.resolve(json),
|
|
38
|
-
...(blob ? { blob: async () => await Promise.resolve(blob) } : {}),
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=test.utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test.utils.js","sourceRoot":"","sources":["../../lib/testkit/test.utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAK5B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,UAAU,gBAAgB,CAAkC,EACjE,IAAI,EACJ,MAAM,EACN,eAAe,GAKf;IACA,OAAO,YAAY,CAAY;QAC9B,MAAM;QACN,eAAe,EAAE,eAAe,IAAI,EAAE;QACtC,IAAI,EAAE,SAAS;QACf,IAAI;KACJ,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAChC,IAAI,EACJ,MAAM,EACN,eAAe,GAKf;IACA,OAAO,YAAY,CAAO;QACzB,IAAI;QACJ,MAAM;QACN,eAAe,EAAE,eAAe,IAAI,EAAE;QACtC,IAAI,EAAE,SAAS;KACf,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW;IAC1B,OAAO,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,YAAY,CAAyC,EAC7D,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,eAAe,GAMf;IACA,OAAO,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE;QACjB,MAAM,iBAAiB,GAAuB,eAAe,CAAC,IAAI,CACjE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAM,cAA2C,CAAC,WAAW,EAAE,CAC1F;YACA,CAAC,CAAC,SAAS;YACX,CAAC,CAAC;gBACA,IAAI,EAAE,cAA0C;gBAChD,KAAK,EAAE,kBAAkB;aACzB,CAAC;QAEJ,OAAO,OAAO,CAAC,OAAO,CAAW;YAChC,sDAAsD;YACtD,GAAI,EAAe;YACnB,EAAE,EAAE,MAAM,KAAK,GAAG;YAClB,OAAO,EAAE,cAAc,CAAC,CAAC,GAAG,eAAe,EAAE,iBAAiB,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YACvF,MAAM;YACN,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;YAC7C,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClE,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import type { Mock } from "vitest";
|
|
2
|
-
import { vi } from "vitest";
|
|
3
|
-
import type { HttpServiceStatus } from "../http/http.models.js";
|
|
4
|
-
import type { CommonHeaderNames } from "../models/core.models.js";
|
|
5
|
-
import type { JsonValue } from "../models/json.models.js";
|
|
6
|
-
import type { Header } from "../public_api.js";
|
|
7
|
-
import { isNotUndefined } from "../utils/core.utils.js";
|
|
8
|
-
import { toFetchHeaders } from "../utils/header.utils.js";
|
|
9
|
-
|
|
10
|
-
export function getFetchJsonMock<TResponseData extends JsonValue>({
|
|
11
|
-
json,
|
|
12
|
-
status,
|
|
13
|
-
responseHeaders,
|
|
14
|
-
}: {
|
|
15
|
-
readonly json: TResponseData;
|
|
16
|
-
readonly status: HttpServiceStatus;
|
|
17
|
-
readonly responseHeaders?: readonly Header[];
|
|
18
|
-
}): Mock<() => Promise<Response>> {
|
|
19
|
-
return getFetchMock<JsonValue>({
|
|
20
|
-
status,
|
|
21
|
-
responseHeaders: responseHeaders ?? [],
|
|
22
|
-
blob: undefined,
|
|
23
|
-
json,
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function getFetchBlobMock({
|
|
28
|
-
blob,
|
|
29
|
-
status,
|
|
30
|
-
responseHeaders,
|
|
31
|
-
}: {
|
|
32
|
-
readonly blob: Blob;
|
|
33
|
-
readonly status: HttpServiceStatus;
|
|
34
|
-
readonly responseHeaders?: readonly Header[];
|
|
35
|
-
}): Mock<() => Promise<Response>> {
|
|
36
|
-
return getFetchMock<Blob>({
|
|
37
|
-
blob,
|
|
38
|
-
status,
|
|
39
|
-
responseHeaders: responseHeaders ?? [],
|
|
40
|
-
json: undefined,
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function getFakeBlob(): Blob {
|
|
45
|
-
return new Blob(["x"], { type: "text/plain" });
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function getFetchMock<TResponseData extends JsonValue | Blob>({
|
|
49
|
-
json,
|
|
50
|
-
blob,
|
|
51
|
-
status,
|
|
52
|
-
responseHeaders,
|
|
53
|
-
}: {
|
|
54
|
-
readonly json: TResponseData extends JsonValue ? JsonValue : undefined;
|
|
55
|
-
readonly blob: TResponseData extends Blob ? Blob : undefined;
|
|
56
|
-
readonly status: HttpServiceStatus;
|
|
57
|
-
readonly responseHeaders: readonly Header[];
|
|
58
|
-
}): Mock<() => Promise<Response>> {
|
|
59
|
-
return vi.fn(() => {
|
|
60
|
-
const contentTypeHeader: Header | undefined = responseHeaders.find(
|
|
61
|
-
(m) => m.name.toLowerCase() === ("Content-Type" satisfies CommonHeaderNames).toLowerCase(),
|
|
62
|
-
)
|
|
63
|
-
? undefined
|
|
64
|
-
: {
|
|
65
|
-
name: "Content-Type" satisfies CommonHeaderNames,
|
|
66
|
-
value: "application/json",
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
return Promise.resolve<Response>({
|
|
70
|
-
// only implement the methods we need, ignore the rest
|
|
71
|
-
...({} as Response),
|
|
72
|
-
ok: status === 200,
|
|
73
|
-
headers: toFetchHeaders([...responseHeaders, contentTypeHeader].filter(isNotUndefined)),
|
|
74
|
-
status,
|
|
75
|
-
json: async () => await Promise.resolve(json),
|
|
76
|
-
...(blob ? { blob: async () => await Promise.resolve(blob) } : {}),
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
}
|