@contentful/optimization-api-client 0.1.0-alpha
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 +21 -0
- package/README.md +282 -0
- package/dist/ApiClient.d.ts +74 -0
- package/dist/ApiClient.d.ts.map +1 -0
- package/dist/ApiClient.js +61 -0
- package/dist/ApiClient.js.map +1 -0
- package/dist/ApiClientBase.d.ts +113 -0
- package/dist/ApiClientBase.d.ts.map +1 -0
- package/dist/ApiClientBase.js +94 -0
- package/dist/ApiClientBase.js.map +1 -0
- package/dist/builders/EventBuilder.d.ts +589 -0
- package/dist/builders/EventBuilder.d.ts.map +1 -0
- package/dist/builders/EventBuilder.js +349 -0
- package/dist/builders/EventBuilder.js.map +1 -0
- package/dist/builders/index.d.ts +3 -0
- package/dist/builders/index.d.ts.map +1 -0
- package/dist/builders/index.js +3 -0
- package/dist/builders/index.js.map +1 -0
- package/dist/experience/ExperienceApiClient.d.ts +267 -0
- package/dist/experience/ExperienceApiClient.d.ts.map +1 -0
- package/dist/experience/ExperienceApiClient.js +324 -0
- package/dist/experience/ExperienceApiClient.js.map +1 -0
- package/dist/experience/index.d.ts +4 -0
- package/dist/experience/index.d.ts.map +1 -0
- package/dist/experience/index.js +4 -0
- package/dist/experience/index.js.map +1 -0
- package/dist/fetch/Fetch.d.ts +96 -0
- package/dist/fetch/Fetch.d.ts.map +1 -0
- package/dist/fetch/Fetch.js +27 -0
- package/dist/fetch/Fetch.js.map +1 -0
- package/dist/fetch/createProtectedFetchMethod.d.ts +40 -0
- package/dist/fetch/createProtectedFetchMethod.d.ts.map +1 -0
- package/dist/fetch/createProtectedFetchMethod.js +53 -0
- package/dist/fetch/createProtectedFetchMethod.js.map +1 -0
- package/dist/fetch/createRetryFetchMethod.d.ts +60 -0
- package/dist/fetch/createRetryFetchMethod.d.ts.map +1 -0
- package/dist/fetch/createRetryFetchMethod.js +138 -0
- package/dist/fetch/createRetryFetchMethod.js.map +1 -0
- package/dist/fetch/createTimeoutFetchMethod.d.ts +51 -0
- package/dist/fetch/createTimeoutFetchMethod.d.ts.map +1 -0
- package/dist/fetch/createTimeoutFetchMethod.js +51 -0
- package/dist/fetch/createTimeoutFetchMethod.js.map +1 -0
- package/dist/fetch/index.d.ts +7 -0
- package/dist/fetch/index.d.ts.map +1 -0
- package/dist/fetch/index.js +7 -0
- package/dist/fetch/index.js.map +1 -0
- package/dist/index.cjs +708 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +583 -0
- package/dist/index.mjs.map +1 -0
- package/dist/insights/InsightsApiClient.d.ts +130 -0
- package/dist/insights/InsightsApiClient.d.ts.map +1 -0
- package/dist/insights/InsightsApiClient.js +142 -0
- package/dist/insights/InsightsApiClient.js.map +1 -0
- package/dist/insights/index.d.ts +4 -0
- package/dist/insights/index.d.ts.map +1 -0
- package/dist/insights/index.js +4 -0
- package/dist/insights/index.js.map +1 -0
- package/package.json +27 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { BatchExperienceResponse, ExperienceEventArray, ExperienceResponse, } from '@contentful/optimization-api-schemas';
|
|
2
|
+
import { createScopedLogger } from 'logger';
|
|
3
|
+
import ApiClientBase from '../ApiClientBase';
|
|
4
|
+
const logger = createScopedLogger('ApiClient:Experience');
|
|
5
|
+
/**
|
|
6
|
+
* Default base URL for the Experience API.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export const EXPERIENCE_BASE_URL = 'https://experience.ninetailed.co/';
|
|
11
|
+
/**
|
|
12
|
+
* Client for interacting with the Experience API.
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* This client is responsible for reading and mutating Ninetailed profiles
|
|
18
|
+
* using the Experience API.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const client = new ExperienceApiClient({
|
|
23
|
+
* clientId: 'org-id',
|
|
24
|
+
* environment: 'main',
|
|
25
|
+
* })
|
|
26
|
+
*
|
|
27
|
+
* const profile = await client.getProfile('profile-id')
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export default class ExperienceApiClient extends ApiClientBase {
|
|
31
|
+
/**
|
|
32
|
+
* Base URL used for Experience API requests.
|
|
33
|
+
*/
|
|
34
|
+
baseUrl;
|
|
35
|
+
enabledFeatures;
|
|
36
|
+
ip;
|
|
37
|
+
locale;
|
|
38
|
+
plainText;
|
|
39
|
+
preflight;
|
|
40
|
+
/**
|
|
41
|
+
* Creates a new {@link ExperienceApiClient} instance.
|
|
42
|
+
*
|
|
43
|
+
* @param config - Configuration for the Experience API client.
|
|
44
|
+
*/
|
|
45
|
+
constructor(config) {
|
|
46
|
+
super('Experience', config);
|
|
47
|
+
const { baseUrl, enabledFeatures, ip, locale, plainText, preflight } = config;
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Set default for anything falsey
|
|
49
|
+
this.baseUrl = baseUrl || EXPERIENCE_BASE_URL;
|
|
50
|
+
this.enabledFeatures = enabledFeatures;
|
|
51
|
+
this.ip = ip;
|
|
52
|
+
this.locale = locale;
|
|
53
|
+
this.plainText = plainText;
|
|
54
|
+
this.preflight = preflight;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Retrieves a profile by ID.
|
|
58
|
+
*
|
|
59
|
+
* @param id - The profile ID to retrieve.
|
|
60
|
+
* @param options - Optional request options. `preflight` and `plainText` are not allowed here.
|
|
61
|
+
* @returns The current optimization data for the profile.
|
|
62
|
+
*
|
|
63
|
+
* @throws {@link Error}
|
|
64
|
+
* Thrown if `id` is missing or the underlying request fails.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* const profile = await client.getProfile('profile-id', {
|
|
69
|
+
* locale: 'en-US',
|
|
70
|
+
* })
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
async getProfile(id, options = {}) {
|
|
74
|
+
if (!id)
|
|
75
|
+
throw new Error('Valid profile ID required.');
|
|
76
|
+
const requestName = 'Get Profile';
|
|
77
|
+
logger.info(`Sending "${requestName}" request`);
|
|
78
|
+
try {
|
|
79
|
+
const response = await this.fetch(this.constructUrl(`v2/organizations/${this.clientId}/environments/${this.environment}/profiles/${id}`, options), {
|
|
80
|
+
method: 'GET',
|
|
81
|
+
});
|
|
82
|
+
const { data: { changes, experiences, profile }, } = ExperienceResponse.parse(await response.json());
|
|
83
|
+
const data = { changes, personalizations: experiences, profile };
|
|
84
|
+
logger.debug(`"${requestName}" request successfully completed`);
|
|
85
|
+
return data;
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
this.logRequestError(error, { requestName });
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Sends a POST request to mutate a profile or profiles.
|
|
94
|
+
*
|
|
95
|
+
* @param request - Mutation request options including URL, body, and request options.
|
|
96
|
+
* @returns The raw {@link Response} from the underlying fetch.
|
|
97
|
+
*
|
|
98
|
+
* @internal
|
|
99
|
+
*/
|
|
100
|
+
async makeProfileMutationRequest({ url, body, options, }) {
|
|
101
|
+
return await this.fetch(this.constructUrl(url, options), {
|
|
102
|
+
method: 'POST',
|
|
103
|
+
headers: this.constructHeaders(options),
|
|
104
|
+
body: JSON.stringify(body),
|
|
105
|
+
keepalive: true,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Creates a profile and returns the resulting optimization data.
|
|
110
|
+
*
|
|
111
|
+
* @param params - Parameters containing the events to aggregate into the profile.
|
|
112
|
+
* @param options - Optional request options.
|
|
113
|
+
* @returns The optimization data for the newly created profile.
|
|
114
|
+
*
|
|
115
|
+
* @remarks
|
|
116
|
+
* The returned profile ID can be used for subsequent update requests.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* const data = await client.createProfile({
|
|
121
|
+
* events: [{ type: 'identify', userId: 'user-123' }],
|
|
122
|
+
* })
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
async createProfile({ events }, options = {}) {
|
|
126
|
+
const requestName = 'Create Profile';
|
|
127
|
+
logger.info(`Sending "${requestName}" request`);
|
|
128
|
+
const body = {
|
|
129
|
+
events: ExperienceEventArray.parse(events),
|
|
130
|
+
options: this.constructBodyOptions(options),
|
|
131
|
+
};
|
|
132
|
+
logger.debug(`"${requestName}" request body:`, body);
|
|
133
|
+
try {
|
|
134
|
+
const response = await this.makeProfileMutationRequest({
|
|
135
|
+
url: `v2/organizations/${this.clientId}/environments/${this.environment}/profiles`,
|
|
136
|
+
body,
|
|
137
|
+
options,
|
|
138
|
+
});
|
|
139
|
+
const { data: { changes, experiences, profile }, } = ExperienceResponse.parse(await response.json());
|
|
140
|
+
const data = { changes, personalizations: experiences, profile };
|
|
141
|
+
logger.debug(`"${requestName}" request successfully completed`);
|
|
142
|
+
return data;
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
this.logRequestError(error, { requestName });
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Updates an existing profile with the given profile ID.
|
|
151
|
+
*
|
|
152
|
+
* @param params - Parameters including the profile ID and events.
|
|
153
|
+
* @param options - Optional request options.
|
|
154
|
+
* @returns The updated optimization data for the profile.
|
|
155
|
+
*
|
|
156
|
+
* @throws {@link Error}
|
|
157
|
+
* Thrown if `profileId` is missing or the underlying request fails.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* const data = await client.updateProfile({
|
|
162
|
+
* profileId: 'profile-id',
|
|
163
|
+
* events: [{ type: 'track', event: 'viewed_video' }],
|
|
164
|
+
* })
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
async updateProfile({ profileId, events }, options = {}) {
|
|
168
|
+
if (!profileId)
|
|
169
|
+
throw new Error('Valid profile ID required.');
|
|
170
|
+
const requestName = 'Update Profile';
|
|
171
|
+
logger.info(`Sending "${requestName}" request`);
|
|
172
|
+
const body = {
|
|
173
|
+
events: ExperienceEventArray.parse(events),
|
|
174
|
+
options: this.constructBodyOptions(options),
|
|
175
|
+
};
|
|
176
|
+
logger.debug(`"${requestName}" request body:`, body);
|
|
177
|
+
try {
|
|
178
|
+
const response = await this.makeProfileMutationRequest({
|
|
179
|
+
url: `v2/organizations/${this.clientId}/environments/${this.environment}/profiles/${profileId}`,
|
|
180
|
+
body,
|
|
181
|
+
options,
|
|
182
|
+
});
|
|
183
|
+
const { data: { changes, experiences, profile }, } = ExperienceResponse.parse(await response.json());
|
|
184
|
+
const data = { changes, personalizations: experiences, profile };
|
|
185
|
+
logger.debug(`"${requestName}" request successfully completed`);
|
|
186
|
+
return data;
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
this.logRequestError(error, { requestName });
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Creates or updates a profile depending on whether a `profileId` is provided.
|
|
195
|
+
*
|
|
196
|
+
* @param params - Parameters including optional profile ID and events.
|
|
197
|
+
* @param options - Optional request options.
|
|
198
|
+
* @returns The resulting optimization data.
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```ts
|
|
202
|
+
* // Create
|
|
203
|
+
* await client.upsertProfile({ events })
|
|
204
|
+
*
|
|
205
|
+
* // Update
|
|
206
|
+
* await client.upsertProfile({ profileId: 'profile-id', events })
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
async upsertProfile({ profileId, events }, options) {
|
|
210
|
+
if (!profileId) {
|
|
211
|
+
return await this.createProfile({ events }, options);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
return await this.updateProfile({ profileId, events }, options);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Sends multiple events to the Ninetailed Experience API to upsert many profiles.
|
|
219
|
+
*
|
|
220
|
+
* @param params - Parameters containing the batch of events.
|
|
221
|
+
* @param options - Optional request options.
|
|
222
|
+
* @returns The list of profiles affected by the batch operation.
|
|
223
|
+
*
|
|
224
|
+
* @remarks
|
|
225
|
+
* Every event must contain an anonymous ID. Profiles will be created or
|
|
226
|
+
* updated according to the anonymous ID.
|
|
227
|
+
*
|
|
228
|
+
* This method is intended to be used from server environments.
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```ts
|
|
232
|
+
* const profiles = await client.upsertManyProfiles({
|
|
233
|
+
* events: [
|
|
234
|
+
* [{ type: 'identify', userId: 'user-1' }],
|
|
235
|
+
* [{ type: 'identify', userId: 'user-2' }],
|
|
236
|
+
* ],
|
|
237
|
+
* })
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
async upsertManyProfiles({ events }, options = {}) {
|
|
241
|
+
const requestName = 'Upsert Many Profiles';
|
|
242
|
+
logger.info(`Sending "${requestName}" request`);
|
|
243
|
+
const body = {
|
|
244
|
+
events: ExperienceEventArray.parse(events),
|
|
245
|
+
options: this.constructBodyOptions(options),
|
|
246
|
+
};
|
|
247
|
+
logger.debug(`"${requestName}" request body:`, body);
|
|
248
|
+
try {
|
|
249
|
+
const response = await this.makeProfileMutationRequest({
|
|
250
|
+
url: `v2/organizations/${this.clientId}/environments/${this.environment}/events`,
|
|
251
|
+
body,
|
|
252
|
+
options: { plainText: false, ...options },
|
|
253
|
+
});
|
|
254
|
+
const { data: { profiles }, } = BatchExperienceResponse.parse(await response.json());
|
|
255
|
+
logger.debug(`"${requestName}" request successfully completed`);
|
|
256
|
+
return profiles;
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
this.logRequestError(error, { requestName });
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Constructs a request URL with query parameters derived from request options.
|
|
265
|
+
*
|
|
266
|
+
* @param path - Path relative to the Experience API base URL.
|
|
267
|
+
* @param options - Request options that may influence query parameters.
|
|
268
|
+
* @returns The fully constructed URL as a string.
|
|
269
|
+
*
|
|
270
|
+
* @internal
|
|
271
|
+
*/
|
|
272
|
+
constructUrl(path, options) {
|
|
273
|
+
const url = new URL(path, this.baseUrl);
|
|
274
|
+
const locale = options.locale ?? this.locale;
|
|
275
|
+
const preflight = options.preflight ?? this.preflight;
|
|
276
|
+
if (locale) {
|
|
277
|
+
url.searchParams.set('locale', locale);
|
|
278
|
+
}
|
|
279
|
+
if (preflight) {
|
|
280
|
+
url.searchParams.set('type', 'preflight');
|
|
281
|
+
}
|
|
282
|
+
return url.toString();
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Constructs request headers based on request options and default configuration.
|
|
286
|
+
*
|
|
287
|
+
* @param options - Request options that may influence headers.
|
|
288
|
+
* @returns A record of HTTP headers to send with the request.
|
|
289
|
+
*
|
|
290
|
+
* @internal
|
|
291
|
+
*/
|
|
292
|
+
constructHeaders({ ip = this.ip, plainText = this.plainText, }) {
|
|
293
|
+
const headers = new Map();
|
|
294
|
+
if (ip) {
|
|
295
|
+
headers.set('X-Force-IP', ip);
|
|
296
|
+
}
|
|
297
|
+
if (plainText ?? this.plainText ?? true) {
|
|
298
|
+
headers.set('Content-Type', 'text/plain');
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
headers.set('Content-Type', 'application/json');
|
|
302
|
+
}
|
|
303
|
+
return Object.fromEntries(headers);
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Constructs the `options` section of the request body for profile mutations.
|
|
307
|
+
*
|
|
308
|
+
* @param options - Request options that may specify enabled features.
|
|
309
|
+
* @returns Experience API body options including feature flags.
|
|
310
|
+
*
|
|
311
|
+
* @internal
|
|
312
|
+
*/
|
|
313
|
+
constructBodyOptions = ({ enabledFeatures = this.enabledFeatures, }) => {
|
|
314
|
+
const bodyOptions = {};
|
|
315
|
+
if (enabledFeatures && Array.isArray(enabledFeatures) && enabledFeatures.length > 0) {
|
|
316
|
+
bodyOptions.features = enabledFeatures;
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
bodyOptions.features = ['ip-enrichment', 'location'];
|
|
320
|
+
}
|
|
321
|
+
return bodyOptions;
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
//# sourceMappingURL=ExperienceApiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExperienceApiClient.js","sourceRoot":"","sources":["../../src/experience/ExperienceApiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/experience/index.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,uBAAuB,CAAA;AAEvD,cAAc,uBAAuB,CAAA;AAErC,eAAe,mBAAmB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/experience/index.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,uBAAuB,CAAA;AAEvD,cAAc,uBAAuB,CAAA;AAErC,eAAe,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { createProtectedFetchMethod } from './createProtectedFetchMethod';
|
|
2
|
+
/**
|
|
3
|
+
* Signature of a fetch method used by the API clients.
|
|
4
|
+
*
|
|
5
|
+
* @param url - The request URL.
|
|
6
|
+
* @param init - Initialization options passed to `fetch`.
|
|
7
|
+
* @returns A promise that resolves with the {@link Response}.
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* This abstraction allows the underlying implementation to be replaced,
|
|
13
|
+
* for example in tests or different runtime environments.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const method: FetchMethod = async (url, init) => {
|
|
18
|
+
* return fetch(url, init)
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export type FetchMethod = (url: string | URL, init: RequestInit) => Promise<Response>;
|
|
23
|
+
/**
|
|
24
|
+
* Base options shared across fetch method factories.
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export interface BaseFetchMethodOptions {
|
|
29
|
+
/**
|
|
30
|
+
* Human-readable name of the API being called.
|
|
31
|
+
*
|
|
32
|
+
* @remarks
|
|
33
|
+
* Used primarily for logging and error messages.
|
|
34
|
+
*/
|
|
35
|
+
apiName?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Custom fetch implementation to use instead of the global `fetch`.
|
|
38
|
+
*
|
|
39
|
+
* @remarks
|
|
40
|
+
* This is useful for providing polyfills, mocks, or instrumented fetch
|
|
41
|
+
* implementations.
|
|
42
|
+
*/
|
|
43
|
+
fetchMethod?: FetchMethod;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Options passed to callback functions invoked by fetch wrappers.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
*
|
|
50
|
+
* @remarks
|
|
51
|
+
* Not all fields are guaranteed to be present in all callback scenarios.
|
|
52
|
+
*/
|
|
53
|
+
export interface FetchMethodCallbackOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Name of the API associated with the request.
|
|
56
|
+
*/
|
|
57
|
+
apiName?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Error that caused the callback to be invoked, if available.
|
|
60
|
+
*/
|
|
61
|
+
error?: Error;
|
|
62
|
+
/**
|
|
63
|
+
* The current attempt number (for retry callbacks).
|
|
64
|
+
*/
|
|
65
|
+
attemptNumber?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Number of retry attempts remaining (for retry callbacks).
|
|
68
|
+
*/
|
|
69
|
+
retriesLeft?: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Namespace-like object providing factory methods for protected fetch functions.
|
|
73
|
+
*
|
|
74
|
+
* @public
|
|
75
|
+
*/
|
|
76
|
+
declare const Fetch: {
|
|
77
|
+
/**
|
|
78
|
+
* Creates a fully protected fetch method with timeout and retry behavior.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* const fetchMethod = Fetch.create({
|
|
83
|
+
* apiName: 'Optimization',
|
|
84
|
+
* requestTimeout: 3000,
|
|
85
|
+
* retries: 2,
|
|
86
|
+
* })
|
|
87
|
+
*
|
|
88
|
+
* const response = await fetchMethod('https://example.com', { method: 'GET' })
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @see createProtectedFetchMethod
|
|
92
|
+
*/
|
|
93
|
+
create: typeof createProtectedFetchMethod;
|
|
94
|
+
};
|
|
95
|
+
export default Fetch;
|
|
96
|
+
//# sourceMappingURL=Fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Fetch.d.ts","sourceRoot":"","sources":["../../src/fetch/Fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAA;AAEzE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAErF;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAA;IAEb;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;;GAIG;AACH,QAAA,MAAM,KAAK;IACT;;;;;;;;;;;;;;;OAeG;;CAEJ,CAAA;AAED,eAAe,KAAK,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createProtectedFetchMethod } from './createProtectedFetchMethod';
|
|
2
|
+
/**
|
|
3
|
+
* Namespace-like object providing factory methods for protected fetch functions.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
const Fetch = {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a fully protected fetch method with timeout and retry behavior.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const fetchMethod = Fetch.create({
|
|
14
|
+
* apiName: 'Optimization',
|
|
15
|
+
* requestTimeout: 3000,
|
|
16
|
+
* retries: 2,
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* const response = await fetchMethod('https://example.com', { method: 'GET' })
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @see createProtectedFetchMethod
|
|
23
|
+
*/
|
|
24
|
+
create: createProtectedFetchMethod,
|
|
25
|
+
};
|
|
26
|
+
export default Fetch;
|
|
27
|
+
//# sourceMappingURL=Fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Fetch.js","sourceRoot":"","sources":["../../src/fetch/Fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAA;AA8EzE;;;;GAIG;AACH,MAAM,KAAK,GAAG;IACZ;;;;;;;;;;;;;;;OAeG;IACH,MAAM,EAAE,0BAA0B;CACnC,CAAA;AAED,eAAe,KAAK,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type RetryFetchMethodOptions } from './createRetryFetchMethod';
|
|
2
|
+
import { type TimeoutFetchMethodOptions } from './createTimeoutFetchMethod';
|
|
3
|
+
import type { FetchMethod } from './Fetch';
|
|
4
|
+
/**
|
|
5
|
+
* Options for {@link createProtectedFetchMethod}, combining timeout and retry behavior.
|
|
6
|
+
*/
|
|
7
|
+
export interface ProtectedFetchMethodOptions extends RetryFetchMethodOptions, TimeoutFetchMethodOptions {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Creates a {@link FetchMethod} that combines timeout and retry protection.
|
|
11
|
+
*
|
|
12
|
+
* @param options - Configuration options for both timeout and retry behavior.
|
|
13
|
+
* @returns A {@link FetchMethod} that applies timeout and retry logic to requests.
|
|
14
|
+
*
|
|
15
|
+
* @remarks
|
|
16
|
+
* The resulting method first wraps the base fetch with a timeout (via
|
|
17
|
+
* {@link createTimeoutFetchMethod}), then applies retry behavior (via
|
|
18
|
+
* {@link createRetryFetchMethod}).
|
|
19
|
+
*
|
|
20
|
+
* If an error is thrown during configuration or request execution, it is logged
|
|
21
|
+
* using {@link logger}.
|
|
22
|
+
*
|
|
23
|
+
* @throws {@link Error}
|
|
24
|
+
* Rethrows the original error after logging, including abort errors.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const fetchProtected = createProtectedFetchMethod({
|
|
29
|
+
* apiName: 'Optimization',
|
|
30
|
+
* requestTimeout: 4000,
|
|
31
|
+
* retries: 2,
|
|
32
|
+
* })
|
|
33
|
+
*
|
|
34
|
+
* const response = await fetchProtected('https://example.com/experiences', {
|
|
35
|
+
* method: 'GET',
|
|
36
|
+
* })
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function createProtectedFetchMethod(options: ProtectedFetchMethodOptions): FetchMethod;
|
|
40
|
+
//# sourceMappingURL=createProtectedFetchMethod.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createProtectedFetchMethod.d.ts","sourceRoot":"","sources":["../../src/fetch/createProtectedFetchMethod.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAC/F,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAI1C;;GAEG;AACH,MAAM,WAAW,2BACf,SAAQ,uBAAuB,EAC7B,yBAAyB;CAAG;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,2BAA2B,GAAG,WAAW,CAgB5F"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createScopedLogger } from 'logger';
|
|
2
|
+
import { createRetryFetchMethod } from './createRetryFetchMethod';
|
|
3
|
+
import { createTimeoutFetchMethod, } from './createTimeoutFetchMethod';
|
|
4
|
+
const logger = createScopedLogger('ApiClient:Fetch');
|
|
5
|
+
/**
|
|
6
|
+
* Creates a {@link FetchMethod} that combines timeout and retry protection.
|
|
7
|
+
*
|
|
8
|
+
* @param options - Configuration options for both timeout and retry behavior.
|
|
9
|
+
* @returns A {@link FetchMethod} that applies timeout and retry logic to requests.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* The resulting method first wraps the base fetch with a timeout (via
|
|
13
|
+
* {@link createTimeoutFetchMethod}), then applies retry behavior (via
|
|
14
|
+
* {@link createRetryFetchMethod}).
|
|
15
|
+
*
|
|
16
|
+
* If an error is thrown during configuration or request execution, it is logged
|
|
17
|
+
* using {@link logger}.
|
|
18
|
+
*
|
|
19
|
+
* @throws {@link Error}
|
|
20
|
+
* Rethrows the original error after logging, including abort errors.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const fetchProtected = createProtectedFetchMethod({
|
|
25
|
+
* apiName: 'Optimization',
|
|
26
|
+
* requestTimeout: 4000,
|
|
27
|
+
* retries: 2,
|
|
28
|
+
* })
|
|
29
|
+
*
|
|
30
|
+
* const response = await fetchProtected('https://example.com/experiences', {
|
|
31
|
+
* method: 'GET',
|
|
32
|
+
* })
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export function createProtectedFetchMethod(options) {
|
|
36
|
+
try {
|
|
37
|
+
const timeoutFetchMethod = createTimeoutFetchMethod(options);
|
|
38
|
+
const retryFetchMethod = createRetryFetchMethod({ ...options, fetchMethod: timeoutFetchMethod });
|
|
39
|
+
return retryFetchMethod;
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (error instanceof Error) {
|
|
43
|
+
if (error.name === 'AbortError') {
|
|
44
|
+
logger.warn('Request aborted due to network issues. This request may not be retried.');
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
logger.error('Request failed:', error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=createProtectedFetchMethod.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createProtectedFetchMethod.js","sourceRoot":"","sources":["../../src/fetch/createProtectedFetchMethod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAC3C,OAAO,EAAE,sBAAsB,EAAgC,MAAM,0BAA0B,CAAA;AAC/F,OAAO,EACL,wBAAwB,GAEzB,MAAM,4BAA4B,CAAA;AAGnC,MAAM,MAAM,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAA;AASpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAAoC;IAC7E,IAAI,CAAC;QACH,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAA;QAC5D,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC,CAAA;QAEhG,OAAO,gBAAgB,CAAA;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAA;YACxF,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAA;YACxC,CAAC;QACH,CAAC;QACD,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { BaseFetchMethodOptions, FetchMethod, FetchMethodCallbackOptions } from './Fetch';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration options for {@link createRetryFetchMethod}.
|
|
4
|
+
*/
|
|
5
|
+
export interface RetryFetchMethodOptions extends BaseFetchMethodOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Delay (in milliseconds) between retry attempts.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Defaults to {@link DEFAULT_INTERVAL_TIMEOUT}.
|
|
11
|
+
*/
|
|
12
|
+
intervalTimeout?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Callback invoked whenever a retry attempt fails.
|
|
15
|
+
*
|
|
16
|
+
* @param options - Information about the failed attempt.
|
|
17
|
+
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* This callback is invoked with additional metadata such as the attempt
|
|
20
|
+
* number and the number of retries left.
|
|
21
|
+
*/
|
|
22
|
+
onFailedAttempt?: (options: FetchMethodCallbackOptions) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Maximum number of retry attempts.
|
|
25
|
+
*
|
|
26
|
+
* @remarks
|
|
27
|
+
* Defaults to {@link DEFAULT_RETRY_COUNT}.
|
|
28
|
+
*/
|
|
29
|
+
retries?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Creates a {@link FetchMethod} that retries failed requests according to the
|
|
33
|
+
* provided configuration.
|
|
34
|
+
*
|
|
35
|
+
* @param options - Configuration options that control retry behavior.
|
|
36
|
+
* @returns A {@link FetchMethod} that automatically retries qualifying failures.
|
|
37
|
+
*
|
|
38
|
+
* @remarks
|
|
39
|
+
* This wrapper integrates with `p-retry` and uses an {@link AbortController}
|
|
40
|
+
* to cancel pending requests when a non-retriable error occurs.
|
|
41
|
+
*
|
|
42
|
+
* @throws {@link Error}
|
|
43
|
+
* Thrown when the request cannot be retried and no successful response is obtained.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* const fetchWithRetry = createRetryFetchMethod({
|
|
48
|
+
* apiName: 'Optimization',
|
|
49
|
+
* retries: 3,
|
|
50
|
+
* intervalTimeout: 200,
|
|
51
|
+
* onFailedAttempt: ({ attemptNumber, retriesLeft }) => {
|
|
52
|
+
* console.warn(`Attempt ${attemptNumber} failed. Retries left: ${retriesLeft}`)
|
|
53
|
+
* },
|
|
54
|
+
* })
|
|
55
|
+
*
|
|
56
|
+
* const response = await fetchWithRetry('https://example.com', { method: 'GET' })
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function createRetryFetchMethod({ apiName, fetchMethod, intervalTimeout, onFailedAttempt, retries, }?: RetryFetchMethodOptions): FetchMethod;
|
|
60
|
+
//# sourceMappingURL=createRetryFetchMethod.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createRetryFetchMethod.d.ts","sourceRoot":"","sources":["../../src/fetch/createRetryFetchMethod.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,WAAW,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAA;AA2D9F;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,sBAAsB;IACrE;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,0BAA0B,KAAK,IAAI,CAAA;IAE/D;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AA4ED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,OAAwB,EACxB,WAAmB,EACnB,eAA0C,EAC1C,eAAe,EACf,OAA6B,GAC9B,GAAE,uBAA4B,GAAG,WAAW,CA8B5C"}
|