@kontent-ai/core-sdk 12.0.0-preview.11 → 12.0.0-preview.13

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.
@@ -1,238 +0,0 @@
1
- /**
2
- * Shared query models/types intended to be reused across SDKs (e.g. Sync, Delivery, Management)
3
- * to keep common code and behavior consistent.
4
- */
5
- import { match, P } from "ts-pattern";
6
- import { getDefaultHttpService } from "../http/http.service.js";
7
- import { createSdkError } from "../utils/error.utils.js";
8
- import { getSdkIdHeader } from "../utils/header.utils.js";
9
- export function createQuery(data) {
10
- return {
11
- toPromise: async () => {
12
- return await resolveQueryAsync({
13
- ...data,
14
- nextPageState: {
15
- hasNextPage: true,
16
- pageSource: "firstRequest",
17
- },
18
- });
19
- },
20
- };
21
- }
22
- export function createPagingQuery(data) {
23
- return {
24
- ...createQuery(data),
25
- toAllPromise: async (config) => {
26
- return await resolvePagingQueryAsync({
27
- ...data,
28
- pageIndex: 0,
29
- paginationConfig: config,
30
- });
31
- },
32
- };
33
- }
34
- export function extractContinuationToken(responseHeaders) {
35
- return responseHeaders.find((header) => header.name.toLowerCase() === "X-Continuation".toLowerCase())
36
- ?.value;
37
- }
38
- function resolveNextPageState({ paginationConfig, getNextPageData, pageIndex, response, }) {
39
- return match({ getNextPageData, paginationConfig, pageIndex, response })
40
- .returnType()
41
- .with({ response: undefined }, () => ({
42
- hasNextPage: true,
43
- pageSource: "firstRequest",
44
- }))
45
- .with({ paginationConfig: { maxPagesCount: 0 } }, () => ({
46
- hasNextPage: false,
47
- }))
48
- .with({ paginationConfig: { maxPagesCount: pageIndex } }, () => ({
49
- hasNextPage: false,
50
- }))
51
- .with({ response: P.not(undefined) }, (m) => {
52
- const responsePageData = m.getNextPageData(m.response);
53
- return match(responsePageData)
54
- .returnType()
55
- .with({ continuationToken: P.string.minLength(1) }, (m) => ({
56
- hasNextPage: true,
57
- pageSource: "continuationToken",
58
- continuationToken: m.continuationToken,
59
- }))
60
- .with({ nextPageUrl: P.string.minLength(1) }, (m) => ({
61
- hasNextPage: true,
62
- pageSource: "nextPageUrl",
63
- nextPageUrl: m.nextPageUrl,
64
- }))
65
- .otherwise(() => ({
66
- hasNextPage: false,
67
- }));
68
- })
69
- .otherwise(() => {
70
- return {
71
- hasNextPage: false,
72
- };
73
- });
74
- }
75
- function getHttpService(config) {
76
- return config.httpService ?? getDefaultHttpService();
77
- }
78
- function getCombinedRequestHeaders({ requestHeaders, continuationToken, authorizationApiKey, sdkInfo, }) {
79
- return [
80
- getSdkIdHeader({
81
- host: sdkInfo.host,
82
- name: sdkInfo.name,
83
- version: sdkInfo.version,
84
- }),
85
- ...requestHeaders,
86
- ...(continuationToken
87
- ? [
88
- {
89
- name: "X-Continuation",
90
- value: continuationToken,
91
- },
92
- ]
93
- : []),
94
- ...(authorizationApiKey
95
- ? [
96
- {
97
- name: "Authorization",
98
- value: `Bearer ${authorizationApiKey}`,
99
- },
100
- ]
101
- : []),
102
- ];
103
- }
104
- async function resolvePagingQueryAsync(data) {
105
- const { success, error, responses } = await fetchAllPagesAsync(data);
106
- if (!success) {
107
- return {
108
- success: false,
109
- error,
110
- };
111
- }
112
- return validateAndBuildPagingResult(responses, data.request.url);
113
- }
114
- async function fetchAllPagesAsync(data) {
115
- const initialPageState = resolveNextPageState({
116
- getNextPageData: data.getNextPageData,
117
- paginationConfig: data.paginationConfig,
118
- pageIndex: data.pageIndex,
119
- response: undefined,
120
- });
121
- return await fetchAllPagesInternal({
122
- queryData: data,
123
- nextPageState: initialPageState,
124
- responses: [],
125
- });
126
- }
127
- async function fetchAllPagesInternal({ queryData, nextPageState, responses, }) {
128
- if (!isNextPageAvailable(nextPageState)) {
129
- return {
130
- success: true,
131
- responses,
132
- };
133
- }
134
- const { success, error, response } = await resolveQueryAsync({
135
- ...queryData,
136
- nextPageState: nextPageState,
137
- });
138
- if (!success) {
139
- return {
140
- success: false,
141
- error: error,
142
- };
143
- }
144
- const updatedResponses = [...responses, response];
145
- return await fetchAllPagesInternal({
146
- queryData: queryData,
147
- nextPageState: resolveNextPageState({
148
- getNextPageData: queryData.getNextPageData,
149
- paginationConfig: queryData.paginationConfig,
150
- pageIndex: updatedResponses.length,
151
- response: response,
152
- }),
153
- responses: updatedResponses,
154
- });
155
- }
156
- function validateAndBuildPagingResult(responses, requestUrl) {
157
- const lastResponse = responses.at(-1);
158
- if (!lastResponse) {
159
- return {
160
- success: false,
161
- error: createSdkError({
162
- reason: "noResponses",
163
- url: requestUrl,
164
- message: "No responses were processed. Expected at least one response to be fetched when using paging queries.",
165
- }),
166
- };
167
- }
168
- return {
169
- success: true,
170
- responses: [...responses],
171
- lastContinuationToken: lastResponse.meta.continuationToken,
172
- };
173
- }
174
- async function resolveQueryAsync({ config, request, mapMetadata, zodSchema, sdkInfo, authorizationApiKey, nextPageState, }) {
175
- const { success, response, error } = await getHttpService(config).requestAsync({
176
- body: request.body,
177
- url: nextPageState?.nextPageUrl ?? request.url,
178
- method: request.method,
179
- requestHeaders: getCombinedRequestHeaders({
180
- requestHeaders: request.requestHeaders ?? [],
181
- continuationToken: nextPageState?.continuationToken,
182
- authorizationApiKey: authorizationApiKey,
183
- sdkInfo,
184
- }),
185
- });
186
- if (!success) {
187
- return {
188
- success: false,
189
- error,
190
- };
191
- }
192
- if (config.responseValidation?.enable) {
193
- const { isValid, error: validationError } = await validateResponseSchemaAsync(response.payload, zodSchema);
194
- if (!isValid) {
195
- return {
196
- success: false,
197
- error: createSdkError({
198
- message: `Failed to validate response schema for url '${request.url}'`,
199
- reason: "validationFailed",
200
- zodError: validationError,
201
- response,
202
- url: request.url,
203
- }),
204
- };
205
- }
206
- }
207
- const continuationTokenFromResponse = extractContinuationToken(response.adapterResponse.responseHeaders);
208
- const result = {
209
- success: true,
210
- response: {
211
- payload: response.payload,
212
- meta: {
213
- url: response.adapterResponse.url,
214
- responseHeaders: response.adapterResponse.responseHeaders,
215
- status: response.adapterResponse.status,
216
- continuationToken: continuationTokenFromResponse,
217
- ...mapMetadata(response, { continuationToken: continuationTokenFromResponse }),
218
- },
219
- },
220
- };
221
- return result;
222
- }
223
- async function validateResponseSchemaAsync(payload, zodSchema) {
224
- const validateResult = await zodSchema.safeParseAsync(payload);
225
- if (validateResult.success) {
226
- return {
227
- isValid: true,
228
- };
229
- }
230
- return {
231
- isValid: false,
232
- error: validateResult.error,
233
- };
234
- }
235
- function isNextPageAvailable(nextPageState) {
236
- return nextPageState.hasNextPage;
237
- }
238
- //# sourceMappingURL=sdk-queries.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sdk-queries.js","sourceRoot":"","sources":["../../lib/sdk/sdk-queries.ts"],"names":[],"mappings":"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"}
@@ -1,413 +0,0 @@
1
- /**
2
- * Shared query models/types intended to be reused across SDKs (e.g. Sync, Delivery, Management)
3
- * to keep common code and behavior consistent.
4
- */
5
-
6
- import { match, P } from "ts-pattern";
7
- import type { ZodError, ZodType } from "zod";
8
- import type { GetNextPageData, HttpService, PaginationConfig, RequestBody } from "../http/http.models.js";
9
- import { getDefaultHttpService } from "../http/http.service.js";
10
- import type { CommonHeaderNames, ContinuationHeaderName, Header, SDKInfo } from "../models/core.models.js";
11
- import type { JsonValue } from "../models/json.models.js";
12
- import type { EmptyObject } from "../models/utility.models.js";
13
- import { createSdkError } from "../utils/error.utils.js";
14
- import { getSdkIdHeader } from "../utils/header.utils.js";
15
- import type { PagingQuery, PagingQueryResult, Query, QueryResponse, SdkConfig, SuccessfulHttpResponse } from "./sdk-models.js";
16
-
17
- type QueryPromiseResult<TResponsePayload extends JsonValue, TMeta = EmptyObject> = ReturnType<
18
- Pick<Query<TResponsePayload, TMeta>, "toPromise">["toPromise"]
19
- >;
20
-
21
- type PagingQueryPromiseResult<TResponsePayload extends JsonValue, TMeta = EmptyObject> = ReturnType<
22
- Pick<PagingQuery<TResponsePayload, TMeta>, "toAllPromise">["toAllPromise"]
23
- >;
24
-
25
- type MetadataContextData = {
26
- readonly continuationToken?: string;
27
- };
28
-
29
- type MetadataMapper<TResponsePayload extends JsonValue, TRequestBody extends RequestBody, TMeta> = (
30
- response: SuccessfulHttpResponse<TResponsePayload, TRequestBody>,
31
- data: MetadataContextData,
32
- ) => TMeta;
33
- type MetadataMapperConfig<TResponsePayload extends JsonValue, TRequestBody extends RequestBody, TMeta> = {
34
- readonly mapMetadata: MetadataMapper<TResponsePayload, TRequestBody, TMeta>;
35
- };
36
- type ResolveQueryData<TResponsePayload extends JsonValue, TRequestBody extends RequestBody, TMeta> = {
37
- readonly nextPageState: NextPageStateWithRequest;
38
- readonly request: Parameters<HttpService["requestAsync"]>[number] & { readonly body: TRequestBody };
39
- readonly config: SdkConfig;
40
- readonly zodSchema: ZodType<TResponsePayload>;
41
- readonly sdkInfo: SDKInfo;
42
- readonly authorizationApiKey: string | undefined;
43
- } & MetadataMapperConfig<TResponsePayload, TRequestBody, TMeta>;
44
-
45
- type NoNextPageState = {
46
- readonly hasNextPage: false;
47
- };
48
-
49
- type NextPageStateWithRequest =
50
- | {
51
- readonly pageSource: "continuationToken";
52
- readonly hasNextPage: true;
53
- readonly continuationToken: string;
54
- readonly nextPageUrl?: never;
55
- }
56
- | {
57
- readonly pageSource: "nextPageUrl";
58
- readonly hasNextPage: true;
59
- readonly continuationToken?: never;
60
- readonly nextPageUrl: string;
61
- }
62
- | {
63
- readonly pageSource: "firstRequest";
64
- readonly hasNextPage: true;
65
- readonly continuationToken?: never;
66
- readonly nextPageUrl?: never;
67
- };
68
-
69
- type NextPageState = NextPageStateWithRequest | NoNextPageState;
70
-
71
- type FetchAllPagesResult<TResponsePayload extends JsonValue, TMeta> =
72
- | {
73
- readonly success: true;
74
- readonly responses: readonly QueryResponse<TResponsePayload, TMeta>[];
75
- readonly error?: never;
76
- }
77
- | {
78
- readonly success: false;
79
- readonly responses?: never;
80
- readonly error: ReturnType<typeof createSdkError>;
81
- };
82
-
83
- export function createQuery<TResponsePayload extends JsonValue, TRequestBody extends RequestBody, TMeta = EmptyObject>(
84
- data: Omit<ResolveQueryData<TResponsePayload, TRequestBody, TMeta>, "continuationToken" | "nextPageState" | "pageIndex">,
85
- ): Pick<Query<TResponsePayload, TMeta>, "toPromise"> {
86
- return {
87
- toPromise: async () => {
88
- return await resolveQueryAsync<TResponsePayload, TRequestBody, TMeta>({
89
- ...data,
90
- nextPageState: {
91
- hasNextPage: true,
92
- pageSource: "firstRequest",
93
- },
94
- });
95
- },
96
- };
97
- }
98
-
99
- export function createPagingQuery<TResponsePayload extends JsonValue, TRequestBody extends RequestBody, TMeta = EmptyObject>(
100
- data: Omit<ResolveQueryData<TResponsePayload, TRequestBody, TMeta>, "nextPageState" | "pageIndex"> & {
101
- readonly getNextPageData: GetNextPageData<TResponsePayload, TMeta>;
102
- },
103
- ): Pick<PagingQuery<TResponsePayload, TMeta>, "toPromise" | "toAllPromise"> {
104
- return {
105
- ...createQuery<TResponsePayload, TRequestBody, TMeta>(data),
106
- toAllPromise: async (config: PaginationConfig) => {
107
- return await resolvePagingQueryAsync<TResponsePayload, TRequestBody, TMeta>({
108
- ...data,
109
- pageIndex: 0,
110
- paginationConfig: config,
111
- });
112
- },
113
- };
114
- }
115
-
116
- export function extractContinuationToken(responseHeaders: readonly Header[]): string | undefined {
117
- return responseHeaders.find((header) => header.name.toLowerCase() === ("X-Continuation" satisfies ContinuationHeaderName).toLowerCase())
118
- ?.value;
119
- }
120
-
121
- function resolveNextPageState<TResponsePayload extends JsonValue, TMeta>({
122
- paginationConfig,
123
- getNextPageData,
124
- pageIndex,
125
- response,
126
- }: {
127
- readonly getNextPageData: GetNextPageData<TResponsePayload, TMeta>;
128
- readonly paginationConfig: PaginationConfig;
129
- readonly pageIndex: number;
130
- readonly response: QueryResponse<TResponsePayload, TMeta> | undefined;
131
- }): NextPageState {
132
- return match({ getNextPageData, paginationConfig, pageIndex, response })
133
- .returnType<NextPageState>()
134
- .with({ response: undefined }, () => ({
135
- hasNextPage: true,
136
- pageSource: "firstRequest",
137
- }))
138
- .with({ paginationConfig: { maxPagesCount: 0 } }, () => ({
139
- hasNextPage: false,
140
- }))
141
- .with({ paginationConfig: { maxPagesCount: pageIndex } }, () => ({
142
- hasNextPage: false,
143
- }))
144
- .with({ response: P.not(undefined) }, (m) => {
145
- const responsePageData = m.getNextPageData(m.response);
146
-
147
- return match(responsePageData)
148
- .returnType<NextPageState>()
149
- .with({ continuationToken: P.string.minLength(1) }, (m) => ({
150
- hasNextPage: true,
151
- pageSource: "continuationToken",
152
- continuationToken: m.continuationToken,
153
- }))
154
- .with({ nextPageUrl: P.string.minLength(1) }, (m) => ({
155
- hasNextPage: true,
156
- pageSource: "nextPageUrl",
157
- nextPageUrl: m.nextPageUrl,
158
- }))
159
- .otherwise(() => ({
160
- hasNextPage: false,
161
- }));
162
- })
163
- .otherwise(() => {
164
- return {
165
- hasNextPage: false,
166
- };
167
- });
168
- }
169
-
170
- function getHttpService(config: SdkConfig) {
171
- return config.httpService ?? getDefaultHttpService();
172
- }
173
-
174
- function getCombinedRequestHeaders({
175
- requestHeaders,
176
- continuationToken,
177
- authorizationApiKey,
178
- sdkInfo,
179
- }: {
180
- readonly requestHeaders: readonly Header[];
181
- readonly continuationToken: string | undefined;
182
- readonly authorizationApiKey: string | undefined;
183
- readonly sdkInfo: SDKInfo;
184
- }): readonly Header[] {
185
- return [
186
- getSdkIdHeader({
187
- host: sdkInfo.host,
188
- name: sdkInfo.name,
189
- version: sdkInfo.version,
190
- }),
191
- ...requestHeaders,
192
- ...(continuationToken
193
- ? [
194
- {
195
- name: "X-Continuation" satisfies CommonHeaderNames,
196
- value: continuationToken,
197
- },
198
- ]
199
- : []),
200
- ...(authorizationApiKey
201
- ? [
202
- {
203
- name: "Authorization" satisfies CommonHeaderNames,
204
- value: `Bearer ${authorizationApiKey}`,
205
- },
206
- ]
207
- : []),
208
- ];
209
- }
210
-
211
- async function resolvePagingQueryAsync<TResponsePayload extends JsonValue, TRequestBody extends RequestBody = null, TMeta = EmptyObject>(
212
- data: Omit<ResolveQueryData<TResponsePayload, TRequestBody, TMeta>, "nextPageState" | "getNextPageData"> & {
213
- readonly getNextPageData: GetNextPageData<TResponsePayload, TMeta>;
214
- readonly paginationConfig: PaginationConfig;
215
- readonly pageIndex: number;
216
- },
217
- ): Promise<PagingQueryPromiseResult<TResponsePayload, TMeta>> {
218
- const { success, error, responses } = await fetchAllPagesAsync<TResponsePayload, TRequestBody, TMeta>(data);
219
-
220
- if (!success) {
221
- return {
222
- success: false,
223
- error,
224
- };
225
- }
226
-
227
- return validateAndBuildPagingResult(responses, data.request.url);
228
- }
229
-
230
- async function fetchAllPagesAsync<TResponsePayload extends JsonValue, TRequestBody extends RequestBody = null, TMeta = EmptyObject>(
231
- data: Omit<ResolveQueryData<TResponsePayload, TRequestBody, TMeta>, "nextPageState"> & {
232
- readonly getNextPageData: GetNextPageData<TResponsePayload, TMeta>;
233
- readonly paginationConfig: PaginationConfig;
234
- readonly pageIndex: number;
235
- },
236
- ): Promise<FetchAllPagesResult<TResponsePayload, TMeta>> {
237
- const initialPageState: NextPageState = resolveNextPageState({
238
- getNextPageData: data.getNextPageData,
239
- paginationConfig: data.paginationConfig,
240
- pageIndex: data.pageIndex,
241
- response: undefined,
242
- });
243
-
244
- return await fetchAllPagesInternal<TResponsePayload, TRequestBody, TMeta>({
245
- queryData: data,
246
- nextPageState: initialPageState,
247
- responses: [],
248
- });
249
- }
250
-
251
- async function fetchAllPagesInternal<TResponsePayload extends JsonValue, TRequestBody extends RequestBody, TMeta = EmptyObject>({
252
- queryData,
253
- nextPageState,
254
- responses,
255
- }: {
256
- readonly queryData: Omit<ResolveQueryData<TResponsePayload, TRequestBody, TMeta>, "nextPageState"> & {
257
- readonly getNextPageData: GetNextPageData<TResponsePayload, TMeta>;
258
- readonly paginationConfig: PaginationConfig;
259
- readonly pageIndex: number;
260
- };
261
- readonly nextPageState: NextPageState;
262
- readonly responses: readonly QueryResponse<TResponsePayload, TMeta>[];
263
- }): Promise<FetchAllPagesResult<TResponsePayload, TMeta>> {
264
- if (!isNextPageAvailable(nextPageState)) {
265
- return {
266
- success: true,
267
- responses,
268
- };
269
- }
270
-
271
- const { success, error, response } = await resolveQueryAsync<TResponsePayload, TRequestBody, TMeta>({
272
- ...queryData,
273
- nextPageState: nextPageState,
274
- });
275
-
276
- if (!success) {
277
- return {
278
- success: false,
279
- error: error,
280
- };
281
- }
282
-
283
- const updatedResponses: readonly QueryResponse<TResponsePayload, TMeta>[] = [...responses, response];
284
-
285
- return await fetchAllPagesInternal<TResponsePayload, TRequestBody, TMeta>({
286
- queryData: queryData,
287
- nextPageState: resolveNextPageState({
288
- getNextPageData: queryData.getNextPageData,
289
- paginationConfig: queryData.paginationConfig,
290
- pageIndex: updatedResponses.length,
291
- response: response,
292
- }),
293
- responses: updatedResponses,
294
- });
295
- }
296
-
297
- function validateAndBuildPagingResult<TResponsePayload extends JsonValue, TMeta>(
298
- responses: readonly QueryResponse<TResponsePayload, TMeta>[],
299
- requestUrl: string,
300
- ): PagingQueryResult<QueryResponse<TResponsePayload, TMeta>> {
301
- const lastResponse = responses.at(-1);
302
-
303
- if (!lastResponse) {
304
- return {
305
- success: false,
306
- error: createSdkError({
307
- reason: "noResponses",
308
- url: requestUrl,
309
- message: "No responses were processed. Expected at least one response to be fetched when using paging queries.",
310
- }),
311
- };
312
- }
313
-
314
- return {
315
- success: true,
316
- responses: [...responses],
317
- lastContinuationToken: lastResponse.meta.continuationToken,
318
- };
319
- }
320
-
321
- async function resolveQueryAsync<TResponsePayload extends JsonValue, TRequestBody extends RequestBody, TMeta>({
322
- config,
323
- request,
324
- mapMetadata,
325
- zodSchema,
326
- sdkInfo,
327
- authorizationApiKey,
328
- nextPageState,
329
- }: ResolveQueryData<TResponsePayload, TRequestBody, TMeta>): QueryPromiseResult<TResponsePayload, TMeta> {
330
- const { success, response, error } = await getHttpService(config).requestAsync<TResponsePayload, TRequestBody>({
331
- body: request.body,
332
- url: nextPageState?.nextPageUrl ?? request.url,
333
- method: request.method,
334
- requestHeaders: getCombinedRequestHeaders({
335
- requestHeaders: request.requestHeaders ?? [],
336
- continuationToken: nextPageState?.continuationToken,
337
- authorizationApiKey: authorizationApiKey,
338
- sdkInfo,
339
- }),
340
- });
341
-
342
- if (!success) {
343
- return {
344
- success: false,
345
- error,
346
- };
347
- }
348
-
349
- if (config.responseValidation?.enable) {
350
- const { isValid, error: validationError } = await validateResponseSchemaAsync(response.payload, zodSchema);
351
- if (!isValid) {
352
- return {
353
- success: false,
354
- error: createSdkError({
355
- message: `Failed to validate response schema for url '${request.url}'`,
356
- reason: "validationFailed",
357
- zodError: validationError,
358
- response,
359
- url: request.url,
360
- }),
361
- };
362
- }
363
- }
364
-
365
- const continuationTokenFromResponse = extractContinuationToken(response.adapterResponse.responseHeaders);
366
-
367
- const result: Awaited<QueryPromiseResult<TResponsePayload, TMeta>> = {
368
- success: true,
369
- response: {
370
- payload: response.payload,
371
- meta: {
372
- url: response.adapterResponse.url,
373
- responseHeaders: response.adapterResponse.responseHeaders,
374
- status: response.adapterResponse.status,
375
- continuationToken: continuationTokenFromResponse,
376
- ...mapMetadata(response, { continuationToken: continuationTokenFromResponse }),
377
- },
378
- },
379
- };
380
-
381
- return result;
382
- }
383
-
384
- async function validateResponseSchemaAsync<TResponsePayload extends JsonValue>(
385
- payload: TResponsePayload,
386
- zodSchema: ZodType<TResponsePayload>,
387
- ): Promise<
388
- | {
389
- readonly isValid: true;
390
- readonly error?: never;
391
- }
392
- | {
393
- readonly isValid: false;
394
- readonly error: ZodError;
395
- }
396
- > {
397
- const validateResult = await zodSchema.safeParseAsync(payload);
398
-
399
- if (validateResult.success) {
400
- return {
401
- isValid: true,
402
- };
403
- }
404
-
405
- return {
406
- isValid: false,
407
- error: validateResult.error,
408
- };
409
- }
410
-
411
- function isNextPageAvailable(nextPageState: NextPageState): nextPageState is NextPageStateWithRequest {
412
- return nextPageState.hasNextPage;
413
- }